@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,492 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { getElementType as e } from "../lib/children.mjs";
|
|
3
|
+
import { isDev as t, reportMissingContext as n, warnOnce as r } from "../lib/dev.mjs";
|
|
4
|
+
import { useEventCallback as i } from "./useEventCallback.mjs";
|
|
5
|
+
import { useId as a } from "./useId.mjs";
|
|
6
|
+
import { isAltGraphCharacter as o, useTypeahead as s } from "./useTypeahead.mjs";
|
|
7
|
+
import { useMergedRefs as c } from "./useMergedRefs.mjs";
|
|
8
|
+
import * as l from "react";
|
|
9
|
+
import { useCallback as u, useContext as d, useEffect as f, useLayoutEffect as p, useMemo as m, useRef as h, useState as g, useSyncExternalStore as ee } from "react";
|
|
10
|
+
//#region src/hooks/useListbox.ts
|
|
11
|
+
var _ = [], v = /* @__PURE__ */ new Set();
|
|
12
|
+
function y() {
|
|
13
|
+
return _;
|
|
14
|
+
}
|
|
15
|
+
function b(e, t) {
|
|
16
|
+
if (e === t) return !0;
|
|
17
|
+
if (e.size !== t.size) return !1;
|
|
18
|
+
for (let n of e) if (!t.has(n)) return !1;
|
|
19
|
+
return !0;
|
|
20
|
+
}
|
|
21
|
+
function x(e, t) {
|
|
22
|
+
return e.value === t.value && e.label === t.label && e.textValue === t.textValue && !!e.disabled == !!t.disabled && !!e.hidden == !!t.hidden;
|
|
23
|
+
}
|
|
24
|
+
function S(e, t) {
|
|
25
|
+
return e === t || e.length === t.length && e.every((e, n) => x(e, t[n]));
|
|
26
|
+
}
|
|
27
|
+
function C(e, t) {
|
|
28
|
+
return e === t || e.length === t.length && e.every((e, n) => e.value === t[n].value);
|
|
29
|
+
}
|
|
30
|
+
function w(e, t) {
|
|
31
|
+
let n = e.element.current, r = t.element.current;
|
|
32
|
+
if (n && r && n !== r && n.isConnected && r.isConnected) {
|
|
33
|
+
let e = n.compareDocumentPosition(r);
|
|
34
|
+
if (e & Node.DOCUMENT_POSITION_FOLLOWING) return -1;
|
|
35
|
+
if (e & Node.DOCUMENT_POSITION_PRECEDING) return 1;
|
|
36
|
+
}
|
|
37
|
+
return e.seq - t.seq;
|
|
38
|
+
}
|
|
39
|
+
var T = class {
|
|
40
|
+
indexByValue = /* @__PURE__ */ new Map();
|
|
41
|
+
registrations = /* @__PURE__ */ new Set();
|
|
42
|
+
stateListeners = /* @__PURE__ */ new Set();
|
|
43
|
+
itemListeners = /* @__PURE__ */ new Set();
|
|
44
|
+
nextIndex = 0;
|
|
45
|
+
nextSeq = 0;
|
|
46
|
+
dirty = !1;
|
|
47
|
+
flushScheduled = !1;
|
|
48
|
+
itemsStale = !1;
|
|
49
|
+
itemsSnapshot = _;
|
|
50
|
+
sorted = [];
|
|
51
|
+
observer = null;
|
|
52
|
+
observed = null;
|
|
53
|
+
watching = !1;
|
|
54
|
+
connected = !1;
|
|
55
|
+
registrationMode = !0;
|
|
56
|
+
active = null;
|
|
57
|
+
selected;
|
|
58
|
+
hidden = v;
|
|
59
|
+
constructor(e) {
|
|
60
|
+
this.selected = new Set(e);
|
|
61
|
+
}
|
|
62
|
+
subscribe = (e) => (this.stateListeners.add(e), () => {
|
|
63
|
+
this.stateListeners.delete(e);
|
|
64
|
+
});
|
|
65
|
+
subscribeItems = (e) => (this.itemListeners.add(e), () => {
|
|
66
|
+
this.itemListeners.delete(e);
|
|
67
|
+
});
|
|
68
|
+
isActive = (e) => this.active === e;
|
|
69
|
+
isSelected = (e) => this.selected.has(e);
|
|
70
|
+
isHidden = (e) => this.hidden.has(e);
|
|
71
|
+
getIndex = (e) => {
|
|
72
|
+
let t = this.indexByValue.get(e);
|
|
73
|
+
return t === void 0 && (t = this.nextIndex++, this.indexByValue.set(e, t)), t;
|
|
74
|
+
};
|
|
75
|
+
register = (e, t) => {
|
|
76
|
+
let n = {
|
|
77
|
+
item: e,
|
|
78
|
+
element: t,
|
|
79
|
+
seq: this.nextSeq++
|
|
80
|
+
};
|
|
81
|
+
return this.registrations.add(n), this.markDirty(), () => {
|
|
82
|
+
this.registrations.delete(n), this.markDirty();
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
getItems = () => {
|
|
86
|
+
if (this.itemsStale) {
|
|
87
|
+
this.itemsStale = !1;
|
|
88
|
+
let e = Array.from(this.registrations).sort(w);
|
|
89
|
+
this.sorted = e;
|
|
90
|
+
let t = /* @__PURE__ */ new Set(), n = [];
|
|
91
|
+
for (let { item: r } of e) t.has(r.value) || (t.add(r.value), n.push(r));
|
|
92
|
+
S(n, this.itemsSnapshot) || (this.itemsSnapshot = n);
|
|
93
|
+
}
|
|
94
|
+
return this.itemsSnapshot;
|
|
95
|
+
};
|
|
96
|
+
getElement(e) {
|
|
97
|
+
for (let { item: t, element: n } of this.registrations) {
|
|
98
|
+
let r = n.current;
|
|
99
|
+
if (t.value === e && r && r.isConnected) return r;
|
|
100
|
+
}
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
setRegistrationMode(e) {
|
|
104
|
+
e !== this.registrationMode && (this.registrationMode = e, this.syncObserver());
|
|
105
|
+
}
|
|
106
|
+
connect() {
|
|
107
|
+
this.connected = !0, this.syncObserver();
|
|
108
|
+
}
|
|
109
|
+
disconnect() {
|
|
110
|
+
this.connected = !1, this.syncObserver();
|
|
111
|
+
}
|
|
112
|
+
flush() {
|
|
113
|
+
this.dirty && (this.dirty = !1, this.itemsStale = !0, this.registrationMode && this.warnDuplicates(), this.syncObserver(), this.notifyItems());
|
|
114
|
+
}
|
|
115
|
+
checkOrder() {
|
|
116
|
+
if (!this.registrationMode || this.dirty || this.itemsStale) return;
|
|
117
|
+
let e = this.sorted;
|
|
118
|
+
for (let t = 1; t < e.length; t++) {
|
|
119
|
+
let n = e[t - 1].element.current, r = e[t].element.current;
|
|
120
|
+
if (n && r && n !== r && n.isConnected && r.isConnected && n.compareDocumentPosition(r) & Node.DOCUMENT_POSITION_PRECEDING) {
|
|
121
|
+
this.itemsStale = !0, this.notifyItems();
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
checkOrderAfterCommit() {
|
|
127
|
+
let e = this.observer !== null && this.observer.takeRecords().length > 0, t = this.watching;
|
|
128
|
+
this.watching = this.observed !== null, (!t || e) && this.checkOrder();
|
|
129
|
+
}
|
|
130
|
+
setRenderState(e, t, n) {
|
|
131
|
+
let r = !1;
|
|
132
|
+
if (e !== this.active && (this.active = e, r = !0), b(t, this.selected) || (this.selected = t, r = !0), b(n, this.hidden) || (this.hidden = n, r = !0), r) for (let e of Array.from(this.stateListeners)) e();
|
|
133
|
+
}
|
|
134
|
+
notifyItems() {
|
|
135
|
+
for (let e of Array.from(this.itemListeners)) e();
|
|
136
|
+
}
|
|
137
|
+
onMutation = () => {
|
|
138
|
+
this.checkOrder();
|
|
139
|
+
};
|
|
140
|
+
syncObserver() {
|
|
141
|
+
let e = this.connected && this.registrationMode && typeof MutationObserver < "u" ? this.commonAncestor() : null;
|
|
142
|
+
e !== this.observed && (this.observer?.disconnect(), this.observed = e, this.watching = !1, e && (t && D(e), this.observer ??= new MutationObserver(this.onMutation), this.observer.observe(e, {
|
|
143
|
+
childList: !0,
|
|
144
|
+
subtree: !0
|
|
145
|
+
})));
|
|
146
|
+
}
|
|
147
|
+
commonAncestor() {
|
|
148
|
+
let e = null, t = 0;
|
|
149
|
+
for (let { element: n } of this.registrations) {
|
|
150
|
+
let r = n.current;
|
|
151
|
+
if (r && r.isConnected) {
|
|
152
|
+
if (t++, e === null) {
|
|
153
|
+
e = r.parentNode;
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
for (; e && !e.contains(r);) e = e.parentNode;
|
|
157
|
+
if (!e) return null;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return t > 1 ? e : null;
|
|
161
|
+
}
|
|
162
|
+
markDirty() {
|
|
163
|
+
this.dirty = !0, !this.flushScheduled && (this.flushScheduled = !0, queueMicrotask(() => {
|
|
164
|
+
this.flushScheduled = !1, this.flush();
|
|
165
|
+
}));
|
|
166
|
+
}
|
|
167
|
+
warnDuplicates() {
|
|
168
|
+
let e = /* @__PURE__ */ new Set();
|
|
169
|
+
for (let { item: t } of this.registrations) e.has(t.value) && E(t.value), e.add(t.value);
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
function E(e) {
|
|
173
|
+
r(`useListbox:duplicate:${e}`, `Listbox: several options share the value "${e}". Option values must be unique within a listbox; only the first one can be highlighted and selected.`);
|
|
174
|
+
}
|
|
175
|
+
function D(e) {
|
|
176
|
+
let t = e.ownerDocument;
|
|
177
|
+
!t || e !== t.body && e !== t.documentElement || r("useListbox:single-container", "Listbox: the options of one listbox are rendered in more than one container (for example an inline list kept mounted next to a portaled one). All options must live in a single container at a time: render the list inline only while closed and in the portal only while open.");
|
|
178
|
+
}
|
|
179
|
+
var O = l.createContext(null);
|
|
180
|
+
O.displayName = "ListboxContext";
|
|
181
|
+
var k = null;
|
|
182
|
+
function A() {
|
|
183
|
+
return k ??= {
|
|
184
|
+
listboxId: "wave-listbox-inert",
|
|
185
|
+
store: new T([]),
|
|
186
|
+
select: () => {},
|
|
187
|
+
highlight: () => {}
|
|
188
|
+
}, k;
|
|
189
|
+
}
|
|
190
|
+
function j(e) {
|
|
191
|
+
return d(O) || (n(e, "a listbox (Combobox or Dropdown)"), A());
|
|
192
|
+
}
|
|
193
|
+
var M = Symbol.for("@mortenbrudvik/waveui/listbox-element-kind");
|
|
194
|
+
function N(e, t) {
|
|
195
|
+
return Object.defineProperty(e, M, {
|
|
196
|
+
value: t,
|
|
197
|
+
configurable: !0
|
|
198
|
+
}), e;
|
|
199
|
+
}
|
|
200
|
+
function P(e) {
|
|
201
|
+
if (typeof e != "function" && typeof e != "object" || e === null) return;
|
|
202
|
+
let t = e[M];
|
|
203
|
+
return t === "option" || t === "group" ? t : void 0;
|
|
204
|
+
}
|
|
205
|
+
function F(e) {
|
|
206
|
+
if (typeof e == "string") return e;
|
|
207
|
+
if (typeof e == "number" || typeof e == "bigint") return String(e);
|
|
208
|
+
if (e == null || typeof e == "boolean") return "";
|
|
209
|
+
if (l.isValidElement(e)) return typeof e.type == "string" || e.type === l.Fragment ? F(e.props.children) : "";
|
|
210
|
+
if (typeof e == "object" && Symbol.iterator in e) {
|
|
211
|
+
let t = "";
|
|
212
|
+
for (let n of e) t += F(n);
|
|
213
|
+
return t;
|
|
214
|
+
}
|
|
215
|
+
return "";
|
|
216
|
+
}
|
|
217
|
+
function I(e, t) {
|
|
218
|
+
return typeof e.label == "string" ? e.label : typeof e.textValue == "string" ? e.textValue : e.children === null || e.children === void 0 ? t : F(e.children).trim() || void 0;
|
|
219
|
+
}
|
|
220
|
+
function L(t, n) {
|
|
221
|
+
l.Children.forEach(t, (t) => {
|
|
222
|
+
if (!l.isValidElement(t)) return;
|
|
223
|
+
let r = e(t);
|
|
224
|
+
if (r === l.Fragment) {
|
|
225
|
+
L(t.props.children, n);
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
let i = P(r);
|
|
229
|
+
if (i === "group") {
|
|
230
|
+
L(t.props.children, n);
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
if (i !== "option") return;
|
|
234
|
+
let { value: a } = t.props;
|
|
235
|
+
if (typeof a != "string" || n.has(a)) return;
|
|
236
|
+
let o = I(t.props, a);
|
|
237
|
+
o !== void 0 && n.set(a, o);
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
function R(e) {
|
|
241
|
+
let t = /* @__PURE__ */ new Map();
|
|
242
|
+
return L(e, t), t;
|
|
243
|
+
}
|
|
244
|
+
function te(e, t, n, r) {
|
|
245
|
+
let i = e.length;
|
|
246
|
+
if (i === 0) return null;
|
|
247
|
+
let a = t === null ? -1 : e.indexOf(t);
|
|
248
|
+
if (a === -1) return n > 0 ? e[0] : e[i - 1];
|
|
249
|
+
let o = a + n;
|
|
250
|
+
return (o < 0 || o >= i) && (o = r && Math.abs(n) === 1 ? (o + i) % i : Math.max(0, Math.min(i - 1, o))), e[o];
|
|
251
|
+
}
|
|
252
|
+
function ne(e) {
|
|
253
|
+
return (e instanceof HTMLInputElement || e instanceof HTMLTextAreaElement) && e.value !== "";
|
|
254
|
+
}
|
|
255
|
+
var z = /* @__PURE__ */ new Set([
|
|
256
|
+
"x",
|
|
257
|
+
"v",
|
|
258
|
+
"z",
|
|
259
|
+
"y"
|
|
260
|
+
]);
|
|
261
|
+
function re(e) {
|
|
262
|
+
let t = e.currentTarget;
|
|
263
|
+
if ((t instanceof HTMLInputElement || t instanceof HTMLTextAreaElement) && (t.readOnly || t.disabled)) return !1;
|
|
264
|
+
let { key: n } = e;
|
|
265
|
+
return n === "Backspace" || n === "Delete" || n === "Process" || n === "Unidentified" ? !0 : n.length === 1 ? !(e.metaKey || e.ctrlKey && !o(e)) || z.has(n.toLowerCase()) : !1;
|
|
266
|
+
}
|
|
267
|
+
function ie(e) {
|
|
268
|
+
e.preventDefault();
|
|
269
|
+
}
|
|
270
|
+
function B(e) {
|
|
271
|
+
let { open: t, onOpenChange: n, mode: r, multiple: c = !1, selectedValues: l, onSelect: d, items: _, filter: b, loop: x = !1, typeahead: S = r === "select-only", autoHighlight: w = "selected", highlightOnFilter: D = !1, idPrefix: O, onClearDraft: k } = e, A = a(O ?? "listbox"), [j] = g(() => new T(l)), M = _ !== void 0, N = ee(j.subscribeItems, M ? y : j.getItems, y), P = _ ?? N, F = m(() => P.filter((e) => !e.hidden && (!b || b(e))), [P, b]), I = m(() => F.filter((e) => !e.disabled).map((e) => e.value), [F]), L = m(() => new Set(I), [I]), R = m(() => {
|
|
272
|
+
let e = /* @__PURE__ */ new Map();
|
|
273
|
+
for (let t of P) e.has(t.value) || e.set(t.value, t);
|
|
274
|
+
return e;
|
|
275
|
+
}, [P]), z = m(() => {
|
|
276
|
+
if (F.length === P.length) return v;
|
|
277
|
+
let e = new Set(F.map((e) => e.value)), t = /* @__PURE__ */ new Set();
|
|
278
|
+
for (let n of P) e.has(n.value) || t.add(n.value);
|
|
279
|
+
return t;
|
|
280
|
+
}, [P, F]), B = new Set(l), [V, H] = g(null), U = t ? V : null, [W, G] = g(() => ({
|
|
281
|
+
open: t,
|
|
282
|
+
items: F
|
|
283
|
+
}));
|
|
284
|
+
if (D) {
|
|
285
|
+
let e = !C(W.items, F);
|
|
286
|
+
(e || W.open !== t) && (G({
|
|
287
|
+
open: t,
|
|
288
|
+
items: F
|
|
289
|
+
}), t && e && (U = I[0] ?? null));
|
|
290
|
+
}
|
|
291
|
+
U !== null && !L.has(U) && (U = null), U !== V && H(U);
|
|
292
|
+
let K = I.find((e) => B.has(e)) ?? null, q = null;
|
|
293
|
+
w === "selected" ? q = K ?? I[0] ?? null : w === "first" && (q = I[0] ?? null);
|
|
294
|
+
let J = t ? U ?? q : null, Y = u((e) => `${A}-opt-${j.getIndex(e)}`, [A, j]), X = J === null ? void 0 : Y(J), ae = u((e) => R.get(e), [R]), Z = h(null), Q = u((e) => {
|
|
295
|
+
Z.current = null, H(e);
|
|
296
|
+
}, []), oe = Q, $ = i((e, t, r) => {
|
|
297
|
+
let i = R.get(e) ?? r;
|
|
298
|
+
i && !i.disabled && (d(e, i), c && t === "select" ? Q(e) : (Q(null), n(!1, t)));
|
|
299
|
+
}), se = i((e, t) => {
|
|
300
|
+
$(e, "select", t);
|
|
301
|
+
}), ce = i((e) => {
|
|
302
|
+
t && L.has(e) && e !== J && (Z.current = e, H(e));
|
|
303
|
+
}), { onTypeahead: le } = s({
|
|
304
|
+
getItems: () => F.map((e) => ({
|
|
305
|
+
value: e.value,
|
|
306
|
+
text: e.textValue ?? e.label,
|
|
307
|
+
disabled: e.disabled
|
|
308
|
+
})),
|
|
309
|
+
onMatch: (e) => {
|
|
310
|
+
Q(e), t || n(!0, "keyboard");
|
|
311
|
+
}
|
|
312
|
+
}), ue = i((e) => {
|
|
313
|
+
if (e.defaultPrevented || e.nativeEvent.isComposing) return;
|
|
314
|
+
r === "editable" && t && re(e) && Q(D ? I[0] ?? null : null);
|
|
315
|
+
let i = o(e);
|
|
316
|
+
if (e.ctrlKey && !i || e.metaKey) return;
|
|
317
|
+
let { key: a, altKey: s } = e, l = r === "select-only", u = I[0] ?? null, d = I[I.length - 1] ?? null, f = (e) => {
|
|
318
|
+
Q(e), t || n(!0, "keyboard");
|
|
319
|
+
}, p = (e) => Q(te(I, J, e, x)), m = () => {
|
|
320
|
+
J === null ? c || n(!1, "keyboard") : $(J, "select");
|
|
321
|
+
};
|
|
322
|
+
switch (a) {
|
|
323
|
+
case "ArrowDown":
|
|
324
|
+
e.preventDefault(), s ? t || n(!0, "keyboard") : t ? p(1) : f(K ?? u);
|
|
325
|
+
return;
|
|
326
|
+
case "ArrowUp":
|
|
327
|
+
if (e.preventDefault(), s) {
|
|
328
|
+
if (!t) return;
|
|
329
|
+
l && !c && J !== null ? $(J, "select") : n(!1, "keyboard");
|
|
330
|
+
} else t ? p(-1) : f(K ?? d);
|
|
331
|
+
return;
|
|
332
|
+
case "Home":
|
|
333
|
+
case "End":
|
|
334
|
+
if (!l) return;
|
|
335
|
+
e.preventDefault(), f(a === "Home" ? u : d);
|
|
336
|
+
return;
|
|
337
|
+
case "PageUp":
|
|
338
|
+
case "PageDown":
|
|
339
|
+
if (!l || !t) return;
|
|
340
|
+
e.preventDefault(), p(a === "PageDown" ? 10 : -10);
|
|
341
|
+
return;
|
|
342
|
+
case "Enter":
|
|
343
|
+
if (!l) {
|
|
344
|
+
t && J !== null && (e.preventDefault(), $(J, "select"));
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
e.preventDefault(), t ? m() : n(!0, "keyboard");
|
|
348
|
+
return;
|
|
349
|
+
case "Escape":
|
|
350
|
+
t ? (e.preventDefault(), n(!1, "escape")) : !l && k && ne(e.currentTarget) && (e.preventDefault(), k());
|
|
351
|
+
return;
|
|
352
|
+
case "Tab":
|
|
353
|
+
if (!t) return;
|
|
354
|
+
l && !c && J !== null ? $(J, "tab") : n(!1, "tab");
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
if (a !== " " || l) {
|
|
358
|
+
if (!S || s && !i || a.length !== 1) {
|
|
359
|
+
a === " " && l && (e.preventDefault(), t ? m() : n(!0, "keyboard"));
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
if (le(e, t ? J : K)) {
|
|
363
|
+
e.preventDefault();
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
if (a === " ") {
|
|
367
|
+
e.preventDefault(), t ? m() : n(!0, "keyboard");
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
l && !t && (e.preventDefault(), n(!0, "keyboard"));
|
|
371
|
+
}
|
|
372
|
+
}), de = i((e) => {
|
|
373
|
+
r === "select-only" && e.key === " " && e.preventDefault();
|
|
374
|
+
});
|
|
375
|
+
return p(() => {
|
|
376
|
+
j.setRegistrationMode(!M), j.flush(), j.checkOrderAfterCommit(), j.setRenderState(J, B, z);
|
|
377
|
+
}), p(() => (j.connect(), () => j.disconnect()), [j]), p(() => {
|
|
378
|
+
let e = J !== null && J === Z.current;
|
|
379
|
+
Z.current = null, !(J === null || e) && (j.getElement(J) ?? (typeof document < "u" ? document.getElementById(Y(J)) : null))?.scrollIntoView?.({ block: "nearest" });
|
|
380
|
+
}, [
|
|
381
|
+
J,
|
|
382
|
+
Y,
|
|
383
|
+
j
|
|
384
|
+
]), f(() => {
|
|
385
|
+
if (!_) return;
|
|
386
|
+
let e = /* @__PURE__ */ new Set();
|
|
387
|
+
for (let t of _) e.has(t.value) && E(t.value), e.add(t.value);
|
|
388
|
+
}, [_]), {
|
|
389
|
+
listboxId: A,
|
|
390
|
+
activeValue: J,
|
|
391
|
+
activeDescendantId: X,
|
|
392
|
+
items: F,
|
|
393
|
+
getItem: ae,
|
|
394
|
+
getOptionId: Y,
|
|
395
|
+
setActiveValue: oe,
|
|
396
|
+
onKeyDown: ue,
|
|
397
|
+
onKeyUp: de,
|
|
398
|
+
getComboboxProps: () => {
|
|
399
|
+
let e = {
|
|
400
|
+
role: "combobox",
|
|
401
|
+
"aria-expanded": t,
|
|
402
|
+
"aria-controls": A,
|
|
403
|
+
"aria-haspopup": "listbox"
|
|
404
|
+
};
|
|
405
|
+
return X !== void 0 && (e["aria-activedescendant"] = X), r === "editable" && (e["aria-autocomplete"] = "list"), e;
|
|
406
|
+
},
|
|
407
|
+
getListboxProps: () => {
|
|
408
|
+
let e = {
|
|
409
|
+
id: A,
|
|
410
|
+
role: "listbox",
|
|
411
|
+
tabIndex: -1,
|
|
412
|
+
onMouseDown: ie
|
|
413
|
+
};
|
|
414
|
+
return c && (e["aria-multiselectable"] = !0), e;
|
|
415
|
+
},
|
|
416
|
+
context: m(() => ({
|
|
417
|
+
listboxId: A,
|
|
418
|
+
store: j,
|
|
419
|
+
select: se,
|
|
420
|
+
highlight: ce
|
|
421
|
+
}), [
|
|
422
|
+
A,
|
|
423
|
+
j,
|
|
424
|
+
se,
|
|
425
|
+
ce
|
|
426
|
+
])
|
|
427
|
+
};
|
|
428
|
+
}
|
|
429
|
+
var V = 1, H = 2, U = 4;
|
|
430
|
+
function W(e, t) {
|
|
431
|
+
return (e.isActive(t) ? V : 0) | (e.isSelected(t) ? H : 0) | (e.isHidden(t) ? U : 0);
|
|
432
|
+
}
|
|
433
|
+
function G(e, t) {
|
|
434
|
+
let { store: n, listboxId: r, select: i, highlight: a } = j("Option"), { value: o, label: s, textValue: l, disabled: d = !1, hidden: f = !1 } = e, m = `${r}-opt-${n.getIndex(o)}`, g = ee(n.subscribe, () => W(n, o), () => W(n, o)), _ = (g & V) !== 0, v = (g & H) !== 0, y = f || (g & U) !== 0, b = h(null), S = u((e) => {
|
|
435
|
+
b.current = e;
|
|
436
|
+
}, []), C = c(t, S), w = h(null);
|
|
437
|
+
p(() => {
|
|
438
|
+
let e = s === void 0 && l === void 0 ? b.current?.textContent?.trim() : void 0, t = {
|
|
439
|
+
value: o,
|
|
440
|
+
label: s ?? l ?? (e || o)
|
|
441
|
+
};
|
|
442
|
+
l !== void 0 && (t.textValue = l), d && (t.disabled = !0), f && (t.hidden = !0);
|
|
443
|
+
let r = w.current;
|
|
444
|
+
r && r.store === n && x(r.item, t) || (r?.unregister(), w.current = {
|
|
445
|
+
store: n,
|
|
446
|
+
item: t,
|
|
447
|
+
unregister: n.register(t, b)
|
|
448
|
+
});
|
|
449
|
+
}), p(() => () => {
|
|
450
|
+
w.current?.unregister(), w.current = null;
|
|
451
|
+
}, []);
|
|
452
|
+
let T = {
|
|
453
|
+
id: m,
|
|
454
|
+
role: "option",
|
|
455
|
+
"aria-selected": v,
|
|
456
|
+
onClick: u(() => {
|
|
457
|
+
if (d) return;
|
|
458
|
+
let e = {
|
|
459
|
+
value: o,
|
|
460
|
+
label: s ?? l ?? o
|
|
461
|
+
};
|
|
462
|
+
l !== void 0 && (e.textValue = l), i(o, e);
|
|
463
|
+
}, [
|
|
464
|
+
i,
|
|
465
|
+
o,
|
|
466
|
+
s,
|
|
467
|
+
l,
|
|
468
|
+
d
|
|
469
|
+
]),
|
|
470
|
+
onPointerMove: u(() => {
|
|
471
|
+
!d && !n.isActive(o) && a(o);
|
|
472
|
+
}, [
|
|
473
|
+
a,
|
|
474
|
+
n,
|
|
475
|
+
o,
|
|
476
|
+
d
|
|
477
|
+
]),
|
|
478
|
+
ref: C
|
|
479
|
+
};
|
|
480
|
+
return d && (T["aria-disabled"] = !0, T["data-disabled"] = ""), y && (T.hidden = !0), _ && (T["data-active"] = ""), v && (T["data-selected"] = ""), {
|
|
481
|
+
id: m,
|
|
482
|
+
selected: v,
|
|
483
|
+
active: _,
|
|
484
|
+
disabled: d,
|
|
485
|
+
hidden: y,
|
|
486
|
+
optionProps: T
|
|
487
|
+
};
|
|
488
|
+
}
|
|
489
|
+
//#endregion
|
|
490
|
+
export { O as ListboxContext, R as collectOptionLabels, N as markListboxElement, B as useListbox, G as useListboxOption };
|
|
491
|
+
|
|
492
|
+
//# sourceMappingURL=useListbox.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useListbox.mjs","names":["useId","useId$1","React","EMPTY_ITEMS","EMPTY_SET","getEmptyItems","sameSet","a","b","value","sameItem","sameItems","item","index","sameValues","compareRegistrations","ea","eb","position","ListboxStoreImpl","selectedValues","listener","registration","sorted","seen","next","el","element","enabled","i","moved","recorded","changed","active","selected","hidden","target","isDev","warnIfPageWide","ancestor","count","warnDuplicateValue","doc","warnOnce","ListboxContext","inertContext","getInertContext","useListboxContext","useContext","reportMissingContext","componentName","LISTBOX_ELEMENT_KIND","markListboxElement","component","kind","kindOf","type","textOf","node","text","child","optionLabel","props","walkOptions","children","getElementType","labels","label","collectOptionLabels","step","values","current","delta","loop","hasText","TEXT_SHORTCUTS","editsText","event","key","isAltGraphCharacter","preventMouseDown","useListbox","dataItems","mode","options","listboxId","idPrefix","store","useState","dataMode","registered","useSyncExternalStore","allItems","navigable","useMemo","filter","enabledValues","enabledSet","itemByValue","map","hiddenSet","visible","selectedSet","activeRaw","setActiveRaw","highlighted","open","filterTrack","setFilterTrack","highlightOnFilter","itemsChanged","firstSelected","fallback","autoHighlight","activeValue","getOptionId","useCallback","activeDescendantId","getItem","pointerHighlightRef","useRef","setActive","setActiveValue","commit","useEventCallback","fallbackItem","onSelect","multiple","reason","onOpenChange","select","highlight","useTypeahead","onKeyDown","altGraph","selectOnly","first","last","openWith","move","commitOrClose","altKey","onClearDraft","typeahead","onTypeahead","onKeyUp","useLayoutEffect","fromPointer","useEffect","FLAG_ACTIVE","FLAG_SELECTED","FLAG_HIDDEN","optionFlags","useListboxOption","hiddenByConsumer","id","flags","elementRef","setElement","mergedRef","useMergedRefs","ref","registrationRef","textValue","disabled","optionProps"],"sources":["../../src/hooks/useListbox.ts"],"sourcesContent":["import * as React from 'react';\nimport {\n useCallback,\n useContext,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n useSyncExternalStore,\n} from 'react';\nimport { getElementType } from '../lib/children';\nimport { isDev, reportMissingContext, warnOnce } from '../lib/dev';\nimport { useEventCallback } from './useEventCallback';\nimport { useId } from './useId';\nimport { useMergedRefs } from './useMergedRefs';\nimport { isAltGraphCharacter, useTypeahead } from './useTypeahead';\n\n/* ------------------------------------------------------------------ */\n/* Public types */\n/* ------------------------------------------------------------------ */\n\n/** One option of a listbox. */\nexport interface ListboxItem {\n /** Unique value within the listbox. */\n value: string;\n /** Display label (Combobox input text, Dropdown trigger text). */\n label: string;\n /** Text matched by typeahead and filters instead of `label`. */\n textValue?: string;\n /** Disabled options are rendered but skipped by navigation and never committed. */\n disabled?: boolean;\n /**\n * Hidden options (the consumer's `hidden` attribute) are left out of navigation and rendering\n * like filtered-out ones: never highlighted, reached by typeahead or committed with the keyboard\n * (registered options render `hidden`). Their label stays known\n * ({@link UseListboxResult.getItem}).\n */\n hidden?: boolean;\n}\n\n/** Why {@link UseListboxOptions.onOpenChange} was called. */\nexport type ListboxOpenChangeReason = 'keyboard' | 'select' | 'escape' | 'tab';\n\n/** Options of {@link useListbox}. */\nexport interface UseListboxOptions {\n /** Whether the listbox is shown. The consumer owns the open state. */\n open: boolean;\n /** Called when a key (or a commit) wants to open or close the listbox. */\n onOpenChange: (open: boolean, reason: ListboxOpenChangeReason) => void;\n /**\n * `'editable'`: a text input combobox (Combobox, TagPicker, TimePicker).\n * `'select-only'`: a button/div combobox without text entry (Dropdown).\n */\n mode: 'editable' | 'select-only';\n /** Several values can be selected; committing keeps the listbox open. */\n multiple?: boolean;\n /** The selected values (`[]` when nothing is selected). */\n selectedValues: readonly string[];\n /**\n * Called when an option is committed: click, Enter/Space, and in single-select select-only mode\n * also Tab and Alt+ArrowUp (with `multiple` they close without committing).\n */\n onSelect: (value: string, item: ListboxItem) => void;\n /**\n * Data mode: the options. Omitted ⇒ registration mode — the `Option` children register\n * themselves through {@link ListboxContext} ({@link useListboxOption}).\n */\n items?: readonly ListboxItem[];\n /** Hides items from navigation and rendering (registered options render `hidden`). */\n filter?: (item: ListboxItem) => boolean;\n /** Arrow keys wrap around at the ends. @default false */\n loop?: boolean;\n /** Printable characters move to the matching option. @default mode === 'select-only' */\n typeahead?: boolean;\n /**\n * The option that is active while no option is highlighted: `'selected'` — the first selected\n * navigable option in list order (not in `selectedValues` order), else the first option;\n * `'first'` — the first option; `false` — none. A highlighted option that leaves the navigable\n * set is dropped (the fallback takes over, also when the option returns); in editable mode a\n * text-editing key clears the highlight.\n * @default 'selected'\n */\n autoHighlight?: 'selected' | 'first' | false;\n /**\n * Editable: whenever the navigable set changes while open (typing), its first option becomes\n * active — also when the keystroke that opens the listbox changes the set (compared with the set\n * before opening) — and so does every text-editing key while open, also when the set stays the\n * same. Opening with an unchanged set keeps the `autoHighlight` start.\n */\n highlightOnFilter?: boolean;\n /** Prefix of the generated listbox id. @default 'listbox' */\n idPrefix?: string;\n /**\n * Editable: Escape with the listbox closed and text in the input calls this (and prevents the\n * default) so the consumer can clear its draft text. Not handled when omitted.\n */\n onClearDraft?: () => void;\n}\n\n/** Props for the combobox element (spread them; see {@link UseListboxResult.getComboboxProps}). */\nexport interface ListboxComboboxProps {\n role: 'combobox';\n 'aria-expanded': boolean;\n 'aria-controls': string;\n 'aria-activedescendant'?: string;\n 'aria-haspopup': 'listbox';\n 'aria-autocomplete'?: 'list';\n}\n\n/** Props for the listbox element (see {@link UseListboxResult.getListboxProps}). */\nexport interface ListboxListProps {\n id: string;\n role: 'listbox';\n 'aria-multiselectable'?: true;\n tabIndex: -1;\n /** Keeps focus on the combobox while options are clicked. */\n onMouseDown(event: React.MouseEvent): void;\n}\n\n/** Result of {@link useListbox}. */\nexport interface UseListboxResult {\n /** Id of the listbox element. */\n listboxId: string;\n /** The active (highlighted) option, derived during render; `null` while closed. */\n activeValue: string | null;\n /** `getOptionId(activeValue)` while open and an option is active. */\n activeDescendantId: string | undefined;\n /**\n * The navigable items in DOM/data order: without filtered-out and hidden items; disabled ones\n * are included (navigation skips them).\n */\n items: ListboxItem[];\n /** Unfiltered lookup (registered options or `items`), e.g. for the selected option's label. */\n getItem(value: string): ListboxItem | undefined;\n /** `${listboxId}-opt-${n}`; `n` is assigned the first time a value is seen and never changes. */\n getOptionId(value: string): string;\n /**\n * Highlights an option while open (ignored when it is not navigable or disabled; dropped when it\n * leaves the navigable set later). Scrolled into view like a keyboard highlight.\n */\n setActiveValue(value: string | null): void;\n /** Attach to the combobox element. Ignores events a consumer handler already prevented. */\n onKeyDown(event: React.KeyboardEvent): void;\n /**\n * Attach to the combobox element next to `onKeyDown`. Required for a `<button>` combobox\n * (select-only): it prevents the Space keyup, so the native click does not toggle the listbox\n * again after the keydown opened or committed.\n */\n onKeyUp(event: React.KeyboardEvent): void;\n getComboboxProps(): ListboxComboboxProps;\n getListboxProps(): ListboxListProps;\n /** Provide it with `<ListboxContext.Provider value={context}>` around the options. */\n context: ListboxContextValue;\n}\n\n/**\n * Per-option state of a listbox. Subscribe with `useSyncExternalStore` and read one value\n * (`() => store.isHidden(value)`), so only components whose answer changed re-render.\n */\nexport interface ListboxStore {\n subscribe(listener: () => void): () => void;\n isActive(value: string): boolean;\n isSelected(value: string): boolean;\n isHidden(value: string): boolean;\n /** The stable per-listbox index of `value`, assigned the first time the value is seen. */\n getIndex(value: string): number;\n /**\n * Registers an option and its element. The registrations of a commit are published once from\n * the listbox root's layout effect (later ones once per microtask). Returns the unregister.\n */\n register(item: ListboxItem, element: React.RefObject<HTMLElement | null>): () => void;\n}\n\n/** Value of {@link ListboxContext} (use {@link UseListboxResult.context}). */\nexport interface ListboxContextValue {\n listboxId: string;\n store: ListboxStore;\n /** Commits `value` (option click). */\n select(value: string, item: ListboxItem): void;\n /** Highlights `value` (pointer movement); not scrolled into view, so the list stays put. */\n highlight(value: string): void;\n}\n\n/**\n * Props of {@link useListboxOption}. The option's position in the listbox follows its element's\n * DOM position, also when the option is memoized and only moved (see {@link useListbox}).\n */\nexport interface UseListboxOptionProps {\n value: string;\n /**\n * Display label; falls back to `textValue`, then the element's text content, then `value`. The\n * text content is re-read after every render of the option. Text that a child component changes\n * from its own state (without the option re-rendering) is not seen; pass `label` or `textValue`\n * for such options.\n */\n label?: string;\n textValue?: string;\n disabled?: boolean;\n /**\n * The consumer hid the option (its own `hidden` attribute, or a hidden group around it): it\n * registers as a hidden item ({@link ListboxItem.hidden}), so it is not navigable, and\n * `optionProps.hidden` is set from the first render (server included).\n */\n hidden?: boolean;\n}\n\n/** Props for an option element (spread them onto the `<li>`; compose `onClick` with yours). */\nexport interface ListboxOptionProps<E extends HTMLElement = HTMLElement> {\n id: string;\n role: 'option';\n 'aria-selected': boolean;\n 'aria-disabled'?: true;\n hidden?: boolean;\n 'data-active'?: '';\n 'data-selected'?: '';\n 'data-disabled'?: '';\n onClick(event: React.MouseEvent<E>): void;\n onPointerMove(event: React.PointerEvent<E>): void;\n ref: React.RefCallback<E>;\n}\n\n/** Result of {@link useListboxOption}. */\nexport interface UseListboxOptionResult<E extends HTMLElement = HTMLElement> {\n id: string;\n selected: boolean;\n active: boolean;\n disabled: boolean;\n /** Filtered out, or hidden by the consumer ({@link UseListboxOptionProps.hidden}). */\n hidden: boolean;\n optionProps: ListboxOptionProps<E>;\n}\n\n/* ------------------------------------------------------------------ */\n/* Store */\n/* ------------------------------------------------------------------ */\n\ninterface Registration {\n item: ListboxItem;\n element: React.RefObject<HTMLElement | null>;\n seq: number;\n}\n\nconst EMPTY_ITEMS: ListboxItem[] = [];\nconst EMPTY_SET: ReadonlySet<string> = new Set<string>();\n\nfunction getEmptyItems(): ListboxItem[] {\n return EMPTY_ITEMS;\n}\n\nfunction sameSet(a: ReadonlySet<string>, b: ReadonlySet<string>): boolean {\n if (a === b) return true;\n if (a.size !== b.size) return false;\n for (const value of a) if (!b.has(value)) return false;\n return true;\n}\n\nfunction sameItem(a: ListboxItem, b: ListboxItem): boolean {\n return (\n a.value === b.value &&\n a.label === b.label &&\n a.textValue === b.textValue &&\n !!a.disabled === !!b.disabled &&\n !!a.hidden === !!b.hidden\n );\n}\n\nfunction sameItems(a: readonly ListboxItem[], b: readonly ListboxItem[]): boolean {\n if (a === b) return true;\n if (a.length !== b.length) return false;\n return a.every((item, index) => sameItem(item, b[index]));\n}\n\nfunction sameValues(a: readonly ListboxItem[], b: readonly ListboxItem[]): boolean {\n if (a === b) return true;\n if (a.length !== b.length) return false;\n return a.every((item, index) => item.value === b[index].value);\n}\n\nfunction compareRegistrations(a: Registration, b: Registration): number {\n const ea = a.element.current;\n const eb = b.element.current;\n if (ea && eb && ea !== eb && ea.isConnected && eb.isConnected) {\n const position = ea.compareDocumentPosition(eb);\n if (position & Node.DOCUMENT_POSITION_FOLLOWING) return -1;\n if (position & Node.DOCUMENT_POSITION_PRECEDING) return 1;\n }\n return a.seq - b.seq;\n}\n\nclass ListboxStoreImpl implements ListboxStore {\n private readonly indexByValue = new Map<string, number>();\n private readonly registrations = new Set<Registration>();\n private readonly stateListeners = new Set<() => void>();\n private readonly itemListeners = new Set<() => void>();\n private nextIndex = 0;\n private nextSeq = 0;\n private dirty = false;\n private flushScheduled = false;\n private itemsStale = false;\n private itemsSnapshot: ListboxItem[] = EMPTY_ITEMS;\n /** The registrations in the order of the last sort (the order {@link checkOrder} verifies). */\n private sorted: Registration[] = [];\n /** Watches the common ancestor of the option elements for moves ({@link syncObserver}). */\n private observer: MutationObserver | null = null;\n private observed: Node | null = null;\n /**\n * The observer has recorded every option move since the order was last verified, so a root\n * commit without `childList` records needs no {@link checkOrder} ({@link checkOrderAfterCommit}).\n * Cleared whenever the observed node changes: moves before `observe()` were not recorded.\n */\n private watching = false;\n /** The listbox root is mounted (between {@link connect} and {@link disconnect}). */\n private connected = false;\n private registrationMode = true;\n private active: string | null = null;\n private selected: ReadonlySet<string>;\n private hidden: ReadonlySet<string> = EMPTY_SET;\n\n constructor(selectedValues: readonly string[]) {\n this.selected = new Set(selectedValues);\n }\n\n subscribe = (listener: () => void): (() => void) => {\n this.stateListeners.add(listener);\n return () => {\n this.stateListeners.delete(listener);\n };\n };\n\n subscribeItems = (listener: () => void): (() => void) => {\n this.itemListeners.add(listener);\n return () => {\n this.itemListeners.delete(listener);\n };\n };\n\n isActive = (value: string): boolean => this.active === value;\n isSelected = (value: string): boolean => this.selected.has(value);\n isHidden = (value: string): boolean => this.hidden.has(value);\n\n getIndex = (value: string): number => {\n let index = this.indexByValue.get(value);\n if (index === undefined) {\n index = this.nextIndex++;\n this.indexByValue.set(value, index);\n }\n return index;\n };\n\n register = (item: ListboxItem, element: React.RefObject<HTMLElement | null>): (() => void) => {\n const registration: Registration = { item, element, seq: this.nextSeq++ };\n this.registrations.add(registration);\n this.markDirty();\n return () => {\n this.registrations.delete(registration);\n this.markDirty();\n };\n };\n\n /** Registration-mode snapshot: registered options in DOM order, first of each value. */\n getItems = (): ListboxItem[] => {\n if (this.itemsStale) {\n this.itemsStale = false;\n const sorted = Array.from(this.registrations).sort(compareRegistrations);\n this.sorted = sorted;\n const seen = new Set<string>();\n const next: ListboxItem[] = [];\n for (const { item } of sorted) {\n if (seen.has(item.value)) continue;\n seen.add(item.value);\n next.push(item);\n }\n if (!sameItems(next, this.itemsSnapshot)) this.itemsSnapshot = next;\n }\n return this.itemsSnapshot;\n };\n\n /** The mounted element of an option (for scrolling). */\n getElement(value: string): HTMLElement | null {\n for (const { item, element } of this.registrations) {\n const el = element.current;\n if (item.value === value && el && el.isConnected) return el;\n }\n return null;\n }\n\n setRegistrationMode(enabled: boolean): void {\n if (enabled === this.registrationMode) return;\n this.registrationMode = enabled;\n this.syncObserver();\n }\n\n /** The listbox root mounted (layout effect): start watching the option elements for moves. */\n connect(): void {\n this.connected = true;\n this.syncObserver();\n }\n\n /** The listbox root unmounted: stop watching. */\n disconnect(): void {\n this.connected = false;\n this.syncObserver();\n }\n\n /** Publishes pending registrations: one notification for everything registered since the last. */\n flush(): void {\n if (!this.dirty) return;\n this.dirty = false;\n this.itemsStale = true;\n if (this.registrationMode) this.warnDuplicates();\n this.syncObserver();\n this.notifyItems();\n }\n\n /**\n * Re-sorts (and publishes) when the registered elements are no longer in document order. A keyed\n * reorder (a sort toggle, re-ranked results) moves option elements without registering them\n * again, so the order is verified after a commit of the listbox root that moved option elements\n * ({@link checkOrderAfterCommit}) and whenever the option elements move ({@link syncObserver}):\n * neighbours of the last sort are compared (n - 1 `compareDocumentPosition` calls), and only an\n * inversion publishes. Pending registrations are left to {@link flush}, which sorts anyway.\n */\n checkOrder(): void {\n if (!this.registrationMode || this.dirty || this.itemsStale) return;\n const sorted = this.sorted;\n for (let i = 1; i < sorted.length; i++) {\n const a = sorted[i - 1].element.current;\n const b = sorted[i].element.current;\n if (!a || !b || a === b || !a.isConnected || !b.isConnected) continue;\n if (a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_PRECEDING) {\n this.itemsStale = true;\n this.notifyItems();\n return;\n }\n }\n }\n\n /**\n * The listbox root committed (layout effect): verifies the order when the commit may have moved\n * option elements. While the observer watches them, the moves of this commit are its pending\n * `childList` records (the callback runs only in a later microtask): they are taken here, so a\n * keyed reorder re-sorts in the same commit and is not checked again by the callback, and a\n * commit without records (a highlight move) costs O(1). Without an observer (fewer than two\n * options, no `MutationObserver`) or right after it started watching, every commit checks.\n */\n checkOrderAfterCommit(): void {\n // Only childList is observed, so every pending record is an insertion or removal.\n const moved = this.observer !== null && this.observer.takeRecords().length > 0;\n const recorded = this.watching;\n this.watching = this.observed !== null;\n if (recorded && !moved) return;\n this.checkOrder();\n }\n\n /** Syncs the root's derived render state for the option selectors (layout effect). */\n setRenderState(\n active: string | null,\n selected: ReadonlySet<string>,\n hidden: ReadonlySet<string>,\n ): void {\n let changed = false;\n if (active !== this.active) {\n this.active = active;\n changed = true;\n }\n if (!sameSet(selected, this.selected)) {\n this.selected = selected;\n changed = true;\n }\n if (!sameSet(hidden, this.hidden)) {\n this.hidden = hidden;\n changed = true;\n }\n if (changed) for (const listener of Array.from(this.stateListeners)) listener();\n }\n\n private notifyItems(): void {\n for (const listener of Array.from(this.itemListeners)) listener();\n }\n\n private readonly onMutation = (): void => {\n this.checkOrder();\n };\n\n /**\n * Observes (`childList`, `subtree`) the closest common ancestor of the connected option elements,\n * so a move that renders neither the listbox root nor the options — memoized options or hoisted\n * elements reordered by a wrapper component inside the listbox — still triggers\n * {@link checkOrder}. Recomputed when the registrations change (a remounted list registers\n * again); nothing is observed with fewer than two options, in data mode, before the root mounted\n * or without `MutationObserver` (server). Attribute and text changes are not observed.\n *\n * All options must live in one container at a time (consumer contract): options split over an\n * inline and a portaled list have `<body>` as their common ancestor, so every DOM mutation on\n * the page would re-check the order — development warns once.\n */\n private syncObserver(): void {\n const target =\n this.connected && this.registrationMode && typeof MutationObserver !== 'undefined'\n ? this.commonAncestor()\n : null;\n if (target === this.observed) return;\n this.observer?.disconnect();\n this.observed = target;\n this.watching = false;\n if (!target) return;\n if (isDev) warnIfPageWide(target);\n this.observer ??= new MutationObserver(this.onMutation);\n this.observer.observe(target, { childList: true, subtree: true });\n }\n\n private commonAncestor(): Node | null {\n let ancestor: Node | null = null;\n let count = 0;\n for (const { element } of this.registrations) {\n const el = element.current;\n if (!el || !el.isConnected) continue;\n count++;\n if (ancestor === null) {\n ancestor = el.parentNode;\n continue;\n }\n while (ancestor && !ancestor.contains(el)) ancestor = ancestor.parentNode;\n if (!ancestor) return null;\n }\n return count > 1 ? ancestor : null;\n }\n\n private markDirty(): void {\n this.dirty = true;\n if (this.flushScheduled) return;\n this.flushScheduled = true;\n queueMicrotask(() => {\n this.flushScheduled = false;\n this.flush();\n });\n }\n\n private warnDuplicates(): void {\n const seen = new Set<string>();\n for (const { item } of this.registrations) {\n if (seen.has(item.value)) warnDuplicateValue(item.value);\n seen.add(item.value);\n }\n }\n}\n\nfunction warnDuplicateValue(value: string): void {\n warnOnce(\n `useListbox:duplicate:${value}`,\n `Listbox: several options share the value \"${value}\". Option values must be unique within ` +\n 'a listbox; only the first one can be highlighted and selected.',\n );\n}\n\nfunction warnIfPageWide(ancestor: Node): void {\n const doc = ancestor.ownerDocument;\n if (!doc || (ancestor !== doc.body && ancestor !== doc.documentElement)) return;\n warnOnce(\n 'useListbox:single-container',\n 'Listbox: the options of one listbox are rendered in more than one container (for example an ' +\n 'inline list kept mounted next to a portaled one). All options must live in a single ' +\n 'container at a time: render the list inline only while closed and in the portal only ' +\n 'while open.',\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Context */\n/* ------------------------------------------------------------------ */\n\n/** Provided by listbox roots (`<ListboxContext.Provider value={listbox.context}>`). */\nexport const ListboxContext: React.Context<ListboxContextValue | null> =\n React.createContext<ListboxContextValue | null>(null);\nListboxContext.displayName = 'ListboxContext';\n\nlet inertContext: ListboxContextValue | null = null;\n\nfunction getInertContext(): ListboxContextValue {\n inertContext ??= {\n listboxId: 'wave-listbox-inert',\n store: new ListboxStoreImpl([]),\n select: () => {},\n highlight: () => {},\n };\n return inertContext;\n}\n\nfunction useListboxContext(componentName: string): ListboxContextValue {\n const context = useContext(ListboxContext);\n if (context) return context;\n reportMissingContext(componentName, 'a listbox (Combobox or Dropdown)');\n return getInertContext();\n}\n\n/* ------------------------------------------------------------------ */\n/* collectOptionLabels */\n/* ------------------------------------------------------------------ */\n\nconst LISTBOX_ELEMENT_KIND = Symbol.for('@mortenbrudvik/waveui/listbox-element-kind');\n\n/** What {@link collectOptionLabels} does with a marked component's elements. */\nexport type ListboxElementKind = 'option' | 'group';\n\n/**\n * Marks a component so {@link collectOptionLabels} recognises its elements: `'option'` (reads\n * `value` and the label) or `'group'` (walks its `children`). Returns the component (function,\n * `memo` or `forwardRef` components). Required for every exported option/group component:\n * unmarked components are opaque to {@link collectOptionLabels}, so their labels are unknown on\n * the server and in the first client render.\n *\n * @example\n * export const Option = markListboxElement(OptionImpl, 'option');\n * export const OptionGroup = markListboxElement(OptionGroupImpl, 'group');\n */\nexport function markListboxElement<C extends object>(component: C, kind: ListboxElementKind): C {\n Object.defineProperty(component, LISTBOX_ELEMENT_KIND, { value: kind, configurable: true });\n return component;\n}\n\nfunction kindOf(type: unknown): ListboxElementKind | undefined {\n if ((typeof type !== 'function' && typeof type !== 'object') || type === null) return undefined;\n const kind = (type as { [LISTBOX_ELEMENT_KIND]?: unknown })[LISTBOX_ELEMENT_KIND];\n return kind === 'option' || kind === 'group' ? kind : undefined;\n}\n\ninterface OptionElementProps {\n value?: unknown;\n label?: unknown;\n textValue?: unknown;\n children?: React.ReactNode;\n}\n\nfunction textOf(node: React.ReactNode): string {\n if (typeof node === 'string') return node;\n if (typeof node === 'number' || typeof node === 'bigint') return String(node);\n if (node === null || node === undefined || typeof node === 'boolean') return '';\n if (React.isValidElement<{ children?: React.ReactNode }>(node)) {\n // Host elements and Fragments render their children; custom components are opaque.\n if (typeof node.type === 'string' || node.type === React.Fragment) {\n return textOf(node.props.children);\n }\n return '';\n }\n if (typeof node === 'object' && Symbol.iterator in node) {\n let text = '';\n for (const child of node as Iterable<React.ReactNode>) text += textOf(child);\n return text;\n }\n return '';\n}\n\nfunction optionLabel(props: OptionElementProps, value: string): string | undefined {\n if (typeof props.label === 'string') return props.label;\n if (typeof props.textValue === 'string') return props.textValue;\n if (props.children === null || props.children === undefined) return value;\n const text = textOf(props.children).trim();\n return text || undefined;\n}\n\nfunction walkOptions(children: React.ReactNode, labels: Map<string, string>): void {\n React.Children.forEach(children, (child) => {\n if (!React.isValidElement<OptionElementProps>(child)) return;\n // An Option or OptionGroup written in a Server Component arrives as a lazy type: unwrap it.\n const type = getElementType(child);\n if (type === React.Fragment) {\n walkOptions(child.props.children, labels);\n return;\n }\n const kind = kindOf(type);\n if (kind === 'group') {\n walkOptions(child.props.children, labels);\n return;\n }\n if (kind !== 'option') return;\n const { value } = child.props;\n if (typeof value !== 'string' || labels.has(value)) return;\n const label = optionLabel(child.props, value);\n if (label !== undefined) labels.set(value, label);\n });\n}\n\n/**\n * Reads option labels from `children` during render (read-only), for display text before the\n * options have registered: on the server, in the first client render and during hydration\n * (layout effects have not run yet). Walks elements of components marked with\n * {@link markListboxElement}: `'option'` elements give `value → label` (`label` prop →\n * `textValue` → the text of their string/number children and host elements → `value` when they\n * have no children); `'group'` elements and Fragments are walked into. Other components are\n * opaque (their options resolve after registration). The first option of a value wins. A lazy\n * element type (an option or group written in a React Server Component) is unwrapped first.\n *\n * Display text = `listbox.getItem(value)?.label ?? collectOptionLabels(children).get(value)`\n * (`?? value` for freeform input only).\n */\nexport function collectOptionLabels(children: React.ReactNode): Map<string, string> {\n const labels = new Map<string, string>();\n walkOptions(children, labels);\n return labels;\n}\n\n/* ------------------------------------------------------------------ */\n/* useListbox */\n/* ------------------------------------------------------------------ */\n\nfunction step(\n values: readonly string[],\n current: string | null,\n delta: number,\n loop: boolean,\n): string | null {\n const count = values.length;\n if (count === 0) return null;\n const index = current === null ? -1 : values.indexOf(current);\n if (index === -1) return delta > 0 ? values[0] : values[count - 1];\n let next = index + delta;\n if (next < 0 || next >= count) {\n next =\n loop && Math.abs(delta) === 1\n ? (next + count) % count\n : Math.max(0, Math.min(count - 1, next));\n }\n return values[next];\n}\n\nfunction hasText(element: EventTarget): boolean {\n return (\n (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement) &&\n element.value !== ''\n );\n}\n\n/** Ctrl/Cmd shortcuts that change the text: cut, paste, undo, redo. */\nconst TEXT_SHORTCUTS: ReadonlySet<string> = new Set(['x', 'v', 'z', 'y']);\n\n/**\n * Editable: whether a keydown edits the text of the combobox input — printable characters (AltGr,\n * i.e. Ctrl+Alt, included), Backspace/Delete, the cut/paste/undo/redo shortcuts and the\n * `Process`/`Unidentified` keys of IMEs and virtual keyboards. Nothing edits a read-only or\n * disabled input.\n */\nfunction editsText(event: React.KeyboardEvent): boolean {\n const target = event.currentTarget;\n if (\n (target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement) &&\n (target.readOnly || target.disabled)\n ) {\n return false;\n }\n const { key } = event;\n if (key === 'Backspace' || key === 'Delete' || key === 'Process' || key === 'Unidentified') {\n return true;\n }\n if (key.length !== 1) return false;\n const shortcut = event.metaKey || (event.ctrlKey && !isAltGraphCharacter(event));\n return !shortcut || TEXT_SHORTCUTS.has(key.toLowerCase());\n}\n\nfunction preventMouseDown(event: React.MouseEvent): void {\n event.preventDefault();\n}\n\n/**\n * The listbox behaviour shared by Combobox, Dropdown, TagPicker and TimePicker (spec §2.5): one\n * navigable option list drives the highlight, `aria-activedescendant` and the commit, so the\n * highlighted option is always the one Enter selects.\n *\n * - **Items.** Data mode (`items`) or registration mode: `Option`s call {@link useListboxOption}\n * inside {@link ListboxContext} and register in DOM order (OptionGroups included). The\n * registrations of one commit are published once from this hook's layout effect (which runs\n * after the options'); later additions/removals are published once per microtask. A keyed\n * reorder of the same options re-sorts them: the DOM order is re-checked after a commit of this\n * hook's component that moved option elements (a highlight move moves none, so it costs O(1))\n * and, while it is mounted, whenever option elements move (a `MutationObserver` on their\n * common ancestor) — so memoized options or hoisted elements that a wrapper component inside\n * the listbox reorders are re-sorted too, although neither the options nor this component\n * render. Options register even when filtered out or hidden by the consumer (they render\n * `hidden` and are not navigable), so labels are always known — use {@link collectOptionLabels}\n * for the display text before registration (SSR/first render).\n * - **Active option** is derived during render: the highlighted value, else the `autoHighlight`\n * fallback. The highlight is reset on close and after a single-select commit, and dropped once\n * it is not navigable and enabled any more (filtered out, hidden, removed by an update,\n * disabled), so it does not come back without a user action when the option returns. Editable:\n * a text-editing key (printable characters, Backspace/Delete, cut/paste/undo/redo) clears it —\n * visual focus returns to the textbox (APG) — so Enter after typing never commits an option\n * highlighted before the edit.\n * - **Ids** `${listboxId}-opt-${n}` are stable per value (across filtering and remounts between\n * an inline closed list and a portaled open list).\n * - **Store.** Options read their active/selected/hidden flags through a store, so moving the\n * highlight re-renders only the old and the new option.\n * - **Keys (APG).** Editable: ArrowDown/ArrowUp open (selected, else first/last) and move;\n * Alt+ArrowDown opens without moving; Alt+ArrowUp closes; Enter commits the active option (with\n * the listbox closed Enter is not prevented, so forms submit); Escape closes (closed + text:\n * `onClearDraft`); Tab closes; Home/End/printable keys stay with the input (text-editing keys\n * clear the highlight, see above). Select-only:\n * ArrowDown/ArrowUp/Home/End/typeahead open and position (a closed typeahead starts from the\n * selected option; characters typed with AltGr, i.e. Ctrl+Alt on Windows, count); PageUp/PageDown\n * jump 10; Enter/Space open or commit (always prevented on keydown, Space also on keyup, so a\n * `<button>` combobox is not clicked again; a Space typed within 500 ms of a typeahead character\n * continues the search instead); Alt+ArrowUp and Tab commit and close in single-select mode\n * (with `multiple` they only close; Tab is not prevented); Escape closes.\n * \"Selected\" means the first selected navigable option in list order. Disabled options are\n * skipped and never committed; hidden options are not navigable at all.\n * - The active option is scrolled into view (`{ block: 'nearest' }`) in a layout effect, except\n * after a pointer highlight (the list would scroll under the pointer).\n *\n * **Consumer contract** (Combobox, Dropdown, TagPicker, TimePicker). Beyond the spec §2.5 signature:\n * - All options of a listbox live in a single container at a time (§5.5: inline only while\n * closed, portaled only while open — never both, not even for an exit animation). Options split\n * over two containers are watched from `<body>` and registered twice (development warns).\n * - Spread `getComboboxProps()` onto the combobox element and attach **both** `onKeyDown` and\n * `onKeyUp` to it (compose them with the consumer's handlers, C-COMPOSE). `onKeyUp` is required\n * for a `<button>` combobox (select-only): without it the button's native click on Space keyup\n * toggles the listbox again after a keydown commit.\n * - Registration mode: export the option components through {@link markListboxElement}\n * (`Option = markListboxElement(OptionImpl, 'option')`, `OptionGroup =\n * markListboxElement(OptionGroupImpl, 'group')`; memo components can be marked too).\n * {@link collectOptionLabels} walks only marked components, so without the marks the server\n * render and the first client render have no display text.\n * - Display text: `getItem(value)?.label ?? collectOptionLabels(children).get(value)` (`?? value`\n * for freeform input only). Editable consumers pass `onClearDraft` for Escape on a closed list.\n */\nexport function useListbox(options: UseListboxOptions): UseListboxResult {\n const {\n open,\n onOpenChange,\n mode,\n multiple = false,\n selectedValues,\n onSelect,\n items: dataItems,\n filter,\n loop = false,\n typeahead = mode === 'select-only',\n autoHighlight = 'selected',\n highlightOnFilter = false,\n idPrefix,\n onClearDraft,\n } = options;\n\n const listboxId = useId(idPrefix ?? 'listbox');\n const [store] = useState(() => new ListboxStoreImpl(selectedValues));\n const dataMode = dataItems !== undefined;\n const registered = useSyncExternalStore(\n store.subscribeItems,\n dataMode ? getEmptyItems : store.getItems,\n getEmptyItems,\n );\n const allItems: readonly ListboxItem[] = dataItems ?? registered;\n\n const navigable = useMemo(\n () => allItems.filter((item) => !item.hidden && (!filter || filter(item))),\n [allItems, filter],\n );\n const enabledValues = useMemo(\n () => navigable.filter((item) => !item.disabled).map((item) => item.value),\n [navigable],\n );\n const enabledSet = useMemo(() => new Set(enabledValues), [enabledValues]);\n const itemByValue = useMemo(() => {\n const map = new Map<string, ListboxItem>();\n for (const item of allItems) if (!map.has(item.value)) map.set(item.value, item);\n return map;\n }, [allItems]);\n // Filtered-out and hidden items: registered options read it to render `hidden`.\n const hiddenSet = useMemo(() => {\n if (navigable.length === allItems.length) return EMPTY_SET;\n const visible = new Set(navigable.map((item) => item.value));\n const hidden = new Set<string>();\n for (const item of allItems) if (!visible.has(item.value)) hidden.add(item.value);\n return hidden;\n }, [allItems, navigable]);\n const selectedSet = new Set(selectedValues);\n\n // The highlighted value (keyboard, pointer, typeahead, setActiveValue), adjusted during render\n // (C-HOOKS: no effect) and stored once:\n // - reset on close (also a highlight set while closed);\n // - highlightOnFilter: moved to the first option when the navigable set changes (below);\n // - dropped once it is not navigable and enabled any more (filtered out, hidden, removed by an\n // update, disabled), so the option is not highlighted again without a user action when it\n // returns.\n const [activeRaw, setActiveRaw] = useState<string | null>(null);\n let highlighted = open ? activeRaw : null;\n\n // highlightOnFilter: compared by content, not identity — an inline `filter` yields a new array on\n // every render pass (also the pass React repeats after this state update). The set is tracked\n // while closed too, so the keystroke that opens the listbox and filters it in the same update\n // counts as a filter change (compared with the set before opening); opening with an unchanged\n // set (ArrowDown, a click) keeps the autoHighlight start.\n const [filterTrack, setFilterTrack] = useState(() => ({ open, items: navigable }));\n if (highlightOnFilter) {\n const itemsChanged = !sameValues(filterTrack.items, navigable);\n if (itemsChanged || filterTrack.open !== open) {\n setFilterTrack({ open, items: navigable });\n if (open && itemsChanged) highlighted = enabledValues[0] ?? null;\n }\n }\n if (highlighted !== null && !enabledSet.has(highlighted)) highlighted = null;\n if (highlighted !== activeRaw) setActiveRaw(highlighted);\n\n // In list order (APG), not in the order the values were selected.\n const firstSelected = enabledValues.find((value) => selectedSet.has(value)) ?? null;\n let fallback: string | null = null;\n if (autoHighlight === 'selected') fallback = firstSelected ?? enabledValues[0] ?? null;\n else if (autoHighlight === 'first') fallback = enabledValues[0] ?? null;\n const activeValue = open ? (highlighted ?? fallback) : null;\n\n const getOptionId = useCallback(\n (value: string) => `${listboxId}-opt-${store.getIndex(value)}`,\n [listboxId, store],\n );\n const activeDescendantId = activeValue !== null ? getOptionId(activeValue) : undefined;\n const getItem = useCallback((value: string) => itemByValue.get(value), [itemByValue]);\n\n // The value the pointer highlighted, until the scroll effect has seen it: a pointer highlight is\n // not scrolled into view. Every other highlight (keyboard, typeahead, setActiveValue) clears it.\n const pointerHighlightRef = useRef<string | null>(null);\n const setActive = useCallback((value: string | null) => {\n pointerHighlightRef.current = null;\n setActiveRaw(value);\n }, []);\n const setActiveValue = setActive;\n\n const commit = useEventCallback(\n (value: string, reason: 'select' | 'tab', fallbackItem?: ListboxItem): void => {\n const item = itemByValue.get(value) ?? fallbackItem;\n if (!item || item.disabled) return;\n onSelect(value, item);\n if (multiple && reason === 'select') {\n setActive(value);\n } else {\n setActive(null);\n onOpenChange(false, reason);\n }\n },\n );\n\n const select = useEventCallback((value: string, item: ListboxItem) => {\n commit(value, 'select', item);\n });\n\n const highlight = useEventCallback((value: string) => {\n if (!open || !enabledSet.has(value) || value === activeValue) return;\n pointerHighlightRef.current = value;\n setActiveRaw(value);\n });\n\n const { onTypeahead } = useTypeahead({\n getItems: () =>\n navigable.map((item) => ({\n value: item.value,\n text: item.textValue ?? item.label,\n disabled: item.disabled,\n })),\n onMatch: (value) => {\n setActive(value);\n if (!open) onOpenChange(true, 'keyboard');\n },\n });\n\n const onKeyDown = useEventCallback((event: React.KeyboardEvent) => {\n if (event.defaultPrevented || event.nativeEvent.isComposing) return;\n // Editable: a key that edits the text returns visual focus to the textbox (APG) and is left to\n // the input: the highlight is cleared (highlightOnFilter: the first option), so Enter after\n // typing never commits an option highlighted before the edit.\n if (mode === 'editable' && open && editsText(event)) {\n setActive(highlightOnFilter ? (enabledValues[0] ?? null) : null);\n }\n const altGraph = isAltGraphCharacter(event);\n if ((event.ctrlKey && !altGraph) || event.metaKey) return;\n const { key, altKey } = event;\n const selectOnly = mode === 'select-only';\n const first = enabledValues[0] ?? null;\n const last = enabledValues[enabledValues.length - 1] ?? null;\n\n const openWith = (value: string | null) => {\n setActive(value);\n if (!open) onOpenChange(true, 'keyboard');\n };\n const move = (delta: number) => setActive(step(enabledValues, activeValue, delta, loop));\n const commitOrClose = () => {\n if (activeValue !== null) commit(activeValue, 'select');\n else if (!multiple) onOpenChange(false, 'keyboard');\n };\n\n switch (key) {\n case 'ArrowDown':\n event.preventDefault();\n if (altKey) {\n if (!open) onOpenChange(true, 'keyboard');\n } else if (!open) {\n openWith(firstSelected ?? first);\n } else {\n move(1);\n }\n return;\n case 'ArrowUp':\n event.preventDefault();\n if (altKey) {\n if (!open) return;\n if (selectOnly && !multiple && activeValue !== null) commit(activeValue, 'select');\n else onOpenChange(false, 'keyboard');\n } else if (!open) {\n openWith(firstSelected ?? last);\n } else {\n move(-1);\n }\n return;\n case 'Home':\n case 'End':\n if (!selectOnly) return;\n event.preventDefault();\n openWith(key === 'Home' ? first : last);\n return;\n case 'PageUp':\n case 'PageDown':\n if (!selectOnly || !open) return;\n event.preventDefault();\n move(key === 'PageDown' ? 10 : -10);\n return;\n case 'Enter':\n if (!selectOnly) {\n // Closed: not prevented, so the surrounding form submits (APG).\n if (open && activeValue !== null) {\n event.preventDefault();\n commit(activeValue, 'select');\n }\n return;\n }\n event.preventDefault();\n if (!open) onOpenChange(true, 'keyboard');\n else commitOrClose();\n return;\n case 'Escape':\n if (open) {\n event.preventDefault();\n onOpenChange(false, 'escape');\n } else if (!selectOnly && onClearDraft && hasText(event.currentTarget)) {\n event.preventDefault();\n onClearDraft();\n }\n return;\n case 'Tab':\n if (!open) return;\n if (selectOnly && !multiple && activeValue !== null) commit(activeValue, 'tab');\n else onOpenChange(false, 'tab');\n return;\n default:\n break;\n }\n\n if (key === ' ' && !selectOnly) return;\n if (!typeahead || (altKey && !altGraph) || key.length !== 1) {\n if (key === ' ' && selectOnly) {\n event.preventDefault();\n if (!open) onOpenChange(true, 'keyboard');\n else commitOrClose();\n }\n return;\n }\n const current = open ? activeValue : firstSelected;\n if (onTypeahead(event, current)) {\n event.preventDefault();\n return;\n }\n if (key === ' ') {\n // Not part of a typeahead search: Space opens or commits (select-only).\n event.preventDefault();\n if (!open) onOpenChange(true, 'keyboard');\n else commitOrClose();\n return;\n }\n if (selectOnly && !open) {\n event.preventDefault();\n onOpenChange(true, 'keyboard');\n }\n });\n\n const onKeyUp = useEventCallback((event: React.KeyboardEvent) => {\n // A <button> clicks on Space keyup: the keydown already opened or committed.\n if (mode === 'select-only' && event.key === ' ') event.preventDefault();\n });\n\n // Publish the registrations of this commit once, re-check the DOM order when this commit moved\n // options (a keyed reorder moves them without registering them again; a highlight move does not\n // move any), then sync the option selectors.\n useLayoutEffect(() => {\n store.setRegistrationMode(!dataMode);\n store.flush();\n store.checkOrderAfterCommit();\n store.setRenderState(activeValue, selectedSet, hiddenSet);\n });\n\n // While mounted, option moves that render neither this root nor the options (memoized options\n // reordered by a wrapper component) re-check the order through a MutationObserver.\n useLayoutEffect(() => {\n store.connect();\n return () => store.disconnect();\n }, [store]);\n\n // Keep the active option visible in the scrollable listbox — not after a pointer highlight: the\n // option under the pointer is already (at least partly) visible, and scrolling would move the\n // list under the pointer.\n useLayoutEffect(() => {\n const fromPointer = activeValue !== null && activeValue === pointerHighlightRef.current;\n pointerHighlightRef.current = null;\n if (activeValue === null || fromPointer) return;\n const element =\n store.getElement(activeValue) ??\n (typeof document !== 'undefined' ? document.getElementById(getOptionId(activeValue)) : null);\n element?.scrollIntoView?.({ block: 'nearest' });\n }, [activeValue, getOptionId, store]);\n\n useEffect(() => {\n if (!dataItems) return;\n const seen = new Set<string>();\n for (const item of dataItems) {\n if (seen.has(item.value)) warnDuplicateValue(item.value);\n seen.add(item.value);\n }\n }, [dataItems]);\n\n const context = useMemo<ListboxContextValue>(\n () => ({ listboxId, store, select, highlight }),\n [listboxId, store, select, highlight],\n );\n\n return {\n listboxId,\n activeValue,\n activeDescendantId,\n items: navigable,\n getItem,\n getOptionId,\n setActiveValue,\n onKeyDown,\n onKeyUp,\n getComboboxProps: () => {\n const props: ListboxComboboxProps = {\n role: 'combobox',\n 'aria-expanded': open,\n 'aria-controls': listboxId,\n 'aria-haspopup': 'listbox',\n };\n if (activeDescendantId !== undefined) props['aria-activedescendant'] = activeDescendantId;\n if (mode === 'editable') props['aria-autocomplete'] = 'list';\n return props;\n },\n getListboxProps: () => {\n const props: ListboxListProps = {\n id: listboxId,\n role: 'listbox',\n tabIndex: -1,\n onMouseDown: preventMouseDown,\n };\n if (multiple) props['aria-multiselectable'] = true;\n return props;\n },\n context,\n };\n}\n\n/* ------------------------------------------------------------------ */\n/* useListboxOption */\n/* ------------------------------------------------------------------ */\n\nconst FLAG_ACTIVE = 1;\nconst FLAG_SELECTED = 2;\nconst FLAG_HIDDEN = 4;\n\n/** What an option registered last (compared after each commit, see {@link useListboxOption}). */\ninterface OptionRegistration {\n store: ListboxStore;\n item: ListboxItem;\n unregister: () => void;\n}\n\nfunction optionFlags(store: ListboxStore, value: string): number {\n return (\n (store.isActive(value) ? FLAG_ACTIVE : 0) |\n (store.isSelected(value) ? FLAG_SELECTED : 0) |\n (store.isHidden(value) ? FLAG_HIDDEN : 0)\n );\n}\n\n/**\n * An option of the surrounding listbox ({@link ListboxContext}). Registers the option (registration\n * mode) and its element, and reads its flags from the listbox store, so it re-renders only when\n * its own active/selected/hidden state changes. Spread `optionProps` onto the `<li>` (`id`,\n * `role=\"option\"`, `aria-selected`, `aria-disabled`, `hidden`, `data-active`/`data-selected`/\n * `data-disabled` for styling, C-CLASS) and compose its `onClick` with the consumer's.\n *\n * Throws in development when used outside a listbox; in production it logs the error once and\n * renders an inert option (C-CONTEXT).\n *\n * @typeParam E The option element type (`HTMLLIElement` for an `<li>`), so `ref` needs no cast.\n */\nexport function useListboxOption<E extends HTMLElement = HTMLElement>(\n props: UseListboxOptionProps,\n ref?: React.Ref<E>,\n): UseListboxOptionResult<E> {\n const context = useListboxContext('Option');\n const { store, listboxId, select, highlight } = context;\n const { value, label, textValue, disabled = false, hidden: hiddenByConsumer = false } = props;\n\n const id = `${listboxId}-opt-${store.getIndex(value)}`;\n const flags = useSyncExternalStore(\n store.subscribe,\n () => optionFlags(store, value),\n () => optionFlags(store, value),\n );\n const active = (flags & FLAG_ACTIVE) !== 0;\n const selected = (flags & FLAG_SELECTED) !== 0;\n const hidden = hiddenByConsumer || (flags & FLAG_HIDDEN) !== 0;\n\n const elementRef = useRef<E | null>(null);\n const setElement = useCallback((element: E | null) => {\n elementRef.current = element;\n }, []);\n const mergedRef = useMergedRefs<E>(ref, setElement);\n const registrationRef = useRef<OptionRegistration | null>(null);\n\n // After every commit of this option: (re-)register when the item changed — including a label\n // read from the element's text, which any re-render can change. A move (keyed reorder) does not\n // register again; the listbox root sees it through its root commit or its MutationObserver.\n useLayoutEffect(() => {\n const text =\n label === undefined && textValue === undefined\n ? elementRef.current?.textContent?.trim()\n : undefined;\n const item: ListboxItem = { value, label: label ?? textValue ?? (text || value) };\n if (textValue !== undefined) item.textValue = textValue;\n if (disabled) item.disabled = true;\n if (hiddenByConsumer) item.hidden = true;\n const current = registrationRef.current;\n if (current && current.store === store && sameItem(current.item, item)) return;\n current?.unregister();\n registrationRef.current = { store, item, unregister: store.register(item, elementRef) };\n });\n useLayoutEffect(\n () => () => {\n registrationRef.current?.unregister();\n registrationRef.current = null;\n },\n [],\n );\n\n const onClick = useCallback(() => {\n if (disabled) return;\n const item: ListboxItem = { value, label: label ?? textValue ?? value };\n if (textValue !== undefined) item.textValue = textValue;\n select(value, item);\n }, [select, value, label, textValue, disabled]);\n\n const onPointerMove = useCallback(() => {\n if (!disabled && !store.isActive(value)) highlight(value);\n }, [highlight, store, value, disabled]);\n\n const optionProps: ListboxOptionProps<E> = {\n id,\n role: 'option',\n 'aria-selected': selected,\n onClick,\n onPointerMove,\n ref: mergedRef,\n };\n if (disabled) {\n optionProps['aria-disabled'] = true;\n optionProps['data-disabled'] = '';\n }\n if (hidden) optionProps.hidden = true;\n if (active) optionProps['data-active'] = '';\n if (selected) optionProps['data-selected'] = '';\n\n return { id, selected, active, disabled, hidden, optionProps };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";const e=require("../lib/mergeRefs.cjs");let t=require("react");function n(e,t){if(e===t)return!0;if(e.length!==t.length)return!1;for(let n=0;n<e.length;n++)if(e[n]!==t[n])return!1;return!0}function r(e){let t=[];for(let n of e)n&&!t.includes(n)&&t.push(n);return t}function i(t,n){return{ref:t,detach:e.setRef(t,n)??(()=>{e.setRef(t,null)})}}function a(e){let{attached:t}=e;e.attached=[],e.node=null;for(let e of t)e.detach()}function o(...e){let o=(0,t.useRef)({refs:e,node:null,attached:[]});(0,t.useInsertionEffect)(()=>{o.current.refs=e});let s=(0,t.useCallback)(e=>{let t=o.current;if(a(t),e!==null)return t.node=e,t.attached=r(t.refs).map(t=>i(t,e)),()=>{t.node===e&&a(t)}},[]);return(0,t.useLayoutEffect)(()=>{let t=o.current,{node:a}=t;if(a===null)return;let s=r(e);if(n(t.attached.map(e=>e.ref),s))return;let c=new Map;for(let e of t.attached)s.includes(e.ref)?c.set(e.ref,e):e.detach();t.attached=s.map(e=>c.get(e)??i(e,a))}),s}exports.useMergedRefs=o;
|
|
2
|
+
//# sourceMappingURL=useMergedRefs.cjs.map
|