1- import { useMemo } from 'react' ;
2- import { Item , Picker as SpectrumPicker } from '@adobe/react-spectrum' ;
1+ import { Key , useCallback , useMemo } from 'react' ;
2+ import { Picker as SpectrumPicker } from '@adobe/react-spectrum' ;
3+ import cl from 'classnames' ;
34import { Tooltip } from '../../popper' ;
45import {
56 NormalizedSpectrumPickerProps ,
67 normalizePickerItemList ,
78 normalizeTooltipOptions ,
8- PickerItem ,
9+ PickerItemOrSection ,
910 PickerItemKey ,
1011 TooltipOptions ,
12+ NormalizedPickerItem ,
13+ isNormalizedPickerSection ,
1114} from './PickerUtils' ;
1215import { PickerItemContent } from './PickerItemContent' ;
16+ import { Item } from '../Item' ;
17+ import { Section } from '../Section' ;
1318
1419export type PickerProps = {
15- children : PickerItem | PickerItem [ ] ;
20+ children : PickerItemOrSection | PickerItemOrSection [ ] ;
1621 /** Can be set to true or a TooltipOptions to enable item tooltips */
1722 tooltip ?: boolean | TooltipOptions ;
1823 /** The currently selected key in the collection (controlled). */
@@ -54,11 +59,13 @@ export type PickerProps = {
5459 */
5560export function Picker ( {
5661 children,
57- tooltip,
62+ tooltip = true ,
5863 defaultSelectedKey,
5964 selectedKey,
6065 onChange,
6166 onSelectionChange,
67+ // eslint-disable-next-line camelcase
68+ UNSAFE_className,
6269 ...spectrumPickerProps
6370} : PickerProps ) : JSX . Element {
6471 const normalizedItems = useMemo (
@@ -71,10 +78,29 @@ export function Picker({
7178 [ tooltip ]
7279 ) ;
7380
81+ const renderItem = useCallback (
82+ ( { key, content, textValue } : NormalizedPickerItem ) => (
83+ // The `textValue` prop gets used to provide the content of `<option>`
84+ // elements that back the Spectrum Picker. These are not visible in the UI,
85+ // but are used for accessibility purposes, so we set to an arbitrary
86+ // 'Empty' value so that they are not empty strings.
87+ < Item key = { key as Key } textValue = { textValue === '' ? 'Empty' : textValue } >
88+ < PickerItemContent > { content } </ PickerItemContent >
89+ { tooltipOptions == null || content === '' ? null : (
90+ < Tooltip options = { tooltipOptions } >
91+ { typeof content === 'boolean' ? String ( content ) : content }
92+ </ Tooltip >
93+ ) }
94+ </ Item >
95+ ) ,
96+ [ tooltipOptions ]
97+ ) ;
98+
7499 return (
75100 < SpectrumPicker
76101 // eslint-disable-next-line react/jsx-props-no-spreading
77102 { ...spectrumPickerProps }
103+ UNSAFE_className = { cl ( 'dh-picker' , UNSAFE_className ) }
78104 items = { normalizedItems }
79105 // Type assertions are necessary for `selectedKey`, `defaultSelectedKey`,
80106 // and `onSelectionChange` due to Spectrum types not accounting for
@@ -89,14 +115,21 @@ export function Picker({
89115 onSelectionChange ) as NormalizedSpectrumPickerProps [ 'onSelectionChange' ]
90116 }
91117 >
92- { ( { content, textValue } ) => (
93- < Item textValue = { textValue === '' ? 'Empty' : textValue } >
94- < PickerItemContent > { content } </ PickerItemContent >
95- { tooltipOptions == null || content === '' ? null : (
96- < Tooltip options = { tooltipOptions } > { content } </ Tooltip >
97- ) }
98- </ Item >
99- ) }
118+ { itemOrSection => {
119+ if ( isNormalizedPickerSection ( itemOrSection ) ) {
120+ return (
121+ < Section
122+ key = { itemOrSection . key }
123+ title = { itemOrSection . title }
124+ items = { itemOrSection . items }
125+ >
126+ { renderItem }
127+ </ Section >
128+ ) ;
129+ }
130+
131+ return renderItem ( itemOrSection ) ;
132+ } }
100133 </ SpectrumPicker >
101134 ) ;
102135}
0 commit comments