@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
|
@@ -5,6 +5,7 @@ import { useControlled } from '../../hooks/useControlled';
|
|
|
5
5
|
import { useId } from '../../hooks/useId';
|
|
6
6
|
import { useStableCallback } from '../../hooks/useStableCallback';
|
|
7
7
|
import { useRenderElement } from '../../use-render/useRenderElement';
|
|
8
|
+
import { useFieldControlRegistration } from '../../internals/field/useFieldControlRegistration';
|
|
8
9
|
import { CompositeList } from '../../internals/composite/list/CompositeList';
|
|
9
10
|
import type { ZestUIComponentProps } from '../../types';
|
|
10
11
|
import type { ZestChangeEventDetails } from '../../utils/createChangeEventDetails';
|
|
@@ -31,7 +32,7 @@ export function OTPFieldRoot(componentProps: OTPFieldRoot.Props) {
|
|
|
31
32
|
autoComplete = 'one-time-code',
|
|
32
33
|
className,
|
|
33
34
|
defaultValue,
|
|
34
|
-
disabled = false,
|
|
35
|
+
disabled: disabledProp = false,
|
|
35
36
|
id: idProp,
|
|
36
37
|
length,
|
|
37
38
|
mask = false,
|
|
@@ -48,6 +49,12 @@ export function OTPFieldRoot(componentProps: OTPFieldRoot.Props) {
|
|
|
48
49
|
...elementProps
|
|
49
50
|
} = componentProps;
|
|
50
51
|
|
|
52
|
+
const { fieldDisabled, fieldProps, markChanged, markTouched } = useFieldControlRegistration({
|
|
53
|
+
initialValue: normalizeOTPValue(defaultValue ?? valueProp, length, validationType, normalizeValue),
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
const disabled = disabledProp || fieldDisabled;
|
|
57
|
+
|
|
51
58
|
const id = useId(idProp);
|
|
52
59
|
|
|
53
60
|
const [value, setValueState] = useControlled<string>({
|
|
@@ -103,8 +110,11 @@ export function OTPFieldRoot(componentProps: OTPFieldRoot.Props) {
|
|
|
103
110
|
}
|
|
104
111
|
|
|
105
112
|
setValueState(normalized);
|
|
113
|
+
markChanged(normalized);
|
|
106
114
|
|
|
107
115
|
if (normalized.length === length) {
|
|
116
|
+
// A complete code ends the interaction; there is no blur to wait for.
|
|
117
|
+
markTouched(normalized);
|
|
108
118
|
onValueComplete?.(normalized, createChangeEventDetails(eventDetails.reason));
|
|
109
119
|
}
|
|
110
120
|
|
|
@@ -169,7 +179,17 @@ export function OTPFieldRoot(componentProps: OTPFieldRoot.Props) {
|
|
|
169
179
|
const element = useRenderElement(View, componentProps, {
|
|
170
180
|
state,
|
|
171
181
|
ref,
|
|
172
|
-
props:
|
|
182
|
+
props: [
|
|
183
|
+
{
|
|
184
|
+
// The slots are separate inputs but one field: without a group role a
|
|
185
|
+
// screen reader announces N unrelated text boxes. Pass
|
|
186
|
+
// `accessibilityLabel` to name the code being entered.
|
|
187
|
+
role: 'group' as const,
|
|
188
|
+
accessibilityState: { disabled: disabled || undefined },
|
|
189
|
+
...fieldProps,
|
|
190
|
+
},
|
|
191
|
+
elementProps,
|
|
192
|
+
],
|
|
173
193
|
});
|
|
174
194
|
|
|
175
195
|
return (
|
|
@@ -20,10 +20,19 @@ export function PopoverPopup(componentProps: PopoverPopup.Props) {
|
|
|
20
20
|
const { transitionStatus } = usePopoverTransitionContext() ?? { transitionStatus: undefined };
|
|
21
21
|
|
|
22
22
|
const open = store.useState('open');
|
|
23
|
+
const triggerWidth = store.useState('triggerWidth');
|
|
24
|
+
const triggerHeight = store.useState('triggerHeight');
|
|
23
25
|
const titleElementId = store.useState('titleElementId');
|
|
24
26
|
const descriptionElementId = store.useState('descriptionElementId');
|
|
25
27
|
|
|
26
|
-
const state: PopoverPopupState = {
|
|
28
|
+
const state: PopoverPopupState = {
|
|
29
|
+
open,
|
|
30
|
+
transitionStatus,
|
|
31
|
+
side,
|
|
32
|
+
align,
|
|
33
|
+
triggerWidth,
|
|
34
|
+
triggerHeight,
|
|
35
|
+
};
|
|
27
36
|
|
|
28
37
|
return useRenderElement(View, componentProps, {
|
|
29
38
|
state,
|
|
@@ -61,6 +70,16 @@ export interface PopoverPopupState {
|
|
|
61
70
|
* The alignment the popup was actually placed with.
|
|
62
71
|
*/
|
|
63
72
|
align: Align;
|
|
73
|
+
/**
|
|
74
|
+
* The trigger's measured width, available for consumers to size the popup
|
|
75
|
+
* against its anchor. This is the React Native equivalent of the web's
|
|
76
|
+
* `--anchor-width` CSS variable.
|
|
77
|
+
*/
|
|
78
|
+
triggerWidth: number | undefined;
|
|
79
|
+
/**
|
|
80
|
+
* The trigger's measured height.
|
|
81
|
+
*/
|
|
82
|
+
triggerHeight: number | undefined;
|
|
64
83
|
}
|
|
65
84
|
|
|
66
85
|
export interface PopoverPopupProps extends ZestUIComponentProps<typeof View, PopoverPopupState> {}
|
|
@@ -38,6 +38,8 @@ export function PopoverPositioner(componentProps: PopoverPositioner.Props) {
|
|
|
38
38
|
usePopoverPortalContext();
|
|
39
39
|
const store = usePopoverRootContext();
|
|
40
40
|
const open = store.useState('open');
|
|
41
|
+
const triggerWidth = store.useState('triggerWidth');
|
|
42
|
+
const triggerHeight = store.useState('triggerHeight');
|
|
41
43
|
const triggerNode = store.useState('triggerNode');
|
|
42
44
|
|
|
43
45
|
const positioning = useAnchorPositioning({
|
|
@@ -72,6 +74,8 @@ export function PopoverPositioner(componentProps: PopoverPositioner.Props) {
|
|
|
72
74
|
open,
|
|
73
75
|
side: positioning.side,
|
|
74
76
|
align: positioning.align,
|
|
77
|
+
triggerWidth,
|
|
78
|
+
triggerHeight,
|
|
75
79
|
};
|
|
76
80
|
|
|
77
81
|
const contextValue: PopoverPositionerContext = React.useMemo(
|
|
@@ -114,6 +118,16 @@ export interface PopoverPositionerState {
|
|
|
114
118
|
* The alignment the popup was actually placed with.
|
|
115
119
|
*/
|
|
116
120
|
align: Align;
|
|
121
|
+
/**
|
|
122
|
+
* The trigger's measured width, available for consumers to size the popup
|
|
123
|
+
* against its anchor. This is the React Native equivalent of the web's
|
|
124
|
+
* `--anchor-width` CSS variable.
|
|
125
|
+
*/
|
|
126
|
+
triggerWidth: number | undefined;
|
|
127
|
+
/**
|
|
128
|
+
* The trigger's measured height.
|
|
129
|
+
*/
|
|
130
|
+
triggerHeight: number | undefined;
|
|
117
131
|
}
|
|
118
132
|
|
|
119
133
|
export interface PopoverPositionerProps
|
|
@@ -22,6 +22,15 @@ export type State = {
|
|
|
22
22
|
* different subtree from the Trigger, so the store is what carries it across.
|
|
23
23
|
*/
|
|
24
24
|
triggerNode: unknown;
|
|
25
|
+
/**
|
|
26
|
+
* The trigger's measured width, the React Native counterpart of the web's
|
|
27
|
+
* `--anchor-width` CSS variable.
|
|
28
|
+
*/
|
|
29
|
+
triggerWidth: number | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* The trigger's measured height.
|
|
32
|
+
*/
|
|
33
|
+
triggerHeight: number | undefined;
|
|
25
34
|
/**
|
|
26
35
|
* Set by the Positioner so the Trigger can request a reposition when it is
|
|
27
36
|
* laid out. React Native has no `autoUpdate`.
|
|
@@ -57,6 +66,8 @@ const selectors = {
|
|
|
57
66
|
descriptionElementId: createSelector((state: State) => state.descriptionElementId),
|
|
58
67
|
disablePointerDismissal: createSelector((state: State) => state.disablePointerDismissal),
|
|
59
68
|
triggerNode: createSelector((state: State) => state.triggerNode),
|
|
69
|
+
triggerWidth: createSelector((state: State) => state.triggerWidth),
|
|
70
|
+
triggerHeight: createSelector((state: State) => state.triggerHeight),
|
|
60
71
|
update: createSelector((state: State) => state.update),
|
|
61
72
|
payload: createSelector((state: State) => state.payload),
|
|
62
73
|
triggerId: createSelector((state: State) => state.triggerIdProp ?? state.triggerId),
|
|
@@ -75,6 +86,8 @@ export class PopoverStore extends ReactStore<Readonly<State>, Context, typeof se
|
|
|
75
86
|
descriptionElementId: undefined,
|
|
76
87
|
disablePointerDismissal: false,
|
|
77
88
|
triggerNode: null,
|
|
89
|
+
triggerWidth: undefined,
|
|
90
|
+
triggerHeight: undefined,
|
|
78
91
|
update: undefined,
|
|
79
92
|
payload: undefined,
|
|
80
93
|
triggerId: null,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import * as React from 'react';
|
|
3
|
-
import { Pressable, type GestureResponderEvent } from 'react-native';
|
|
3
|
+
import { Pressable, type GestureResponderEvent, type LayoutChangeEvent } from 'react-native';
|
|
4
4
|
import { PopoverRootContext } from '../root/PopoverRootContext';
|
|
5
5
|
import { useRenderElement } from '../../use-render/useRenderElement';
|
|
6
6
|
import { useButton } from '../../internals/use-button/useButton';
|
|
@@ -99,7 +99,10 @@ export function PopoverTrigger<Payload = unknown>(componentProps: PopoverTrigger
|
|
|
99
99
|
onPressOut() {
|
|
100
100
|
setPressed(false);
|
|
101
101
|
},
|
|
102
|
-
onLayout() {
|
|
102
|
+
onLayout(event: LayoutChangeEvent) {
|
|
103
|
+
const { width, height } = event.nativeEvent.layout;
|
|
104
|
+
store.set('triggerWidth', width);
|
|
105
|
+
store.set('triggerHeight', height);
|
|
103
106
|
// Nothing tracks the anchor globally in React Native, so a moved or
|
|
104
107
|
// resized trigger has to ask the positioner to recompute.
|
|
105
108
|
store.state.update?.();
|
|
@@ -62,7 +62,10 @@ export function ProgressRoot(componentProps: ProgressRoot.Props) {
|
|
|
62
62
|
: formatNumber(percentageValue / 100, locale, { style: 'percent' });
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
const state: ProgressRootState = React.useMemo(
|
|
65
|
+
const state: ProgressRootState = React.useMemo(
|
|
66
|
+
() => ({ status, value: clampedValue, min, max, percent: percentageValue, formattedValue }),
|
|
67
|
+
[status, clampedValue, min, max, percentageValue, formattedValue],
|
|
68
|
+
);
|
|
66
69
|
|
|
67
70
|
const contextValue: ProgressRootContext = React.useMemo(
|
|
68
71
|
() => ({ formattedValue, percentageValue, setLabelId, state, value }),
|
|
@@ -102,6 +105,27 @@ export interface ProgressRootState {
|
|
|
102
105
|
* The current status.
|
|
103
106
|
*/
|
|
104
107
|
status: ProgressStatus;
|
|
108
|
+
/**
|
|
109
|
+
* The current value, clamped into `[min, max]`, or `null` while indeterminate.
|
|
110
|
+
*/
|
|
111
|
+
value: number | null;
|
|
112
|
+
/**
|
|
113
|
+
* The minimum value.
|
|
114
|
+
*/
|
|
115
|
+
min: number;
|
|
116
|
+
/**
|
|
117
|
+
* The maximum value.
|
|
118
|
+
*/
|
|
119
|
+
max: number;
|
|
120
|
+
/**
|
|
121
|
+
* How far the value sits through the range, `0`–`100`, or `null` while
|
|
122
|
+
* indeterminate. This is what an indicator's width comes from.
|
|
123
|
+
*/
|
|
124
|
+
percent: number | null;
|
|
125
|
+
/**
|
|
126
|
+
* The value as text, through `format`/`locale`. Empty while indeterminate.
|
|
127
|
+
*/
|
|
128
|
+
formattedValue: string;
|
|
105
129
|
}
|
|
106
130
|
|
|
107
131
|
export interface ProgressRootProps extends ZestUIComponentProps<typeof View, ProgressRootState> {
|
|
@@ -29,7 +29,9 @@ export function RadioGroup<Value = any>(componentProps: RadioGroup.Props<Value>)
|
|
|
29
29
|
...elementProps
|
|
30
30
|
} = componentProps;
|
|
31
31
|
|
|
32
|
-
const { fieldDisabled, fieldProps,
|
|
32
|
+
const { fieldDisabled, fieldProps, markChanged, markTouched } = useFieldControlRegistration({
|
|
33
|
+
initialValue: defaultValue ?? valueProp,
|
|
34
|
+
});
|
|
33
35
|
|
|
34
36
|
const disabled = disabledProp || fieldDisabled;
|
|
35
37
|
|
|
@@ -49,7 +51,8 @@ export function RadioGroup<Value = any>(componentProps: RadioGroup.Props<Value>)
|
|
|
49
51
|
}
|
|
50
52
|
|
|
51
53
|
setCheckedValueUnwrapped(value);
|
|
52
|
-
|
|
54
|
+
markChanged(value);
|
|
55
|
+
markTouched(value);
|
|
53
56
|
},
|
|
54
57
|
);
|
|
55
58
|
|
|
@@ -25,6 +25,10 @@ export function SelectBackdrop(componentProps: SelectBackdrop.Props) {
|
|
|
25
25
|
{
|
|
26
26
|
style: StyleSheet.absoluteFill,
|
|
27
27
|
onPress(event: GestureResponderEvent) {
|
|
28
|
+
if (store.select('disablePointerDismissal')) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
28
32
|
store.setOpen(false, createChangeEventDetails(REASONS.outsidePress, event));
|
|
29
33
|
},
|
|
30
34
|
},
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { SelectRoot as Root } from './root/SelectRoot';
|
|
2
|
+
export { createSelectHandle as createHandle, SelectHandle as Handle } from './store/SelectHandle';
|
|
2
3
|
export { SelectLabel as Label } from './label/SelectLabel';
|
|
3
4
|
export { SelectTrigger as Trigger } from './trigger/SelectTrigger';
|
|
4
5
|
export { SelectValue as Value } from './value/SelectValue';
|
|
@@ -21,8 +21,17 @@ export function SelectPopup(componentProps: SelectPopup.Props) {
|
|
|
21
21
|
const { transitionStatus } = useSelectTransitionContext() ?? { transitionStatus: undefined };
|
|
22
22
|
|
|
23
23
|
const open = store.useState('open');
|
|
24
|
+
const triggerWidth = store.useState('triggerWidth');
|
|
25
|
+
const triggerHeight = store.useState('triggerHeight');
|
|
24
26
|
|
|
25
|
-
const state: SelectPopupState = {
|
|
27
|
+
const state: SelectPopupState = {
|
|
28
|
+
open,
|
|
29
|
+
transitionStatus,
|
|
30
|
+
side,
|
|
31
|
+
align,
|
|
32
|
+
triggerWidth,
|
|
33
|
+
triggerHeight,
|
|
34
|
+
};
|
|
26
35
|
|
|
27
36
|
const element = useRenderElement(View, componentProps, {
|
|
28
37
|
state,
|
|
@@ -59,6 +68,14 @@ export interface SelectPopupState {
|
|
|
59
68
|
* The alignment the popup was actually placed with.
|
|
60
69
|
*/
|
|
61
70
|
align: Align;
|
|
71
|
+
/**
|
|
72
|
+
* The trigger's measured width, available for consumers to apply to the popup.
|
|
73
|
+
*/
|
|
74
|
+
triggerWidth: number | undefined;
|
|
75
|
+
/**
|
|
76
|
+
* The trigger's measured height.
|
|
77
|
+
*/
|
|
78
|
+
triggerHeight: number | undefined;
|
|
62
79
|
}
|
|
63
80
|
|
|
64
81
|
export interface SelectPopupProps extends ZestUIComponentProps<typeof View, SelectPopupState> {}
|
|
@@ -39,6 +39,8 @@ export function SelectPositioner(componentProps: SelectPositioner.Props) {
|
|
|
39
39
|
const store = useSelectRootContext();
|
|
40
40
|
const open = store.useState('open');
|
|
41
41
|
const triggerNode = store.useState('triggerNode');
|
|
42
|
+
const triggerWidth = store.useState('triggerWidth');
|
|
43
|
+
const triggerHeight = store.useState('triggerHeight');
|
|
42
44
|
|
|
43
45
|
const positioning = useAnchorPositioning({
|
|
44
46
|
align,
|
|
@@ -65,7 +67,13 @@ export function SelectPositioner(componentProps: SelectPositioner.Props) {
|
|
|
65
67
|
|
|
66
68
|
const mergedRef = useMergedRefs(ref, refs.setFloating);
|
|
67
69
|
|
|
68
|
-
const state: SelectPositionerState = {
|
|
70
|
+
const state: SelectPositionerState = {
|
|
71
|
+
open,
|
|
72
|
+
side: positioning.side,
|
|
73
|
+
align: positioning.align,
|
|
74
|
+
triggerWidth,
|
|
75
|
+
triggerHeight,
|
|
76
|
+
};
|
|
69
77
|
|
|
70
78
|
const contextValue: SelectPositionerContext = React.useMemo(
|
|
71
79
|
() => ({ side: positioning.side, align: positioning.align, arrowRef, arrowStyles }),
|
|
@@ -97,6 +105,15 @@ export interface SelectPositionerState {
|
|
|
97
105
|
open: boolean;
|
|
98
106
|
side: Side;
|
|
99
107
|
align: Align;
|
|
108
|
+
/**
|
|
109
|
+
* The trigger's measured width, available for consumers to apply to the popup.
|
|
110
|
+
* This is the React Native equivalent of the web's `--anchor-width` CSS variable.
|
|
111
|
+
*/
|
|
112
|
+
triggerWidth: number | undefined;
|
|
113
|
+
/**
|
|
114
|
+
* The trigger's measured height.
|
|
115
|
+
*/
|
|
116
|
+
triggerHeight: number | undefined;
|
|
100
117
|
}
|
|
101
118
|
|
|
102
119
|
export interface SelectPositionerProps
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import { useRefWithInit } from '../../hooks/useRefWithInit';
|
|
4
|
+
import { useStableCallback } from '../../hooks/useStableCallback';
|
|
4
5
|
import { useTransitionStatus } from '../../internals/useTransitionStatus';
|
|
6
|
+
import { usePopupRootHandle } from '../../utils/popups/usePopupRootHandle';
|
|
7
|
+
import { useFieldControlRegistration } from '../../internals/field/useFieldControlRegistration';
|
|
5
8
|
import type { ZestChangeEventDetails } from '../../utils/createChangeEventDetails';
|
|
6
9
|
import type { REASONS } from '../../utils/reasons';
|
|
10
|
+
import type { SelectHandle } from '../store/SelectHandle';
|
|
7
11
|
import { SelectStore, type SelectItems } from '../store/SelectStore';
|
|
8
12
|
import { SelectRootContext } from './SelectRootContext';
|
|
9
13
|
import { SelectTransitionContext } from './SelectTransitionContext';
|
|
@@ -15,12 +19,18 @@ import { SelectTransitionContext } from './SelectTransitionContext';
|
|
|
15
19
|
* Unlike the web version there is no hidden `<select>`: React Native has no form
|
|
16
20
|
* submission, so `name`/`form` are omitted. Multi-select is not ported yet.
|
|
17
21
|
*/
|
|
18
|
-
export function SelectRoot<Value = any>(
|
|
22
|
+
export function SelectRoot<Value = any, Payload = unknown>(
|
|
23
|
+
props: SelectRoot.Props<Value, Payload>,
|
|
24
|
+
) {
|
|
19
25
|
const {
|
|
26
|
+
actionsRef,
|
|
20
27
|
children,
|
|
21
28
|
defaultOpen = false,
|
|
29
|
+
defaultTriggerId = null,
|
|
22
30
|
defaultValue,
|
|
23
|
-
|
|
31
|
+
disablePointerDismissal = false,
|
|
32
|
+
disabled: disabledProp = false,
|
|
33
|
+
handle,
|
|
24
34
|
items,
|
|
25
35
|
multiple = false,
|
|
26
36
|
onOpenChange,
|
|
@@ -28,9 +38,16 @@ export function SelectRoot<Value = any>(props: SelectRoot.Props<Value>) {
|
|
|
28
38
|
open,
|
|
29
39
|
readOnly = false,
|
|
30
40
|
required = false,
|
|
41
|
+
triggerId,
|
|
31
42
|
value,
|
|
32
43
|
} = props;
|
|
33
44
|
|
|
45
|
+
const { fieldDisabled, markChanged, markTouched } = useFieldControlRegistration({
|
|
46
|
+
initialValue: defaultValue ?? value ?? (multiple ? [] : undefined),
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const disabled = disabledProp || fieldDisabled;
|
|
50
|
+
|
|
34
51
|
const store = useRefWithInit(
|
|
35
52
|
() =>
|
|
36
53
|
new SelectStore({
|
|
@@ -45,18 +62,60 @@ export function SelectRoot<Value = any>(props: SelectRoot.Props<Value>) {
|
|
|
45
62
|
disabled,
|
|
46
63
|
readOnly,
|
|
47
64
|
required,
|
|
65
|
+
disablePointerDismissal,
|
|
66
|
+
triggerId: defaultTriggerId,
|
|
67
|
+
triggerIdProp: triggerId,
|
|
48
68
|
}),
|
|
49
69
|
).current;
|
|
50
70
|
|
|
71
|
+
// Wrapping the consumer's callbacks is what lets a select report itself to a
|
|
72
|
+
// surrounding `Field.Root`: choosing a value makes the field dirty, and
|
|
73
|
+
// closing the popup is the select's equivalent of a blur.
|
|
74
|
+
const handleValueChange = useStableCallback(
|
|
75
|
+
(nextValue: Value, eventDetails: SelectRoot.ChangeEventDetails) => {
|
|
76
|
+
onValueChange?.(nextValue, eventDetails);
|
|
77
|
+
|
|
78
|
+
if (eventDetails.isCanceled) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
markChanged(nextValue);
|
|
83
|
+
},
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
const handleOpenChange = useStableCallback(
|
|
87
|
+
(nextOpen: boolean, eventDetails: SelectRoot.ChangeEventDetails) => {
|
|
88
|
+
onOpenChange?.(nextOpen, eventDetails);
|
|
89
|
+
|
|
90
|
+
if (eventDetails.isCanceled || nextOpen) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
markTouched(store.select('value'));
|
|
95
|
+
},
|
|
96
|
+
);
|
|
97
|
+
|
|
51
98
|
store.useControlledProp('openProp', open);
|
|
52
99
|
store.useControlledProp('valueProp', value);
|
|
53
|
-
store.
|
|
54
|
-
store.useContextCallback('
|
|
55
|
-
store.
|
|
100
|
+
store.useControlledProp('triggerIdProp', triggerId);
|
|
101
|
+
store.useContextCallback('onOpenChange', handleOpenChange);
|
|
102
|
+
store.useContextCallback('onValueChange', handleValueChange);
|
|
103
|
+
store.useSyncedValues({
|
|
104
|
+
disabled,
|
|
105
|
+
readOnly,
|
|
106
|
+
required,
|
|
107
|
+
items,
|
|
108
|
+
multiple,
|
|
109
|
+
disablePointerDismissal,
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
usePopupRootHandle({ store, handle, actionsRef });
|
|
56
113
|
|
|
57
114
|
const resolvedOpen = store.useState('open');
|
|
58
115
|
const { transitionStatus } = useTransitionStatus(resolvedOpen, false, true);
|
|
59
116
|
|
|
117
|
+
const payload = store.useState('payload') as Payload;
|
|
118
|
+
|
|
60
119
|
const transitionContextValue = React.useMemo(
|
|
61
120
|
() => ({ transitionStatus }),
|
|
62
121
|
[transitionStatus],
|
|
@@ -65,7 +124,7 @@ export function SelectRoot<Value = any>(props: SelectRoot.Props<Value>) {
|
|
|
65
124
|
return (
|
|
66
125
|
<SelectRootContext.Provider value={store}>
|
|
67
126
|
<SelectTransitionContext.Provider value={transitionContextValue}>
|
|
68
|
-
{children}
|
|
127
|
+
{typeof children === 'function' ? children(payload) : children}
|
|
69
128
|
</SelectTransitionContext.Provider>
|
|
70
129
|
</SelectRootContext.Provider>
|
|
71
130
|
);
|
|
@@ -73,7 +132,19 @@ export function SelectRoot<Value = any>(props: SelectRoot.Props<Value>) {
|
|
|
73
132
|
|
|
74
133
|
export interface SelectRootState {}
|
|
75
134
|
|
|
76
|
-
export interface
|
|
135
|
+
export interface SelectRootActions {
|
|
136
|
+
/**
|
|
137
|
+
* Unmounts the popup without firing `onOpenChange`. Call it after an
|
|
138
|
+
* externally controlled closing animation finishes.
|
|
139
|
+
*/
|
|
140
|
+
unmount: () => void;
|
|
141
|
+
/**
|
|
142
|
+
* Closes the popup, reporting the `imperative-action` reason.
|
|
143
|
+
*/
|
|
144
|
+
close: () => void;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export interface SelectRootProps<Value = any, Payload = unknown> {
|
|
77
148
|
/**
|
|
78
149
|
* The value of the currently selected item.
|
|
79
150
|
*
|
|
@@ -145,10 +216,38 @@ export interface SelectRootProps<Value = any> {
|
|
|
145
216
|
* ```
|
|
146
217
|
*/
|
|
147
218
|
items?: SelectItems | undefined;
|
|
219
|
+
/**
|
|
220
|
+
* Whether to prevent the popup from closing on presses outside it.
|
|
221
|
+
* @default false
|
|
222
|
+
*/
|
|
223
|
+
disablePointerDismissal?: boolean | undefined;
|
|
224
|
+
/**
|
|
225
|
+
* A ref to imperative actions.
|
|
226
|
+
*/
|
|
227
|
+
actionsRef?: React.RefObject<SelectRoot.Actions | null> | undefined;
|
|
228
|
+
/**
|
|
229
|
+
* A handle associating this select with triggers rendered outside it, and
|
|
230
|
+
* letting it be opened and closed imperatively. Create one with
|
|
231
|
+
* `Select.createHandle()`.
|
|
232
|
+
*/
|
|
233
|
+
handle?: SelectHandle<Payload> | undefined;
|
|
234
|
+
/**
|
|
235
|
+
* The id of the trigger the popup is anchored to. Useful together with the
|
|
236
|
+
* `open` prop, to control which trigger a controlled select belongs to.
|
|
237
|
+
*/
|
|
238
|
+
triggerId?: string | null | undefined;
|
|
239
|
+
/**
|
|
240
|
+
* The id of the trigger the popup is initially anchored to. Useful together
|
|
241
|
+
* with `defaultOpen`.
|
|
242
|
+
*/
|
|
243
|
+
defaultTriggerId?: string | null | undefined;
|
|
148
244
|
/**
|
|
149
245
|
* The content of the select.
|
|
246
|
+
*
|
|
247
|
+
* Pass a function to receive the payload the select was opened with, via a
|
|
248
|
+
* trigger's `payload` prop.
|
|
150
249
|
*/
|
|
151
|
-
children?: React.ReactNode;
|
|
250
|
+
children?: React.ReactNode | ((payload: Payload) => React.ReactNode);
|
|
152
251
|
}
|
|
153
252
|
|
|
154
253
|
export type SelectRootChangeEventReason =
|
|
@@ -163,7 +262,8 @@ export type SelectRootChangeEventDetails = ZestChangeEventDetails<SelectRootChan
|
|
|
163
262
|
|
|
164
263
|
export namespace SelectRoot {
|
|
165
264
|
export type State = SelectRootState;
|
|
166
|
-
export type Props<TValue = any> = SelectRootProps<TValue>;
|
|
265
|
+
export type Props<TValue = any, TPayload = unknown> = SelectRootProps<TValue, TPayload>;
|
|
266
|
+
export type Actions = SelectRootActions;
|
|
167
267
|
export type ChangeEventReason = SelectRootChangeEventReason;
|
|
168
268
|
export type ChangeEventDetails = SelectRootChangeEventDetails;
|
|
169
269
|
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { SelectStore } from './SelectStore';
|
|
2
|
+
import { BasePopupHandle } from '../../utils/popups/BasePopupHandle';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Controls a select imperatively, and associates `Select.Trigger`s rendered
|
|
6
|
+
* outside the root with it. Create one with `Select.createHandle()` and pass it
|
|
7
|
+
* to the root's and the triggers' `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
|
+
// `Payload` is unused in the class body but load-bearing in the public API: a
|
|
13
|
+
// `Select.Root`'s `handle?: SelectHandle<Payload>` prop is what infers the
|
|
14
|
+
// payload type its `children(payload)` receives.
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
16
|
+
export class SelectHandle<Payload = unknown> extends BasePopupHandle<SelectStore, SelectStore> {
|
|
17
|
+
constructor() {
|
|
18
|
+
// `true`: a select popup is anchored to its trigger, so opening it by an
|
|
19
|
+
// unknown trigger id is an error rather than a warning — there would be
|
|
20
|
+
// nothing to anchor to.
|
|
21
|
+
super(new SelectStore(), 'Select', true);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Points the positioner at the trigger the popup was opened by. Without this
|
|
26
|
+
* an imperative open would anchor to whatever was last pressed.
|
|
27
|
+
*/
|
|
28
|
+
protected override associateTrigger(store: SelectStore, triggerNode: unknown) {
|
|
29
|
+
if (triggerNode !== undefined) {
|
|
30
|
+
store.set('triggerNode', triggerNode);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Opens the popup, anchored to the trigger with the given id.
|
|
36
|
+
*
|
|
37
|
+
* Call this from an event handler or an effect, never during rendering.
|
|
38
|
+
*
|
|
39
|
+
* @param triggerId The `nativeID` of a mounted `Select.Trigger` carrying this handle.
|
|
40
|
+
*/
|
|
41
|
+
open(triggerId: string) {
|
|
42
|
+
this.openByTrigger(triggerId);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Closes the popup.
|
|
47
|
+
*
|
|
48
|
+
* Call this from an event handler or an effect, never during rendering.
|
|
49
|
+
*/
|
|
50
|
+
close() {
|
|
51
|
+
this.closePopup();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Whether the popup is open. `false` while no root is attached.
|
|
56
|
+
*/
|
|
57
|
+
get isOpen() {
|
|
58
|
+
return this.attachedStore?.select('open') ?? false;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Creates a handle that connects a `Select.Root` to `Select.Trigger`s rendered
|
|
64
|
+
* outside it, and controls it imperatively.
|
|
65
|
+
*/
|
|
66
|
+
export function createSelectHandle<Payload = unknown>(): SelectHandle<Payload> {
|
|
67
|
+
return new SelectHandle<Payload>();
|
|
68
|
+
}
|