Skip to content

Commit

Permalink
Use KeyedItem interface in Picker (#1858)
Browse files Browse the repository at this point in the history
  • Loading branch information
bmingles committed Mar 19, 2024
1 parent 4783092 commit 0c5980e
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 28 deletions.
26 changes: 17 additions & 9 deletions packages/components/src/spectrum/picker/Picker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,20 +99,28 @@ export function Picker({
);

const renderItem = useCallback(
({ key, content, textValue }: NormalizedPickerItem) => (
({ key, item }: NormalizedPickerItem) => (
// The `textValue` prop gets used to provide the content of `<option>`
// elements that back the Spectrum Picker. These are not visible in the UI,
// but are used for accessibility purposes, so we set to an arbitrary
// 'Empty' value so that they are not empty strings.
<Item
key={key as Key}
textValue={textValue === '' || textValue == null ? 'Empty' : textValue}
textValue={
item?.textValue === '' || item?.textValue == null
? 'Empty'
: item.textValue
}
>
<PickerItemContent>{content}</PickerItemContent>
{tooltipOptions == null || content === '' ? null : (
<Tooltip options={tooltipOptions}>
{createTooltipContent(content)}
</Tooltip>
{item?.content == null ? null : (
<>
<PickerItemContent>{item.content}</PickerItemContent>
{tooltipOptions == null || item.content === '' ? null : (
<Tooltip options={tooltipOptions}>
{createTooltipContent(item.content)}
</Tooltip>
)}
</>
)}
</Item>
),
Expand Down Expand Up @@ -143,8 +151,8 @@ export function Picker({
return (
<Section
key={itemOrSection.key}
title={itemOrSection.title}
items={itemOrSection.items}
title={itemOrSection.item?.title}
items={itemOrSection.item?.items}
>
{renderItem}
</Section>
Expand Down
41 changes: 25 additions & 16 deletions packages/components/src/spectrum/picker/PickerUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { isValidElement, Key, ReactElement, ReactNode } from 'react';
import { SpectrumPickerProps } from '@adobe/react-spectrum';
import type { ItemRenderer } from '@react-types/shared';
import Log from '@deephaven/log';
import { KeyedItem } from '@deephaven/utils';
import { Item, ItemProps, Section, SectionProps } from '../shared';
import { PopperOptions } from '../../popper';

Expand Down Expand Up @@ -46,17 +47,21 @@ export type PickerSelectionChangeHandler = (key: PickerItemKey) => void;
* form to make rendering items simpler and keep the logic of transformation
* in separate util methods.
*/
export interface NormalizedPickerItem {
key?: PickerItemKey;
content: ReactNode;
textValue?: string;
}

export interface NormalizedPickerSection {
key?: Key;
title?: ReactNode;
items: NormalizedPickerItem[];
}
export type NormalizedPickerItem = KeyedItem<
{
content: ReactNode;
textValue?: string;
},
PickerItemKey | undefined
>;

export type NormalizedPickerSection = KeyedItem<
{
title?: ReactNode;
items: NormalizedPickerItem[];
},
Key | undefined
>;

export type NormalizedSpectrumPickerProps =
SpectrumPickerProps<NormalizedPickerItem>;
Expand Down Expand Up @@ -111,7 +116,10 @@ export function isPickerItemOrSection(
export function isNormalizedPickerSection(
maybeNormalizedPickerSection: NormalizedPickerItem | NormalizedPickerSection
): maybeNormalizedPickerSection is NormalizedPickerSection {
return 'items' in maybeNormalizedPickerSection;
return (
maybeNormalizedPickerSection.item != null &&
'items' in maybeNormalizedPickerSection.item
);
}

/**
Expand Down Expand Up @@ -195,8 +203,10 @@ function normalizePickerItem(

return {
key,
title,
items,
item: {
title,
items,
},
};
}

Expand All @@ -208,8 +218,7 @@ function normalizePickerItem(

return {
key,
content,
textValue,
item: { content, textValue },
};
}

Expand Down
9 changes: 6 additions & 3 deletions packages/utils/src/DataUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@ export const EMPTY_MAP: ReadonlyMap<never, never> = new Map<never, never>();

export const EMPTY_FUNCTION = (): void => undefined;

export interface KeyedItem<T> {
key: string;
item?: T;
export interface KeyedItem<
TItem,
TKey extends string | number | boolean | undefined = string,
> {
key: TKey;
item?: TItem;
}

export type SelectionT<T = string> = 'all' | Set<T>;
Expand Down

0 comments on commit 0c5980e

Please sign in to comment.