@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,389 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { isDev as e, warnOnce as t } from "../lib/dev.mjs";
|
|
3
|
+
import { setRef as n } from "../lib/mergeRefs.mjs";
|
|
4
|
+
import { useEventCallback as r } from "./useEventCallback.mjs";
|
|
5
|
+
import { getArrowIntent as i, getDirection as a } from "../lib/direction.mjs";
|
|
6
|
+
import { getFirstTabbable as o, isHiddenInput as s } from "../lib/focus.mjs";
|
|
7
|
+
import { isAltGraphCharacter as c, useTypeahead as l } from "./useTypeahead.mjs";
|
|
8
|
+
import * as u from "react";
|
|
9
|
+
//#region src/hooks/useRovingTabIndex.ts
|
|
10
|
+
var d = "[data-roving-value]", f = /* @__PURE__ */ new Set([
|
|
11
|
+
"radiogroup",
|
|
12
|
+
"listbox",
|
|
13
|
+
"grid",
|
|
14
|
+
"treegrid",
|
|
15
|
+
"tablist",
|
|
16
|
+
"menu",
|
|
17
|
+
"menubar",
|
|
18
|
+
"tree",
|
|
19
|
+
"spinbutton"
|
|
20
|
+
]), p = /* @__PURE__ */ new Set([
|
|
21
|
+
"slider",
|
|
22
|
+
"spinbutton",
|
|
23
|
+
"textbox",
|
|
24
|
+
"searchbox"
|
|
25
|
+
]), m = /* @__PURE__ */ new Set([
|
|
26
|
+
"button",
|
|
27
|
+
"checkbox",
|
|
28
|
+
"color",
|
|
29
|
+
"file",
|
|
30
|
+
"hidden",
|
|
31
|
+
"image",
|
|
32
|
+
"radio",
|
|
33
|
+
"reset",
|
|
34
|
+
"submit"
|
|
35
|
+
]), h = [
|
|
36
|
+
"disabled",
|
|
37
|
+
"aria-disabled",
|
|
38
|
+
"data-disabled-focusable",
|
|
39
|
+
"data-roving-disabled",
|
|
40
|
+
"data-roving-value",
|
|
41
|
+
"data-roving-container",
|
|
42
|
+
"data-roving-transparent",
|
|
43
|
+
"tabindex",
|
|
44
|
+
"hidden",
|
|
45
|
+
"inert",
|
|
46
|
+
"role",
|
|
47
|
+
"type",
|
|
48
|
+
"contenteditable"
|
|
49
|
+
];
|
|
50
|
+
function g(e, t) {
|
|
51
|
+
if (e.hasAttribute("data-roving-container")) return !0;
|
|
52
|
+
if (!t || e.hasAttribute("data-roving-transparent")) return !1;
|
|
53
|
+
let n = e.getAttribute("role");
|
|
54
|
+
return n !== null && f.has(n);
|
|
55
|
+
}
|
|
56
|
+
function _(e, t, n) {
|
|
57
|
+
for (let r = e; r && r !== t; r = r.parentElement) if (g(r, n)) return !0;
|
|
58
|
+
return !1;
|
|
59
|
+
}
|
|
60
|
+
function v(e) {
|
|
61
|
+
return e.tabIndex >= 0 && !e.hasAttribute("disabled");
|
|
62
|
+
}
|
|
63
|
+
function y(e) {
|
|
64
|
+
let { element: t } = e;
|
|
65
|
+
if (!e.nested || v(t)) return t;
|
|
66
|
+
let n = t.querySelector("[tabindex=\"0\"]");
|
|
67
|
+
if (n) return n;
|
|
68
|
+
let r = o(t);
|
|
69
|
+
return r instanceof HTMLElement ? r : null;
|
|
70
|
+
}
|
|
71
|
+
function b(e) {
|
|
72
|
+
let t = e.getAttribute("data-roving-disabled");
|
|
73
|
+
return t !== null && t !== "false" || x(e) ? !0 : !e.hasAttribute("data-disabled-focusable") && e.getAttribute("aria-disabled") === "true";
|
|
74
|
+
}
|
|
75
|
+
function x(e) {
|
|
76
|
+
if (e.disabled === !0) return !0;
|
|
77
|
+
try {
|
|
78
|
+
return e.matches(":disabled");
|
|
79
|
+
} catch {
|
|
80
|
+
return !1;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function S(e) {
|
|
84
|
+
if (!e || e.nodeType !== 1) return !1;
|
|
85
|
+
let t = e, n = t.getAttribute("role");
|
|
86
|
+
if (n !== null && p.has(n)) return !0;
|
|
87
|
+
let r = t.localName;
|
|
88
|
+
if (r === "textarea" || r === "select") return !0;
|
|
89
|
+
if (r === "input") return !m.has(t.type);
|
|
90
|
+
let i = t.closest("[contenteditable]");
|
|
91
|
+
return i !== null && i.getAttribute("contenteditable") !== "false";
|
|
92
|
+
}
|
|
93
|
+
function C(e) {
|
|
94
|
+
return !e.nested && !S(e.element);
|
|
95
|
+
}
|
|
96
|
+
function w(e, t, n) {
|
|
97
|
+
let r = e.ownerDocument.defaultView;
|
|
98
|
+
if (!r) return !1;
|
|
99
|
+
for (let i = e; i && i !== t; i = i.parentElement) {
|
|
100
|
+
let e = n.get(i);
|
|
101
|
+
if (e === void 0) {
|
|
102
|
+
let t = i.parentElement;
|
|
103
|
+
e = r.getComputedStyle(i).display === "none" || t !== null && t.localName === "details" && !t.hasAttribute("open") && Array.from(t.children).find((e) => e.localName === "summary") !== i, n.set(i, e);
|
|
104
|
+
}
|
|
105
|
+
if (e) return !0;
|
|
106
|
+
}
|
|
107
|
+
let { visibility: i } = r.getComputedStyle(e);
|
|
108
|
+
return i !== "hidden" && i !== "collapse" ? !1 : r.getComputedStyle(t).visibility === "visible";
|
|
109
|
+
}
|
|
110
|
+
function ee(e) {
|
|
111
|
+
let t = e.getRootNode().activeElement;
|
|
112
|
+
return !!t && e.contains(t);
|
|
113
|
+
}
|
|
114
|
+
function te(e) {
|
|
115
|
+
try {
|
|
116
|
+
return document.createDocumentFragment().querySelector(e), !0;
|
|
117
|
+
} catch {
|
|
118
|
+
return !1;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
function T(e) {
|
|
122
|
+
return [e.value, e.disabled ? 0 : C(e) ? 1 : 2];
|
|
123
|
+
}
|
|
124
|
+
function E(e, t, n, r) {
|
|
125
|
+
let i = e.some(([, e]) => e === 1) ? 1 : 2, a = e.filter(([, e]) => e === i).map(([e]) => e);
|
|
126
|
+
return n === "last-focused" && r !== null && a.includes(r) ? r : t !== null && t !== "" && a.includes(t) ? t : a[0] ?? null;
|
|
127
|
+
}
|
|
128
|
+
function D(e, t) {
|
|
129
|
+
if (!t) return e;
|
|
130
|
+
let n = new Map(e.map((e) => [e.value, e])), r = [];
|
|
131
|
+
for (let e of t) {
|
|
132
|
+
let t = n.get(e);
|
|
133
|
+
t && r.push(t);
|
|
134
|
+
}
|
|
135
|
+
return r;
|
|
136
|
+
}
|
|
137
|
+
var O = class {
|
|
138
|
+
container = null;
|
|
139
|
+
lastFocused = null;
|
|
140
|
+
options = {
|
|
141
|
+
itemSelector: d,
|
|
142
|
+
manageTabIndex: !1,
|
|
143
|
+
items: void 0,
|
|
144
|
+
activeValue: null,
|
|
145
|
+
tabStop: "active",
|
|
146
|
+
roleComposites: !0
|
|
147
|
+
};
|
|
148
|
+
stamped = /* @__PURE__ */ new WeakMap();
|
|
149
|
+
autoValues = /* @__PURE__ */ new WeakMap();
|
|
150
|
+
autoCounter = 0;
|
|
151
|
+
notify = null;
|
|
152
|
+
observer = null;
|
|
153
|
+
dirty = !0;
|
|
154
|
+
snapshot = "";
|
|
155
|
+
subscribe = (e) => (this.notify = e, this.observe(), () => {
|
|
156
|
+
this.notify = null, this.disconnect();
|
|
157
|
+
});
|
|
158
|
+
getSnapshot = () => this.container ? (this.dirty && (this.dirty = !1, this.snapshot = JSON.stringify(this.resolveOwn().map(T))), this.snapshot) : "";
|
|
159
|
+
getServerSnapshot = () => "";
|
|
160
|
+
setContainer(e) {
|
|
161
|
+
e !== this.container && (this.disconnect(), this.container = e, this.dirty = !0, this.notify && (this.observe(), this.notify()));
|
|
162
|
+
}
|
|
163
|
+
recordFocus(e) {
|
|
164
|
+
C(e) && (this.lastFocused = e.value);
|
|
165
|
+
}
|
|
166
|
+
setOptions(e) {
|
|
167
|
+
let t = this.options;
|
|
168
|
+
this.options = e, (t.itemSelector !== e.itemSelector || t.manageTabIndex !== e.manageTabIndex || t.roleComposites !== e.roleComposites) && (this.dirty = !0, this.notify?.());
|
|
169
|
+
}
|
|
170
|
+
resolve(e = this.container) {
|
|
171
|
+
return D(this.resolveOwn(e), this.options.items);
|
|
172
|
+
}
|
|
173
|
+
resolveOwn(e = this.container) {
|
|
174
|
+
if (!e) return [];
|
|
175
|
+
let { itemSelector: t, manageTabIndex: n, roleComposites: r } = this.options, i;
|
|
176
|
+
try {
|
|
177
|
+
i = Array.from(e.querySelectorAll(t));
|
|
178
|
+
} catch {
|
|
179
|
+
return [];
|
|
180
|
+
}
|
|
181
|
+
let a = [], o = /* @__PURE__ */ new Set(), c = /* @__PURE__ */ new Map();
|
|
182
|
+
for (let t of i) {
|
|
183
|
+
let i = null, l = !1;
|
|
184
|
+
for (let n = t; n && n !== e; n = n.parentElement) g(n, r) && (i = n), (n.hidden || n.hasAttribute("inert")) && (l = !0);
|
|
185
|
+
if (l) continue;
|
|
186
|
+
let u = i ?? t;
|
|
187
|
+
if (o.has(u)) continue;
|
|
188
|
+
let d = i !== null;
|
|
189
|
+
if (!d && n && (t.getAttribute("tabindex") === "-1" && !this.stamped.has(t) || s(t))) continue;
|
|
190
|
+
o.add(u);
|
|
191
|
+
let f = {
|
|
192
|
+
value: this.valueOf(u, d),
|
|
193
|
+
element: u,
|
|
194
|
+
nested: d,
|
|
195
|
+
disabled: b(u)
|
|
196
|
+
};
|
|
197
|
+
d && !f.disabled && !y(f) && (f.disabled = !0), n && !f.disabled && w(u, e, c) && (f.disabled = !0), a.push(f);
|
|
198
|
+
}
|
|
199
|
+
return a;
|
|
200
|
+
}
|
|
201
|
+
stamp() {
|
|
202
|
+
if (!this.options.manageTabIndex || !this.container) return;
|
|
203
|
+
this.release(this.container);
|
|
204
|
+
let e = this.resolve(), t = E(e.map(T), this.options.activeValue, this.options.tabStop, this.lastFocused);
|
|
205
|
+
for (let n of e) {
|
|
206
|
+
if (n.nested) continue;
|
|
207
|
+
let { element: e } = n, r = this.stamped.get(e);
|
|
208
|
+
r || (r = {
|
|
209
|
+
tabIndex: e.getAttribute("tabindex"),
|
|
210
|
+
addedValue: !e.hasAttribute("data-roving-value")
|
|
211
|
+
}, this.stamped.set(e, r));
|
|
212
|
+
let i = n.value === t ? "0" : "-1";
|
|
213
|
+
e.getAttribute("tabindex") !== i && e.setAttribute("tabindex", i), e.hasAttribute("data-roving-value") || e.setAttribute("data-roving-value", n.value);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
release(e) {
|
|
217
|
+
let t;
|
|
218
|
+
try {
|
|
219
|
+
t = Array.from(e.querySelectorAll(this.options.itemSelector));
|
|
220
|
+
} catch {
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
for (let n of t) {
|
|
224
|
+
let t = this.stamped.get(n);
|
|
225
|
+
t && _(n, e, this.options.roleComposites) && (this.stamped.delete(n), t.tabIndex === null ? n.removeAttribute("tabindex") : n.setAttribute("tabindex", t.tabIndex), t.addedValue && n.removeAttribute("data-roving-value"));
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
valueOf(e, t) {
|
|
229
|
+
let n = t ? null : e.getAttribute("data-roving-value");
|
|
230
|
+
if (n !== null) return n;
|
|
231
|
+
let r = this.autoValues.get(e);
|
|
232
|
+
return r === void 0 && (this.autoCounter += 1, r = `auto-${this.autoCounter}`, this.autoValues.set(e, r)), r;
|
|
233
|
+
}
|
|
234
|
+
observe() {
|
|
235
|
+
this.container && !this.observer && typeof MutationObserver < "u" && (this.observer = new MutationObserver(() => {
|
|
236
|
+
this.stamp(), this.dirty = !0, this.notify?.();
|
|
237
|
+
}), this.observer.observe(this.container, {
|
|
238
|
+
subtree: !0,
|
|
239
|
+
childList: !0,
|
|
240
|
+
attributes: !0,
|
|
241
|
+
attributeFilter: h
|
|
242
|
+
}), this.dirty = !0);
|
|
243
|
+
}
|
|
244
|
+
disconnect() {
|
|
245
|
+
this.observer?.disconnect(), this.observer = null;
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
function k(e) {
|
|
249
|
+
if (e === "") return null;
|
|
250
|
+
try {
|
|
251
|
+
return JSON.parse(e);
|
|
252
|
+
} catch {
|
|
253
|
+
return null;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
function A(e) {
|
|
257
|
+
return e.getAttribute("data-roving-text") ?? e.textContent ?? "";
|
|
258
|
+
}
|
|
259
|
+
function j(e, t) {
|
|
260
|
+
return !t || typeof t.nodeType != "number" ? !1 : t === e || e.contains(t);
|
|
261
|
+
}
|
|
262
|
+
function M(e, t, n) {
|
|
263
|
+
if (e.length === 0 || !t || typeof t.nodeType != "number") return null;
|
|
264
|
+
let r = new Map(e.map((e) => [e.element, e]));
|
|
265
|
+
for (let e = t; e && e !== n; e = e.parentNode) {
|
|
266
|
+
let t = r.get(e);
|
|
267
|
+
if (t) return t;
|
|
268
|
+
}
|
|
269
|
+
return null;
|
|
270
|
+
}
|
|
271
|
+
function N(e, t, n) {
|
|
272
|
+
return e ? t === y(e) : t === n;
|
|
273
|
+
}
|
|
274
|
+
function P(o, s) {
|
|
275
|
+
let f = s === void 0 ? void 0 : o, { activeValue: p = null, items: m, orientation: h = "horizontal", loop: g = !0, dir: _, itemSelector: v = d, typeahead: b = !1, homeEndKeys: x = !0, tabStop: w = "active", manageTabIndex: T = !1, onFocusMove: D } = s ?? o, [P] = u.useState(() => new O()), F = u.useSyncExternalStore(P.subscribe, P.getSnapshot, P.getServerSnapshot), [I, L] = u.useState(null), [R, z] = u.useState(null), B = f === void 0 && m === void 0;
|
|
276
|
+
u.useLayoutEffect(() => {
|
|
277
|
+
P.setOptions({
|
|
278
|
+
itemSelector: v,
|
|
279
|
+
manageTabIndex: T,
|
|
280
|
+
items: m,
|
|
281
|
+
activeValue: p,
|
|
282
|
+
tabStop: w,
|
|
283
|
+
roleComposites: B
|
|
284
|
+
}), f && P.setContainer(f.current), P.stamp();
|
|
285
|
+
}), u.useEffect(() => {
|
|
286
|
+
e && !te(v) && t(`useRovingTabIndex:itemSelector:${v}`, `useRovingTabIndex: itemSelector "${v}" is not a valid CSS selector in this browser; no item is navigable or tabbable.`);
|
|
287
|
+
}, [v]);
|
|
288
|
+
let V = u.useMemo(() => k(F), [F]), H = u.useMemo(() => {
|
|
289
|
+
if (!m) return V;
|
|
290
|
+
if (V) {
|
|
291
|
+
let e = new Map(V), t = m.flatMap((t) => {
|
|
292
|
+
let n = e.get(t);
|
|
293
|
+
return n === void 0 ? [] : [[t, n]];
|
|
294
|
+
});
|
|
295
|
+
if (t.length > 0) return t;
|
|
296
|
+
}
|
|
297
|
+
return m.map((e) => [e, 1]);
|
|
298
|
+
}, [m, V]), U = H ? E(H, p, w, R) : p || null, W = u.useCallback((e) => e === U ? 0 : -1, [U]), G = u.useCallback((e) => {
|
|
299
|
+
P.setContainer(e), f && n(f, e);
|
|
300
|
+
}, [P, f]), K = u.useRef([]), q = u.useRef([]), { onTypeahead: ne, isSearching: re } = l({
|
|
301
|
+
getItems: () => K.current,
|
|
302
|
+
onMatch: (e, t) => {
|
|
303
|
+
q.current = t;
|
|
304
|
+
}
|
|
305
|
+
}), J = (e) => {
|
|
306
|
+
if (!e || e.disabled) return !1;
|
|
307
|
+
let t = y(e);
|
|
308
|
+
return !t || (t.focus(), !ee(t)) ? !1 : (P.recordFocus(e), !0);
|
|
309
|
+
}, Y = (e) => {
|
|
310
|
+
for (let t of e) if (J(t)) return;
|
|
311
|
+
}, X = r((e, t) => {
|
|
312
|
+
let n = e.metaKey || (e.altKey || e.ctrlKey) && !c(e);
|
|
313
|
+
if (e.defaultPrevented || n || S(e.target)) return;
|
|
314
|
+
let r = P.container ?? e.currentTarget;
|
|
315
|
+
if (!j(r, e.target)) return;
|
|
316
|
+
let o = P.resolve(r), s = o.filter((e) => !e.disabled);
|
|
317
|
+
if (s.length === 0) return;
|
|
318
|
+
let l = M(o, e.target, r), u = !1, d = [], f = t ? null : i(e.key, {
|
|
319
|
+
orientation: h,
|
|
320
|
+
dir: _ ?? a(e.currentTarget)
|
|
321
|
+
});
|
|
322
|
+
if (f) {
|
|
323
|
+
if (u = !0, !l) d = f === "next" ? s : [...s].reverse();
|
|
324
|
+
else {
|
|
325
|
+
let e = f === "next" ? 1 : -1, t = o.length, n = o.indexOf(l);
|
|
326
|
+
for (let r = 1; r < t; r++) {
|
|
327
|
+
if (n += e, n < 0 || n >= t) {
|
|
328
|
+
if (!g) break;
|
|
329
|
+
n = (n + t) % t;
|
|
330
|
+
}
|
|
331
|
+
o[n].disabled || d.push(o[n]);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
} else !t && x && (e.key === "Home" || e.key === "End") ? (u = !0, d = e.key === "Home" ? s : [...s].reverse()) : b && N(l, e.target, r) && (K.current = o.map((e) => ({
|
|
335
|
+
value: e.value,
|
|
336
|
+
text: A(e.element),
|
|
337
|
+
disabled: e.disabled
|
|
338
|
+
})), q.current = [], ne(e, l?.value ?? null) && (u = !0, d = q.current.flatMap((e) => s.filter((t) => t.value === e))));
|
|
339
|
+
if (u) {
|
|
340
|
+
e.preventDefault();
|
|
341
|
+
for (let t of d) {
|
|
342
|
+
if (t === l) return;
|
|
343
|
+
if (J(t)) {
|
|
344
|
+
D?.(t.value, e);
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}), Z = r((e) => X(e, !1)), Q = r((e) => {
|
|
350
|
+
b && e.key === " " && re() && X(e, !0);
|
|
351
|
+
}), $ = r((e) => {
|
|
352
|
+
let t = P.container ?? e.currentTarget;
|
|
353
|
+
if (!j(t, e.target)) return;
|
|
354
|
+
let n = M(P.resolve(t), e.target, t);
|
|
355
|
+
n && (P.recordFocus(n), L(n.value), C(n) && z(n.value), P.stamp());
|
|
356
|
+
}), ie = r((e) => {
|
|
357
|
+
J(P.resolve().find((t) => t.value === e));
|
|
358
|
+
}), ae = r(() => {
|
|
359
|
+
Y(P.resolve().filter((e) => !e.disabled));
|
|
360
|
+
}), oe = r(() => {
|
|
361
|
+
Y(P.resolve().filter((e) => !e.disabled).reverse());
|
|
362
|
+
});
|
|
363
|
+
return {
|
|
364
|
+
containerProps: u.useMemo(() => ({
|
|
365
|
+
ref: G,
|
|
366
|
+
"data-roving-container": "",
|
|
367
|
+
onKeyDown: Z,
|
|
368
|
+
onKeyDownCapture: Q,
|
|
369
|
+
onFocus: $
|
|
370
|
+
}), [
|
|
371
|
+
G,
|
|
372
|
+
Z,
|
|
373
|
+
Q,
|
|
374
|
+
$
|
|
375
|
+
]),
|
|
376
|
+
handleKeyDown: Z,
|
|
377
|
+
handleKeyDownCapture: Q,
|
|
378
|
+
handleFocus: $,
|
|
379
|
+
getTabIndex: W,
|
|
380
|
+
focusedValue: I,
|
|
381
|
+
focusValue: ie,
|
|
382
|
+
focusFirst: ae,
|
|
383
|
+
focusLast: oe
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
//#endregion
|
|
387
|
+
export { P as useRovingTabIndex };
|
|
388
|
+
|
|
389
|
+
//# sourceMappingURL=useRovingTabIndex.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useRovingTabIndex.mjs","names":["React","DEFAULT_ITEM_SELECTOR","COMPOSITE_ROLES","ARROW_KEY_OWNER_ROLES","NON_TEXT_INPUT_TYPES","OBSERVED_ATTRIBUTES","isNestedComposite","el","roleComposites","role","isInNestedComposite","node","container","isFocusableSelf","getFocusTarget","item","element","ownStop","tabbable","getFirstTabbable","isDisabledElement","marker","isNativelyDisabled","ownsArrowKeys","target","tag","editable","canHoldTabStop","isHiddenByCss","view","hidden","cache","parent","child","visibility","hasFocus","active","isValidSelector","selector","toEntry","resolveTabStop","rank","entries","r","values","value","tabStop","lastFocused","activeValue","orderByItems","items","resolved","byValue","ordered","RovingStore","notify","previous","options","candidates","itemSelector","result","seen","cssHidden","candidate","composite","nested","manageTabIndex","isHiddenInput","stop","original","tabIndex","own","generated","parseSnapshot","snapshot","textOf","isInContainer","findOwningItem","byElement","startsOnItem","useRovingTabIndex","legacyRef","maybeOptions","refOrOptions","store","focusedValue","setFocusedValue","focusedStop","setFocusedStop","isDev","warnOnce","domItems","stopEntries","ranks","present","tabStopValue","getTabIndex","containerRef","setRef","typeaheadItemsRef","typeaheadMatchesRef","useTypeahead","matches","focusItem","focusFirstOf","handleKeys","useEventCallback","shortcut","isAltGraphCharacter","enabled","current","handled","targets","intent","spaceOnly","getArrowIntent","dir","getDirection","step","count","index","i","loop","homeEndKeys","typeahead","onTypeahead","next","handleKeyDown","handleKeyDownCapture","isSearching","handleFocus","focusValue","focusFirst","focusLast"],"sources":["../../src/hooks/useRovingTabIndex.ts"],"sourcesContent":["import * as React from 'react';\nimport type { WaveDir } from '../components/provider/WaveProvider';\nimport { isDev, warnOnce } from '../lib/dev';\nimport { getArrowIntent, getDirection } from '../lib/direction';\nimport { getFirstTabbable, isHiddenInput } from '../lib/focus';\nimport { setRef } from '../lib/mergeRefs';\nimport { useEventCallback } from './useEventCallback';\nimport { isAltGraphCharacter, useTypeahead, type TypeaheadItem } from './useTypeahead';\n\n/**\n * Configuration options for the {@link useRovingTabIndex} hook. Disabled items are skipped; items\n * marked `data-disabled-focusable` (the `disabledFocusable` prop of WaveUI buttons, links and\n * choice controls) stay reachable and may hold the tab stop: APG allows focusable disabled items.\n */\nexport interface UseRovingTabIndexOptions {\n /**\n * The selected value. It may be absent, `''` or `null` (nothing selected) and does not have to be\n * one of the items.\n */\n activeValue?: string | null;\n /**\n * Explicit item order (0.4 call shape). Omitted ⇒ the DOM order of the elements matching\n * `itemSelector`. Disabled items are skipped either way, and so are listed values with no\n * element in the container (not rendered, or `hidden`/`inert`): they never hold the tab stop.\n */\n items?: readonly string[];\n /**\n * Arrow key axis: `'horizontal'` uses Left/Right (mirrored in RTL), `'vertical'` uses Up/Down,\n * `'both'` uses all four.\n * @default 'horizontal'\n */\n orientation?: 'horizontal' | 'vertical' | 'both';\n /**\n * Whether arrow keys wrap around at the ends.\n * @default true\n */\n loop?: boolean;\n /** Text direction. Defaults to the direction of the container at key time (`getDirection`). */\n dir?: WaveDir;\n /**\n * Selector for the item elements inside the container. A selector the browser rejects matches\n * nothing (no item is navigable or tabbable) and logs a development warning.\n * @default '[data-roving-value]'\n */\n itemSelector?: string;\n /**\n * Printable characters move focus to the next item whose text (`data-roving-text`, else its\n * text content) starts with them. A Space typed within 500 ms of another character continues\n * the search instead of activating the focused item: `containerProps.onKeyDownCapture` calls\n * `preventDefault()` on it before an item's own keydown handler runs, so that handler must skip\n * default-prevented events (`composeEventHandlers` does). Keys typed in content nested inside an\n * item (a row's action button) are not typeahead. A character typed with AltGr (which Windows\n * reports as Ctrl+Alt, e.g. Polish `ł`) is typeahead text; other Ctrl, Alt or Meta\n * combinations, Ctrl+Alt+Space included, are shortcuts and ignored. A match whose `focus()`\n * leaves focus where it was is passed over for the next item that matches.\n * @default false\n */\n typeahead?: boolean;\n /**\n * Whether Home/End move to the first/last enabled item.\n * @default true\n */\n homeEndKeys?: boolean;\n /** Which item holds the tab stop. 'active' (default): the enabled activeValue item, else the first\n * enabled item — APG Tabs/Radio/Listbox/Tree. 'last-focused': the last focused enabled item, else\n * 'active' — APG Toolbar (and the static Menu). Either way a nested composite or a control that\n * uses the arrow keys itself (text field, select, slider, spin button, editable combobox) holds\n * it only when no other item can: arrows pressed there never lead back to the other items, so\n * focusing one keeps the tab stop on the last focused other item. */\n tabStop?: 'active' | 'last-focused';\n /** true ⇒ the hook writes tabIndex 0/-1 onto item elements itself and assigns\n * data-roving-value=\"auto-<n>\" to items that lack one. For containers that do not render their\n * items (Toolbar children, Menu items, Tree rows). Default false (items call getTabIndex).\n * Matches that cannot take focus are no items: `input[type=hidden]` is skipped, and a control\n * hidden by CSS inside the container (`display: none` or `visibility: hidden` on it or on an\n * ancestor inside the container) is treated as disabled (skipped, never the tab stop, stamped\n * -1). A container hidden as a whole from outside keeps its items and tab stop. */\n manageTabIndex?: boolean;\n /** Called after an arrow, Home/End or typeahead key moved focus to `value`. */\n onFocusMove?: (value: string, event: React.KeyboardEvent) => void;\n}\n\n/** Props to spread onto the container element. */\nexport interface RovingContainerProps {\n ref: React.RefCallback<HTMLElement>;\n 'data-roving-container': '';\n onKeyDown: React.KeyboardEventHandler;\n /** With `typeahead`: default-prevents a Space that continues a search, before item handlers. */\n onKeyDownCapture: React.KeyboardEventHandler;\n onFocus: React.FocusEventHandler;\n}\n\n/** Result of {@link useRovingTabIndex}. */\nexport interface UseRovingTabIndexResult {\n /** Spread onto the container: ref, `data-roving-container` marker and the key/focus handlers. */\n containerProps: RovingContainerProps;\n /** The container's keydown handler (same function as `containerProps.onKeyDown`). */\n handleKeyDown: (e: React.KeyboardEvent) => void;\n /**\n * The container's capture-phase keydown handler (same function as\n * `containerProps.onKeyDownCapture`). With `typeahead`, it extends the search with a Space that\n * continues one and calls `preventDefault()`, before an item's own keydown handler runs: an item\n * that activates on Space must skip default-prevented events (`composeEventHandlers` does).\n */\n handleKeyDownCapture: (e: React.KeyboardEvent) => void;\n /** The container's focus handler (same function as `containerProps.onFocus`). */\n handleFocus: (e: React.FocusEvent) => void;\n /** `0` for the item that holds the tab stop, `-1` for every other item. */\n getTabIndex: (value: string) => 0 | -1;\n /** The value of the item that last received focus, or `null`. */\n focusedValue: string | null;\n /** Focuses the item with this value (ignored when it is disabled or unknown). */\n focusValue: (value: string) => void;\n /** Focuses the first enabled item. */\n focusFirst: () => void;\n /** Focuses the last enabled item. */\n focusLast: () => void;\n}\n\ninterface ResolvedItem {\n value: string;\n /** The item element (for a nested composite: its root). */\n element: HTMLElement;\n /** A nested composite (own roving container or composite role) counts as one item. */\n nested: boolean;\n /**\n * Skipped by the keys and never the tab stop: disabled, a nested composite with nothing to\n * focus, or (`manageTabIndex`) hidden by CSS.\n */\n disabled: boolean;\n}\n\ninterface StoreOptions {\n itemSelector: string;\n manageTabIndex: boolean;\n items: readonly string[] | undefined;\n activeValue: string | null;\n tabStop: 'active' | 'last-focused';\n /**\n * Whether an element with a composite role but no roving container of its own is a nested\n * composite (one item). Off in the 0.4 call shape and with explicit `items`, where such an element\n * is usually the widget's own root inside a wrapper that carries the container ref.\n */\n roleComposites: boolean;\n}\n\nconst DEFAULT_ITEM_SELECTOR = '[data-roving-value]';\n\n/** Roles of widgets that manage their own children: an element with one of them is one item. */\nconst COMPOSITE_ROLES = new Set([\n 'radiogroup',\n 'listbox',\n 'grid',\n 'treegrid',\n 'tablist',\n 'menu',\n 'menubar',\n 'tree',\n 'spinbutton',\n]);\n\n/**\n * Roles whose widgets use the arrow keys themselves. A combobox does only when it is editable (an\n * `<input>` or contenteditable, caught by the native checks): a select-only combobox such as\n * Dropdown's `<button role=\"combobox\">` uses Up/Down, Home and End, never Left/Right.\n */\nconst ARROW_KEY_OWNER_ROLES = new Set(['slider', 'spinbutton', 'textbox', 'searchbox']);\n\n/** `<input>` types that do not use the arrow keys for text editing. */\nconst NON_TEXT_INPUT_TYPES = new Set([\n 'button',\n 'checkbox',\n 'color',\n 'file',\n 'hidden',\n 'image',\n 'radio',\n 'reset',\n 'submit',\n]);\n\nconst OBSERVED_ATTRIBUTES = [\n 'disabled',\n 'aria-disabled',\n 'data-disabled-focusable',\n 'data-roving-disabled',\n 'data-roving-value',\n 'data-roving-container',\n 'data-roving-transparent',\n 'tabindex',\n 'hidden',\n 'inert',\n 'role',\n // Whether an item uses the arrow keys itself (text input types, contenteditable).\n 'type',\n 'contenteditable',\n];\n\n/**\n * Whether `el` is a nested composite: it has its own roving container, or (with `roleComposites`)\n * a composite role. An element marked `data-roving-transparent` is never one by its role (a\n * `role=\"radiogroup\"` whose radios are items of the enclosing container, `Toolbar.RadioGroup`);\n * its own `data-roving-container` still makes it one.\n */\nfunction isNestedComposite(el: Element, roleComposites: boolean): boolean {\n if (el.hasAttribute('data-roving-container')) return true;\n if (!roleComposites || el.hasAttribute('data-roving-transparent')) return false;\n const role = el.getAttribute('role');\n return role !== null && COMPOSITE_ROLES.has(role);\n}\n\n/** Whether `el` is a nested composite or inside one, below `container`. */\nfunction isInNestedComposite(el: Element, container: Element, roleComposites: boolean): boolean {\n for (let node: Element | null = el; node && node !== container; node = node.parentElement) {\n if (isNestedComposite(node, roleComposites)) return true;\n }\n return false;\n}\n\n/** What an element looked like before the hook stamped it, to hand it back unchanged. */\ninterface StampedOriginal {\n /**\n * The author's own `tabindex` attribute, or `null`, read at the first stamp. A `tabIndex` the\n * author renders differently while the element is stamped is not seen (the stamps overwrite it),\n * so the hand-back restores the first value.\n */\n tabIndex: string | null;\n /** Whether the hook added the element's `data-roving-value`. */\n addedValue: boolean;\n}\n\nfunction isFocusableSelf(el: HTMLElement): boolean {\n return el.tabIndex >= 0 && !el.hasAttribute('disabled');\n}\n\n/** The element to focus for an item: the item itself, or a nested composite's own tab stop. */\nfunction getFocusTarget(item: ResolvedItem): HTMLElement | null {\n const { element } = item;\n if (!item.nested || isFocusableSelf(element)) return element;\n const ownStop = element.querySelector<HTMLElement>('[tabindex=\"0\"]');\n if (ownStop) return ownStop;\n const tabbable = getFirstTabbable(element);\n return tabbable instanceof HTMLElement ? tabbable : null;\n}\n\n/**\n * Whether the keys skip an item, in this order: the composite's own `data-roving-disabled` marker\n * (not `\"false\"`) and native `disabled` skip it; `data-disabled-focusable` keeps it (a\n * `disabledFocusable` control: APG allows focusable disabled items); `aria-disabled=\"true\"` skips\n * it.\n */\nfunction isDisabledElement(el: HTMLElement): boolean {\n const marker = el.getAttribute('data-roving-disabled');\n if (marker !== null && marker !== 'false') return true;\n if (isNativelyDisabled(el)) return true;\n if (el.hasAttribute('data-disabled-focusable')) return false;\n return el.getAttribute('aria-disabled') === 'true';\n}\n\nfunction isNativelyDisabled(el: HTMLElement): boolean {\n if ((el as { disabled?: unknown }).disabled === true) return true;\n try {\n return el.matches(':disabled');\n } catch {\n return false;\n }\n}\n\n/** Text-entry fields and widgets that use the arrow keys themselves (APG Toolbar). */\nfunction ownsArrowKeys(target: EventTarget | null): boolean {\n if (!target || (target as Node).nodeType !== 1) return false;\n const el = target as HTMLElement;\n const role = el.getAttribute('role');\n if (role !== null && ARROW_KEY_OWNER_ROLES.has(role)) return true;\n const tag = el.localName;\n if (tag === 'textarea' || tag === 'select') return true;\n if (tag === 'input') return !NON_TEXT_INPUT_TYPES.has((el as HTMLInputElement).type);\n const editable = el.closest('[contenteditable]');\n return editable !== null && editable.getAttribute('contenteditable') !== 'false';\n}\n\n/**\n * Whether an item can hold the container's tab stop: not a nested composite (it keeps a tab stop\n * of its own) and not a control that uses the arrow keys itself. From either, the arrow keys never\n * lead to the other items, so a tab stop there would leave them reachable by keyboard only through\n * it (or not at all).\n */\nfunction canHoldTabStop(item: ResolvedItem): boolean {\n return !item.nested && !ownsArrowKeys(item.element);\n}\n\n/**\n * Whether CSS inside `container` keeps `el` from taking focus (browsers ignore `focus()` on it):\n * `display: none` on it or on an ancestor inside `container`, `visibility: hidden`/`collapse` set\n * inside `container`, or a place inside a closed `<details>` other than its summary. Hiding from\n * outside the container (a surface that stays invisible until it is positioned, a consumer panel)\n * hides the whole item set and does not count: showing it again changes nothing the hook observes,\n * so nothing would re-stamp. `cache` holds, for one resolution, whether an element hides its whole\n * subtree (the `display` and `<details>` checks).\n */\nfunction isHiddenByCss(el: Element, container: Element, cache: Map<Element, boolean>): boolean {\n const view = el.ownerDocument.defaultView;\n if (!view) return false;\n for (let node: Element | null = el; node && node !== container; node = node.parentElement) {\n let hidden = cache.get(node);\n if (hidden === undefined) {\n const parent = node.parentElement;\n hidden =\n view.getComputedStyle(node).display === 'none' ||\n (parent !== null &&\n parent.localName === 'details' &&\n !parent.hasAttribute('open') &&\n Array.from(parent.children).find((child) => child.localName === 'summary') !== node);\n cache.set(node, hidden);\n }\n if (hidden) return true;\n }\n const { visibility } = view.getComputedStyle(el);\n if (visibility !== 'hidden' && visibility !== 'collapse') return false;\n // Visibility is inherited, so `el` also reads hidden when an ancestor of the container hides the\n // whole container. It counts only when the container itself is visible, i.e. when the hiding is\n // set inside it (on `el` or on a wrapper between them).\n return view.getComputedStyle(container).visibility === 'visible';\n}\n\n/** Whether focus is on `el` or inside it (in its document or shadow root). */\nfunction hasFocus(el: HTMLElement): boolean {\n const active = (el.getRootNode() as Node & { activeElement?: Element | null }).activeElement;\n return !!active && el.contains(active);\n}\n\nfunction isValidSelector(selector: string): boolean {\n try {\n document.createDocumentFragment().querySelector(selector);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * How an item takes part in the tab stop: `0` never (disabled), `1` can hold it, `2` holds it only\n * when no item can (a nested composite, or a control that uses the arrow keys itself).\n */\ntype TabStopRank = 0 | 1 | 2;\n\n/** One item of the published DOM snapshot, and the input of {@link resolveTabStop}. */\ntype SnapshotEntry = [value: string, rank: TabStopRank];\n\nfunction toEntry(item: ResolvedItem): SnapshotEntry {\n return [item.value, item.disabled ? 0 : canHoldTabStop(item) ? 1 : 2];\n}\n\n/**\n * The value that holds the tab stop, among the items of the best rank present (`1`, else `2`):\n * with 'last-focused' the last focused one, else the `activeValue` item, else the first one.\n */\nfunction resolveTabStop(\n entries: readonly SnapshotEntry[],\n activeValue: string | null,\n tabStop: 'active' | 'last-focused',\n lastFocused: string | null,\n): string | null {\n const rank = entries.some(([, r]) => r === 1) ? 1 : 2;\n const values = entries.filter(([, r]) => r === rank).map(([value]) => value);\n if (tabStop === 'last-focused' && lastFocused !== null && values.includes(lastFocused)) {\n return lastFocused;\n }\n if (activeValue !== null && activeValue !== '' && values.includes(activeValue)) {\n return activeValue;\n }\n return values[0] ?? null;\n}\n\nfunction orderByItems(\n resolved: ResolvedItem[],\n items: readonly string[] | undefined,\n): ResolvedItem[] {\n if (!items) return resolved;\n const byValue = new Map(resolved.map((item) => [item.value, item]));\n const ordered: ResolvedItem[] = [];\n for (const value of items) {\n const item = byValue.get(value);\n if (item) ordered.push(item);\n }\n return ordered;\n}\n\n/**\n * Per-hook store: resolves items from the DOM, publishes the enabled set to React through\n * `useSyncExternalStore` (a MutationObserver on the container notifies it), and stamps tabIndex in\n * `manageTabIndex` mode.\n */\nclass RovingStore {\n container: HTMLElement | null = null;\n lastFocused: string | null = null;\n options: StoreOptions = {\n itemSelector: DEFAULT_ITEM_SELECTOR,\n manageTabIndex: false,\n items: undefined,\n activeValue: null,\n tabStop: 'active',\n roleComposites: true,\n };\n\n private readonly stamped = new WeakMap<Element, StampedOriginal>();\n private readonly autoValues = new WeakMap<Element, string>();\n private autoCounter = 0;\n private notify: (() => void) | null = null;\n private observer: MutationObserver | null = null;\n private dirty = true;\n private snapshot = '';\n\n subscribe = (notify: () => void): (() => void) => {\n this.notify = notify;\n this.observe();\n return () => {\n this.notify = null;\n this.disconnect();\n };\n };\n\n getSnapshot = (): string => {\n if (!this.container) return '';\n if (this.dirty) {\n this.dirty = false;\n // DOM facts only (order and tab stop rank); `items` is applied during render.\n this.snapshot = JSON.stringify(this.resolveOwn().map(toEntry));\n }\n return this.snapshot;\n };\n\n getServerSnapshot = (): string => '';\n\n setContainer(container: HTMLElement | null): void {\n if (container === this.container) return;\n this.disconnect();\n this.container = container;\n this.dirty = true;\n if (this.notify) {\n this.observe();\n this.notify();\n }\n }\n\n /**\n * Records a focused item for the 'last-focused' tab stop. An item that cannot hold the tab stop\n * (a nested composite, a control that uses the arrow keys itself) leaves the last one in place.\n */\n recordFocus(item: ResolvedItem): void {\n if (canHoldTabStop(item)) this.lastFocused = item.value;\n }\n\n setOptions(options: StoreOptions): void {\n const previous = this.options;\n this.options = options;\n if (\n previous.itemSelector !== options.itemSelector ||\n previous.manageTabIndex !== options.manageTabIndex ||\n previous.roleComposites !== options.roleComposites\n ) {\n this.dirty = true;\n this.notify?.();\n }\n }\n\n /** Own items in navigation order: the explicit `items` order when given, else DOM order. */\n resolve(container: HTMLElement | null = this.container): ResolvedItem[] {\n return orderByItems(this.resolveOwn(container), this.options.items);\n }\n\n /** Own items of the container in DOM order (items of nested composites excluded). */\n resolveOwn(container: HTMLElement | null = this.container): ResolvedItem[] {\n if (!container) return [];\n const { itemSelector, manageTabIndex, roleComposites } = this.options;\n let candidates: HTMLElement[];\n try {\n candidates = Array.from(container.querySelectorAll<HTMLElement>(itemSelector));\n } catch {\n // An invalid selector (warned from an effect in development): this runs during render\n // (getSnapshot), where throwing would take the whole tree down.\n return [];\n }\n\n const result: ResolvedItem[] = [];\n const seen = new Set<Element>();\n const cssHidden = new Map<Element, boolean>();\n for (const candidate of candidates) {\n let composite: HTMLElement | null = null;\n let hidden = false;\n for (\n let node: HTMLElement | null = candidate;\n node && node !== container;\n node = node.parentElement\n ) {\n if (isNestedComposite(node, roleComposites)) composite = node;\n if (node.hidden || node.hasAttribute('inert')) hidden = true;\n }\n if (hidden) continue;\n\n const element = composite ?? candidate;\n if (seen.has(element)) continue;\n const nested = composite !== null;\n if (!nested && manageTabIndex) {\n // An author tabindex=\"-1\" (a SpinButton stepper, SplitButton internals) opts out.\n if (candidate.getAttribute('tabindex') === '-1' && !this.stamped.has(candidate)) continue;\n // A hidden form input (HiddenInput's `type=\"hidden\"`) is never focusable.\n if (isHiddenInput(candidate)) continue;\n }\n seen.add(element);\n\n const item: ResolvedItem = {\n value: this.valueOf(element, nested),\n element,\n nested,\n disabled: isDisabledElement(element),\n };\n if (nested && !item.disabled && !getFocusTarget(item)) item.disabled = true;\n // Consumer children hidden by CSS (a responsive `hidden md:inline-flex` control). Treated as\n // disabled rather than dropped, so it is stamped -1 and is no extra Tab stop once the CSS\n // shows it again (a CSS change triggers no mutation, hence no re-stamp).\n if (manageTabIndex && !item.disabled && isHiddenByCss(element, container, cssHidden)) {\n item.disabled = true;\n }\n result.push(item);\n }\n return result;\n }\n\n /**\n * manageTabIndex: writes tabIndex 0 on the tab stop and -1 on every other own item. An element\n * it stamped that now belongs to a nested composite (a `data-roving-transparent` marker removed)\n * gets its own `tabindex` back, and loses the `data-roving-value` the hook added.\n */\n stamp(): void {\n if (!this.options.manageTabIndex || !this.container) return;\n this.release(this.container);\n const resolved = this.resolve();\n const stop = resolveTabStop(\n resolved.map(toEntry),\n this.options.activeValue,\n this.options.tabStop,\n this.lastFocused,\n );\n for (const item of resolved) {\n if (item.nested) continue;\n const { element } = item;\n let original = this.stamped.get(element);\n if (!original) {\n original = {\n tabIndex: element.getAttribute('tabindex'),\n addedValue: !element.hasAttribute('data-roving-value'),\n };\n this.stamped.set(element, original);\n }\n const tabIndex = item.value === stop ? '0' : '-1';\n if (element.getAttribute('tabindex') !== tabIndex) element.setAttribute('tabindex', tabIndex);\n if (!element.hasAttribute('data-roving-value')) {\n element.setAttribute('data-roving-value', item.value);\n }\n }\n }\n\n /** Hands the elements it stamped that now belong to a nested composite back to their author. */\n private release(container: HTMLElement): void {\n let candidates: HTMLElement[];\n try {\n candidates = Array.from(container.querySelectorAll<HTMLElement>(this.options.itemSelector));\n } catch {\n return;\n }\n for (const candidate of candidates) {\n const original = this.stamped.get(candidate);\n if (!original) continue;\n if (!isInNestedComposite(candidate, container, this.options.roleComposites)) continue;\n this.stamped.delete(candidate);\n if (original.tabIndex === null) candidate.removeAttribute('tabindex');\n else candidate.setAttribute('tabindex', original.tabIndex);\n if (original.addedValue) candidate.removeAttribute('data-roving-value');\n }\n }\n\n private valueOf(element: HTMLElement, nested: boolean): string {\n const own = nested ? null : element.getAttribute('data-roving-value');\n if (own !== null) return own;\n let generated = this.autoValues.get(element);\n if (generated === undefined) {\n this.autoCounter += 1;\n generated = `auto-${this.autoCounter}`;\n this.autoValues.set(element, generated);\n }\n return generated;\n }\n\n private observe(): void {\n if (!this.container || this.observer || typeof MutationObserver === 'undefined') return;\n this.observer = new MutationObserver(() => {\n this.stamp();\n this.dirty = true;\n this.notify?.();\n });\n this.observer.observe(this.container, {\n subtree: true,\n childList: true,\n attributes: true,\n attributeFilter: OBSERVED_ATTRIBUTES,\n });\n this.dirty = true;\n }\n\n private disconnect(): void {\n this.observer?.disconnect();\n this.observer = null;\n }\n}\n\nfunction parseSnapshot(snapshot: string): SnapshotEntry[] | null {\n if (snapshot === '') return null;\n try {\n return JSON.parse(snapshot) as SnapshotEntry[];\n } catch {\n return null;\n }\n}\n\nfunction textOf(element: HTMLElement): string {\n return element.getAttribute('data-roving-text') ?? element.textContent ?? '';\n}\n\n/**\n * Whether an event target is the container or inside its DOM. React bubbles events from a portal\n * (a Menu.Popover or Popover.Content a Toolbar item renders) through the container although their\n * target is elsewhere in the document; those events are not the container's to handle.\n */\nfunction isInContainer(container: Node, target: EventTarget | null): boolean {\n if (!target || typeof (target as Node).nodeType !== 'number') return false;\n return target === container || container.contains(target as Node);\n}\n\n/**\n * The item an event started in: the innermost item element that is the target or one of its\n * ancestors (up to the container). Items can nest (an APG treeitem contains the group of its child\n * treeitems), so the first containing item in DOM order would be the outermost ancestor.\n */\nfunction findOwningItem(\n items: readonly ResolvedItem[],\n target: EventTarget | null,\n container: Node,\n): ResolvedItem | null {\n if (items.length === 0 || !target || typeof (target as Node).nodeType !== 'number') return null;\n const byElement = new Map<Node, ResolvedItem>(items.map((item) => [item.element, item]));\n for (let node: Node | null = target as Node; node && node !== container; node = node.parentNode) {\n const item = byElement.get(node);\n if (item) return item;\n }\n return null;\n}\n\n/**\n * Whether a key started on the item itself (on the container when it started on no item), not on\n * content nested inside the item, such as a row's action button.\n */\nfunction startsOnItem(item: ResolvedItem | null, target: EventTarget | null, container: Node) {\n return item ? target === getFocusTarget(item) : target === container;\n}\n\n/**\n * Implements the WAI-ARIA roving tabindex pattern for composite widgets: one item holds the tab\n * stop (`tabIndex=0`, all others `-1`), arrow keys move focus between items, Home/End jump to the\n * ends, and (optionally) typeahead jumps by text. Used by RadioGroup, Rating, SwatchPicker, List,\n * TabList, Tree, Menu and Toolbar.\n *\n * - **Items** come from the DOM at event time: elements matching `itemSelector` (default\n * `[data-roving-value]`) whose nearest roving container is this one. A nested composite (an\n * element with its own `data-roving-container`, or a radiogroup/listbox/grid/tablist/menu/tree/\n * spinbutton role) counts as one item whose focus target is its own tab stop; the hook never\n * writes tabindex inside it, so it keeps its own Tab stop. An element marked\n * `data-roving-transparent` is never a nested composite by its role: its items are items of this\n * container (the radios of `Toolbar.RadioGroup`); it must not carry a `data-roving-container`.\n * Pass `items` to fix the order instead.\n * In the 0.4 call shape and with explicit `items`, only elements with their own roving container\n * are nested composites: a role-only `radiogroup`/`tablist`/… element between the container and\n * the items (the widget's root inside a wrapper that holds the ref) does not swallow them.\n * - **Disabled items** (`data-roving-disabled`, `disabled`, `aria-disabled=\"true\"`) are skipped and\n * never hold the tab stop. Items marked `data-disabled-focusable` (the `disabledFocusable` prop\n * of WaveUI buttons, links and choice controls) stay reachable and may hold the tab stop: APG\n * allows focusable disabled items. The attribute only overrides `aria-disabled`: an item that is\n * natively disabled or marked `data-roving-disabled` is still skipped. The enabled set is\n * tracked with a MutationObserver, so an item that disables itself moves the tab stop without\n * the owner re-rendering. With `manageTabIndex`, a control hidden by CSS counts as disabled and\n * `input[type=hidden]` is no item.\n * - **Tab stop** (`tabStop`): `'active'` — the enabled `activeValue` item, else the first enabled\n * item; `'last-focused'` — the last focused enabled item, else the `'active'` rule. A nested\n * composite or a control that uses the arrow keys itself holds it only when no other item can.\n * - **Keys** are ignored when another handler already called `preventDefault()`; with Meta; with\n * Alt or Ctrl, except a single character typed with AltGr (Ctrl+Alt on Windows), which is\n * typeahead text (arrows, Home, End and Space with Ctrl+Alt stay ignored); and when they start\n * in a text field, select, contenteditable, slider, spinbutton or editable combobox (Left/Right\n * keep moving the caret; a select-only combobox such as Dropdown's button does not keep them).\n * Left/Right are mirrored in RTL (`dir`, else the direction of the container at key time).\n * Arrows and typeahead move from the item the key started in — the innermost one when items\n * nest, as treeitems do inside their parent's group; when it started on no item (focus on the\n * container itself) next goes to the first enabled item and prev to the last.\n * An item whose `focus()` leaves focus where it was (the browser ignores it on an element CSS\n * hides) is passed over for the next one, and is never recorded or reported to `onFocusMove`.\n * Handled keys call `preventDefault()`. Keys and focus from outside the container's DOM — a\n * popup an item renders through a portal, whose events React bubbles through the container —\n * are ignored, so focus never leaves an open menu or popover for the container's items.\n *\n * @example\n * const { containerProps, getTabIndex } = useRovingTabIndex({ activeValue: value, orientation: 'both' });\n * <div role=\"radiogroup\" {...containerProps}>\n * <button role=\"radio\" data-roving-value=\"a\" tabIndex={getTabIndex('a')} />\n * </div>\n *\n * The 0.4 call shape `useRovingTabIndex(containerRef, options)` still works: pass the container's\n * ref object and attach `handleKeyDown` (and ideally `handleFocus`, and with `typeahead`\n * `handleKeyDownCapture` as `onKeyDownCapture`) yourself.\n *\n * @param options - See {@link UseRovingTabIndexOptions}.\n * @returns See {@link UseRovingTabIndexResult}.\n */\nexport function useRovingTabIndex(options: UseRovingTabIndexOptions): UseRovingTabIndexResult;\nexport function useRovingTabIndex(\n containerRef: React.RefObject<HTMLElement | null>,\n options: UseRovingTabIndexOptions,\n): UseRovingTabIndexResult;\nexport function useRovingTabIndex(\n refOrOptions: React.RefObject<HTMLElement | null> | UseRovingTabIndexOptions,\n maybeOptions?: UseRovingTabIndexOptions,\n): UseRovingTabIndexResult {\n const legacyRef =\n maybeOptions !== undefined ? (refOrOptions as React.RefObject<HTMLElement | null>) : undefined;\n const options = (maybeOptions ?? refOrOptions) as UseRovingTabIndexOptions;\n const {\n activeValue = null,\n items,\n orientation = 'horizontal',\n loop = true,\n dir,\n itemSelector = DEFAULT_ITEM_SELECTOR,\n typeahead = false,\n homeEndKeys = true,\n tabStop = 'active',\n manageTabIndex = false,\n onFocusMove,\n } = options;\n\n const [store] = React.useState(() => new RovingStore());\n const snapshot = React.useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getServerSnapshot,\n );\n const [focusedValue, setFocusedValue] = React.useState<string | null>(null);\n // The last focused item that can hold the tab stop ('last-focused' during render).\n const [focusedStop, setFocusedStop] = React.useState<string | null>(null);\n\n // 0.4 call shape or explicit `items`: only elements with their own roving container are nested\n // composites (a role=radiogroup/tablist/… around the items is the widget's own root).\n const roleComposites = legacyRef === undefined && items === undefined;\n\n React.useLayoutEffect(() => {\n store.setOptions({ itemSelector, manageTabIndex, items, activeValue, tabStop, roleComposites });\n if (legacyRef) store.setContainer(legacyRef.current);\n store.stamp();\n });\n\n // C-DEV: `resolveOwn` treats a selector the browser rejects as \"no items\" (it runs during render,\n // where it must not throw), so the developer hears about it here.\n React.useEffect(() => {\n if (isDev && !isValidSelector(itemSelector)) {\n warnOnce(\n `useRovingTabIndex:itemSelector:${itemSelector}`,\n `useRovingTabIndex: itemSelector \"${itemSelector}\" is not a valid CSS selector in this browser; no item is navigable or tabbable.`,\n );\n }\n }, [itemSelector]);\n\n // Tab stop during render, from the DOM snapshot (null before the container is known).\n const domItems = React.useMemo(() => parseSnapshot(snapshot), [snapshot]);\n const stopEntries = React.useMemo<readonly SnapshotEntry[] | null>(() => {\n if (!items) return domItems;\n // Explicit `items`: the listed values the DOM has, in the listed order. Every listed value\n // before the container is known, or while the DOM has none of them yet (items rendered in the\n // commit the snapshot has not caught up with).\n if (domItems) {\n const ranks = new Map(domItems);\n const present = items.flatMap((value): SnapshotEntry[] => {\n const rank = ranks.get(value);\n return rank === undefined ? [] : [[value, rank]];\n });\n if (present.length > 0) return present;\n }\n return items.map((value): SnapshotEntry => [value, 1]);\n }, [items, domItems]);\n const tabStopValue = stopEntries\n ? resolveTabStop(stopEntries, activeValue, tabStop, focusedStop)\n : activeValue || null;\n\n const getTabIndex = React.useCallback(\n (value: string): 0 | -1 => (value === tabStopValue ? 0 : -1),\n [tabStopValue],\n );\n\n const containerRef = React.useCallback(\n (node: HTMLElement | null) => {\n store.setContainer(node);\n if (legacyRef) setRef(legacyRef, node);\n },\n [store, legacyRef],\n );\n\n const typeaheadItemsRef = React.useRef<TypeaheadItem[]>([]);\n // Every item matching the typed characters, in search order (the first is the match).\n const typeaheadMatchesRef = React.useRef<readonly string[]>([]);\n const { onTypeahead, isSearching } = useTypeahead({\n getItems: () => typeaheadItemsRef.current,\n onMatch: (_value, matches) => {\n typeaheadMatchesRef.current = matches;\n },\n });\n\n /** Focuses an item; `true` only when focus actually moved there (then it is recorded). */\n const focusItem = (item: ResolvedItem | undefined): boolean => {\n if (!item || item.disabled) return false;\n const target = getFocusTarget(item);\n if (!target) return false;\n target.focus();\n // Browsers ignore focus() on an element CSS hides (display: none, visibility: hidden).\n if (!hasFocus(target)) return false;\n store.recordFocus(item);\n return true;\n };\n\n /** Focuses the first item of `candidates` that takes focus. */\n const focusFirstOf = (candidates: readonly ResolvedItem[]): void => {\n for (const item of candidates) {\n if (focusItem(item)) return;\n }\n };\n\n // `spaceOnly` (the capture phase) handles nothing but a Space that continues a typeahead search.\n const handleKeys = useEventCallback((e: React.KeyboardEvent, spaceOnly: boolean) => {\n // Ctrl, Alt and Meta combinations are shortcuts, except a single character typed with AltGr\n // (Ctrl+Alt on Windows), which is typeahead text: arrows, Home, End and Space with it stay\n // shortcuts.\n const shortcut = e.metaKey || ((e.altKey || e.ctrlKey) && !isAltGraphCharacter(e));\n if (e.defaultPrevented || shortcut) return;\n if (ownsArrowKeys(e.target)) return;\n const container = store.container ?? (e.currentTarget as HTMLElement);\n // A key from a portaled popup is the popup's: never pull focus back out of it.\n if (!isInContainer(container, e.target)) return;\n const ordered = store.resolve(container);\n const enabled = ordered.filter((item) => !item.disabled);\n if (enabled.length === 0) return;\n\n // The (innermost) item the key started in. None (the container itself has focus): next → first,\n // prev → last.\n const current = findOwningItem(ordered, e.target, container);\n\n let handled = false;\n // Where focus goes, in order of preference: an item whose focus() does not move focus (hidden\n // by CSS) passes the key on to the next one.\n let targets: ResolvedItem[] = [];\n const intent = spaceOnly\n ? null\n : getArrowIntent(e.key, {\n orientation,\n dir: dir ?? getDirection(e.currentTarget as Element),\n });\n if (intent) {\n handled = true;\n if (!current) {\n targets = intent === 'next' ? enabled : [...enabled].reverse();\n } else {\n const step = intent === 'next' ? 1 : -1;\n const count = ordered.length;\n let index = ordered.indexOf(current);\n for (let i = 1; i < count; i++) {\n index += step;\n if (index < 0 || index >= count) {\n if (!loop) break;\n index = (index + count) % count;\n }\n if (!ordered[index].disabled) targets.push(ordered[index]);\n }\n }\n } else if (!spaceOnly && homeEndKeys && (e.key === 'Home' || e.key === 'End')) {\n handled = true;\n targets = e.key === 'Home' ? enabled : [...enabled].reverse();\n } else if (typeahead && startsOnItem(current, e.target, container)) {\n typeaheadItemsRef.current = ordered.map((item) => ({\n value: item.value,\n text: textOf(item.element),\n disabled: item.disabled,\n }));\n typeaheadMatchesRef.current = [];\n if (onTypeahead(e, current?.value ?? null)) {\n handled = true;\n // The match first, then the next ones, for a match that does not take focus.\n targets = typeaheadMatchesRef.current.flatMap((value) =>\n enabled.filter((item) => item.value === value),\n );\n }\n }\n\n if (!handled) return;\n e.preventDefault();\n for (const next of targets) {\n // Back at the item the key started on (Home on the first item): focus stays.\n if (next === current) return;\n if (focusItem(next)) {\n onFocusMove?.(next.value, e);\n return;\n }\n }\n });\n\n const handleKeyDown = useEventCallback((e: React.KeyboardEvent) => handleKeys(e, false));\n\n // A Space that continues a typeahead search belongs to the search, not to the focused item: it is\n // handled and default-prevented in the capture phase, so the item's own keydown handler, which\n // skips default-prevented events, does not activate the item.\n const handleKeyDownCapture = useEventCallback((e: React.KeyboardEvent) => {\n if (typeahead && e.key === ' ' && isSearching()) handleKeys(e, true);\n });\n\n const handleFocus = useEventCallback((e: React.FocusEvent) => {\n const container = store.container ?? (e.currentTarget as HTMLElement);\n if (!isInContainer(container, e.target)) return;\n const item = findOwningItem(store.resolve(container), e.target, container);\n if (!item) return;\n store.recordFocus(item);\n setFocusedValue(item.value);\n if (canHoldTabStop(item)) setFocusedStop(item.value);\n store.stamp();\n });\n\n const focusValue = useEventCallback((value: string) => {\n focusItem(store.resolve().find((item) => item.value === value));\n });\n const focusFirst = useEventCallback(() => {\n focusFirstOf(store.resolve().filter((item) => !item.disabled));\n });\n const focusLast = useEventCallback(() => {\n focusFirstOf(\n store\n .resolve()\n .filter((item) => !item.disabled)\n .reverse(),\n );\n });\n\n const containerProps = React.useMemo<RovingContainerProps>(\n () => ({\n ref: containerRef,\n 'data-roving-container': '',\n onKeyDown: handleKeyDown,\n onKeyDownCapture: handleKeyDownCapture,\n onFocus: handleFocus,\n }),\n [containerRef, handleKeyDown, handleKeyDownCapture, handleFocus],\n );\n\n return {\n containerProps,\n handleKeyDown,\n handleKeyDownCapture,\n handleFocus,\n getTabIndex,\n focusedValue,\n focusValue,\n focusFirst,\n focusLast,\n };\n}\n"],"mappings":";;;;;;;;;AAkJA,IAAMC,IAAwB,uBAGxBC,oBAAkB,IAAI,IAAI;CAC9B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC,GAOKC,oBAAwB,IAAI,IAAI;CAAC;CAAU;CAAc;CAAW;AAAW,CAAC,GAGhFC,oBAAuB,IAAI,IAAI;CACnC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC,GAEKC,IAAsB;CAC1B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA;CACA;AACF;AAQA,SAASC,EAAkB,GAAa,GAAkC;CACxE,IAAIC,EAAG,aAAa,uBAAuB,GAAG,OAAO;CACrD,IAAI,CAACC,KAAkBD,EAAG,aAAa,yBAAyB,GAAG,OAAO;CAC1E,IAAME,IAAOF,EAAG,aAAa,MAAM;CACnC,OAAOE,MAAS,QAAQP,EAAgB,IAAIO,CAAI;AAClD;AAGA,SAASC,EAAoB,GAAa,GAAoB,GAAkC;CAC9F,KAAK,IAAIC,IAAuBJ,GAAII,KAAQA,MAASC,GAAW,IAAOD,EAAK,eAC1E,IAAIL,EAAkBK,GAAMH,CAAc,GAAG,OAAO;CAEtD,OAAO;AACT;AAcA,SAASK,EAAgB,GAA0B;CACjD,OAAON,EAAG,YAAY,KAAK,CAACA,EAAG,aAAa,UAAU;AACxD;AAGA,SAASO,EAAe,GAAwC;CAC9D,IAAM,EAAE,eAAYC;CACpB,IAAI,CAACA,EAAK,UAAUF,EAAgBG,CAAO,GAAG,OAAOA;CACrD,IAAMC,IAAUD,EAAQ,cAA2B,kBAAgB;CACnE,IAAIC,GAAS,OAAOA;CACpB,IAAMC,IAAWC,EAAiBH,CAAO;CACzC,OAAOE,aAAoB,cAAcA,IAAW;AACtD;AAQA,SAASE,EAAkB,GAA0B;CACnD,IAAMC,IAASd,EAAG,aAAa,sBAAsB;CAIrD,OAHIc,MAAW,QAAQA,MAAW,WAC9BC,EAAmBf,CAAE,IAAU,KACnC,CAAIA,EAAG,aAAa,yBAAyB,KACtCA,EAAG,aAAa,eAAe,MAAM;AAC9C;AAEA,SAASe,EAAmB,GAA0B;CACpD,IAAKf,EAA8B,aAAa,IAAM,OAAO;CAC7D,IAAI;EACF,OAAOA,EAAG,QAAQ,WAAW;CAC/B,QAAQ;EACN,OAAO;CACT;AACF;AAGA,SAASgB,EAAc,GAAqC;CAC1D,IAAI,CAACC,KAAWA,EAAgB,aAAa,GAAG,OAAO;CACvD,IAAMjB,IAAKiB,GACLf,IAAOF,EAAG,aAAa,MAAM;CACnC,IAAIE,MAAS,QAAQN,EAAsB,IAAIM,CAAI,GAAG,OAAO;CAC7D,IAAMgB,IAAMlB,EAAG;CACf,IAAIkB,MAAQ,cAAcA,MAAQ,UAAU,OAAO;CACnD,IAAIA,MAAQ,SAAS,OAAO,CAACrB,EAAqB,IAAKG,EAAwB,IAAI;CACnF,IAAMmB,IAAWnB,EAAG,QAAQ,mBAAmB;CAC/C,OAAOmB,MAAa,QAAQA,EAAS,aAAa,iBAAiB,MAAM;AAC3E;AAQA,SAASC,EAAe,GAA6B;CACnD,OAAO,CAACZ,EAAK,UAAU,CAACQ,EAAcR,EAAK,OAAO;AACpD;AAWA,SAASa,EAAc,GAAa,GAAoB,GAAuC;CAC7F,IAAMC,IAAOtB,EAAG,cAAc;CAC9B,IAAI,CAACsB,GAAM,OAAO;CAClB,KAAK,IAAIlB,IAAuBJ,GAAII,KAAQA,MAASC,GAAW,IAAOD,EAAK,eAAe;EACzF,IAAImB,IAASC,EAAM,IAAIpB,CAAI;EAC3B,IAAImB,MAAW,KAAA,GAAW;GACxB,IAAME,IAASrB,EAAK;GAOpB,AANA,IACEkB,EAAK,iBAAiBlB,CAAI,CAAC,CAAC,YAAY,UACvCqB,MAAW,QACVA,EAAO,cAAc,aACrB,CAACA,EAAO,aAAa,MAAM,KAC3B,MAAM,KAAKA,EAAO,QAAQ,CAAC,CAAC,MAAM,MAAUC,EAAM,cAAc,SAAS,MAAMtB,GACnFoB,EAAM,IAAIpB,GAAMmB,CAAM;EACxB;EACA,IAAIA,GAAQ,OAAO;CACrB;CACA,IAAM,EAAE,kBAAeD,EAAK,iBAAiBtB,CAAE;CAK/C,OAJI2B,MAAe,YAAYA,MAAe,aAAmB,KAI1DL,EAAK,iBAAiBjB,CAAS,CAAC,CAAC,eAAe;AACzD;AAGA,SAASuB,GAAS,GAA0B;CAC1C,IAAMC,IAAU7B,EAAG,YAAY,CAAC,CAA+C;CAC/E,OAAO,CAAC,CAAC6B,KAAU7B,EAAG,SAAS6B,CAAM;AACvC;AAEA,SAASC,GAAgB,GAA2B;CAClD,IAAI;EAEF,OADA,SAAS,uBAAuB,CAAC,CAAC,cAAcC,CAAQ,GACjD;CACT,QAAQ;EACN,OAAO;CACT;AACF;AAWA,SAASC,EAAQ,GAAmC;CAClD,OAAO,CAACxB,EAAK,OAAOA,EAAK,WAAW,IAAIY,EAAeZ,CAAI,IAAI,IAAI,CAAC;AACtE;AAMA,SAASyB,EACP,GACA,GACA,GACA,GACe;CACf,IAAMC,IAAOC,EAAQ,MAAM,GAAGC,OAAOA,MAAM,CAAC,IAAI,IAAI,GAC9CC,IAASF,EAAQ,QAAQ,GAAGC,OAAOA,MAAMF,CAAI,CAAC,CAAC,KAAK,CAACI,OAAWA,CAAK;CAO3E,OANIC,MAAY,kBAAkBC,MAAgB,QAAQH,EAAO,SAASG,CAAW,IAC5EA,IAELC,MAAgB,QAAQA,MAAgB,MAAMJ,EAAO,SAASI,CAAW,IACpEA,IAEFJ,EAAO,MAAM;AACtB;AAEA,SAASK,EACP,GACA,GACgB;CAChB,IAAI,CAACC,GAAO,OAAOC;CACnB,IAAMC,IAAU,IAAI,IAAID,EAAS,KAAK,MAAS,CAACpC,EAAK,OAAOA,CAAI,CAAC,CAAC,GAC5DsC,IAA0B,CAAC;CACjC,KAAK,IAAMR,KAASK,GAAO;EACzB,IAAMnC,IAAOqC,EAAQ,IAAIP,CAAK;EAC9B,AAAI9B,KAAMsC,EAAQ,KAAKtC,CAAI;CAC7B;CACA,OAAOsC;AACT;AAOA,IAAMC,IAAN,MAAkB;CAChB,YAAgC;CAChC,cAA6B;CAC7B,UAAwB;EACtB,cAAcrD;EACd,gBAAgB;EAChB,OAAO,KAAA;EACP,aAAa;EACb,SAAS;EACT,gBAAgB;CAClB;CAEA,0BAA2B,IAAI,QAAkC;CACjE,6BAA8B,IAAI,QAAyB;CAC3D,cAAsB;CACtB,SAAsC;CACtC,WAA4C;CAC5C,QAAgB;CAChB,WAAmB;CAEnB,aAAa,OACX,KAAK,SAASsD,GACd,KAAK,QAAQ,SACA;EAEX,AADA,KAAK,SAAS,MACd,KAAK,WAAW;CAClB;CAGF,oBACO,KAAK,aACN,KAAK,UACP,KAAK,QAAQ,IAEb,KAAK,WAAW,KAAK,UAAU,KAAK,WAAW,CAAC,CAAC,IAAIhB,CAAO,CAAC,IAExD,KAAK,YANgB;CAS9B,0BAAkC;CAElC,aAAa,GAAqC;EAChD,AAAI3B,MAAc,KAAK,cACvB,KAAK,WAAW,GAChB,KAAK,YAAYA,GACjB,KAAK,QAAQ,IACT,KAAK,WACP,KAAK,QAAQ,GACb,KAAK,OAAO;CAEhB;CAMA,YAAY,GAA0B;EACpC,AAAIe,EAAeZ,CAAI,MAAG,KAAK,cAAcA,EAAK;CACpD;CAEA,WAAW,GAA6B;EACtC,IAAMyC,IAAW,KAAK;EAEtB,AADA,KAAK,UAAUC,IAEbD,EAAS,iBAAiBC,EAAQ,gBAClCD,EAAS,mBAAmBC,EAAQ,kBACpCD,EAAS,mBAAmBC,EAAQ,oBAEpC,KAAK,QAAQ,IACb,KAAK,SAAS;CAElB;CAGA,QAAQ,IAAgC,KAAK,WAA2B;EACtE,OAAOR,EAAa,KAAK,WAAWrC,CAAS,GAAG,KAAK,QAAQ,KAAK;CACpE;CAGA,WAAW,IAAgC,KAAK,WAA2B;EACzE,IAAI,CAACA,GAAW,OAAO,CAAC;EACxB,IAAM,EAAE,iBAAc,mBAAgB,sBAAmB,KAAK,SAC1D8C;EACJ,IAAI;GACF,IAAa,MAAM,KAAK9C,EAAU,iBAA8B+C,CAAY,CAAC;EAC/E,QAAQ;GAGN,OAAO,CAAC;EACV;EAEA,IAAMC,IAAyB,CAAC,GAC1BC,oBAAO,IAAI,IAAa,GACxBC,oBAAY,IAAI,IAAsB;EAC5C,KAAK,IAAMC,KAAaL,GAAY;GAClC,IAAIM,IAAgC,MAChClC,IAAS;GACb,KACE,IAAInB,IAA2BoD,GAC/BpD,KAAQA,MAASC,GACjB,IAAOD,EAAK,eAGZ,AADIL,EAAkBK,GAAMH,CAAc,MAAG,IAAYG,KACrDA,EAAK,UAAUA,EAAK,aAAa,OAAO,OAAG,IAAS;GAE1D,IAAImB,GAAQ;GAEZ,IAAMd,IAAUgD,KAAaD;GAC7B,IAAIF,EAAK,IAAI7C,CAAO,GAAG;GACvB,IAAMiD,IAASD,MAAc;GAC7B,IAAI,CAACC,KAAUC,MAETH,EAAU,aAAa,UAAU,MAAM,QAAQ,CAAC,KAAK,QAAQ,IAAIA,CAAS,KAE1EI,EAAcJ,CAAS,IAAG;GAEhC,EAAK,IAAI/C,CAAO;GAEhB,IAAMD,IAAqB;IACzB,OAAO,KAAK,QAAQC,GAASiD,CAAM;IACnC;IACA;IACA,UAAU7C,EAAkBJ,CAAO;GACrC;GAQA,AAPIiD,KAAU,CAAClD,EAAK,YAAY,CAACD,EAAeC,CAAI,MAAG,EAAK,WAAW,KAInEmD,KAAkB,CAACnD,EAAK,YAAYa,EAAcZ,GAASJ,GAAWkD,CAAS,MACjF,EAAK,WAAW,KAElBF,EAAO,KAAK7C,CAAI;EAClB;EACA,OAAO6C;CACT;CAOA,QAAc;EACZ,IAAI,CAAC,KAAK,QAAQ,kBAAkB,CAAC,KAAK,WAAW;EACrD,KAAK,QAAQ,KAAK,SAAS;EAC3B,IAAMT,IAAW,KAAK,QAAQ,GACxBiB,IAAO5B,EACXW,EAAS,IAAIZ,CAAO,GACpB,KAAK,QAAQ,aACb,KAAK,QAAQ,SACb,KAAK,WACP;EACA,KAAK,IAAMxB,KAAQoC,GAAU;GAC3B,IAAIpC,EAAK,QAAQ;GACjB,IAAM,EAAE,eAAYA,GAChBsD,IAAW,KAAK,QAAQ,IAAIrD,CAAO;GACvC,AAAKqD,MACH,IAAW;IACT,UAAUrD,EAAQ,aAAa,UAAU;IACzC,YAAY,CAACA,EAAQ,aAAa,mBAAmB;GACvD,GACA,KAAK,QAAQ,IAAIA,GAASqD,CAAQ;GAEpC,IAAMC,IAAWvD,EAAK,UAAUqD,IAAO,MAAM;GAE7C,AADIpD,EAAQ,aAAa,UAAU,MAAMsD,KAAUtD,EAAQ,aAAa,YAAYsD,CAAQ,GACvFtD,EAAQ,aAAa,mBAAmB,KAC3CA,EAAQ,aAAa,qBAAqBD,EAAK,KAAK;EAExD;CACF;CAGA,QAAgB,GAA8B;EAC5C,IAAI2C;EACJ,IAAI;GACF,IAAa,MAAM,KAAK9C,EAAU,iBAA8B,KAAK,QAAQ,YAAY,CAAC;EAC5F,QAAQ;GACN;EACF;EACA,KAAK,IAAMmD,KAAaL,GAAY;GAClC,IAAMW,IAAW,KAAK,QAAQ,IAAIN,CAAS;GAC3C,AAAKM,KACA3D,EAAoBqD,GAAWnD,GAAW,KAAK,QAAQ,cAAc,MAC1E,KAAK,QAAQ,OAAOmD,CAAS,GACzBM,EAAS,aAAa,OAAMN,EAAU,gBAAgB,UAAU,IAC/DA,EAAU,aAAa,YAAYM,EAAS,QAAQ,GACrDA,EAAS,cAAYN,EAAU,gBAAgB,mBAAmB;EACxE;CACF;CAEA,QAAgB,GAAsB,GAAyB;EAC7D,IAAMQ,IAAMN,IAAS,OAAOjD,EAAQ,aAAa,mBAAmB;EACpE,IAAIuD,MAAQ,MAAM,OAAOA;EACzB,IAAIC,IAAY,KAAK,WAAW,IAAIxD,CAAO;EAM3C,OALIwD,MAAc,KAAA,MAChB,KAAK,eAAe,GACpB,IAAY,QAAQ,KAAK,eACzB,KAAK,WAAW,IAAIxD,GAASwD,CAAS,IAEjCA;CACT;CAEA,UAAwB;EACtB,AAAK,KAAK,aAAa,MAAK,YAAY,OAAO,mBAAqB,QACpE,KAAK,WAAW,IAAI,uBAAuB;GAGzC,AAFA,KAAK,MAAM,GACX,KAAK,QAAQ,IACb,KAAK,SAAS;EAChB,CAAC,GACD,KAAK,SAAS,QAAQ,KAAK,WAAW;GACpC,SAAS;GACT,WAAW;GACX,YAAY;GACZ,iBAAiBnE;EACnB,CAAC,GACD,KAAK,QAAQ;CACf;CAEA,aAA2B;EAEzB,AADA,KAAK,UAAU,WAAW,GAC1B,KAAK,WAAW;CAClB;AACF;AAEA,SAASoE,EAAc,GAA0C;CAC/D,IAAIC,MAAa,IAAI,OAAO;CAC5B,IAAI;EACF,OAAO,KAAK,MAAMA,CAAQ;CAC5B,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAASC,EAAO,GAA8B;CAC5C,OAAO3D,EAAQ,aAAa,kBAAkB,KAAKA,EAAQ,eAAe;AAC5E;AAOA,SAAS4D,EAAc,GAAiB,GAAqC;CAE3E,OADI,CAACpD,KAAU,OAAQA,EAAgB,YAAa,WAAiB,KAC9DA,MAAWZ,KAAaA,EAAU,SAASY,CAAc;AAClE;AAOA,SAASqD,EACP,GACA,GACA,GACqB;CACrB,IAAI3B,EAAM,WAAW,KAAK,CAAC1B,KAAU,OAAQA,EAAgB,YAAa,UAAU,OAAO;CAC3F,IAAMsD,IAAY,IAAI,IAAwB5B,EAAM,KAAK,MAAS,CAACnC,EAAK,SAASA,CAAI,CAAC,CAAC;CACvF,KAAK,IAAIJ,IAAoBa,GAAgBb,KAAQA,MAASC,GAAW,IAAOD,EAAK,YAAY;EAC/F,IAAMI,IAAO+D,EAAU,IAAInE,CAAI;EAC/B,IAAII,GAAM,OAAOA;CACnB;CACA,OAAO;AACT;AAMA,SAASgE,EAAa,GAA2B,GAA4B,GAAiB;CAC5F,OAAOhE,IAAOS,MAAWV,EAAeC,CAAI,IAAIS,MAAWZ;AAC7D;AA+DA,SAAgBoE,EACd,GACA,GACyB;CACzB,IAAMC,IACJC,MAAiB,KAAA,IAAoE,KAAA,IAAvDC,GAE1B,EACJ,iBAAc,MACd,UACA,iBAAc,cACd,UAAO,IACP,QACA,kBAAelF,GACf,eAAY,IACZ,iBAAc,IACd,aAAU,UACV,oBAAiB,IACjB,mBAZeiF,KAAgBC,GAe3B,CAACC,KAASpF,EAAM,eAAe,IAAIsD,EAAY,CAAC,GAChDoB,IAAW1E,EAAM,qBACrBoF,EAAM,WACNA,EAAM,aACNA,EAAM,iBACR,GACM,CAACC,GAAcC,KAAmBtF,EAAM,SAAwB,IAAI,GAEpE,CAACuF,GAAaC,KAAkBxF,EAAM,SAAwB,IAAI,GAIlEQ,IAAiByE,MAAc,KAAA,KAAa/B,MAAU,KAAA;CAU5D,AARAlD,EAAM,sBAAsB;EAG1B,AAFAoF,EAAM,WAAW;GAAE;GAAc;GAAgB;GAAO;GAAa;GAAS;EAAe,CAAC,GAC1FH,KAAWG,EAAM,aAAaH,EAAU,OAAO,GACnDG,EAAM,MAAM;CACd,CAAC,GAIDpF,EAAM,gBAAgB;EACpB,AAAIyF,KAAS,CAACpD,GAAgBsB,CAAY,KACxC+B,EACE,kCAAkC/B,KAClC,oCAAoCA,EAAa,iFACnD;CAEJ,GAAG,CAACA,CAAY,CAAC;CAGjB,IAAMgC,IAAW3F,EAAM,cAAcyE,EAAcC,CAAQ,GAAG,CAACA,CAAQ,CAAC,GAClEkB,IAAc5F,EAAM,cAA+C;EACvE,IAAI,CAACkD,GAAO,OAAOyC;EAInB,IAAIA,GAAU;GACZ,IAAME,IAAQ,IAAI,IAAIF,CAAQ,GACxBG,IAAU5C,EAAM,SAAS,MAA2B;IACxD,IAAMT,IAAOoD,EAAM,IAAIhD,CAAK;IAC5B,OAAOJ,MAAS,KAAA,IAAY,CAAC,IAAI,CAAC,CAACI,GAAOJ,CAAI,CAAC;GACjD,CAAC;GACD,IAAIqD,EAAQ,SAAS,GAAG,OAAOA;EACjC;EACA,OAAO5C,EAAM,KAAK,MAAyB,CAACL,GAAO,CAAC,CAAC;CACvD,GAAG,CAACK,GAAOyC,CAAQ,CAAC,GACdI,IAAeH,IACjBpD,EAAeoD,GAAa5C,GAAaF,GAASyC,CAAW,IAC7DvC,KAAe,MAEbgD,IAAchG,EAAM,aACvB,MAA2B6C,MAAUkD,IAAe,IAAI,IACzD,CAACA,CAAY,CACf,GAEME,IAAejG,EAAM,aACxB,MAA6B;EAE5B,AADAoF,EAAM,aAAazE,CAAI,GACnBsE,KAAWiB,EAAOjB,GAAWtE,CAAI;CACvC,GACA,CAACyE,GAAOH,CAAS,CACnB,GAEMkB,IAAoBnG,EAAM,OAAwB,CAAC,CAAC,GAEpDoG,IAAsBpG,EAAM,OAA0B,CAAC,CAAC,GACxD,EAAE,iBAAa,oBAAgBqG,EAAa;EAChD,gBAAgBF,EAAkB;EAClC,UAAU,GAAQ,MAAY;GAC5B,EAAoB,UAAUG;EAChC;CACF,CAAC,GAGKC,KAAa,MAA4C;EAC7D,IAAI,CAACxF,KAAQA,EAAK,UAAU,OAAO;EACnC,IAAMS,IAASV,EAAeC,CAAI;EAMlC,OALI,CAACS,MACLA,EAAO,MAAM,GAET,CAACW,GAASX,CAAM,KAAU,MAC9B4D,EAAM,YAAYrE,CAAI,GACf;CACT,GAGMyF,KAAgB,MAA8C;EAClE,KAAK,IAAMzF,KAAQ2C,GACjB,IAAI6C,EAAUxF,CAAI,GAAG;CAEzB,GAGM0F,IAAaC,GAAkB,GAAwB,MAAuB;EAIlF,IAAMC,IAAW,EAAE,YAAa,EAAE,UAAU,EAAE,YAAY,CAACC,EAAoB,CAAC;EAEhF,IADI,EAAE,oBAAoBD,KACtBpF,EAAc,EAAE,MAAM,GAAG;EAC7B,IAAMX,IAAYwE,EAAM,aAAc,EAAE;EAExC,IAAI,CAACR,EAAchE,GAAW,EAAE,MAAM,GAAG;EACzC,IAAMyC,IAAU+B,EAAM,QAAQxE,CAAS,GACjCiG,IAAUxD,EAAQ,QAAQ,MAAS,CAACtC,EAAK,QAAQ;EACvD,IAAI8F,EAAQ,WAAW,GAAG;EAI1B,IAAMC,IAAUjC,EAAexB,GAAS,EAAE,QAAQzC,CAAS,GAEvDmG,IAAU,IAGVC,IAA0B,CAAC,GACzBC,IAASC,IACX,OACAC,EAAe,EAAE,KAAK;GACpB;GACA,KAAKC,KAAOC,EAAa,EAAE,aAAwB;EACrD,CAAC;EACL,IAAIJ,GAAQ;GAEV,IADA,IAAU,IACN,CAACH,GACH,IAAUG,MAAW,SAASJ,IAAU,CAAC,GAAGA,CAAO,CAAC,CAAC,QAAQ;QACxD;IACL,IAAMS,IAAOL,MAAW,SAAS,IAAI,IAC/BM,IAAQlE,EAAQ,QAClBmE,IAAQnE,EAAQ,QAAQyD,CAAO;IACnC,KAAK,IAAIW,IAAI,GAAGA,IAAIF,GAAO,KAAK;KAE9B,IADA,KAASD,GACLE,IAAQ,KAAKA,KAASD,GAAO;MAC/B,IAAI,CAACG,GAAM;MACX,KAASF,IAAQD,KAASA;KAC5B;KACA,AAAKlE,EAAQmE,EAAM,CAAC,YAAUR,EAAQ,KAAK3D,EAAQmE,EAAM;IAC3D;GACF;EACF,OAAO,AAAI,CAACN,KAAaS,MAAgB,EAAE,QAAQ,UAAU,EAAE,QAAQ,UACrE,IAAU,IACV,IAAU,EAAE,QAAQ,SAASd,IAAU,CAAC,GAAGA,CAAO,CAAC,CAAC,QAAQ,KACnDe,KAAa7C,EAAa+B,GAAS,EAAE,QAAQlG,CAAS,MAC/D,EAAkB,UAAUyC,EAAQ,KAAK,OAAU;GACjD,OAAOtC,EAAK;GACZ,MAAM4D,EAAO5D,EAAK,OAAO;GACzB,UAAUA,EAAK;EACjB,EAAE,GACF,EAAoB,UAAU,CAAC,GAC3B8G,GAAY,GAAGf,GAAS,SAAS,IAAI,MACvC,IAAU,IAEV,IAAUV,EAAoB,QAAQ,SAAS,MAC7CS,EAAQ,QAAQ,MAAS9F,EAAK,UAAU8B,CAAK,CAC/C;EAIJ,IAAKkE,GACL;KAAE,eAAe;GACjB,KAAK,IAAMe,KAAQd,GAAS;IAE1B,IAAIc,MAAShB,GAAS;IACtB,IAAIP,EAAUuB,CAAI,GAAG;KACnB,IAAcA,EAAK,OAAO,CAAC;KAC3B;IACF;GACF;EARiB;CASnB,CAAC,GAEKC,IAAgBrB,GAAkB,MAA2BD,EAAW,GAAG,EAAK,CAAC,GAKjFuB,IAAuBtB,GAAkB,MAA2B;EACxE,AAAIkB,KAAa,EAAE,QAAQ,OAAOK,GAAY,KAAGxB,EAAW,GAAG,EAAI;CACrE,CAAC,GAEKyB,IAAcxB,GAAkB,MAAwB;EAC5D,IAAM9F,IAAYwE,EAAM,aAAc,EAAE;EACxC,IAAI,CAACR,EAAchE,GAAW,EAAE,MAAM,GAAG;EACzC,IAAMG,IAAO8D,EAAeO,EAAM,QAAQxE,CAAS,GAAG,EAAE,QAAQA,CAAS;EACzE,AAAKG,MACLqE,EAAM,YAAYrE,CAAI,GACtBuE,EAAgBvE,EAAK,KAAK,GACtBY,EAAeZ,CAAI,KAAGyE,EAAezE,EAAK,KAAK,GACnDqE,EAAM,MAAM;CACd,CAAC,GAEK+C,KAAazB,GAAkB,MAAkB;EACrD,EAAUtB,EAAM,QAAQ,CAAC,CAAC,MAAM,MAASrE,EAAK,UAAU8B,CAAK,CAAC;CAChE,CAAC,GACKuF,KAAa1B,QAAuB;EACxC,EAAatB,EAAM,QAAQ,CAAC,CAAC,QAAQ,MAAS,CAACrE,EAAK,QAAQ,CAAC;CAC/D,CAAC,GACKsH,KAAY3B,QAAuB;EACvC,EACEtB,EACG,QAAQ,CAAC,CACT,QAAQ,MAAS,CAACrE,EAAK,QAAQ,CAAC,CAChC,QAAQ,CACb;CACF,CAAC;CAaD,OAAO;EACL,gBAZqBf,EAAM,eACpB;GACL,KAAKiG;GACL,yBAAyB;GACzB,WAAW8B;GACX,kBAAkBC;GAClB,SAASE;EACX,IACA;GAACjC;GAAc8B;GAAeC;GAAsBE;EAAW,CAI/D;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;AACF"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";const e=require("../lib/globalRegistry.cjs");let t=require("react");var n=[`overflow-x`,`overflow-y`];function r(){return e.getGlobalRegistry(`scrollLock`,()=>({count:0,saved:null}))}function i(){let e=globalThis.CSS;if(!e||typeof e.supports!=`function`)return!1;try{return e.supports(`scrollbar-gutter`,`stable`)}catch{return!1}}function a(){let e=document.documentElement.clientWidth;return e?Math.max(0,window.innerWidth-e):0}function o(e){let t=document,r=t.documentElement,o=t.scrollingElement??r,s=t.body,c=a(),l={scroller:o,overflow:o.style.overflow,overflowLonghands:n.map(e=>({name:e,value:o.style.getPropertyValue(e),priority:o.style.getPropertyPriority(e)})),scrollbarGutter:null,bodyPaddingInlineEnd:null};if(c>0){if(i())l.scrollbarGutter=r.style.getPropertyValue(`scrollbar-gutter`),r.style.setProperty(`scrollbar-gutter`,`stable`);else if(s){l.bodyPaddingInlineEnd=s.style.paddingInlineEnd;let e=Number.parseFloat(getComputedStyle(s).paddingInlineEnd)||0;s.style.paddingInlineEnd=`${e+c}px`}}o.style.overflow=`hidden`,e.saved=l}function s(e){let t=e.saved;if(e.saved=null,!t||typeof document>`u`)return;let n=document.documentElement,r=t.scroller.style;r.overflow=t.overflow;for(let{name:e,value:n,priority:i}of t.overflowLonghands??[])n?r.setProperty(e,n,i):r.removeProperty(e);t.scrollbarGutter!==null&&(t.scrollbarGutter?n.style.setProperty(`scrollbar-gutter`,t.scrollbarGutter):n.style.removeProperty(`scrollbar-gutter`)),t.bodyPaddingInlineEnd!==null&&document.body&&(document.body.style.paddingInlineEnd=t.bodyPaddingInlineEnd)}function c(){let e=r();e.count+=1,e.count===1&&o(e);let t=!1;return()=>{t||(t=!0,e.count=Math.max(0,e.count-1),e.count===0&&s(e))}}function l(e){(0,t.useLayoutEffect)(()=>{if(e&&typeof document<`u`)return c()},[e])}exports.useScrollLock=l;
|
|
2
|
+
//# sourceMappingURL=useScrollLock.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useScrollLock.cjs","names":["getGlobalRegistry","require_globalRegistry","react","OVERFLOW_LONGHANDS","getState","supportsScrollbarGutter","css","measureScrollbarWidth","clientWidth","lock","doc","html","scroller","body","scrollbarWidth","saved","name","current","unlock","state","style","value","priority","acquire","released","useScrollLock","enabled"],"sources":["../../src/hooks/useScrollLock.ts"],"sourcesContent":["import { useLayoutEffect } from 'react';\nimport { getGlobalRegistry } from '../lib/globalRegistry';\n\n/** An inline declaration as it was before the lock (`value` is '' when it was not set). */\ninterface SavedDeclaration {\n name: string;\n value: string;\n priority: string;\n}\n\n/**\n * The longhands of `overflow`. A page may set `overflow-y: scroll` inline to keep its scrollbar:\n * the shorthand alone reads '' then, and setting it replaces (restoring '' removes) the longhands.\n */\nconst OVERFLOW_LONGHANDS = ['overflow-x', 'overflow-y'];\n\n// The saved styles live in the global registry: another copy of the library (an older version\n// too) may unlock what this one locked, so fields are only ever added.\ninterface SavedStyles {\n scroller: HTMLElement;\n /** The scroller's inline `overflow` shorthand before the lock. */\n overflow: string;\n /** Its inline `overflow-x`/`overflow-y` before the lock (missing when an older copy locked). */\n overflowLonghands?: SavedDeclaration[];\n /** The inline `scrollbar-gutter` of `<html>` before the lock, or `null` when the lock left it. */\n scrollbarGutter: string | null;\n /** The inline `padding-inline-end` of `<body>` before the lock, or `null` when the lock left it. */\n bodyPaddingInlineEnd: string | null;\n}\n\ninterface ScrollLockState {\n count: number;\n saved: SavedStyles | null;\n}\n\nfunction getState(): ScrollLockState {\n return getGlobalRegistry<ScrollLockState>('scrollLock', () => ({ count: 0, saved: null }));\n}\n\nfunction supportsScrollbarGutter(): boolean {\n const css = (globalThis as { CSS?: { supports?: (property: string, value?: string) => boolean } })\n .CSS;\n if (!css || typeof css.supports !== 'function') return false;\n try {\n return css.supports('scrollbar-gutter', 'stable');\n } catch {\n return false;\n }\n}\n\n/** Width of the classic (layout-taking) viewport scrollbar; 0 for overlay scrollbars or no layout. */\nfunction measureScrollbarWidth(): number {\n const html = document.documentElement;\n const clientWidth = html.clientWidth;\n if (!clientWidth) return 0; // no layout (jsdom, display: none)\n return Math.max(0, window.innerWidth - clientWidth);\n}\n\nfunction lock(state: ScrollLockState): void {\n const doc = document;\n const html = doc.documentElement;\n const scroller = (doc.scrollingElement as HTMLElement | null) ?? html;\n const body = doc.body;\n const scrollbarWidth = measureScrollbarWidth();\n\n // Only what the lock changes is recorded, so unlocking never overwrites styles that something\n // else set on <html>/<body> while the lock was held.\n const saved: SavedStyles = {\n scroller,\n overflow: scroller.style.overflow,\n overflowLonghands: OVERFLOW_LONGHANDS.map((name) => ({\n name,\n value: scroller.style.getPropertyValue(name),\n priority: scroller.style.getPropertyPriority(name),\n })),\n scrollbarGutter: null,\n bodyPaddingInlineEnd: null,\n };\n\n if (scrollbarWidth > 0) {\n if (supportsScrollbarGutter()) {\n saved.scrollbarGutter = html.style.getPropertyValue('scrollbar-gutter');\n html.style.setProperty('scrollbar-gutter', 'stable');\n } else if (body) {\n saved.bodyPaddingInlineEnd = body.style.paddingInlineEnd;\n const current = Number.parseFloat(getComputedStyle(body).paddingInlineEnd) || 0;\n body.style.paddingInlineEnd = `${current + scrollbarWidth}px`;\n }\n }\n scroller.style.overflow = 'hidden';\n state.saved = saved;\n}\n\nfunction unlock(state: ScrollLockState): void {\n const saved = state.saved;\n state.saved = null;\n if (!saved || typeof document === 'undefined') return;\n const html = document.documentElement;\n // Shorthand first: restoring '' removes the longhands, which are then set again where they were.\n const style = saved.scroller.style;\n style.overflow = saved.overflow;\n for (const { name, value, priority } of saved.overflowLonghands ?? []) {\n if (value) style.setProperty(name, value, priority);\n else style.removeProperty(name);\n }\n if (saved.scrollbarGutter !== null) {\n if (saved.scrollbarGutter) html.style.setProperty('scrollbar-gutter', saved.scrollbarGutter);\n else html.style.removeProperty('scrollbar-gutter');\n }\n if (saved.bodyPaddingInlineEnd !== null && document.body) {\n document.body.style.paddingInlineEnd = saved.bodyPaddingInlineEnd;\n }\n}\n\nfunction acquire(): () => void {\n const state = getState();\n state.count += 1;\n if (state.count === 1) lock(state);\n let released = false;\n return () => {\n if (released) return;\n released = true;\n state.count = Math.max(0, state.count - 1);\n if (state.count === 0) unlock(state);\n };\n}\n\n/**\n * Prevents the page behind a modal from scrolling while `enabled` (Dialog, Drawer).\n *\n * Locks are counted in a global registry shared by every copy of the library: the first lock\n * saves the document's inline styles and sets `overflow: hidden` on the document scroller; only\n * the last unlock restores them, so overlays that close out of order (or in the same commit) never\n * leave the page locked or unlocked too early. The scroller's `overflow-x` and `overflow-y` are\n * saved and restored one by one, with their priority (an inline `overflow-y: scroll` that keeps\n * the page's scrollbar survives).\n *\n * The layout stays put when a classic scrollbar disappears: with `scrollbar-gutter: stable` on\n * `<html>` where supported, otherwise by adding the measured scrollbar width to `<body>`'s\n * `padding-inline-end` (the correct side in RTL documents too). Unlocking restores only the\n * styles the lock changed. SSR-safe.\n */\nexport function useScrollLock(enabled: boolean): void {\n useLayoutEffect(() => {\n if (!enabled || typeof document === 'undefined') return;\n return acquire();\n }, [enabled]);\n}\n"],"mappings":"iFAcA,IAAMG,EAAqB,CAAC,aAAc,YAAY,EAqBtD,SAASC,GAA4B,CACnC,OAAOJ,EAAAA,kBAAmC,kBAAqB,CAAE,MAAO,EAAG,MAAO,IAAK,EAAE,CAC3F,CAEA,SAASK,GAAmC,CAC1C,IAAMC,EAAO,WACV,IACH,GAAI,CAACA,GAAO,OAAOA,EAAI,UAAa,WAAY,MAAO,GACvD,GAAI,CACF,OAAOA,EAAI,SAAS,mBAAoB,QAAQ,CAClD,MAAQ,CACN,MAAO,EACT,CACF,CAGA,SAASC,GAAgC,CAEvC,IAAMC,EADO,SAAS,gBACG,YAEzB,OADKA,EACE,KAAK,IAAI,EAAG,OAAO,WAAaA,CAAW,EADzB,CAE3B,CAEA,SAASC,EAAK,EAA8B,CAC1C,IAAMC,EAAM,SACNC,EAAOD,EAAI,gBACXE,EAAYF,EAAI,kBAA2CC,EAC3DE,EAAOH,EAAI,KACXI,EAAiBP,EAAsB,EAIvCQ,EAAqB,CACzB,WACA,SAAUH,EAAS,MAAM,SACzB,kBAAmBT,EAAmB,IAAK,IAAU,CACnD,OACA,MAAOS,EAAS,MAAM,iBAAiBI,CAAI,EAC3C,SAAUJ,EAAS,MAAM,oBAAoBI,CAAI,CACnD,EAAE,EACF,gBAAiB,KACjB,qBAAsB,IACxB,EAEA,GAAIF,EAAiB,EAAG,CACtB,GAAIT,EAAwB,EAC1B,EAAM,gBAAkBM,EAAK,MAAM,iBAAiB,kBAAkB,EACtEA,EAAK,MAAM,YAAY,mBAAoB,QAAQ,OAC9C,GAAIE,EAAM,CACf,EAAM,qBAAuBA,EAAK,MAAM,iBACxC,IAAMI,EAAU,OAAO,WAAW,iBAAiBJ,CAAI,CAAC,CAAC,gBAAgB,GAAK,EAC9E,EAAK,MAAM,iBAAmB,GAAGI,EAAUH,EAAe,GAC5D,CACF,CACA,EAAS,MAAM,SAAW,SAC1B,EAAM,MAAQC,CAChB,CAEA,SAASG,EAAO,EAA8B,CAC5C,IAAMH,EAAQI,EAAM,MAEpB,GADA,EAAM,MAAQ,KACV,CAACJ,GAAS,OAAO,SAAa,IAAa,OAC/C,IAAMJ,EAAO,SAAS,gBAEhBS,EAAQL,EAAM,SAAS,MAC7B,EAAM,SAAWA,EAAM,SACvB,IAAK,GAAM,CAAE,OAAM,QAAO,cAAcA,EAAM,mBAAqB,CAAC,EAC9DM,EAAOD,EAAM,YAAYJ,EAAMK,EAAOC,CAAQ,EAC7CF,EAAM,eAAeJ,CAAI,EAE5BD,EAAM,kBAAoB,OACxBA,EAAM,gBAAiBJ,EAAK,MAAM,YAAY,mBAAoBI,EAAM,eAAe,EACtFJ,EAAK,MAAM,eAAe,kBAAkB,GAE/CI,EAAM,uBAAyB,MAAQ,SAAS,OAClD,SAAS,KAAK,MAAM,iBAAmBA,EAAM,qBAEjD,CAEA,SAASQ,GAAsB,CAC7B,IAAMJ,EAAQf,EAAS,EACvB,EAAM,OAAS,EACXe,EAAM,QAAU,GAAGV,EAAKU,CAAK,EACjC,IAAIK,EAAW,GACf,UAAa,CACPA,IACJ,EAAW,GACX,EAAM,MAAQ,KAAK,IAAI,EAAGL,EAAM,MAAQ,CAAC,EACrCA,EAAM,QAAU,GAAGD,EAAOC,CAAK,EACrC,CACF,CAiBA,SAAgBM,EAAc,EAAwB,EACpD,EAAAvB,EAAA,gBAAA,KAAsB,CACpB,GAAKwB,GAAW,OAAO,SAAa,IACpC,OAAOH,EAAQ,CACjB,EAAG,CAACG,CAAO,CAAC,CACd"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { getGlobalRegistry as e } from "../lib/globalRegistry.mjs";
|
|
3
|
+
import { useLayoutEffect as t } from "react";
|
|
4
|
+
//#region src/hooks/useScrollLock.ts
|
|
5
|
+
var n = ["overflow-x", "overflow-y"];
|
|
6
|
+
function r() {
|
|
7
|
+
return e("scrollLock", () => ({
|
|
8
|
+
count: 0,
|
|
9
|
+
saved: null
|
|
10
|
+
}));
|
|
11
|
+
}
|
|
12
|
+
function i() {
|
|
13
|
+
let e = globalThis.CSS;
|
|
14
|
+
if (!e || typeof e.supports != "function") return !1;
|
|
15
|
+
try {
|
|
16
|
+
return e.supports("scrollbar-gutter", "stable");
|
|
17
|
+
} catch {
|
|
18
|
+
return !1;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function a() {
|
|
22
|
+
let e = document.documentElement.clientWidth;
|
|
23
|
+
return e ? Math.max(0, window.innerWidth - e) : 0;
|
|
24
|
+
}
|
|
25
|
+
function o(e) {
|
|
26
|
+
let t = document, r = t.documentElement, o = t.scrollingElement ?? r, s = t.body, c = a(), l = {
|
|
27
|
+
scroller: o,
|
|
28
|
+
overflow: o.style.overflow,
|
|
29
|
+
overflowLonghands: n.map((e) => ({
|
|
30
|
+
name: e,
|
|
31
|
+
value: o.style.getPropertyValue(e),
|
|
32
|
+
priority: o.style.getPropertyPriority(e)
|
|
33
|
+
})),
|
|
34
|
+
scrollbarGutter: null,
|
|
35
|
+
bodyPaddingInlineEnd: null
|
|
36
|
+
};
|
|
37
|
+
if (c > 0) {
|
|
38
|
+
if (i()) l.scrollbarGutter = r.style.getPropertyValue("scrollbar-gutter"), r.style.setProperty("scrollbar-gutter", "stable");
|
|
39
|
+
else if (s) {
|
|
40
|
+
l.bodyPaddingInlineEnd = s.style.paddingInlineEnd;
|
|
41
|
+
let e = Number.parseFloat(getComputedStyle(s).paddingInlineEnd) || 0;
|
|
42
|
+
s.style.paddingInlineEnd = `${e + c}px`;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
o.style.overflow = "hidden", e.saved = l;
|
|
46
|
+
}
|
|
47
|
+
function s(e) {
|
|
48
|
+
let t = e.saved;
|
|
49
|
+
if (e.saved = null, !t || typeof document > "u") return;
|
|
50
|
+
let n = document.documentElement, r = t.scroller.style;
|
|
51
|
+
r.overflow = t.overflow;
|
|
52
|
+
for (let { name: e, value: n, priority: i } of t.overflowLonghands ?? []) n ? r.setProperty(e, n, i) : r.removeProperty(e);
|
|
53
|
+
t.scrollbarGutter !== null && (t.scrollbarGutter ? n.style.setProperty("scrollbar-gutter", t.scrollbarGutter) : n.style.removeProperty("scrollbar-gutter")), t.bodyPaddingInlineEnd !== null && document.body && (document.body.style.paddingInlineEnd = t.bodyPaddingInlineEnd);
|
|
54
|
+
}
|
|
55
|
+
function c() {
|
|
56
|
+
let e = r();
|
|
57
|
+
e.count += 1, e.count === 1 && o(e);
|
|
58
|
+
let t = !1;
|
|
59
|
+
return () => {
|
|
60
|
+
t || (t = !0, e.count = Math.max(0, e.count - 1), e.count === 0 && s(e));
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function l(e) {
|
|
64
|
+
t(() => {
|
|
65
|
+
if (e && typeof document < "u") return c();
|
|
66
|
+
}, [e]);
|
|
67
|
+
}
|
|
68
|
+
//#endregion
|
|
69
|
+
export { l as useScrollLock };
|
|
70
|
+
|
|
71
|
+
//# sourceMappingURL=useScrollLock.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useScrollLock.mjs","names":["OVERFLOW_LONGHANDS","getState","getGlobalRegistry","supportsScrollbarGutter","css","measureScrollbarWidth","clientWidth","lock","doc","html","scroller","body","scrollbarWidth","saved","name","current","unlock","state","style","value","priority","acquire","released","useScrollLock","enabled"],"sources":["../../src/hooks/useScrollLock.ts"],"sourcesContent":["import { useLayoutEffect } from 'react';\nimport { getGlobalRegistry } from '../lib/globalRegistry';\n\n/** An inline declaration as it was before the lock (`value` is '' when it was not set). */\ninterface SavedDeclaration {\n name: string;\n value: string;\n priority: string;\n}\n\n/**\n * The longhands of `overflow`. A page may set `overflow-y: scroll` inline to keep its scrollbar:\n * the shorthand alone reads '' then, and setting it replaces (restoring '' removes) the longhands.\n */\nconst OVERFLOW_LONGHANDS = ['overflow-x', 'overflow-y'];\n\n// The saved styles live in the global registry: another copy of the library (an older version\n// too) may unlock what this one locked, so fields are only ever added.\ninterface SavedStyles {\n scroller: HTMLElement;\n /** The scroller's inline `overflow` shorthand before the lock. */\n overflow: string;\n /** Its inline `overflow-x`/`overflow-y` before the lock (missing when an older copy locked). */\n overflowLonghands?: SavedDeclaration[];\n /** The inline `scrollbar-gutter` of `<html>` before the lock, or `null` when the lock left it. */\n scrollbarGutter: string | null;\n /** The inline `padding-inline-end` of `<body>` before the lock, or `null` when the lock left it. */\n bodyPaddingInlineEnd: string | null;\n}\n\ninterface ScrollLockState {\n count: number;\n saved: SavedStyles | null;\n}\n\nfunction getState(): ScrollLockState {\n return getGlobalRegistry<ScrollLockState>('scrollLock', () => ({ count: 0, saved: null }));\n}\n\nfunction supportsScrollbarGutter(): boolean {\n const css = (globalThis as { CSS?: { supports?: (property: string, value?: string) => boolean } })\n .CSS;\n if (!css || typeof css.supports !== 'function') return false;\n try {\n return css.supports('scrollbar-gutter', 'stable');\n } catch {\n return false;\n }\n}\n\n/** Width of the classic (layout-taking) viewport scrollbar; 0 for overlay scrollbars or no layout. */\nfunction measureScrollbarWidth(): number {\n const html = document.documentElement;\n const clientWidth = html.clientWidth;\n if (!clientWidth) return 0; // no layout (jsdom, display: none)\n return Math.max(0, window.innerWidth - clientWidth);\n}\n\nfunction lock(state: ScrollLockState): void {\n const doc = document;\n const html = doc.documentElement;\n const scroller = (doc.scrollingElement as HTMLElement | null) ?? html;\n const body = doc.body;\n const scrollbarWidth = measureScrollbarWidth();\n\n // Only what the lock changes is recorded, so unlocking never overwrites styles that something\n // else set on <html>/<body> while the lock was held.\n const saved: SavedStyles = {\n scroller,\n overflow: scroller.style.overflow,\n overflowLonghands: OVERFLOW_LONGHANDS.map((name) => ({\n name,\n value: scroller.style.getPropertyValue(name),\n priority: scroller.style.getPropertyPriority(name),\n })),\n scrollbarGutter: null,\n bodyPaddingInlineEnd: null,\n };\n\n if (scrollbarWidth > 0) {\n if (supportsScrollbarGutter()) {\n saved.scrollbarGutter = html.style.getPropertyValue('scrollbar-gutter');\n html.style.setProperty('scrollbar-gutter', 'stable');\n } else if (body) {\n saved.bodyPaddingInlineEnd = body.style.paddingInlineEnd;\n const current = Number.parseFloat(getComputedStyle(body).paddingInlineEnd) || 0;\n body.style.paddingInlineEnd = `${current + scrollbarWidth}px`;\n }\n }\n scroller.style.overflow = 'hidden';\n state.saved = saved;\n}\n\nfunction unlock(state: ScrollLockState): void {\n const saved = state.saved;\n state.saved = null;\n if (!saved || typeof document === 'undefined') return;\n const html = document.documentElement;\n // Shorthand first: restoring '' removes the longhands, which are then set again where they were.\n const style = saved.scroller.style;\n style.overflow = saved.overflow;\n for (const { name, value, priority } of saved.overflowLonghands ?? []) {\n if (value) style.setProperty(name, value, priority);\n else style.removeProperty(name);\n }\n if (saved.scrollbarGutter !== null) {\n if (saved.scrollbarGutter) html.style.setProperty('scrollbar-gutter', saved.scrollbarGutter);\n else html.style.removeProperty('scrollbar-gutter');\n }\n if (saved.bodyPaddingInlineEnd !== null && document.body) {\n document.body.style.paddingInlineEnd = saved.bodyPaddingInlineEnd;\n }\n}\n\nfunction acquire(): () => void {\n const state = getState();\n state.count += 1;\n if (state.count === 1) lock(state);\n let released = false;\n return () => {\n if (released) return;\n released = true;\n state.count = Math.max(0, state.count - 1);\n if (state.count === 0) unlock(state);\n };\n}\n\n/**\n * Prevents the page behind a modal from scrolling while `enabled` (Dialog, Drawer).\n *\n * Locks are counted in a global registry shared by every copy of the library: the first lock\n * saves the document's inline styles and sets `overflow: hidden` on the document scroller; only\n * the last unlock restores them, so overlays that close out of order (or in the same commit) never\n * leave the page locked or unlocked too early. The scroller's `overflow-x` and `overflow-y` are\n * saved and restored one by one, with their priority (an inline `overflow-y: scroll` that keeps\n * the page's scrollbar survives).\n *\n * The layout stays put when a classic scrollbar disappears: with `scrollbar-gutter: stable` on\n * `<html>` where supported, otherwise by adding the measured scrollbar width to `<body>`'s\n * `padding-inline-end` (the correct side in RTL documents too). Unlocking restores only the\n * styles the lock changed. SSR-safe.\n */\nexport function useScrollLock(enabled: boolean): void {\n useLayoutEffect(() => {\n if (!enabled || typeof document === 'undefined') return;\n return acquire();\n }, [enabled]);\n}\n"],"mappings":";;;;AAcA,IAAMA,IAAqB,CAAC,cAAc,YAAY;AAqBtD,SAASC,IAA4B;CACnC,OAAOC,EAAmC,qBAAqB;EAAE,OAAO;EAAG,OAAO;CAAK,EAAE;AAC3F;AAEA,SAASC,IAAmC;CAC1C,IAAMC,IAAO,WACV;CACH,IAAI,CAACA,KAAO,OAAOA,EAAI,YAAa,YAAY,OAAO;CACvD,IAAI;EACF,OAAOA,EAAI,SAAS,oBAAoB,QAAQ;CAClD,QAAQ;EACN,OAAO;CACT;AACF;AAGA,SAASC,IAAgC;CAEvC,IAAMC,IADO,SAAS,gBACG;CAEzB,OADKA,IACE,KAAK,IAAI,GAAG,OAAO,aAAaA,CAAW,IADzB;AAE3B;AAEA,SAASC,EAAK,GAA8B;CAC1C,IAAMC,IAAM,UACNC,IAAOD,EAAI,iBACXE,IAAYF,EAAI,oBAA2CC,GAC3DE,IAAOH,EAAI,MACXI,IAAiBP,EAAsB,GAIvCQ,IAAqB;EACzB;EACA,UAAUH,EAAS,MAAM;EACzB,mBAAmBV,EAAmB,KAAK,OAAU;GACnD;GACA,OAAOU,EAAS,MAAM,iBAAiBI,CAAI;GAC3C,UAAUJ,EAAS,MAAM,oBAAoBI,CAAI;EACnD,EAAE;EACF,iBAAiB;EACjB,sBAAsB;CACxB;CAEA,IAAIF,IAAiB,GAAG;EACtB,IAAIT,EAAwB,GAE1B,AADA,EAAM,kBAAkBM,EAAK,MAAM,iBAAiB,kBAAkB,GACtEA,EAAK,MAAM,YAAY,oBAAoB,QAAQ;OAC9C,IAAIE,GAAM;GACf,EAAM,uBAAuBA,EAAK,MAAM;GACxC,IAAMI,IAAU,OAAO,WAAW,iBAAiBJ,CAAI,CAAC,CAAC,gBAAgB,KAAK;GAC9E,EAAK,MAAM,mBAAmB,GAAGI,IAAUH,EAAe;EAC5D;CACF;CAEA,AADA,EAAS,MAAM,WAAW,UAC1B,EAAM,QAAQC;AAChB;AAEA,SAASG,EAAO,GAA8B;CAC5C,IAAMH,IAAQI,EAAM;CAEpB,IADA,EAAM,QAAQ,MACV,CAACJ,KAAS,OAAO,WAAa,KAAa;CAC/C,IAAMJ,IAAO,SAAS,iBAEhBS,IAAQL,EAAM,SAAS;CAC7B,EAAM,WAAWA,EAAM;CACvB,KAAK,IAAM,EAAE,SAAM,UAAO,iBAAcA,EAAM,qBAAqB,CAAC,GAClE,AAAIM,IAAOD,EAAM,YAAYJ,GAAMK,GAAOC,CAAQ,IAC7CF,EAAM,eAAeJ,CAAI;CAMhC,AAJID,EAAM,oBAAoB,SACxBA,EAAM,kBAAiBJ,EAAK,MAAM,YAAY,oBAAoBI,EAAM,eAAe,IACtFJ,EAAK,MAAM,eAAe,kBAAkB,IAE/CI,EAAM,yBAAyB,QAAQ,SAAS,SAClD,SAAS,KAAK,MAAM,mBAAmBA,EAAM;AAEjD;AAEA,SAASQ,IAAsB;CAC7B,IAAMJ,IAAQhB,EAAS;CAEvB,AADA,EAAM,SAAS,GACXgB,EAAM,UAAU,KAAGV,EAAKU,CAAK;CACjC,IAAIK,IAAW;CACf,aAAa;EACX,AAAIA,MACJ,IAAW,IACX,EAAM,QAAQ,KAAK,IAAI,GAAGL,EAAM,QAAQ,CAAC,GACrCA,EAAM,UAAU,KAAGD,EAAOC,CAAK;CACrC;AACF;AAiBA,SAAgBM,EAAc,GAAwB;CACpD,QAAsB;EACpB,IAAKC,KAAW,OAAO,WAAa,KACpC,OAAOH,EAAQ;CACjB,GAAG,CAACG,CAAO,CAAC;AACd"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";const e=require("../_virtual/_rolldown/runtime.cjs"),t=require("../lib/dev.cjs"),n=require("./useEventCallback.cjs"),r=require("../lib/focus.cjs"),i=require("./useMergedRefs.cjs"),a=require("../lib/mergeProps.cjs"),o=require("../lib/renderTrigger.cjs");let s=require("react");s=e.__toESM(s,1);var c=new Set([`generic`,`none`,`presentation`]);function l(e){if(typeof e!=`string`)return!1;let t=e.trim().split(/\s+/)[0];return t!==``&&!c.has(t)}function u(e){return typeof e==`number`?e>=0:typeof e==`string`&&e.trim()!==``&&Number(e)>=0}var d=`a[href], button, input, select, summary, textarea`;function f(e){let t=e.getAttribute(`role`);return t!==null&&t.trim()!==``?l(t):e.matches(d)}function p(e){let t=f(e);if(t&&e.tabIndex>=0)return e;for(let t of e.querySelectorAll(r.FOCUSABLE_SELECTOR))if(!r.isHiddenInput(t)&&t.tabIndex>=0)return t;return t?e:null}function m(e){if(!e)return null;let t=p(e);return t&&r.isFocusable(t)?t:r.getFirstTabbable(e)??(r.isFocusable(e)?e:null)}function h(e){return s.useMemo(()=>g(e),[e])}function g(e){return{get current(){let t=e.current;return t&&(m(t)??t)}}}function _(e){return typeof e==`object`&&!!e&&e.nodeType===1}function v(e){let t={...e};for(let e of o.STATE_ARIA)delete t[e];return t}function y(e){let t={};for(let n of o.STATE_ARIA)n in e&&(t[n]=e[n]);return t}function b(e,t){let n=Object.keys(t).map(t=>[t,e.getAttribute(t)]);for(let[n,r]of Object.entries(t))r==null?e.removeAttribute(n):e.setAttribute(n,String(r));return()=>{for(let[t,r]of n)r===null?e.removeAttribute(t):e.setAttribute(t,r)}}function x(e,r,c){let{componentName:d,asChild:f=!0,onResolvedId:m,omitStateAria:h=!1}=c,[g,x]=s.useState(!1),S=typeof e==`function`,C=S?null:o.unwrapFragment(e),w=o.isCloneableElement(C),T=f&&!g&&w,E=T?C:null,D=r,O=D.ref,k=h?v(D):D,A=E?E.props.ref:void 0,j=s.useRef(null),M=s.useCallback(e=>{j.current=_(e)?e:null},[]),N=i.useMergedRefs(O,A,M);s.useLayoutEffect(()=>{T&&!j.current&&(t.warnOnce(`trigger-ref:${d}`,`${d}: its child did not attach the trigger ref (a component that neither forwards \`ref\` nor spreads its props). It is rendered inside a <span> wrapper instead; forward \`ref\` and spread props onto the element, or pass asChild={false}.`),x(!0))},[T,d]);let P=f&&g&&w,F=!S&&!T,I=F&&l(k.role)&&u(k.tabIndex),L=F&&!I&&!h?y(k):null;s.useLayoutEffect(()=>{let e=j.current;if(!L||!e)return;let t=p(e);return t?b(t,L):void 0}),s.useLayoutEffect(()=>{let e=j.current;if(!h||!S||!e)return;let n=o.STATE_ARIA.filter(t=>e.hasAttribute(t));if(n.length!==0){for(let t of n)e.removeAttribute(t);t.warnOnce(`${d}:context-state-aria`,`${d}: the trigger element is a context-menu region (openOnContext), which is not a menu button: do not spread aria-haspopup, aria-expanded and aria-controls onto it.`)}});let R=typeof k.id==`string`?k.id:void 0,z=(E&&typeof E.props.id==`string`?E.props.id:void 0)??R,B=n.useEventCallback(m);if(s.useEffect(()=>{z&&B(z)},[z,B]),E){let{ref:e,...t}=E.props,{ref:n,...r}=k,i=a.mergeProps(r,t,{oursWin:o.STATE_ARIA});return s.cloneElement(E,{...i,ref:N})}if(F){let{ref:t,...n}=k,r={...n,ref:N};if(!I||h)for(let e of o.STATE_ARIA)delete r[e];return f?o.renderTrigger(C,r,{componentName:d,asChild:!P}):o.renderTrigger(e,r,{componentName:d,asChild:!1})}let V=h?{...D,ref:N}:r;return o.renderTrigger(e,V,{componentName:d,asChild:!1})}exports.getTriggerFocusTarget=m,exports.getTriggerTarget=p,exports.useTriggerElement=x,exports.useTriggerFocusRef=h;
|
|
2
|
+
//# sourceMappingURL=useTriggerElement.cjs.map
|