@limonify/zest-ui 0.3.1 → 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 -2
- 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 +68 -8
- 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 -4
- 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 +11 -1
- package/lib/combobox/positioner/ComboboxPositioner.d.ts.map +1 -1
- package/lib/combobox/positioner/ComboboxPositioner.js +67 -7
- 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 -43
- 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 +9 -0
- package/lib/select/positioner/SelectPositioner.d.ts.map +1 -1
- package/lib/select/positioner/SelectPositioner.js +9 -1
- 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 +33 -0
- package/lib/select/store/SelectStore.d.ts.map +1 -1
- package/lib/select/store/SelectStore.js +17 -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 +51 -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 -2
- 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 +118 -23
- package/src/combobox/item/ComboboxItem.tsx +24 -5
- 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 +52 -7
- 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 -43
- 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 +18 -1
- package/src/select/root/SelectRoot.tsx +109 -9
- package/src/select/store/SelectHandle.ts +68 -0
- package/src/select/store/SelectStore.ts +44 -1
- package/src/select/trigger/SelectTrigger.tsx +81 -8
- 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 -168
- 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 -190
- package/src/utils/fastObjectShallowCompare.ts +0 -30
- package/src/utils/mergeObjects.ts +0 -15
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
import { Pressable, StyleSheet, type GestureResponderEvent } from 'react-native';
|
|
3
3
|
import { useComboboxRootContext } from '../root/ComboboxRootContext';
|
|
4
4
|
import { useRenderElement } from '../../use-render/useRenderElement';
|
|
5
|
+
import { createChangeEventDetails } from '../../utils/createChangeEventDetails';
|
|
6
|
+
import { REASONS } from '../../utils/reasons';
|
|
5
7
|
import type { ZestUIComponentProps } from '../../types';
|
|
6
8
|
|
|
7
9
|
/**
|
|
@@ -11,7 +13,8 @@ import type { ZestUIComponentProps } from '../../types';
|
|
|
11
13
|
export function ComboboxBackdrop(componentProps: ComboboxBackdrop.Props) {
|
|
12
14
|
const { render, className, style, ref, ...elementProps } = componentProps;
|
|
13
15
|
|
|
14
|
-
const
|
|
16
|
+
const store = useComboboxRootContext();
|
|
17
|
+
const open = store.useState('open');
|
|
15
18
|
|
|
16
19
|
const state: ComboboxBackdropState = { open };
|
|
17
20
|
|
|
@@ -22,7 +25,12 @@ export function ComboboxBackdrop(componentProps: ComboboxBackdrop.Props) {
|
|
|
22
25
|
{
|
|
23
26
|
style: StyleSheet.absoluteFill,
|
|
24
27
|
onPress(event: GestureResponderEvent) {
|
|
25
|
-
|
|
28
|
+
if (store.select('disablePointerDismissal')) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
store.setOpen(false, createChangeEventDetails(REASONS.outsidePress, event));
|
|
33
|
+
store.select('inputRef')?.current?.blur();
|
|
26
34
|
},
|
|
27
35
|
},
|
|
28
36
|
elementProps,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { View } from 'react-native';
|
|
3
3
|
import { useComboboxRootContext } from '../root/ComboboxRootContext';
|
|
4
|
+
import { useComboboxItemsContext } from '../root/ComboboxItemsContext';
|
|
4
5
|
import { useRenderElement } from '../../use-render/useRenderElement';
|
|
5
6
|
import type { ZestUIComponentProps } from '../../types';
|
|
6
7
|
|
|
@@ -11,7 +12,10 @@ import type { ZestUIComponentProps } from '../../types';
|
|
|
11
12
|
export function ComboboxEmpty(componentProps: ComboboxEmpty.Props) {
|
|
12
13
|
const { render, className, style, ref, ...elementProps } = componentProps;
|
|
13
14
|
|
|
14
|
-
const
|
|
15
|
+
const store = useComboboxRootContext();
|
|
16
|
+
const { filteredItems } = useComboboxItemsContext();
|
|
17
|
+
|
|
18
|
+
const open = store.useState('open');
|
|
15
19
|
|
|
16
20
|
const state: ComboboxEmptyState = { open };
|
|
17
21
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { ComboboxRoot as Root } from './root/ComboboxRoot';
|
|
2
|
+
export { createComboboxHandle as createHandle, ComboboxHandle as Handle } from './store/ComboboxHandle';
|
|
2
3
|
export { ComboboxInput as Input } from './input/ComboboxInput';
|
|
3
4
|
export { ComboboxPortal as Portal } from './portal/ComboboxPortal';
|
|
4
5
|
export { ComboboxBackdrop as Backdrop } from './backdrop/ComboboxBackdrop';
|
package/src/combobox/index.ts
CHANGED
|
@@ -1,36 +1,88 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import * as React from 'react';
|
|
3
|
-
import { TextInput } from 'react-native';
|
|
4
|
-
import {
|
|
3
|
+
import { TextInput, type LayoutChangeEvent } from 'react-native';
|
|
4
|
+
import { ComboboxRootContext } from '../root/ComboboxRootContext';
|
|
5
5
|
import { useRenderElement } from '../../use-render/useRenderElement';
|
|
6
|
+
import { useId } from '../../hooks/useId';
|
|
7
|
+
import { useIsoLayoutEffect } from '../../hooks/useIsoLayoutEffect';
|
|
6
8
|
import { useMergedRefs } from '../../hooks/useMergedRefs';
|
|
9
|
+
import { usePopupHandleStore } from '../../utils/popups/usePopupHandleStore';
|
|
10
|
+
import { createChangeEventDetails } from '../../utils/createChangeEventDetails';
|
|
11
|
+
import { REASONS } from '../../utils/reasons';
|
|
12
|
+
import type { ComboboxHandle } from '../store/ComboboxHandle';
|
|
13
|
+
import type { ComboboxStore } from '../store/ComboboxStore';
|
|
7
14
|
import type { ZestUIComponentProps } from '../../types';
|
|
8
15
|
|
|
9
16
|
/**
|
|
10
17
|
* The text input that filters the list, and the element the popup is anchored to.
|
|
11
18
|
* Renders a `<TextInput>`.
|
|
19
|
+
*
|
|
20
|
+
* Pass a `handle` to render the input outside of its `Combobox.Root`: there is
|
|
21
|
+
* no context reaching across, so the handle is what connects the two.
|
|
12
22
|
*/
|
|
13
|
-
export function ComboboxInput(componentProps: ComboboxInput.Props) {
|
|
14
|
-
const { render, className, style, ref, ...elementProps } = componentProps;
|
|
15
|
-
|
|
23
|
+
export function ComboboxInput<Payload = unknown>(componentProps: ComboboxInput.Props<Payload>) {
|
|
16
24
|
const {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
} =
|
|
25
|
+
render,
|
|
26
|
+
className,
|
|
27
|
+
style,
|
|
28
|
+
handle,
|
|
29
|
+
nativeID: idProp,
|
|
30
|
+
payload,
|
|
31
|
+
ref,
|
|
32
|
+
...elementProps
|
|
33
|
+
} = componentProps;
|
|
34
|
+
|
|
35
|
+
const rootStore = React.useContext(ComboboxRootContext);
|
|
36
|
+
const handleStore = usePopupHandleStore(handle);
|
|
37
|
+
|
|
38
|
+
// An input inside a root uses that root; a detached one follows its handle,
|
|
39
|
+
// which resolves to the attached root's store or to an inert fallback.
|
|
40
|
+
const store = (handleStore ?? rootStore) as ComboboxStore | undefined;
|
|
41
|
+
|
|
42
|
+
if (store === undefined) {
|
|
43
|
+
throw new Error(
|
|
44
|
+
'Zest: Combobox.Input must be placed within <Combobox.Root> or <Autocomplete.Root>, or given a `handle` it shares with one.',
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const id = useId(idProp ?? undefined);
|
|
26
49
|
|
|
50
|
+
const open = store.useState('open');
|
|
51
|
+
const disabled = store.useState('disabled');
|
|
52
|
+
const inputValue = store.useState('inputValue');
|
|
53
|
+
const openOnFocus = store.useState('openOnFocus');
|
|
54
|
+
const update = store.useState('update');
|
|
55
|
+
|
|
56
|
+
const internalRef = React.useRef<TextInput>(null);
|
|
57
|
+
|
|
58
|
+
useIsoLayoutEffect(() => {
|
|
59
|
+
store.set('inputRef', internalRef);
|
|
60
|
+
}, [store]);
|
|
61
|
+
|
|
62
|
+
const triggerRef = React.useRef<unknown>(null);
|
|
27
63
|
const anchorRef = React.useCallback(
|
|
28
64
|
(node: unknown) => {
|
|
29
|
-
|
|
65
|
+
triggerRef.current = node;
|
|
66
|
+
store.set('triggerNode', node);
|
|
30
67
|
},
|
|
31
|
-
[
|
|
68
|
+
[store],
|
|
32
69
|
);
|
|
33
|
-
const mergedRef = useMergedRefs(ref, anchorRef);
|
|
70
|
+
const mergedRef = useMergedRefs(ref, anchorRef, internalRef);
|
|
71
|
+
|
|
72
|
+
// Registering into whichever store is current is what lets a handle resolve
|
|
73
|
+
// `open(id)`. The effect re-runs when the handle swaps stores, migrating the
|
|
74
|
+
// registration to the root that just attached.
|
|
75
|
+
useIsoLayoutEffect(() => {
|
|
76
|
+
if (id === undefined) {
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
store.context.triggerNodes.add(id, triggerRef.current);
|
|
81
|
+
|
|
82
|
+
return () => {
|
|
83
|
+
store.context.triggerNodes.delete(id);
|
|
84
|
+
};
|
|
85
|
+
}, [store, id]);
|
|
34
86
|
|
|
35
87
|
const state: ComboboxInputState = { open, disabled };
|
|
36
88
|
|
|
@@ -39,20 +91,45 @@ export function ComboboxInput(componentProps: ComboboxInput.Props) {
|
|
|
39
91
|
ref: mergedRef,
|
|
40
92
|
props: [
|
|
41
93
|
{
|
|
94
|
+
nativeID: id,
|
|
42
95
|
value: inputValue,
|
|
43
96
|
editable: !disabled,
|
|
44
97
|
onChangeText(text: string) {
|
|
45
|
-
|
|
98
|
+
// One event details object is shared, so canceling the text change
|
|
99
|
+
// also stops the list from opening.
|
|
100
|
+
const eventDetails = createChangeEventDetails(REASONS.inputChange);
|
|
101
|
+
|
|
102
|
+
store.setInputValue(text, eventDetails);
|
|
103
|
+
|
|
104
|
+
if (eventDetails.isCanceled) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Typing reopens the list so suggestions follow the query.
|
|
109
|
+
if (!store.select('open') && text.length > 0) {
|
|
110
|
+
store.setOpen(true, eventDetails);
|
|
111
|
+
}
|
|
46
112
|
},
|
|
47
113
|
onFocus() {
|
|
114
|
+
if (payload !== undefined) {
|
|
115
|
+
store.set('payload', payload);
|
|
116
|
+
}
|
|
117
|
+
if (id !== undefined) {
|
|
118
|
+
store.set('triggerId', id);
|
|
119
|
+
}
|
|
120
|
+
|
|
48
121
|
if (openOnFocus) {
|
|
49
|
-
setOpen(true);
|
|
122
|
+
store.setOpen(true, createChangeEventDetails(REASONS.triggerFocus));
|
|
50
123
|
}
|
|
51
124
|
},
|
|
52
|
-
onLayout() {
|
|
125
|
+
onLayout(event: LayoutChangeEvent) {
|
|
126
|
+
const { width, height } = event.nativeEvent.layout;
|
|
127
|
+
store.set('triggerWidth', width);
|
|
128
|
+
store.set('triggerHeight', height);
|
|
53
129
|
update?.();
|
|
54
130
|
},
|
|
55
131
|
accessibilityRole: 'search' as const,
|
|
132
|
+
accessibilityState: { expanded: open, disabled: disabled || undefined },
|
|
56
133
|
'aria-expanded': open,
|
|
57
134
|
'aria-autocomplete': 'list' as const,
|
|
58
135
|
},
|
|
@@ -62,14 +139,32 @@ export function ComboboxInput(componentProps: ComboboxInput.Props) {
|
|
|
62
139
|
}
|
|
63
140
|
|
|
64
141
|
export interface ComboboxInputState {
|
|
142
|
+
/**
|
|
143
|
+
* Whether the list is currently open.
|
|
144
|
+
*/
|
|
65
145
|
open: boolean;
|
|
146
|
+
/**
|
|
147
|
+
* Whether the component should ignore user interaction.
|
|
148
|
+
*/
|
|
66
149
|
disabled: boolean;
|
|
67
150
|
}
|
|
68
151
|
|
|
69
|
-
export interface ComboboxInputProps
|
|
70
|
-
extends Omit<ZestUIComponentProps<typeof TextInput, ComboboxInputState>, 'value'> {
|
|
152
|
+
export interface ComboboxInputProps<Payload = unknown>
|
|
153
|
+
extends Omit<ZestUIComponentProps<typeof TextInput, ComboboxInputState>, 'value'> {
|
|
154
|
+
/**
|
|
155
|
+
* A handle shared with a `Combobox.Root`, which is what lets this input live
|
|
156
|
+
* outside of it. Create one with `Combobox.createHandle()`.
|
|
157
|
+
*
|
|
158
|
+
* The input's `nativeID` is the id a handle's `open(triggerId)` resolves.
|
|
159
|
+
*/
|
|
160
|
+
handle?: ComboboxHandle | undefined;
|
|
161
|
+
/**
|
|
162
|
+
* A payload handed to the root's children when they are a function.
|
|
163
|
+
*/
|
|
164
|
+
payload?: Payload | undefined;
|
|
165
|
+
}
|
|
71
166
|
|
|
72
167
|
export namespace ComboboxInput {
|
|
73
168
|
export type State = ComboboxInputState;
|
|
74
|
-
export type Props = ComboboxInputProps
|
|
169
|
+
export type Props<Payload = unknown> = ComboboxInputProps<Payload>;
|
|
75
170
|
}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import { Pressable, type GestureResponderEvent } from 'react-native';
|
|
4
|
-
import { useComboboxRootContext
|
|
4
|
+
import { useComboboxRootContext } from '../root/ComboboxRootContext';
|
|
5
5
|
import { useRenderElement } from '../../use-render/useRenderElement';
|
|
6
6
|
import { useCompositeListItem } from '../../internals/composite/list/useCompositeListItem';
|
|
7
|
+
import { createChangeEventDetails } from '../../utils/createChangeEventDetails';
|
|
8
|
+
import { REASONS } from '../../utils/reasons';
|
|
9
|
+
import type { ComboboxItem as ComboboxItemData } from '../store/ComboboxStore';
|
|
7
10
|
import type { ZestUIComponentProps } from '../../types';
|
|
8
11
|
|
|
9
12
|
/**
|
|
@@ -13,13 +16,18 @@ import type { ZestUIComponentProps } from '../../types';
|
|
|
13
16
|
export function ComboboxItem(componentProps: ComboboxItem.Props) {
|
|
14
17
|
const { render, className, style, item, ref, ...elementProps } = componentProps;
|
|
15
18
|
|
|
16
|
-
const
|
|
17
|
-
const
|
|
19
|
+
const store = useComboboxRootContext();
|
|
20
|
+
const selectedValue = store.useState('value');
|
|
21
|
+
|
|
22
|
+
const { index, onLayout } = useCompositeListItem();
|
|
18
23
|
|
|
19
24
|
const [pressed, setPressed] = React.useState(false);
|
|
20
25
|
const selected = selectedValue === item.value;
|
|
21
26
|
|
|
22
|
-
const state: ComboboxItemState =
|
|
27
|
+
const state: ComboboxItemState = React.useMemo(
|
|
28
|
+
() => ({ selected, pressed, index }),
|
|
29
|
+
[selected, pressed, index],
|
|
30
|
+
);
|
|
23
31
|
|
|
24
32
|
return useRenderElement(Pressable, componentProps, {
|
|
25
33
|
state,
|
|
@@ -28,7 +36,8 @@ export function ComboboxItem(componentProps: ComboboxItem.Props) {
|
|
|
28
36
|
{
|
|
29
37
|
onLayout,
|
|
30
38
|
onPress(event: GestureResponderEvent) {
|
|
31
|
-
selectItem(item, event);
|
|
39
|
+
store.selectItem(item, createChangeEventDetails(REASONS.itemPress, event));
|
|
40
|
+
store.select('inputRef')?.current?.blur();
|
|
32
41
|
},
|
|
33
42
|
onPressIn: () => setPressed(true),
|
|
34
43
|
onPressOut: () => setPressed(false),
|
|
@@ -43,8 +52,18 @@ export function ComboboxItem(componentProps: ComboboxItem.Props) {
|
|
|
43
52
|
}
|
|
44
53
|
|
|
45
54
|
export interface ComboboxItemState {
|
|
55
|
+
/**
|
|
56
|
+
* Whether this item is the selected one.
|
|
57
|
+
*/
|
|
46
58
|
selected: boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Whether the item is currently pressed.
|
|
61
|
+
*/
|
|
47
62
|
pressed: boolean;
|
|
63
|
+
/**
|
|
64
|
+
* The item's index in the list, in visual order.
|
|
65
|
+
*/
|
|
66
|
+
index: number;
|
|
48
67
|
}
|
|
49
68
|
|
|
50
69
|
export interface ComboboxItemProps extends ZestUIComponentProps<typeof Pressable, ComboboxItemState> {
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import { View } from 'react-native';
|
|
4
|
-
import { useComboboxRootContext
|
|
4
|
+
import { useComboboxRootContext } from '../root/ComboboxRootContext';
|
|
5
|
+
import { useComboboxItemsContext } from '../root/ComboboxItemsContext';
|
|
5
6
|
import { useRenderElement } from '../../use-render/useRenderElement';
|
|
7
|
+
import type { ComboboxItem } from '../store/ComboboxStore';
|
|
6
8
|
import type { ZestUIComponentProps } from '../../types';
|
|
7
9
|
|
|
8
10
|
/**
|
|
@@ -16,7 +18,10 @@ import type { ZestUIComponentProps } from '../../types';
|
|
|
16
18
|
export function ComboboxList(componentProps: ComboboxList.Props) {
|
|
17
19
|
const { render, className, style, children, ref, ...elementProps } = componentProps;
|
|
18
20
|
|
|
19
|
-
const
|
|
21
|
+
const store = useComboboxRootContext();
|
|
22
|
+
const { filteredItems } = useComboboxItemsContext();
|
|
23
|
+
|
|
24
|
+
const open = store.useState('open');
|
|
20
25
|
|
|
21
26
|
const state: ComboboxListState = { open, empty: filteredItems.length === 0 };
|
|
22
27
|
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { View } from 'react-native';
|
|
3
3
|
import { useComboboxRootContext } from '../root/ComboboxRootContext';
|
|
4
|
+
import { useComboboxPositionerContext } from '../positioner/ComboboxPositionerContext';
|
|
5
|
+
import { useComboboxTransitionContext } from '../root/ComboboxTransitionContext';
|
|
4
6
|
import { useRenderElement } from '../../use-render/useRenderElement';
|
|
5
7
|
import { CompositeList } from '../../internals/composite/list/CompositeList';
|
|
8
|
+
import type { Align, Side } from '../../utils/useAnchorPositioning';
|
|
9
|
+
import type { TransitionStatus } from '../../internals/useTransitionStatus';
|
|
6
10
|
import type { ZestUIComponentProps } from '../../types';
|
|
7
11
|
|
|
8
12
|
/**
|
|
@@ -12,9 +16,22 @@ import type { ZestUIComponentProps } from '../../types';
|
|
|
12
16
|
export function ComboboxPopup(componentProps: ComboboxPopup.Props) {
|
|
13
17
|
const { render, className, style, ref, ...elementProps } = componentProps;
|
|
14
18
|
|
|
15
|
-
const
|
|
19
|
+
const store = useComboboxRootContext();
|
|
20
|
+
const { side, align } = useComboboxPositionerContext();
|
|
21
|
+
const { transitionStatus } = useComboboxTransitionContext() ?? { transitionStatus: undefined };
|
|
16
22
|
|
|
17
|
-
const
|
|
23
|
+
const open = store.useState('open');
|
|
24
|
+
const triggerWidth = store.useState('triggerWidth');
|
|
25
|
+
const triggerHeight = store.useState('triggerHeight');
|
|
26
|
+
|
|
27
|
+
const state: ComboboxPopupState = {
|
|
28
|
+
open,
|
|
29
|
+
transitionStatus,
|
|
30
|
+
side,
|
|
31
|
+
align,
|
|
32
|
+
triggerWidth,
|
|
33
|
+
triggerHeight,
|
|
34
|
+
};
|
|
18
35
|
|
|
19
36
|
const element = useRenderElement(View, componentProps, {
|
|
20
37
|
state,
|
|
@@ -29,11 +46,36 @@ export function ComboboxPopup(componentProps: ComboboxPopup.Props) {
|
|
|
29
46
|
],
|
|
30
47
|
});
|
|
31
48
|
|
|
49
|
+
// Items register here so they can be indexed in visual order.
|
|
32
50
|
return <CompositeList>{element}</CompositeList>;
|
|
33
51
|
}
|
|
34
52
|
|
|
35
53
|
export interface ComboboxPopupState {
|
|
54
|
+
/**
|
|
55
|
+
* Whether the list is currently open.
|
|
56
|
+
*/
|
|
36
57
|
open: boolean;
|
|
58
|
+
/**
|
|
59
|
+
* The transition status of the list: `'starting'` as it opens (auto-clears to
|
|
60
|
+
* `undefined` after one frame), `'ending'` once it is closing.
|
|
61
|
+
*/
|
|
62
|
+
transitionStatus: TransitionStatus;
|
|
63
|
+
/**
|
|
64
|
+
* The side the popup was actually placed on, after collision handling.
|
|
65
|
+
*/
|
|
66
|
+
side: Side;
|
|
67
|
+
/**
|
|
68
|
+
* The alignment the popup was actually placed with.
|
|
69
|
+
*/
|
|
70
|
+
align: Align;
|
|
71
|
+
/**
|
|
72
|
+
* The input's measured width, available for consumers to apply to the popup.
|
|
73
|
+
*/
|
|
74
|
+
triggerWidth: number | undefined;
|
|
75
|
+
/**
|
|
76
|
+
* The input's measured height.
|
|
77
|
+
*/
|
|
78
|
+
triggerHeight: number | undefined;
|
|
37
79
|
}
|
|
38
80
|
|
|
39
81
|
export interface ComboboxPopupProps extends ZestUIComponentProps<typeof View, ComboboxPopupState> {}
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import { Modal, type NativeSyntheticEvent } from 'react-native';
|
|
4
4
|
import { useComboboxRootContext } from '../root/ComboboxRootContext';
|
|
5
|
+
import { ComboboxPortalContext } from './ComboboxPortalContext';
|
|
6
|
+
import { createChangeEventDetails } from '../../utils/createChangeEventDetails';
|
|
7
|
+
import { REASONS } from '../../utils/reasons';
|
|
5
8
|
|
|
6
9
|
/**
|
|
7
10
|
* Moves the popup to the top of the app, as an RN `Modal` like the rest of the
|
|
@@ -10,7 +13,8 @@ import { useComboboxRootContext } from '../root/ComboboxRootContext';
|
|
|
10
13
|
export function ComboboxPortal(props: ComboboxPortal.Props) {
|
|
11
14
|
const { children, keepMounted = false } = props;
|
|
12
15
|
|
|
13
|
-
const
|
|
16
|
+
const store = useComboboxRootContext();
|
|
17
|
+
const open = store.useState('open');
|
|
14
18
|
|
|
15
19
|
const shouldRender = open || keepMounted;
|
|
16
20
|
if (!shouldRender) {
|
|
@@ -18,18 +22,20 @@ export function ComboboxPortal(props: ComboboxPortal.Props) {
|
|
|
18
22
|
}
|
|
19
23
|
|
|
20
24
|
return (
|
|
21
|
-
<
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
25
|
+
<ComboboxPortalContext.Provider value={keepMounted}>
|
|
26
|
+
<Modal
|
|
27
|
+
transparent
|
|
28
|
+
visible={open}
|
|
29
|
+
animationType="fade"
|
|
30
|
+
statusBarTranslucent
|
|
31
|
+
navigationBarTranslucent
|
|
32
|
+
onRequestClose={(event: NativeSyntheticEvent<unknown>) => {
|
|
33
|
+
store.setOpen(false, createChangeEventDetails(REASONS.escapeKey, event));
|
|
34
|
+
}}
|
|
35
|
+
>
|
|
36
|
+
{children}
|
|
37
|
+
</Modal>
|
|
38
|
+
</ComboboxPortalContext.Provider>
|
|
33
39
|
);
|
|
34
40
|
}
|
|
35
41
|
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
|
|
4
|
+
export const ComboboxPortalContext = React.createContext<boolean | undefined>(undefined);
|
|
5
|
+
|
|
6
|
+
export function useComboboxPortalContext() {
|
|
7
|
+
const context = React.useContext(ComboboxPortalContext);
|
|
8
|
+
if (context === undefined) {
|
|
9
|
+
throw new Error(
|
|
10
|
+
'Zest: ComboboxPortalContext is missing. <Combobox.Positioner> must be placed within <Combobox.Portal>.',
|
|
11
|
+
);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return context;
|
|
15
|
+
}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
'use client';
|
|
2
|
+
import * as React from 'react';
|
|
2
3
|
import { View } from 'react-native';
|
|
3
4
|
import { useComboboxRootContext } from '../root/ComboboxRootContext';
|
|
5
|
+
import { useComboboxPortalContext } from '../portal/ComboboxPortalContext';
|
|
6
|
+
import { ComboboxPositionerContext } from './ComboboxPositionerContext';
|
|
4
7
|
import { useRenderElement } from '../../use-render/useRenderElement';
|
|
5
8
|
import { useIsoLayoutEffect } from '../../hooks/useIsoLayoutEffect';
|
|
6
9
|
import { useMergedRefs } from '../../hooks/useMergedRefs';
|
|
@@ -32,7 +35,13 @@ export function ComboboxPositioner(componentProps: ComboboxPositioner.Props) {
|
|
|
32
35
|
...elementProps
|
|
33
36
|
} = componentProps;
|
|
34
37
|
|
|
35
|
-
|
|
38
|
+
useComboboxPortalContext();
|
|
39
|
+
const store = useComboboxRootContext();
|
|
40
|
+
|
|
41
|
+
const open = store.useState('open');
|
|
42
|
+
const triggerNode = store.useState('triggerNode');
|
|
43
|
+
const triggerWidth = store.useState('triggerWidth');
|
|
44
|
+
const triggerHeight = store.useState('triggerHeight');
|
|
36
45
|
|
|
37
46
|
const positioning = useAnchorPositioning({
|
|
38
47
|
align,
|
|
@@ -51,25 +60,61 @@ export function ComboboxPositioner(componentProps: ComboboxPositioner.Props) {
|
|
|
51
60
|
}, [refs, triggerNode]);
|
|
52
61
|
|
|
53
62
|
useIsoLayoutEffect(() => {
|
|
54
|
-
|
|
55
|
-
return () =>
|
|
56
|
-
|
|
63
|
+
store.set('update', update);
|
|
64
|
+
return () => {
|
|
65
|
+
store.set('update', undefined);
|
|
66
|
+
};
|
|
67
|
+
}, [store, update]);
|
|
57
68
|
|
|
58
69
|
const mergedRef = useMergedRefs(ref, refs.setFloating);
|
|
59
70
|
|
|
60
|
-
const state: ComboboxPositionerState = {
|
|
71
|
+
const state: ComboboxPositionerState = {
|
|
72
|
+
open,
|
|
73
|
+
side: positioning.side,
|
|
74
|
+
align: positioning.align,
|
|
75
|
+
triggerWidth,
|
|
76
|
+
triggerHeight,
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const contextValue: ComboboxPositionerContext = React.useMemo(
|
|
80
|
+
() => ({ side: positioning.side, align: positioning.align }),
|
|
81
|
+
[positioning.side, positioning.align],
|
|
82
|
+
);
|
|
61
83
|
|
|
62
|
-
|
|
84
|
+
const element = useRenderElement(View, componentProps, {
|
|
63
85
|
state,
|
|
64
86
|
ref: mergedRef,
|
|
65
|
-
props: [
|
|
87
|
+
props: [
|
|
88
|
+
{
|
|
89
|
+
style: positionerStyles,
|
|
90
|
+
onLayout() {
|
|
91
|
+
update();
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
elementProps,
|
|
95
|
+
],
|
|
66
96
|
});
|
|
97
|
+
|
|
98
|
+
return (
|
|
99
|
+
<ComboboxPositionerContext.Provider value={contextValue}>
|
|
100
|
+
{element}
|
|
101
|
+
</ComboboxPositionerContext.Provider>
|
|
102
|
+
);
|
|
67
103
|
}
|
|
68
104
|
|
|
69
105
|
export interface ComboboxPositionerState {
|
|
70
106
|
open: boolean;
|
|
71
107
|
side: Side;
|
|
72
108
|
align: Align;
|
|
109
|
+
/**
|
|
110
|
+
* The input's measured width, available for consumers to apply to the popup.
|
|
111
|
+
* This is the React Native equivalent of the web's `--anchor-width` CSS variable.
|
|
112
|
+
*/
|
|
113
|
+
triggerWidth: number | undefined;
|
|
114
|
+
/**
|
|
115
|
+
* The input's measured height.
|
|
116
|
+
*/
|
|
117
|
+
triggerHeight: number | undefined;
|
|
73
118
|
}
|
|
74
119
|
|
|
75
120
|
export interface ComboboxPositionerProps
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import type { Align, Side } from '../../utils/useAnchorPositioning';
|
|
4
|
+
|
|
5
|
+
export interface ComboboxPositionerContext {
|
|
6
|
+
side: Side;
|
|
7
|
+
align: Align;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const ComboboxPositionerContext = React.createContext<
|
|
11
|
+
ComboboxPositionerContext | undefined
|
|
12
|
+
>(undefined);
|
|
13
|
+
|
|
14
|
+
export function useComboboxPositionerContext() {
|
|
15
|
+
const context = React.useContext(ComboboxPositionerContext);
|
|
16
|
+
if (context === undefined) {
|
|
17
|
+
throw new Error(
|
|
18
|
+
'Zest: ComboboxPositionerContext is missing. <Combobox.Popup> must be placed within <Combobox.Positioner>.',
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return context;
|
|
23
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import type { ComboboxItem } from '../store/ComboboxStore';
|
|
4
|
+
|
|
5
|
+
export interface ComboboxItemsContext {
|
|
6
|
+
/**
|
|
7
|
+
* The items left after filtering by the current query.
|
|
8
|
+
*/
|
|
9
|
+
filteredItems: ComboboxItem[];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* The filtered view of the items.
|
|
14
|
+
*
|
|
15
|
+
* This is derived from the store rather than stored in it: a synced store value
|
|
16
|
+
* only lands in a layout effect, which would leave the list one commit behind
|
|
17
|
+
* the text the user just typed.
|
|
18
|
+
*/
|
|
19
|
+
export const ComboboxItemsContext = React.createContext<ComboboxItemsContext | undefined>(
|
|
20
|
+
undefined,
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
export function useComboboxItemsContext() {
|
|
24
|
+
const context = React.useContext(ComboboxItemsContext);
|
|
25
|
+
if (context === undefined) {
|
|
26
|
+
throw new Error(
|
|
27
|
+
'Zest: ComboboxItemsContext is missing. Combobox parts must be placed within <Combobox.Root> or <Autocomplete.Root>.',
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return context;
|
|
32
|
+
}
|