|
1 | | -import { useMemo } from 'react'; |
2 | 1 | import { Picker as SpectrumPicker } from '@adobe/react-spectrum'; |
3 | | -import type { DOMRef } from '@react-types/shared'; |
4 | 2 | import cl from 'classnames'; |
5 | | -import { EMPTY_FUNCTION } from '@deephaven/utils'; |
6 | | -import { Section } from '../shared'; |
7 | 3 | import type { PickerNormalizedProps } from './PickerProps'; |
8 | 4 |
|
9 | | -import { |
10 | | - getItemKey, |
11 | | - isNormalizedSection, |
12 | | - normalizeTooltipOptions, |
13 | | - useRenderNormalizedItem, |
14 | | - useStringifiedSelection, |
15 | | -} from '../utils'; |
16 | | -import usePickerScrollOnOpen from './usePickerScrollOnOpen'; |
| 5 | +import usePickerNormalizedProps from './usePickerNormalizedProps'; |
17 | 6 |
|
18 | 7 | /** |
19 | 8 | * Picker that takes an array of `NormalizedItem` or `NormalizedSection` items |
20 | 9 | * as children and uses a render item function to render the items. This is |
21 | 10 | * necessary to support windowed data. |
22 | 11 | */ |
23 | 12 | export function PickerNormalized({ |
24 | | - normalizedItems, |
25 | | - tooltip = true, |
26 | | - selectedKey, |
27 | | - defaultSelectedKey, |
28 | | - disabledKeys, |
29 | | - showItemIcons, |
30 | 13 | UNSAFE_className, |
31 | | - getInitialScrollPosition, |
32 | | - onChange, |
33 | | - onOpenChange, |
34 | | - onScroll = EMPTY_FUNCTION, |
35 | | - onSelectionChange, |
36 | 14 | ...props |
37 | 15 | }: PickerNormalizedProps): JSX.Element { |
38 | | - const tooltipOptions = useMemo( |
39 | | - () => normalizeTooltipOptions(tooltip), |
40 | | - [tooltip] |
41 | | - ); |
42 | | - |
43 | | - const renderNormalizedItem = useRenderNormalizedItem({ |
44 | | - itemIconSlot: 'icon', |
45 | | - // Descriptions introduce variable item heights which throws off calculation |
46 | | - // of initial scroll position and setting viewport on windowed data. For now |
47 | | - // not going to implement description support in Picker. |
48 | | - // https://github.com/deephaven/web-client-ui/issues/1958 |
49 | | - showItemDescriptions: false, |
50 | | - showItemIcons, |
51 | | - tooltipOptions, |
52 | | - }); |
53 | | - |
54 | | - // Spectrum doesn't re-render if only the `renderNormalizedItems` function |
55 | | - // changes, so we create a key from its dependencies that can be used to force |
56 | | - // re-render. |
57 | | - const forceRerenderKey = `${showItemIcons}-${tooltipOptions?.placement}`; |
58 | | - |
59 | | - const { ref: scrollRef, onOpenChange: onOpenChangeInternal } = |
60 | | - usePickerScrollOnOpen({ |
61 | | - getInitialScrollPosition, |
62 | | - onScroll, |
63 | | - onOpenChange, |
64 | | - }); |
65 | | - |
66 | | - // Spectrum Picker treats keys as strings if the `key` prop is explicitly |
67 | | - // set on `Item` elements. Since we do this in `renderItem`, we need to |
68 | | - // map original key types to and from strings so that selection works. |
69 | | - const { |
70 | | - selectedStringKey, |
71 | | - defaultSelectedStringKey, |
72 | | - disabledStringKeys, |
73 | | - onStringSelectionChange, |
74 | | - } = useStringifiedSelection({ |
75 | | - normalizedItems, |
76 | | - selectedKey, |
77 | | - defaultSelectedKey, |
78 | | - disabledKeys, |
79 | | - onChange: onChange ?? onSelectionChange, |
80 | | - }); |
| 16 | + const { forceRerenderKey, ...pickerProps } = usePickerNormalizedProps< |
| 17 | + PickerNormalizedProps, |
| 18 | + HTMLDivElement |
| 19 | + >(props); |
81 | 20 |
|
82 | 21 | return ( |
83 | 22 | <SpectrumPicker |
84 | 23 | // eslint-disable-next-line react/jsx-props-no-spreading |
85 | | - {...props} |
| 24 | + {...pickerProps} |
86 | 25 | key={forceRerenderKey} |
87 | | - ref={scrollRef as DOMRef<HTMLDivElement>} |
88 | 26 | UNSAFE_className={cl( |
89 | 27 | 'dh-picker', |
90 | 28 | 'dh-picker-normalized', |
91 | 29 | UNSAFE_className |
92 | 30 | )} |
93 | | - items={normalizedItems} |
94 | | - selectedKey={selectedStringKey} |
95 | | - defaultSelectedKey={defaultSelectedStringKey} |
96 | | - disabledKeys={disabledStringKeys} |
97 | | - onSelectionChange={onStringSelectionChange} |
98 | | - onOpenChange={onOpenChangeInternal} |
99 | | - > |
100 | | - {itemOrSection => { |
101 | | - if (isNormalizedSection(itemOrSection)) { |
102 | | - return ( |
103 | | - <Section |
104 | | - key={getItemKey(itemOrSection)} |
105 | | - title={itemOrSection.item?.title} |
106 | | - items={itemOrSection.item?.items} |
107 | | - > |
108 | | - {renderNormalizedItem} |
109 | | - </Section> |
110 | | - ); |
111 | | - } |
112 | | - |
113 | | - return renderNormalizedItem(itemOrSection); |
114 | | - }} |
115 | | - </SpectrumPicker> |
| 31 | + /> |
116 | 32 | ); |
117 | 33 | } |
118 | 34 |
|
|
0 commit comments