@mortenbrudvik/waveui 0.4.0 → 0.7.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 +1221 -173
- package/dist/_virtual/_rolldown/runtime.cjs +1 -0
- package/dist/components/button/Button.cjs +2 -0
- package/dist/components/button/Button.cjs.map +1 -0
- package/dist/components/button/Button.mjs +50 -0
- package/dist/components/button/Button.mjs.map +1 -0
- package/dist/components/button/Button.semantics.cjs +2 -0
- package/dist/components/button/Button.semantics.cjs.map +1 -0
- package/dist/components/button/Button.semantics.mjs +61 -0
- package/dist/components/button/Button.semantics.mjs.map +1 -0
- package/dist/components/button/Button.slots.cjs +2 -0
- package/dist/components/button/Button.slots.cjs.map +1 -0
- package/dist/components/button/Button.slots.mjs +47 -0
- package/dist/components/button/Button.slots.mjs.map +1 -0
- package/dist/components/button/CompoundButton.cjs +2 -0
- package/dist/components/button/CompoundButton.cjs.map +1 -0
- package/dist/components/button/CompoundButton.mjs +53 -0
- package/dist/components/button/CompoundButton.mjs.map +1 -0
- package/dist/components/button/Link.cjs +2 -0
- package/dist/components/button/Link.cjs.map +1 -0
- package/dist/components/button/Link.mjs +37 -0
- package/dist/components/button/Link.mjs.map +1 -0
- package/dist/components/button/MenuButton.cjs +2 -0
- package/dist/components/button/MenuButton.cjs.map +1 -0
- package/dist/components/button/MenuButton.mjs +45 -0
- package/dist/components/button/MenuButton.mjs.map +1 -0
- package/dist/components/button/SplitButton.cjs +2 -0
- package/dist/components/button/SplitButton.cjs.map +1 -0
- package/dist/components/button/SplitButton.mjs +66 -0
- package/dist/components/button/SplitButton.mjs.map +1 -0
- package/dist/components/button/ToggleButton.cjs +2 -0
- package/dist/components/button/ToggleButton.cjs.map +1 -0
- package/dist/components/button/ToggleButton.mjs +65 -0
- package/dist/components/button/ToggleButton.mjs.map +1 -0
- package/dist/components/button/Toolbar.cjs +2 -0
- package/dist/components/button/Toolbar.cjs.map +1 -0
- package/dist/components/button/Toolbar.context.cjs +2 -0
- package/dist/components/button/Toolbar.context.cjs.map +1 -0
- package/dist/components/button/Toolbar.context.mjs +31 -0
- package/dist/components/button/Toolbar.context.mjs.map +1 -0
- package/dist/components/button/Toolbar.mjs +63 -0
- package/dist/components/button/Toolbar.mjs.map +1 -0
- package/dist/components/button/Toolbar.parts.cjs +2 -0
- package/dist/components/button/Toolbar.parts.cjs.map +1 -0
- package/dist/components/button/Toolbar.parts.mjs +131 -0
- package/dist/components/button/Toolbar.parts.mjs.map +1 -0
- package/dist/components/button/buttonStyles.cjs +2 -0
- package/dist/components/button/buttonStyles.cjs.map +1 -0
- package/dist/components/button/buttonStyles.mjs +39 -0
- package/dist/components/button/buttonStyles.mjs.map +1 -0
- package/dist/components/data-display/Avatar.cjs +2 -0
- package/dist/components/data-display/Avatar.cjs.map +1 -0
- package/dist/components/data-display/Avatar.mjs +157 -0
- package/dist/components/data-display/Avatar.mjs.map +1 -0
- package/dist/components/data-display/AvatarGroup.cjs +2 -0
- package/dist/components/data-display/AvatarGroup.cjs.map +1 -0
- package/dist/components/data-display/AvatarGroup.mjs +134 -0
- package/dist/components/data-display/AvatarGroup.mjs.map +1 -0
- package/dist/components/data-display/Badge.cjs +2 -0
- package/dist/components/data-display/Badge.cjs.map +1 -0
- package/dist/components/data-display/Badge.colors.cjs +2 -0
- package/dist/components/data-display/Badge.colors.cjs.map +1 -0
- package/dist/components/data-display/Badge.colors.mjs +58 -0
- package/dist/components/data-display/Badge.colors.mjs.map +1 -0
- package/dist/components/data-display/Badge.mjs +32 -0
- package/dist/components/data-display/Badge.mjs.map +1 -0
- package/dist/components/data-display/CounterBadge.cjs +2 -0
- package/dist/components/data-display/CounterBadge.cjs.map +1 -0
- package/dist/components/data-display/CounterBadge.mjs +28 -0
- package/dist/components/data-display/CounterBadge.mjs.map +1 -0
- package/dist/components/data-display/Divider.cjs +2 -0
- package/dist/components/data-display/Divider.cjs.map +1 -0
- package/dist/components/data-display/Divider.mjs +52 -0
- package/dist/components/data-display/Divider.mjs.map +1 -0
- package/dist/components/data-display/Image.cjs +2 -0
- package/dist/components/data-display/Image.cjs.map +1 -0
- package/dist/components/data-display/Image.mjs +32 -0
- package/dist/components/data-display/Image.mjs.map +1 -0
- package/dist/components/data-display/InfoLabel.cjs +2 -0
- package/dist/components/data-display/InfoLabel.cjs.map +1 -0
- package/dist/components/data-display/InfoLabel.mjs +104 -0
- package/dist/components/data-display/InfoLabel.mjs.map +1 -0
- package/dist/components/data-display/List.cjs +2 -0
- package/dist/components/data-display/List.cjs.map +1 -0
- package/dist/components/data-display/List.mjs +381 -0
- package/dist/components/data-display/List.mjs.map +1 -0
- package/dist/components/data-display/List.registry.cjs +2 -0
- package/dist/components/data-display/List.registry.cjs.map +1 -0
- package/dist/components/data-display/List.registry.mjs +101 -0
- package/dist/components/data-display/List.registry.mjs.map +1 -0
- package/dist/components/data-display/Persona.cjs +2 -0
- package/dist/components/data-display/Persona.cjs.map +1 -0
- package/dist/components/data-display/Persona.mjs +48 -0
- package/dist/components/data-display/Persona.mjs.map +1 -0
- package/dist/components/data-display/PresenceBadge.cjs +2 -0
- package/dist/components/data-display/PresenceBadge.cjs.map +1 -0
- package/dist/components/data-display/PresenceBadge.mjs +71 -0
- package/dist/components/data-display/PresenceBadge.mjs.map +1 -0
- package/dist/components/data-display/Tag.cjs +2 -0
- package/dist/components/data-display/Tag.cjs.map +1 -0
- package/dist/components/data-display/Tag.mjs +147 -0
- package/dist/components/data-display/Tag.mjs.map +1 -0
- package/dist/components/feedback/MessageBar.cjs +2 -0
- package/dist/components/feedback/MessageBar.cjs.map +1 -0
- package/dist/components/feedback/MessageBar.mjs +144 -0
- package/dist/components/feedback/MessageBar.mjs.map +1 -0
- package/dist/components/feedback/MessageBar.status.cjs +2 -0
- package/dist/components/feedback/MessageBar.status.cjs.map +1 -0
- package/dist/components/feedback/MessageBar.status.mjs +45 -0
- package/dist/components/feedback/MessageBar.status.mjs.map +1 -0
- package/dist/components/feedback/ProgressBar.cjs +2 -0
- package/dist/components/feedback/ProgressBar.cjs.map +1 -0
- package/dist/components/feedback/ProgressBar.mjs +72 -0
- package/dist/components/feedback/ProgressBar.mjs.map +1 -0
- package/dist/components/feedback/Skeleton.cjs +2 -0
- package/dist/components/feedback/Skeleton.cjs.map +1 -0
- package/dist/components/feedback/Skeleton.mjs +47 -0
- package/dist/components/feedback/Skeleton.mjs.map +1 -0
- package/dist/components/feedback/Spinner.cjs +2 -0
- package/dist/components/feedback/Spinner.cjs.map +1 -0
- package/dist/components/feedback/Spinner.mjs +60 -0
- package/dist/components/feedback/Spinner.mjs.map +1 -0
- package/dist/components/feedback/Toast.cjs +2 -0
- package/dist/components/feedback/Toast.cjs.map +1 -0
- package/dist/components/feedback/Toast.mjs +347 -0
- package/dist/components/feedback/Toast.mjs.map +1 -0
- package/dist/components/input/Checkbox.cjs +2 -0
- package/dist/components/input/Checkbox.cjs.map +1 -0
- package/dist/components/input/Checkbox.mjs +96 -0
- package/dist/components/input/Checkbox.mjs.map +1 -0
- package/dist/components/input/ColorPicker.cjs +6 -0
- package/dist/components/input/ColorPicker.cjs.map +1 -0
- package/dist/components/input/ColorPicker.mjs +236 -0
- package/dist/components/input/ColorPicker.mjs.map +1 -0
- package/dist/components/input/Combobox.cjs +2 -0
- package/dist/components/input/Combobox.cjs.map +1 -0
- package/dist/components/input/Combobox.expand.cjs +2 -0
- package/dist/components/input/Combobox.expand.cjs.map +1 -0
- package/dist/components/input/Combobox.expand.mjs +38 -0
- package/dist/components/input/Combobox.expand.mjs.map +1 -0
- package/dist/components/input/Combobox.mjs +187 -0
- package/dist/components/input/Combobox.mjs.map +1 -0
- package/dist/components/input/DatePicker.cjs +2 -0
- package/dist/components/input/DatePicker.cjs.map +1 -0
- package/dist/components/input/DatePicker.mjs +340 -0
- package/dist/components/input/DatePicker.mjs.map +1 -0
- package/dist/components/input/Dropdown.cjs +2 -0
- package/dist/components/input/Dropdown.cjs.map +1 -0
- package/dist/components/input/Dropdown.mjs +128 -0
- package/dist/components/input/Dropdown.mjs.map +1 -0
- package/dist/components/input/Field.cjs +2 -0
- package/dist/components/input/Field.cjs.map +1 -0
- package/dist/components/input/Field.mjs +200 -0
- package/dist/components/input/Field.mjs.map +1 -0
- package/dist/components/input/Input.cjs +2 -0
- package/dist/components/input/Input.cjs.map +1 -0
- package/dist/components/input/Input.mjs +81 -0
- package/dist/components/input/Input.mjs.map +1 -0
- package/dist/components/input/Label.cjs +2 -0
- package/dist/components/input/Label.cjs.map +1 -0
- package/dist/components/input/Label.mjs +28 -0
- package/dist/components/input/Label.mjs.map +1 -0
- package/dist/components/input/Option.cjs +2 -0
- package/dist/components/input/Option.cjs.map +1 -0
- package/dist/components/input/Option.mjs +169 -0
- package/dist/components/input/Option.mjs.map +1 -0
- package/dist/components/input/RadioGroup.cjs +2 -0
- package/dist/components/input/RadioGroup.cjs.map +1 -0
- package/dist/components/input/RadioGroup.mjs +139 -0
- package/dist/components/input/RadioGroup.mjs.map +1 -0
- package/dist/components/input/Rating.cjs +2 -0
- package/dist/components/input/Rating.cjs.map +1 -0
- package/dist/components/input/Rating.mjs +196 -0
- package/dist/components/input/Rating.mjs.map +1 -0
- package/dist/components/input/SearchBox.cjs +2 -0
- package/dist/components/input/SearchBox.cjs.map +1 -0
- package/dist/components/input/SearchBox.mjs +205 -0
- package/dist/components/input/SearchBox.mjs.map +1 -0
- package/dist/components/input/Select.cjs +2 -0
- package/dist/components/input/Select.cjs.map +1 -0
- package/dist/components/input/Select.mjs +33 -0
- package/dist/components/input/Select.mjs.map +1 -0
- package/dist/components/input/Slider.cjs +2 -0
- package/dist/components/input/Slider.cjs.map +1 -0
- package/dist/components/input/Slider.mjs +79 -0
- package/dist/components/input/Slider.mjs.map +1 -0
- package/dist/components/input/SpinButton.cjs +2 -0
- package/dist/components/input/SpinButton.cjs.map +1 -0
- package/dist/components/input/SpinButton.mjs +157 -0
- package/dist/components/input/SpinButton.mjs.map +1 -0
- package/dist/components/input/SwatchPicker.cjs +2 -0
- package/dist/components/input/SwatchPicker.cjs.map +1 -0
- package/dist/components/input/SwatchPicker.mjs +113 -0
- package/dist/components/input/SwatchPicker.mjs.map +1 -0
- package/dist/components/input/Switch.cjs +2 -0
- package/dist/components/input/Switch.cjs.map +1 -0
- package/dist/components/input/Switch.mjs +92 -0
- package/dist/components/input/Switch.mjs.map +1 -0
- package/dist/components/input/TagPicker.cjs +2 -0
- package/dist/components/input/TagPicker.cjs.map +1 -0
- package/dist/components/input/TagPicker.mjs +249 -0
- package/dist/components/input/TagPicker.mjs.map +1 -0
- package/dist/components/input/Textarea.cjs +2 -0
- package/dist/components/input/Textarea.cjs.map +1 -0
- package/dist/components/input/Textarea.mjs +32 -0
- package/dist/components/input/Textarea.mjs.map +1 -0
- package/dist/components/input/TimePicker.cjs +2 -0
- package/dist/components/input/TimePicker.cjs.map +1 -0
- package/dist/components/input/TimePicker.mjs +292 -0
- package/dist/components/input/TimePicker.mjs.map +1 -0
- package/dist/components/input/colorUtils.cjs +2 -0
- package/dist/components/input/colorUtils.cjs.map +1 -0
- package/dist/components/input/colorUtils.mjs +96 -0
- package/dist/components/input/colorUtils.mjs.map +1 -0
- package/dist/components/input/dateUtils.cjs +2 -0
- package/dist/components/input/dateUtils.cjs.map +1 -0
- package/dist/components/input/dateUtils.mjs +250 -0
- package/dist/components/input/dateUtils.mjs.map +1 -0
- package/dist/components/input/pickerStyles.cjs +2 -0
- package/dist/components/input/pickerStyles.cjs.map +1 -0
- package/dist/components/input/pickerStyles.mjs +10 -0
- package/dist/components/input/pickerStyles.mjs.map +1 -0
- package/dist/components/internal/HiddenInput.cjs +2 -0
- package/dist/components/internal/HiddenInput.cjs.map +1 -0
- package/dist/components/internal/HiddenInput.mjs +88 -0
- package/dist/components/internal/HiddenInput.mjs.map +1 -0
- package/dist/components/layout/Accordion.cjs +2 -0
- package/dist/components/layout/Accordion.cjs.map +1 -0
- package/dist/components/layout/Accordion.mjs +236 -0
- package/dist/components/layout/Accordion.mjs.map +1 -0
- package/dist/components/layout/Card.cjs +2 -0
- package/dist/components/layout/Card.cjs.map +1 -0
- package/dist/components/layout/Card.mjs +121 -0
- package/dist/components/layout/Card.mjs.map +1 -0
- package/dist/components/layout/Carousel.cjs +2 -0
- package/dist/components/layout/Carousel.cjs.map +1 -0
- package/dist/components/layout/Carousel.mjs +205 -0
- package/dist/components/layout/Carousel.mjs.map +1 -0
- package/dist/components/layout/Flex.cjs +2 -0
- package/dist/components/layout/Flex.cjs.map +1 -0
- package/dist/components/layout/Flex.mjs +54 -0
- package/dist/components/layout/Flex.mjs.map +1 -0
- package/dist/components/layout/Grid.cjs +2 -0
- package/dist/components/layout/Grid.cjs.map +1 -0
- package/dist/components/layout/Grid.mjs +62 -0
- package/dist/components/layout/Grid.mjs.map +1 -0
- package/dist/components/layout/Overflow.cjs +2 -0
- package/dist/components/layout/Overflow.cjs.map +1 -0
- package/dist/components/layout/Overflow.mjs +269 -0
- package/dist/components/layout/Overflow.mjs.map +1 -0
- package/dist/components/layout/Stack.cjs +2 -0
- package/dist/components/layout/Stack.cjs.map +1 -0
- package/dist/components/layout/Stack.mjs +39 -0
- package/dist/components/layout/Stack.mjs.map +1 -0
- package/dist/components/layout/TabList.cjs +2 -0
- package/dist/components/layout/TabList.cjs.map +1 -0
- package/dist/components/layout/TabList.mjs +238 -0
- package/dist/components/layout/TabList.mjs.map +1 -0
- package/dist/components/layout/Tree.cjs +2 -0
- package/dist/components/layout/Tree.cjs.map +1 -0
- package/dist/components/layout/Tree.mjs +220 -0
- package/dist/components/layout/Tree.mjs.map +1 -0
- package/dist/components/layout/disclosureIds.cjs +2 -0
- package/dist/components/layout/disclosureIds.cjs.map +1 -0
- package/dist/components/layout/disclosureIds.mjs +12 -0
- package/dist/components/layout/disclosureIds.mjs.map +1 -0
- package/dist/components/motion/Presence.cjs +2 -0
- package/dist/components/motion/Presence.cjs.map +1 -0
- package/dist/components/motion/Presence.mjs +35 -0
- package/dist/components/motion/Presence.mjs.map +1 -0
- package/dist/components/navigation/Breadcrumb.cjs +2 -0
- package/dist/components/navigation/Breadcrumb.cjs.map +1 -0
- package/dist/components/navigation/Breadcrumb.mjs +144 -0
- package/dist/components/navigation/Breadcrumb.mjs.map +1 -0
- package/dist/components/navigation/Menu.cjs +2 -0
- package/dist/components/navigation/Menu.cjs.map +1 -0
- package/dist/components/navigation/Menu.context.cjs +2 -0
- package/dist/components/navigation/Menu.context.cjs.map +1 -0
- package/dist/components/navigation/Menu.context.mjs +82 -0
- package/dist/components/navigation/Menu.context.mjs.map +1 -0
- package/dist/components/navigation/Menu.group.cjs +2 -0
- package/dist/components/navigation/Menu.group.cjs.map +1 -0
- package/dist/components/navigation/Menu.group.mjs +58 -0
- package/dist/components/navigation/Menu.group.mjs.map +1 -0
- package/dist/components/navigation/Menu.items.cjs +2 -0
- package/dist/components/navigation/Menu.items.cjs.map +1 -0
- package/dist/components/navigation/Menu.items.mjs +127 -0
- package/dist/components/navigation/Menu.items.mjs.map +1 -0
- package/dist/components/navigation/Menu.link.cjs +2 -0
- package/dist/components/navigation/Menu.link.cjs.map +1 -0
- package/dist/components/navigation/Menu.link.mjs +41 -0
- package/dist/components/navigation/Menu.link.mjs.map +1 -0
- package/dist/components/navigation/Menu.mjs +27 -0
- package/dist/components/navigation/Menu.mjs.map +1 -0
- package/dist/components/navigation/Menu.popover.cjs +2 -0
- package/dist/components/navigation/Menu.popover.cjs.map +1 -0
- package/dist/components/navigation/Menu.popover.mjs +231 -0
- package/dist/components/navigation/Menu.popover.mjs.map +1 -0
- package/dist/components/navigation/Menu.root.cjs +2 -0
- package/dist/components/navigation/Menu.root.cjs.map +1 -0
- package/dist/components/navigation/Menu.root.mjs +308 -0
- package/dist/components/navigation/Menu.root.mjs.map +1 -0
- package/dist/components/navigation/Menu.selectable.cjs +2 -0
- package/dist/components/navigation/Menu.selectable.cjs.map +1 -0
- package/dist/components/navigation/Menu.selectable.mjs +89 -0
- package/dist/components/navigation/Menu.selectable.mjs.map +1 -0
- package/dist/components/navigation/Menu.shared.cjs +2 -0
- package/dist/components/navigation/Menu.shared.cjs.map +1 -0
- package/dist/components/navigation/Menu.shared.mjs +23 -0
- package/dist/components/navigation/Menu.shared.mjs.map +1 -0
- package/dist/components/navigation/Menu.splitGroup.cjs +2 -0
- package/dist/components/navigation/Menu.splitGroup.cjs.map +1 -0
- package/dist/components/navigation/Menu.splitGroup.mjs +51 -0
- package/dist/components/navigation/Menu.splitGroup.mjs.map +1 -0
- package/dist/components/navigation/Menu.trigger.cjs +2 -0
- package/dist/components/navigation/Menu.trigger.cjs.map +1 -0
- package/dist/components/navigation/Menu.trigger.mjs +79 -0
- package/dist/components/navigation/Menu.trigger.mjs.map +1 -0
- package/dist/components/navigation/Nav.cjs +2 -0
- package/dist/components/navigation/Nav.cjs.map +1 -0
- package/dist/components/navigation/Nav.mjs +276 -0
- package/dist/components/navigation/Nav.mjs.map +1 -0
- package/dist/components/navigation/Pagination.cjs +2 -0
- package/dist/components/navigation/Pagination.cjs.map +1 -0
- package/dist/components/navigation/Pagination.mjs +110 -0
- package/dist/components/navigation/Pagination.mjs.map +1 -0
- package/dist/components/navigation/Stepper.cjs +2 -0
- package/dist/components/navigation/Stepper.cjs.map +1 -0
- package/dist/components/navigation/Stepper.mjs +204 -0
- package/dist/components/navigation/Stepper.mjs.map +1 -0
- package/dist/components/overlays/Dialog.cjs +2 -0
- package/dist/components/overlays/Dialog.cjs.map +1 -0
- package/dist/components/overlays/Dialog.mjs +180 -0
- package/dist/components/overlays/Dialog.mjs.map +1 -0
- package/dist/components/overlays/Dialog.shared.cjs +2 -0
- package/dist/components/overlays/Dialog.shared.cjs.map +1 -0
- package/dist/components/overlays/Dialog.shared.mjs +227 -0
- package/dist/components/overlays/Dialog.shared.mjs.map +1 -0
- package/dist/components/overlays/Drawer.cjs +2 -0
- package/dist/components/overlays/Drawer.cjs.map +1 -0
- package/dist/components/overlays/Drawer.mjs +192 -0
- package/dist/components/overlays/Drawer.mjs.map +1 -0
- package/dist/components/overlays/Popover.cjs +2 -0
- package/dist/components/overlays/Popover.cjs.map +1 -0
- package/dist/components/overlays/Popover.mjs +365 -0
- package/dist/components/overlays/Popover.mjs.map +1 -0
- package/dist/components/overlays/Popover.shared.cjs +2 -0
- package/dist/components/overlays/Popover.shared.cjs.map +1 -0
- package/dist/components/overlays/Popover.shared.mjs +182 -0
- package/dist/components/overlays/Popover.shared.mjs.map +1 -0
- package/dist/components/overlays/TeachingPopover.cjs +2 -0
- package/dist/components/overlays/TeachingPopover.cjs.map +1 -0
- package/dist/components/overlays/TeachingPopover.mjs +181 -0
- package/dist/components/overlays/TeachingPopover.mjs.map +1 -0
- package/dist/components/overlays/Tooltip.cjs +2 -0
- package/dist/components/overlays/Tooltip.cjs.map +1 -0
- package/dist/components/overlays/Tooltip.mjs +160 -0
- package/dist/components/overlays/Tooltip.mjs.map +1 -0
- package/dist/components/portal/Portal.cjs +2 -0
- package/dist/components/portal/Portal.cjs.map +1 -0
- package/dist/components/portal/Portal.mjs +45 -0
- package/dist/components/portal/Portal.mjs.map +1 -0
- package/dist/components/provider/WaveProvider.cjs +2 -0
- package/dist/components/provider/WaveProvider.cjs.map +1 -0
- package/dist/components/provider/WaveProvider.mjs +51 -0
- package/dist/components/provider/WaveProvider.mjs.map +1 -0
- package/dist/components/table/DataGrid.cjs +2 -0
- package/dist/components/table/DataGrid.cjs.map +1 -0
- package/dist/components/table/DataGrid.mjs +489 -0
- package/dist/components/table/DataGrid.mjs.map +1 -0
- package/dist/components/table/Table.cjs +2 -0
- package/dist/components/table/Table.cjs.map +1 -0
- package/dist/components/table/Table.mjs +99 -0
- package/dist/components/table/Table.mjs.map +1 -0
- package/dist/components/table/useGridNavigation.cjs +2 -0
- package/dist/components/table/useGridNavigation.cjs.map +1 -0
- package/dist/components/table/useGridNavigation.mjs +336 -0
- package/dist/components/table/useGridNavigation.mjs.map +1 -0
- package/dist/components/typography/Text.cjs +2 -0
- package/dist/components/typography/Text.cjs.map +1 -0
- package/dist/components/typography/Text.mjs +38 -0
- package/dist/components/typography/Text.mjs.map +1 -0
- package/dist/hooks/useAnnounce.cjs +2 -0
- package/dist/hooks/useAnnounce.cjs.map +1 -0
- package/dist/hooks/useAnnounce.mjs +88 -0
- package/dist/hooks/useAnnounce.mjs.map +1 -0
- package/dist/hooks/useCheckedValues.cjs +2 -0
- package/dist/hooks/useCheckedValues.cjs.map +1 -0
- package/dist/hooks/useCheckedValues.mjs +102 -0
- package/dist/hooks/useCheckedValues.mjs.map +1 -0
- package/dist/hooks/useContextMenuAnchor.cjs +2 -0
- package/dist/hooks/useContextMenuAnchor.cjs.map +1 -0
- package/dist/hooks/useContextMenuAnchor.mjs +132 -0
- package/dist/hooks/useContextMenuAnchor.mjs.map +1 -0
- package/dist/hooks/useControllable.cjs +2 -0
- package/dist/hooks/useControllable.cjs.map +1 -0
- package/dist/hooks/useControllable.mjs +37 -0
- package/dist/hooks/useControllable.mjs.map +1 -0
- package/dist/hooks/useDirection.cjs +2 -0
- package/dist/hooks/useDirection.cjs.map +1 -0
- package/dist/hooks/useDirection.mjs +57 -0
- package/dist/hooks/useDirection.mjs.map +1 -0
- package/dist/hooks/useDismiss.cjs +2 -0
- package/dist/hooks/useDismiss.cjs.map +1 -0
- package/dist/hooks/useDismiss.mjs +57 -0
- package/dist/hooks/useDismiss.mjs.map +1 -0
- package/dist/hooks/useEventCallback.cjs +2 -0
- package/dist/hooks/useEventCallback.cjs.map +1 -0
- package/dist/hooks/useEventCallback.mjs +16 -0
- package/dist/hooks/useEventCallback.mjs.map +1 -0
- package/dist/hooks/useFieldControl.cjs +2 -0
- package/dist/hooks/useFieldControl.cjs.map +1 -0
- package/dist/hooks/useFieldControl.mjs +62 -0
- package/dist/hooks/useFieldControl.mjs.map +1 -0
- package/dist/hooks/useFocusTrap.cjs +2 -0
- package/dist/hooks/useFocusTrap.cjs.map +1 -0
- package/dist/hooks/useFocusTrap.mjs +266 -0
- package/dist/hooks/useFocusTrap.mjs.map +1 -0
- package/dist/hooks/useFormReset.cjs +2 -0
- package/dist/hooks/useFormReset.cjs.map +1 -0
- package/dist/hooks/useFormReset.mjs +33 -0
- package/dist/hooks/useFormReset.mjs.map +1 -0
- package/dist/hooks/useHoverIntent.cjs +2 -0
- package/dist/hooks/useHoverIntent.cjs.map +1 -0
- package/dist/hooks/useHoverIntent.mjs +201 -0
- package/dist/hooks/useHoverIntent.mjs.map +1 -0
- package/dist/hooks/useId.cjs +2 -0
- package/dist/hooks/useId.cjs.map +1 -0
- package/dist/hooks/useId.mjs +11 -0
- package/dist/hooks/useId.mjs.map +1 -0
- package/dist/hooks/useIsClient.cjs +2 -0
- package/dist/hooks/useIsClient.cjs.map +1 -0
- package/dist/hooks/useIsClient.mjs +19 -0
- package/dist/hooks/useIsClient.mjs.map +1 -0
- package/dist/hooks/useListbox.cjs +2 -0
- package/dist/hooks/useListbox.cjs.map +1 -0
- package/dist/hooks/useListbox.mjs +492 -0
- package/dist/hooks/useListbox.mjs.map +1 -0
- package/dist/hooks/useMergedRefs.cjs +2 -0
- package/dist/hooks/useMergedRefs.cjs.map +1 -0
- package/dist/hooks/useMergedRefs.mjs +57 -0
- package/dist/hooks/useMergedRefs.mjs.map +1 -0
- package/dist/hooks/useModalIsolation.cjs +2 -0
- package/dist/hooks/useModalIsolation.cjs.map +1 -0
- package/dist/hooks/useModalIsolation.mjs +87 -0
- package/dist/hooks/useModalIsolation.mjs.map +1 -0
- package/dist/hooks/useModalLayer.cjs +2 -0
- package/dist/hooks/useModalLayer.cjs.map +1 -0
- package/dist/hooks/useModalLayer.mjs +30 -0
- package/dist/hooks/useModalLayer.mjs.map +1 -0
- package/dist/hooks/usePopupPosition.cjs +2 -0
- package/dist/hooks/usePopupPosition.cjs.map +1 -0
- package/dist/hooks/usePopupPosition.mjs +117 -0
- package/dist/hooks/usePopupPosition.mjs.map +1 -0
- package/dist/hooks/usePrefersReducedMotion.cjs +2 -0
- package/dist/hooks/usePrefersReducedMotion.cjs.map +1 -0
- package/dist/hooks/usePrefersReducedMotion.mjs +24 -0
- package/dist/hooks/usePrefersReducedMotion.mjs.map +1 -0
- package/dist/hooks/usePresence.cjs +2 -0
- package/dist/hooks/usePresence.cjs.map +1 -0
- package/dist/hooks/usePresence.mjs +136 -0
- package/dist/hooks/usePresence.mjs.map +1 -0
- package/dist/hooks/usePreserveFocus.cjs +2 -0
- package/dist/hooks/usePreserveFocus.cjs.map +1 -0
- package/dist/hooks/usePreserveFocus.mjs +50 -0
- package/dist/hooks/usePreserveFocus.mjs.map +1 -0
- package/dist/hooks/useRestoreFocus.cjs +2 -0
- package/dist/hooks/useRestoreFocus.cjs.map +1 -0
- package/dist/hooks/useRestoreFocus.mjs +271 -0
- package/dist/hooks/useRestoreFocus.mjs.map +1 -0
- package/dist/hooks/useRovingTabIndex.cjs +2 -0
- package/dist/hooks/useRovingTabIndex.cjs.map +1 -0
- package/dist/hooks/useRovingTabIndex.mjs +389 -0
- package/dist/hooks/useRovingTabIndex.mjs.map +1 -0
- package/dist/hooks/useScrollLock.cjs +2 -0
- package/dist/hooks/useScrollLock.cjs.map +1 -0
- package/dist/hooks/useScrollLock.mjs +71 -0
- package/dist/hooks/useScrollLock.mjs.map +1 -0
- package/dist/hooks/useTriggerElement.cjs +2 -0
- package/dist/hooks/useTriggerElement.cjs.map +1 -0
- package/dist/hooks/useTriggerElement.mjs +126 -0
- package/dist/hooks/useTriggerElement.mjs.map +1 -0
- package/dist/hooks/useTypeahead.cjs +2 -0
- package/dist/hooks/useTypeahead.cjs.map +1 -0
- package/dist/hooks/useTypeahead.mjs +38 -0
- package/dist/hooks/useTypeahead.mjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +9099 -0
- package/dist/index.d.ts +7688 -1027
- package/dist/index.mjs +91 -5695
- package/dist/lib/aria.cjs +2 -0
- package/dist/lib/aria.cjs.map +1 -0
- package/dist/lib/aria.mjs +29 -0
- package/dist/lib/aria.mjs.map +1 -0
- package/dist/lib/children.cjs +2 -0
- package/dist/lib/children.cjs.map +1 -0
- package/dist/lib/children.mjs +37 -0
- package/dist/lib/children.mjs.map +1 -0
- package/dist/lib/cn.cjs +2 -0
- package/dist/lib/cn.cjs.map +1 -0
- package/dist/lib/cn.mjs +64 -0
- package/dist/lib/cn.mjs.map +1 -0
- package/dist/lib/composeEventHandlers.cjs +2 -0
- package/dist/lib/composeEventHandlers.cjs.map +1 -0
- package/dist/lib/composeEventHandlers.mjs +11 -0
- package/dist/lib/composeEventHandlers.mjs.map +1 -0
- package/dist/lib/dev.cjs +2 -0
- package/dist/lib/dev.cjs.map +1 -0
- package/dist/lib/dev.mjs +42 -0
- package/dist/lib/dev.mjs.map +1 -0
- package/dist/lib/direction.cjs +2 -0
- package/dist/lib/direction.cjs.map +1 -0
- package/dist/lib/direction.mjs +35 -0
- package/dist/lib/direction.mjs.map +1 -0
- package/dist/lib/events.cjs +2 -0
- package/dist/lib/events.cjs.map +1 -0
- package/dist/lib/events.mjs +31 -0
- package/dist/lib/events.mjs.map +1 -0
- package/dist/lib/focus.cjs +2 -0
- package/dist/lib/focus.cjs.map +1 -0
- package/dist/lib/focus.mjs +119 -0
- package/dist/lib/focus.mjs.map +1 -0
- package/dist/lib/globalRegistry.cjs +2 -0
- package/dist/lib/globalRegistry.cjs.map +1 -0
- package/dist/lib/globalRegistry.mjs +13 -0
- package/dist/lib/globalRegistry.mjs.map +1 -0
- package/dist/lib/icons.cjs +2 -0
- package/dist/lib/icons.cjs.map +1 -0
- package/dist/lib/icons.mjs +254 -0
- package/dist/lib/icons.mjs.map +1 -0
- package/dist/lib/labelInName.cjs +2 -0
- package/dist/lib/labelInName.cjs.map +1 -0
- package/dist/lib/labelInName.mjs +54 -0
- package/dist/lib/labelInName.mjs.map +1 -0
- package/dist/lib/layers.cjs +2 -0
- package/dist/lib/layers.cjs.map +1 -0
- package/dist/lib/layers.mjs +224 -0
- package/dist/lib/layers.mjs.map +1 -0
- package/dist/lib/mergeProps.cjs +2 -0
- package/dist/lib/mergeProps.cjs.map +1 -0
- package/dist/lib/mergeProps.mjs +21 -0
- package/dist/lib/mergeProps.mjs.map +1 -0
- package/dist/lib/mergeRefs.cjs +2 -0
- package/dist/lib/mergeRefs.cjs.map +1 -0
- package/dist/lib/mergeRefs.mjs +29 -0
- package/dist/lib/mergeRefs.mjs.map +1 -0
- package/dist/lib/renderTrigger.cjs +2 -0
- package/dist/lib/renderTrigger.cjs.map +1 -0
- package/dist/lib/renderTrigger.mjs +29 -0
- package/dist/lib/renderTrigger.mjs.map +1 -0
- package/dist/lib/slot.cjs +2 -0
- package/dist/lib/slot.cjs.map +1 -0
- package/dist/lib/slot.mjs +122 -0
- package/dist/lib/slot.mjs.map +1 -0
- package/dist/lib/styles.cjs +2 -0
- package/dist/lib/styles.cjs.map +1 -0
- package/dist/lib/styles.mjs +16 -0
- package/dist/lib/styles.mjs.map +1 -0
- package/dist/lib/theme.cjs +2 -0
- package/dist/lib/theme.cjs.map +1 -0
- package/dist/lib/theme.mjs +16 -0
- package/dist/lib/theme.mjs.map +1 -0
- package/dist/preflight.css +2 -0
- package/dist/styles.css +2 -0
- package/package.json +149 -100
- package/src/styles/animations.css +7 -39
- package/src/styles/base.css +103 -0
- package/src/styles/globals.css +10 -22
- package/src/styles/legacy-tokens.css +184 -0
- package/src/styles/preflight.css +7 -0
- package/src/styles/styles.css +32 -0
- package/src/styles/tailwind.css +17 -0
- package/src/styles/tokens.css +561 -221
- package/src/styles/variants.css +29 -0
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";const e=require("../_virtual/_rolldown/runtime.cjs"),t=require("./useId.cjs"),n=require("../lib/layers.cjs");let r=require("react");r=e.__toESM(r,1);var i=r.createContext(null);i.displayName=`DismissLayerContext`;function a(e){return r.createElement(i.Provider,{value:e.layerId},e.children)}function o(e){let a=t.useId(`wave-layer`),o=r.useContext(i),s=(0,r.useRef)({options:e,parentId:o});(0,r.useInsertionEffect)(()=>{s.current={options:e,parentId:o}});let{open:c}=e;return(0,r.useLayoutEffect)(()=>{if(!c)return;let e=s;return n.registerLayer({id:a,get parentId(){return e.current.parentId},get kind(){return e.current.options.kind??`popover`},order:0,getElements:()=>e.current.options.refs.map(e=>e.current),getAnchor:()=>e.current.options.anchorRef?.current??null,get escape(){return e.current.options.escape??!0},get outsidePress(){return e.current.options.outsidePress??!0},get focusOutside(){return e.current.options.focusOutside??!1},onDismiss:(t,n)=>e.current.options.onDismiss(t,n)})},[c,a]),(0,r.useMemo)(()=>({layerId:a,isTopmost:()=>n.getTopmostLayer()?.id===a}),[a])}exports.DismissLayerContext=i,exports.DismissLayerProvider=a,exports.useDismiss=o;
|
|
2
|
+
//# sourceMappingURL=useDismiss.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDismiss.cjs","names":["React","useId","useRef","registerLayer","useMemo","getTopmostLayer","require_runtime","require_useId","require_layers","react","DismissLayerContext","DismissLayerProvider","props","useDismiss","layerId","parentId","latestRef","options","open","latest","ref","reason","event"],"sources":["../../src/hooks/useDismiss.ts"],"sourcesContent":["import * as React from 'react';\nimport { useInsertionEffect, useLayoutEffect, useMemo, useRef } from 'react';\nimport { useId } from './useId';\nimport {\n getTopmostLayer,\n registerLayer,\n type DismissReason,\n type LayerKind,\n type LayerRecord,\n} from '../lib/layers';\n\nexport type { DismissReason } from '../lib/layers';\n\n/** Options of {@link useDismiss}. */\nexport interface UseDismissOptions {\n /** Whether the layer is open; the layer is registered only while `true`. */\n open: boolean;\n /** Called when the layer should close (the component sets its `open` state to `false`). */\n onDismiss: (reason: DismissReason, event: Event) => void;\n /**\n * Elements that belong to the layer: the content surface, the trigger/anchor and any extra\n * targets that must not count as \"outside\" (read at event time).\n */\n refs: ReadonlyArray<React.RefObject<HTMLElement | null>>;\n /** The trigger; focus traps leave a descendant layer through it (Tab → the element after it). */\n anchorRef?: React.RefObject<HTMLElement | null>;\n /** @default 'popover' */\n kind?: LayerKind;\n /** Whether Escape dismisses the layer. @default true */\n escape?: boolean;\n /**\n * Whether a press outside the layer's tree dismisses it. A predicate receives the `pointerdown`\n * event; returning `false` ignores that press. @default true\n */\n outsidePress?: boolean | ((event: PointerEvent | MouseEvent) => boolean);\n /** Whether focus moving outside the layer's tree dismisses it (listboxes). @default false */\n focusOutside?: boolean;\n}\n\n/** Returned by {@link useDismiss}. */\nexport interface DismissLayer {\n /** The layer's id: pass it to `Portal layerId` or `DismissLayerProvider` around the surface. */\n layerId: string;\n /** Whether the layer is currently the topmost open layer (read at call time). */\n isTopmost(): boolean;\n}\n\n/**\n * The id of the enclosing dismiss layer. React context survives portals, so a popover opened from\n * inside a dialog knows the dialog is its parent layer. `null` outside any layer.\n */\nexport const DismissLayerContext: React.Context<string | null> = React.createContext<string | null>(\n null,\n);\nDismissLayerContext.displayName = 'DismissLayerContext';\n\n/**\n * Makes `layerId` the parent layer of everything rendered inside (`Portal layerId` does this for\n * its children automatically).\n */\nexport function DismissLayerProvider(props: {\n layerId: string;\n children: React.ReactNode;\n}): React.ReactElement {\n return React.createElement(\n DismissLayerContext.Provider,\n { value: props.layerId },\n props.children,\n );\n}\n\n/**\n * Registers an open overlay surface as a **dismiss layer** in the shared layer stack and closes it\n * on Escape, outside presses and (optionally) focus leaving it — with correct nesting:\n *\n * - **Escape** (document `keydown`, bubble phase) is routed by focus location: the innermost layer\n * whose tree contains the event target or the focused element is the scope, and the topmost\n * escape-enabled layer of that scope's subtree handles it — so a tooltip or popover opened from\n * the focused dialog closes before the dialog, while an unrelated layer opened later does not\n * steal the key. With no escape-enabled layer there, an escape-enabled ancestor handles it; when\n * no layer contains the focus (or none of those takes Escape), the global topmost\n * escape-enabled one. Layers stacked below the topmost **isolating** modal (a Dialog/Drawer\n * whose `useModalIsolation` is active — its ancestors and older siblings) never take Escape, so\n * a modal that ignores Escape blocks it whether it is nested in a dialog or opened beside it.\n * The handler calls `preventDefault()`. Events whose default is already prevented (an inner\n * widget consumed Escape) and IME composition events are ignored.\n * - **Outside press**: on `pointerdown` (capture) every open layer whose tree does not contain the\n * target is recorded; on the following `click` each recorded layer whose tree still does not\n * contain the click target is dismissed (children first). A drag from inside to outside never\n * dismisses, clicks inside nested portaled layers count as inside, a popup opened by the same\n * click survives, and an external toggle works. Layers stacked below the topmost isolating modal\n * are inert and never dismissed by presses on that modal or its backdrop; a `kind: 'modal'`\n * layer without isolation (the DatePicker calendar) shields nothing, so a page click closes it\n * and the layers around it. The pending press survives modifier keys (Shift/Ctrl+click) and\n * ends on Enter/Space, on `pointercancel`, or when no click follows a mouse `pointerup` in the\n * same task; touch and pen presses are kept until their click, which the browser dispatches\n * from a separate tap gesture.\n * - **Focus outside** (`focusOutside: true`): dismisses when focus moves outside the layer's tree.\n * That is decided in a microtask, once the current commit has run: an `autoFocus` field of a\n * popover, dialog or plain portal opened inside the layer gets focus before that surface's\n * portal and layer register, and keeps the layer open. Focus that is back inside the tree by\n * then keeps it open too.\n *\n * A layer's tree is its `refs`, the portal wrappers rendered inside it, its descendant layers and\n * the `[data-wave-focus-trap-allow]` regions (toasts). Parentage comes from\n * {@link DismissLayerContext}: wrap the surface in `Portal layerId={layerId}` (or\n * {@link DismissLayerProvider}) so layers opened inside it become its children.\n *\n * @example\n * const { layerId } = useDismiss({ open, onDismiss: () => setOpen(false), refs: [surfaceRef, triggerRef], anchorRef: triggerRef });\n * return open && <Portal layerId={layerId}><div ref={surfaceRef}>…</div></Portal>;\n */\nexport function useDismiss(options: UseDismissOptions): DismissLayer {\n const layerId = useId('wave-layer');\n const parentId = React.useContext(DismissLayerContext);\n const latestRef = useRef({ options, parentId });\n\n // Current before any layout effect or event handler of this commit reads it.\n useInsertionEffect(() => {\n latestRef.current = { options, parentId };\n });\n\n const { open } = options;\n\n useLayoutEffect(() => {\n if (!open) return;\n const latest = latestRef;\n const record: LayerRecord = {\n id: layerId,\n get parentId() {\n return latest.current.parentId;\n },\n get kind() {\n return latest.current.options.kind ?? 'popover';\n },\n order: 0,\n getElements: () => latest.current.options.refs.map((ref) => ref.current),\n getAnchor: () => latest.current.options.anchorRef?.current ?? null,\n get escape() {\n return latest.current.options.escape ?? true;\n },\n get outsidePress() {\n return latest.current.options.outsidePress ?? true;\n },\n get focusOutside() {\n return latest.current.options.focusOutside ?? false;\n },\n onDismiss: (reason, event) => latest.current.options.onDismiss(reason, event),\n };\n return registerLayer(record);\n }, [open, layerId]);\n\n return useMemo(\n () => ({\n layerId,\n isTopmost: () => getTopmostLayer()?.id === layerId,\n }),\n [layerId],\n );\n}\n"],"mappings":"kKAmDA,IAAaU,EAAoDV,EAAM,cACrE,IACF,EACA,EAAoB,YAAc,sBAMlC,SAAgBW,EAAqB,EAGd,CACrB,OAAOX,EAAM,cACXU,EAAoB,SACpB,CAAE,MAAOE,EAAM,OAAQ,EACvBA,EAAM,QACR,CACF,CA2CA,SAAgBC,EAAW,EAA0C,CACnE,IAAMC,EAAUb,EAAAA,MAAM,YAAY,EAC5Bc,EAAWf,EAAM,WAAWU,CAAmB,EAC/CM,GAAA,EAAYd,EAAAA,OAAAA,CAAO,CAAE,UAAS,UAAS,CAAC,GAG9C,EAAAO,EAAA,mBAAA,KAAyB,CACvB,EAAU,QAAU,CAAE,UAAS,UAAS,CAC1C,CAAC,EAED,GAAM,CAAE,QAASQ,EA8BjB,OA5BA,EAAAR,EAAA,gBAAA,KAAsB,CACpB,GAAI,CAACS,EAAM,OACX,IAAMC,EAASH,EAuBf,OAAOb,EAAAA,cAAc,CArBnB,GAAIW,EACJ,IAAI,UAAW,CACb,OAAOK,EAAO,QAAQ,QACxB,EACA,IAAI,MAAO,CACT,OAAOA,EAAO,QAAQ,QAAQ,MAAQ,SACxC,EACA,MAAO,EACP,gBAAmBA,EAAO,QAAQ,QAAQ,KAAK,IAAK,GAAQC,EAAI,OAAO,EACvE,cAAiBD,EAAO,QAAQ,QAAQ,WAAW,SAAW,KAC9D,IAAI,QAAS,CACX,OAAOA,EAAO,QAAQ,QAAQ,QAAU,EAC1C,EACA,IAAI,cAAe,CACjB,OAAOA,EAAO,QAAQ,QAAQ,cAAgB,EAChD,EACA,IAAI,cAAe,CACjB,OAAOA,EAAO,QAAQ,QAAQ,cAAgB,EAChD,EACA,WAAY,EAAQ,IAAUA,EAAO,QAAQ,QAAQ,UAAUE,EAAQC,CAAK,CAEzD,CAAM,CAC7B,EAAG,CAACJ,EAAMJ,CAAO,CAAC,GAElB,EAAOV,EAAAA,QAAAA,MACE,CACL,UACA,cAAiBC,EAAAA,gBAAgB,CAAC,EAAE,KAAOS,CAC7C,GACA,CAACA,CAAO,CACV,CACF"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useId as e } from "./useId.mjs";
|
|
3
|
+
import { getTopmostLayer as t, registerLayer as n } from "../lib/layers.mjs";
|
|
4
|
+
import * as r from "react";
|
|
5
|
+
import { useInsertionEffect as i, useLayoutEffect as a, useMemo as o, useRef as s } from "react";
|
|
6
|
+
//#region src/hooks/useDismiss.ts
|
|
7
|
+
var c = r.createContext(null);
|
|
8
|
+
c.displayName = "DismissLayerContext";
|
|
9
|
+
function l(e) {
|
|
10
|
+
return r.createElement(c.Provider, { value: e.layerId }, e.children);
|
|
11
|
+
}
|
|
12
|
+
function u(l) {
|
|
13
|
+
let u = e("wave-layer"), d = r.useContext(c), f = s({
|
|
14
|
+
options: l,
|
|
15
|
+
parentId: d
|
|
16
|
+
});
|
|
17
|
+
i(() => {
|
|
18
|
+
f.current = {
|
|
19
|
+
options: l,
|
|
20
|
+
parentId: d
|
|
21
|
+
};
|
|
22
|
+
});
|
|
23
|
+
let { open: p } = l;
|
|
24
|
+
return a(() => {
|
|
25
|
+
if (!p) return;
|
|
26
|
+
let e = f;
|
|
27
|
+
return n({
|
|
28
|
+
id: u,
|
|
29
|
+
get parentId() {
|
|
30
|
+
return e.current.parentId;
|
|
31
|
+
},
|
|
32
|
+
get kind() {
|
|
33
|
+
return e.current.options.kind ?? "popover";
|
|
34
|
+
},
|
|
35
|
+
order: 0,
|
|
36
|
+
getElements: () => e.current.options.refs.map((e) => e.current),
|
|
37
|
+
getAnchor: () => e.current.options.anchorRef?.current ?? null,
|
|
38
|
+
get escape() {
|
|
39
|
+
return e.current.options.escape ?? !0;
|
|
40
|
+
},
|
|
41
|
+
get outsidePress() {
|
|
42
|
+
return e.current.options.outsidePress ?? !0;
|
|
43
|
+
},
|
|
44
|
+
get focusOutside() {
|
|
45
|
+
return e.current.options.focusOutside ?? !1;
|
|
46
|
+
},
|
|
47
|
+
onDismiss: (t, n) => e.current.options.onDismiss(t, n)
|
|
48
|
+
});
|
|
49
|
+
}, [p, u]), o(() => ({
|
|
50
|
+
layerId: u,
|
|
51
|
+
isTopmost: () => t()?.id === u
|
|
52
|
+
}), [u]);
|
|
53
|
+
}
|
|
54
|
+
//#endregion
|
|
55
|
+
export { c as DismissLayerContext, l as DismissLayerProvider, u as useDismiss };
|
|
56
|
+
|
|
57
|
+
//# sourceMappingURL=useDismiss.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDismiss.mjs","names":["useId","useId$1","React","DismissLayerContext","DismissLayerProvider","props","useDismiss","layerId","parentId","latestRef","useRef","options","useLayoutEffect","open","latest","registerLayer","ref","reason","event","useMemo","getTopmostLayer"],"sources":["../../src/hooks/useDismiss.ts"],"sourcesContent":["import * as React from 'react';\nimport { useInsertionEffect, useLayoutEffect, useMemo, useRef } from 'react';\nimport { useId } from './useId';\nimport {\n getTopmostLayer,\n registerLayer,\n type DismissReason,\n type LayerKind,\n type LayerRecord,\n} from '../lib/layers';\n\nexport type { DismissReason } from '../lib/layers';\n\n/** Options of {@link useDismiss}. */\nexport interface UseDismissOptions {\n /** Whether the layer is open; the layer is registered only while `true`. */\n open: boolean;\n /** Called when the layer should close (the component sets its `open` state to `false`). */\n onDismiss: (reason: DismissReason, event: Event) => void;\n /**\n * Elements that belong to the layer: the content surface, the trigger/anchor and any extra\n * targets that must not count as \"outside\" (read at event time).\n */\n refs: ReadonlyArray<React.RefObject<HTMLElement | null>>;\n /** The trigger; focus traps leave a descendant layer through it (Tab → the element after it). */\n anchorRef?: React.RefObject<HTMLElement | null>;\n /** @default 'popover' */\n kind?: LayerKind;\n /** Whether Escape dismisses the layer. @default true */\n escape?: boolean;\n /**\n * Whether a press outside the layer's tree dismisses it. A predicate receives the `pointerdown`\n * event; returning `false` ignores that press. @default true\n */\n outsidePress?: boolean | ((event: PointerEvent | MouseEvent) => boolean);\n /** Whether focus moving outside the layer's tree dismisses it (listboxes). @default false */\n focusOutside?: boolean;\n}\n\n/** Returned by {@link useDismiss}. */\nexport interface DismissLayer {\n /** The layer's id: pass it to `Portal layerId` or `DismissLayerProvider` around the surface. */\n layerId: string;\n /** Whether the layer is currently the topmost open layer (read at call time). */\n isTopmost(): boolean;\n}\n\n/**\n * The id of the enclosing dismiss layer. React context survives portals, so a popover opened from\n * inside a dialog knows the dialog is its parent layer. `null` outside any layer.\n */\nexport const DismissLayerContext: React.Context<string | null> = React.createContext<string | null>(\n null,\n);\nDismissLayerContext.displayName = 'DismissLayerContext';\n\n/**\n * Makes `layerId` the parent layer of everything rendered inside (`Portal layerId` does this for\n * its children automatically).\n */\nexport function DismissLayerProvider(props: {\n layerId: string;\n children: React.ReactNode;\n}): React.ReactElement {\n return React.createElement(\n DismissLayerContext.Provider,\n { value: props.layerId },\n props.children,\n );\n}\n\n/**\n * Registers an open overlay surface as a **dismiss layer** in the shared layer stack and closes it\n * on Escape, outside presses and (optionally) focus leaving it — with correct nesting:\n *\n * - **Escape** (document `keydown`, bubble phase) is routed by focus location: the innermost layer\n * whose tree contains the event target or the focused element is the scope, and the topmost\n * escape-enabled layer of that scope's subtree handles it — so a tooltip or popover opened from\n * the focused dialog closes before the dialog, while an unrelated layer opened later does not\n * steal the key. With no escape-enabled layer there, an escape-enabled ancestor handles it; when\n * no layer contains the focus (or none of those takes Escape), the global topmost\n * escape-enabled one. Layers stacked below the topmost **isolating** modal (a Dialog/Drawer\n * whose `useModalIsolation` is active — its ancestors and older siblings) never take Escape, so\n * a modal that ignores Escape blocks it whether it is nested in a dialog or opened beside it.\n * The handler calls `preventDefault()`. Events whose default is already prevented (an inner\n * widget consumed Escape) and IME composition events are ignored.\n * - **Outside press**: on `pointerdown` (capture) every open layer whose tree does not contain the\n * target is recorded; on the following `click` each recorded layer whose tree still does not\n * contain the click target is dismissed (children first). A drag from inside to outside never\n * dismisses, clicks inside nested portaled layers count as inside, a popup opened by the same\n * click survives, and an external toggle works. Layers stacked below the topmost isolating modal\n * are inert and never dismissed by presses on that modal or its backdrop; a `kind: 'modal'`\n * layer without isolation (the DatePicker calendar) shields nothing, so a page click closes it\n * and the layers around it. The pending press survives modifier keys (Shift/Ctrl+click) and\n * ends on Enter/Space, on `pointercancel`, or when no click follows a mouse `pointerup` in the\n * same task; touch and pen presses are kept until their click, which the browser dispatches\n * from a separate tap gesture.\n * - **Focus outside** (`focusOutside: true`): dismisses when focus moves outside the layer's tree.\n * That is decided in a microtask, once the current commit has run: an `autoFocus` field of a\n * popover, dialog or plain portal opened inside the layer gets focus before that surface's\n * portal and layer register, and keeps the layer open. Focus that is back inside the tree by\n * then keeps it open too.\n *\n * A layer's tree is its `refs`, the portal wrappers rendered inside it, its descendant layers and\n * the `[data-wave-focus-trap-allow]` regions (toasts). Parentage comes from\n * {@link DismissLayerContext}: wrap the surface in `Portal layerId={layerId}` (or\n * {@link DismissLayerProvider}) so layers opened inside it become its children.\n *\n * @example\n * const { layerId } = useDismiss({ open, onDismiss: () => setOpen(false), refs: [surfaceRef, triggerRef], anchorRef: triggerRef });\n * return open && <Portal layerId={layerId}><div ref={surfaceRef}>…</div></Portal>;\n */\nexport function useDismiss(options: UseDismissOptions): DismissLayer {\n const layerId = useId('wave-layer');\n const parentId = React.useContext(DismissLayerContext);\n const latestRef = useRef({ options, parentId });\n\n // Current before any layout effect or event handler of this commit reads it.\n useInsertionEffect(() => {\n latestRef.current = { options, parentId };\n });\n\n const { open } = options;\n\n useLayoutEffect(() => {\n if (!open) return;\n const latest = latestRef;\n const record: LayerRecord = {\n id: layerId,\n get parentId() {\n return latest.current.parentId;\n },\n get kind() {\n return latest.current.options.kind ?? 'popover';\n },\n order: 0,\n getElements: () => latest.current.options.refs.map((ref) => ref.current),\n getAnchor: () => latest.current.options.anchorRef?.current ?? null,\n get escape() {\n return latest.current.options.escape ?? true;\n },\n get outsidePress() {\n return latest.current.options.outsidePress ?? true;\n },\n get focusOutside() {\n return latest.current.options.focusOutside ?? false;\n },\n onDismiss: (reason, event) => latest.current.options.onDismiss(reason, event),\n };\n return registerLayer(record);\n }, [open, layerId]);\n\n return useMemo(\n () => ({\n layerId,\n isTopmost: () => getTopmostLayer()?.id === layerId,\n }),\n [layerId],\n );\n}\n"],"mappings":";;;;;;AAmDA,IAAaG,IAAoDD,EAAM,cACrE,IACF;AACA,EAAoB,cAAc;AAMlC,SAAgBE,EAAqB,GAGd;CACrB,OAAOF,EAAM,cACXC,EAAoB,UACpB,EAAE,OAAOE,EAAM,QAAQ,GACvBA,EAAM,QACR;AACF;AA2CA,SAAgBC,EAAW,GAA0C;CACnE,IAAMC,IAAUP,EAAM,YAAY,GAC5BQ,IAAWN,EAAM,WAAWC,CAAmB,GAC/CM,IAAYC,EAAO;EAAE;EAAS;CAAS,CAAC;CAG9C,QAAyB;EACvB,EAAU,UAAU;GAAE;GAAS;EAAS;CAC1C,CAAC;CAED,IAAM,EAAE,YAASC;CA8BjB,OA5BAC,QAAsB;EACpB,IAAI,CAACC,GAAM;EACX,IAAMC,IAASL;EAuBf,OAAOM,EAAc;GArBnB,IAAIR;GACJ,IAAI,WAAW;IACb,OAAOO,EAAO,QAAQ;GACxB;GACA,IAAI,OAAO;IACT,OAAOA,EAAO,QAAQ,QAAQ,QAAQ;GACxC;GACA,OAAO;GACP,mBAAmBA,EAAO,QAAQ,QAAQ,KAAK,KAAK,MAAQE,EAAI,OAAO;GACvE,iBAAiBF,EAAO,QAAQ,QAAQ,WAAW,WAAW;GAC9D,IAAI,SAAS;IACX,OAAOA,EAAO,QAAQ,QAAQ,UAAU;GAC1C;GACA,IAAI,eAAe;IACjB,OAAOA,EAAO,QAAQ,QAAQ,gBAAgB;GAChD;GACA,IAAI,eAAe;IACjB,OAAOA,EAAO,QAAQ,QAAQ,gBAAgB;GAChD;GACA,YAAY,GAAQ,MAAUA,EAAO,QAAQ,QAAQ,UAAUG,GAAQC,CAAK;EAEzD,CAAM;CAC7B,GAAG,CAACL,GAAMN,CAAO,CAAC,GAEXY,SACE;EACL;EACA,iBAAiBC,EAAgB,CAAC,EAAE,OAAOb;CAC7C,IACA,CAACA,CAAO,CACV;AACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useEventCallback.cjs","names":["useRef","useCallback","react","useEventCallback","ref","fn","args","current"],"sources":["../../src/hooks/useEventCallback.ts"],"sourcesContent":["import { useCallback, useInsertionEffect, useRef } from 'react';\n\n/**\n * Returns a callback with a stable identity that always invokes the latest `fn` passed to the hook.\n * Use it for handlers read by effects or passed to memoised children, so neither re-runs when the\n * consumer passes a new inline function on every render.\n *\n * The latest `fn` is stored in an insertion effect, so it is current before any layout effect or\n * event handler runs. Do not call the returned function during render.\n *\n * Typing: for a required `fn` the result has exactly `fn`'s type `T` (overloads and generic call\n * signatures included); for an optional `fn` it is `(...args: Parameters<T>) => ReturnType<T> |\n * undefined`. The single function-type parameter of 0.4 is kept, so\n * `useEventCallback<(event: React.MouseEvent) => void>((event) => …)` still types an inline lambda.\n *\n * @example\n * const emitChange = useEventCallback(props.onValueChange); // optional prop\n * emitChange(next); // always a function; returns `undefined` while the prop is not given\n *\n * @param fn - The callback to wrap. May be `undefined`; calls are then no-ops that return `undefined`.\n * @returns A function with a stable identity that delegates to the latest `fn`.\n */\nexport function useEventCallback<T extends (...args: never[]) => unknown>(fn: T): T;\nexport function useEventCallback<T extends (...args: never[]) => unknown>(\n fn: T | undefined,\n): (...args: Parameters<T>) => ReturnType<T> | undefined;\nexport function useEventCallback<T extends (...args: never[]) => unknown>(\n fn: T | undefined,\n): (...args: Parameters<T>) => ReturnType<T> | undefined {\n const ref = useRef(fn);\n\n // useInsertionEffect runs before layout effects, so the ref is up to date before any effect or\n // event handler reads it.\n useInsertionEffect(() => {\n ref.current = fn;\n });\n\n return useCallback((...args: Parameters<T>) => {\n // `T` is only known to take `never[]`; calling it with its own parameters is sound.\n const current = ref.current as ((...params: Parameters<T>) => ReturnType<T>) | undefined;\n return current?.(...args);\n }, []);\n}\n"],"mappings":"oCA0BA,SAAgBG,EACd,EACuD,CACvD,IAAMC,GAAA,EAAMJ,EAAAA,OAAAA,CAAOK,CAAE,EAQrB,OAJA,EAAAH,EAAA,mBAAA,KAAyB,CACvB,EAAI,QAAUG,CAChB,CAAC,GAED,EAAOJ,EAAAA,YAAAA,EAAa,GAAGK,IAAwB,CAE7C,IAAMC,EAAUH,EAAI,QACpB,OAAOG,IAAU,GAAGD,CAAI,CAC1B,EAAG,CAAC,CAAC,CACP"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useCallback as e, useInsertionEffect as t, useRef as n } from "react";
|
|
3
|
+
//#region src/hooks/useEventCallback.ts
|
|
4
|
+
function r(r) {
|
|
5
|
+
let i = n(r);
|
|
6
|
+
return t(() => {
|
|
7
|
+
i.current = r;
|
|
8
|
+
}), e((...e) => {
|
|
9
|
+
let t = i.current;
|
|
10
|
+
return t?.(...e);
|
|
11
|
+
}, []);
|
|
12
|
+
}
|
|
13
|
+
//#endregion
|
|
14
|
+
export { r as useEventCallback };
|
|
15
|
+
|
|
16
|
+
//# sourceMappingURL=useEventCallback.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useEventCallback.mjs","names":["useEventCallback","ref","useRef","fn","useInsertionEffect","useCallback","args","current"],"sources":["../../src/hooks/useEventCallback.ts"],"sourcesContent":["import { useCallback, useInsertionEffect, useRef } from 'react';\n\n/**\n * Returns a callback with a stable identity that always invokes the latest `fn` passed to the hook.\n * Use it for handlers read by effects or passed to memoised children, so neither re-runs when the\n * consumer passes a new inline function on every render.\n *\n * The latest `fn` is stored in an insertion effect, so it is current before any layout effect or\n * event handler runs. Do not call the returned function during render.\n *\n * Typing: for a required `fn` the result has exactly `fn`'s type `T` (overloads and generic call\n * signatures included); for an optional `fn` it is `(...args: Parameters<T>) => ReturnType<T> |\n * undefined`. The single function-type parameter of 0.4 is kept, so\n * `useEventCallback<(event: React.MouseEvent) => void>((event) => …)` still types an inline lambda.\n *\n * @example\n * const emitChange = useEventCallback(props.onValueChange); // optional prop\n * emitChange(next); // always a function; returns `undefined` while the prop is not given\n *\n * @param fn - The callback to wrap. May be `undefined`; calls are then no-ops that return `undefined`.\n * @returns A function with a stable identity that delegates to the latest `fn`.\n */\nexport function useEventCallback<T extends (...args: never[]) => unknown>(fn: T): T;\nexport function useEventCallback<T extends (...args: never[]) => unknown>(\n fn: T | undefined,\n): (...args: Parameters<T>) => ReturnType<T> | undefined;\nexport function useEventCallback<T extends (...args: never[]) => unknown>(\n fn: T | undefined,\n): (...args: Parameters<T>) => ReturnType<T> | undefined {\n const ref = useRef(fn);\n\n // useInsertionEffect runs before layout effects, so the ref is up to date before any effect or\n // event handler reads it.\n useInsertionEffect(() => {\n ref.current = fn;\n });\n\n return useCallback((...args: Parameters<T>) => {\n // `T` is only known to take `never[]`; calling it with its own parameters is sound.\n const current = ref.current as ((...params: Parameters<T>) => ReturnType<T>) | undefined;\n return current?.(...args);\n }, []);\n}\n"],"mappings":";;;AA0BA,SAAgBA,EACd,GACuD;CACvD,IAAMC,IAAMC,EAAOC,CAAE;CAQrB,OAJAC,QAAyB;EACvB,EAAI,UAAUD;CAChB,CAAC,GAEME,GAAa,GAAGC,MAAwB;EAE7C,IAAMC,IAAUN,EAAI;EACpB,OAAOM,IAAU,GAAGD,CAAI;CAC1B,GAAG,CAAC,CAAC;AACP"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";const e=require("../_virtual/_rolldown/runtime.cjs"),t=require("./useId.cjs"),n=require("../lib/aria.cjs");let r=require("react");r=e.__toESM(r,1);var i=class{holder=void 0;mounted=new Set;listeners=new Set;version=0;claim=e=>(this.holder===void 0&&(this.holder=e),this.holder===e);mount=e=>(this.mounted.add(e),()=>{this.mounted.delete(e),this.holder===e&&this.free()});hold=e=>{this.holder===void 0?this.holder=e:this.holder!==e&&this.notify()};releaseStale=()=>{this.holder!==void 0&&!this.mounted.has(this.holder)&&this.free()};subscribe=e=>(this.listeners.add(e),()=>{this.listeners.delete(e)});getVersion=()=>this.version;free(){this.holder=void 0,this.notify()}notify(){this.version+=1;for(let e of Array.from(this.listeners))e()}};function a(){return new i}var o=()=>()=>{},s=()=>0,c=r.createContext(null);c.displayName=`FieldContext`;function l(){return r.useContext(c)}function u(e,i={}){let a=l(),c=t.useId(`field-control`),{labelable:u=!0,nativeRequired:d=!1}=i,f=a!==null&&e.id===void 0&&!a.controlIdAssigned,p=f?a.controlIdClaim:void 0;r.useSyncExternalStore(p?p.subscribe:o,p?p.getVersion:s,p?p.getVersion:s);let m=f&&(!p||p.claim(c));r.useLayoutEffect(()=>p?.mount(c),[p,c]),r.useLayoutEffect(()=>{p&&m&&p.hold(c)},[p,m,c]),r.useEffect(()=>{p&&!m&&p.releaseStale()});let h=e.id??(a===null?void 0:m?a.controlId:c),g=e[`aria-labelledby`];a&&e[`aria-label`]===void 0&&(!u||h!==a.controlId)&&(g=n.joinIds(g,a.labelId));let _=a?n.joinIds(e[`aria-describedby`],a.validationMessageId??a.errorId,a.hintId):e[`aria-describedby`],v=e[`aria-invalid`]??(a?.invalid||void 0),y=e[`aria-required`]??(e.required===!1?void 0:a?.required||void 0),b=d?e.required??(a?.required||void 0):void 0,x={};return h!==void 0&&(x.id=h),e[`aria-label`]!==void 0&&(x[`aria-label`]=e[`aria-label`]),g!==void 0&&(x[`aria-labelledby`]=g),_!==void 0&&(x[`aria-describedby`]=_),v!==void 0&&(x[`aria-invalid`]=v),y!==void 0&&(x[`aria-required`]=y),b!==void 0&&(x.required=b),x}exports.FieldContext=c,exports.createFieldControlIdClaim=a,exports.useFieldContext=l,exports.useFieldControl=u;
|
|
2
|
+
//# sourceMappingURL=useFieldControl.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useFieldControl.cjs","names":["React","useId","joinIds","require_runtime","require_useId","require_aria","react","FieldControlIdClaimStore","token","onChange","listener","createFieldControlIdClaim","subscribeNothing","noVersion","FieldContext","useFieldContext","useFieldControl","field","fallbackId","options","wantsControlId","props","claim","holdsControlId","id","labelledBy","labelable","describedBy","invalid","ariaRequired","required","nativeRequired","result"],"sources":["../../src/hooks/useFieldControl.ts"],"sourcesContent":["import * as React from 'react';\nimport { joinIds } from '../lib/aria';\nimport type { ValidationState } from '../lib/types';\nimport { useId } from './useId';\n\n/**\n * What a `Field` tells the controls inside it: the ids of its label, hint and validation message,\n * and its validation, invalid and required state. `Field` provides it; every library input reads\n * it through {@link useFieldControl}, and so can your own control.\n */\nexport interface FieldContextValue {\n /** The id the Field's `<label htmlFor>` points at. */\n controlId: string;\n /** The id of the Field's `<label>`, used for `aria-labelledby` on non-labelable controls. */\n labelId: string | undefined;\n /** The id of the rendered hint, if any. */\n hintId: string | undefined;\n /**\n * The id of the rendered error message, if any: set only while the validation message is an\n * error (see `validationMessageId` for every state).\n */\n errorId: string | undefined;\n /** Whether the Field is in an error state (only the `error` validation state is invalid). */\n invalid: boolean;\n /** Whether the Field is required. */\n required: boolean;\n /** Field renders the error message itself; controls with their own `error` must not repeat it. */\n hasErrorMessage: boolean;\n /**\n * Field already gave `controlId` to its first child, a label-for merge target (component,\n * labelable element, custom element), whether Field merged it or it was the child's own id; a\n * control that receives no `id` prop is then not that child (it is nested inside it, e.g.\n * `Field > Tooltip > Input`, or a later sibling) and must not reuse `controlId`.\n * {@link useFieldControl} gives such a control its own id and names it through\n * `aria-labelledby`. Absent or `false`: a control without an `id` uses `controlId`, subject to\n * `controlIdClaim`.\n */\n controlIdAssigned?: boolean;\n /**\n * Hands `controlId` to one control when `controlIdAssigned` is not set — Field left its first\n * child alone (a plain `<div>`, a Fragment), so every library control inside reads this context.\n * The first control without an `id` of its own takes `controlId`; the others get their own id\n * and are named through `aria-labelledby`, so no id is duplicated. `Field` creates one for each\n * Field. Absent: every control without an `id` uses `controlId`.\n */\n controlIdClaim?: FieldControlIdClaim;\n /**\n * The Field's validation state (`validationState`, or `'error'` from `error`). Absent in\n * contexts built before 0.6: read it as `invalid ? 'error' : 'none'`.\n */\n validationState?: ValidationState;\n /**\n * The id of the rendered validation message in any state (error, warning, success, neutral).\n * `errorId` is set only while that message is an error.\n */\n validationMessageId?: string;\n}\n\n/**\n * Decides which control inside a `Field` takes the Field's `controlId` (the id its\n * `<label htmlFor>` points at) when several library controls without an `id` of their own read\n * the same context. `Field` creates one for each Field and passes it as\n * {@link FieldContextValue.controlIdClaim}; {@link useFieldControl} calls the methods, so a\n * control never calls them itself.\n *\n * - The first control to render takes `controlId`: on the first render (and on the server, so\n * hydration matches) that is the first one in document order. It keeps it across re-renders.\n * - When the holder unmounts or stops wanting `controlId` (it gets an `id` of its own), the\n * subscribers are notified, re-render, and the first of them takes `controlId` over.\n * - A render that claimed `controlId` but never committed (a discarded concurrent render) does not\n * keep it: a mounted control that renders without `controlId` frees it.\n */\nexport interface FieldControlIdClaim {\n /**\n * During render, with the control's stable token (its `useId`): gives `controlId` to `token`\n * when no control holds it, and returns whether `token` holds it. Idempotent per token, so\n * StrictMode double renders and later re-renders agree.\n */\n claim(token: string): boolean;\n /**\n * From a layout effect while the control wants `controlId`: marks `token` mounted. The returned\n * cleanup frees `controlId` when `token` holds it and notifies the subscribers.\n */\n mount(token: string): () => void;\n /**\n * From a layout effect of the control that rendered with `controlId`: takes it again after a\n * StrictMode effect replay freed it; if another control took it meanwhile, notifies the\n * subscribers so both re-render and agree.\n */\n hold(token: string): void;\n /**\n * From a passive effect of a mounted control that rendered without `controlId`: frees\n * `controlId` when its holder is not mounted (its render was discarded) and notifies the\n * subscribers.\n */\n releaseStale(): void;\n /** Subscribes to changes of the holder (for `useSyncExternalStore`); returns the unsubscribe. */\n subscribe(onChange: () => void): () => void;\n /** A number that changes whenever the subscribers are notified (the store snapshot). */\n getVersion(): number;\n}\n\nclass FieldControlIdClaimStore implements FieldControlIdClaim {\n private holder: string | undefined = undefined;\n private readonly mounted = new Set<string>();\n private readonly listeners = new Set<() => void>();\n private version = 0;\n\n claim = (token: string): boolean => {\n if (this.holder === undefined) this.holder = token;\n return this.holder === token;\n };\n\n mount = (token: string): (() => void) => {\n this.mounted.add(token);\n return () => {\n this.mounted.delete(token);\n if (this.holder === token) this.free();\n };\n };\n\n hold = (token: string): void => {\n if (this.holder === undefined) this.holder = token;\n else if (this.holder !== token) this.notify();\n };\n\n releaseStale = (): void => {\n if (this.holder !== undefined && !this.mounted.has(this.holder)) this.free();\n };\n\n subscribe = (onChange: () => void): (() => void) => {\n this.listeners.add(onChange);\n return () => {\n this.listeners.delete(onChange);\n };\n };\n\n getVersion = (): number => this.version;\n\n private free(): void {\n this.holder = undefined;\n this.notify();\n }\n\n private notify(): void {\n this.version += 1;\n for (const listener of Array.from(this.listeners)) listener();\n }\n}\n\n/**\n * Creates the {@link FieldControlIdClaim} a Field puts into its context (one per Field instance,\n * e.g. `const [claim] = useState(createFieldControlIdClaim)`).\n *\n * @internal Not exported from the package.\n */\nexport function createFieldControlIdClaim(): FieldControlIdClaim {\n return new FieldControlIdClaimStore();\n}\n\nconst subscribeNothing = (): (() => void) => () => {};\nconst noVersion = (): number => 0;\n\n/**\n * Context provided by `Field`. `null` outside a Field (controls then use only their own props).\n */\nexport const FieldContext: React.Context<FieldContextValue | null> =\n React.createContext<FieldContextValue | null>(null);\nFieldContext.displayName = 'FieldContext';\n\n/** The surrounding Field's context value, or `null` when the control is not inside a Field. */\nexport function useFieldContext(): FieldContextValue | null {\n return React.useContext(FieldContext);\n}\n\n/** The labelling/validation props a control receives from its consumer and from its Field. */\nexport interface FieldControlProps {\n id?: string;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n 'aria-describedby'?: string;\n 'aria-invalid'?: React.AriaAttributes['aria-invalid'];\n 'aria-required'?: React.AriaAttributes['aria-required'];\n required?: boolean;\n}\n\n/** Options of {@link useFieldControl}. */\nexport interface UseFieldControlOptions {\n /**\n * Whether the focusable element can be the target of `<label htmlFor>` (`<input>`, `<button>`,\n * `<select>`, `<textarea>`). Non-labelable controls (`role=\"radiogroup\"`/`role=\"group\"` divs)\n * are named with `aria-labelledby` instead.\n * @default true\n */\n labelable?: boolean;\n /**\n * Whether the focusable element is a native form control (Input, Select, Textarea, Slider,\n * SpinButton's input), so the Field's `required` becomes the native `required` attribute and\n * constraint validation runs. Controls built on buttons or divs validate through `HiddenInput`.\n * @default false\n */\n nativeRequired?: boolean;\n}\n\n/**\n * Merges a control's own labelling props with its surrounding `Field`. Spread the result onto the\n * **focusable element** (for a control whose root wraps it, not onto the root). Consumer values\n * are merged, never overwritten, and only defined keys are returned, so spreading never clears an\n * attribute.\n *\n * - `id`: the consumer's id; else, when the Field already gave `controlId` to its first child\n * (`controlIdAssigned`) — so this control is nested inside that child or a later sibling — a\n * generated id of its own; else the Field's `controlId`, which only one control takes when the\n * Field provides a `controlIdClaim` (several controls inside a plain `<div>`: the first one\n * takes it, the others get a generated id of their own). The first child itself receives\n * `controlId` as its `id` prop from Field, so it keeps it.\n * - `aria-labelledby`: when the consumer set an `aria-label`, only the consumer's\n * `aria-labelledby`; otherwise, when the control is not labelable **or** its id is not the\n * Field's `controlId` (it carries its own id, or is not the Field's first child, so\n * `<label htmlFor>` does not reach it), the consumer's ids plus the Field's `labelId`.\n * - `aria-describedby`: the consumer's ids, then the Field's validation message\n * (`validationMessageId`, else `errorId`), then its hint (deduplicated). A warning, success or\n * neutral message describes the control too.\n * - `aria-invalid` / `aria-required`: the consumer's value, else `true` when the Field is\n * invalid/required (`aria-required`: not when the consumer passes `required={false}`). Only the\n * `error` validation state makes the Field invalid.\n * - `required`: only with `nativeRequired` — the consumer's value, else the Field's `required`.\n * - `aria-label`: passed through.\n *\n * @example\n * const fieldProps = useFieldControl({ id, 'aria-label': ariaLabel, 'aria-labelledby': labelledBy,\n * 'aria-describedby': describedBy, 'aria-invalid': ariaInvalid, 'aria-required': ariaRequired });\n * return <button role=\"switch\" {...fieldProps} />;\n */\nexport function useFieldControl(\n props: FieldControlProps,\n options: UseFieldControlOptions = {},\n): FieldControlProps {\n const field = useFieldContext();\n // Always called (stable hook order); used only when the Field's controlId is taken. It is also\n // the control's token in the Field's controlIdClaim.\n const fallbackId = useId('field-control');\n const { labelable = true, nativeRequired = false } = options;\n\n // A control without an id of its own wants the Field's controlId unless Field gave it to its\n // first child. With a claim, only the first such control takes it.\n const wantsControlId = field !== null && props.id === undefined && !field.controlIdAssigned;\n const claim = wantsControlId ? field.controlIdClaim : undefined;\n // Re-render when the controlId is freed, so the next control takes it over.\n React.useSyncExternalStore(\n claim ? claim.subscribe : subscribeNothing,\n claim ? claim.getVersion : noVersion,\n claim ? claim.getVersion : noVersion,\n );\n const holdsControlId = wantsControlId && (claim ? claim.claim(fallbackId) : true);\n // Layout effects do nothing on the server, and React 19 no longer warns about them there.\n React.useLayoutEffect(() => claim?.mount(fallbackId), [claim, fallbackId]);\n React.useLayoutEffect(() => {\n if (claim && holdsControlId) claim.hold(fallbackId);\n }, [claim, holdsControlId, fallbackId]);\n // After every commit (all layout effects of the commit, and so every mount, have run): a\n // control rendered without controlId frees one held by a render that never committed.\n React.useEffect(() => {\n if (claim && !holdsControlId) claim.releaseStale();\n });\n\n const id =\n props.id ?? (field === null ? undefined : holdsControlId ? field.controlId : fallbackId);\n\n let labelledBy = props['aria-labelledby'];\n if (field && props['aria-label'] === undefined && (!labelable || id !== field.controlId)) {\n labelledBy = joinIds(labelledBy, field.labelId);\n }\n\n // The message in any validation state (a context built before 0.6 has only `errorId`).\n const describedBy = field\n ? joinIds(props['aria-describedby'], field.validationMessageId ?? field.errorId, field.hintId)\n : props['aria-describedby'];\n const invalid = props['aria-invalid'] ?? (field?.invalid || undefined);\n // A consumer `required={false}` (native controls pass `required`) also keeps the Field's\n // required state out of aria-required, so the announced state matches native validation.\n const ariaRequired =\n props['aria-required'] ?? (props.required === false ? undefined : field?.required || undefined);\n const required = nativeRequired ? (props.required ?? (field?.required || undefined)) : undefined;\n\n const result: FieldControlProps = {};\n if (id !== undefined) result.id = id;\n if (props['aria-label'] !== undefined) result['aria-label'] = props['aria-label'];\n if (labelledBy !== undefined) result['aria-labelledby'] = labelledBy;\n if (describedBy !== undefined) result['aria-describedby'] = describedBy;\n if (invalid !== undefined) result['aria-invalid'] = invalid;\n if (ariaRequired !== undefined) result['aria-required'] = ariaRequired;\n if (required !== undefined) result.required = required;\n return result;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useId as e } from "./useId.mjs";
|
|
3
|
+
import { joinIds as t } from "../lib/aria.mjs";
|
|
4
|
+
import * as n from "react";
|
|
5
|
+
//#region src/hooks/useFieldControl.ts
|
|
6
|
+
var r = class {
|
|
7
|
+
holder = void 0;
|
|
8
|
+
mounted = /* @__PURE__ */ new Set();
|
|
9
|
+
listeners = /* @__PURE__ */ new Set();
|
|
10
|
+
version = 0;
|
|
11
|
+
claim = (e) => (this.holder === void 0 && (this.holder = e), this.holder === e);
|
|
12
|
+
mount = (e) => (this.mounted.add(e), () => {
|
|
13
|
+
this.mounted.delete(e), this.holder === e && this.free();
|
|
14
|
+
});
|
|
15
|
+
hold = (e) => {
|
|
16
|
+
this.holder === void 0 ? this.holder = e : this.holder !== e && this.notify();
|
|
17
|
+
};
|
|
18
|
+
releaseStale = () => {
|
|
19
|
+
this.holder !== void 0 && !this.mounted.has(this.holder) && this.free();
|
|
20
|
+
};
|
|
21
|
+
subscribe = (e) => (this.listeners.add(e), () => {
|
|
22
|
+
this.listeners.delete(e);
|
|
23
|
+
});
|
|
24
|
+
getVersion = () => this.version;
|
|
25
|
+
free() {
|
|
26
|
+
this.holder = void 0, this.notify();
|
|
27
|
+
}
|
|
28
|
+
notify() {
|
|
29
|
+
this.version += 1;
|
|
30
|
+
for (let e of Array.from(this.listeners)) e();
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
function i() {
|
|
34
|
+
return new r();
|
|
35
|
+
}
|
|
36
|
+
var a = () => () => {}, o = () => 0, s = n.createContext(null);
|
|
37
|
+
s.displayName = "FieldContext";
|
|
38
|
+
function c() {
|
|
39
|
+
return n.useContext(s);
|
|
40
|
+
}
|
|
41
|
+
function l(r, i = {}) {
|
|
42
|
+
let s = c(), l = e("field-control"), { labelable: u = !0, nativeRequired: d = !1 } = i, f = s !== null && r.id === void 0 && !s.controlIdAssigned, p = f ? s.controlIdClaim : void 0;
|
|
43
|
+
n.useSyncExternalStore(p ? p.subscribe : a, p ? p.getVersion : o, p ? p.getVersion : o);
|
|
44
|
+
let m = f && (!p || p.claim(l));
|
|
45
|
+
n.useLayoutEffect(() => p?.mount(l), [p, l]), n.useLayoutEffect(() => {
|
|
46
|
+
p && m && p.hold(l);
|
|
47
|
+
}, [
|
|
48
|
+
p,
|
|
49
|
+
m,
|
|
50
|
+
l
|
|
51
|
+
]), n.useEffect(() => {
|
|
52
|
+
p && !m && p.releaseStale();
|
|
53
|
+
});
|
|
54
|
+
let h = r.id ?? (s === null ? void 0 : m ? s.controlId : l), g = r["aria-labelledby"];
|
|
55
|
+
s && r["aria-label"] === void 0 && (!u || h !== s.controlId) && (g = t(g, s.labelId));
|
|
56
|
+
let _ = s ? t(r["aria-describedby"], s.validationMessageId ?? s.errorId, s.hintId) : r["aria-describedby"], v = r["aria-invalid"] ?? (s?.invalid || void 0), y = r["aria-required"] ?? (r.required === !1 ? void 0 : s?.required || void 0), b = d ? r.required ?? (s?.required || void 0) : void 0, x = {};
|
|
57
|
+
return h !== void 0 && (x.id = h), r["aria-label"] !== void 0 && (x["aria-label"] = r["aria-label"]), g !== void 0 && (x["aria-labelledby"] = g), _ !== void 0 && (x["aria-describedby"] = _), v !== void 0 && (x["aria-invalid"] = v), y !== void 0 && (x["aria-required"] = y), b !== void 0 && (x.required = b), x;
|
|
58
|
+
}
|
|
59
|
+
//#endregion
|
|
60
|
+
export { s as FieldContext, i as createFieldControlIdClaim, c as useFieldContext, l as useFieldControl };
|
|
61
|
+
|
|
62
|
+
//# sourceMappingURL=useFieldControl.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useFieldControl.mjs","names":["useId","useId$1","React","FieldControlIdClaimStore","token","onChange","listener","createFieldControlIdClaim","subscribeNothing","noVersion","FieldContext","useFieldContext","useFieldControl","field","fallbackId","options","wantsControlId","props","claim","holdsControlId","id","labelledBy","labelable","joinIds","describedBy","invalid","ariaRequired","required","nativeRequired","result"],"sources":["../../src/hooks/useFieldControl.ts"],"sourcesContent":["import * as React from 'react';\nimport { joinIds } from '../lib/aria';\nimport type { ValidationState } from '../lib/types';\nimport { useId } from './useId';\n\n/**\n * What a `Field` tells the controls inside it: the ids of its label, hint and validation message,\n * and its validation, invalid and required state. `Field` provides it; every library input reads\n * it through {@link useFieldControl}, and so can your own control.\n */\nexport interface FieldContextValue {\n /** The id the Field's `<label htmlFor>` points at. */\n controlId: string;\n /** The id of the Field's `<label>`, used for `aria-labelledby` on non-labelable controls. */\n labelId: string | undefined;\n /** The id of the rendered hint, if any. */\n hintId: string | undefined;\n /**\n * The id of the rendered error message, if any: set only while the validation message is an\n * error (see `validationMessageId` for every state).\n */\n errorId: string | undefined;\n /** Whether the Field is in an error state (only the `error` validation state is invalid). */\n invalid: boolean;\n /** Whether the Field is required. */\n required: boolean;\n /** Field renders the error message itself; controls with their own `error` must not repeat it. */\n hasErrorMessage: boolean;\n /**\n * Field already gave `controlId` to its first child, a label-for merge target (component,\n * labelable element, custom element), whether Field merged it or it was the child's own id; a\n * control that receives no `id` prop is then not that child (it is nested inside it, e.g.\n * `Field > Tooltip > Input`, or a later sibling) and must not reuse `controlId`.\n * {@link useFieldControl} gives such a control its own id and names it through\n * `aria-labelledby`. Absent or `false`: a control without an `id` uses `controlId`, subject to\n * `controlIdClaim`.\n */\n controlIdAssigned?: boolean;\n /**\n * Hands `controlId` to one control when `controlIdAssigned` is not set — Field left its first\n * child alone (a plain `<div>`, a Fragment), so every library control inside reads this context.\n * The first control without an `id` of its own takes `controlId`; the others get their own id\n * and are named through `aria-labelledby`, so no id is duplicated. `Field` creates one for each\n * Field. Absent: every control without an `id` uses `controlId`.\n */\n controlIdClaim?: FieldControlIdClaim;\n /**\n * The Field's validation state (`validationState`, or `'error'` from `error`). Absent in\n * contexts built before 0.6: read it as `invalid ? 'error' : 'none'`.\n */\n validationState?: ValidationState;\n /**\n * The id of the rendered validation message in any state (error, warning, success, neutral).\n * `errorId` is set only while that message is an error.\n */\n validationMessageId?: string;\n}\n\n/**\n * Decides which control inside a `Field` takes the Field's `controlId` (the id its\n * `<label htmlFor>` points at) when several library controls without an `id` of their own read\n * the same context. `Field` creates one for each Field and passes it as\n * {@link FieldContextValue.controlIdClaim}; {@link useFieldControl} calls the methods, so a\n * control never calls them itself.\n *\n * - The first control to render takes `controlId`: on the first render (and on the server, so\n * hydration matches) that is the first one in document order. It keeps it across re-renders.\n * - When the holder unmounts or stops wanting `controlId` (it gets an `id` of its own), the\n * subscribers are notified, re-render, and the first of them takes `controlId` over.\n * - A render that claimed `controlId` but never committed (a discarded concurrent render) does not\n * keep it: a mounted control that renders without `controlId` frees it.\n */\nexport interface FieldControlIdClaim {\n /**\n * During render, with the control's stable token (its `useId`): gives `controlId` to `token`\n * when no control holds it, and returns whether `token` holds it. Idempotent per token, so\n * StrictMode double renders and later re-renders agree.\n */\n claim(token: string): boolean;\n /**\n * From a layout effect while the control wants `controlId`: marks `token` mounted. The returned\n * cleanup frees `controlId` when `token` holds it and notifies the subscribers.\n */\n mount(token: string): () => void;\n /**\n * From a layout effect of the control that rendered with `controlId`: takes it again after a\n * StrictMode effect replay freed it; if another control took it meanwhile, notifies the\n * subscribers so both re-render and agree.\n */\n hold(token: string): void;\n /**\n * From a passive effect of a mounted control that rendered without `controlId`: frees\n * `controlId` when its holder is not mounted (its render was discarded) and notifies the\n * subscribers.\n */\n releaseStale(): void;\n /** Subscribes to changes of the holder (for `useSyncExternalStore`); returns the unsubscribe. */\n subscribe(onChange: () => void): () => void;\n /** A number that changes whenever the subscribers are notified (the store snapshot). */\n getVersion(): number;\n}\n\nclass FieldControlIdClaimStore implements FieldControlIdClaim {\n private holder: string | undefined = undefined;\n private readonly mounted = new Set<string>();\n private readonly listeners = new Set<() => void>();\n private version = 0;\n\n claim = (token: string): boolean => {\n if (this.holder === undefined) this.holder = token;\n return this.holder === token;\n };\n\n mount = (token: string): (() => void) => {\n this.mounted.add(token);\n return () => {\n this.mounted.delete(token);\n if (this.holder === token) this.free();\n };\n };\n\n hold = (token: string): void => {\n if (this.holder === undefined) this.holder = token;\n else if (this.holder !== token) this.notify();\n };\n\n releaseStale = (): void => {\n if (this.holder !== undefined && !this.mounted.has(this.holder)) this.free();\n };\n\n subscribe = (onChange: () => void): (() => void) => {\n this.listeners.add(onChange);\n return () => {\n this.listeners.delete(onChange);\n };\n };\n\n getVersion = (): number => this.version;\n\n private free(): void {\n this.holder = undefined;\n this.notify();\n }\n\n private notify(): void {\n this.version += 1;\n for (const listener of Array.from(this.listeners)) listener();\n }\n}\n\n/**\n * Creates the {@link FieldControlIdClaim} a Field puts into its context (one per Field instance,\n * e.g. `const [claim] = useState(createFieldControlIdClaim)`).\n *\n * @internal Not exported from the package.\n */\nexport function createFieldControlIdClaim(): FieldControlIdClaim {\n return new FieldControlIdClaimStore();\n}\n\nconst subscribeNothing = (): (() => void) => () => {};\nconst noVersion = (): number => 0;\n\n/**\n * Context provided by `Field`. `null` outside a Field (controls then use only their own props).\n */\nexport const FieldContext: React.Context<FieldContextValue | null> =\n React.createContext<FieldContextValue | null>(null);\nFieldContext.displayName = 'FieldContext';\n\n/** The surrounding Field's context value, or `null` when the control is not inside a Field. */\nexport function useFieldContext(): FieldContextValue | null {\n return React.useContext(FieldContext);\n}\n\n/** The labelling/validation props a control receives from its consumer and from its Field. */\nexport interface FieldControlProps {\n id?: string;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n 'aria-describedby'?: string;\n 'aria-invalid'?: React.AriaAttributes['aria-invalid'];\n 'aria-required'?: React.AriaAttributes['aria-required'];\n required?: boolean;\n}\n\n/** Options of {@link useFieldControl}. */\nexport interface UseFieldControlOptions {\n /**\n * Whether the focusable element can be the target of `<label htmlFor>` (`<input>`, `<button>`,\n * `<select>`, `<textarea>`). Non-labelable controls (`role=\"radiogroup\"`/`role=\"group\"` divs)\n * are named with `aria-labelledby` instead.\n * @default true\n */\n labelable?: boolean;\n /**\n * Whether the focusable element is a native form control (Input, Select, Textarea, Slider,\n * SpinButton's input), so the Field's `required` becomes the native `required` attribute and\n * constraint validation runs. Controls built on buttons or divs validate through `HiddenInput`.\n * @default false\n */\n nativeRequired?: boolean;\n}\n\n/**\n * Merges a control's own labelling props with its surrounding `Field`. Spread the result onto the\n * **focusable element** (for a control whose root wraps it, not onto the root). Consumer values\n * are merged, never overwritten, and only defined keys are returned, so spreading never clears an\n * attribute.\n *\n * - `id`: the consumer's id; else, when the Field already gave `controlId` to its first child\n * (`controlIdAssigned`) — so this control is nested inside that child or a later sibling — a\n * generated id of its own; else the Field's `controlId`, which only one control takes when the\n * Field provides a `controlIdClaim` (several controls inside a plain `<div>`: the first one\n * takes it, the others get a generated id of their own). The first child itself receives\n * `controlId` as its `id` prop from Field, so it keeps it.\n * - `aria-labelledby`: when the consumer set an `aria-label`, only the consumer's\n * `aria-labelledby`; otherwise, when the control is not labelable **or** its id is not the\n * Field's `controlId` (it carries its own id, or is not the Field's first child, so\n * `<label htmlFor>` does not reach it), the consumer's ids plus the Field's `labelId`.\n * - `aria-describedby`: the consumer's ids, then the Field's validation message\n * (`validationMessageId`, else `errorId`), then its hint (deduplicated). A warning, success or\n * neutral message describes the control too.\n * - `aria-invalid` / `aria-required`: the consumer's value, else `true` when the Field is\n * invalid/required (`aria-required`: not when the consumer passes `required={false}`). Only the\n * `error` validation state makes the Field invalid.\n * - `required`: only with `nativeRequired` — the consumer's value, else the Field's `required`.\n * - `aria-label`: passed through.\n *\n * @example\n * const fieldProps = useFieldControl({ id, 'aria-label': ariaLabel, 'aria-labelledby': labelledBy,\n * 'aria-describedby': describedBy, 'aria-invalid': ariaInvalid, 'aria-required': ariaRequired });\n * return <button role=\"switch\" {...fieldProps} />;\n */\nexport function useFieldControl(\n props: FieldControlProps,\n options: UseFieldControlOptions = {},\n): FieldControlProps {\n const field = useFieldContext();\n // Always called (stable hook order); used only when the Field's controlId is taken. It is also\n // the control's token in the Field's controlIdClaim.\n const fallbackId = useId('field-control');\n const { labelable = true, nativeRequired = false } = options;\n\n // A control without an id of its own wants the Field's controlId unless Field gave it to its\n // first child. With a claim, only the first such control takes it.\n const wantsControlId = field !== null && props.id === undefined && !field.controlIdAssigned;\n const claim = wantsControlId ? field.controlIdClaim : undefined;\n // Re-render when the controlId is freed, so the next control takes it over.\n React.useSyncExternalStore(\n claim ? claim.subscribe : subscribeNothing,\n claim ? claim.getVersion : noVersion,\n claim ? claim.getVersion : noVersion,\n );\n const holdsControlId = wantsControlId && (claim ? claim.claim(fallbackId) : true);\n // Layout effects do nothing on the server, and React 19 no longer warns about them there.\n React.useLayoutEffect(() => claim?.mount(fallbackId), [claim, fallbackId]);\n React.useLayoutEffect(() => {\n if (claim && holdsControlId) claim.hold(fallbackId);\n }, [claim, holdsControlId, fallbackId]);\n // After every commit (all layout effects of the commit, and so every mount, have run): a\n // control rendered without controlId frees one held by a render that never committed.\n React.useEffect(() => {\n if (claim && !holdsControlId) claim.releaseStale();\n });\n\n const id =\n props.id ?? (field === null ? undefined : holdsControlId ? field.controlId : fallbackId);\n\n let labelledBy = props['aria-labelledby'];\n if (field && props['aria-label'] === undefined && (!labelable || id !== field.controlId)) {\n labelledBy = joinIds(labelledBy, field.labelId);\n }\n\n // The message in any validation state (a context built before 0.6 has only `errorId`).\n const describedBy = field\n ? joinIds(props['aria-describedby'], field.validationMessageId ?? field.errorId, field.hintId)\n : props['aria-describedby'];\n const invalid = props['aria-invalid'] ?? (field?.invalid || undefined);\n // A consumer `required={false}` (native controls pass `required`) also keeps the Field's\n // required state out of aria-required, so the announced state matches native validation.\n const ariaRequired =\n props['aria-required'] ?? (props.required === false ? undefined : field?.required || undefined);\n const required = nativeRequired ? (props.required ?? (field?.required || undefined)) : undefined;\n\n const result: FieldControlProps = {};\n if (id !== undefined) result.id = id;\n if (props['aria-label'] !== undefined) result['aria-label'] = props['aria-label'];\n if (labelledBy !== undefined) result['aria-labelledby'] = labelledBy;\n if (describedBy !== undefined) result['aria-describedby'] = describedBy;\n if (invalid !== undefined) result['aria-invalid'] = invalid;\n if (ariaRequired !== undefined) result['aria-required'] = ariaRequired;\n if (required !== undefined) result.required = required;\n return result;\n}\n"],"mappings":";;;;;AAsGA,IAAMG,IAAN,MAA8D;CAC5D,SAAqC,KAAA;CACrC,0BAA2B,IAAI,IAAY;CAC3C,4BAA6B,IAAI,IAAgB;CACjD,UAAkB;CAElB,SAAS,OACH,KAAK,WAAW,KAAA,MAAW,KAAK,SAASC,IACtC,KAAK,WAAWA;CAGzB,SAAS,OACP,KAAK,QAAQ,IAAIA,CAAK,SACT;EAEX,AADA,KAAK,QAAQ,OAAOA,CAAK,GACrB,KAAK,WAAWA,KAAO,KAAK,KAAK;CACvC;CAGF,QAAQ,MAAwB;EAC9B,AAAI,KAAK,WAAW,KAAA,IAAW,KAAK,SAASA,IACpC,KAAK,WAAWA,KAAO,KAAK,OAAO;CAC9C;CAEA,qBAA2B;EACzB,AAAI,KAAK,WAAW,KAAA,KAAa,CAAC,KAAK,QAAQ,IAAI,KAAK,MAAM,KAAG,KAAK,KAAK;CAC7E;CAEA,aAAa,OACX,KAAK,UAAU,IAAIC,CAAQ,SACd;EACX,KAAK,UAAU,OAAOA,CAAQ;CAChC;CAGF,mBAA2B,KAAK;CAEhC,OAAqB;EAEnB,AADA,KAAK,SAAS,KAAA,GACd,KAAK,OAAO;CACd;CAEA,SAAuB;EACrB,KAAK,WAAW;EAChB,KAAK,IAAMC,KAAY,MAAM,KAAK,KAAK,SAAS,GAAG,EAAS;CAC9D;AACF;AAQA,SAAgBC,IAAiD;CAC/D,OAAO,IAAIJ,EAAyB;AACtC;AAEA,IAAMK,gBAA6C,CAAC,GAC9CC,UAA0B,GAKnBC,IACXR,EAAM,cAAwC,IAAI;AACpD,EAAa,cAAc;AAG3B,SAAgBS,IAA4C;CAC1D,OAAOT,EAAM,WAAWQ,CAAY;AACtC;AA6DA,SAAgBE,EACd,GACA,IAAkC,CAAC,GAChB;CACnB,IAAMC,IAAQF,EAAgB,GAGxBG,IAAad,EAAM,eAAe,GAClC,EAAE,eAAY,IAAM,oBAAiB,OAAUe,GAI/CC,IAAiBH,MAAU,QAAQI,EAAM,OAAO,KAAA,KAAa,CAACJ,EAAM,mBACpEK,IAAQF,IAAiBH,EAAM,iBAAiB,KAAA;CAEtD,EAAM,qBACJK,IAAQA,EAAM,YAAYV,GAC1BU,IAAQA,EAAM,aAAaT,GAC3BS,IAAQA,EAAM,aAAaT,CAC7B;CACA,IAAMU,IAAiBH,MAAmB,MAAQE,EAAM,MAAMJ,CAAU;CAQxE,AANAZ,EAAM,sBAAsBgB,GAAO,MAAMJ,CAAU,GAAG,CAACI,GAAOJ,CAAU,CAAC,GACzEZ,EAAM,sBAAsB;EAC1B,AAAIgB,KAASC,KAAgBD,EAAM,KAAKJ,CAAU;CACpD,GAAG;EAACI;EAAOC;EAAgBL;CAAU,CAAC,GAGtCZ,EAAM,gBAAgB;EACpB,AAAIgB,KAAS,CAACC,KAAgBD,EAAM,aAAa;CACnD,CAAC;CAED,IAAME,IACJH,EAAM,OAAOJ,MAAU,OAAO,KAAA,IAAYM,IAAiBN,EAAM,YAAYC,IAE3EO,IAAaJ,EAAM;CACvB,AAAIJ,KAASI,EAAM,kBAAkB,KAAA,MAAc,CAACK,KAAaF,MAAOP,EAAM,eAC5E,IAAaU,EAAQF,GAAYR,EAAM,OAAO;CAIhD,IAAMW,IAAcX,IAChBU,EAAQN,EAAM,qBAAqBJ,EAAM,uBAAuBA,EAAM,SAASA,EAAM,MAAM,IAC3FI,EAAM,qBACJQ,IAAUR,EAAM,oBAAoBJ,GAAO,WAAW,KAAA,IAGtDa,IACJT,EAAM,qBAAqBA,EAAM,aAAa,KAAQ,KAAA,IAAYJ,GAAO,YAAY,KAAA,IACjFc,IAAWC,IAAkBX,EAAM,aAAaJ,GAAO,YAAY,KAAA,KAAc,KAAA,GAEjFgB,IAA4B,CAAC;CAQnC,OAPIT,MAAO,KAAA,MAAW,EAAO,KAAKA,IAC9BH,EAAM,kBAAkB,KAAA,MAAW,EAAO,gBAAgBA,EAAM,gBAChEI,MAAe,KAAA,MAAW,EAAO,qBAAqBA,IACtDG,MAAgB,KAAA,MAAW,EAAO,sBAAsBA,IACxDC,MAAY,KAAA,MAAW,EAAO,kBAAkBA,IAChDC,MAAiB,KAAA,MAAW,EAAO,mBAAmBA,IACtDC,MAAa,KAAA,MAAW,EAAO,WAAWA,IACvCE;AACT"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";const e=require("../lib/globalRegistry.cjs"),t=require("../lib/focus.cjs"),n=require("../lib/layers.cjs");let r=require("react");function i(){return e.getGlobalRegistry(`traps`,()=>({traps:[],seq:0,listeners:null}))}function a(e,t){let r=e.layerId,i=t.layerId;if(r!==void 0&&i!==void 0&&r!==i){if(n.isDescendantLayer(r,i))return 1;if(n.isDescendantLayer(i,r))return-1;let e=n.getLayer(r),t=n.getLayer(i);if(e&&t)return n.compareLayers(e,t)}return e.seq-t.seq}function o(e){let t=null;for(let n of e.traps)(!t||a(n,t)>0)&&(t=n);return t}var s=4,c=2;function l(e){let t=e.container.ownerDocument,n=Array.from(t.querySelectorAll(e.allowOutsideSelector));return n.filter(t=>!e.container.contains(t)&&!t.contains(e.container)&&!n.some(e=>e!==t&&e.contains(t)))}function u(e,n){let r=t.getTabbableElements(e.container).map(e=>({el:e,segment:0}));return n.forEach((e,n)=>{for(let i of t.getTabbableElements(e))r.push({el:i,segment:n+1})}),r}function d(e,t){return(e.compareDocumentPosition(t)&s)!==0}function f(e,t){return(e.compareDocumentPosition(t)&c)!==0&&!t.contains(e)}function p(e,t,n,r){if(!r){let r=e.find(e=>e.segment===n&&d(t,e.el));return r?r.el:(e.find(e=>e.segment>n)??e[0]).el}for(let r=e.length-1;r>=0;r--){let i=e[r];if(i.segment===n&&f(t,i.el))return i.el}for(let t=e.length-1;t>=0;t--)if(e[t].segment<n)return e[t].el;return e[e.length-1].el}function m(e,t){return e!==void 0&&n.getLayerTreeElements(e,{includeOwnElements:!1}).some(e=>e.contains(t))}function h(e,t){if(e.container.contains(t))return!0;let n=t.nodeType===1?t:t.parentElement;return n&&n.closest(e.allowOutsideSelector)?!0:m(e.layerId,t)}function g(e,t){let r=e.layerId;if(r===void 0)return null;let i=null;for(let a of n.getOpenLayers()){if(a.id===r||!n.isDescendantLayer(a.id,r))continue;let o=a.getAnchor(),s=a.getElements().find(n=>!!n&&n.contains(t)&&!e.container.contains(n)&&!(o&&n.contains(o)));s&&(!i||n.compareLayers(a,i.layer)>0)&&(i={layer:a,region:s})}return i}function _(e,t){if(e.layerId===void 0)return null;let r=n.getLayerTreeElements(e.layerId,{includeOwnElements:!1}).filter(e=>e.contains(t));return r.find(e=>!r.some(t=>t!==e&&t.contains(e)))??null}function v(e){for(let n of e)if(n&&t.focusElement(n))return}function y(e,n,r){let i=t.getTabbableElements(e),a=i.indexOf(n);return a===-1?r?!i.some(e=>f(n,e)):!i.some(e=>d(n,e)):r?a===0:a===i.length-1}function b(e,t,n){let r=u(e,t);v([n?r[r.length-1]?.el:r[0]?.el,e.container])}function x(e,t,n,r){let i=_(e,n);return i?!y(i,n,t.shiftKey)||(t.preventDefault(),b(e,r,t.shiftKey),!0):!1}function S(e,n,r,i){let a=r,o=n.shiftKey;for(let s=0;s<10;s++){let s=g(e,a);if(!s)return!1;let{layer:c,region:l}=s;if(a===r&&!y(l,a,o))return!0;let d=c.getAnchor();if(n.preventDefault(),!d||!d.isConnected)return b(e,i,o),!0;if(o&&t.isFocusable(d))return t.focusElement(d),!0;if(e.container.contains(d)){let n=u(e,i);return n.length===0?(t.focusElement(e.container),!0):(v([n.some(e=>e.el===d)?w(n,d,o):p(n,d,0,o),e.container]),!0)}let f=g(e,d);if(!f){let n=_(e,d);if(!n)return v([d,e.container]),!0;let r=C(t.getTabbableElements(n),d,o);return r?t.focusElement(r):b(e,i,o),!0}let m=C(t.getTabbableElements(f.region),d,o);if(m)return t.focusElement(m),!0;a=d}return!0}function C(e,t,n){return n?[...e].reverse().find(e=>f(t,e)):e.find(e=>d(t,e)&&!t.contains(e))}function w(e,t,n){let r=e.findIndex(e=>e.el===t);return e[((n?r-1:r+1)+e.length)%e.length].el}function T(e,n){let{container:r}=e;if(!r.isConnected)return;let i=r.ownerDocument,a=i.activeElement,o=n.shiftKey,s=l(e),c=!!a&&r.contains(a),d=a&&!c?s.findIndex(e=>e.contains(a)):-1;if(a&&!c&&d===-1&&a!==i.body&&m(e.layerId,a)&&(S(e,n,a,s)||x(e,n,a,s)))return;let f=u(e,s);if(f.length===0){n.preventDefault(),t.focusElement(r);return}let h=a?f.findIndex(e=>e.el===a):-1;if(h!==-1){let e=o?h-1:h+1;if(e<0||e>=f.length){n.preventDefault(),t.focusElement(f[o?f.length-1:0].el);return}let r=f[e];r.segment!==f[h].segment&&(n.preventDefault(),t.focusElement(r.el));return}if(n.preventDefault(),a&&(c||d!==-1)){let e=c?0:d+1;t.focusElement(p(f,a,e,o));return}t.focusElement(f[o?f.length-1:0].el)}function E(e){if(e.key!==`Tab`||e.defaultPrevented||e.altKey||e.ctrlKey||e.metaKey||e.isComposing)return;let t=o(i());t&&T(t,e)}function D(e){let t=o(i());if(!t)return;let n=e.target;if(!n||typeof n.nodeType!=`number`)return;let r=n;if(r.nodeType!==1)return;let a=r;if(h(t,a)){t.lastFocused=a;return}O||queueMicrotask(()=>A(a))}var O=!1;function k(e){let t=e.activeElement;return!t||t===e.body||t===e.documentElement}function A(e){let n=e.ownerDocument,r=n.activeElement!==e;if(r&&!k(n))return;let a=o(i());if(!a||!a.container.isConnected)return;if(!r&&h(a,e)){a.lastFocused=e;return}let s=a.lastFocused,c=!!s&&s.isConnected&&h(a,s)&&t.isFocusable(s);O=!0;try{v([c?s:null,t.getFirstTabbable(a.container),a.container])}finally{O=!1}}function j(e){if(e.listeners||typeof document>`u`)return;let t=document;t.addEventListener(`keydown`,E),t.addEventListener(`focusin`,D,!0),e.listeners={remove(){t.removeEventListener(`keydown`,E),t.removeEventListener(`focusin`,D,!0)}}}function M(e){let t=i();return t.traps.push(e),j(t),()=>{let n=t.traps.indexOf(e);n!==-1&&t.traps.splice(n,1),t.traps.length===0&&(t.listeners?.remove(),t.listeners=null)}}function N(e,n){let r=t.getFirstTabbable(e);return n===`container`?[e]:n===void 0||n===`first`?[r,e]:[typeof n==`function`?n():n.current,r,e]}function P(e,t){let{enabled:n}=t,a=(0,r.useRef)(t);(0,r.useInsertionEffect)(()=>{a.current=t}),(0,r.useLayoutEffect)(()=>{if(!n||!e)return;let t=a,r=i();r.seq+=1;let o={container:e,seq:r.seq,get layerId(){return t.current.layerId},get allowOutsideSelector(){return t.current.allowOutsideSelector??`[data-wave-focus-trap-allow]`},lastFocused:null},s=M(o),c=e.ownerDocument.activeElement;if(c&&(e.contains(c)||!c.closest(o.allowOutsideSelector)&&m(t.current.layerId,c)))o.lastFocused=c;else{v(N(e,t.current.initialFocus));let n=e.ownerDocument.activeElement;n&&e.contains(n)&&(o.lastFocused=n)}return s},[n,e])}exports.useFocusTrap=P;
|
|
2
|
+
//# sourceMappingURL=useFocusTrap.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useFocusTrap.cjs","names":["getGlobalRegistry","isDescendantLayer","getLayer","compareLayers","getTabbableElements","getLayerTreeElements","getOpenLayers","focusElement","isFocusable","getFirstTabbable","useRef","require_globalRegistry","require_focus","require_layers","react","getState","compareTraps","idA","a","idB","b","layerA","layerB","getActiveTrap","active","trap","state","FOLLOWING","PRECEDING","getAllowRegions","doc","all","region","other","getCycle","entries","regions","el","index","follows","reference","precedes","findFromPosition","backward","sameSegment","cycle","entry","segment","from","i","isInsideDescendantLayers","layerId","node","isInsideTrap","findDescendantLayer","found","layer","anchor","findPortalWrapper","containing","focusFirstPossible","candidate","candidates","isAtRegionEdge","tabbables","focusCycleEdge","handlePortalWrapperTab","wrapper","event","handleDescendantLayerTab","depth","neighbour","outer","next","findNextTo","handleTab","container","inContainer","regionIndex","nextIndex","handleKeyDown","handleFocusIn","target","reclaiming","reclaimFocus","isFocusLost","lost","last","lastIsValid","ensureListeners","pushTrap","resolveInitialFocus","first","initialFocus","useFocusTrap","options","latestRef","enabled","latest","release","now"],"sources":["../../src/hooks/useFocusTrap.ts"],"sourcesContent":["import { useInsertionEffect, useLayoutEffect, useRef } from 'react';\nimport type * as React from 'react';\nimport { getGlobalRegistry } from '../lib/globalRegistry';\nimport { focusElement, getFirstTabbable, getTabbableElements, isFocusable } from '../lib/focus';\nimport {\n ALLOW_OUTSIDE_SELECTOR,\n compareLayers,\n getLayer,\n getLayerTreeElements,\n getOpenLayers,\n isDescendantLayer,\n type LayerRecord,\n} from '../lib/layers';\n\n/** Options of {@link useFocusTrap}. */\nexport interface UseFocusTrapOptions {\n /** Whether the trap is active. */\n enabled: boolean;\n /**\n * The surface's dismiss layer; focus inside its descendant layers (portaled popovers opened from\n * inside) is allowed. The layer's own `refs` outside the container (its trigger) are not.\n */\n layerId?: string;\n /**\n * What to focus when the trap starts, unless focus is already inside (an `autoFocus` element\n * wins). @default 'first' (the first tabbable element, else the container)\n */\n initialFocus?:\n React.RefObject<HTMLElement | null> | 'first' | 'container' | (() => HTMLElement | null);\n /** Regions outside the container whose tabbables join the Tab cycle. @default ALLOW_OUTSIDE_SELECTOR */\n allowOutsideSelector?: string;\n}\n\ninterface TrapEntry {\n container: HTMLElement;\n seq: number;\n readonly layerId: string | undefined;\n readonly allowOutsideSelector: string;\n lastFocused: HTMLElement | null;\n}\n\ninterface TrapState {\n traps: TrapEntry[];\n seq: number;\n listeners: { remove(): void } | null;\n}\n\nfunction getState(): TrapState {\n return getGlobalRegistry<TrapState>('traps', () => ({ traps: [], seq: 0, listeners: null }));\n}\n\n// ---------------------------------------------------------------------------\n// Trap stack\n// ---------------------------------------------------------------------------\n\n/** `> 0` when trap `a` is above trap `b`: layer parentage/stacking first, then activation order. */\nfunction compareTraps(a: TrapEntry, b: TrapEntry): number {\n const idA = a.layerId;\n const idB = b.layerId;\n if (idA !== undefined && idB !== undefined && idA !== idB) {\n if (isDescendantLayer(idA, idB)) return 1;\n if (isDescendantLayer(idB, idA)) return -1;\n const layerA = getLayer(idA);\n const layerB = getLayer(idB);\n if (layerA && layerB) return compareLayers(layerA, layerB);\n }\n return a.seq - b.seq;\n}\n\nfunction getActiveTrap(state: TrapState): TrapEntry | null {\n let active: TrapEntry | null = null;\n for (const trap of state.traps) {\n if (!active || compareTraps(trap, active) > 0) active = trap;\n }\n return active;\n}\n\n// ---------------------------------------------------------------------------\n// Tab cycle\n// ---------------------------------------------------------------------------\n\ninterface CycleEntry {\n el: HTMLElement;\n /** 0 = the container, 1… = allow-listed regions in document order. */\n segment: number;\n}\n\nconst FOLLOWING = 4; // Node.DOCUMENT_POSITION_FOLLOWING\nconst PRECEDING = 2; // Node.DOCUMENT_POSITION_PRECEDING\n\n/** Top-level allow-listed regions outside the container. */\nfunction getAllowRegions(trap: TrapEntry): HTMLElement[] {\n const doc = trap.container.ownerDocument;\n const all = Array.from(doc.querySelectorAll<HTMLElement>(trap.allowOutsideSelector));\n return all.filter(\n (region) =>\n !trap.container.contains(region) &&\n !region.contains(trap.container) &&\n !all.some((other) => other !== region && other.contains(region)),\n );\n}\n\nfunction getCycle(trap: TrapEntry, regions: HTMLElement[]): CycleEntry[] {\n const entries: CycleEntry[] = getTabbableElements(trap.container).map((el) => ({\n el,\n segment: 0,\n }));\n regions.forEach((region, index) => {\n for (const el of getTabbableElements(region)) entries.push({ el, segment: index + 1 });\n });\n return entries;\n}\n\nfunction follows(reference: Node, el: Node): boolean {\n return (reference.compareDocumentPosition(el) & FOLLOWING) !== 0;\n}\n\nfunction precedes(reference: Node, el: Node): boolean {\n // An ancestor also \"precedes\"; it is not a place Tab goes back to.\n return (reference.compareDocumentPosition(el) & PRECEDING) !== 0 && !el.contains(reference);\n}\n\n/** The cycle entry Tab (or Shift+Tab) reaches from `from`, an element not in the cycle. */\nfunction findFromPosition(\n cycle: CycleEntry[],\n from: Element,\n segment: number,\n backward: boolean,\n): HTMLElement {\n if (!backward) {\n const sameSegment = cycle.find((entry) => entry.segment === segment && follows(from, entry.el));\n if (sameSegment) return sameSegment.el;\n const later = cycle.find((entry) => entry.segment > segment);\n return (later ?? cycle[0]).el;\n }\n for (let i = cycle.length - 1; i >= 0; i--) {\n const entry = cycle[i];\n if (entry.segment === segment && precedes(from, entry.el)) return entry.el;\n }\n for (let i = cycle.length - 1; i >= 0; i--) {\n if (cycle[i].segment < segment) return cycle[i].el;\n }\n return cycle[cycle.length - 1].el;\n}\n\n/**\n * Whether `node` is inside a **descendant** of the layer `layerId`: the portal wrappers registered\n * with it (overlays rendered inside the trapped surface) and the trees of its descendant layers.\n * The layer's own `getElements()` are left out — they usually include its trigger, which lives\n * outside the container (a DatePicker toggle) and must not count as inside the trap.\n */\nfunction isInsideDescendantLayers(layerId: string | undefined, node: Node): boolean {\n if (layerId === undefined) return false;\n return getLayerTreeElements(layerId, { includeOwnElements: false }).some((el) =>\n el.contains(node),\n );\n}\n\nfunction isInsideTrap(trap: TrapEntry, node: Node): boolean {\n if (trap.container.contains(node)) return true;\n const el = node.nodeType === 1 ? (node as Element) : node.parentElement;\n if (el && el.closest(trap.allowOutsideSelector)) return true;\n return isInsideDescendantLayers(trap.layerId, node);\n}\n\n/**\n * The open descendant layer of the trap's layer that `node` is in (the topmost when several\n * contain it), with the element of that layer containing `node` (its portaled surface). A layer's\n * trigger is not its surface: an element that is, or contains, the layer's anchor (an info\n * button, a tooltip's wrapper) belongs to the region around it — the container, the surface of\n * an enclosing descendant layer or a plain portal.\n */\nfunction findDescendantLayer(\n trap: TrapEntry,\n node: Node,\n): { layer: LayerRecord; region: HTMLElement } | null {\n const layerId = trap.layerId;\n if (layerId === undefined) return null;\n let found: { layer: LayerRecord; region: HTMLElement } | null = null;\n for (const layer of getOpenLayers()) {\n if (layer.id === layerId || !isDescendantLayer(layer.id, layerId)) continue;\n const anchor = layer.getAnchor();\n const region = layer\n .getElements()\n .find(\n (el): el is HTMLElement =>\n !!el &&\n el.contains(node) &&\n !trap.container.contains(el) &&\n !(anchor && el.contains(anchor)),\n );\n if (region && (!found || compareLayers(layer, found.layer) > 0)) found = { layer, region };\n }\n return found;\n}\n\n/**\n * The outermost element of the trap's layer tree (its own layer's elements left out) that contains\n * `node`. Asked once no descendant layer's surface contains `node`, this is the wrapper of a plain\n * `<Portal>` rendered inside the trapped surface (or inside one of its descendant layers).\n */\nfunction findPortalWrapper(trap: TrapEntry, node: Node): HTMLElement | null {\n if (trap.layerId === undefined) return null;\n const containing = getLayerTreeElements(trap.layerId, { includeOwnElements: false }).filter(\n (el) => el.contains(node),\n );\n return (\n containing.find((el) => !containing.some((other) => other !== el && other.contains(el))) ?? null\n );\n}\n\nfunction focusFirstPossible(candidates: Array<HTMLElement | null | undefined>): void {\n for (const candidate of candidates) {\n if (candidate && focusElement(candidate)) return;\n }\n}\n\n/** Whether Tab (Shift+Tab) from `from` leaves `region`: no tabbable of it follows (precedes). */\nfunction isAtRegionEdge(region: HTMLElement, from: HTMLElement, backward: boolean): boolean {\n const tabbables = getTabbableElements(region);\n const index = tabbables.indexOf(from);\n if (index === -1) {\n return backward\n ? !tabbables.some((el) => precedes(from, el))\n : !tabbables.some((el) => follows(from, el));\n }\n return backward ? index === 0 : index === tabbables.length - 1;\n}\n\n/** Leaving a region without an anchor: the first (Shift+Tab: last) element of the Tab cycle. */\nfunction focusCycleEdge(trap: TrapEntry, regions: HTMLElement[], backward: boolean): void {\n const cycle = getCycle(trap, regions);\n focusFirstPossible([backward ? cycle[cycle.length - 1]?.el : cycle[0]?.el, trap.container]);\n}\n\n/**\n * Tab inside a plain portal wrapper of the trap's layer tree (see {@link findPortalWrapper}):\n * native inside it; it has no anchor, so leaving it continues at the edge of the Tab cycle.\n * Returns `true` when it handled the event.\n */\nfunction handlePortalWrapperTab(\n trap: TrapEntry,\n event: KeyboardEvent,\n active: HTMLElement,\n regions: HTMLElement[],\n): boolean {\n const wrapper = findPortalWrapper(trap, active);\n if (!wrapper) return false;\n if (!isAtRegionEdge(wrapper, active, event.shiftKey)) return true; // native Tab inside it\n event.preventDefault();\n focusCycleEdge(trap, regions, event.shiftKey);\n return true;\n}\n\n/**\n * Tab inside a descendant layer: native inside it; leaving it forward goes to the tabbable after\n * the layer's anchor, backward to the anchor itself. Returns `true` when it handled the event.\n */\nfunction handleDescendantLayerTab(\n trap: TrapEntry,\n event: KeyboardEvent,\n active: HTMLElement,\n regions: HTMLElement[],\n): boolean {\n let from: HTMLElement = active;\n const backward = event.shiftKey;\n // Nested descendant layers: leave each one whose edge is reached, up to the container.\n for (let depth = 0; depth < 10; depth++) {\n const found = findDescendantLayer(trap, from);\n if (!found) return false;\n const { layer, region } = found;\n // Native Tab inside the layer.\n if (from === active && !isAtRegionEdge(region, from, backward)) return true;\n\n const anchor = layer.getAnchor();\n event.preventDefault();\n if (!anchor || !anchor.isConnected) {\n focusCycleEdge(trap, regions, backward);\n return true;\n }\n if (backward && isFocusable(anchor)) {\n focusElement(anchor);\n return true;\n }\n if (trap.container.contains(anchor)) {\n const cycle = getCycle(trap, regions);\n if (cycle.length === 0) {\n focusElement(trap.container);\n return true;\n }\n const target = cycle.some((entry) => entry.el === anchor)\n ? neighbour(cycle, anchor, backward)\n : findFromPosition(cycle, anchor, 0, backward);\n focusFirstPossible([target, trap.container]);\n return true;\n }\n // The anchor lives in another descendant layer: continue from there.\n const outer = findDescendantLayer(trap, anchor);\n if (!outer) {\n // Or in a plain portal of the trap's tree: the element next to it there, else the edge of\n // the Tab cycle (as when Tab leaves that portal).\n const wrapper = findPortalWrapper(trap, anchor);\n if (!wrapper) {\n focusFirstPossible([anchor, trap.container]);\n return true;\n }\n const next = findNextTo(getTabbableElements(wrapper), anchor, backward);\n if (next) focusElement(next);\n else focusCycleEdge(trap, regions, backward);\n return true;\n }\n const next = findNextTo(getTabbableElements(outer.region), anchor, backward);\n if (next) {\n focusElement(next);\n return true;\n }\n from = anchor;\n }\n return true;\n}\n\n/** The tabbable after `anchor` (backward: before it) in `tabbables`, never one inside it. */\nfunction findNextTo(\n tabbables: HTMLElement[],\n anchor: HTMLElement,\n backward: boolean,\n): HTMLElement | undefined {\n return backward\n ? [...tabbables].reverse().find((el) => precedes(anchor, el))\n : tabbables.find((el) => follows(anchor, el) && !anchor.contains(el));\n}\n\nfunction neighbour(cycle: CycleEntry[], el: HTMLElement, backward: boolean): HTMLElement {\n const index = cycle.findIndex((entry) => entry.el === el);\n const next = backward ? index - 1 : index + 1;\n return cycle[(next + cycle.length) % cycle.length].el;\n}\n\nfunction handleTab(trap: TrapEntry, event: KeyboardEvent): void {\n const { container } = trap;\n if (!container.isConnected) return;\n const doc = container.ownerDocument;\n const active = doc.activeElement as HTMLElement | null;\n const backward = event.shiftKey;\n const regions = getAllowRegions(trap);\n\n const inContainer = !!active && container.contains(active);\n const regionIndex =\n active && !inContainer ? regions.findIndex((region) => region.contains(active)) : -1;\n\n if (active && !inContainer && regionIndex === -1 && active !== doc.body) {\n if (isInsideDescendantLayers(trap.layerId, active)) {\n if (handleDescendantLayerTab(trap, event, active, regions)) return;\n if (handlePortalWrapperTab(trap, event, active, regions)) return;\n }\n }\n\n const cycle = getCycle(trap, regions);\n if (cycle.length === 0) {\n event.preventDefault();\n focusElement(container);\n return;\n }\n\n const index = active ? cycle.findIndex((entry) => entry.el === active) : -1;\n if (index !== -1) {\n const nextIndex = backward ? index - 1 : index + 1;\n if (nextIndex < 0 || nextIndex >= cycle.length) {\n event.preventDefault();\n focusElement(cycle[backward ? cycle.length - 1 : 0].el);\n return;\n }\n // Inside one segment the browser's own Tab order is used; crossing segments is explicit.\n const next = cycle[nextIndex];\n if (next.segment !== cycle[index].segment) {\n event.preventDefault();\n focusElement(next.el);\n }\n return;\n }\n\n event.preventDefault();\n if (active && (inContainer || regionIndex !== -1)) {\n const segment = inContainer ? 0 : regionIndex + 1;\n focusElement(findFromPosition(cycle, active, segment, backward));\n return;\n }\n focusElement(cycle[backward ? cycle.length - 1 : 0].el);\n}\n\n// ---------------------------------------------------------------------------\n// Document listeners\n// ---------------------------------------------------------------------------\n\nfunction handleKeyDown(event: KeyboardEvent): void {\n if (event.key !== 'Tab' || event.defaultPrevented) return;\n if (event.altKey || event.ctrlKey || event.metaKey || event.isComposing) return;\n const trap = getActiveTrap(getState());\n if (trap) handleTab(trap, event);\n}\n\nfunction handleFocusIn(event: FocusEvent): void {\n const trap = getActiveTrap(getState());\n if (!trap) return;\n const target = event.target as { nodeType?: unknown } | null;\n if (!target || typeof target.nodeType !== 'number') return;\n const node = target as Node;\n if (node.nodeType !== 1) return;\n const el = node as HTMLElement;\n if (isInsideTrap(trap, el)) {\n trap.lastFocused = el;\n return;\n }\n // Pulled out again by the focus being returned (another focus trap on the page): leave it there\n // rather than fight forever.\n if (reclaiming) return;\n // Not in this dispatch: React applies `autoFocus` in the layout phase of the commit that mounts\n // a surface, before the surface's portal wrapper and dismiss layer register and before its own\n // trap starts (a nested dialog, a confirm dialog over a drawer, a popover opened from a dialog).\n // Once that commit has run, the element is inside the trap that is active then.\n queueMicrotask(() => reclaimFocus(el));\n}\n\n/** Whether {@link reclaimFocus} is moving focus (its `focusin` events are dispatched meanwhile). */\nlet reclaiming = false;\n\n/** Whether focus is on no element: `<body>`, the document element or nothing. */\nfunction isFocusLost(doc: Document): boolean {\n const active = doc.activeElement;\n return !active || active === doc.body || active === doc.documentElement;\n}\n\n/**\n * Returns focus that landed on `el`, outside the trap, to the last focused element inside — also\n * when `el` lost it again before this ran (removed or blurred: focus is on `<body>` then, and no\n * later `focusin` would bring it back). Focus that moved on to another element is left to that\n * element's own check.\n */\nfunction reclaimFocus(el: HTMLElement): void {\n const doc = el.ownerDocument;\n const lost = doc.activeElement !== el;\n if (lost && !isFocusLost(doc)) return; // focus has moved on since\n const trap = getActiveTrap(getState());\n if (!trap || !trap.container.isConnected) return;\n if (!lost && isInsideTrap(trap, el)) {\n trap.lastFocused = el;\n return;\n }\n const last = trap.lastFocused;\n const lastIsValid = !!last && last.isConnected && isInsideTrap(trap, last) && isFocusable(last);\n reclaiming = true;\n try {\n focusFirstPossible([\n lastIsValid ? last : null,\n getFirstTabbable(trap.container),\n trap.container,\n ]);\n } finally {\n reclaiming = false;\n }\n}\n\nfunction ensureListeners(state: TrapState): void {\n if (state.listeners || typeof document === 'undefined') return;\n const doc = document;\n doc.addEventListener('keydown', handleKeyDown);\n doc.addEventListener('focusin', handleFocusIn, true);\n state.listeners = {\n remove() {\n doc.removeEventListener('keydown', handleKeyDown);\n doc.removeEventListener('focusin', handleFocusIn, true);\n },\n };\n}\n\nfunction pushTrap(entry: TrapEntry): () => void {\n const state = getState();\n state.traps.push(entry);\n ensureListeners(state);\n return () => {\n const index = state.traps.indexOf(entry);\n if (index !== -1) state.traps.splice(index, 1);\n if (state.traps.length === 0) {\n state.listeners?.remove();\n state.listeners = null;\n }\n };\n}\n\nfunction resolveInitialFocus(\n container: HTMLElement,\n initialFocus: UseFocusTrapOptions['initialFocus'],\n): Array<HTMLElement | null> {\n const first = getFirstTabbable(container);\n if (initialFocus === 'container') return [container];\n if (initialFocus === undefined || initialFocus === 'first') return [first, container];\n const chosen = typeof initialFocus === 'function' ? initialFocus() : initialFocus.current;\n return [chosen, first, container];\n}\n\n/**\n * Keeps keyboard focus inside `container` while `enabled` (modal dialogs, drawers, the DatePicker\n * calendar). Element-based: pass the surface held in state via a callback ref, so the trap starts\n * when the element appears.\n *\n * - **Initial focus** runs synchronously in the commit in which the container appears (no\n * `requestAnimationFrame`), and does nothing when focus is already inside (an `autoFocus`\n * element wins).\n * - **Tab / Shift+Tab** are handled by a document bubble-phase `keydown` listener that ignores\n * events whose default is already prevented, so a React handler inside (a menu closing on Tab, a\n * grid) can take the key first. Focus wraps at the edges, and from the container itself or a\n * non-tabbable element it continues in document order. Tabbable elements are computed on every\n * keydown (content may change; radio-group stops depend on focus), never cached.\n * - Tabbables inside `[data-wave-focus-trap-allow]` regions (the Toaster viewport) join the cycle.\n * - **Descendant layers** (a popover or menu opened from inside, identified through `layerId`):\n * Tab moves natively inside them; leaving one moves focus to the element after its anchor\n * (Shift+Tab: the anchor itself). Inside a plain `<Portal>` rendered in the surface (no layer,\n * no anchor) Tab is native too; leaving it wraps to the first (Shift+Tab: last) element. A\n * layer's trigger (its anchor, or an element around it such as a tooltip's wrapper) belongs to\n * the region it sits in, so Tab from an open info button or a button showing its tooltip moves\n * on as from any other element of that portal or popover.\n * - Focus that lands outside (not in the container, an allowed region or a descendant layer)\n * returns to the last focused element inside, also when that outside element loses it again\n * (removed or blurred, leaving focus on `<body>`). That is decided in a microtask, once the\n * current commit has run: an `autoFocus` element of a surface opened above the trap (a nested or\n * stacked dialog, a popover opened from the surface) gets focus before that surface's layer and\n * trap exist, and keeps it. The layer's own `refs` (its trigger, outside the container) are\n * outside: opening from the focused trigger still moves focus in, and focus moving back onto\n * the trigger is returned. Focus pulled out again while it is being returned (another focus\n * trap on the page) is left there.\n * - Traps form a stack (shared through the global registry): only the topmost acts.\n */\nexport function useFocusTrap(container: HTMLElement | null, options: UseFocusTrapOptions): void {\n const { enabled } = options;\n const latestRef = useRef(options);\n\n useInsertionEffect(() => {\n latestRef.current = options;\n });\n\n useLayoutEffect(() => {\n if (!enabled || !container) return;\n const latest = latestRef;\n const state = getState();\n state.seq += 1;\n const entry: TrapEntry = {\n container,\n seq: state.seq,\n get layerId() {\n return latest.current.layerId;\n },\n get allowOutsideSelector() {\n return latest.current.allowOutsideSelector ?? ALLOW_OUTSIDE_SELECTOR;\n },\n lastFocused: null,\n };\n const release = pushTrap(entry);\n\n // Initial focus is skipped only when focus is already inside the container or one of its\n // descendant layers (never for the layer's own trigger or an allow-listed toast).\n const active = container.ownerDocument.activeElement as HTMLElement | null;\n const focusInside =\n !!active &&\n (container.contains(active) ||\n (!active.closest(entry.allowOutsideSelector) &&\n isInsideDescendantLayers(latest.current.layerId, active)));\n if (focusInside) {\n entry.lastFocused = active;\n } else {\n focusFirstPossible(resolveInitialFocus(container, latest.current.initialFocus));\n const now = container.ownerDocument.activeElement as HTMLElement | null;\n if (now && container.contains(now)) entry.lastFocused = now;\n }\n return release;\n }, [enabled, container]);\n}\n"],"mappings":"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"}
|