@@ -21,6 +21,95 @@ import { useControlledValue, useEventCallback, useMergeRefs } from './hooks';
2121import { createFC } from './common' ;
2222import { Bivariant } from './typeUtils' ;
2323
24+ /**
25+ * Recursively collect option values from PicklistItem components
26+ */
27+ function collectOptionValues ( children : unknown ) : PicklistValue [ ] {
28+ return React . Children . map ( children , ( child ) => {
29+ if ( ! React . isValidElement ( child ) ) {
30+ return [ ] ;
31+ }
32+
33+ const props = child . props ;
34+ const isPropsObject = typeof props === 'object' && props !== null ;
35+
36+ if ( ! isPropsObject ) {
37+ return [ ] ;
38+ }
39+
40+ // Recursively check children for nested PicklistItems
41+ if ( child . type !== PicklistItem ) {
42+ return ! ( 'children' in props ) ? [ ] : collectOptionValues ( props . children ) ;
43+ }
44+
45+ // Check if this is specifically a PicklistItem component
46+ if (
47+ ! ( 'value' in props ) ||
48+ ( typeof props . value !== 'string' && typeof props . value !== 'number' )
49+ ) {
50+ return [ ] ;
51+ }
52+
53+ return [ props . value ] ;
54+ } ) . flat ( ) ;
55+ }
56+
57+ /**
58+ * Recursively find selected item label from PicklistItem components
59+ */
60+ function findSelectedItemLabel (
61+ children : unknown ,
62+ selectedValue : PicklistValue
63+ ) : React . ReactNode | null {
64+ return (
65+ React . Children . map ( children , ( child ) => {
66+ if ( ! React . isValidElement ( child ) ) {
67+ return null ;
68+ }
69+
70+ const props = child . props ;
71+ const isPropsObject = typeof props === 'object' && props !== null ;
72+
73+ if ( ! isPropsObject ) {
74+ return null ;
75+ }
76+
77+ // Recursively check children for nested PicklistItems
78+ if ( child . type !== PicklistItem ) {
79+ return ! ( 'children' in props )
80+ ? null
81+ : findSelectedItemLabel ( props . children , selectedValue ) ;
82+ }
83+
84+ // Check if this is specifically a PicklistItem component
85+ if ( ! ( 'value' in props ) || props . value !== selectedValue ) {
86+ return null ;
87+ }
88+
89+ // Safely access label and children properties with proper type checking
90+ const label = 'label' in props ? props . label : undefined ;
91+ const itemChildren = 'children' in props ? props . children : undefined ;
92+
93+ // Simple type check for React.ReactNode values
94+ const labelValue =
95+ typeof label === 'string' ||
96+ typeof label === 'number' ||
97+ React . isValidElement ( label )
98+ ? label
99+ : undefined ;
100+ const childrenValue =
101+ typeof itemChildren === 'string' ||
102+ typeof itemChildren === 'number' ||
103+ React . isValidElement ( itemChildren ) ||
104+ Array . isArray ( itemChildren )
105+ ? itemChildren
106+ : undefined ;
107+
108+ return labelValue || childrenValue ;
109+ } ) . find ( ( result ) => result !== null ) ?? null
110+ ) ;
111+ }
112+
24113/**
25114 *
26115 */
@@ -161,26 +250,9 @@ export const Picklist: (<MultiSelect extends boolean | undefined>(
161250
162251 const { getActiveElement } = useContext ( ComponentSettingsContext ) ;
163252
164- // Get option values from children
253+ // Get option values from children (recursively)
165254 const getOptionValues = useCallback ( ( ) => {
166- const optionValues : PicklistValue [ ] = [ ] ;
167- React . Children . forEach ( children , ( child ) => {
168- if ( ! React . isValidElement ( child ) ) {
169- return ;
170- }
171-
172- const props : unknown = child . props ;
173- const isPropsObject = typeof props === 'object' && props !== null ;
174-
175- if (
176- isPropsObject &&
177- 'value' in props &&
178- ( typeof props . value === 'string' || typeof props . value === 'number' )
179- ) {
180- optionValues . push ( props . value ) ;
181- }
182- } ) ;
183- return optionValues ;
255+ return collectOptionValues ( children ) ;
184256 } , [ children ] ) ;
185257
186258 // Get next option value for keyboard navigation
@@ -414,15 +486,7 @@ export const Picklist: (<MultiSelect extends boolean | undefined>(
414486 // one item
415487 if ( values . length === 1 ) {
416488 const selectedValue = values [ 0 ] ;
417- let selected = null ;
418- React . Children . forEach ( children , ( item ) => {
419- if ( React . isValidElement ( item ) ) {
420- const { label, value, children } = item . props as PicklistItemProps ;
421- if ( value === selectedValue ) {
422- selected = label || children ;
423- }
424- }
425- } ) ;
489+ const selected = findSelectedItemLabel ( children , selectedValue ) ;
426490 return selected || selectedValue ;
427491 }
428492
0 commit comments