@@ -17,7 +17,7 @@ import { FormElement, FormElementProps } from './FormElement';
17
17
import { Icon } from './Icon' ;
18
18
import { AutoAlign , RectangleAlignment } from './AutoAlign' ;
19
19
import { DropdownMenuProps } from './DropdownMenu' ;
20
- import { isElInChildren } from './util' ;
20
+ import { registerStyle , isElInChildren } from './util' ;
21
21
import { ComponentSettingsContext } from './ComponentSettings' ;
22
22
import { useControlledValue , useEventCallback , useMergeRefs } from './hooks' ;
23
23
import { createFC } from './common' ;
@@ -67,7 +67,7 @@ function collectOptionValues(children: unknown): PicklistValue[] {
67
67
function findSelectedItemLabel (
68
68
children : unknown ,
69
69
selectedValue : PicklistValue
70
- ) : React . ReactNode | null {
70
+ ) : string | number | null {
71
71
return (
72
72
React . Children . map ( children , ( child ) => {
73
73
if ( ! React . isValidElement ( child ) ) {
@@ -107,21 +107,56 @@ function findSelectedItemLabel(
107
107
typeof label === 'string' ||
108
108
typeof label === 'number' ||
109
109
React . isValidElement ( label )
110
- ? label
110
+ ? extractTextContent ( label )
111
111
: undefined ;
112
112
const childrenValue =
113
113
typeof itemChildren === 'string' ||
114
114
typeof itemChildren === 'number' ||
115
115
React . isValidElement ( itemChildren ) ||
116
116
Array . isArray ( itemChildren )
117
- ? itemChildren
117
+ ? extractTextContent ( itemChildren )
118
118
: undefined ;
119
119
120
120
return labelValue || childrenValue ;
121
121
} ) . find ( ( result ) => result !== null ) ?? null
122
122
) ;
123
123
}
124
124
125
+ /**
126
+ * Extract text content from React node recursively
127
+ */
128
+ function extractTextContent ( node : unknown ) : string | number | null {
129
+ if ( node == null ) {
130
+ return null ;
131
+ }
132
+
133
+ if ( typeof node === 'string' || typeof node === 'number' ) {
134
+ return node ;
135
+ }
136
+
137
+ if ( typeof node === 'boolean' ) {
138
+ return String ( node ) ;
139
+ }
140
+
141
+ if ( Array . isArray ( node ) ) {
142
+ return node
143
+ . map ( extractTextContent )
144
+ . filter ( ( result ) => result !== null )
145
+ . join ( '' ) ;
146
+ }
147
+
148
+ if (
149
+ React . isValidElement ( node ) &&
150
+ node . props &&
151
+ typeof node . props === 'object' &&
152
+ 'children' in node . props
153
+ ) {
154
+ return extractTextContent ( node . props . children ) ;
155
+ }
156
+
157
+ return null ;
158
+ }
159
+
125
160
/**
126
161
*
127
162
*/
@@ -150,6 +185,17 @@ const PicklistContext = createContext<{
150
185
optionIdPrefix : '' ,
151
186
} ) ;
152
187
188
+ /**
189
+ *
190
+ */
191
+ function useInitComponentStyle ( ) {
192
+ useEffect ( ( ) => {
193
+ registerStyle ( 'picklist' , [
194
+ [ '.react-picklist-input:not(:disabled)' , '{ cursor: pointer; }' ] ,
195
+ ] ) ;
196
+ } , [ ] ) ;
197
+ }
198
+
153
199
/**
154
200
*
155
201
*/
@@ -174,7 +220,7 @@ export type PicklistProps<MultiSelect extends boolean | undefined> = {
174
220
tooltip ?: ReactNode ;
175
221
tooltipIcon ?: string ;
176
222
elementRef ?: Ref < HTMLDivElement > ;
177
- inputRef ?: Ref < HTMLDivElement > ;
223
+ inputRef ?: Ref < HTMLInputElement > ;
178
224
dropdownRef ?: Ref < HTMLDivElement > ;
179
225
onValueChange ?: Bivariant <
180
226
(
@@ -227,6 +273,8 @@ export const Picklist: (<MultiSelect extends boolean | undefined>(
227
273
...rprops
228
274
} = props ;
229
275
276
+ useInitComponentStyle ( ) ;
277
+
230
278
const fallbackId = useId ( ) ;
231
279
const id = id_ ?? fallbackId ;
232
280
const listboxId = `${ id } -listbox` ;
@@ -338,7 +386,7 @@ export const Picklist: (<MultiSelect extends boolean | undefined>(
338
386
339
387
const elRef = useRef < HTMLDivElement | null > ( null ) ;
340
388
const elementRef = useMergeRefs ( [ elRef , elementRef_ ] ) ;
341
- const comboboxElRef = useRef < HTMLDivElement | null > ( null ) ;
389
+ const comboboxElRef = useRef < HTMLInputElement | null > ( null ) ;
342
390
const inputRef = useMergeRefs ( [ comboboxElRef , inputRef_ ] ) ;
343
391
const dropdownElRef = useRef < HTMLDivElement | null > ( null ) ;
344
392
const dropdownRef = useMergeRefs ( [ dropdownElRef , dropdownRef_ ] ) ;
@@ -522,6 +570,7 @@ export const Picklist: (<MultiSelect extends boolean | undefined>(
522
570
}
523
571
) ;
524
572
const inputClassNames = classnames (
573
+ 'react-picklist-input' ,
525
574
'slds-input_faux' ,
526
575
'slds-combobox__input' ,
527
576
{
@@ -572,7 +621,8 @@ export const Picklist: (<MultiSelect extends boolean | undefined>(
572
621
className = 'slds-combobox__form-element slds-input-has-icon slds-input-has-icon_right'
573
622
role = 'none'
574
623
>
575
- < div
624
+ < input
625
+ type = 'text'
576
626
ref = { inputRef }
577
627
role = 'combobox'
578
628
tabIndex = { disabled ? - 1 : 0 }
@@ -588,9 +638,10 @@ export const Picklist: (<MultiSelect extends boolean | undefined>(
588
638
onKeyDown = { onKeyDown }
589
639
onBlur = { onBlur }
590
640
{ ...rprops }
591
- >
592
- < span className = 'slds-truncate' > { selectedItemLabel } </ span >
593
- </ div >
641
+ value = { selectedItemLabel }
642
+ readOnly
643
+ disabled = { disabled }
644
+ />
594
645
< Icon
595
646
containerClassName = 'slds-input__icon slds-input__icon_right'
596
647
category = 'utility'
0 commit comments