@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 @@
|
|
|
1
|
+
{"version":3,"file":"SearchBox.cjs","names":["Button","slotRendersContent","materialiseSlotContent","hasTextLabel","BUTTON_OWN_PROP_KEYS","renderSlot","placeButtonIcon","isElementOfType","getElementType","resolveSlot","slotWrapsDefaultContent","DismissIcon","React","useControllable","useMergedRefs","useFieldControl","isInvalidLook","observeTextLabel","hasRenderedTextLabel","mergeProps","cn","focusRing","mergedAriaDisabledClasses","inputFocusWithin","composeEventHandlers","SearchIcon","MERGED_DISABLED_FOCUSABLE_PROPS","require_runtime","require_cn","require_children","require_dev","require_slot","require_composeEventHandlers","require_useControllable","require_useMergedRefs","require_useFieldControl","require_styles","require_Button","require_icons","require_mergeProps","require_Button_slots","require_Input","require_useFormReset","require_labelInName","react","react_jsx_runtime","BUTTON_ONLY_KEYS","HANDLER_KEY","NAMING_KEYS","DEFAULT_CLEAR_LABEL","noop","INTERACTIVE_CONTENT","DEFAULT_DISMISS","isButtonType","type","splitButtonLike","hasChildren","children","content","literalTextLabel","buttonProps","key","value","props","iconNode","_children","resolveDismiss","node","dismiss","resolved","Component","contentProps","hasButtonProps","empty","contentChildren","SearchBox","controlledValue","ariaLabel","ariaLabelledBy","ariaDescribedBy","ariaInvalid","ariaRequired","ariaErrorMessage","ariaDetails","rest","onChange","setValue","defaultValue","onValueChange","next","inputRef","mergedInputRef","controlRef","form","fieldProps","invalidLook","dismissParts","dismissKind","handleClear","onClear","handleKeyDown","event","readOnly","disabled","handleRootMouseDown","input","root","target","control","slotOnClick","slotRef","slotButtonProps","hasOwnName","checksContent","labelTarget","setLabelTarget","subscribeToContent","contentHasTextLabel","namedByContent","clearRef","clearButtonProps","clearContent","hasBefore","contentBefore","hasAfter","contentAfter","className","onMouseDown","onKeyDown"],"sources":["../../../src/components/input/SearchBox.tsx"],"sourcesContent":["import * as React from 'react';\nimport { getElementType, isElementOfType } from '../../lib/children';\nimport { cn } from '../../lib/cn';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { warnDeprecated, warnOnce } from '../../lib/dev';\nimport { DismissIcon, SearchIcon } from '../../lib/icons';\nimport { hasRenderedTextLabel, hasTextLabel, observeTextLabel } from '../../lib/labelInName';\nimport { mergeProps } from '../../lib/mergeProps';\nimport {\n materialiseSlotContent,\n renderSlot,\n resolveSlot,\n slotRendersContent,\n slotWrapsDefaultContent,\n} from '../../lib/slot';\nimport { focusRing, inputFocusWithin, inputInvalidWithin } from '../../lib/styles';\nimport type { Slot, SlotObject } from '../../lib/types';\nimport { useControllable } from '../../hooks/useControllable';\nimport { useFieldControl } from '../../hooks/useFieldControl';\nimport { useFormReset } from '../../hooks/useFormReset';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { Button } from '../button/Button';\nimport {\n BUTTON_OWN_PROP_KEYS,\n MERGED_DISABLED_FOCUSABLE_PROPS,\n mergedAriaDisabledClasses,\n placeButtonIcon,\n} from '../button/Button.slots';\nimport { isInvalidLook } from './Input';\n\n/**\n * Props that SearchBox routes to its `<input>` (C-ROUTING): the id, the ARIA naming/validation\n * attributes, native text-input attributes and the focus/keyboard handlers.\n */\nexport type SearchBoxInputProps = Pick<\n React.InputHTMLAttributes<HTMLInputElement>,\n | 'id'\n | 'aria-label'\n | 'aria-labelledby'\n | 'aria-describedby'\n | 'aria-invalid'\n | 'aria-required'\n | 'aria-errormessage'\n | 'aria-details'\n | 'name'\n | 'form'\n | 'required'\n | 'readOnly'\n | 'autoComplete'\n | 'autoFocus'\n | 'autoCapitalize'\n | 'autoCorrect'\n | 'inputMode'\n | 'enterKeyHint'\n | 'spellCheck'\n | 'maxLength'\n | 'minLength'\n | 'pattern'\n | 'tabIndex'\n | 'onFocus'\n | 'onBlur'\n | 'onKeyDown'\n | 'onKeyUp'\n>;\n\n/** Properties for the SearchBox component. */\nexport interface SearchBoxProps\n extends\n Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'onChange' | 'defaultValue' | keyof SearchBoxInputProps\n >,\n SearchBoxInputProps {\n /** Controlled search text value. */\n value?: string;\n /** Initial search text for uncontrolled usage (also what a form reset restores).\n * @default ''\n */\n defaultValue?: string;\n /** Called with the new search text when it changes (typing or clearing). */\n onValueChange?: (value: string) => void;\n /**\n * Called with the new search text when it changes.\n * @deprecated Use `onValueChange`. (`onChange` is reserved for native change events.)\n */\n onChange?: (value: string) => void;\n /**\n * Called when the user clears the search: with the clear button, or with Escape while there is\n * text (after `onValueChange('')`).\n */\n onClear?: () => void;\n /** Placeholder text shown when the input is empty.\n * @default 'Search'\n */\n placeholder?: string;\n /** Whether the search box is disabled and non-interactive. */\n disabled?: boolean;\n /**\n * Slot rendered before the text (replaces the default search icon). It takes the room it needs;\n * the text starts after it. A value that renders nothing (`null`, `false`, `''`, an empty array\n * or Fragment) keeps the default icon.\n */\n contentBefore?: Slot<'span'>;\n /**\n * Slot rendered after the text, before the clear button. It takes the room it needs; the text\n * ends before it. A value that renders nothing (`false`, `''`, an empty array or Fragment) is no\n * slot: nothing takes room.\n */\n contentAfter?: Slot<'span'>;\n /**\n * Content of the clear button (replaces the default dismiss icon). It always renders **inside**\n * the built-in `<button type=\"button\" aria-label=\"Clear search\">`, which clears the value, calls\n * `onClear` and moves focus back to the input. The slot cannot hide the clear button or leave\n * it empty: content that renders nothing (`null`, `false`, `true`, `''`, or an array, `Set`,\n * generator or Fragment of only those) keeps the default icon, and a slot object without\n * children (`{ className: 'text-error' }`) wraps the default icon in its element (not when it\n * brings markup of its own through `dangerouslySetInnerHTML`, or is a void or component element).\n *\n * A `<button>` element or a Wave `Button` passed here is not nested: its props are merged into\n * the built-in button (its `onClick` runs first; `preventDefault()` cancels the clear) and its\n * children become the content, with a development warning. A Wave `Button`'s own props are not\n * attributes: its `icon` becomes decorative content before its children (after them with\n * `iconPosition=\"after\"`), `disabledFocusable` makes the clear button unavailable but focusable\n * as on the Button (nothing is cleared), and `appearance` and `size` are ignored. The 0.4\n * button-object form (`{ as: 'button', onClick, … }` or an object with button props) is\n * **deprecated**: its button props are merged the same way. Pass icon content instead.\n *\n * Name (WCAG 2.5.3 Label in Name): content is decorative (`aria-hidden`), so the button keeps\n * the name \"Clear search\". An `aria-label`, `aria-labelledby` or `title` on the merged button or\n * on a slot object names the button instead (`{ children: 'Reset', 'aria-label': 'Reset' }`).\n * The children of a merged `<button>`/`Button` (or of `{ as: 'button' }`) are rendered as is:\n * when they render a text label (at least two letters or digits outside `aria-hidden`/`hidden`\n * content, text from components such as translations included), that text names the button;\n * an icon or a lone character (`X`, `×`) keeps \"Clear search\". Text hidden only with CSS still\n * counts as the label, so give a button with a responsive label an explicit `aria-label`.\n */\n dismiss?: Slot<'span'> | SlotObject<'button'>;\n /** Ref to the root `<div>`. */\n ref?: React.Ref<HTMLDivElement>;\n /** Ref to the `<input type=\"search\">` (the focusable control). */\n controlRef?: React.Ref<HTMLInputElement>;\n}\n\ntype UnknownProps = Record<string, unknown>;\n\n/** Attributes that only make sense on the clear `<button>` itself (merged onto it). */\nconst BUTTON_ONLY_KEYS: ReadonlySet<string> = new Set([\n 'type',\n 'disabled',\n 'form',\n 'formAction',\n 'formEncType',\n 'formMethod',\n 'formNoValidate',\n 'formTarget',\n 'name',\n 'value',\n 'popoverTarget',\n 'popoverTargetAction',\n]);\nconst HANDLER_KEY = /^on[A-Z]/;\n\n/**\n * Attributes that name the clear button (C-SLOTS naming). On a merged button or a slot object they\n * go to the clear button (slot content is `aria-hidden`), and any of them replaces the default\n * `aria-label`.\n */\nconst NAMING_KEYS: ReadonlySet<string> = new Set(['aria-label', 'aria-labelledby', 'title']);\n\n/** Default name of the clear button. */\nconst DEFAULT_CLEAR_LABEL = 'Clear search';\n\ninterface DismissParts {\n /**\n * `default`: no slot (default icon); `content`: icon content; `element`: a `<button>`/`Button`\n * element; `button-object`: the deprecated button-object form.\n */\n kind: 'default' | 'content' | 'element' | 'button-object';\n /** Props merged onto the built-in clear button. */\n buttonProps: UnknownProps;\n /** Content of the clear button (`null` = the default icon, except for `content`). */\n content: React.ReactNode;\n /**\n * `true` when the content is rendered as is (a merged `<button>`/`Button` or `{ as: 'button' }`),\n * so a text label in it names the button (C-SLOTS naming, WCAG 2.5.3); `false` when the content\n * is decorative (`aria-hidden`).\n */\n contentMayName: boolean;\n /**\n * Whether the literal children contain a text label: the name for the server render and the\n * first client render. After mount the rendered button's text decides.\n */\n literalTextLabel: boolean;\n /**\n * Whether a merged Wave `Button` set `disabledFocusable`: the clear button is then unavailable\n * but focusable, as the Button would be.\n */\n disabledFocusable: boolean;\n}\n\nconst noop = () => {};\n\n/**\n * Elements inside the field that keep a press to themselves: a control in a slot, the clear\n * button.\n */\nconst INTERACTIVE_CONTENT =\n 'a[href], button, input, select, textarea, [tabindex], [contenteditable]:not([contenteditable=\"false\"])';\n\nconst DEFAULT_DISMISS: DismissParts = {\n kind: 'default',\n buttonProps: {},\n content: null,\n contentMayName: false,\n literalTextLabel: false,\n disabledFocusable: false,\n};\n\nfunction isButtonType(type: unknown): boolean {\n return type === 'button' || type === Button;\n}\n\n/**\n * Splits the props of a button-like element or object into button props and content. The content\n * is rendered as is, so a text label in it names the button (C-SLOTS naming). Content that renders\n * nothing is `null` (the default icon); a generator is read once and rendered as its items.\n */\nfunction splitButtonLike(type: unknown, props: UnknownProps, children: React.ReactNode) {\n const hasChildren = slotRendersContent(children);\n const content = materialiseSlotContent(children);\n const literalTextLabel = hasTextLabel(content);\n if (type === Button) {\n // Wave Button's own props do not belong on a native <button>: its icon becomes content (after\n // the children with `iconPosition=\"after\"`) and `disabledFocusable` is applied by the caller.\n const buttonProps: UnknownProps = {};\n for (const [key, value] of Object.entries(props)) {\n if (key !== 'children' && !BUTTON_OWN_PROP_KEYS.has(key)) buttonProps[key] = value;\n }\n const iconNode = renderSlot(props.icon as Slot<'span'>, 'span', 'inline-flex', {\n 'aria-hidden': true,\n });\n const buttonContent =\n iconNode || hasChildren ? placeButtonIcon(iconNode, content, props.iconPosition) : null;\n return {\n buttonProps,\n content: buttonContent,\n contentMayName: true,\n literalTextLabel,\n disabledFocusable: Boolean(props.disabledFocusable),\n };\n }\n const { as, children: _children, ...buttonProps } = props;\n // `null` content falls back to the default icon.\n return {\n buttonProps,\n content: hasChildren ? content : null,\n contentMayName: true,\n literalTextLabel,\n disabledFocusable: false,\n };\n}\n\n/**\n * Splits `dismiss` into the props merged onto the built-in clear button and its content. Content\n * that renders nothing (`slotRendersContent`) never leaves the button empty: without other props\n * it is the default icon; a slot object with its own content props (`className`, `style`, …)\n * wraps the default icon in its element.\n */\nfunction resolveDismiss(dismiss: SearchBoxProps['dismiss']): DismissParts {\n // The type is unwrapped (C-COMPOUND): a Button written in a Server Component arrives as a lazy\n // client reference, and must be merged like a plain one rather than nested inside the clear\n // button. A slot object is never an element, so the check can take any slot value as a node.\n const node = dismiss as React.ReactNode;\n if (isElementOfType<UnknownProps>(node, 'button', Button)) {\n const children = node.props.children as React.ReactNode;\n return {\n kind: 'element',\n ...splitButtonLike(getElementType(node), node.props, children),\n };\n }\n // Resolved once: a generator is materialised (and cached) by resolveSlot, so it can be checked\n // for emptiness and rendered without being consumed twice.\n const resolved = resolveSlot(dismiss as Slot<'span'>, 'span');\n if (!resolved) return DEFAULT_DISMISS;\n const { Component, props, children } = resolved;\n if (isButtonType(Component)) {\n return { kind: 'button-object', ...splitButtonLike(Component, props, children) };\n }\n const buttonProps: UnknownProps = {};\n const contentProps: UnknownProps = {};\n let hasButtonProps = false;\n for (const [key, value] of Object.entries(props)) {\n // resolveSlot sets `className: undefined` when there are no classes.\n if (value === undefined) continue;\n if (BUTTON_ONLY_KEYS.has(key) || HANDLER_KEY.test(key)) {\n buttonProps[key] = value;\n hasButtonProps = true;\n } else if (NAMING_KEYS.has(key)) {\n // The content is aria-hidden, so a naming attribute names the clear button instead (not the\n // deprecated button-object form).\n buttonProps[key] = value;\n } else {\n contentProps[key] = value;\n }\n }\n // A void (`img`), component (`{ as: MyIcon }`) or markup (`dangerouslySetInnerHTML`) slot\n // renders content of its own.\n const hasChildren = slotRendersContent(children);\n const empty = slotWrapsDefaultContent(Component, { ...contentProps, children });\n if (empty && Object.keys(buttonProps).length === 0 && Object.keys(contentProps).length === 0) {\n return DEFAULT_DISMISS;\n }\n // A button object without content (`{ onClick }`, `{ type: 'button' }`) or a content object\n // without children (`{ className }`) keeps the default icon inside the object's own element (its\n // className/style/attributes still apply). Markup of its own takes no children at all.\n const contentChildren = empty ? <DismissIcon /> : hasChildren ? children : undefined;\n const content =\n contentChildren === undefined\n ? React.createElement(Component, { 'aria-hidden': true, ...contentProps })\n : React.createElement(Component, { 'aria-hidden': true, ...contentProps }, contentChildren);\n return {\n kind: hasButtonProps ? 'button-object' : 'content',\n buttonProps,\n content,\n contentMayName: false,\n literalTextLabel: false,\n disabledFocusable: false,\n };\n}\n\n/**\n * A search input with a leading search icon and a clear button that appears while there is text\n * (not while `readOnly`).\n *\n * - **Layout**: the root `<div>` draws the field (its outline, focus and invalid look). The icon\n * (or `contentBefore`), the text, `contentAfter` and the clear button sit side by side in it, so\n * no slot covers the text. Pressing the field outside a control of its own focuses the input.\n * - **Clearing**: the clear button clears the text and moves focus back to the input. Escape\n * clears the text too while there is any, and is then consumed, so an enclosing Dialog, Drawer\n * or Popover stays open; in an empty field Escape reaches them. Both call `onClear`.\n * - **Routing**: `id`, ARIA and native input attributes and the focus/keyboard handlers go to the\n * `<input type=\"search\">` (role `searchbox`); `className`, `style`, `data-*`, other handlers and\n * `ref` stay on the root `<div>` (`controlRef` reaches the input). Inside a `Field` it picks up\n * the label, hint, error and required state automatically.\n * - **Forms**: with `name` the text is submitted with the form; a form reset restores\n * `defaultValue`.\n *\n * @example\n * <SearchBox aria-label=\"Search files\" value={query} onValueChange={setQuery} />\n */\nexport const SearchBox = ({\n value: controlledValue,\n defaultValue = '',\n onValueChange,\n onChange,\n onClear,\n placeholder = 'Search',\n disabled,\n contentBefore,\n contentAfter,\n dismiss,\n className,\n ref,\n controlRef,\n // Routed to the input (C-ROUTING)\n id,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n 'aria-invalid': ariaInvalid,\n 'aria-required': ariaRequired,\n 'aria-errormessage': ariaErrorMessage,\n 'aria-details': ariaDetails,\n required,\n name,\n form,\n readOnly,\n autoComplete,\n autoFocus,\n autoCapitalize,\n autoCorrect,\n inputMode,\n enterKeyHint,\n spellCheck,\n maxLength,\n minLength,\n pattern,\n tabIndex,\n onFocus,\n onBlur,\n onKeyDown,\n onKeyUp,\n onMouseDown,\n hidden,\n ...rest\n}: SearchBoxProps) => {\n if (onChange !== undefined) warnDeprecated('SearchBox', 'onChange', 'onValueChange');\n\n const [value, setValue] = useControllable(controlledValue, defaultValue, (next: string) => {\n onValueChange?.(next);\n onChange?.(next);\n });\n\n const inputRef = React.useRef<HTMLInputElement>(null);\n const mergedInputRef = useMergedRefs(inputRef, controlRef);\n // The input is always React-controlled, so the browser's own reset would put the current text\n // back: restore the default here instead (C-FORMS).\n useFormReset(inputRef, () => setValue(defaultValue), form);\n\n const fieldProps = useFieldControl(\n {\n id,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n 'aria-invalid': ariaInvalid,\n 'aria-required': ariaRequired,\n required,\n },\n { nativeRequired: true },\n );\n const invalidLook = isInvalidLook(false, fieldProps['aria-invalid']);\n\n const dismissParts = resolveDismiss(dismiss);\n const dismissKind = dismissParts.kind;\n React.useEffect(() => {\n if (dismissKind === 'element') {\n warnOnce(\n 'SearchBox:dismiss-button-element',\n 'SearchBox: `dismiss` received a button element; its props were merged into the built-in clear button (buttons cannot be nested). Pass icon content instead, e.g. `dismiss={<MyIcon />}`.',\n );\n } else if (dismissKind === 'button-object') {\n warnOnce(\n 'SearchBox:dismiss-button-object',\n 'SearchBox: `dismiss` with button props (`as: \"button\"`, `onClick`, `type`, …) is deprecated and will be removed in 1.0; the props were merged into the built-in clear button. Pass icon content instead, e.g. `dismiss={<MyIcon />}`.',\n );\n }\n }, [dismissKind]);\n\n const handleClear = () => {\n setValue('');\n onClear?.();\n inputRef.current?.focus();\n };\n\n // Escape clears the text first, as native search fields do, and is consumed so an enclosing\n // Dialog, Drawer or Popover stays open; with an empty field it reaches them (C-POPUPS).\n const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n if (event.key !== 'Escape' || event.nativeEvent.isComposing) return;\n if (!value || readOnly || disabled) return;\n event.preventDefault();\n setValue('');\n onClear?.();\n };\n\n // The whole box is the field: pressing the icon, a slot or the padding around the text focuses\n // the input, as it does in a native search field. A control inside a slot keeps its press.\n const handleRootMouseDown = (event: React.MouseEvent<HTMLDivElement>) => {\n const input = inputRef.current;\n const root = event.currentTarget;\n const target = event.target;\n if (!input || disabled || event.button !== 0 || target === input) return;\n // Events that bubble through React portals from outside this box are not ours (C-COMPOSE).\n if (!(target instanceof Element) || !root.contains(target)) return;\n const control = target.closest(INTERACTIVE_CONTENT);\n if (control && root.contains(control)) return;\n event.preventDefault(); // keeps the press from moving focus to the page\n input.focus();\n };\n\n // The slot's onClick is composed at click time (it runs first; preventDefault() cancels the\n // clear), so handleClear, which reads the input ref, is never passed to a render-time helper.\n // The slot's ref joins ours through a stable merged ref (never a new callback per render).\n const {\n onClick: slotOnClick,\n ref: slotRef,\n ...slotButtonProps\n } = dismissParts.buttonProps as UnknownProps & {\n onClick?: React.MouseEventHandler<HTMLButtonElement>;\n ref?: React.Ref<HTMLButtonElement>;\n };\n\n // C-SLOTS naming (WCAG 2.5.3 Label in Name): a consumer naming attribute names the clear button;\n // otherwise content rendered as is names it when it has a text label, and the default\n // `aria-label` would hide that label. The literal children decide on the server and on the first\n // render; after mount, the rendered button's text does (text from components, later changes).\n const hasOwnName = Object.keys(slotButtonProps).some(\n (key) => NAMING_KEYS.has(key) && slotButtonProps[key] != null,\n );\n const checksContent = dismissParts.contentMayName && !hasOwnName;\n const literalTextLabel = dismissParts.literalTextLabel;\n const [labelTarget, setLabelTarget] = React.useState<HTMLButtonElement | null>(null);\n const subscribeToContent = React.useCallback(\n (onChange: () => void) => (labelTarget ? observeTextLabel(labelTarget, onChange) : noop),\n [labelTarget],\n );\n const contentHasTextLabel = React.useSyncExternalStore(\n subscribeToContent,\n () => (labelTarget ? hasRenderedTextLabel(labelTarget) : literalTextLabel),\n () => literalTextLabel,\n );\n const namedByContent = checksContent && contentHasTextLabel;\n const clearRef = useMergedRefs<HTMLButtonElement>(\n slotRef,\n checksContent ? setLabelTarget : undefined,\n );\n\n const clearButtonProps = mergeProps(\n {\n type: 'button',\n disabled,\n 'aria-label': hasOwnName || namedByContent ? undefined : DEFAULT_CLEAR_LABEL,\n className: cn(\n // Padding and background set here (C-NATIVE): an app-wide `button` rule cannot fill it.\n 'me-1 flex h-6 w-6 shrink-0 items-center justify-center rounded bg-transparent p-0 text-muted-foreground',\n 'not-disabled:not-aria-disabled:hover:text-foreground',\n focusRing,\n 'disabled:cursor-not-allowed',\n mergedAriaDisabledClasses,\n ),\n },\n slotButtonProps,\n ) as React.ComponentPropsWithoutRef<'button'>;\n\n // A merged button with markup of its own (`dangerouslySetInnerHTML`) takes no children.\n const clearContent =\n clearButtonProps.dangerouslySetInnerHTML != null\n ? undefined\n : dismissKind === 'content'\n ? dismissParts.content\n : (dismissParts.content ?? <DismissIcon />);\n // A slot value that renders nothing is no slot (the default icon before the text, no box after).\n const hasBefore = slotRendersContent(contentBefore);\n const hasAfter = slotRendersContent(contentAfter);\n\n return (\n <div\n ref={ref}\n className={cn(\n // The root draws the field; the slots, the text and the clear button are laid out side by\n // side inside it, so a slot never covers the text.\n 'relative inline-flex h-8 w-full items-center rounded border border-input border-b-stroke-accessible bg-background text-body-1 text-foreground',\n inputFocusWithin,\n invalidLook && inputInvalidWithin,\n // The dimmed look lifts while a focus ring shows inside the root (a clear button kept\n // focusable by a merged `disabledFocusable` Button, focusable slot content; the disabled\n // input never takes focus): opacity would dim the ring below 3:1.\n disabled && 'cursor-not-allowed opacity-50 has-focus-visible:opacity-100',\n className,\n )}\n hidden={hidden}\n {...rest}\n // Composed at press time, like the clear button's click: the handler reads the input ref.\n onMouseDown={(event) => composeEventHandlers(onMouseDown, handleRootMouseDown)(event)}\n >\n <span className=\"flex shrink-0 items-center ps-2\">\n {hasBefore ? (\n renderSlot(contentBefore, 'span', 'shrink-0')\n ) : (\n <SearchIcon className=\"text-muted-foreground\" />\n )}\n </span>\n\n <input\n ref={mergedInputRef}\n type=\"search\"\n value={value}\n onChange={(event) => setValue(event.target.value)}\n placeholder={placeholder}\n disabled={disabled}\n className={cn(\n 'h-full min-w-0 flex-1 appearance-none border-none bg-transparent px-2 text-body-1 text-foreground',\n 'placeholder:text-muted-foreground',\n 'focus:outline-hidden',\n 'disabled:cursor-not-allowed',\n '[&::-webkit-search-cancel-button]:hidden',\n )}\n aria-errormessage={ariaErrorMessage}\n aria-details={ariaDetails}\n name={name}\n form={form}\n readOnly={readOnly}\n autoComplete={autoComplete}\n autoFocus={autoFocus}\n autoCapitalize={autoCapitalize}\n autoCorrect={autoCorrect}\n inputMode={inputMode}\n enterKeyHint={enterKeyHint}\n spellCheck={spellCheck}\n maxLength={maxLength}\n minLength={minLength}\n pattern={pattern}\n tabIndex={tabIndex}\n onFocus={onFocus}\n onBlur={onBlur}\n onKeyDown={composeEventHandlers(onKeyDown, handleKeyDown)}\n onKeyUp={onKeyUp}\n {...fieldProps}\n />\n\n {hasAfter && (\n <span className=\"flex shrink-0 items-center pe-2\">\n {renderSlot(contentAfter, 'span', 'shrink-0')}\n </span>\n )}\n\n {/* No clear button while read-only: clearing would change a value the user cannot edit. */}\n {value && !readOnly ? (\n <button\n {...clearButtonProps}\n ref={clearRef}\n // mergeProps keeps a slot's `type: null`, which would drop the attribute and make the\n // button submit its form; only nullish falls back (an explicit type is kept).\n type={clearButtonProps.type ?? 'button'}\n disabled={disabled || clearButtonProps.disabled}\n onClick={(event) => composeEventHandlers(slotOnClick, handleClear)(event)}\n // A merged `disabledFocusable` Button makes the clear button unavailable but focusable\n // (spread last: it wins over `disabled` and the clear handler).\n {...(dismissParts.disabledFocusable ? MERGED_DISABLED_FOCUSABLE_PROPS : undefined)}\n >\n {clearContent}\n </button>\n ) : null}\n </div>\n );\n};\n\nSearchBox.displayName = 'SearchBox';\n"],"mappings":"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"}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn as e } from "../../lib/cn.mjs";
|
|
3
|
+
import { getElementType as t, isElementOfType as n } from "../../lib/children.mjs";
|
|
4
|
+
import { warnDeprecated as r, warnOnce as i } from "../../lib/dev.mjs";
|
|
5
|
+
import { materialiseSlotContent as a, renderSlot as o, resolveSlot as s, slotRendersContent as c, slotWrapsDefaultContent as l } from "../../lib/slot.mjs";
|
|
6
|
+
import { composeEventHandlers as u } from "../../lib/composeEventHandlers.mjs";
|
|
7
|
+
import { useControllable as d } from "../../hooks/useControllable.mjs";
|
|
8
|
+
import { useMergedRefs as f } from "../../hooks/useMergedRefs.mjs";
|
|
9
|
+
import { useFieldControl as p } from "../../hooks/useFieldControl.mjs";
|
|
10
|
+
import { focusRing as m, inputFocusWithin as h } from "../../lib/styles.mjs";
|
|
11
|
+
import { Button as g } from "../button/Button.mjs";
|
|
12
|
+
import { DismissIcon as _, SearchIcon as v } from "../../lib/icons.mjs";
|
|
13
|
+
import { mergeProps as y } from "../../lib/mergeProps.mjs";
|
|
14
|
+
import { BUTTON_OWN_PROP_KEYS as b, MERGED_DISABLED_FOCUSABLE_PROPS as ee, mergedAriaDisabledClasses as te, placeButtonIcon as x } from "../button/Button.slots.mjs";
|
|
15
|
+
import { isInvalidLook as ne } from "./Input.mjs";
|
|
16
|
+
import { useFormReset as re } from "../../hooks/useFormReset.mjs";
|
|
17
|
+
import { hasRenderedTextLabel as ie, hasTextLabel as S, observeTextLabel as ae } from "../../lib/labelInName.mjs";
|
|
18
|
+
import * as C from "react";
|
|
19
|
+
import { jsx as w, jsxs as oe } from "react/jsx-runtime";
|
|
20
|
+
//#region src/components/input/SearchBox.tsx
|
|
21
|
+
var T = /* @__PURE__ */ new Set([
|
|
22
|
+
"type",
|
|
23
|
+
"disabled",
|
|
24
|
+
"form",
|
|
25
|
+
"formAction",
|
|
26
|
+
"formEncType",
|
|
27
|
+
"formMethod",
|
|
28
|
+
"formNoValidate",
|
|
29
|
+
"formTarget",
|
|
30
|
+
"name",
|
|
31
|
+
"value",
|
|
32
|
+
"popoverTarget",
|
|
33
|
+
"popoverTargetAction"
|
|
34
|
+
]), E = /^on[A-Z]/, D = /* @__PURE__ */ new Set([
|
|
35
|
+
"aria-label",
|
|
36
|
+
"aria-labelledby",
|
|
37
|
+
"title"
|
|
38
|
+
]), O = "Clear search", k = () => {}, se = "a[href], button, input, select, textarea, [tabindex], [contenteditable]:not([contenteditable=\"false\"])", A = {
|
|
39
|
+
kind: "default",
|
|
40
|
+
buttonProps: {},
|
|
41
|
+
content: null,
|
|
42
|
+
contentMayName: !1,
|
|
43
|
+
literalTextLabel: !1,
|
|
44
|
+
disabledFocusable: !1
|
|
45
|
+
};
|
|
46
|
+
function j(e) {
|
|
47
|
+
return e === "button" || e === g;
|
|
48
|
+
}
|
|
49
|
+
function M(e, t, n) {
|
|
50
|
+
let r = c(n), i = a(n), s = S(i);
|
|
51
|
+
if (e === g) {
|
|
52
|
+
let e = {};
|
|
53
|
+
for (let [n, r] of Object.entries(t)) n !== "children" && !b.has(n) && (e[n] = r);
|
|
54
|
+
let n = o(t.icon, "span", "inline-flex", { "aria-hidden": !0 });
|
|
55
|
+
return {
|
|
56
|
+
buttonProps: e,
|
|
57
|
+
content: n || r ? x(n, i, t.iconPosition) : null,
|
|
58
|
+
contentMayName: !0,
|
|
59
|
+
literalTextLabel: s,
|
|
60
|
+
disabledFocusable: !!t.disabledFocusable
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
let { as: l, children: u, ...d } = t;
|
|
64
|
+
return {
|
|
65
|
+
buttonProps: d,
|
|
66
|
+
content: r ? i : null,
|
|
67
|
+
contentMayName: !0,
|
|
68
|
+
literalTextLabel: s,
|
|
69
|
+
disabledFocusable: !1
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function ce(e) {
|
|
73
|
+
let r = e;
|
|
74
|
+
if (n(r, "button", g)) {
|
|
75
|
+
let e = r.props.children;
|
|
76
|
+
return {
|
|
77
|
+
kind: "element",
|
|
78
|
+
...M(t(r), r.props, e)
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
let i = s(e, "span");
|
|
82
|
+
if (!i) return A;
|
|
83
|
+
let { Component: a, props: o, children: u } = i;
|
|
84
|
+
if (j(a)) return {
|
|
85
|
+
kind: "button-object",
|
|
86
|
+
...M(a, o, u)
|
|
87
|
+
};
|
|
88
|
+
let d = {}, f = {}, p = !1;
|
|
89
|
+
for (let [e, t] of Object.entries(o)) t !== void 0 && (T.has(e) || E.test(e) ? (d[e] = t, p = !0) : D.has(e) ? d[e] = t : f[e] = t);
|
|
90
|
+
let m = c(u), h = l(a, {
|
|
91
|
+
...f,
|
|
92
|
+
children: u
|
|
93
|
+
});
|
|
94
|
+
if (h && Object.keys(d).length === 0 && Object.keys(f).length === 0) return A;
|
|
95
|
+
let v = h ? /* @__PURE__ */ w(_, {}) : m ? u : void 0, y = v === void 0 ? C.createElement(a, {
|
|
96
|
+
"aria-hidden": !0,
|
|
97
|
+
...f
|
|
98
|
+
}) : C.createElement(a, {
|
|
99
|
+
"aria-hidden": !0,
|
|
100
|
+
...f
|
|
101
|
+
}, v);
|
|
102
|
+
return {
|
|
103
|
+
kind: p ? "button-object" : "content",
|
|
104
|
+
buttonProps: d,
|
|
105
|
+
content: y,
|
|
106
|
+
contentMayName: !1,
|
|
107
|
+
literalTextLabel: !1,
|
|
108
|
+
disabledFocusable: !1
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
var N = ({ value: t, defaultValue: n = "", onValueChange: a, onChange: s, onClear: l, placeholder: g = "Search", disabled: b, contentBefore: x, contentAfter: S, dismiss: T, className: E, ref: A, controlRef: j, id: M, "aria-label": N, "aria-labelledby": le, "aria-describedby": ue, "aria-invalid": de, "aria-required": fe, "aria-errormessage": pe, "aria-details": P, required: F, name: I, form: L, readOnly: R, autoComplete: z, autoFocus: B, autoCapitalize: me, autoCorrect: he, inputMode: ge, enterKeyHint: _e, spellCheck: ve, maxLength: ye, minLength: be, pattern: xe, tabIndex: Se, onFocus: Ce, onBlur: we, onKeyDown: Te, onKeyUp: Ee, onMouseDown: De, hidden: Oe, ...ke }) => {
|
|
112
|
+
s !== void 0 && r("SearchBox", "onChange", "onValueChange");
|
|
113
|
+
let [V, H] = d(t, n, (e) => {
|
|
114
|
+
a?.(e), s?.(e);
|
|
115
|
+
}), U = C.useRef(null), Ae = f(U, j);
|
|
116
|
+
re(U, () => H(n), L);
|
|
117
|
+
let W = p({
|
|
118
|
+
id: M,
|
|
119
|
+
"aria-label": N,
|
|
120
|
+
"aria-labelledby": le,
|
|
121
|
+
"aria-describedby": ue,
|
|
122
|
+
"aria-invalid": de,
|
|
123
|
+
"aria-required": fe,
|
|
124
|
+
required: F
|
|
125
|
+
}, { nativeRequired: !0 }), je = ne(!1, W["aria-invalid"]), G = ce(T), K = G.kind;
|
|
126
|
+
C.useEffect(() => {
|
|
127
|
+
K === "element" ? i("SearchBox:dismiss-button-element", "SearchBox: `dismiss` received a button element; its props were merged into the built-in clear button (buttons cannot be nested). Pass icon content instead, e.g. `dismiss={<MyIcon />}`.") : K === "button-object" && i("SearchBox:dismiss-button-object", "SearchBox: `dismiss` with button props (`as: \"button\"`, `onClick`, `type`, …) is deprecated and will be removed in 1.0; the props were merged into the built-in clear button. Pass icon content instead, e.g. `dismiss={<MyIcon />}`.");
|
|
128
|
+
}, [K]);
|
|
129
|
+
let Me = () => {
|
|
130
|
+
H(""), l?.(), U.current?.focus();
|
|
131
|
+
}, Ne = (e) => {
|
|
132
|
+
e.key !== "Escape" || e.nativeEvent.isComposing || !V || R || b || (e.preventDefault(), H(""), l?.());
|
|
133
|
+
}, Pe = (e) => {
|
|
134
|
+
let t = U.current, n = e.currentTarget, r = e.target;
|
|
135
|
+
if (!t || b || e.button !== 0 || r === t || !(r instanceof Element) || !n.contains(r)) return;
|
|
136
|
+
let i = r.closest(se);
|
|
137
|
+
i && n.contains(i) || (e.preventDefault(), t.focus());
|
|
138
|
+
}, { onClick: Fe, ref: Ie, ...q } = G.buttonProps, J = Object.keys(q).some((e) => D.has(e) && q[e] != null), Y = G.contentMayName && !J, X = G.literalTextLabel, [Z, Le] = C.useState(null), Re = C.useCallback((e) => Z ? ae(Z, e) : k, [Z]), ze = C.useSyncExternalStore(Re, () => Z ? ie(Z) : X, () => X), Be = Y && ze, Q = f(Ie, Y ? Le : void 0), $ = y({
|
|
139
|
+
type: "button",
|
|
140
|
+
disabled: b,
|
|
141
|
+
"aria-label": J || Be ? void 0 : O,
|
|
142
|
+
className: e("me-1 flex h-6 w-6 shrink-0 items-center justify-center rounded bg-transparent p-0 text-muted-foreground", "not-disabled:not-aria-disabled:hover:text-foreground", m, "disabled:cursor-not-allowed", te)
|
|
143
|
+
}, q), Ve = $.dangerouslySetInnerHTML == null ? K === "content" ? G.content : G.content ?? /* @__PURE__ */ w(_, {}) : void 0, He = c(x), Ue = c(S);
|
|
144
|
+
return /* @__PURE__ */ oe("div", {
|
|
145
|
+
ref: A,
|
|
146
|
+
className: e("relative inline-flex h-8 w-full items-center rounded border border-input border-b-stroke-accessible bg-background text-body-1 text-foreground", h, je && "border-destructive focus-within:border-b-destructive", b && "cursor-not-allowed opacity-50 has-focus-visible:opacity-100", E),
|
|
147
|
+
hidden: Oe,
|
|
148
|
+
...ke,
|
|
149
|
+
onMouseDown: (e) => u(De, Pe)(e),
|
|
150
|
+
children: [
|
|
151
|
+
/* @__PURE__ */ w("span", {
|
|
152
|
+
className: "flex shrink-0 items-center ps-2",
|
|
153
|
+
children: He ? o(x, "span", "shrink-0") : /* @__PURE__ */ w(v, { className: "text-muted-foreground" })
|
|
154
|
+
}),
|
|
155
|
+
/* @__PURE__ */ w("input", {
|
|
156
|
+
ref: Ae,
|
|
157
|
+
type: "search",
|
|
158
|
+
value: V,
|
|
159
|
+
onChange: (e) => H(e.target.value),
|
|
160
|
+
placeholder: g,
|
|
161
|
+
disabled: b,
|
|
162
|
+
className: e("h-full min-w-0 flex-1 appearance-none border-none bg-transparent px-2 text-body-1 text-foreground", "placeholder:text-muted-foreground", "focus:outline-hidden", "disabled:cursor-not-allowed", "[&::-webkit-search-cancel-button]:hidden"),
|
|
163
|
+
"aria-errormessage": pe,
|
|
164
|
+
"aria-details": P,
|
|
165
|
+
name: I,
|
|
166
|
+
form: L,
|
|
167
|
+
readOnly: R,
|
|
168
|
+
autoComplete: z,
|
|
169
|
+
autoFocus: B,
|
|
170
|
+
autoCapitalize: me,
|
|
171
|
+
autoCorrect: he,
|
|
172
|
+
inputMode: ge,
|
|
173
|
+
enterKeyHint: _e,
|
|
174
|
+
spellCheck: ve,
|
|
175
|
+
maxLength: ye,
|
|
176
|
+
minLength: be,
|
|
177
|
+
pattern: xe,
|
|
178
|
+
tabIndex: Se,
|
|
179
|
+
onFocus: Ce,
|
|
180
|
+
onBlur: we,
|
|
181
|
+
onKeyDown: u(Te, Ne),
|
|
182
|
+
onKeyUp: Ee,
|
|
183
|
+
...W
|
|
184
|
+
}),
|
|
185
|
+
Ue && /* @__PURE__ */ w("span", {
|
|
186
|
+
className: "flex shrink-0 items-center pe-2",
|
|
187
|
+
children: o(S, "span", "shrink-0")
|
|
188
|
+
}),
|
|
189
|
+
V && !R ? /* @__PURE__ */ w("button", {
|
|
190
|
+
...$,
|
|
191
|
+
ref: Q,
|
|
192
|
+
type: $.type ?? "button",
|
|
193
|
+
disabled: b || $.disabled,
|
|
194
|
+
onClick: (e) => u(Fe, Me)(e),
|
|
195
|
+
...G.disabledFocusable ? ee : void 0,
|
|
196
|
+
children: Ve
|
|
197
|
+
}) : null
|
|
198
|
+
]
|
|
199
|
+
});
|
|
200
|
+
};
|
|
201
|
+
N.displayName = "SearchBox";
|
|
202
|
+
//#endregion
|
|
203
|
+
export { N as SearchBox };
|
|
204
|
+
|
|
205
|
+
//# sourceMappingURL=SearchBox.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SearchBox.mjs","names":["React","BUTTON_ONLY_KEYS","HANDLER_KEY","NAMING_KEYS","DEFAULT_CLEAR_LABEL","noop","INTERACTIVE_CONTENT","DEFAULT_DISMISS","isButtonType","type","Button","splitButtonLike","hasChildren","slotRendersContent","children","content","materialiseSlotContent","literalTextLabel","hasTextLabel","buttonProps","key","value","props","BUTTON_OWN_PROP_KEYS","iconNode","renderSlot","placeButtonIcon","_children","resolveDismiss","node","dismiss","isElementOfType","getElementType","resolved","resolveSlot","Component","contentProps","hasButtonProps","empty","slotWrapsDefaultContent","contentChildren","DismissIcon","SearchBox","controlledValue","ariaLabel","ariaLabelledBy","ariaDescribedBy","ariaInvalid","ariaRequired","ariaErrorMessage","ariaDetails","rest","onChange","warnDeprecated","setValue","useControllable","defaultValue","onValueChange","next","inputRef","mergedInputRef","useMergedRefs","controlRef","form","fieldProps","useFieldControl","invalidLook","isInvalidLook","dismissParts","dismissKind","warnOnce","handleClear","onClear","handleKeyDown","event","readOnly","disabled","handleRootMouseDown","input","root","target","control","slotOnClick","slotRef","slotButtonProps","hasOwnName","checksContent","labelTarget","setLabelTarget","subscribeToContent","observeTextLabel","contentHasTextLabel","hasRenderedTextLabel","namedByContent","clearRef","clearButtonProps","mergeProps","cn","focusRing","mergedAriaDisabledClasses","clearContent","hasBefore","contentBefore","hasAfter","contentAfter","inputFocusWithin","className","composeEventHandlers","onMouseDown","SearchIcon","onKeyDown","MERGED_DISABLED_FOCUSABLE_PROPS"],"sources":["../../../src/components/input/SearchBox.tsx"],"sourcesContent":["import * as React from 'react';\nimport { getElementType, isElementOfType } from '../../lib/children';\nimport { cn } from '../../lib/cn';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { warnDeprecated, warnOnce } from '../../lib/dev';\nimport { DismissIcon, SearchIcon } from '../../lib/icons';\nimport { hasRenderedTextLabel, hasTextLabel, observeTextLabel } from '../../lib/labelInName';\nimport { mergeProps } from '../../lib/mergeProps';\nimport {\n materialiseSlotContent,\n renderSlot,\n resolveSlot,\n slotRendersContent,\n slotWrapsDefaultContent,\n} from '../../lib/slot';\nimport { focusRing, inputFocusWithin, inputInvalidWithin } from '../../lib/styles';\nimport type { Slot, SlotObject } from '../../lib/types';\nimport { useControllable } from '../../hooks/useControllable';\nimport { useFieldControl } from '../../hooks/useFieldControl';\nimport { useFormReset } from '../../hooks/useFormReset';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { Button } from '../button/Button';\nimport {\n BUTTON_OWN_PROP_KEYS,\n MERGED_DISABLED_FOCUSABLE_PROPS,\n mergedAriaDisabledClasses,\n placeButtonIcon,\n} from '../button/Button.slots';\nimport { isInvalidLook } from './Input';\n\n/**\n * Props that SearchBox routes to its `<input>` (C-ROUTING): the id, the ARIA naming/validation\n * attributes, native text-input attributes and the focus/keyboard handlers.\n */\nexport type SearchBoxInputProps = Pick<\n React.InputHTMLAttributes<HTMLInputElement>,\n | 'id'\n | 'aria-label'\n | 'aria-labelledby'\n | 'aria-describedby'\n | 'aria-invalid'\n | 'aria-required'\n | 'aria-errormessage'\n | 'aria-details'\n | 'name'\n | 'form'\n | 'required'\n | 'readOnly'\n | 'autoComplete'\n | 'autoFocus'\n | 'autoCapitalize'\n | 'autoCorrect'\n | 'inputMode'\n | 'enterKeyHint'\n | 'spellCheck'\n | 'maxLength'\n | 'minLength'\n | 'pattern'\n | 'tabIndex'\n | 'onFocus'\n | 'onBlur'\n | 'onKeyDown'\n | 'onKeyUp'\n>;\n\n/** Properties for the SearchBox component. */\nexport interface SearchBoxProps\n extends\n Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'onChange' | 'defaultValue' | keyof SearchBoxInputProps\n >,\n SearchBoxInputProps {\n /** Controlled search text value. */\n value?: string;\n /** Initial search text for uncontrolled usage (also what a form reset restores).\n * @default ''\n */\n defaultValue?: string;\n /** Called with the new search text when it changes (typing or clearing). */\n onValueChange?: (value: string) => void;\n /**\n * Called with the new search text when it changes.\n * @deprecated Use `onValueChange`. (`onChange` is reserved for native change events.)\n */\n onChange?: (value: string) => void;\n /**\n * Called when the user clears the search: with the clear button, or with Escape while there is\n * text (after `onValueChange('')`).\n */\n onClear?: () => void;\n /** Placeholder text shown when the input is empty.\n * @default 'Search'\n */\n placeholder?: string;\n /** Whether the search box is disabled and non-interactive. */\n disabled?: boolean;\n /**\n * Slot rendered before the text (replaces the default search icon). It takes the room it needs;\n * the text starts after it. A value that renders nothing (`null`, `false`, `''`, an empty array\n * or Fragment) keeps the default icon.\n */\n contentBefore?: Slot<'span'>;\n /**\n * Slot rendered after the text, before the clear button. It takes the room it needs; the text\n * ends before it. A value that renders nothing (`false`, `''`, an empty array or Fragment) is no\n * slot: nothing takes room.\n */\n contentAfter?: Slot<'span'>;\n /**\n * Content of the clear button (replaces the default dismiss icon). It always renders **inside**\n * the built-in `<button type=\"button\" aria-label=\"Clear search\">`, which clears the value, calls\n * `onClear` and moves focus back to the input. The slot cannot hide the clear button or leave\n * it empty: content that renders nothing (`null`, `false`, `true`, `''`, or an array, `Set`,\n * generator or Fragment of only those) keeps the default icon, and a slot object without\n * children (`{ className: 'text-error' }`) wraps the default icon in its element (not when it\n * brings markup of its own through `dangerouslySetInnerHTML`, or is a void or component element).\n *\n * A `<button>` element or a Wave `Button` passed here is not nested: its props are merged into\n * the built-in button (its `onClick` runs first; `preventDefault()` cancels the clear) and its\n * children become the content, with a development warning. A Wave `Button`'s own props are not\n * attributes: its `icon` becomes decorative content before its children (after them with\n * `iconPosition=\"after\"`), `disabledFocusable` makes the clear button unavailable but focusable\n * as on the Button (nothing is cleared), and `appearance` and `size` are ignored. The 0.4\n * button-object form (`{ as: 'button', onClick, … }` or an object with button props) is\n * **deprecated**: its button props are merged the same way. Pass icon content instead.\n *\n * Name (WCAG 2.5.3 Label in Name): content is decorative (`aria-hidden`), so the button keeps\n * the name \"Clear search\". An `aria-label`, `aria-labelledby` or `title` on the merged button or\n * on a slot object names the button instead (`{ children: 'Reset', 'aria-label': 'Reset' }`).\n * The children of a merged `<button>`/`Button` (or of `{ as: 'button' }`) are rendered as is:\n * when they render a text label (at least two letters or digits outside `aria-hidden`/`hidden`\n * content, text from components such as translations included), that text names the button;\n * an icon or a lone character (`X`, `×`) keeps \"Clear search\". Text hidden only with CSS still\n * counts as the label, so give a button with a responsive label an explicit `aria-label`.\n */\n dismiss?: Slot<'span'> | SlotObject<'button'>;\n /** Ref to the root `<div>`. */\n ref?: React.Ref<HTMLDivElement>;\n /** Ref to the `<input type=\"search\">` (the focusable control). */\n controlRef?: React.Ref<HTMLInputElement>;\n}\n\ntype UnknownProps = Record<string, unknown>;\n\n/** Attributes that only make sense on the clear `<button>` itself (merged onto it). */\nconst BUTTON_ONLY_KEYS: ReadonlySet<string> = new Set([\n 'type',\n 'disabled',\n 'form',\n 'formAction',\n 'formEncType',\n 'formMethod',\n 'formNoValidate',\n 'formTarget',\n 'name',\n 'value',\n 'popoverTarget',\n 'popoverTargetAction',\n]);\nconst HANDLER_KEY = /^on[A-Z]/;\n\n/**\n * Attributes that name the clear button (C-SLOTS naming). On a merged button or a slot object they\n * go to the clear button (slot content is `aria-hidden`), and any of them replaces the default\n * `aria-label`.\n */\nconst NAMING_KEYS: ReadonlySet<string> = new Set(['aria-label', 'aria-labelledby', 'title']);\n\n/** Default name of the clear button. */\nconst DEFAULT_CLEAR_LABEL = 'Clear search';\n\ninterface DismissParts {\n /**\n * `default`: no slot (default icon); `content`: icon content; `element`: a `<button>`/`Button`\n * element; `button-object`: the deprecated button-object form.\n */\n kind: 'default' | 'content' | 'element' | 'button-object';\n /** Props merged onto the built-in clear button. */\n buttonProps: UnknownProps;\n /** Content of the clear button (`null` = the default icon, except for `content`). */\n content: React.ReactNode;\n /**\n * `true` when the content is rendered as is (a merged `<button>`/`Button` or `{ as: 'button' }`),\n * so a text label in it names the button (C-SLOTS naming, WCAG 2.5.3); `false` when the content\n * is decorative (`aria-hidden`).\n */\n contentMayName: boolean;\n /**\n * Whether the literal children contain a text label: the name for the server render and the\n * first client render. After mount the rendered button's text decides.\n */\n literalTextLabel: boolean;\n /**\n * Whether a merged Wave `Button` set `disabledFocusable`: the clear button is then unavailable\n * but focusable, as the Button would be.\n */\n disabledFocusable: boolean;\n}\n\nconst noop = () => {};\n\n/**\n * Elements inside the field that keep a press to themselves: a control in a slot, the clear\n * button.\n */\nconst INTERACTIVE_CONTENT =\n 'a[href], button, input, select, textarea, [tabindex], [contenteditable]:not([contenteditable=\"false\"])';\n\nconst DEFAULT_DISMISS: DismissParts = {\n kind: 'default',\n buttonProps: {},\n content: null,\n contentMayName: false,\n literalTextLabel: false,\n disabledFocusable: false,\n};\n\nfunction isButtonType(type: unknown): boolean {\n return type === 'button' || type === Button;\n}\n\n/**\n * Splits the props of a button-like element or object into button props and content. The content\n * is rendered as is, so a text label in it names the button (C-SLOTS naming). Content that renders\n * nothing is `null` (the default icon); a generator is read once and rendered as its items.\n */\nfunction splitButtonLike(type: unknown, props: UnknownProps, children: React.ReactNode) {\n const hasChildren = slotRendersContent(children);\n const content = materialiseSlotContent(children);\n const literalTextLabel = hasTextLabel(content);\n if (type === Button) {\n // Wave Button's own props do not belong on a native <button>: its icon becomes content (after\n // the children with `iconPosition=\"after\"`) and `disabledFocusable` is applied by the caller.\n const buttonProps: UnknownProps = {};\n for (const [key, value] of Object.entries(props)) {\n if (key !== 'children' && !BUTTON_OWN_PROP_KEYS.has(key)) buttonProps[key] = value;\n }\n const iconNode = renderSlot(props.icon as Slot<'span'>, 'span', 'inline-flex', {\n 'aria-hidden': true,\n });\n const buttonContent =\n iconNode || hasChildren ? placeButtonIcon(iconNode, content, props.iconPosition) : null;\n return {\n buttonProps,\n content: buttonContent,\n contentMayName: true,\n literalTextLabel,\n disabledFocusable: Boolean(props.disabledFocusable),\n };\n }\n const { as, children: _children, ...buttonProps } = props;\n // `null` content falls back to the default icon.\n return {\n buttonProps,\n content: hasChildren ? content : null,\n contentMayName: true,\n literalTextLabel,\n disabledFocusable: false,\n };\n}\n\n/**\n * Splits `dismiss` into the props merged onto the built-in clear button and its content. Content\n * that renders nothing (`slotRendersContent`) never leaves the button empty: without other props\n * it is the default icon; a slot object with its own content props (`className`, `style`, …)\n * wraps the default icon in its element.\n */\nfunction resolveDismiss(dismiss: SearchBoxProps['dismiss']): DismissParts {\n // The type is unwrapped (C-COMPOUND): a Button written in a Server Component arrives as a lazy\n // client reference, and must be merged like a plain one rather than nested inside the clear\n // button. A slot object is never an element, so the check can take any slot value as a node.\n const node = dismiss as React.ReactNode;\n if (isElementOfType<UnknownProps>(node, 'button', Button)) {\n const children = node.props.children as React.ReactNode;\n return {\n kind: 'element',\n ...splitButtonLike(getElementType(node), node.props, children),\n };\n }\n // Resolved once: a generator is materialised (and cached) by resolveSlot, so it can be checked\n // for emptiness and rendered without being consumed twice.\n const resolved = resolveSlot(dismiss as Slot<'span'>, 'span');\n if (!resolved) return DEFAULT_DISMISS;\n const { Component, props, children } = resolved;\n if (isButtonType(Component)) {\n return { kind: 'button-object', ...splitButtonLike(Component, props, children) };\n }\n const buttonProps: UnknownProps = {};\n const contentProps: UnknownProps = {};\n let hasButtonProps = false;\n for (const [key, value] of Object.entries(props)) {\n // resolveSlot sets `className: undefined` when there are no classes.\n if (value === undefined) continue;\n if (BUTTON_ONLY_KEYS.has(key) || HANDLER_KEY.test(key)) {\n buttonProps[key] = value;\n hasButtonProps = true;\n } else if (NAMING_KEYS.has(key)) {\n // The content is aria-hidden, so a naming attribute names the clear button instead (not the\n // deprecated button-object form).\n buttonProps[key] = value;\n } else {\n contentProps[key] = value;\n }\n }\n // A void (`img`), component (`{ as: MyIcon }`) or markup (`dangerouslySetInnerHTML`) slot\n // renders content of its own.\n const hasChildren = slotRendersContent(children);\n const empty = slotWrapsDefaultContent(Component, { ...contentProps, children });\n if (empty && Object.keys(buttonProps).length === 0 && Object.keys(contentProps).length === 0) {\n return DEFAULT_DISMISS;\n }\n // A button object without content (`{ onClick }`, `{ type: 'button' }`) or a content object\n // without children (`{ className }`) keeps the default icon inside the object's own element (its\n // className/style/attributes still apply). Markup of its own takes no children at all.\n const contentChildren = empty ? <DismissIcon /> : hasChildren ? children : undefined;\n const content =\n contentChildren === undefined\n ? React.createElement(Component, { 'aria-hidden': true, ...contentProps })\n : React.createElement(Component, { 'aria-hidden': true, ...contentProps }, contentChildren);\n return {\n kind: hasButtonProps ? 'button-object' : 'content',\n buttonProps,\n content,\n contentMayName: false,\n literalTextLabel: false,\n disabledFocusable: false,\n };\n}\n\n/**\n * A search input with a leading search icon and a clear button that appears while there is text\n * (not while `readOnly`).\n *\n * - **Layout**: the root `<div>` draws the field (its outline, focus and invalid look). The icon\n * (or `contentBefore`), the text, `contentAfter` and the clear button sit side by side in it, so\n * no slot covers the text. Pressing the field outside a control of its own focuses the input.\n * - **Clearing**: the clear button clears the text and moves focus back to the input. Escape\n * clears the text too while there is any, and is then consumed, so an enclosing Dialog, Drawer\n * or Popover stays open; in an empty field Escape reaches them. Both call `onClear`.\n * - **Routing**: `id`, ARIA and native input attributes and the focus/keyboard handlers go to the\n * `<input type=\"search\">` (role `searchbox`); `className`, `style`, `data-*`, other handlers and\n * `ref` stay on the root `<div>` (`controlRef` reaches the input). Inside a `Field` it picks up\n * the label, hint, error and required state automatically.\n * - **Forms**: with `name` the text is submitted with the form; a form reset restores\n * `defaultValue`.\n *\n * @example\n * <SearchBox aria-label=\"Search files\" value={query} onValueChange={setQuery} />\n */\nexport const SearchBox = ({\n value: controlledValue,\n defaultValue = '',\n onValueChange,\n onChange,\n onClear,\n placeholder = 'Search',\n disabled,\n contentBefore,\n contentAfter,\n dismiss,\n className,\n ref,\n controlRef,\n // Routed to the input (C-ROUTING)\n id,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n 'aria-invalid': ariaInvalid,\n 'aria-required': ariaRequired,\n 'aria-errormessage': ariaErrorMessage,\n 'aria-details': ariaDetails,\n required,\n name,\n form,\n readOnly,\n autoComplete,\n autoFocus,\n autoCapitalize,\n autoCorrect,\n inputMode,\n enterKeyHint,\n spellCheck,\n maxLength,\n minLength,\n pattern,\n tabIndex,\n onFocus,\n onBlur,\n onKeyDown,\n onKeyUp,\n onMouseDown,\n hidden,\n ...rest\n}: SearchBoxProps) => {\n if (onChange !== undefined) warnDeprecated('SearchBox', 'onChange', 'onValueChange');\n\n const [value, setValue] = useControllable(controlledValue, defaultValue, (next: string) => {\n onValueChange?.(next);\n onChange?.(next);\n });\n\n const inputRef = React.useRef<HTMLInputElement>(null);\n const mergedInputRef = useMergedRefs(inputRef, controlRef);\n // The input is always React-controlled, so the browser's own reset would put the current text\n // back: restore the default here instead (C-FORMS).\n useFormReset(inputRef, () => setValue(defaultValue), form);\n\n const fieldProps = useFieldControl(\n {\n id,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n 'aria-invalid': ariaInvalid,\n 'aria-required': ariaRequired,\n required,\n },\n { nativeRequired: true },\n );\n const invalidLook = isInvalidLook(false, fieldProps['aria-invalid']);\n\n const dismissParts = resolveDismiss(dismiss);\n const dismissKind = dismissParts.kind;\n React.useEffect(() => {\n if (dismissKind === 'element') {\n warnOnce(\n 'SearchBox:dismiss-button-element',\n 'SearchBox: `dismiss` received a button element; its props were merged into the built-in clear button (buttons cannot be nested). Pass icon content instead, e.g. `dismiss={<MyIcon />}`.',\n );\n } else if (dismissKind === 'button-object') {\n warnOnce(\n 'SearchBox:dismiss-button-object',\n 'SearchBox: `dismiss` with button props (`as: \"button\"`, `onClick`, `type`, …) is deprecated and will be removed in 1.0; the props were merged into the built-in clear button. Pass icon content instead, e.g. `dismiss={<MyIcon />}`.',\n );\n }\n }, [dismissKind]);\n\n const handleClear = () => {\n setValue('');\n onClear?.();\n inputRef.current?.focus();\n };\n\n // Escape clears the text first, as native search fields do, and is consumed so an enclosing\n // Dialog, Drawer or Popover stays open; with an empty field it reaches them (C-POPUPS).\n const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n if (event.key !== 'Escape' || event.nativeEvent.isComposing) return;\n if (!value || readOnly || disabled) return;\n event.preventDefault();\n setValue('');\n onClear?.();\n };\n\n // The whole box is the field: pressing the icon, a slot or the padding around the text focuses\n // the input, as it does in a native search field. A control inside a slot keeps its press.\n const handleRootMouseDown = (event: React.MouseEvent<HTMLDivElement>) => {\n const input = inputRef.current;\n const root = event.currentTarget;\n const target = event.target;\n if (!input || disabled || event.button !== 0 || target === input) return;\n // Events that bubble through React portals from outside this box are not ours (C-COMPOSE).\n if (!(target instanceof Element) || !root.contains(target)) return;\n const control = target.closest(INTERACTIVE_CONTENT);\n if (control && root.contains(control)) return;\n event.preventDefault(); // keeps the press from moving focus to the page\n input.focus();\n };\n\n // The slot's onClick is composed at click time (it runs first; preventDefault() cancels the\n // clear), so handleClear, which reads the input ref, is never passed to a render-time helper.\n // The slot's ref joins ours through a stable merged ref (never a new callback per render).\n const {\n onClick: slotOnClick,\n ref: slotRef,\n ...slotButtonProps\n } = dismissParts.buttonProps as UnknownProps & {\n onClick?: React.MouseEventHandler<HTMLButtonElement>;\n ref?: React.Ref<HTMLButtonElement>;\n };\n\n // C-SLOTS naming (WCAG 2.5.3 Label in Name): a consumer naming attribute names the clear button;\n // otherwise content rendered as is names it when it has a text label, and the default\n // `aria-label` would hide that label. The literal children decide on the server and on the first\n // render; after mount, the rendered button's text does (text from components, later changes).\n const hasOwnName = Object.keys(slotButtonProps).some(\n (key) => NAMING_KEYS.has(key) && slotButtonProps[key] != null,\n );\n const checksContent = dismissParts.contentMayName && !hasOwnName;\n const literalTextLabel = dismissParts.literalTextLabel;\n const [labelTarget, setLabelTarget] = React.useState<HTMLButtonElement | null>(null);\n const subscribeToContent = React.useCallback(\n (onChange: () => void) => (labelTarget ? observeTextLabel(labelTarget, onChange) : noop),\n [labelTarget],\n );\n const contentHasTextLabel = React.useSyncExternalStore(\n subscribeToContent,\n () => (labelTarget ? hasRenderedTextLabel(labelTarget) : literalTextLabel),\n () => literalTextLabel,\n );\n const namedByContent = checksContent && contentHasTextLabel;\n const clearRef = useMergedRefs<HTMLButtonElement>(\n slotRef,\n checksContent ? setLabelTarget : undefined,\n );\n\n const clearButtonProps = mergeProps(\n {\n type: 'button',\n disabled,\n 'aria-label': hasOwnName || namedByContent ? undefined : DEFAULT_CLEAR_LABEL,\n className: cn(\n // Padding and background set here (C-NATIVE): an app-wide `button` rule cannot fill it.\n 'me-1 flex h-6 w-6 shrink-0 items-center justify-center rounded bg-transparent p-0 text-muted-foreground',\n 'not-disabled:not-aria-disabled:hover:text-foreground',\n focusRing,\n 'disabled:cursor-not-allowed',\n mergedAriaDisabledClasses,\n ),\n },\n slotButtonProps,\n ) as React.ComponentPropsWithoutRef<'button'>;\n\n // A merged button with markup of its own (`dangerouslySetInnerHTML`) takes no children.\n const clearContent =\n clearButtonProps.dangerouslySetInnerHTML != null\n ? undefined\n : dismissKind === 'content'\n ? dismissParts.content\n : (dismissParts.content ?? <DismissIcon />);\n // A slot value that renders nothing is no slot (the default icon before the text, no box after).\n const hasBefore = slotRendersContent(contentBefore);\n const hasAfter = slotRendersContent(contentAfter);\n\n return (\n <div\n ref={ref}\n className={cn(\n // The root draws the field; the slots, the text and the clear button are laid out side by\n // side inside it, so a slot never covers the text.\n 'relative inline-flex h-8 w-full items-center rounded border border-input border-b-stroke-accessible bg-background text-body-1 text-foreground',\n inputFocusWithin,\n invalidLook && inputInvalidWithin,\n // The dimmed look lifts while a focus ring shows inside the root (a clear button kept\n // focusable by a merged `disabledFocusable` Button, focusable slot content; the disabled\n // input never takes focus): opacity would dim the ring below 3:1.\n disabled && 'cursor-not-allowed opacity-50 has-focus-visible:opacity-100',\n className,\n )}\n hidden={hidden}\n {...rest}\n // Composed at press time, like the clear button's click: the handler reads the input ref.\n onMouseDown={(event) => composeEventHandlers(onMouseDown, handleRootMouseDown)(event)}\n >\n <span className=\"flex shrink-0 items-center ps-2\">\n {hasBefore ? (\n renderSlot(contentBefore, 'span', 'shrink-0')\n ) : (\n <SearchIcon className=\"text-muted-foreground\" />\n )}\n </span>\n\n <input\n ref={mergedInputRef}\n type=\"search\"\n value={value}\n onChange={(event) => setValue(event.target.value)}\n placeholder={placeholder}\n disabled={disabled}\n className={cn(\n 'h-full min-w-0 flex-1 appearance-none border-none bg-transparent px-2 text-body-1 text-foreground',\n 'placeholder:text-muted-foreground',\n 'focus:outline-hidden',\n 'disabled:cursor-not-allowed',\n '[&::-webkit-search-cancel-button]:hidden',\n )}\n aria-errormessage={ariaErrorMessage}\n aria-details={ariaDetails}\n name={name}\n form={form}\n readOnly={readOnly}\n autoComplete={autoComplete}\n autoFocus={autoFocus}\n autoCapitalize={autoCapitalize}\n autoCorrect={autoCorrect}\n inputMode={inputMode}\n enterKeyHint={enterKeyHint}\n spellCheck={spellCheck}\n maxLength={maxLength}\n minLength={minLength}\n pattern={pattern}\n tabIndex={tabIndex}\n onFocus={onFocus}\n onBlur={onBlur}\n onKeyDown={composeEventHandlers(onKeyDown, handleKeyDown)}\n onKeyUp={onKeyUp}\n {...fieldProps}\n />\n\n {hasAfter && (\n <span className=\"flex shrink-0 items-center pe-2\">\n {renderSlot(contentAfter, 'span', 'shrink-0')}\n </span>\n )}\n\n {/* No clear button while read-only: clearing would change a value the user cannot edit. */}\n {value && !readOnly ? (\n <button\n {...clearButtonProps}\n ref={clearRef}\n // mergeProps keeps a slot's `type: null`, which would drop the attribute and make the\n // button submit its form; only nullish falls back (an explicit type is kept).\n type={clearButtonProps.type ?? 'button'}\n disabled={disabled || clearButtonProps.disabled}\n onClick={(event) => composeEventHandlers(slotOnClick, handleClear)(event)}\n // A merged `disabledFocusable` Button makes the clear button unavailable but focusable\n // (spread last: it wins over `disabled` and the clear handler).\n {...(dismissParts.disabledFocusable ? MERGED_DISABLED_FOCUSABLE_PROPS : undefined)}\n >\n {clearContent}\n </button>\n ) : null}\n </div>\n );\n};\n\nSearchBox.displayName = 'SearchBox';\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("../../lib/cn.cjs"),n=require("../../lib/aria.cjs"),r=require("../../hooks/useFieldControl.cjs"),i=require("../../lib/styles.cjs"),a=require("./Input.cjs");let o=require("react");o=e.__toESM(o,1);let s=require("react/jsx-runtime");var c=({error:e,errorMessageProps:o,className:c,children:l,ref:u,id:d,"aria-label":f,"aria-labelledby":p,"aria-describedby":m,"aria-invalid":h,"aria-required":g,"aria-errormessage":_,required:v,...y})=>{let{invalid:b,messageId:x,message:S}=a.useControlErrorMessage(e,o,h),C=r.useFieldControl({id:d,"aria-label":f,"aria-labelledby":p,"aria-describedby":n.joinIds(m,x),"aria-invalid":h??(b||void 0),"aria-required":g,required:v},{nativeRequired:!0}),w=a.isInvalidLook(b,C[`aria-invalid`]),T=(0,s.jsx)(`select`,{ref:u,className:t.cn(`h-8 w-full appearance-none rounded border border-input border-b-stroke-accessible bg-background ps-3 pe-8 text-body-1 text-foreground`,`bg-no-repeat bg-[size:5px_5px,5px_5px] bg-[position:right_16px_center,right_11px_center] wave-rtl:bg-[position:left_11px_center,left_16px_center]`,`bg-[image:linear-gradient(45deg,transparent_50%,var(--wave-muted-foreground)_50%),linear-gradient(135deg,var(--wave-muted-foreground)_50%,transparent_50%)]`,`forced-colors:appearance-auto forced-colors:bg-none`,i.inputFocus,`disabled:cursor-not-allowed disabled:opacity-50`,w&&`border-destructive focus:border-b-destructive`,c),...y,...C,"aria-errormessage":n.joinIds(_,x),children:l});return S?(0,s.jsxs)(s.Fragment,{children:[T,S]}):T};c.displayName=`Select`,exports.Select=c;
|
|
2
|
+
//# sourceMappingURL=Select.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Select.cjs","names":["useControlErrorMessage","useFieldControl","joinIds","isInvalidLook","cn","inputFocus","_Fragment","require_runtime","require_cn","require_aria","require_useFieldControl","require_styles","require_Input","react","react_jsx_runtime","Select","ariaLabel","ariaLabelledBy","ariaDescribedBy","ariaInvalid","ariaRequired","ariaErrorMessage","props","error","errorMessageProps","fieldProps","messageId","invalid","invalidLook","control","className","message"],"sources":["../../../src/components/input/Select.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { joinIds } from '../../lib/aria';\nimport { inputFocus, inputInvalid } from '../../lib/styles';\nimport { useFieldControl } from '../../hooks/useFieldControl';\nimport { isInvalidLook, useControlErrorMessage, type InputErrorMessageProps } from './Input';\n\n/** Properties for the Select component. */\nexport interface SelectProps extends React.SelectHTMLAttributes<HTMLSelectElement> {\n /**\n * Validation error.\n * - A non-empty string renders the message in a `role=\"alert\"` element **after** the select\n * (a sibling, so `ref` and `className` stay on the select) and links it through\n * `aria-describedby` and `aria-errormessage`. Inside a `Field` that renders its own `error`,\n * the message is not repeated.\n * - `true` only marks the select invalid (`aria-invalid` and the error border), as in 0.4.\n *\n * The error border also shows whenever the select ends up `aria-invalid=\"true\"` without this\n * prop (an `error` on the surrounding `Field`, or your own `aria-invalid`).\n * Your own `aria-invalid={false}` (or `\"false\"`) wins over this prop: the select is reported\n * valid and shows neither the error border nor the message.\n */\n error?: string | boolean;\n /** Props of the error message element (`id`, `className`, …) rendered for a string `error`. */\n errorMessageProps?: InputErrorMessageProps;\n /** Ref to the `<select>` element. */\n ref?: React.Ref<HTMLSelectElement>;\n}\n\n/**\n * A native `<select>` with Fluent styling: a 1px border with an accessible bottom stroke, a token\n * chevron at the inline end and a primary bottom border while focused. Give it a name with a\n * `Field` label, `aria-label` or `aria-labelledby`. Inside a `Field` it picks up the label, hint,\n * error, `required` (native attribute) and invalid state automatically.\n *\n * @example\n * <Field label=\"Country\" required>\n * <Select defaultValue=\"\">\n * <option value=\"\" disabled>Choose a country</option>\n * <option value=\"no\">Norway</option>\n * </Select>\n * </Field>\n */\nexport const Select = ({\n error,\n errorMessageProps,\n className,\n children,\n ref,\n id,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n 'aria-invalid': ariaInvalid,\n 'aria-required': ariaRequired,\n 'aria-errormessage': ariaErrorMessage,\n required,\n ...props\n}: SelectProps) => {\n const { invalid, messageId, message } = useControlErrorMessage(\n error,\n errorMessageProps,\n ariaInvalid,\n );\n const fieldProps = useFieldControl(\n {\n id,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': joinIds(ariaDescribedBy, messageId),\n 'aria-invalid': ariaInvalid ?? (invalid || undefined),\n 'aria-required': ariaRequired,\n required,\n },\n { nativeRequired: true },\n );\n const invalidLook = isInvalidLook(invalid, fieldProps['aria-invalid']);\n\n const control = (\n <select\n ref={ref}\n className={cn(\n 'h-8 w-full appearance-none rounded border border-input border-b-stroke-accessible bg-background ps-3 pe-8 text-body-1 text-foreground',\n // Chevron: two token-colored gradient halves of a small triangle at the inline end.\n 'bg-no-repeat bg-[size:5px_5px,5px_5px] bg-[position:right_16px_center,right_11px_center] wave-rtl:bg-[position:left_11px_center,left_16px_center]',\n 'bg-[image:linear-gradient(45deg,transparent_50%,var(--wave-muted-foreground)_50%),linear-gradient(135deg,var(--wave-muted-foreground)_50%,transparent_50%)]',\n // Forced colors drop the background chevron: show the native arrow instead.\n 'forced-colors:appearance-auto forced-colors:bg-none',\n inputFocus,\n 'disabled:cursor-not-allowed disabled:opacity-50',\n invalidLook && inputInvalid,\n className,\n )}\n {...props}\n {...fieldProps}\n aria-errormessage={joinIds(ariaErrorMessage, messageId)}\n >\n {children}\n </select>\n );\n\n if (!message) return control;\n return (\n <>\n {control}\n {message}\n </>\n );\n};\n\nSelect.displayName = 'Select';\n"],"mappings":"sTA2CA,IAAae,GAAU,CACrB,QACA,oBACA,YACA,WACA,MACA,KACA,aAAcC,EACd,kBAAmBC,EACnB,mBAAoBC,EACpB,eAAgBC,EAChB,gBAAiBC,EACjB,oBAAqBC,EACrB,WACA,GAAGC,KACc,CACjB,GAAM,CAAE,UAAS,YAAW,WAAYtB,EAAAA,uBACtCuB,EACAC,EACAL,CACF,EACMM,EAAaxB,EAAAA,gBACjB,CACE,KACA,aAAce,EACd,kBAAmBC,EACnB,mBAAoBf,EAAAA,QAAQgB,EAAiBQ,CAAS,EACtD,eAAgBP,IAAgBQ,GAAW,IAAA,IAC3C,gBAAiBP,EACjB,UACF,EACA,CAAE,eAAgB,EAAK,CACzB,EACMQ,EAAczB,EAAAA,cAAcwB,EAASF,EAAW,eAAe,EAE/DI,GACJ,EAAAf,EAAA,IAAA,CAAC,SAAD,CACO,MACL,UAAWV,EAAAA,GACT,wIAEA,oJACA,8JAEA,sDACAC,EAAAA,WACA,kDACAuB,GAAA,gDACAE,CACF,EACA,GAAIR,EACJ,GAAIG,EACJ,oBAAmBvB,EAAAA,QAAQmB,EAAkBK,CAAS,EAErD,UACK,CAAA,EAIV,OADKK,GAEH,EAAAjB,EAAA,KAAA,CAAAR,EAAAA,SAAA,CAAA,SAAA,CACGuB,EACAE,CACD,CAAA,CAAA,EALiBF,CAOvB,EAEA,EAAO,YAAc"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn as e } from "../../lib/cn.mjs";
|
|
3
|
+
import { joinIds as t } from "../../lib/aria.mjs";
|
|
4
|
+
import { useFieldControl as n } from "../../hooks/useFieldControl.mjs";
|
|
5
|
+
import { inputFocus as r } from "../../lib/styles.mjs";
|
|
6
|
+
import { isInvalidLook as i, useControlErrorMessage as a } from "./Input.mjs";
|
|
7
|
+
import "react";
|
|
8
|
+
import { Fragment as o, jsx as s, jsxs as c } from "react/jsx-runtime";
|
|
9
|
+
//#region src/components/input/Select.tsx
|
|
10
|
+
var l = ({ error: l, errorMessageProps: u, className: d, children: f, ref: p, id: m, "aria-label": h, "aria-labelledby": g, "aria-describedby": _, "aria-invalid": v, "aria-required": y, "aria-errormessage": b, required: x, ...S }) => {
|
|
11
|
+
let { invalid: C, messageId: w, message: T } = a(l, u, v), E = n({
|
|
12
|
+
id: m,
|
|
13
|
+
"aria-label": h,
|
|
14
|
+
"aria-labelledby": g,
|
|
15
|
+
"aria-describedby": t(_, w),
|
|
16
|
+
"aria-invalid": v ?? (C || void 0),
|
|
17
|
+
"aria-required": y,
|
|
18
|
+
required: x
|
|
19
|
+
}, { nativeRequired: !0 }), D = i(C, E["aria-invalid"]), O = /* @__PURE__ */ s("select", {
|
|
20
|
+
ref: p,
|
|
21
|
+
className: e("h-8 w-full appearance-none rounded border border-input border-b-stroke-accessible bg-background ps-3 pe-8 text-body-1 text-foreground", "bg-no-repeat bg-[size:5px_5px,5px_5px] bg-[position:right_16px_center,right_11px_center] wave-rtl:bg-[position:left_11px_center,left_16px_center]", "bg-[image:linear-gradient(45deg,transparent_50%,var(--wave-muted-foreground)_50%),linear-gradient(135deg,var(--wave-muted-foreground)_50%,transparent_50%)]", "forced-colors:appearance-auto forced-colors:bg-none", r, "disabled:cursor-not-allowed disabled:opacity-50", D && "border-destructive focus:border-b-destructive", d),
|
|
22
|
+
...S,
|
|
23
|
+
...E,
|
|
24
|
+
"aria-errormessage": t(b, w),
|
|
25
|
+
children: f
|
|
26
|
+
});
|
|
27
|
+
return T ? /* @__PURE__ */ c(o, { children: [O, T] }) : O;
|
|
28
|
+
};
|
|
29
|
+
l.displayName = "Select";
|
|
30
|
+
//#endregion
|
|
31
|
+
export { l as Select };
|
|
32
|
+
|
|
33
|
+
//# sourceMappingURL=Select.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Select.mjs","names":["_Fragment","Select","ariaLabel","ariaLabelledBy","ariaDescribedBy","ariaInvalid","ariaRequired","ariaErrorMessage","props","useControlErrorMessage","error","errorMessageProps","fieldProps","useFieldControl","joinIds","messageId","invalid","invalidLook","isInvalidLook","control","cn","inputFocus","className","message","Fragment"],"sources":["../../../src/components/input/Select.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { joinIds } from '../../lib/aria';\nimport { inputFocus, inputInvalid } from '../../lib/styles';\nimport { useFieldControl } from '../../hooks/useFieldControl';\nimport { isInvalidLook, useControlErrorMessage, type InputErrorMessageProps } from './Input';\n\n/** Properties for the Select component. */\nexport interface SelectProps extends React.SelectHTMLAttributes<HTMLSelectElement> {\n /**\n * Validation error.\n * - A non-empty string renders the message in a `role=\"alert\"` element **after** the select\n * (a sibling, so `ref` and `className` stay on the select) and links it through\n * `aria-describedby` and `aria-errormessage`. Inside a `Field` that renders its own `error`,\n * the message is not repeated.\n * - `true` only marks the select invalid (`aria-invalid` and the error border), as in 0.4.\n *\n * The error border also shows whenever the select ends up `aria-invalid=\"true\"` without this\n * prop (an `error` on the surrounding `Field`, or your own `aria-invalid`).\n * Your own `aria-invalid={false}` (or `\"false\"`) wins over this prop: the select is reported\n * valid and shows neither the error border nor the message.\n */\n error?: string | boolean;\n /** Props of the error message element (`id`, `className`, …) rendered for a string `error`. */\n errorMessageProps?: InputErrorMessageProps;\n /** Ref to the `<select>` element. */\n ref?: React.Ref<HTMLSelectElement>;\n}\n\n/**\n * A native `<select>` with Fluent styling: a 1px border with an accessible bottom stroke, a token\n * chevron at the inline end and a primary bottom border while focused. Give it a name with a\n * `Field` label, `aria-label` or `aria-labelledby`. Inside a `Field` it picks up the label, hint,\n * error, `required` (native attribute) and invalid state automatically.\n *\n * @example\n * <Field label=\"Country\" required>\n * <Select defaultValue=\"\">\n * <option value=\"\" disabled>Choose a country</option>\n * <option value=\"no\">Norway</option>\n * </Select>\n * </Field>\n */\nexport const Select = ({\n error,\n errorMessageProps,\n className,\n children,\n ref,\n id,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n 'aria-invalid': ariaInvalid,\n 'aria-required': ariaRequired,\n 'aria-errormessage': ariaErrorMessage,\n required,\n ...props\n}: SelectProps) => {\n const { invalid, messageId, message } = useControlErrorMessage(\n error,\n errorMessageProps,\n ariaInvalid,\n );\n const fieldProps = useFieldControl(\n {\n id,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': joinIds(ariaDescribedBy, messageId),\n 'aria-invalid': ariaInvalid ?? (invalid || undefined),\n 'aria-required': ariaRequired,\n required,\n },\n { nativeRequired: true },\n );\n const invalidLook = isInvalidLook(invalid, fieldProps['aria-invalid']);\n\n const control = (\n <select\n ref={ref}\n className={cn(\n 'h-8 w-full appearance-none rounded border border-input border-b-stroke-accessible bg-background ps-3 pe-8 text-body-1 text-foreground',\n // Chevron: two token-colored gradient halves of a small triangle at the inline end.\n 'bg-no-repeat bg-[size:5px_5px,5px_5px] bg-[position:right_16px_center,right_11px_center] wave-rtl:bg-[position:left_11px_center,left_16px_center]',\n 'bg-[image:linear-gradient(45deg,transparent_50%,var(--wave-muted-foreground)_50%),linear-gradient(135deg,var(--wave-muted-foreground)_50%,transparent_50%)]',\n // Forced colors drop the background chevron: show the native arrow instead.\n 'forced-colors:appearance-auto forced-colors:bg-none',\n inputFocus,\n 'disabled:cursor-not-allowed disabled:opacity-50',\n invalidLook && inputInvalid,\n className,\n )}\n {...props}\n {...fieldProps}\n aria-errormessage={joinIds(ariaErrorMessage, messageId)}\n >\n {children}\n </select>\n );\n\n if (!message) return control;\n return (\n <>\n {control}\n {message}\n </>\n );\n};\n\nSelect.displayName = 'Select';\n"],"mappings":";;;;;;;;;AA2CA,IAAaC,KAAU,EACrB,UACA,sBACA,cACA,aACA,QACA,OACA,cAAcC,GACd,mBAAmBC,GACnB,oBAAoBC,GACpB,gBAAgBC,GAChB,iBAAiBC,GACjB,qBAAqBC,GACrB,aACA,GAAGC,QACc;CACjB,IAAM,EAAE,YAAS,cAAW,eAAYC,EACtCC,GACAC,GACAN,CACF,GACMO,IAAaC,EACjB;EACE;EACA,cAAcX;EACd,mBAAmBC;EACnB,oBAAoBW,EAAQV,GAAiBW,CAAS;EACtD,gBAAgBV,MAAgBW,KAAW,KAAA;EAC3C,iBAAiBV;EACjB;CACF,GACA,EAAE,gBAAgB,GAAK,CACzB,GACMW,IAAcC,EAAcF,GAASJ,EAAW,eAAe,GAE/DO,IACJ,kBAAC,UAAD;EACO;EACL,WAAWC,EACT,yIAEA,qJACA,+JAEA,uDACAC,GACA,mDACAJ,KAAA,iDACAK,CACF;EACA,GAAId;EACJ,GAAII;EACJ,qBAAmBE,EAAQP,GAAkBQ,CAAS;EAErD;CACK,CAAA;CAIV,OADKQ,IAEH,kBAAAvB,GAAA,EAAA,UAAA,CACGmB,GACAI,CACD,EAAA,CAAA,IALiBJ;AAOvB;AAEA,EAAO,cAAc"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("../../lib/cn.cjs"),n=require("../../lib/composeEventHandlers.cjs"),r=require("../../hooks/useEventCallback.cjs"),i=require("../../hooks/useMergedRefs.cjs"),a=require("../../hooks/useFieldControl.cjs"),o=require("../../lib/styles.cjs"),s=require("../../hooks/useFormReset.cjs");let c=require("react");c=e.__toESM(c,1);let l=require("react/jsx-runtime");var u=`--wave-slider-progress`;function d(e,t,n){let r=n>t?(e-t)/(n-t)*100:0;return`${Number.isFinite(r)?Math.min(100,Math.max(0,r)):0}%`}var f=[`[&::-webkit-slider-runnable-track]:h-1 [&::-webkit-slider-runnable-track]:rounded-full [&::-webkit-slider-runnable-track]:bg-stroke-accessible`,`[&::-webkit-slider-runnable-track]:bg-[linear-gradient(to_right,var(--wave-primary)_var(--wave-slider-progress),var(--wave-stroke-accessible)_var(--wave-slider-progress))]`,`wave-rtl:[&::-webkit-slider-runnable-track]:bg-[linear-gradient(to_left,var(--wave-primary)_var(--wave-slider-progress),var(--wave-stroke-accessible)_var(--wave-slider-progress))]`,`[&::-moz-range-track]:h-1 [&::-moz-range-track]:rounded-full [&::-moz-range-track]:bg-stroke-accessible`,`[&::-moz-range-progress]:h-1 [&::-moz-range-progress]:rounded-full [&::-moz-range-progress]:bg-primary`],p=[`forced-colors:[&::-webkit-slider-runnable-track]:bg-[linear-gradient(to_right,Highlight_var(--wave-slider-progress),CanvasText_var(--wave-slider-progress))]`,`forced-colors:wave-rtl:[&::-webkit-slider-runnable-track]:bg-[linear-gradient(to_left,Highlight_var(--wave-slider-progress),CanvasText_var(--wave-slider-progress))]`,`forced-colors:[&::-moz-range-progress]:bg-[Highlight]`,`forced-colors:disabled:[&::-webkit-slider-runnable-track]:bg-none forced-colors:disabled:[&::-moz-range-progress]:bg-[GrayText]`],m=({className:e,style:m,label:h,value:g,defaultValue:_,min:v,max:y,step:b,form:x,onChange:S,onValueChange:C,ref:w,id:T,"aria-label":E,"aria-labelledby":D,"aria-describedby":O,"aria-invalid":k,"aria-required":A,required:j,...M})=>{let N=a.useFieldControl({id:T,"aria-label":E??h,"aria-labelledby":D,"aria-describedby":O,"aria-invalid":k,"aria-required":A,required:j},{nativeRequired:!0}),P=c.useRef(null),F=i.useMergedRefs(P,w),I=v??0,L=y??100,R=d(g??_??I+(L-I)/2,I,L),z=r.useEventCallback(()=>{let e=P.current;if(!e)return;let t=d(Number(e.value),I,L);e.style.getPropertyValue(u)!==t&&e.style.setProperty(u,t)});c.useLayoutEffect(()=>{z()},[g,_,v,y,b,z]),s.useFormReset(P,()=>queueMicrotask(z),x);let B=n.composeEventHandlers(S,e=>{g===void 0&&z(),C?.(Number(e.currentTarget.value))},{checkDefaultPrevented:!1});return(0,l.jsx)(`input`,{ref:F,type:`range`,className:t.cn(`w-full cursor-pointer appearance-none bg-transparent`,f,`[&::-webkit-slider-thumb]:-mt-2 [&::-webkit-slider-thumb]:h-5 [&::-webkit-slider-thumb]:w-5 [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-background [&::-webkit-slider-thumb]:bg-primary [&::-webkit-slider-thumb]:shadow`,`[&::-moz-range-thumb]:h-5 [&::-moz-range-thumb]:w-5 [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-background [&::-moz-range-thumb]:bg-primary [&::-moz-range-thumb]:shadow`,`disabled:cursor-not-allowed disabled:opacity-50`,o.focusRing,o.forcedColors.rangeInput,p,e),style:{...m,[u]:R},value:g,defaultValue:_,min:v,max:y,step:b,form:x,...M,...N,onChange:B})};m.displayName=`Slider`,exports.Slider=m;
|
|
2
|
+
//# sourceMappingURL=Slider.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Slider.cjs","names":["useFieldControl","React","useMergedRefs","useEventCallback","composeEventHandlers","cn","focusRing","forcedColors","require_runtime","require_cn","require_composeEventHandlers","require_useEventCallback","require_useMergedRefs","require_useFieldControl","require_styles","require_useFormReset","react","react_jsx_runtime","PROGRESS_VAR","progressPercent","share","max","min","value","railClasses","forcedColorsFill","Slider","ariaLabel","ariaLabelledBy","ariaDescribedBy","ariaInvalid","ariaRequired","props","fieldProps","label","inputRef","mergedRef","ref","rangeMin","rangeMax","renderedProgress","defaultValue","updateFill","input","next","step","form","handleChange","onChange","onValueChange","event","className","style"],"sources":["../../../src/components/input/Slider.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { focusRing, forcedColors } from '../../lib/styles';\nimport { useEventCallback } from '../../hooks/useEventCallback';\nimport { useFieldControl } from '../../hooks/useFieldControl';\nimport { useFormReset } from '../../hooks/useFormReset';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\n\n/** Properties for the Slider component. */\nexport interface SliderProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'type'> {\n /** Controlled slider value. */\n value?: number;\n /** Initial value for uncontrolled usage. */\n defaultValue?: number;\n /** Native change event handler (`event.target.value` is a string). */\n onChange?: React.ChangeEventHandler<HTMLInputElement>;\n /** Called with the new value as a number on every change, next to the native `onChange`. */\n onValueChange?: (value: number) => void;\n /** Minimum allowed value. */\n min?: number;\n /** Maximum allowed value. */\n max?: number;\n /** Step increment between values. */\n step?: number;\n /**\n * Accessible label for the slider (sets `aria-label`; an explicit `aria-label` wins). Inside a\n * `Field`, leave it out so the Field's label names the slider.\n */\n label?: string;\n /** Ref to the `<input type=\"range\">` element. */\n ref?: React.Ref<HTMLInputElement>;\n}\n\n/** The CSS variable that holds how much of the rail the fill covers (`<p>%`). */\nconst PROGRESS_VAR = '--wave-slider-progress';\n\n/** The share of the rail up to `value`, as a CSS percentage: 0–100, and 0 when `max <= min`. */\nfunction progressPercent(value: number, min: number, max: number): string {\n const share = max > min ? ((value - min) / (max - min)) * 100 : 0;\n return `${Number.isFinite(share) ? Math.min(100, Math.max(0, share)) : 0}%`;\n}\n\n/**\n * The rail: the primary fill up to the thumb, the accessible stroke after it. WebKit and Blink\n * draw it as a gradient on the track (mirrored for right-to-left); Firefox has a progress part and\n * mirrors it itself. The track color stays underneath (the whole rail without the variable).\n */\nconst railClasses = [\n // The rail color gives the rail itself 3:1 non-text contrast.\n '[&::-webkit-slider-runnable-track]:h-1 [&::-webkit-slider-runnable-track]:rounded-full [&::-webkit-slider-runnable-track]:bg-stroke-accessible',\n '[&::-webkit-slider-runnable-track]:bg-[linear-gradient(to_right,var(--wave-primary)_var(--wave-slider-progress),var(--wave-stroke-accessible)_var(--wave-slider-progress))]',\n 'wave-rtl:[&::-webkit-slider-runnable-track]:bg-[linear-gradient(to_left,var(--wave-primary)_var(--wave-slider-progress),var(--wave-stroke-accessible)_var(--wave-slider-progress))]',\n '[&::-moz-range-track]:h-1 [&::-moz-range-track]:rounded-full [&::-moz-range-track]:bg-stroke-accessible',\n '[&::-moz-range-progress]:h-1 [&::-moz-range-progress]:rounded-full [&::-moz-range-progress]:bg-primary',\n];\n\n/**\n * Forced colors, after `forcedColors.rangeInput` (which draws the whole rail in CanvasText): the\n * filled part in Highlight; a disabled rail stays GrayText, without the fill.\n */\nconst forcedColorsFill = [\n 'forced-colors:[&::-webkit-slider-runnable-track]:bg-[linear-gradient(to_right,Highlight_var(--wave-slider-progress),CanvasText_var(--wave-slider-progress))]',\n 'forced-colors:wave-rtl:[&::-webkit-slider-runnable-track]:bg-[linear-gradient(to_left,Highlight_var(--wave-slider-progress),CanvasText_var(--wave-slider-progress))]',\n 'forced-colors:[&::-moz-range-progress]:bg-[Highlight]',\n 'forced-colors:disabled:[&::-webkit-slider-runnable-track]:bg-none forced-colors:disabled:[&::-moz-range-progress]:bg-[GrayText]',\n];\n\n/**\n * A native range input with Fluent styling: a rail drawn in the accessible stroke color (3:1\n * against the page), filled in the primary color up to a primary thumb; in forced-colors mode the\n * rail, fill and thumb are drawn in system colors. Inside a `Field` it picks up the label, hint,\n * validation message, `required` and invalid state automatically.\n *\n * The fill follows the value through the `--wave-slider-progress` variable on the input (also in\n * the server HTML), including the browser's snapping to `step` and a form reset.\n *\n * @example\n * <Slider label=\"Volume\" min={0} max={100} value={volume} onValueChange={setVolume} />\n */\nexport const Slider = ({\n className,\n style,\n label,\n value,\n defaultValue,\n min,\n max,\n step,\n form,\n onChange,\n onValueChange,\n ref,\n id,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n 'aria-invalid': ariaInvalid,\n 'aria-required': ariaRequired,\n required,\n ...props\n}: SliderProps) => {\n const fieldProps = useFieldControl(\n {\n id,\n 'aria-label': ariaLabel ?? label,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n 'aria-invalid': ariaInvalid,\n 'aria-required': ariaRequired,\n required,\n },\n { nativeRequired: true },\n );\n\n const inputRef = React.useRef<HTMLInputElement>(null);\n const mergedRef = useMergedRefs(inputRef, ref);\n const rangeMin = min ?? 0;\n const rangeMax = max ?? 100;\n // During render (and on the server): the value, else the default, else the native midpoint.\n const renderedProgress = progressPercent(\n value ?? defaultValue ?? rangeMin + (rangeMax - rangeMin) / 2,\n rangeMin,\n rangeMax,\n );\n\n /** Writes the fill of the value the input really has (the browser snaps it to `step`). */\n const updateFill = useEventCallback(() => {\n const input = inputRef.current;\n if (!input) return;\n const next = progressPercent(Number(input.value), rangeMin, rangeMax);\n if (input.style.getPropertyValue(PROGRESS_VAR) !== next) {\n input.style.setProperty(PROGRESS_VAR, next);\n }\n });\n\n // On mount and whenever the value or its range changes: React wrote the variable from the props,\n // the input may hold another value (step snapping, an uncontrolled value the user moved).\n React.useLayoutEffect(() => {\n updateFill();\n }, [value, defaultValue, min, max, step, updateFill]);\n\n // The reset event fires before the form restores the value: read it a microtask later.\n useFormReset(inputRef, () => queueMicrotask(updateFill), form);\n\n const handleChange = composeEventHandlers(\n onChange,\n (event: React.ChangeEvent<HTMLInputElement>) => {\n // A controlled fill follows `value` (a parent that rejects the change keeps it).\n if (value === undefined) updateFill();\n onValueChange?.(Number(event.currentTarget.value));\n },\n { checkDefaultPrevented: false },\n );\n\n return (\n <input\n ref={mergedRef}\n type=\"range\"\n className={cn(\n 'w-full cursor-pointer appearance-none bg-transparent',\n railClasses,\n // Thumb. WebKit and Blink align its top with the rail's top, so it is pulled up by half the\n // difference of the two heights (5 and 1 spacing units): it stays centred at any root\n // font size.\n '[&::-webkit-slider-thumb]:-mt-2 [&::-webkit-slider-thumb]:h-5 [&::-webkit-slider-thumb]:w-5 [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-background [&::-webkit-slider-thumb]:bg-primary [&::-webkit-slider-thumb]:shadow',\n // Firefox thumb\n '[&::-moz-range-thumb]:h-5 [&::-moz-range-thumb]:w-5 [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-background [&::-moz-range-thumb]:bg-primary [&::-moz-range-thumb]:shadow',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n focusRing,\n // Forced colors replace the author backgrounds of the rail and thumb with Canvas: give\n // every part a system color instead.\n forcedColors.rangeInput,\n forcedColorsFill,\n className,\n )}\n style={{ ...style, [PROGRESS_VAR]: renderedProgress } as React.CSSProperties}\n value={value}\n defaultValue={defaultValue}\n min={min}\n max={max}\n step={step}\n form={form}\n {...props}\n {...fieldProps}\n onChange={handleChange}\n />\n );\n};\n\nSlider.displayName = 'Slider';\n"],"mappings":"gbAmCA,IAAMkB,EAAe,yBAGrB,SAASC,EAAgB,EAAe,EAAa,EAAqB,CACxE,IAAMC,EAAQC,EAAMC,GAAQC,EAAQD,IAAQD,EAAMC,GAAQ,IAAM,EAChE,MAAO,GAAG,OAAO,SAASF,CAAK,EAAI,KAAK,IAAI,IAAK,KAAK,IAAI,EAAGA,CAAK,CAAC,EAAI,EAAE,EAC3E,CAOA,IAAMI,EAAc,CAElB,iJACA,8KACA,sLACA,0GACA,wGACF,EAMMC,EAAmB,CACvB,+JACA,uKACA,wDACA,iIACF,EAcaC,GAAU,CACrB,YACA,QACA,QACA,QACA,eACA,MACA,MACA,OACA,OACA,WACA,gBACA,MACA,KACA,aAAcC,EACd,kBAAmBC,EACnB,mBAAoBC,EACpB,eAAgBC,EAChB,gBAAiBC,EACjB,WACA,GAAGC,KACc,CACjB,IAAMC,EAAajC,EAAAA,gBACjB,CACE,KACA,aAAc2B,GAAaO,EAC3B,kBAAmBN,EACnB,mBAAoBC,EACpB,eAAgBC,EAChB,gBAAiBC,EACjB,UACF,EACA,CAAE,eAAgB,EAAK,CACzB,EAEMI,EAAWlC,EAAM,OAAyB,IAAI,EAC9CmC,EAAYlC,EAAAA,cAAciC,EAAUE,CAAG,EACvCC,EAAWhB,GAAO,EAClBiB,EAAWlB,GAAO,IAElBmB,EAAmBrB,EACvBI,GAASkB,GAAgBH,GAAYC,EAAWD,GAAY,EAC5DA,EACAC,CACF,EAGMG,EAAavC,EAAAA,qBAAuB,CACxC,IAAMwC,EAAQR,EAAS,QACvB,GAAI,CAACQ,EAAO,OACZ,IAAMC,EAAOzB,EAAgB,OAAOwB,EAAM,KAAK,EAAGL,EAAUC,CAAQ,EAChEI,EAAM,MAAM,iBAAiBzB,CAAY,IAAM0B,GACjDD,EAAM,MAAM,YAAYzB,EAAc0B,CAAI,CAE9C,CAAC,EAID5B,EAAM,oBAAsB,CAC1B0B,EAAW,CACb,EAAG,CAACnB,EAAOkB,EAAcnB,EAAKD,EAAKwB,EAAMH,CAAU,CAAC,EAGpD3B,EAAA,aAAaoB,MAAgB,eAAeO,CAAU,EAAGI,CAAI,EAE7D,IAAMC,EAAe3C,EAAAA,qBACnB4C,EACC,GAA+C,CAE1CzB,IAAU,IAAA,IAAWmB,EAAW,EACpCO,IAAgB,OAAOC,EAAM,cAAc,KAAK,CAAC,CACnD,EACA,CAAE,sBAAuB,EAAM,CACjC,EAEA,OACE,EAAAjC,EAAA,IAAA,CAAC,QAAD,CACE,IAAKmB,EACL,KAAK,QACL,UAAW/B,EAAAA,GACT,uDACAmB,EAIA,oUAEA,8NACA,kDACAlB,EAAAA,UAGAC,EAAAA,aAAa,WACbkB,EACA0B,CACF,EACA,MAAO,CAAE,GAAGC,GAAQlC,GAAesB,CAAiB,EAC7C,QACO,eACT,MACA,MACC,OACA,OACN,GAAIR,EACJ,GAAIC,EACJ,SAAUc,CACX,CAAA,CAEL,EAEA,EAAO,YAAc"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn as e } from "../../lib/cn.mjs";
|
|
3
|
+
import { composeEventHandlers as t } from "../../lib/composeEventHandlers.mjs";
|
|
4
|
+
import { useEventCallback as n } from "../../hooks/useEventCallback.mjs";
|
|
5
|
+
import { useMergedRefs as r } from "../../hooks/useMergedRefs.mjs";
|
|
6
|
+
import { useFieldControl as i } from "../../hooks/useFieldControl.mjs";
|
|
7
|
+
import { focusRing as a, forcedColors as o } from "../../lib/styles.mjs";
|
|
8
|
+
import { useFormReset as s } from "../../hooks/useFormReset.mjs";
|
|
9
|
+
import * as c from "react";
|
|
10
|
+
import { jsx as l } from "react/jsx-runtime";
|
|
11
|
+
//#region src/components/input/Slider.tsx
|
|
12
|
+
var u = "--wave-slider-progress";
|
|
13
|
+
function d(e, t, n) {
|
|
14
|
+
let r = n > t ? (e - t) / (n - t) * 100 : 0;
|
|
15
|
+
return `${Number.isFinite(r) ? Math.min(100, Math.max(0, r)) : 0}%`;
|
|
16
|
+
}
|
|
17
|
+
var f = [
|
|
18
|
+
"[&::-webkit-slider-runnable-track]:h-1 [&::-webkit-slider-runnable-track]:rounded-full [&::-webkit-slider-runnable-track]:bg-stroke-accessible",
|
|
19
|
+
"[&::-webkit-slider-runnable-track]:bg-[linear-gradient(to_right,var(--wave-primary)_var(--wave-slider-progress),var(--wave-stroke-accessible)_var(--wave-slider-progress))]",
|
|
20
|
+
"wave-rtl:[&::-webkit-slider-runnable-track]:bg-[linear-gradient(to_left,var(--wave-primary)_var(--wave-slider-progress),var(--wave-stroke-accessible)_var(--wave-slider-progress))]",
|
|
21
|
+
"[&::-moz-range-track]:h-1 [&::-moz-range-track]:rounded-full [&::-moz-range-track]:bg-stroke-accessible",
|
|
22
|
+
"[&::-moz-range-progress]:h-1 [&::-moz-range-progress]:rounded-full [&::-moz-range-progress]:bg-primary"
|
|
23
|
+
], p = [
|
|
24
|
+
"forced-colors:[&::-webkit-slider-runnable-track]:bg-[linear-gradient(to_right,Highlight_var(--wave-slider-progress),CanvasText_var(--wave-slider-progress))]",
|
|
25
|
+
"forced-colors:wave-rtl:[&::-webkit-slider-runnable-track]:bg-[linear-gradient(to_left,Highlight_var(--wave-slider-progress),CanvasText_var(--wave-slider-progress))]",
|
|
26
|
+
"forced-colors:[&::-moz-range-progress]:bg-[Highlight]",
|
|
27
|
+
"forced-colors:disabled:[&::-webkit-slider-runnable-track]:bg-none forced-colors:disabled:[&::-moz-range-progress]:bg-[GrayText]"
|
|
28
|
+
], m = ({ className: m, style: h, label: g, value: _, defaultValue: v, min: y, max: b, step: x, form: S, onChange: C, onValueChange: w, ref: T, id: E, "aria-label": D, "aria-labelledby": O, "aria-describedby": k, "aria-invalid": A, "aria-required": j, required: M, ...N }) => {
|
|
29
|
+
let P = i({
|
|
30
|
+
id: E,
|
|
31
|
+
"aria-label": D ?? g,
|
|
32
|
+
"aria-labelledby": O,
|
|
33
|
+
"aria-describedby": k,
|
|
34
|
+
"aria-invalid": A,
|
|
35
|
+
"aria-required": j,
|
|
36
|
+
required: M
|
|
37
|
+
}, { nativeRequired: !0 }), F = c.useRef(null), I = r(F, T), L = y ?? 0, R = b ?? 100, z = d(_ ?? v ?? L + (R - L) / 2, L, R), B = n(() => {
|
|
38
|
+
let e = F.current;
|
|
39
|
+
if (!e) return;
|
|
40
|
+
let t = d(Number(e.value), L, R);
|
|
41
|
+
e.style.getPropertyValue(u) !== t && e.style.setProperty(u, t);
|
|
42
|
+
});
|
|
43
|
+
c.useLayoutEffect(() => {
|
|
44
|
+
B();
|
|
45
|
+
}, [
|
|
46
|
+
_,
|
|
47
|
+
v,
|
|
48
|
+
y,
|
|
49
|
+
b,
|
|
50
|
+
x,
|
|
51
|
+
B
|
|
52
|
+
]), s(F, () => queueMicrotask(B), S);
|
|
53
|
+
let V = t(C, (e) => {
|
|
54
|
+
_ === void 0 && B(), w?.(Number(e.currentTarget.value));
|
|
55
|
+
}, { checkDefaultPrevented: !1 });
|
|
56
|
+
return /* @__PURE__ */ l("input", {
|
|
57
|
+
ref: I,
|
|
58
|
+
type: "range",
|
|
59
|
+
className: e("w-full cursor-pointer appearance-none bg-transparent", f, "[&::-webkit-slider-thumb]:-mt-2 [&::-webkit-slider-thumb]:h-5 [&::-webkit-slider-thumb]:w-5 [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-background [&::-webkit-slider-thumb]:bg-primary [&::-webkit-slider-thumb]:shadow", "[&::-moz-range-thumb]:h-5 [&::-moz-range-thumb]:w-5 [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-background [&::-moz-range-thumb]:bg-primary [&::-moz-range-thumb]:shadow", "disabled:cursor-not-allowed disabled:opacity-50", a, o.rangeInput, p, m),
|
|
60
|
+
style: {
|
|
61
|
+
...h,
|
|
62
|
+
[u]: z
|
|
63
|
+
},
|
|
64
|
+
value: _,
|
|
65
|
+
defaultValue: v,
|
|
66
|
+
min: y,
|
|
67
|
+
max: b,
|
|
68
|
+
step: x,
|
|
69
|
+
form: S,
|
|
70
|
+
...N,
|
|
71
|
+
...P,
|
|
72
|
+
onChange: V
|
|
73
|
+
});
|
|
74
|
+
};
|
|
75
|
+
m.displayName = "Slider";
|
|
76
|
+
//#endregion
|
|
77
|
+
export { m as Slider };
|
|
78
|
+
|
|
79
|
+
//# sourceMappingURL=Slider.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Slider.mjs","names":["React","PROGRESS_VAR","progressPercent","share","max","min","value","railClasses","forcedColorsFill","Slider","ariaLabel","ariaLabelledBy","ariaDescribedBy","ariaInvalid","ariaRequired","props","fieldProps","useFieldControl","label","inputRef","mergedRef","useMergedRefs","ref","rangeMin","rangeMax","renderedProgress","defaultValue","updateFill","useEventCallback","input","next","step","useFormReset","form","handleChange","composeEventHandlers","onChange","onValueChange","event","cn","focusRing","forcedColors","className","style"],"sources":["../../../src/components/input/Slider.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { focusRing, forcedColors } from '../../lib/styles';\nimport { useEventCallback } from '../../hooks/useEventCallback';\nimport { useFieldControl } from '../../hooks/useFieldControl';\nimport { useFormReset } from '../../hooks/useFormReset';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\n\n/** Properties for the Slider component. */\nexport interface SliderProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'type'> {\n /** Controlled slider value. */\n value?: number;\n /** Initial value for uncontrolled usage. */\n defaultValue?: number;\n /** Native change event handler (`event.target.value` is a string). */\n onChange?: React.ChangeEventHandler<HTMLInputElement>;\n /** Called with the new value as a number on every change, next to the native `onChange`. */\n onValueChange?: (value: number) => void;\n /** Minimum allowed value. */\n min?: number;\n /** Maximum allowed value. */\n max?: number;\n /** Step increment between values. */\n step?: number;\n /**\n * Accessible label for the slider (sets `aria-label`; an explicit `aria-label` wins). Inside a\n * `Field`, leave it out so the Field's label names the slider.\n */\n label?: string;\n /** Ref to the `<input type=\"range\">` element. */\n ref?: React.Ref<HTMLInputElement>;\n}\n\n/** The CSS variable that holds how much of the rail the fill covers (`<p>%`). */\nconst PROGRESS_VAR = '--wave-slider-progress';\n\n/** The share of the rail up to `value`, as a CSS percentage: 0–100, and 0 when `max <= min`. */\nfunction progressPercent(value: number, min: number, max: number): string {\n const share = max > min ? ((value - min) / (max - min)) * 100 : 0;\n return `${Number.isFinite(share) ? Math.min(100, Math.max(0, share)) : 0}%`;\n}\n\n/**\n * The rail: the primary fill up to the thumb, the accessible stroke after it. WebKit and Blink\n * draw it as a gradient on the track (mirrored for right-to-left); Firefox has a progress part and\n * mirrors it itself. The track color stays underneath (the whole rail without the variable).\n */\nconst railClasses = [\n // The rail color gives the rail itself 3:1 non-text contrast.\n '[&::-webkit-slider-runnable-track]:h-1 [&::-webkit-slider-runnable-track]:rounded-full [&::-webkit-slider-runnable-track]:bg-stroke-accessible',\n '[&::-webkit-slider-runnable-track]:bg-[linear-gradient(to_right,var(--wave-primary)_var(--wave-slider-progress),var(--wave-stroke-accessible)_var(--wave-slider-progress))]',\n 'wave-rtl:[&::-webkit-slider-runnable-track]:bg-[linear-gradient(to_left,var(--wave-primary)_var(--wave-slider-progress),var(--wave-stroke-accessible)_var(--wave-slider-progress))]',\n '[&::-moz-range-track]:h-1 [&::-moz-range-track]:rounded-full [&::-moz-range-track]:bg-stroke-accessible',\n '[&::-moz-range-progress]:h-1 [&::-moz-range-progress]:rounded-full [&::-moz-range-progress]:bg-primary',\n];\n\n/**\n * Forced colors, after `forcedColors.rangeInput` (which draws the whole rail in CanvasText): the\n * filled part in Highlight; a disabled rail stays GrayText, without the fill.\n */\nconst forcedColorsFill = [\n 'forced-colors:[&::-webkit-slider-runnable-track]:bg-[linear-gradient(to_right,Highlight_var(--wave-slider-progress),CanvasText_var(--wave-slider-progress))]',\n 'forced-colors:wave-rtl:[&::-webkit-slider-runnable-track]:bg-[linear-gradient(to_left,Highlight_var(--wave-slider-progress),CanvasText_var(--wave-slider-progress))]',\n 'forced-colors:[&::-moz-range-progress]:bg-[Highlight]',\n 'forced-colors:disabled:[&::-webkit-slider-runnable-track]:bg-none forced-colors:disabled:[&::-moz-range-progress]:bg-[GrayText]',\n];\n\n/**\n * A native range input with Fluent styling: a rail drawn in the accessible stroke color (3:1\n * against the page), filled in the primary color up to a primary thumb; in forced-colors mode the\n * rail, fill and thumb are drawn in system colors. Inside a `Field` it picks up the label, hint,\n * validation message, `required` and invalid state automatically.\n *\n * The fill follows the value through the `--wave-slider-progress` variable on the input (also in\n * the server HTML), including the browser's snapping to `step` and a form reset.\n *\n * @example\n * <Slider label=\"Volume\" min={0} max={100} value={volume} onValueChange={setVolume} />\n */\nexport const Slider = ({\n className,\n style,\n label,\n value,\n defaultValue,\n min,\n max,\n step,\n form,\n onChange,\n onValueChange,\n ref,\n id,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n 'aria-invalid': ariaInvalid,\n 'aria-required': ariaRequired,\n required,\n ...props\n}: SliderProps) => {\n const fieldProps = useFieldControl(\n {\n id,\n 'aria-label': ariaLabel ?? label,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n 'aria-invalid': ariaInvalid,\n 'aria-required': ariaRequired,\n required,\n },\n { nativeRequired: true },\n );\n\n const inputRef = React.useRef<HTMLInputElement>(null);\n const mergedRef = useMergedRefs(inputRef, ref);\n const rangeMin = min ?? 0;\n const rangeMax = max ?? 100;\n // During render (and on the server): the value, else the default, else the native midpoint.\n const renderedProgress = progressPercent(\n value ?? defaultValue ?? rangeMin + (rangeMax - rangeMin) / 2,\n rangeMin,\n rangeMax,\n );\n\n /** Writes the fill of the value the input really has (the browser snaps it to `step`). */\n const updateFill = useEventCallback(() => {\n const input = inputRef.current;\n if (!input) return;\n const next = progressPercent(Number(input.value), rangeMin, rangeMax);\n if (input.style.getPropertyValue(PROGRESS_VAR) !== next) {\n input.style.setProperty(PROGRESS_VAR, next);\n }\n });\n\n // On mount and whenever the value or its range changes: React wrote the variable from the props,\n // the input may hold another value (step snapping, an uncontrolled value the user moved).\n React.useLayoutEffect(() => {\n updateFill();\n }, [value, defaultValue, min, max, step, updateFill]);\n\n // The reset event fires before the form restores the value: read it a microtask later.\n useFormReset(inputRef, () => queueMicrotask(updateFill), form);\n\n const handleChange = composeEventHandlers(\n onChange,\n (event: React.ChangeEvent<HTMLInputElement>) => {\n // A controlled fill follows `value` (a parent that rejects the change keeps it).\n if (value === undefined) updateFill();\n onValueChange?.(Number(event.currentTarget.value));\n },\n { checkDefaultPrevented: false },\n );\n\n return (\n <input\n ref={mergedRef}\n type=\"range\"\n className={cn(\n 'w-full cursor-pointer appearance-none bg-transparent',\n railClasses,\n // Thumb. WebKit and Blink align its top with the rail's top, so it is pulled up by half the\n // difference of the two heights (5 and 1 spacing units): it stays centred at any root\n // font size.\n '[&::-webkit-slider-thumb]:-mt-2 [&::-webkit-slider-thumb]:h-5 [&::-webkit-slider-thumb]:w-5 [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-background [&::-webkit-slider-thumb]:bg-primary [&::-webkit-slider-thumb]:shadow',\n // Firefox thumb\n '[&::-moz-range-thumb]:h-5 [&::-moz-range-thumb]:w-5 [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-background [&::-moz-range-thumb]:bg-primary [&::-moz-range-thumb]:shadow',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n focusRing,\n // Forced colors replace the author backgrounds of the rail and thumb with Canvas: give\n // every part a system color instead.\n forcedColors.rangeInput,\n forcedColorsFill,\n className,\n )}\n style={{ ...style, [PROGRESS_VAR]: renderedProgress } as React.CSSProperties}\n value={value}\n defaultValue={defaultValue}\n min={min}\n max={max}\n step={step}\n form={form}\n {...props}\n {...fieldProps}\n onChange={handleChange}\n />\n );\n};\n\nSlider.displayName = 'Slider';\n"],"mappings":";;;;;;;;;;;AAmCA,IAAMC,IAAe;AAGrB,SAASC,EAAgB,GAAe,GAAa,GAAqB;CACxE,IAAMC,IAAQC,IAAMC,KAAQC,IAAQD,MAAQD,IAAMC,KAAQ,MAAM;CAChE,OAAO,GAAG,OAAO,SAASF,CAAK,IAAI,KAAK,IAAI,KAAK,KAAK,IAAI,GAAGA,CAAK,CAAC,IAAI,EAAE;AAC3E;AAOA,IAAMI,IAAc;CAElB;CACA;CACA;CACA;CACA;AACF,GAMMC,IAAmB;CACvB;CACA;CACA;CACA;AACF,GAcaC,KAAU,EACrB,cACA,UACA,UACA,UACA,iBACA,QACA,QACA,SACA,SACA,aACA,kBACA,QACA,OACA,cAAcC,GACd,mBAAmBC,GACnB,oBAAoBC,GACpB,gBAAgBC,GAChB,iBAAiBC,GACjB,aACA,GAAGC,QACc;CACjB,IAAMC,IAAaC,EACjB;EACE;EACA,cAAcP,KAAaQ;EAC3B,mBAAmBP;EACnB,oBAAoBC;EACpB,gBAAgBC;EAChB,iBAAiBC;EACjB;CACF,GACA,EAAE,gBAAgB,GAAK,CACzB,GAEMK,IAAWnB,EAAM,OAAyB,IAAI,GAC9CoB,IAAYC,EAAcF,GAAUG,CAAG,GACvCC,IAAWlB,KAAO,GAClBmB,IAAWpB,KAAO,KAElBqB,IAAmBvB,EACvBI,KAASoB,KAAgBH,KAAYC,IAAWD,KAAY,GAC5DA,GACAC,CACF,GAGMG,IAAaC,QAAuB;EACxC,IAAMC,IAAQV,EAAS;EACvB,IAAI,CAACU,GAAO;EACZ,IAAMC,IAAO5B,EAAgB,OAAO2B,EAAM,KAAK,GAAGN,GAAUC,CAAQ;EACpE,AAAIK,EAAM,MAAM,iBAAiB5B,CAAY,MAAM6B,KACjDD,EAAM,MAAM,YAAY5B,GAAc6B,CAAI;CAE9C,CAAC;CASD,AALA9B,EAAM,sBAAsB;EAC1B,EAAW;CACb,GAAG;EAACM;EAAOoB;EAAcrB;EAAKD;EAAK2B;EAAMJ;CAAU,CAAC,GAGpDK,EAAab,SAAgB,eAAeQ,CAAU,GAAGM,CAAI;CAE7D,IAAMC,IAAeC,EACnBC,IACC,MAA+C;EAG9C,AADI9B,MAAU,KAAA,KAAWqB,EAAW,GACpCU,IAAgB,OAAOC,EAAM,cAAc,KAAK,CAAC;CACnD,GACA,EAAE,uBAAuB,GAAM,CACjC;CAEA,OACE,kBAAC,SAAD;EACE,KAAKlB;EACL,MAAK;EACL,WAAWmB,EACT,wDACAhC,GAIA,qUAEA,+NACA,mDACAiC,GAGAC,EAAa,YACbjC,GACAkC,CACF;EACA,OAAO;GAAE,GAAGC;IAAQ1C,IAAewB;EAAiB;EAC7C;EACO;EACT;EACA;EACC;EACA;EACN,GAAIV;EACJ,GAAIC;EACJ,UAAUkB;CACX,CAAA;AAEL;AAEA,EAAO,cAAc"}
|