({props, collection, comboBoxRef: ref}: ComboBoxInnerProps<T>)
| 183 | } |
| 184 | |
| 185 | function ComboBoxInner<T>({props, collection, comboBoxRef: ref}: ComboBoxInnerProps<T>) { |
| 186 | let {name, formValue = 'key', allowsCustomValue} = props; |
| 187 | if (allowsCustomValue) { |
| 188 | formValue = 'text'; |
| 189 | } |
| 190 | |
| 191 | let {validationBehavior: formValidationBehavior} = useSlottedContext(FormContext) || {}; |
| 192 | let validationBehavior = props.validationBehavior ?? formValidationBehavior ?? 'native'; |
| 193 | let {contains} = useFilter({sensitivity: 'base'}); |
| 194 | let state = useComboBoxState({ |
| 195 | ...props, |
| 196 | defaultFilter: props.defaultFilter || contains, |
| 197 | // If props.items isn't provided, rely on collection filtering (aka listbox.items is provided or defaultItems provided to Combobox) |
| 198 | items: props.items, |
| 199 | children: undefined, |
| 200 | collection, |
| 201 | validationBehavior |
| 202 | }); |
| 203 | |
| 204 | let buttonRef = useRef<HTMLButtonElement>(null); |
| 205 | let inputRef = useRef<HTMLInputElement>(null); |
| 206 | let groupRef = useRef<HTMLDivElement>(null); |
| 207 | let listBoxRef = useRef<HTMLDivElement>(null); |
| 208 | let popoverRef = useRef<HTMLDivElement>(null); |
| 209 | let [labelRef, label] = useSlot(!props['aria-label'] && !props['aria-labelledby']); |
| 210 | let { |
| 211 | buttonProps, |
| 212 | inputProps, |
| 213 | listBoxProps, |
| 214 | labelProps, |
| 215 | descriptionProps, |
| 216 | errorMessageProps, |
| 217 | valueProps, |
| 218 | ...validation |
| 219 | } = useComboBox( |
| 220 | { |
| 221 | ...removeDataAttributes(props), |
| 222 | label, |
| 223 | inputRef, |
| 224 | buttonRef, |
| 225 | listBoxRef, |
| 226 | popoverRef, |
| 227 | name: formValue === 'text' ? name : undefined, |
| 228 | validationBehavior |
| 229 | }, |
| 230 | state |
| 231 | ); |
| 232 | |
| 233 | // Make menu width match input + button |
| 234 | // Left for backward compatibility in case a <Group> is not rendered. |
| 235 | let [menuWidth, setMenuWidth] = useState<string | null>(null); |
| 236 | let onResize = useCallback(() => { |
| 237 | if (inputRef.current && !groupRef.current) { |
| 238 | let buttonRect = buttonRef.current?.getBoundingClientRect(); |
| 239 | let inputRect = inputRef.current.getBoundingClientRect(); |
| 240 | let minX = buttonRect ? Math.min(buttonRect.left, inputRect.left) : inputRect.left; |
| 241 | let maxX = buttonRect ? Math.max(buttonRect.right, inputRect.right) : inputRect.right; |
| 242 | setMenuWidth(maxX - minX + 'px'); |
nothing calls this directly
no test coverage detected