@limonify/zest-ui 0.3.2 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/lib/alert-dialog/index.parts.d.ts +1 -1
- package/lib/alert-dialog/index.parts.d.ts.map +1 -1
- package/lib/alert-dialog/index.parts.js.map +1 -1
- package/lib/autocomplete/handle.d.ts +15 -0
- package/lib/autocomplete/handle.d.ts.map +1 -0
- package/lib/autocomplete/handle.js +12 -0
- package/lib/autocomplete/handle.js.map +1 -0
- package/lib/autocomplete/index.d.ts +1 -0
- package/lib/autocomplete/index.d.ts.map +1 -1
- package/lib/autocomplete/index.parts.d.ts +1 -0
- package/lib/autocomplete/index.parts.d.ts.map +1 -1
- package/lib/autocomplete/index.parts.js +3 -1
- package/lib/autocomplete/index.parts.js.map +1 -1
- package/lib/autocomplete/root/AutocompleteRoot.d.ts +55 -16
- package/lib/autocomplete/root/AutocompleteRoot.d.ts.map +1 -1
- package/lib/autocomplete/root/AutocompleteRoot.js +2 -18
- package/lib/autocomplete/root/AutocompleteRoot.js.map +1 -1
- package/lib/avatar/fallback/AvatarFallback.d.ts.map +1 -1
- package/lib/avatar/fallback/AvatarFallback.js +3 -1
- package/lib/avatar/fallback/AvatarFallback.js.map +1 -1
- package/lib/avatar/image/AvatarImage.d.ts.map +1 -1
- package/lib/avatar/image/AvatarImage.js +5 -0
- package/lib/avatar/image/AvatarImage.js.map +1 -1
- package/lib/checkbox/root/CheckboxRoot.d.ts.map +1 -1
- package/lib/checkbox/root/CheckboxRoot.js +9 -4
- package/lib/checkbox/root/CheckboxRoot.js.map +1 -1
- package/lib/combobox/backdrop/ComboboxBackdrop.d.ts.map +1 -1
- package/lib/combobox/backdrop/ComboboxBackdrop.js +10 -4
- package/lib/combobox/backdrop/ComboboxBackdrop.js.map +1 -1
- package/lib/combobox/empty/ComboboxEmpty.d.ts.map +1 -1
- package/lib/combobox/empty/ComboboxEmpty.js +4 -1
- package/lib/combobox/empty/ComboboxEmpty.js.map +1 -1
- package/lib/combobox/index.d.ts +2 -0
- package/lib/combobox/index.d.ts.map +1 -1
- package/lib/combobox/index.js +3 -1
- package/lib/combobox/index.js.map +1 -1
- package/lib/combobox/index.parts.d.ts +1 -0
- package/lib/combobox/index.parts.d.ts.map +1 -1
- package/lib/combobox/index.parts.js +4 -1
- package/lib/combobox/index.parts.js.map +1 -1
- package/lib/combobox/input/ComboboxInput.d.ts +24 -3
- package/lib/combobox/input/ComboboxInput.d.ts.map +1 -1
- package/lib/combobox/input/ComboboxInput.js +65 -11
- package/lib/combobox/input/ComboboxInput.js.map +1 -1
- package/lib/combobox/item/ComboboxItem.d.ts +11 -1
- package/lib/combobox/item/ComboboxItem.d.ts.map +1 -1
- package/lib/combobox/item/ComboboxItem.js +9 -6
- package/lib/combobox/item/ComboboxItem.js.map +1 -1
- package/lib/combobox/list/ComboboxList.d.ts +1 -1
- package/lib/combobox/list/ComboboxList.d.ts.map +1 -1
- package/lib/combobox/list/ComboboxList.js +4 -1
- package/lib/combobox/list/ComboboxList.js.map +1 -1
- package/lib/combobox/popup/ComboboxPopup.d.ts +26 -0
- package/lib/combobox/popup/ComboboxPopup.d.ts.map +1 -1
- package/lib/combobox/popup/ComboboxPopup.js +18 -2
- package/lib/combobox/popup/ComboboxPopup.js.map +1 -1
- package/lib/combobox/portal/ComboboxPortal.d.ts.map +1 -1
- package/lib/combobox/portal/ComboboxPortal.js +8 -4
- package/lib/combobox/portal/ComboboxPortal.js.map +1 -1
- package/lib/combobox/portal/ComboboxPortalContext.d.ts +4 -0
- package/lib/combobox/portal/ComboboxPortalContext.d.ts.map +1 -0
- package/lib/combobox/portal/ComboboxPortalContext.js +48 -0
- package/lib/combobox/portal/ComboboxPortalContext.js.map +1 -0
- package/lib/combobox/positioner/ComboboxPositioner.d.ts +7 -2
- package/lib/combobox/positioner/ComboboxPositioner.d.ts.map +1 -1
- package/lib/combobox/positioner/ComboboxPositioner.js +61 -6
- package/lib/combobox/positioner/ComboboxPositioner.js.map +1 -1
- package/lib/combobox/positioner/ComboboxPositionerContext.d.ts +9 -0
- package/lib/combobox/positioner/ComboboxPositionerContext.d.ts.map +1 -0
- package/lib/combobox/positioner/ComboboxPositionerContext.js +48 -0
- package/lib/combobox/positioner/ComboboxPositionerContext.js.map +1 -0
- package/lib/combobox/root/ComboboxItemsContext.d.ts +18 -0
- package/lib/combobox/root/ComboboxItemsContext.d.ts.map +1 -0
- package/lib/combobox/root/ComboboxItemsContext.js +55 -0
- package/lib/combobox/root/ComboboxItemsContext.js.map +1 -0
- package/lib/combobox/root/ComboboxRoot.d.ts +77 -21
- package/lib/combobox/root/ComboboxRoot.d.ts.map +1 -1
- package/lib/combobox/root/ComboboxRoot.js +4 -23
- package/lib/combobox/root/ComboboxRoot.js.map +1 -1
- package/lib/combobox/root/ComboboxRootContext.d.ts +4 -54
- package/lib/combobox/root/ComboboxRootContext.d.ts.map +1 -1
- package/lib/combobox/root/ComboboxRootContext.js.map +1 -1
- package/lib/combobox/root/ComboboxTransitionContext.d.ts +8 -0
- package/lib/combobox/root/ComboboxTransitionContext.d.ts.map +1 -0
- package/lib/combobox/root/ComboboxTransitionContext.js +44 -0
- package/lib/combobox/root/ComboboxTransitionContext.js.map +1 -0
- package/lib/combobox/root/useRenderComboboxRoot.d.ts +39 -0
- package/lib/combobox/root/useRenderComboboxRoot.d.ts.map +1 -0
- package/lib/combobox/root/useRenderComboboxRoot.js +136 -0
- package/lib/combobox/root/useRenderComboboxRoot.js.map +1 -0
- package/lib/combobox/store/ComboboxHandle.d.ts +42 -0
- package/lib/combobox/store/ComboboxHandle.d.ts.map +1 -0
- package/lib/combobox/store/ComboboxHandle.js +65 -0
- package/lib/combobox/store/ComboboxHandle.js.map +1 -0
- package/lib/combobox/store/ComboboxStore.d.ts +147 -0
- package/lib/combobox/store/ComboboxStore.d.ts.map +1 -0
- package/lib/combobox/store/ComboboxStore.js +127 -0
- package/lib/combobox/store/ComboboxStore.js.map +1 -0
- package/lib/combobox/value/ComboboxValue.d.ts.map +1 -1
- package/lib/combobox/value/ComboboxValue.js +2 -1
- package/lib/combobox/value/ComboboxValue.js.map +1 -1
- package/lib/context-menu/positioner/ContextMenuPositioner.d.ts +19 -3
- package/lib/context-menu/positioner/ContextMenuPositioner.d.ts.map +1 -1
- package/lib/context-menu/positioner/ContextMenuPositioner.js +56 -7
- package/lib/context-menu/positioner/ContextMenuPositioner.js.map +1 -1
- package/lib/context-menu/root/ContextMenuRoot.d.ts +8 -0
- package/lib/context-menu/root/ContextMenuRoot.d.ts.map +1 -1
- package/lib/dialog/backdrop/DialogBackdrop.d.ts +9 -0
- package/lib/dialog/backdrop/DialogBackdrop.d.ts.map +1 -1
- package/lib/dialog/backdrop/DialogBackdrop.js +3 -1
- package/lib/dialog/backdrop/DialogBackdrop.js.map +1 -1
- package/lib/dialog/popup/DialogPopup.d.ts +9 -0
- package/lib/dialog/popup/DialogPopup.d.ts.map +1 -1
- package/lib/dialog/popup/DialogPopup.js +2 -2
- package/lib/dialog/popup/DialogPopup.js.map +1 -1
- package/lib/dialog/popup/useDialogPopupProps.d.ts +2 -0
- package/lib/dialog/popup/useDialogPopupProps.d.ts.map +1 -1
- package/lib/dialog/popup/useDialogPopupProps.js +4 -0
- package/lib/dialog/popup/useDialogPopupProps.js.map +1 -1
- package/lib/dialog/root/DialogNestingContext.d.ts +20 -0
- package/lib/dialog/root/DialogNestingContext.d.ts.map +1 -0
- package/lib/dialog/root/DialogNestingContext.js +53 -0
- package/lib/dialog/root/DialogNestingContext.js.map +1 -0
- package/lib/dialog/root/useRenderDialogRoot.d.ts.map +1 -1
- package/lib/dialog/root/useRenderDialogRoot.js +26 -2
- package/lib/dialog/root/useRenderDialogRoot.js.map +1 -1
- package/lib/dialog/store/DialogStore.d.ts +19 -2
- package/lib/dialog/store/DialogStore.d.ts.map +1 -1
- package/lib/dialog/store/DialogStore.js +14 -2
- package/lib/dialog/store/DialogStore.js.map +1 -1
- package/lib/drawer/index.parts.d.ts +1 -1
- package/lib/drawer/index.parts.d.ts.map +1 -1
- package/lib/drawer/index.parts.js.map +1 -1
- package/lib/drawer/popup/DrawerPopup.d.ts +9 -0
- package/lib/drawer/popup/DrawerPopup.d.ts.map +1 -1
- package/lib/drawer/popup/DrawerPopup.js +3 -1
- package/lib/drawer/popup/DrawerPopup.js.map +1 -1
- package/lib/filter/index.d.ts +2 -0
- package/lib/filter/index.d.ts.map +1 -0
- package/lib/filter/index.js +6 -0
- package/lib/filter/index.js.map +1 -0
- package/lib/filter/useFilter.d.ts +45 -0
- package/lib/filter/useFilter.d.ts.map +1 -0
- package/lib/filter/useFilter.js +96 -0
- package/lib/filter/useFilter.js.map +1 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/internals/field/useFieldControlRegistration.d.ts +25 -6
- package/lib/internals/field/useFieldControlRegistration.d.ts.map +1 -1
- package/lib/internals/field/useFieldControlRegistration.js +93 -6
- package/lib/internals/field/useFieldControlRegistration.js.map +1 -1
- package/lib/menu/popup/MenuPopup.d.ts +10 -0
- package/lib/menu/popup/MenuPopup.d.ts.map +1 -1
- package/lib/menu/popup/MenuPopup.js +10 -1
- package/lib/menu/popup/MenuPopup.js.map +1 -1
- package/lib/menu/positioner/MenuPositioner.d.ts +10 -0
- package/lib/menu/positioner/MenuPositioner.d.ts.map +1 -1
- package/lib/menu/positioner/MenuPositioner.js +9 -1
- package/lib/menu/positioner/MenuPositioner.js.map +1 -1
- package/lib/menu/store/MenuStore.d.ts +11 -0
- package/lib/menu/store/MenuStore.d.ts.map +1 -1
- package/lib/menu/store/MenuStore.js +4 -0
- package/lib/menu/store/MenuStore.js.map +1 -1
- package/lib/menu/submenu-trigger/MenuSubmenuTrigger.d.ts.map +1 -1
- package/lib/menu/submenu-trigger/MenuSubmenuTrigger.js +3 -0
- package/lib/menu/submenu-trigger/MenuSubmenuTrigger.js.map +1 -1
- package/lib/menu/trigger/MenuTrigger.d.ts.map +1 -1
- package/lib/menu/trigger/MenuTrigger.js +4 -1
- package/lib/menu/trigger/MenuTrigger.js.map +1 -1
- package/lib/meter/indicator/MeterIndicator.d.ts +2 -1
- package/lib/meter/indicator/MeterIndicator.d.ts.map +1 -1
- package/lib/meter/indicator/MeterIndicator.js +1 -2
- package/lib/meter/indicator/MeterIndicator.js.map +1 -1
- package/lib/meter/label/MeterLabel.d.ts +2 -1
- package/lib/meter/label/MeterLabel.d.ts.map +1 -1
- package/lib/meter/label/MeterLabel.js +1 -2
- package/lib/meter/label/MeterLabel.js.map +1 -1
- package/lib/meter/root/MeterRoot.d.ts +21 -0
- package/lib/meter/root/MeterRoot.d.ts.map +1 -1
- package/lib/meter/root/MeterRoot.js +2 -2
- package/lib/meter/root/MeterRoot.js.map +1 -1
- package/lib/meter/root/MeterRootContext.d.ts +5 -0
- package/lib/meter/root/MeterRootContext.d.ts.map +1 -1
- package/lib/meter/root/MeterRootContext.js.map +1 -1
- package/lib/meter/track/MeterTrack.d.ts +2 -1
- package/lib/meter/track/MeterTrack.d.ts.map +1 -1
- package/lib/meter/track/MeterTrack.js +1 -2
- package/lib/meter/track/MeterTrack.js.map +1 -1
- package/lib/meter/value/MeterValue.d.ts +2 -1
- package/lib/meter/value/MeterValue.d.ts.map +1 -1
- package/lib/meter/value/MeterValue.js +1 -2
- package/lib/meter/value/MeterValue.js.map +1 -1
- package/lib/number-field/input/NumberFieldInput.d.ts.map +1 -1
- package/lib/number-field/input/NumberFieldInput.js +11 -2
- package/lib/number-field/input/NumberFieldInput.js.map +1 -1
- package/lib/number-field/root/NumberFieldRoot.d.ts.map +1 -1
- package/lib/number-field/root/NumberFieldRoot.js +5 -2
- package/lib/number-field/root/NumberFieldRoot.js.map +1 -1
- package/lib/otp-field/input/OTPFieldInput.d.ts.map +1 -1
- package/lib/otp-field/input/OTPFieldInput.js +4 -0
- package/lib/otp-field/input/OTPFieldInput.js.map +1 -1
- package/lib/otp-field/root/OTPFieldRoot.d.ts.map +1 -1
- package/lib/otp-field/root/OTPFieldRoot.js +20 -2
- package/lib/otp-field/root/OTPFieldRoot.js.map +1 -1
- package/lib/popover/popup/PopoverPopup.d.ts +10 -0
- package/lib/popover/popup/PopoverPopup.d.ts.map +1 -1
- package/lib/popover/popup/PopoverPopup.js +10 -1
- package/lib/popover/popup/PopoverPopup.js.map +1 -1
- package/lib/popover/positioner/PopoverPositioner.d.ts +10 -0
- package/lib/popover/positioner/PopoverPositioner.d.ts.map +1 -1
- package/lib/popover/positioner/PopoverPositioner.js +4 -0
- package/lib/popover/positioner/PopoverPositioner.js.map +1 -1
- package/lib/popover/store/PopoverStore.d.ts +11 -0
- package/lib/popover/store/PopoverStore.d.ts.map +1 -1
- package/lib/popover/store/PopoverStore.js +4 -0
- package/lib/popover/store/PopoverStore.js.map +1 -1
- package/lib/popover/trigger/PopoverTrigger.d.ts.map +1 -1
- package/lib/popover/trigger/PopoverTrigger.js +4 -1
- package/lib/popover/trigger/PopoverTrigger.js.map +1 -1
- package/lib/progress/root/ProgressRoot.d.ts +21 -0
- package/lib/progress/root/ProgressRoot.d.ts.map +1 -1
- package/lib/progress/root/ProgressRoot.js +1 -1
- package/lib/progress/root/ProgressRoot.js.map +1 -1
- package/lib/radio-group/RadioGroup.d.ts.map +1 -1
- package/lib/radio-group/RadioGroup.js +5 -2
- package/lib/radio-group/RadioGroup.js.map +1 -1
- package/lib/select/backdrop/SelectBackdrop.d.ts.map +1 -1
- package/lib/select/backdrop/SelectBackdrop.js +3 -0
- package/lib/select/backdrop/SelectBackdrop.js.map +1 -1
- package/lib/select/index.parts.d.ts +1 -0
- package/lib/select/index.parts.d.ts.map +1 -1
- package/lib/select/index.parts.js +4 -1
- package/lib/select/index.parts.js.map +1 -1
- package/lib/select/popup/SelectPopup.d.ts +8 -0
- package/lib/select/popup/SelectPopup.d.ts.map +1 -1
- package/lib/select/popup/SelectPopup.js +10 -1
- package/lib/select/popup/SelectPopup.js.map +1 -1
- package/lib/select/positioner/SelectPositioner.d.ts +4 -0
- package/lib/select/positioner/SelectPositioner.d.ts.map +1 -1
- package/lib/select/positioner/SelectPositioner.js +2 -0
- package/lib/select/positioner/SelectPositioner.js.map +1 -1
- package/lib/select/root/SelectRoot.d.ts +45 -4
- package/lib/select/root/SelectRoot.d.ts.map +1 -1
- package/lib/select/root/SelectRoot.js +43 -5
- package/lib/select/root/SelectRoot.js.map +1 -1
- package/lib/select/store/SelectHandle.d.ts +42 -0
- package/lib/select/store/SelectHandle.d.ts.map +1 -0
- package/lib/select/store/SelectHandle.js +69 -0
- package/lib/select/store/SelectHandle.js.map +1 -0
- package/lib/select/store/SelectStore.d.ts +28 -0
- package/lib/select/store/SelectStore.d.ts.map +1 -1
- package/lib/select/store/SelectStore.js +15 -1
- package/lib/select/store/SelectStore.js.map +1 -1
- package/lib/select/trigger/SelectTrigger.d.ts +18 -3
- package/lib/select/trigger/SelectTrigger.d.ts.map +1 -1
- package/lib/select/trigger/SelectTrigger.js +49 -4
- package/lib/select/trigger/SelectTrigger.js.map +1 -1
- package/lib/slider/root/SliderRoot.d.ts.map +1 -1
- package/lib/slider/root/SliderRoot.js +9 -1
- package/lib/slider/root/SliderRoot.js.map +1 -1
- package/lib/slider/thumb/SliderThumb.d.ts.map +1 -1
- package/lib/slider/thumb/SliderThumb.js +10 -2
- package/lib/slider/thumb/SliderThumb.js.map +1 -1
- package/lib/switch/root/SwitchRoot.d.ts.map +1 -1
- package/lib/switch/root/SwitchRoot.js +6 -2
- package/lib/switch/root/SwitchRoot.js.map +1 -1
- package/lib/tabs/tab/TabsTab.d.ts +2 -10
- package/lib/tabs/tab/TabsTab.d.ts.map +1 -1
- package/lib/tooltip/popup/TooltipPopup.d.ts +10 -0
- package/lib/tooltip/popup/TooltipPopup.d.ts.map +1 -1
- package/lib/tooltip/popup/TooltipPopup.js +10 -1
- package/lib/tooltip/popup/TooltipPopup.js.map +1 -1
- package/lib/tooltip/positioner/TooltipPositioner.d.ts +10 -0
- package/lib/tooltip/positioner/TooltipPositioner.d.ts.map +1 -1
- package/lib/tooltip/positioner/TooltipPositioner.js +4 -0
- package/lib/tooltip/positioner/TooltipPositioner.js.map +1 -1
- package/lib/tooltip/store/TooltipStore.d.ts +11 -0
- package/lib/tooltip/store/TooltipStore.d.ts.map +1 -1
- package/lib/tooltip/store/TooltipStore.js +11 -1
- package/lib/tooltip/store/TooltipStore.js.map +1 -1
- package/lib/tooltip/trigger/TooltipTrigger.d.ts.map +1 -1
- package/lib/tooltip/trigger/TooltipTrigger.js +4 -1
- package/lib/tooltip/trigger/TooltipTrigger.js.map +1 -1
- package/package.json +1 -1
- package/src/alert-dialog/index.parts.ts +1 -1
- package/src/autocomplete/handle.ts +18 -0
- package/src/autocomplete/index.parts.ts +1 -0
- package/src/autocomplete/index.ts +1 -0
- package/src/autocomplete/root/AutocompleteRoot.tsx +65 -50
- package/src/avatar/fallback/AvatarFallback.tsx +3 -1
- package/src/avatar/image/AvatarImage.tsx +5 -0
- package/src/checkbox/root/CheckboxRoot.tsx +7 -2
- package/src/combobox/backdrop/ComboboxBackdrop.tsx +10 -3
- package/src/combobox/empty/ComboboxEmpty.tsx +5 -1
- package/src/combobox/index.parts.ts +1 -0
- package/src/combobox/index.ts +2 -0
- package/src/combobox/input/ComboboxInput.tsx +112 -27
- package/src/combobox/item/ComboboxItem.tsx +24 -6
- package/src/combobox/list/ComboboxList.tsx +7 -2
- package/src/combobox/popup/ComboboxPopup.tsx +44 -2
- package/src/combobox/portal/ComboboxPortal.tsx +19 -13
- package/src/combobox/portal/ComboboxPortalContext.ts +15 -0
- package/src/combobox/positioner/ComboboxPositioner.tsx +45 -10
- package/src/combobox/positioner/ComboboxPositionerContext.ts +23 -0
- package/src/combobox/root/ComboboxItemsContext.ts +32 -0
- package/src/combobox/root/ComboboxRoot.tsx +94 -56
- package/src/combobox/root/ComboboxRootContext.ts +3 -54
- package/src/combobox/root/ComboboxTransitionContext.ts +15 -0
- package/src/combobox/root/useRenderComboboxRoot.tsx +189 -0
- package/src/combobox/store/ComboboxHandle.ts +64 -0
- package/src/combobox/store/ComboboxStore.ts +249 -0
- package/src/combobox/value/ComboboxValue.tsx +2 -1
- package/src/context-menu/positioner/ContextMenuPositioner.tsx +90 -10
- package/src/context-menu/root/ContextMenuRoot.tsx +8 -0
- package/src/dialog/backdrop/DialogBackdrop.tsx +12 -1
- package/src/dialog/popup/DialogPopup.tsx +11 -2
- package/src/dialog/popup/useDialogPopupProps.ts +4 -0
- package/src/dialog/root/DialogNestingContext.ts +27 -0
- package/src/dialog/root/useRenderDialogRoot.tsx +37 -2
- package/src/dialog/store/DialogStore.ts +24 -2
- package/src/drawer/index.parts.ts +1 -1
- package/src/drawer/popup/DrawerPopup.tsx +12 -1
- package/src/filter/index.ts +5 -0
- package/src/filter/useFilter.ts +95 -0
- package/src/index.ts +1 -0
- package/src/internals/field/useFieldControlRegistration.ts +86 -6
- package/src/menu/popup/MenuPopup.tsx +20 -1
- package/src/menu/positioner/MenuPositioner.tsx +19 -1
- package/src/menu/store/MenuStore.ts +13 -0
- package/src/menu/submenu-trigger/MenuSubmenuTrigger.tsx +3 -0
- package/src/menu/trigger/MenuTrigger.tsx +5 -2
- package/src/meter/indicator/MeterIndicator.tsx +3 -4
- package/src/meter/label/MeterLabel.tsx +3 -4
- package/src/meter/root/MeterRoot.tsx +29 -4
- package/src/meter/root/MeterRootContext.ts +5 -0
- package/src/meter/track/MeterTrack.tsx +3 -4
- package/src/meter/value/MeterValue.tsx +3 -4
- package/src/number-field/input/NumberFieldInput.tsx +11 -2
- package/src/number-field/root/NumberFieldRoot.tsx +4 -2
- package/src/otp-field/input/OTPFieldInput.tsx +4 -0
- package/src/otp-field/root/OTPFieldRoot.tsx +22 -2
- package/src/popover/popup/PopoverPopup.tsx +20 -1
- package/src/popover/positioner/PopoverPositioner.tsx +14 -0
- package/src/popover/store/PopoverStore.ts +13 -0
- package/src/popover/trigger/PopoverTrigger.tsx +5 -2
- package/src/progress/root/ProgressRoot.tsx +25 -1
- package/src/radio-group/RadioGroup.tsx +5 -2
- package/src/select/backdrop/SelectBackdrop.tsx +4 -0
- package/src/select/index.parts.ts +1 -0
- package/src/select/popup/SelectPopup.tsx +18 -1
- package/src/select/positioner/SelectPositioner.tsx +9 -3
- package/src/select/root/SelectRoot.tsx +109 -9
- package/src/select/store/SelectHandle.ts +68 -0
- package/src/select/store/SelectStore.ts +38 -1
- package/src/select/trigger/SelectTrigger.tsx +78 -7
- package/src/slider/root/SliderRoot.tsx +11 -1
- package/src/slider/thumb/SliderThumb.tsx +10 -1
- package/src/switch/root/SwitchRoot.tsx +5 -2
- package/src/tabs/tab/TabsTab.tsx +2 -10
- package/src/tooltip/popup/TooltipPopup.tsx +20 -1
- package/src/tooltip/positioner/TooltipPositioner.tsx +14 -0
- package/src/tooltip/store/TooltipStore.ts +20 -1
- package/src/tooltip/trigger/TooltipTrigger.tsx +5 -2
- package/lib/combobox/root/useComboboxRoot.d.ts +0 -29
- package/lib/combobox/root/useComboboxRoot.d.ts.map +0 -1
- package/lib/combobox/root/useComboboxRoot.js +0 -176
- package/lib/combobox/root/useComboboxRoot.js.map +0 -1
- package/lib/utils/fastObjectShallowCompare.d.ts +0 -2
- package/lib/utils/fastObjectShallowCompare.d.ts.map +0 -1
- package/lib/utils/fastObjectShallowCompare.js +0 -29
- package/lib/utils/fastObjectShallowCompare.js.map +0 -1
- package/lib/utils/mergeObjects.d.ts +0 -2
- package/lib/utils/mergeObjects.d.ts.map +0 -1
- package/lib/utils/mergeObjects.js +0 -16
- package/lib/utils/mergeObjects.js.map +0 -1
- package/src/combobox/root/useComboboxRoot.ts +0 -199
- package/src/utils/fastObjectShallowCompare.ts +0 -30
- package/src/utils/mergeObjects.ts +0 -15
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import * as React from 'react';
|
|
3
|
-
import type {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
2
|
+
import type * as React from 'react';
|
|
3
|
+
import type { ZestChangeEventDetails } from '../../utils/createChangeEventDetails';
|
|
4
|
+
import type { REASONS } from '../../utils/reasons';
|
|
5
|
+
import type { ComboboxHandle } from '../store/ComboboxHandle';
|
|
6
|
+
import type { ComboboxItem, ComboboxItems } from '../store/ComboboxStore';
|
|
7
|
+
import { useRenderComboboxRoot } from './useRenderComboboxRoot';
|
|
6
8
|
|
|
7
9
|
/**
|
|
8
10
|
* Groups all parts of the combobox: a text input that filters a list of items,
|
|
@@ -12,50 +14,28 @@ import { useComboboxRoot, type ComboboxItems } from './useComboboxRoot';
|
|
|
12
14
|
* **Adapted from upstream.** Base UI's Combobox is a large component built on a
|
|
13
15
|
* shared collection/filter core with chips, groups, rows and virtualization.
|
|
14
16
|
* This is a focused React Native port: an input, a filtered list, and single
|
|
15
|
-
* selection. Filtering is a
|
|
16
|
-
* `filter` to change it.
|
|
17
|
+
* selection. Filtering is a locale-aware label match by default (see
|
|
18
|
+
* `useFilter`); pass `filter` to change it.
|
|
17
19
|
*/
|
|
18
|
-
export function ComboboxRoot(props: ComboboxRoot.Props) {
|
|
19
|
-
|
|
20
|
-
items,
|
|
21
|
-
value,
|
|
22
|
-
defaultValue,
|
|
23
|
-
onValueChange,
|
|
24
|
-
inputValue,
|
|
25
|
-
defaultInputValue,
|
|
26
|
-
onInputValueChange,
|
|
27
|
-
open,
|
|
28
|
-
defaultOpen,
|
|
29
|
-
onOpenChange,
|
|
30
|
-
openOnFocus,
|
|
31
|
-
filter,
|
|
32
|
-
disabled = false,
|
|
33
|
-
children,
|
|
34
|
-
} = props;
|
|
35
|
-
|
|
36
|
-
const contextValue = useComboboxRoot({
|
|
37
|
-
mode: 'combobox',
|
|
38
|
-
items,
|
|
39
|
-
value,
|
|
40
|
-
defaultValue,
|
|
41
|
-
onValueChange,
|
|
42
|
-
inputValue,
|
|
43
|
-
defaultInputValue,
|
|
44
|
-
onInputValueChange,
|
|
45
|
-
open,
|
|
46
|
-
defaultOpen,
|
|
47
|
-
onOpenChange,
|
|
48
|
-
openOnFocus,
|
|
49
|
-
filter,
|
|
50
|
-
disabled,
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
return <ComboboxRootContext.Provider value={contextValue}>{children}</ComboboxRootContext.Provider>;
|
|
20
|
+
export function ComboboxRoot<Payload = unknown>(props: ComboboxRoot.Props<Payload>) {
|
|
21
|
+
return useRenderComboboxRoot(props, 'combobox');
|
|
54
22
|
}
|
|
55
23
|
|
|
56
24
|
export interface ComboboxRootState {}
|
|
57
25
|
|
|
58
|
-
export interface
|
|
26
|
+
export interface ComboboxRootActions {
|
|
27
|
+
/**
|
|
28
|
+
* Unmounts the list without firing `onOpenChange`. Call it after an
|
|
29
|
+
* externally controlled closing animation finishes.
|
|
30
|
+
*/
|
|
31
|
+
unmount: () => void;
|
|
32
|
+
/**
|
|
33
|
+
* Closes the list, reporting the `imperative-action` reason.
|
|
34
|
+
*/
|
|
35
|
+
close: () => void;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface ComboboxRootProps<Payload = unknown> {
|
|
59
39
|
/**
|
|
60
40
|
* The items to filter and choose from. Strings, or `{ value, label }` records
|
|
61
41
|
* for non-string values.
|
|
@@ -63,16 +43,20 @@ export interface ComboboxRootProps {
|
|
|
63
43
|
items?: ComboboxItems | undefined;
|
|
64
44
|
/**
|
|
65
45
|
* The selected value.
|
|
46
|
+
*
|
|
47
|
+
* To render an uncontrolled combobox, use the `defaultValue` prop instead.
|
|
66
48
|
*/
|
|
67
49
|
value?: unknown;
|
|
68
50
|
/**
|
|
69
|
-
* The initially selected value
|
|
51
|
+
* The initially selected value.
|
|
52
|
+
*
|
|
53
|
+
* To render a controlled combobox, use the `value` prop instead.
|
|
70
54
|
*/
|
|
71
55
|
defaultValue?: unknown;
|
|
72
56
|
/**
|
|
73
|
-
*
|
|
57
|
+
* Event handler called when the selection changes.
|
|
74
58
|
*/
|
|
75
|
-
onValueChange?: ((value:
|
|
59
|
+
onValueChange?: ((value: any, eventDetails: ComboboxRoot.ChangeEventDetails) => void) | undefined;
|
|
76
60
|
/**
|
|
77
61
|
* The controlled input text.
|
|
78
62
|
*/
|
|
@@ -82,39 +66,93 @@ export interface ComboboxRootProps {
|
|
|
82
66
|
*/
|
|
83
67
|
defaultInputValue?: string | undefined;
|
|
84
68
|
/**
|
|
85
|
-
*
|
|
69
|
+
* Event handler called as the input text changes.
|
|
86
70
|
*/
|
|
87
|
-
onInputValueChange?:
|
|
71
|
+
onInputValueChange?:
|
|
72
|
+
| ((value: string, eventDetails: ComboboxRoot.ChangeEventDetails) => void)
|
|
73
|
+
| undefined;
|
|
88
74
|
/**
|
|
89
|
-
* Whether the list is open.
|
|
75
|
+
* Whether the list is currently open.
|
|
90
76
|
*/
|
|
91
77
|
open?: boolean | undefined;
|
|
92
78
|
/**
|
|
93
|
-
* Whether the list is initially open
|
|
79
|
+
* Whether the list is initially open.
|
|
80
|
+
*
|
|
81
|
+
* To render a controlled combobox, use the `open` prop instead.
|
|
82
|
+
* @default false
|
|
94
83
|
*/
|
|
95
84
|
defaultOpen?: boolean | undefined;
|
|
96
85
|
/**
|
|
97
|
-
*
|
|
86
|
+
* Event handler called when the list is opened or closed.
|
|
98
87
|
*/
|
|
99
|
-
onOpenChange?:
|
|
88
|
+
onOpenChange?:
|
|
89
|
+
| ((open: boolean, eventDetails: ComboboxRoot.ChangeEventDetails) => void)
|
|
90
|
+
| undefined;
|
|
100
91
|
/**
|
|
101
92
|
* Whether focusing the input opens the list.
|
|
102
93
|
* @default true
|
|
103
94
|
*/
|
|
104
95
|
openOnFocus?: boolean | undefined;
|
|
105
96
|
/**
|
|
106
|
-
* A custom filter predicate. Defaults to a
|
|
97
|
+
* A custom filter predicate. Defaults to a locale-aware label match, so
|
|
98
|
+
* "resume" finds "Résumé" — see `useFilter` to build your own.
|
|
107
99
|
*/
|
|
108
100
|
filter?: ((item: ComboboxItem, query: string) => boolean) | undefined;
|
|
109
101
|
/**
|
|
110
|
-
* Whether the
|
|
102
|
+
* Whether the component should ignore user interaction.
|
|
111
103
|
* @default false
|
|
112
104
|
*/
|
|
113
105
|
disabled?: boolean | undefined;
|
|
114
|
-
|
|
106
|
+
/**
|
|
107
|
+
* Whether to prevent the list from closing on presses outside the popup.
|
|
108
|
+
* @default false
|
|
109
|
+
*/
|
|
110
|
+
disablePointerDismissal?: boolean | undefined;
|
|
111
|
+
/**
|
|
112
|
+
* A ref to imperative actions.
|
|
113
|
+
*/
|
|
114
|
+
actionsRef?: React.RefObject<ComboboxRoot.Actions | null> | undefined;
|
|
115
|
+
/**
|
|
116
|
+
* A handle associating this combobox with an input rendered outside it, and
|
|
117
|
+
* letting it be opened and closed imperatively. Create one with
|
|
118
|
+
* `Combobox.createHandle()`.
|
|
119
|
+
*/
|
|
120
|
+
handle?: ComboboxHandle | undefined;
|
|
121
|
+
/**
|
|
122
|
+
* The id of the input the list is anchored to. Useful together with the `open`
|
|
123
|
+
* prop, to control which input a controlled list belongs to.
|
|
124
|
+
*/
|
|
125
|
+
triggerId?: string | null | undefined;
|
|
126
|
+
/**
|
|
127
|
+
* The id of the input the list is initially anchored to. Useful together with
|
|
128
|
+
* `defaultOpen`.
|
|
129
|
+
*/
|
|
130
|
+
defaultTriggerId?: string | null | undefined;
|
|
131
|
+
/**
|
|
132
|
+
* The content of the combobox.
|
|
133
|
+
*
|
|
134
|
+
* Pass a function to receive the payload the list was opened with, via a
|
|
135
|
+
* detached input's `payload` prop.
|
|
136
|
+
*/
|
|
137
|
+
children?: React.ReactNode | ((payload: Payload) => React.ReactNode);
|
|
115
138
|
}
|
|
116
139
|
|
|
140
|
+
export type ComboboxRootChangeEventReason =
|
|
141
|
+
| typeof REASONS.inputPress
|
|
142
|
+
| typeof REASONS.inputChange
|
|
143
|
+
| typeof REASONS.triggerFocus
|
|
144
|
+
| typeof REASONS.itemPress
|
|
145
|
+
| typeof REASONS.outsidePress
|
|
146
|
+
| typeof REASONS.escapeKey
|
|
147
|
+
| typeof REASONS.imperativeAction
|
|
148
|
+
| typeof REASONS.none;
|
|
149
|
+
|
|
150
|
+
export type ComboboxRootChangeEventDetails = ZestChangeEventDetails<ComboboxRootChangeEventReason>;
|
|
151
|
+
|
|
117
152
|
export namespace ComboboxRoot {
|
|
118
153
|
export type State = ComboboxRootState;
|
|
119
|
-
export type Props = ComboboxRootProps
|
|
154
|
+
export type Props<Payload = unknown> = ComboboxRootProps<Payload>;
|
|
155
|
+
export type Actions = ComboboxRootActions;
|
|
156
|
+
export type ChangeEventReason = ComboboxRootChangeEventReason;
|
|
157
|
+
export type ChangeEventDetails = ComboboxRootChangeEventDetails;
|
|
120
158
|
}
|
|
@@ -1,61 +1,10 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import * as React from 'react';
|
|
3
|
-
import type {
|
|
4
|
-
import type { ZestNativeEvent } from '../../utils/createChangeEventDetails';
|
|
3
|
+
import type { ComboboxStore } from '../store/ComboboxStore';
|
|
5
4
|
|
|
6
|
-
export
|
|
7
|
-
value: unknown;
|
|
8
|
-
label: string;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export interface ComboboxRootContext {
|
|
12
|
-
/**
|
|
13
|
-
* `'combobox'` selects a value and shows its label; `'autocomplete'` is free
|
|
14
|
-
* text with suggestions, where the typed string is the value.
|
|
15
|
-
*/
|
|
16
|
-
mode: 'combobox' | 'autocomplete';
|
|
17
|
-
open: boolean;
|
|
18
|
-
setOpen: (open: boolean, event?: ZestNativeEvent) => void;
|
|
19
|
-
inputValue: string;
|
|
20
|
-
setInputValue: (value: string) => void;
|
|
21
|
-
/**
|
|
22
|
-
* The selected value (combobox mode only). `null` when nothing is selected.
|
|
23
|
-
*/
|
|
24
|
-
selectedValue: unknown;
|
|
25
|
-
/**
|
|
26
|
-
* Selects an item: records the value, fills the input with its label, and
|
|
27
|
-
* closes the popup.
|
|
28
|
-
*/
|
|
29
|
-
selectItem: (item: ComboboxItem, event?: ZestNativeEvent) => void;
|
|
30
|
-
/**
|
|
31
|
-
* The items after filtering by the current input value.
|
|
32
|
-
*/
|
|
33
|
-
filteredItems: ComboboxItem[];
|
|
34
|
-
disabled: boolean;
|
|
35
|
-
/**
|
|
36
|
-
* Whether focusing the input opens the list.
|
|
37
|
-
*/
|
|
38
|
-
openOnFocus: boolean;
|
|
39
|
-
/**
|
|
40
|
-
* The anchor's native node, carried across the portal boundary.
|
|
41
|
-
*/
|
|
42
|
-
triggerNode: unknown;
|
|
43
|
-
setTriggerNode: (node: unknown) => void;
|
|
44
|
-
update: (() => void) | undefined;
|
|
45
|
-
setUpdate: (fn: (() => void) | undefined) => void;
|
|
46
|
-
/**
|
|
47
|
-
* Ref to the input element for programmatic blur.
|
|
48
|
-
*/
|
|
49
|
-
inputRef: React.RefObject<TextInput | null> | undefined;
|
|
50
|
-
setInputRef: (ref: React.RefObject<TextInput | null>) => void;
|
|
51
|
-
/**
|
|
52
|
-
* The trigger's measured width, used to size the popup.
|
|
53
|
-
*/
|
|
54
|
-
triggerWidth: number | undefined;
|
|
55
|
-
setTriggerWidth: (width: number) => void;
|
|
56
|
-
}
|
|
5
|
+
export type { ComboboxItem, ComboboxItems } from '../store/ComboboxStore';
|
|
57
6
|
|
|
58
|
-
export const ComboboxRootContext = React.createContext<
|
|
7
|
+
export const ComboboxRootContext = React.createContext<ComboboxStore | undefined>(undefined);
|
|
59
8
|
|
|
60
9
|
export function useComboboxRootContext() {
|
|
61
10
|
const context = React.useContext(ComboboxRootContext);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import type { TransitionStatus } from '../../internals/useTransitionStatus';
|
|
4
|
+
|
|
5
|
+
export interface ComboboxTransitionContext {
|
|
6
|
+
transitionStatus: TransitionStatus;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const ComboboxTransitionContext = React.createContext<
|
|
10
|
+
ComboboxTransitionContext | undefined
|
|
11
|
+
>(undefined);
|
|
12
|
+
|
|
13
|
+
export function useComboboxTransitionContext() {
|
|
14
|
+
return React.useContext(ComboboxTransitionContext);
|
|
15
|
+
}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { useIsoLayoutEffect } from '../../hooks/useIsoLayoutEffect';
|
|
4
|
+
import { useRefWithInit } from '../../hooks/useRefWithInit';
|
|
5
|
+
import { useTransitionStatus } from '../../internals/useTransitionStatus';
|
|
6
|
+
import { usePopupRootHandle } from '../../utils/popups/usePopupRootHandle';
|
|
7
|
+
import { useFilter } from '../../filter/useFilter';
|
|
8
|
+
import type { ComboboxHandle } from '../store/ComboboxHandle';
|
|
9
|
+
import {
|
|
10
|
+
ComboboxStore,
|
|
11
|
+
normalizeComboboxItems,
|
|
12
|
+
type ComboboxItem,
|
|
13
|
+
type ComboboxItems,
|
|
14
|
+
} from '../store/ComboboxStore';
|
|
15
|
+
import type { ComboboxRoot } from './ComboboxRoot';
|
|
16
|
+
import { ComboboxItemsContext } from './ComboboxItemsContext';
|
|
17
|
+
import { ComboboxRootContext } from './ComboboxRootContext';
|
|
18
|
+
import { ComboboxTransitionContext } from './ComboboxTransitionContext';
|
|
19
|
+
|
|
20
|
+
export type ComboboxMode = 'combobox' | 'autocomplete';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* The props both `Combobox.Root` and `Autocomplete.Root` accept. An
|
|
24
|
+
* autocomplete's value *is* its input text, so it omits the selection props.
|
|
25
|
+
*/
|
|
26
|
+
export interface UseRenderComboboxRootProps<Payload = unknown> {
|
|
27
|
+
items?: ComboboxItems | undefined;
|
|
28
|
+
value?: unknown;
|
|
29
|
+
defaultValue?: unknown;
|
|
30
|
+
onValueChange?: ((value: any, eventDetails: ComboboxRoot.ChangeEventDetails) => void) | undefined;
|
|
31
|
+
inputValue?: string | undefined;
|
|
32
|
+
defaultInputValue?: string | undefined;
|
|
33
|
+
onInputValueChange?:
|
|
34
|
+
| ((value: string, eventDetails: ComboboxRoot.ChangeEventDetails) => void)
|
|
35
|
+
| undefined;
|
|
36
|
+
open?: boolean | undefined;
|
|
37
|
+
defaultOpen?: boolean | undefined;
|
|
38
|
+
onOpenChange?: ((open: boolean, eventDetails: ComboboxRoot.ChangeEventDetails) => void) | undefined;
|
|
39
|
+
openOnFocus?: boolean | undefined;
|
|
40
|
+
filter?: ((item: ComboboxItem, query: string) => boolean) | undefined;
|
|
41
|
+
disabled?: boolean | undefined;
|
|
42
|
+
disablePointerDismissal?: boolean | undefined;
|
|
43
|
+
actionsRef?: React.RefObject<ComboboxRoot.Actions | null> | undefined;
|
|
44
|
+
handle?: ComboboxHandle | undefined;
|
|
45
|
+
triggerId?: string | null | undefined;
|
|
46
|
+
defaultTriggerId?: string | null | undefined;
|
|
47
|
+
children?: React.ReactNode | ((payload: Payload) => React.ReactNode);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* The shared Root implementation behind `Combobox.Root` and `Autocomplete.Root`.
|
|
52
|
+
*
|
|
53
|
+
* The two differ only in whether choosing an item records a separate value:
|
|
54
|
+
* a combobox selects `item.value` and shows its label, an autocomplete puts the
|
|
55
|
+
* typed text itself forward and treats the list as suggestions.
|
|
56
|
+
*/
|
|
57
|
+
export function useRenderComboboxRoot<Payload = unknown>(
|
|
58
|
+
props: UseRenderComboboxRootProps<Payload>,
|
|
59
|
+
mode: ComboboxMode,
|
|
60
|
+
) {
|
|
61
|
+
const {
|
|
62
|
+
actionsRef,
|
|
63
|
+
children,
|
|
64
|
+
defaultInputValue,
|
|
65
|
+
defaultOpen = false,
|
|
66
|
+
defaultTriggerId = null,
|
|
67
|
+
defaultValue,
|
|
68
|
+
disablePointerDismissal = false,
|
|
69
|
+
disabled = false,
|
|
70
|
+
filter,
|
|
71
|
+
handle,
|
|
72
|
+
inputValue,
|
|
73
|
+
items,
|
|
74
|
+
onInputValueChange,
|
|
75
|
+
onOpenChange,
|
|
76
|
+
onValueChange,
|
|
77
|
+
open,
|
|
78
|
+
openOnFocus = true,
|
|
79
|
+
triggerId,
|
|
80
|
+
value,
|
|
81
|
+
} = props;
|
|
82
|
+
|
|
83
|
+
const normalizedItems = React.useMemo(() => normalizeComboboxItems(items), [items]);
|
|
84
|
+
|
|
85
|
+
const { contains } = useFilter();
|
|
86
|
+
const filterItem = React.useMemo(
|
|
87
|
+
() => filter ?? ((item: ComboboxItem, query: string) => contains(item.label, query)),
|
|
88
|
+
[filter, contains],
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
// The initial input text is only read on the first render; compute it once so
|
|
92
|
+
// it stays stable, or a later selection changing the controlled `value` (and
|
|
93
|
+
// with it the derived label) would look like a controlled/uncontrolled switch.
|
|
94
|
+
const initialInputRef = React.useRef<string | undefined>(undefined);
|
|
95
|
+
if (initialInputRef.current === undefined) {
|
|
96
|
+
initialInputRef.current =
|
|
97
|
+
defaultInputValue ??
|
|
98
|
+
(mode === 'combobox'
|
|
99
|
+
? (normalizedItems.find((item) => item.value === (value ?? defaultValue))?.label ?? '')
|
|
100
|
+
: '');
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const store = useRefWithInit(
|
|
104
|
+
() =>
|
|
105
|
+
new ComboboxStore({
|
|
106
|
+
open: defaultOpen,
|
|
107
|
+
openProp: open,
|
|
108
|
+
value: defaultValue ?? null,
|
|
109
|
+
valueProp: value,
|
|
110
|
+
inputValue: initialInputRef.current!,
|
|
111
|
+
inputValueProp: inputValue,
|
|
112
|
+
items: normalizedItems,
|
|
113
|
+
mode,
|
|
114
|
+
disabled,
|
|
115
|
+
disablePointerDismissal,
|
|
116
|
+
openOnFocus,
|
|
117
|
+
triggerId: defaultTriggerId,
|
|
118
|
+
triggerIdProp: triggerId,
|
|
119
|
+
}),
|
|
120
|
+
).current;
|
|
121
|
+
|
|
122
|
+
store.useControlledProp('openProp', open);
|
|
123
|
+
store.useControlledProp('valueProp', value);
|
|
124
|
+
store.useControlledProp('inputValueProp', inputValue);
|
|
125
|
+
store.useControlledProp('triggerIdProp', triggerId);
|
|
126
|
+
store.useContextCallback('onOpenChange', onOpenChange);
|
|
127
|
+
store.useContextCallback('onValueChange', onValueChange);
|
|
128
|
+
store.useContextCallback('onInputValueChange', onInputValueChange);
|
|
129
|
+
store.useSyncedValues({
|
|
130
|
+
mode,
|
|
131
|
+
disabled,
|
|
132
|
+
disablePointerDismissal,
|
|
133
|
+
openOnFocus,
|
|
134
|
+
items: normalizedItems,
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
usePopupRootHandle({ store, handle, actionsRef });
|
|
138
|
+
|
|
139
|
+
const resolvedOpen = store.useState('open');
|
|
140
|
+
const selectedValue = store.useState('value');
|
|
141
|
+
const currentInputValue = store.useState('inputValue');
|
|
142
|
+
|
|
143
|
+
// The label of the currently selected value (combobox mode only).
|
|
144
|
+
const selectedLabel =
|
|
145
|
+
mode === 'combobox'
|
|
146
|
+
? (normalizedItems.find((item) => item.value === selectedValue)?.label ?? '')
|
|
147
|
+
: '';
|
|
148
|
+
|
|
149
|
+
// Reflect a controlled `value` that changed from outside into the input text.
|
|
150
|
+
// `selectItem` already sets both, so the ref guard makes that a no-op and stops
|
|
151
|
+
// this from fighting the user's typing (typing never changes the selection).
|
|
152
|
+
const lastReflectedValueRef = React.useRef(selectedValue);
|
|
153
|
+
useIsoLayoutEffect(() => {
|
|
154
|
+
if (mode !== 'combobox' || selectedValue === lastReflectedValueRef.current) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
lastReflectedValueRef.current = selectedValue;
|
|
158
|
+
store.reflectInputValue(selectedLabel);
|
|
159
|
+
}, [mode, selectedValue, selectedLabel, store]);
|
|
160
|
+
|
|
161
|
+
const filteredItems = React.useMemo(() => {
|
|
162
|
+
// When the input still shows the current selection, the user has not started
|
|
163
|
+
// filtering — show every item so a fresh focus reveals the whole list rather
|
|
164
|
+
// than the single selected row.
|
|
165
|
+
const query =
|
|
166
|
+
mode === 'combobox' && currentInputValue === selectedLabel ? '' : currentInputValue.trim();
|
|
167
|
+
if (query.length === 0) {
|
|
168
|
+
return normalizedItems;
|
|
169
|
+
}
|
|
170
|
+
return normalizedItems.filter((item) => filterItem(item, query));
|
|
171
|
+
}, [normalizedItems, currentInputValue, selectedLabel, mode, filterItem]);
|
|
172
|
+
|
|
173
|
+
const { transitionStatus } = useTransitionStatus(resolvedOpen, false, true);
|
|
174
|
+
|
|
175
|
+
const itemsContextValue = React.useMemo(() => ({ filteredItems }), [filteredItems]);
|
|
176
|
+
const transitionContextValue = React.useMemo(() => ({ transitionStatus }), [transitionStatus]);
|
|
177
|
+
|
|
178
|
+
const payload = store.useState('payload') as Payload;
|
|
179
|
+
|
|
180
|
+
return (
|
|
181
|
+
<ComboboxRootContext.Provider value={store}>
|
|
182
|
+
<ComboboxItemsContext.Provider value={itemsContextValue}>
|
|
183
|
+
<ComboboxTransitionContext.Provider value={transitionContextValue}>
|
|
184
|
+
{typeof children === 'function' ? children(payload) : children}
|
|
185
|
+
</ComboboxTransitionContext.Provider>
|
|
186
|
+
</ComboboxItemsContext.Provider>
|
|
187
|
+
</ComboboxRootContext.Provider>
|
|
188
|
+
);
|
|
189
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { ComboboxStore } from './ComboboxStore';
|
|
2
|
+
import { BasePopupHandle } from '../../utils/popups/BasePopupHandle';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Controls a combobox imperatively, and associates a `Combobox.Input` rendered
|
|
6
|
+
* outside the root with it. Create one with `Combobox.createHandle()` and pass
|
|
7
|
+
* it to the root's and the input's `handle` prop.
|
|
8
|
+
*
|
|
9
|
+
* The imperative methods only take effect while a root using this handle is
|
|
10
|
+
* mounted; calls made before one attaches (or after it unmounts) are ignored.
|
|
11
|
+
*/
|
|
12
|
+
export class ComboboxHandle extends BasePopupHandle<ComboboxStore, ComboboxStore> {
|
|
13
|
+
constructor(componentName: string = 'Combobox') {
|
|
14
|
+
// `true`: the list is anchored to the input, so opening it by an unknown
|
|
15
|
+
// trigger id is an error rather than a warning — there would be nothing to
|
|
16
|
+
// anchor to.
|
|
17
|
+
super(new ComboboxStore(), componentName, true);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Points the positioner at the input the list was opened from. Without this an
|
|
22
|
+
* imperative open would anchor to whatever was last measured.
|
|
23
|
+
*/
|
|
24
|
+
protected override associateTrigger(store: ComboboxStore, triggerNode: unknown) {
|
|
25
|
+
if (triggerNode !== undefined) {
|
|
26
|
+
store.set('triggerNode', triggerNode);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Opens the list, anchored to the input with the given id.
|
|
32
|
+
*
|
|
33
|
+
* Call this from an event handler or an effect, never during rendering.
|
|
34
|
+
*
|
|
35
|
+
* @param triggerId The `nativeID` of a mounted `Combobox.Input` carrying this handle.
|
|
36
|
+
*/
|
|
37
|
+
open(triggerId: string) {
|
|
38
|
+
this.openByTrigger(triggerId);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Closes the list.
|
|
43
|
+
*
|
|
44
|
+
* Call this from an event handler or an effect, never during rendering.
|
|
45
|
+
*/
|
|
46
|
+
close() {
|
|
47
|
+
this.closePopup();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Whether the list is open. `false` while no root is attached.
|
|
52
|
+
*/
|
|
53
|
+
get isOpen() {
|
|
54
|
+
return this.attachedStore?.select('open') ?? false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Creates a handle that connects a `Combobox.Root` to a `Combobox.Input`
|
|
60
|
+
* rendered outside it, and controls it imperatively.
|
|
61
|
+
*/
|
|
62
|
+
export function createComboboxHandle(): ComboboxHandle {
|
|
63
|
+
return new ComboboxHandle();
|
|
64
|
+
}
|