@mortenbrudvik/waveui 0.4.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1221 -173
- package/dist/_virtual/_rolldown/runtime.cjs +1 -0
- package/dist/components/button/Button.cjs +2 -0
- package/dist/components/button/Button.cjs.map +1 -0
- package/dist/components/button/Button.mjs +50 -0
- package/dist/components/button/Button.mjs.map +1 -0
- package/dist/components/button/Button.semantics.cjs +2 -0
- package/dist/components/button/Button.semantics.cjs.map +1 -0
- package/dist/components/button/Button.semantics.mjs +61 -0
- package/dist/components/button/Button.semantics.mjs.map +1 -0
- package/dist/components/button/Button.slots.cjs +2 -0
- package/dist/components/button/Button.slots.cjs.map +1 -0
- package/dist/components/button/Button.slots.mjs +47 -0
- package/dist/components/button/Button.slots.mjs.map +1 -0
- package/dist/components/button/CompoundButton.cjs +2 -0
- package/dist/components/button/CompoundButton.cjs.map +1 -0
- package/dist/components/button/CompoundButton.mjs +53 -0
- package/dist/components/button/CompoundButton.mjs.map +1 -0
- package/dist/components/button/Link.cjs +2 -0
- package/dist/components/button/Link.cjs.map +1 -0
- package/dist/components/button/Link.mjs +37 -0
- package/dist/components/button/Link.mjs.map +1 -0
- package/dist/components/button/MenuButton.cjs +2 -0
- package/dist/components/button/MenuButton.cjs.map +1 -0
- package/dist/components/button/MenuButton.mjs +45 -0
- package/dist/components/button/MenuButton.mjs.map +1 -0
- package/dist/components/button/SplitButton.cjs +2 -0
- package/dist/components/button/SplitButton.cjs.map +1 -0
- package/dist/components/button/SplitButton.mjs +66 -0
- package/dist/components/button/SplitButton.mjs.map +1 -0
- package/dist/components/button/ToggleButton.cjs +2 -0
- package/dist/components/button/ToggleButton.cjs.map +1 -0
- package/dist/components/button/ToggleButton.mjs +65 -0
- package/dist/components/button/ToggleButton.mjs.map +1 -0
- package/dist/components/button/Toolbar.cjs +2 -0
- package/dist/components/button/Toolbar.cjs.map +1 -0
- package/dist/components/button/Toolbar.context.cjs +2 -0
- package/dist/components/button/Toolbar.context.cjs.map +1 -0
- package/dist/components/button/Toolbar.context.mjs +31 -0
- package/dist/components/button/Toolbar.context.mjs.map +1 -0
- package/dist/components/button/Toolbar.mjs +63 -0
- package/dist/components/button/Toolbar.mjs.map +1 -0
- package/dist/components/button/Toolbar.parts.cjs +2 -0
- package/dist/components/button/Toolbar.parts.cjs.map +1 -0
- package/dist/components/button/Toolbar.parts.mjs +131 -0
- package/dist/components/button/Toolbar.parts.mjs.map +1 -0
- package/dist/components/button/buttonStyles.cjs +2 -0
- package/dist/components/button/buttonStyles.cjs.map +1 -0
- package/dist/components/button/buttonStyles.mjs +39 -0
- package/dist/components/button/buttonStyles.mjs.map +1 -0
- package/dist/components/data-display/Avatar.cjs +2 -0
- package/dist/components/data-display/Avatar.cjs.map +1 -0
- package/dist/components/data-display/Avatar.mjs +157 -0
- package/dist/components/data-display/Avatar.mjs.map +1 -0
- package/dist/components/data-display/AvatarGroup.cjs +2 -0
- package/dist/components/data-display/AvatarGroup.cjs.map +1 -0
- package/dist/components/data-display/AvatarGroup.mjs +134 -0
- package/dist/components/data-display/AvatarGroup.mjs.map +1 -0
- package/dist/components/data-display/Badge.cjs +2 -0
- package/dist/components/data-display/Badge.cjs.map +1 -0
- package/dist/components/data-display/Badge.colors.cjs +2 -0
- package/dist/components/data-display/Badge.colors.cjs.map +1 -0
- package/dist/components/data-display/Badge.colors.mjs +58 -0
- package/dist/components/data-display/Badge.colors.mjs.map +1 -0
- package/dist/components/data-display/Badge.mjs +32 -0
- package/dist/components/data-display/Badge.mjs.map +1 -0
- package/dist/components/data-display/CounterBadge.cjs +2 -0
- package/dist/components/data-display/CounterBadge.cjs.map +1 -0
- package/dist/components/data-display/CounterBadge.mjs +28 -0
- package/dist/components/data-display/CounterBadge.mjs.map +1 -0
- package/dist/components/data-display/Divider.cjs +2 -0
- package/dist/components/data-display/Divider.cjs.map +1 -0
- package/dist/components/data-display/Divider.mjs +52 -0
- package/dist/components/data-display/Divider.mjs.map +1 -0
- package/dist/components/data-display/Image.cjs +2 -0
- package/dist/components/data-display/Image.cjs.map +1 -0
- package/dist/components/data-display/Image.mjs +32 -0
- package/dist/components/data-display/Image.mjs.map +1 -0
- package/dist/components/data-display/InfoLabel.cjs +2 -0
- package/dist/components/data-display/InfoLabel.cjs.map +1 -0
- package/dist/components/data-display/InfoLabel.mjs +104 -0
- package/dist/components/data-display/InfoLabel.mjs.map +1 -0
- package/dist/components/data-display/List.cjs +2 -0
- package/dist/components/data-display/List.cjs.map +1 -0
- package/dist/components/data-display/List.mjs +381 -0
- package/dist/components/data-display/List.mjs.map +1 -0
- package/dist/components/data-display/List.registry.cjs +2 -0
- package/dist/components/data-display/List.registry.cjs.map +1 -0
- package/dist/components/data-display/List.registry.mjs +101 -0
- package/dist/components/data-display/List.registry.mjs.map +1 -0
- package/dist/components/data-display/Persona.cjs +2 -0
- package/dist/components/data-display/Persona.cjs.map +1 -0
- package/dist/components/data-display/Persona.mjs +48 -0
- package/dist/components/data-display/Persona.mjs.map +1 -0
- package/dist/components/data-display/PresenceBadge.cjs +2 -0
- package/dist/components/data-display/PresenceBadge.cjs.map +1 -0
- package/dist/components/data-display/PresenceBadge.mjs +71 -0
- package/dist/components/data-display/PresenceBadge.mjs.map +1 -0
- package/dist/components/data-display/Tag.cjs +2 -0
- package/dist/components/data-display/Tag.cjs.map +1 -0
- package/dist/components/data-display/Tag.mjs +147 -0
- package/dist/components/data-display/Tag.mjs.map +1 -0
- package/dist/components/feedback/MessageBar.cjs +2 -0
- package/dist/components/feedback/MessageBar.cjs.map +1 -0
- package/dist/components/feedback/MessageBar.mjs +144 -0
- package/dist/components/feedback/MessageBar.mjs.map +1 -0
- package/dist/components/feedback/MessageBar.status.cjs +2 -0
- package/dist/components/feedback/MessageBar.status.cjs.map +1 -0
- package/dist/components/feedback/MessageBar.status.mjs +45 -0
- package/dist/components/feedback/MessageBar.status.mjs.map +1 -0
- package/dist/components/feedback/ProgressBar.cjs +2 -0
- package/dist/components/feedback/ProgressBar.cjs.map +1 -0
- package/dist/components/feedback/ProgressBar.mjs +72 -0
- package/dist/components/feedback/ProgressBar.mjs.map +1 -0
- package/dist/components/feedback/Skeleton.cjs +2 -0
- package/dist/components/feedback/Skeleton.cjs.map +1 -0
- package/dist/components/feedback/Skeleton.mjs +47 -0
- package/dist/components/feedback/Skeleton.mjs.map +1 -0
- package/dist/components/feedback/Spinner.cjs +2 -0
- package/dist/components/feedback/Spinner.cjs.map +1 -0
- package/dist/components/feedback/Spinner.mjs +60 -0
- package/dist/components/feedback/Spinner.mjs.map +1 -0
- package/dist/components/feedback/Toast.cjs +2 -0
- package/dist/components/feedback/Toast.cjs.map +1 -0
- package/dist/components/feedback/Toast.mjs +347 -0
- package/dist/components/feedback/Toast.mjs.map +1 -0
- package/dist/components/input/Checkbox.cjs +2 -0
- package/dist/components/input/Checkbox.cjs.map +1 -0
- package/dist/components/input/Checkbox.mjs +96 -0
- package/dist/components/input/Checkbox.mjs.map +1 -0
- package/dist/components/input/ColorPicker.cjs +6 -0
- package/dist/components/input/ColorPicker.cjs.map +1 -0
- package/dist/components/input/ColorPicker.mjs +236 -0
- package/dist/components/input/ColorPicker.mjs.map +1 -0
- package/dist/components/input/Combobox.cjs +2 -0
- package/dist/components/input/Combobox.cjs.map +1 -0
- package/dist/components/input/Combobox.expand.cjs +2 -0
- package/dist/components/input/Combobox.expand.cjs.map +1 -0
- package/dist/components/input/Combobox.expand.mjs +38 -0
- package/dist/components/input/Combobox.expand.mjs.map +1 -0
- package/dist/components/input/Combobox.mjs +187 -0
- package/dist/components/input/Combobox.mjs.map +1 -0
- package/dist/components/input/DatePicker.cjs +2 -0
- package/dist/components/input/DatePicker.cjs.map +1 -0
- package/dist/components/input/DatePicker.mjs +340 -0
- package/dist/components/input/DatePicker.mjs.map +1 -0
- package/dist/components/input/Dropdown.cjs +2 -0
- package/dist/components/input/Dropdown.cjs.map +1 -0
- package/dist/components/input/Dropdown.mjs +128 -0
- package/dist/components/input/Dropdown.mjs.map +1 -0
- package/dist/components/input/Field.cjs +2 -0
- package/dist/components/input/Field.cjs.map +1 -0
- package/dist/components/input/Field.mjs +200 -0
- package/dist/components/input/Field.mjs.map +1 -0
- package/dist/components/input/Input.cjs +2 -0
- package/dist/components/input/Input.cjs.map +1 -0
- package/dist/components/input/Input.mjs +81 -0
- package/dist/components/input/Input.mjs.map +1 -0
- package/dist/components/input/Label.cjs +2 -0
- package/dist/components/input/Label.cjs.map +1 -0
- package/dist/components/input/Label.mjs +28 -0
- package/dist/components/input/Label.mjs.map +1 -0
- package/dist/components/input/Option.cjs +2 -0
- package/dist/components/input/Option.cjs.map +1 -0
- package/dist/components/input/Option.mjs +169 -0
- package/dist/components/input/Option.mjs.map +1 -0
- package/dist/components/input/RadioGroup.cjs +2 -0
- package/dist/components/input/RadioGroup.cjs.map +1 -0
- package/dist/components/input/RadioGroup.mjs +139 -0
- package/dist/components/input/RadioGroup.mjs.map +1 -0
- package/dist/components/input/Rating.cjs +2 -0
- package/dist/components/input/Rating.cjs.map +1 -0
- package/dist/components/input/Rating.mjs +196 -0
- package/dist/components/input/Rating.mjs.map +1 -0
- package/dist/components/input/SearchBox.cjs +2 -0
- package/dist/components/input/SearchBox.cjs.map +1 -0
- package/dist/components/input/SearchBox.mjs +205 -0
- package/dist/components/input/SearchBox.mjs.map +1 -0
- package/dist/components/input/Select.cjs +2 -0
- package/dist/components/input/Select.cjs.map +1 -0
- package/dist/components/input/Select.mjs +33 -0
- package/dist/components/input/Select.mjs.map +1 -0
- package/dist/components/input/Slider.cjs +2 -0
- package/dist/components/input/Slider.cjs.map +1 -0
- package/dist/components/input/Slider.mjs +79 -0
- package/dist/components/input/Slider.mjs.map +1 -0
- package/dist/components/input/SpinButton.cjs +2 -0
- package/dist/components/input/SpinButton.cjs.map +1 -0
- package/dist/components/input/SpinButton.mjs +157 -0
- package/dist/components/input/SpinButton.mjs.map +1 -0
- package/dist/components/input/SwatchPicker.cjs +2 -0
- package/dist/components/input/SwatchPicker.cjs.map +1 -0
- package/dist/components/input/SwatchPicker.mjs +113 -0
- package/dist/components/input/SwatchPicker.mjs.map +1 -0
- package/dist/components/input/Switch.cjs +2 -0
- package/dist/components/input/Switch.cjs.map +1 -0
- package/dist/components/input/Switch.mjs +92 -0
- package/dist/components/input/Switch.mjs.map +1 -0
- package/dist/components/input/TagPicker.cjs +2 -0
- package/dist/components/input/TagPicker.cjs.map +1 -0
- package/dist/components/input/TagPicker.mjs +249 -0
- package/dist/components/input/TagPicker.mjs.map +1 -0
- package/dist/components/input/Textarea.cjs +2 -0
- package/dist/components/input/Textarea.cjs.map +1 -0
- package/dist/components/input/Textarea.mjs +32 -0
- package/dist/components/input/Textarea.mjs.map +1 -0
- package/dist/components/input/TimePicker.cjs +2 -0
- package/dist/components/input/TimePicker.cjs.map +1 -0
- package/dist/components/input/TimePicker.mjs +292 -0
- package/dist/components/input/TimePicker.mjs.map +1 -0
- package/dist/components/input/colorUtils.cjs +2 -0
- package/dist/components/input/colorUtils.cjs.map +1 -0
- package/dist/components/input/colorUtils.mjs +96 -0
- package/dist/components/input/colorUtils.mjs.map +1 -0
- package/dist/components/input/dateUtils.cjs +2 -0
- package/dist/components/input/dateUtils.cjs.map +1 -0
- package/dist/components/input/dateUtils.mjs +250 -0
- package/dist/components/input/dateUtils.mjs.map +1 -0
- package/dist/components/input/pickerStyles.cjs +2 -0
- package/dist/components/input/pickerStyles.cjs.map +1 -0
- package/dist/components/input/pickerStyles.mjs +10 -0
- package/dist/components/input/pickerStyles.mjs.map +1 -0
- package/dist/components/internal/HiddenInput.cjs +2 -0
- package/dist/components/internal/HiddenInput.cjs.map +1 -0
- package/dist/components/internal/HiddenInput.mjs +88 -0
- package/dist/components/internal/HiddenInput.mjs.map +1 -0
- package/dist/components/layout/Accordion.cjs +2 -0
- package/dist/components/layout/Accordion.cjs.map +1 -0
- package/dist/components/layout/Accordion.mjs +236 -0
- package/dist/components/layout/Accordion.mjs.map +1 -0
- package/dist/components/layout/Card.cjs +2 -0
- package/dist/components/layout/Card.cjs.map +1 -0
- package/dist/components/layout/Card.mjs +121 -0
- package/dist/components/layout/Card.mjs.map +1 -0
- package/dist/components/layout/Carousel.cjs +2 -0
- package/dist/components/layout/Carousel.cjs.map +1 -0
- package/dist/components/layout/Carousel.mjs +205 -0
- package/dist/components/layout/Carousel.mjs.map +1 -0
- package/dist/components/layout/Flex.cjs +2 -0
- package/dist/components/layout/Flex.cjs.map +1 -0
- package/dist/components/layout/Flex.mjs +54 -0
- package/dist/components/layout/Flex.mjs.map +1 -0
- package/dist/components/layout/Grid.cjs +2 -0
- package/dist/components/layout/Grid.cjs.map +1 -0
- package/dist/components/layout/Grid.mjs +62 -0
- package/dist/components/layout/Grid.mjs.map +1 -0
- package/dist/components/layout/Overflow.cjs +2 -0
- package/dist/components/layout/Overflow.cjs.map +1 -0
- package/dist/components/layout/Overflow.mjs +269 -0
- package/dist/components/layout/Overflow.mjs.map +1 -0
- package/dist/components/layout/Stack.cjs +2 -0
- package/dist/components/layout/Stack.cjs.map +1 -0
- package/dist/components/layout/Stack.mjs +39 -0
- package/dist/components/layout/Stack.mjs.map +1 -0
- package/dist/components/layout/TabList.cjs +2 -0
- package/dist/components/layout/TabList.cjs.map +1 -0
- package/dist/components/layout/TabList.mjs +238 -0
- package/dist/components/layout/TabList.mjs.map +1 -0
- package/dist/components/layout/Tree.cjs +2 -0
- package/dist/components/layout/Tree.cjs.map +1 -0
- package/dist/components/layout/Tree.mjs +220 -0
- package/dist/components/layout/Tree.mjs.map +1 -0
- package/dist/components/layout/disclosureIds.cjs +2 -0
- package/dist/components/layout/disclosureIds.cjs.map +1 -0
- package/dist/components/layout/disclosureIds.mjs +12 -0
- package/dist/components/layout/disclosureIds.mjs.map +1 -0
- package/dist/components/motion/Presence.cjs +2 -0
- package/dist/components/motion/Presence.cjs.map +1 -0
- package/dist/components/motion/Presence.mjs +35 -0
- package/dist/components/motion/Presence.mjs.map +1 -0
- package/dist/components/navigation/Breadcrumb.cjs +2 -0
- package/dist/components/navigation/Breadcrumb.cjs.map +1 -0
- package/dist/components/navigation/Breadcrumb.mjs +144 -0
- package/dist/components/navigation/Breadcrumb.mjs.map +1 -0
- package/dist/components/navigation/Menu.cjs +2 -0
- package/dist/components/navigation/Menu.cjs.map +1 -0
- package/dist/components/navigation/Menu.context.cjs +2 -0
- package/dist/components/navigation/Menu.context.cjs.map +1 -0
- package/dist/components/navigation/Menu.context.mjs +82 -0
- package/dist/components/navigation/Menu.context.mjs.map +1 -0
- package/dist/components/navigation/Menu.group.cjs +2 -0
- package/dist/components/navigation/Menu.group.cjs.map +1 -0
- package/dist/components/navigation/Menu.group.mjs +58 -0
- package/dist/components/navigation/Menu.group.mjs.map +1 -0
- package/dist/components/navigation/Menu.items.cjs +2 -0
- package/dist/components/navigation/Menu.items.cjs.map +1 -0
- package/dist/components/navigation/Menu.items.mjs +127 -0
- package/dist/components/navigation/Menu.items.mjs.map +1 -0
- package/dist/components/navigation/Menu.link.cjs +2 -0
- package/dist/components/navigation/Menu.link.cjs.map +1 -0
- package/dist/components/navigation/Menu.link.mjs +41 -0
- package/dist/components/navigation/Menu.link.mjs.map +1 -0
- package/dist/components/navigation/Menu.mjs +27 -0
- package/dist/components/navigation/Menu.mjs.map +1 -0
- package/dist/components/navigation/Menu.popover.cjs +2 -0
- package/dist/components/navigation/Menu.popover.cjs.map +1 -0
- package/dist/components/navigation/Menu.popover.mjs +231 -0
- package/dist/components/navigation/Menu.popover.mjs.map +1 -0
- package/dist/components/navigation/Menu.root.cjs +2 -0
- package/dist/components/navigation/Menu.root.cjs.map +1 -0
- package/dist/components/navigation/Menu.root.mjs +308 -0
- package/dist/components/navigation/Menu.root.mjs.map +1 -0
- package/dist/components/navigation/Menu.selectable.cjs +2 -0
- package/dist/components/navigation/Menu.selectable.cjs.map +1 -0
- package/dist/components/navigation/Menu.selectable.mjs +89 -0
- package/dist/components/navigation/Menu.selectable.mjs.map +1 -0
- package/dist/components/navigation/Menu.shared.cjs +2 -0
- package/dist/components/navigation/Menu.shared.cjs.map +1 -0
- package/dist/components/navigation/Menu.shared.mjs +23 -0
- package/dist/components/navigation/Menu.shared.mjs.map +1 -0
- package/dist/components/navigation/Menu.splitGroup.cjs +2 -0
- package/dist/components/navigation/Menu.splitGroup.cjs.map +1 -0
- package/dist/components/navigation/Menu.splitGroup.mjs +51 -0
- package/dist/components/navigation/Menu.splitGroup.mjs.map +1 -0
- package/dist/components/navigation/Menu.trigger.cjs +2 -0
- package/dist/components/navigation/Menu.trigger.cjs.map +1 -0
- package/dist/components/navigation/Menu.trigger.mjs +79 -0
- package/dist/components/navigation/Menu.trigger.mjs.map +1 -0
- package/dist/components/navigation/Nav.cjs +2 -0
- package/dist/components/navigation/Nav.cjs.map +1 -0
- package/dist/components/navigation/Nav.mjs +276 -0
- package/dist/components/navigation/Nav.mjs.map +1 -0
- package/dist/components/navigation/Pagination.cjs +2 -0
- package/dist/components/navigation/Pagination.cjs.map +1 -0
- package/dist/components/navigation/Pagination.mjs +110 -0
- package/dist/components/navigation/Pagination.mjs.map +1 -0
- package/dist/components/navigation/Stepper.cjs +2 -0
- package/dist/components/navigation/Stepper.cjs.map +1 -0
- package/dist/components/navigation/Stepper.mjs +204 -0
- package/dist/components/navigation/Stepper.mjs.map +1 -0
- package/dist/components/overlays/Dialog.cjs +2 -0
- package/dist/components/overlays/Dialog.cjs.map +1 -0
- package/dist/components/overlays/Dialog.mjs +180 -0
- package/dist/components/overlays/Dialog.mjs.map +1 -0
- package/dist/components/overlays/Dialog.shared.cjs +2 -0
- package/dist/components/overlays/Dialog.shared.cjs.map +1 -0
- package/dist/components/overlays/Dialog.shared.mjs +227 -0
- package/dist/components/overlays/Dialog.shared.mjs.map +1 -0
- package/dist/components/overlays/Drawer.cjs +2 -0
- package/dist/components/overlays/Drawer.cjs.map +1 -0
- package/dist/components/overlays/Drawer.mjs +192 -0
- package/dist/components/overlays/Drawer.mjs.map +1 -0
- package/dist/components/overlays/Popover.cjs +2 -0
- package/dist/components/overlays/Popover.cjs.map +1 -0
- package/dist/components/overlays/Popover.mjs +365 -0
- package/dist/components/overlays/Popover.mjs.map +1 -0
- package/dist/components/overlays/Popover.shared.cjs +2 -0
- package/dist/components/overlays/Popover.shared.cjs.map +1 -0
- package/dist/components/overlays/Popover.shared.mjs +182 -0
- package/dist/components/overlays/Popover.shared.mjs.map +1 -0
- package/dist/components/overlays/TeachingPopover.cjs +2 -0
- package/dist/components/overlays/TeachingPopover.cjs.map +1 -0
- package/dist/components/overlays/TeachingPopover.mjs +181 -0
- package/dist/components/overlays/TeachingPopover.mjs.map +1 -0
- package/dist/components/overlays/Tooltip.cjs +2 -0
- package/dist/components/overlays/Tooltip.cjs.map +1 -0
- package/dist/components/overlays/Tooltip.mjs +160 -0
- package/dist/components/overlays/Tooltip.mjs.map +1 -0
- package/dist/components/portal/Portal.cjs +2 -0
- package/dist/components/portal/Portal.cjs.map +1 -0
- package/dist/components/portal/Portal.mjs +45 -0
- package/dist/components/portal/Portal.mjs.map +1 -0
- package/dist/components/provider/WaveProvider.cjs +2 -0
- package/dist/components/provider/WaveProvider.cjs.map +1 -0
- package/dist/components/provider/WaveProvider.mjs +51 -0
- package/dist/components/provider/WaveProvider.mjs.map +1 -0
- package/dist/components/table/DataGrid.cjs +2 -0
- package/dist/components/table/DataGrid.cjs.map +1 -0
- package/dist/components/table/DataGrid.mjs +489 -0
- package/dist/components/table/DataGrid.mjs.map +1 -0
- package/dist/components/table/Table.cjs +2 -0
- package/dist/components/table/Table.cjs.map +1 -0
- package/dist/components/table/Table.mjs +99 -0
- package/dist/components/table/Table.mjs.map +1 -0
- package/dist/components/table/useGridNavigation.cjs +2 -0
- package/dist/components/table/useGridNavigation.cjs.map +1 -0
- package/dist/components/table/useGridNavigation.mjs +336 -0
- package/dist/components/table/useGridNavigation.mjs.map +1 -0
- package/dist/components/typography/Text.cjs +2 -0
- package/dist/components/typography/Text.cjs.map +1 -0
- package/dist/components/typography/Text.mjs +38 -0
- package/dist/components/typography/Text.mjs.map +1 -0
- package/dist/hooks/useAnnounce.cjs +2 -0
- package/dist/hooks/useAnnounce.cjs.map +1 -0
- package/dist/hooks/useAnnounce.mjs +88 -0
- package/dist/hooks/useAnnounce.mjs.map +1 -0
- package/dist/hooks/useCheckedValues.cjs +2 -0
- package/dist/hooks/useCheckedValues.cjs.map +1 -0
- package/dist/hooks/useCheckedValues.mjs +102 -0
- package/dist/hooks/useCheckedValues.mjs.map +1 -0
- package/dist/hooks/useContextMenuAnchor.cjs +2 -0
- package/dist/hooks/useContextMenuAnchor.cjs.map +1 -0
- package/dist/hooks/useContextMenuAnchor.mjs +132 -0
- package/dist/hooks/useContextMenuAnchor.mjs.map +1 -0
- package/dist/hooks/useControllable.cjs +2 -0
- package/dist/hooks/useControllable.cjs.map +1 -0
- package/dist/hooks/useControllable.mjs +37 -0
- package/dist/hooks/useControllable.mjs.map +1 -0
- package/dist/hooks/useDirection.cjs +2 -0
- package/dist/hooks/useDirection.cjs.map +1 -0
- package/dist/hooks/useDirection.mjs +57 -0
- package/dist/hooks/useDirection.mjs.map +1 -0
- package/dist/hooks/useDismiss.cjs +2 -0
- package/dist/hooks/useDismiss.cjs.map +1 -0
- package/dist/hooks/useDismiss.mjs +57 -0
- package/dist/hooks/useDismiss.mjs.map +1 -0
- package/dist/hooks/useEventCallback.cjs +2 -0
- package/dist/hooks/useEventCallback.cjs.map +1 -0
- package/dist/hooks/useEventCallback.mjs +16 -0
- package/dist/hooks/useEventCallback.mjs.map +1 -0
- package/dist/hooks/useFieldControl.cjs +2 -0
- package/dist/hooks/useFieldControl.cjs.map +1 -0
- package/dist/hooks/useFieldControl.mjs +62 -0
- package/dist/hooks/useFieldControl.mjs.map +1 -0
- package/dist/hooks/useFocusTrap.cjs +2 -0
- package/dist/hooks/useFocusTrap.cjs.map +1 -0
- package/dist/hooks/useFocusTrap.mjs +266 -0
- package/dist/hooks/useFocusTrap.mjs.map +1 -0
- package/dist/hooks/useFormReset.cjs +2 -0
- package/dist/hooks/useFormReset.cjs.map +1 -0
- package/dist/hooks/useFormReset.mjs +33 -0
- package/dist/hooks/useFormReset.mjs.map +1 -0
- package/dist/hooks/useHoverIntent.cjs +2 -0
- package/dist/hooks/useHoverIntent.cjs.map +1 -0
- package/dist/hooks/useHoverIntent.mjs +201 -0
- package/dist/hooks/useHoverIntent.mjs.map +1 -0
- package/dist/hooks/useId.cjs +2 -0
- package/dist/hooks/useId.cjs.map +1 -0
- package/dist/hooks/useId.mjs +11 -0
- package/dist/hooks/useId.mjs.map +1 -0
- package/dist/hooks/useIsClient.cjs +2 -0
- package/dist/hooks/useIsClient.cjs.map +1 -0
- package/dist/hooks/useIsClient.mjs +19 -0
- package/dist/hooks/useIsClient.mjs.map +1 -0
- package/dist/hooks/useListbox.cjs +2 -0
- package/dist/hooks/useListbox.cjs.map +1 -0
- package/dist/hooks/useListbox.mjs +492 -0
- package/dist/hooks/useListbox.mjs.map +1 -0
- package/dist/hooks/useMergedRefs.cjs +2 -0
- package/dist/hooks/useMergedRefs.cjs.map +1 -0
- package/dist/hooks/useMergedRefs.mjs +57 -0
- package/dist/hooks/useMergedRefs.mjs.map +1 -0
- package/dist/hooks/useModalIsolation.cjs +2 -0
- package/dist/hooks/useModalIsolation.cjs.map +1 -0
- package/dist/hooks/useModalIsolation.mjs +87 -0
- package/dist/hooks/useModalIsolation.mjs.map +1 -0
- package/dist/hooks/useModalLayer.cjs +2 -0
- package/dist/hooks/useModalLayer.cjs.map +1 -0
- package/dist/hooks/useModalLayer.mjs +30 -0
- package/dist/hooks/useModalLayer.mjs.map +1 -0
- package/dist/hooks/usePopupPosition.cjs +2 -0
- package/dist/hooks/usePopupPosition.cjs.map +1 -0
- package/dist/hooks/usePopupPosition.mjs +117 -0
- package/dist/hooks/usePopupPosition.mjs.map +1 -0
- package/dist/hooks/usePrefersReducedMotion.cjs +2 -0
- package/dist/hooks/usePrefersReducedMotion.cjs.map +1 -0
- package/dist/hooks/usePrefersReducedMotion.mjs +24 -0
- package/dist/hooks/usePrefersReducedMotion.mjs.map +1 -0
- package/dist/hooks/usePresence.cjs +2 -0
- package/dist/hooks/usePresence.cjs.map +1 -0
- package/dist/hooks/usePresence.mjs +136 -0
- package/dist/hooks/usePresence.mjs.map +1 -0
- package/dist/hooks/usePreserveFocus.cjs +2 -0
- package/dist/hooks/usePreserveFocus.cjs.map +1 -0
- package/dist/hooks/usePreserveFocus.mjs +50 -0
- package/dist/hooks/usePreserveFocus.mjs.map +1 -0
- package/dist/hooks/useRestoreFocus.cjs +2 -0
- package/dist/hooks/useRestoreFocus.cjs.map +1 -0
- package/dist/hooks/useRestoreFocus.mjs +271 -0
- package/dist/hooks/useRestoreFocus.mjs.map +1 -0
- package/dist/hooks/useRovingTabIndex.cjs +2 -0
- package/dist/hooks/useRovingTabIndex.cjs.map +1 -0
- package/dist/hooks/useRovingTabIndex.mjs +389 -0
- package/dist/hooks/useRovingTabIndex.mjs.map +1 -0
- package/dist/hooks/useScrollLock.cjs +2 -0
- package/dist/hooks/useScrollLock.cjs.map +1 -0
- package/dist/hooks/useScrollLock.mjs +71 -0
- package/dist/hooks/useScrollLock.mjs.map +1 -0
- package/dist/hooks/useTriggerElement.cjs +2 -0
- package/dist/hooks/useTriggerElement.cjs.map +1 -0
- package/dist/hooks/useTriggerElement.mjs +126 -0
- package/dist/hooks/useTriggerElement.mjs.map +1 -0
- package/dist/hooks/useTypeahead.cjs +2 -0
- package/dist/hooks/useTypeahead.cjs.map +1 -0
- package/dist/hooks/useTypeahead.mjs +38 -0
- package/dist/hooks/useTypeahead.mjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +9099 -0
- package/dist/index.d.ts +7688 -1027
- package/dist/index.mjs +91 -5695
- package/dist/lib/aria.cjs +2 -0
- package/dist/lib/aria.cjs.map +1 -0
- package/dist/lib/aria.mjs +29 -0
- package/dist/lib/aria.mjs.map +1 -0
- package/dist/lib/children.cjs +2 -0
- package/dist/lib/children.cjs.map +1 -0
- package/dist/lib/children.mjs +37 -0
- package/dist/lib/children.mjs.map +1 -0
- package/dist/lib/cn.cjs +2 -0
- package/dist/lib/cn.cjs.map +1 -0
- package/dist/lib/cn.mjs +64 -0
- package/dist/lib/cn.mjs.map +1 -0
- package/dist/lib/composeEventHandlers.cjs +2 -0
- package/dist/lib/composeEventHandlers.cjs.map +1 -0
- package/dist/lib/composeEventHandlers.mjs +11 -0
- package/dist/lib/composeEventHandlers.mjs.map +1 -0
- package/dist/lib/dev.cjs +2 -0
- package/dist/lib/dev.cjs.map +1 -0
- package/dist/lib/dev.mjs +42 -0
- package/dist/lib/dev.mjs.map +1 -0
- package/dist/lib/direction.cjs +2 -0
- package/dist/lib/direction.cjs.map +1 -0
- package/dist/lib/direction.mjs +35 -0
- package/dist/lib/direction.mjs.map +1 -0
- package/dist/lib/events.cjs +2 -0
- package/dist/lib/events.cjs.map +1 -0
- package/dist/lib/events.mjs +31 -0
- package/dist/lib/events.mjs.map +1 -0
- package/dist/lib/focus.cjs +2 -0
- package/dist/lib/focus.cjs.map +1 -0
- package/dist/lib/focus.mjs +119 -0
- package/dist/lib/focus.mjs.map +1 -0
- package/dist/lib/globalRegistry.cjs +2 -0
- package/dist/lib/globalRegistry.cjs.map +1 -0
- package/dist/lib/globalRegistry.mjs +13 -0
- package/dist/lib/globalRegistry.mjs.map +1 -0
- package/dist/lib/icons.cjs +2 -0
- package/dist/lib/icons.cjs.map +1 -0
- package/dist/lib/icons.mjs +254 -0
- package/dist/lib/icons.mjs.map +1 -0
- package/dist/lib/labelInName.cjs +2 -0
- package/dist/lib/labelInName.cjs.map +1 -0
- package/dist/lib/labelInName.mjs +54 -0
- package/dist/lib/labelInName.mjs.map +1 -0
- package/dist/lib/layers.cjs +2 -0
- package/dist/lib/layers.cjs.map +1 -0
- package/dist/lib/layers.mjs +224 -0
- package/dist/lib/layers.mjs.map +1 -0
- package/dist/lib/mergeProps.cjs +2 -0
- package/dist/lib/mergeProps.cjs.map +1 -0
- package/dist/lib/mergeProps.mjs +21 -0
- package/dist/lib/mergeProps.mjs.map +1 -0
- package/dist/lib/mergeRefs.cjs +2 -0
- package/dist/lib/mergeRefs.cjs.map +1 -0
- package/dist/lib/mergeRefs.mjs +29 -0
- package/dist/lib/mergeRefs.mjs.map +1 -0
- package/dist/lib/renderTrigger.cjs +2 -0
- package/dist/lib/renderTrigger.cjs.map +1 -0
- package/dist/lib/renderTrigger.mjs +29 -0
- package/dist/lib/renderTrigger.mjs.map +1 -0
- package/dist/lib/slot.cjs +2 -0
- package/dist/lib/slot.cjs.map +1 -0
- package/dist/lib/slot.mjs +122 -0
- package/dist/lib/slot.mjs.map +1 -0
- package/dist/lib/styles.cjs +2 -0
- package/dist/lib/styles.cjs.map +1 -0
- package/dist/lib/styles.mjs +16 -0
- package/dist/lib/styles.mjs.map +1 -0
- package/dist/lib/theme.cjs +2 -0
- package/dist/lib/theme.cjs.map +1 -0
- package/dist/lib/theme.mjs +16 -0
- package/dist/lib/theme.mjs.map +1 -0
- package/dist/preflight.css +2 -0
- package/dist/styles.css +2 -0
- package/package.json +149 -100
- package/src/styles/animations.css +7 -39
- package/src/styles/base.css +103 -0
- package/src/styles/globals.css +10 -22
- package/src/styles/legacy-tokens.css +184 -0
- package/src/styles/preflight.css +7 -0
- package/src/styles/styles.css +32 -0
- package/src/styles/tailwind.css +17 -0
- package/src/styles/tokens.css +561 -221
- package/src/styles/variants.css +29 -0
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("../../lib/cn.cjs"),n=require("../../lib/dev.cjs"),r=require("../../lib/composeEventHandlers.cjs"),ee=require("../../hooks/useControllable.cjs"),te=require("../../hooks/useMergedRefs.cjs"),ne=require("../../hooks/useFieldControl.cjs"),re=require("../../lib/styles.cjs"),i=require("../../lib/icons.cjs"),ie=require("./Input.cjs"),a=require("../../hooks/useFormReset.cjs"),o=require("../internal/HiddenInput.cjs");let s=require("react");s=e.__toESM(s,1);let c=require("react/jsx-runtime");var l=/^[+-]?(\d+\.?\d*|\.\d+)(e[+-]?\d+)?$/i,ae=/^[+-]?\.?$/;function oe(e){let t=e.trim();if(!l.test(t))return null;let n=Number(t);return Number.isFinite(n)?n:null}function u(e){if(!Number.isFinite(e))return 0;let[t,n]=String(e).toLowerCase().split(`e`),r=t.split(`.`)[1]?.length??0;return Math.max(0,r-(n?Number(n):0))}function d(e,t){return Number(e.toFixed(Math.min(t,20)))}var f=t.cn(`flex h-8 w-8 shrink-0 items-center justify-center border-input bg-transparent p-0 text-foreground`,`not-disabled:not-aria-disabled:hover:bg-subtle-hover not-disabled:not-aria-disabled:active:bg-subtle-pressed`,`disabled:pointer-events-none`),p=({value:e,defaultValue:l,onValueChange:p,onChange:m,min:h=-1/0,max:g=1/0,step:_=1,largeStep:se,disabled:v,name:ce,form:y,labels:b,className:le,hidden:ue,ref:de,controlRef:fe,id:pe,"aria-label":me,"aria-labelledby":he,"aria-describedby":x,"aria-invalid":S,"aria-required":C,"aria-errormessage":w,"aria-details":T,"aria-valuetext":E,required:D,readOnly:O,placeholder:k,maxLength:A,spellCheck:j,autoComplete:M=`off`,autoFocus:N,inputMode:P,enterKeyHint:F,tabIndex:I,onFocus:L,onBlur:R,onKeyDown:ge,onKeyUp:_e,...ve})=>{m!==void 0&&n.warnDeprecated(`SpinButton`,`onChange`,`onValueChange`);let z=l??0,[B,V]=ee.useControllable(e,z,e=>{p?.(e),m?.(e)}),[H,U]=s.useState(null),[ye,be]=s.useState(B);Object.is(ye,B)||(be(B),U(null));let W=H===null?null:oe(H),G=W??B,xe=H!==null&&W===null&&H.trim()!==``&&!ae.test(H.trim()),Se=e=>Math.min(g,Math.max(h,e)),K=!v&&!O,q=e=>{U(null),V(Se(e))},J=e=>{let t=Math.max(u(_),u(e),u(G));q(d(G+e,t))},Y=()=>{H!==null&&(W===null?U(null):q(W))},X=s.useRef(null),Ce=te.useMergedRefs(X,fe),Z=ne.useFieldControl({id:pe,"aria-label":me,"aria-labelledby":he,"aria-describedby":x,"aria-invalid":S,"aria-required":C,required:D},{nativeRequired:!0}),Q=xe?!0:Z[`aria-invalid`],we=ie.isInvalidLook(!1,Q);a.useFormReset(X,()=>{U(null),V(z)},y),s.useEffect(()=>{let e=X.current;e&&(e.hasAttribute(`aria-label`)||e.hasAttribute(`aria-labelledby`)||(e.labels?.length??0)>0||e.hasAttribute(`title`)||n.warnOnce(`SpinButton:unnamed`,"SpinButton: the spinbutton has no accessible name. Pass `aria-label` or `aria-labelledby`, use a <label htmlFor>, or render it inside a Field."))});let Te=e=>{if(!K||e.altKey||e.ctrlKey||e.metaKey)return;let t=se??d(_*10,u(_));switch(e.key){case`ArrowUp`:case`ArrowDown`:case`PageUp`:case`PageDown`:{e.preventDefault();let n=e.key===`ArrowUp`||e.key===`ArrowDown`?_:t;J(e.key===`ArrowUp`||e.key===`PageUp`?n:-n);return}case`Home`:case`End`:{let t=e.key===`Home`?h:g;if(!Number.isFinite(t))return;e.preventDefault(),q(t);return}case`Enter`:Y();return;case`Escape`:H!==null&&(e.preventDefault(),U(null));return}},Ee=h<0?`text`:u(_)>0||u(h)>0?`decimal`:`numeric`,$=e=>e.preventDefault();return(0,c.jsxs)(`div`,{ref:de,className:t.cn(`relative inline-flex items-center rounded border border-input border-b-stroke-accessible bg-background`,re.inputFocusWithin,we&&`border-destructive focus-within:border-b-destructive`,v&&`cursor-not-allowed opacity-50`,le),hidden:ue,...ve,children:[(0,c.jsx)(`button`,{type:`button`,tabIndex:-1,onMouseDown:$,onClick:()=>J(-_),disabled:!K||G<=h,"aria-label":b?.decrement??`Decrement`,className:t.cn(f,`border-e`,!v&&`disabled:opacity-50`),children:(0,c.jsx)(i.SubtractIcon,{size:12})}),(0,c.jsx)(`input`,{ref:Ce,type:`text`,role:`spinbutton`,inputMode:P??Ee,autoComplete:M,autoFocus:N,enterKeyHint:F,placeholder:k,maxLength:A,spellCheck:j,tabIndex:I,readOnly:O,form:y,...Z,"aria-invalid":Q,"aria-errormessage":w,"aria-details":T,"aria-valuenow":B,"aria-valuemin":Number.isFinite(h)?h:void 0,"aria-valuemax":Number.isFinite(g)?g:void 0,"aria-valuetext":E,value:H??String(B),onChange:e=>U(e.target.value),onFocus:L,onBlur:r.composeEventHandlers(R,Y,{checkDefaultPrevented:!1}),onKeyDown:r.composeEventHandlers(ge,Te),onKeyUp:_e,disabled:v,className:`h-8 w-12 min-w-0 border-none bg-transparent text-center text-body-1 text-foreground focus:outline-hidden disabled:cursor-not-allowed [appearance:textfield]`}),(0,c.jsx)(`button`,{type:`button`,tabIndex:-1,onMouseDown:$,onClick:()=>J(_),disabled:!K||G>=g,"aria-label":b?.increment??`Increment`,className:t.cn(f,`border-s`,!v&&`disabled:opacity-50`),children:(0,c.jsx)(i.AddIcon,{size:12})}),(0,c.jsx)(o.HiddenInput,{name:ce,form:y,disabled:v,value:String(B)})]})};p.displayName=`SpinButton`,exports.SpinButton=p;
|
|
2
|
+
//# sourceMappingURL=SpinButton.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SpinButton.cjs","names":["cn","useControllable","React","useMergedRefs","useFieldControl","isInvalidLook","inputFocusWithin","SubtractIcon","composeEventHandlers","AddIcon","HiddenInput","require_runtime","require_cn","require_dev","require_composeEventHandlers","require_useControllable","require_useMergedRefs","require_useFieldControl","require_styles","require_icons","require_Input","require_useFormReset","require_HiddenInput","react","react_jsx_runtime","NUMBER_TEXT","PARTIAL_NUMBER_TEXT","parseNumberText","trimmed","text","decimalsOf","n","mantissa","exponent","fraction","roundTo","decimals","stepButtonClass","SpinButton","valueProp","ariaLabel","ariaLabelledBy","ariaDescribedBy","ariaInvalid","ariaRequired","ariaErrorMessage","ariaDetails","ariaValueText","rest","onChange","initialValue","defaultValue","value","setValue","onValueChange","next","draft","setDraft","prevValue","setPrevValue","draftNumber","current","draftInvalid","clamp","max","min","interactive","disabled","readOnly","commit","stepBy","precision","step","delta","commitDraft","inputRef","mergedInputRef","controlRef","fieldProps","ariaInvalidValue","invalidLook","form","input","handleKeyDown","big","largeStep","size","bound","defaultInputMode","keepFocus","className","labels","inputMode","onBlur","onKeyDown"],"sources":["../../../src/components/input/SpinButton.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { warnDeprecated, warnOnce } from '../../lib/dev';\nimport { AddIcon, SubtractIcon } from '../../lib/icons';\nimport { inputFocusWithin, inputInvalidWithin } from '../../lib/styles';\nimport { useControllable } from '../../hooks/useControllable';\nimport { useFieldControl } from '../../hooks/useFieldControl';\nimport { useFormReset } from '../../hooks/useFormReset';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { HiddenInput } from '../internal/HiddenInput';\nimport { isInvalidLook } from './Input';\n\n/**\n * Props that SpinButton routes to its `<input role=\"spinbutton\">` (C-ROUTING): the id, the ARIA\n * naming/validation attributes, native text-input attributes and the focus/keyboard handlers.\n */\nexport type SpinButtonInputProps = 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 | 'aria-valuetext'\n | 'required'\n | 'readOnly'\n | 'placeholder'\n | 'maxLength'\n | 'spellCheck'\n | 'autoComplete'\n | 'autoFocus'\n | 'inputMode'\n | 'enterKeyHint'\n | 'tabIndex'\n | 'onFocus'\n | 'onBlur'\n | 'onKeyDown'\n | 'onKeyUp'\n>;\n\n/**\n * Names of the SpinButton's step buttons, for localization. Each member is optional and falls back\n * to its English default.\n */\nexport interface SpinButtonLabels {\n /** Name of the button that steps up.\n * @default 'Increment'\n */\n increment?: string;\n /** Name of the button that steps down.\n * @default 'Decrement'\n */\n decrement?: string;\n}\n\n/** Properties for the SpinButton component. */\nexport interface SpinButtonProps\n extends\n Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'onChange' | 'defaultValue' | keyof SpinButtonInputProps\n >,\n SpinButtonInputProps {\n /** Controlled numeric value. */\n value?: number;\n /** Initial value for uncontrolled usage (also what a form reset restores).\n * @default 0\n */\n defaultValue?: number;\n /**\n * Called with the new value when it changes: a step (buttons, arrow keys, PageUp/PageDown,\n * Home/End) or a typed value committed on blur or Enter. Not called while the user is typing,\n * nor when the value stays the same.\n */\n onValueChange?: (value: number) => void;\n /**\n * Called with the new value when it changes.\n * @deprecated Use `onValueChange`. (`onChange` is reserved for native change events.)\n */\n onChange?: (value: number) => void;\n /** Minimum allowed value.\n * @default -Infinity\n */\n min?: number;\n /** Maximum allowed value.\n * @default Infinity\n */\n max?: number;\n /** Step of the increment/decrement buttons and of ArrowUp/ArrowDown.\n * @default 1\n */\n step?: number;\n /** Step of PageUp/PageDown.\n * @default step * 10\n */\n largeStep?: number;\n /** Whether the spin button is disabled and non-interactive. */\n disabled?: boolean;\n /** Form field name. With a name, the committed value is submitted with the form. */\n name?: string;\n /** Id of the form the spin button belongs to, when it is rendered outside that form. */\n form?: string;\n /**\n * Names of the −/+ step buttons (not tab stops, but in the accessibility tree), for\n * localization. Unset members keep their English defaults.\n */\n labels?: SpinButtonLabels;\n /** Ref to the root `<div>`. */\n ref?: React.Ref<HTMLDivElement>;\n /** Ref to the `<input role=\"spinbutton\">` (the focusable control). */\n controlRef?: React.Ref<HTMLInputElement>;\n}\n\n/** Decimal numbers as a user types them: `12`, `-3`, `1.5`, `.5`, `2.`, `1e3`. */\nconst NUMBER_TEXT = /^[+-]?(\\d+\\.?\\d*|\\.\\d+)(e[+-]?\\d+)?$/i;\n/** Text on the way to a number (`-`, `.`, `-.`): not a value yet, but not an error either. */\nconst PARTIAL_NUMBER_TEXT = /^[+-]?\\.?$/;\n\nfunction parseNumberText(text: string): number | null {\n const trimmed = text.trim();\n if (!NUMBER_TEXT.test(trimmed)) return null;\n const n = Number(trimmed);\n return Number.isFinite(n) ? n : null;\n}\n\n/** Number of decimals of `n` as written by JavaScript (`0.1` → 1, `1e-7` → 7). */\nfunction decimalsOf(n: number): number {\n if (!Number.isFinite(n)) return 0;\n const [mantissa, exponent] = String(n).toLowerCase().split('e');\n const fraction = mantissa.split('.')[1]?.length ?? 0;\n return Math.max(0, fraction - (exponent ? Number(exponent) : 0));\n}\n\nfunction roundTo(n: number, decimals: number): number {\n return Number(n.toFixed(Math.min(decimals, 20)));\n}\n\nconst stepButtonClass = cn(\n // Padding and background set here (C-NATIVE): an app-wide `button` rule cannot fill them.\n 'flex h-8 w-8 shrink-0 items-center justify-center border-input bg-transparent p-0 text-foreground',\n 'not-disabled:not-aria-disabled:hover:bg-subtle-hover not-disabled:not-aria-disabled:active:bg-subtle-pressed',\n 'disabled:pointer-events-none',\n);\n\n/**\n * A numeric input with decrement/increment buttons (APG spinbutton pattern).\n *\n * - **Keyboard** on the input: ArrowUp/ArrowDown step by `step`, PageUp/PageDown by `largeStep`\n * (default ten steps), Home/End jump to `min`/`max` when they are finite. The −/+ buttons are\n * not tab stops and never take focus, so focus stays on the spinbutton and screen readers\n * announce the new value.\n * - **Typing** edits a draft: the value is parsed, clamped and committed on blur or Enter\n * (Escape reverts). Text that is not a number is flagged with `aria-invalid` and reverted on\n * blur. Steps (keys and buttons) start from the typed number, and the −/+ buttons are disabled\n * when that number is at `min`/`max`. Steps are rounded to the precision of `step` and of the\n * value, so `0.1 + 0.2` is `0.3`.\n * - **Routing**: `id`, ARIA, native input attributes and focus/keyboard handlers go to the\n * `<input role=\"spinbutton\">`; `className`, `style`, `data-*`, other handlers and `ref` stay on\n * the root (`controlRef` reaches the input). Inside a `Field` it picks up the label, hint, error\n * and required state automatically. It has no built-in name: pass `aria-label`/`aria-labelledby`\n * or use a label (development warning otherwise).\n * - **Forms**: with `name` the committed value is submitted; `required` makes the input natively\n * required; a form reset restores `defaultValue`.\n * - The −/+ buttons are named \"Decrement\"/\"Increment\"; `labels` localizes the names.\n *\n * @example\n * <SpinButton aria-label=\"Quantity\" min={1} max={10} value={qty} onValueChange={setQty} />\n */\nexport const SpinButton = ({\n value: valueProp,\n defaultValue,\n onValueChange,\n onChange,\n min = -Infinity,\n max = Infinity,\n step = 1,\n largeStep,\n disabled,\n name,\n form,\n labels,\n className,\n hidden,\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 'aria-valuetext': ariaValueText,\n required,\n readOnly,\n placeholder,\n maxLength,\n spellCheck,\n autoComplete = 'off',\n autoFocus,\n inputMode,\n enterKeyHint,\n tabIndex,\n onFocus,\n onBlur,\n onKeyDown,\n onKeyUp,\n ...rest\n}: SpinButtonProps) => {\n if (onChange !== undefined) warnDeprecated('SpinButton', 'onChange', 'onValueChange');\n const initialValue = defaultValue ?? 0;\n const [value, setValue] = useControllable(valueProp, initialValue, (next: number) => {\n onValueChange?.(next);\n onChange?.(next);\n });\n\n // The text is a draft while the user types (null = show the value).\n const [draft, setDraft] = React.useState<string | null>(null);\n // A value that changes from outside replaces the draft (adjust state during render, C-HOOKS).\n const [prevValue, setPrevValue] = React.useState(value);\n if (!Object.is(prevValue, value)) {\n setPrevValue(value);\n setDraft(null);\n }\n\n const draftNumber = draft === null ? null : parseNumberText(draft);\n // What stepping starts from: the typed draft when it is a number, else the value. The −/+\n // buttons are enabled by it too, so they agree with ArrowUp/ArrowDown while the user types.\n const current = draftNumber ?? value;\n const draftInvalid =\n draft !== null &&\n draftNumber === null &&\n draft.trim() !== '' &&\n !PARTIAL_NUMBER_TEXT.test(draft.trim());\n\n const clamp = (n: number) => Math.min(max, Math.max(min, n));\n const interactive = !disabled && !readOnly;\n\n const commit = (next: number) => {\n setDraft(null);\n setValue(clamp(next));\n };\n\n /** Steps from the typed draft when it is a number, else from the value. */\n const stepBy = (delta: number) => {\n const precision = Math.max(decimalsOf(step), decimalsOf(delta), decimalsOf(current));\n commit(roundTo(current + delta, precision));\n };\n\n const commitDraft = () => {\n if (draft === null) return;\n if (draftNumber === null) setDraft(null);\n else commit(draftNumber);\n };\n\n const inputRef = React.useRef<HTMLInputElement>(null);\n const mergedInputRef = useMergedRefs(inputRef, controlRef);\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 // Typed text that is not a number is invalid whatever the consumer says; otherwise the\n // consumer's or the Field's `aria-invalid` is passed through as is (`grammar` included), and the\n // error look follows the shared rule of the text controls.\n const ariaInvalidValue = draftInvalid ? true : fieldProps['aria-invalid'];\n const invalidLook = isInvalidLook(false, ariaInvalidValue);\n\n useFormReset(\n inputRef,\n () => {\n setDraft(null);\n setValue(initialValue);\n },\n form,\n );\n\n // No built-in name any more (\"Value\" named every instance the same): report unnamed inputs.\n React.useEffect(() => {\n const input = inputRef.current;\n if (!input) return;\n const named =\n input.hasAttribute('aria-label') ||\n input.hasAttribute('aria-labelledby') ||\n (input.labels?.length ?? 0) > 0 ||\n input.hasAttribute('title');\n if (!named) {\n warnOnce(\n 'SpinButton:unnamed',\n 'SpinButton: the spinbutton has no accessible name. Pass `aria-label` or `aria-labelledby`, use a <label htmlFor>, or render it inside a Field.',\n );\n }\n });\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n // Read-only: the keys keep their native caret behaviour and never change the value.\n if (!interactive || e.altKey || e.ctrlKey || e.metaKey) return;\n // Ten steps, rounded: step * 10 carries float error (0.07 * 10 = 0.7000000000000001) that\n // stepBy would otherwise keep, since it rounds to the precision of the delta too.\n const big = largeStep ?? roundTo(step * 10, decimalsOf(step));\n switch (e.key) {\n case 'ArrowUp':\n case 'ArrowDown':\n case 'PageUp':\n case 'PageDown': {\n e.preventDefault();\n const size = e.key === 'ArrowUp' || e.key === 'ArrowDown' ? step : big;\n stepBy(e.key === 'ArrowUp' || e.key === 'PageUp' ? size : -size);\n return;\n }\n case 'Home':\n case 'End': {\n const bound = e.key === 'Home' ? min : max;\n if (!Number.isFinite(bound)) return; // no bound: Home/End move the caret\n e.preventDefault();\n commit(bound);\n return;\n }\n case 'Enter':\n // Not prevented: Enter still submits the surrounding form, with the committed value.\n commitDraft();\n return;\n case 'Escape':\n if (draft !== null) {\n e.preventDefault(); // enclosing layers (a Dialog) ignore this Escape\n setDraft(null);\n }\n return;\n default:\n }\n };\n\n const defaultInputMode: React.HTMLAttributes<HTMLInputElement>['inputMode'] =\n min < 0 ? 'text' : decimalsOf(step) > 0 || decimalsOf(min) > 0 ? 'decimal' : 'numeric';\n\n // The step buttons never take focus: a pointer press leaves it where it is (on the input while\n // editing), so a button that becomes disabled at a bound cannot drop focus to <body>.\n const keepFocus = (e: React.MouseEvent) => e.preventDefault();\n\n return (\n <div\n ref={ref}\n className={cn(\n 'relative inline-flex items-center rounded border border-input border-b-stroke-accessible bg-background',\n inputFocusWithin,\n invalidLook && inputInvalidWithin,\n disabled && 'cursor-not-allowed opacity-50',\n className,\n )}\n hidden={hidden}\n {...rest}\n >\n <button\n type=\"button\"\n tabIndex={-1}\n onMouseDown={keepFocus}\n onClick={() => stepBy(-step)}\n disabled={!interactive || current <= min}\n aria-label={labels?.decrement ?? 'Decrement'}\n className={cn(stepButtonClass, 'border-e', !disabled && 'disabled:opacity-50')}\n >\n <SubtractIcon size={12} />\n </button>\n\n <input\n ref={mergedInputRef}\n type=\"text\"\n role=\"spinbutton\"\n inputMode={inputMode ?? defaultInputMode}\n autoComplete={autoComplete}\n autoFocus={autoFocus}\n enterKeyHint={enterKeyHint}\n placeholder={placeholder}\n maxLength={maxLength}\n spellCheck={spellCheck}\n tabIndex={tabIndex}\n readOnly={readOnly}\n form={form}\n {...fieldProps}\n aria-invalid={ariaInvalidValue}\n aria-errormessage={ariaErrorMessage}\n aria-details={ariaDetails}\n aria-valuenow={value}\n aria-valuemin={Number.isFinite(min) ? min : undefined}\n aria-valuemax={Number.isFinite(max) ? max : undefined}\n aria-valuetext={ariaValueText}\n value={draft ?? String(value)}\n onChange={(e) => setDraft(e.target.value)}\n onFocus={onFocus}\n onBlur={composeEventHandlers(onBlur, commitDraft, { checkDefaultPrevented: false })}\n onKeyDown={composeEventHandlers(onKeyDown, handleKeyDown)}\n onKeyUp={onKeyUp}\n disabled={disabled}\n className=\"h-8 w-12 min-w-0 border-none bg-transparent text-center text-body-1 text-foreground focus:outline-hidden disabled:cursor-not-allowed [appearance:textfield]\"\n />\n\n <button\n type=\"button\"\n tabIndex={-1}\n onMouseDown={keepFocus}\n onClick={() => stepBy(step)}\n disabled={!interactive || current >= max}\n aria-label={labels?.increment ?? 'Increment'}\n className={cn(stepButtonClass, 'border-s', !disabled && 'disabled:opacity-50')}\n >\n <AddIcon size={12} />\n </button>\n\n <HiddenInput name={name} form={form} disabled={disabled} value={String(value)} />\n </div>\n );\n};\n\nSpinButton.displayName = 'SpinButton';\n"],"mappings":"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"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn as e } from "../../lib/cn.mjs";
|
|
3
|
+
import { warnDeprecated as t, warnOnce as n } from "../../lib/dev.mjs";
|
|
4
|
+
import { composeEventHandlers as r } from "../../lib/composeEventHandlers.mjs";
|
|
5
|
+
import { useControllable as ee } from "../../hooks/useControllable.mjs";
|
|
6
|
+
import { useMergedRefs as te } from "../../hooks/useMergedRefs.mjs";
|
|
7
|
+
import { useFieldControl as ne } from "../../hooks/useFieldControl.mjs";
|
|
8
|
+
import { inputFocusWithin as i } from "../../lib/styles.mjs";
|
|
9
|
+
import { AddIcon as re, SubtractIcon as ie } from "../../lib/icons.mjs";
|
|
10
|
+
import { isInvalidLook as ae } from "./Input.mjs";
|
|
11
|
+
import { useFormReset as oe } from "../../hooks/useFormReset.mjs";
|
|
12
|
+
import { HiddenInput as se } from "../internal/HiddenInput.mjs";
|
|
13
|
+
import * as a from "react";
|
|
14
|
+
import { jsx as o, jsxs as ce } from "react/jsx-runtime";
|
|
15
|
+
//#region src/components/input/SpinButton.tsx
|
|
16
|
+
var s = /^[+-]?(\d+\.?\d*|\.\d+)(e[+-]?\d+)?$/i, le = /^[+-]?\.?$/;
|
|
17
|
+
function c(e) {
|
|
18
|
+
let t = e.trim();
|
|
19
|
+
if (!s.test(t)) return null;
|
|
20
|
+
let n = Number(t);
|
|
21
|
+
return Number.isFinite(n) ? n : null;
|
|
22
|
+
}
|
|
23
|
+
function l(e) {
|
|
24
|
+
if (!Number.isFinite(e)) return 0;
|
|
25
|
+
let [t, n] = String(e).toLowerCase().split("e"), r = t.split(".")[1]?.length ?? 0;
|
|
26
|
+
return Math.max(0, r - (n ? Number(n) : 0));
|
|
27
|
+
}
|
|
28
|
+
function u(e, t) {
|
|
29
|
+
return Number(e.toFixed(Math.min(t, 20)));
|
|
30
|
+
}
|
|
31
|
+
var d = e("flex h-8 w-8 shrink-0 items-center justify-center border-input bg-transparent p-0 text-foreground", "not-disabled:not-aria-disabled:hover:bg-subtle-hover not-disabled:not-aria-disabled:active:bg-subtle-pressed", "disabled:pointer-events-none"), f = ({ value: s, defaultValue: f, onValueChange: ue, onChange: p, min: m = -Infinity, max: h = Infinity, step: g = 1, largeStep: de, disabled: _, name: fe, form: v, labels: y, className: pe, hidden: me, ref: he, controlRef: b, id: x, "aria-label": S, "aria-labelledby": C, "aria-describedby": w, "aria-invalid": T, "aria-required": E, "aria-errormessage": D, "aria-details": O, "aria-valuetext": k, required: A, readOnly: j, placeholder: M, maxLength: N, spellCheck: P, autoComplete: F = "off", autoFocus: I, inputMode: L, enterKeyHint: R, tabIndex: ge, onFocus: _e, onBlur: ve, onKeyDown: ye, onKeyUp: be, ...xe }) => {
|
|
32
|
+
p !== void 0 && t("SpinButton", "onChange", "onValueChange");
|
|
33
|
+
let z = f ?? 0, [B, V] = ee(s, z, (e) => {
|
|
34
|
+
ue?.(e), p?.(e);
|
|
35
|
+
}), [H, U] = a.useState(null), [Se, Ce] = a.useState(B);
|
|
36
|
+
Object.is(Se, B) || (Ce(B), U(null));
|
|
37
|
+
let W = H === null ? null : c(H), G = W ?? B, we = H !== null && W === null && H.trim() !== "" && !le.test(H.trim()), Te = (e) => Math.min(h, Math.max(m, e)), K = !_ && !j, q = (e) => {
|
|
38
|
+
U(null), V(Te(e));
|
|
39
|
+
}, J = (e) => {
|
|
40
|
+
let t = Math.max(l(g), l(e), l(G));
|
|
41
|
+
q(u(G + e, t));
|
|
42
|
+
}, Y = () => {
|
|
43
|
+
H !== null && (W === null ? U(null) : q(W));
|
|
44
|
+
}, X = a.useRef(null), Ee = te(X, b), Z = ne({
|
|
45
|
+
id: x,
|
|
46
|
+
"aria-label": S,
|
|
47
|
+
"aria-labelledby": C,
|
|
48
|
+
"aria-describedby": w,
|
|
49
|
+
"aria-invalid": T,
|
|
50
|
+
"aria-required": E,
|
|
51
|
+
required: A
|
|
52
|
+
}, { nativeRequired: !0 }), Q = we ? !0 : Z["aria-invalid"], De = ae(!1, Q);
|
|
53
|
+
oe(X, () => {
|
|
54
|
+
U(null), V(z);
|
|
55
|
+
}, v), a.useEffect(() => {
|
|
56
|
+
let e = X.current;
|
|
57
|
+
e && (e.hasAttribute("aria-label") || e.hasAttribute("aria-labelledby") || (e.labels?.length ?? 0) > 0 || e.hasAttribute("title") || n("SpinButton:unnamed", "SpinButton: the spinbutton has no accessible name. Pass `aria-label` or `aria-labelledby`, use a <label htmlFor>, or render it inside a Field."));
|
|
58
|
+
});
|
|
59
|
+
let Oe = (e) => {
|
|
60
|
+
if (!K || e.altKey || e.ctrlKey || e.metaKey) return;
|
|
61
|
+
let t = de ?? u(g * 10, l(g));
|
|
62
|
+
switch (e.key) {
|
|
63
|
+
case "ArrowUp":
|
|
64
|
+
case "ArrowDown":
|
|
65
|
+
case "PageUp":
|
|
66
|
+
case "PageDown": {
|
|
67
|
+
e.preventDefault();
|
|
68
|
+
let n = e.key === "ArrowUp" || e.key === "ArrowDown" ? g : t;
|
|
69
|
+
J(e.key === "ArrowUp" || e.key === "PageUp" ? n : -n);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
case "Home":
|
|
73
|
+
case "End": {
|
|
74
|
+
let t = e.key === "Home" ? m : h;
|
|
75
|
+
if (!Number.isFinite(t)) return;
|
|
76
|
+
e.preventDefault(), q(t);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
case "Enter":
|
|
80
|
+
Y();
|
|
81
|
+
return;
|
|
82
|
+
case "Escape":
|
|
83
|
+
H !== null && (e.preventDefault(), U(null));
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
}, ke = m < 0 ? "text" : l(g) > 0 || l(m) > 0 ? "decimal" : "numeric", $ = (e) => e.preventDefault();
|
|
87
|
+
return /* @__PURE__ */ ce("div", {
|
|
88
|
+
ref: he,
|
|
89
|
+
className: e("relative inline-flex items-center rounded border border-input border-b-stroke-accessible bg-background", i, De && "border-destructive focus-within:border-b-destructive", _ && "cursor-not-allowed opacity-50", pe),
|
|
90
|
+
hidden: me,
|
|
91
|
+
...xe,
|
|
92
|
+
children: [
|
|
93
|
+
/* @__PURE__ */ o("button", {
|
|
94
|
+
type: "button",
|
|
95
|
+
tabIndex: -1,
|
|
96
|
+
onMouseDown: $,
|
|
97
|
+
onClick: () => J(-g),
|
|
98
|
+
disabled: !K || G <= m,
|
|
99
|
+
"aria-label": y?.decrement ?? "Decrement",
|
|
100
|
+
className: e(d, "border-e", !_ && "disabled:opacity-50"),
|
|
101
|
+
children: /* @__PURE__ */ o(ie, { size: 12 })
|
|
102
|
+
}),
|
|
103
|
+
/* @__PURE__ */ o("input", {
|
|
104
|
+
ref: Ee,
|
|
105
|
+
type: "text",
|
|
106
|
+
role: "spinbutton",
|
|
107
|
+
inputMode: L ?? ke,
|
|
108
|
+
autoComplete: F,
|
|
109
|
+
autoFocus: I,
|
|
110
|
+
enterKeyHint: R,
|
|
111
|
+
placeholder: M,
|
|
112
|
+
maxLength: N,
|
|
113
|
+
spellCheck: P,
|
|
114
|
+
tabIndex: ge,
|
|
115
|
+
readOnly: j,
|
|
116
|
+
form: v,
|
|
117
|
+
...Z,
|
|
118
|
+
"aria-invalid": Q,
|
|
119
|
+
"aria-errormessage": D,
|
|
120
|
+
"aria-details": O,
|
|
121
|
+
"aria-valuenow": B,
|
|
122
|
+
"aria-valuemin": Number.isFinite(m) ? m : void 0,
|
|
123
|
+
"aria-valuemax": Number.isFinite(h) ? h : void 0,
|
|
124
|
+
"aria-valuetext": k,
|
|
125
|
+
value: H ?? String(B),
|
|
126
|
+
onChange: (e) => U(e.target.value),
|
|
127
|
+
onFocus: _e,
|
|
128
|
+
onBlur: r(ve, Y, { checkDefaultPrevented: !1 }),
|
|
129
|
+
onKeyDown: r(ye, Oe),
|
|
130
|
+
onKeyUp: be,
|
|
131
|
+
disabled: _,
|
|
132
|
+
className: "h-8 w-12 min-w-0 border-none bg-transparent text-center text-body-1 text-foreground focus:outline-hidden disabled:cursor-not-allowed [appearance:textfield]"
|
|
133
|
+
}),
|
|
134
|
+
/* @__PURE__ */ o("button", {
|
|
135
|
+
type: "button",
|
|
136
|
+
tabIndex: -1,
|
|
137
|
+
onMouseDown: $,
|
|
138
|
+
onClick: () => J(g),
|
|
139
|
+
disabled: !K || G >= h,
|
|
140
|
+
"aria-label": y?.increment ?? "Increment",
|
|
141
|
+
className: e(d, "border-s", !_ && "disabled:opacity-50"),
|
|
142
|
+
children: /* @__PURE__ */ o(re, { size: 12 })
|
|
143
|
+
}),
|
|
144
|
+
/* @__PURE__ */ o(se, {
|
|
145
|
+
name: fe,
|
|
146
|
+
form: v,
|
|
147
|
+
disabled: _,
|
|
148
|
+
value: String(B)
|
|
149
|
+
})
|
|
150
|
+
]
|
|
151
|
+
});
|
|
152
|
+
};
|
|
153
|
+
f.displayName = "SpinButton";
|
|
154
|
+
//#endregion
|
|
155
|
+
export { f as SpinButton };
|
|
156
|
+
|
|
157
|
+
//# sourceMappingURL=SpinButton.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SpinButton.mjs","names":["React","NUMBER_TEXT","PARTIAL_NUMBER_TEXT","parseNumberText","trimmed","text","decimalsOf","n","mantissa","exponent","fraction","roundTo","decimals","stepButtonClass","cn","SpinButton","valueProp","ariaLabel","ariaLabelledBy","ariaDescribedBy","ariaInvalid","ariaRequired","ariaErrorMessage","ariaDetails","ariaValueText","rest","onChange","warnDeprecated","initialValue","defaultValue","value","setValue","useControllable","onValueChange","next","draft","setDraft","prevValue","setPrevValue","draftNumber","current","draftInvalid","clamp","max","min","interactive","disabled","readOnly","commit","stepBy","precision","step","delta","commitDraft","inputRef","mergedInputRef","useMergedRefs","controlRef","fieldProps","useFieldControl","ariaInvalidValue","invalidLook","isInvalidLook","useFormReset","form","input","warnOnce","handleKeyDown","big","largeStep","size","bound","defaultInputMode","keepFocus","inputFocusWithin","className","labels","SubtractIcon","inputMode","composeEventHandlers","onBlur","onKeyDown","AddIcon","HiddenInput"],"sources":["../../../src/components/input/SpinButton.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { warnDeprecated, warnOnce } from '../../lib/dev';\nimport { AddIcon, SubtractIcon } from '../../lib/icons';\nimport { inputFocusWithin, inputInvalidWithin } from '../../lib/styles';\nimport { useControllable } from '../../hooks/useControllable';\nimport { useFieldControl } from '../../hooks/useFieldControl';\nimport { useFormReset } from '../../hooks/useFormReset';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { HiddenInput } from '../internal/HiddenInput';\nimport { isInvalidLook } from './Input';\n\n/**\n * Props that SpinButton routes to its `<input role=\"spinbutton\">` (C-ROUTING): the id, the ARIA\n * naming/validation attributes, native text-input attributes and the focus/keyboard handlers.\n */\nexport type SpinButtonInputProps = 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 | 'aria-valuetext'\n | 'required'\n | 'readOnly'\n | 'placeholder'\n | 'maxLength'\n | 'spellCheck'\n | 'autoComplete'\n | 'autoFocus'\n | 'inputMode'\n | 'enterKeyHint'\n | 'tabIndex'\n | 'onFocus'\n | 'onBlur'\n | 'onKeyDown'\n | 'onKeyUp'\n>;\n\n/**\n * Names of the SpinButton's step buttons, for localization. Each member is optional and falls back\n * to its English default.\n */\nexport interface SpinButtonLabels {\n /** Name of the button that steps up.\n * @default 'Increment'\n */\n increment?: string;\n /** Name of the button that steps down.\n * @default 'Decrement'\n */\n decrement?: string;\n}\n\n/** Properties for the SpinButton component. */\nexport interface SpinButtonProps\n extends\n Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'onChange' | 'defaultValue' | keyof SpinButtonInputProps\n >,\n SpinButtonInputProps {\n /** Controlled numeric value. */\n value?: number;\n /** Initial value for uncontrolled usage (also what a form reset restores).\n * @default 0\n */\n defaultValue?: number;\n /**\n * Called with the new value when it changes: a step (buttons, arrow keys, PageUp/PageDown,\n * Home/End) or a typed value committed on blur or Enter. Not called while the user is typing,\n * nor when the value stays the same.\n */\n onValueChange?: (value: number) => void;\n /**\n * Called with the new value when it changes.\n * @deprecated Use `onValueChange`. (`onChange` is reserved for native change events.)\n */\n onChange?: (value: number) => void;\n /** Minimum allowed value.\n * @default -Infinity\n */\n min?: number;\n /** Maximum allowed value.\n * @default Infinity\n */\n max?: number;\n /** Step of the increment/decrement buttons and of ArrowUp/ArrowDown.\n * @default 1\n */\n step?: number;\n /** Step of PageUp/PageDown.\n * @default step * 10\n */\n largeStep?: number;\n /** Whether the spin button is disabled and non-interactive. */\n disabled?: boolean;\n /** Form field name. With a name, the committed value is submitted with the form. */\n name?: string;\n /** Id of the form the spin button belongs to, when it is rendered outside that form. */\n form?: string;\n /**\n * Names of the −/+ step buttons (not tab stops, but in the accessibility tree), for\n * localization. Unset members keep their English defaults.\n */\n labels?: SpinButtonLabels;\n /** Ref to the root `<div>`. */\n ref?: React.Ref<HTMLDivElement>;\n /** Ref to the `<input role=\"spinbutton\">` (the focusable control). */\n controlRef?: React.Ref<HTMLInputElement>;\n}\n\n/** Decimal numbers as a user types them: `12`, `-3`, `1.5`, `.5`, `2.`, `1e3`. */\nconst NUMBER_TEXT = /^[+-]?(\\d+\\.?\\d*|\\.\\d+)(e[+-]?\\d+)?$/i;\n/** Text on the way to a number (`-`, `.`, `-.`): not a value yet, but not an error either. */\nconst PARTIAL_NUMBER_TEXT = /^[+-]?\\.?$/;\n\nfunction parseNumberText(text: string): number | null {\n const trimmed = text.trim();\n if (!NUMBER_TEXT.test(trimmed)) return null;\n const n = Number(trimmed);\n return Number.isFinite(n) ? n : null;\n}\n\n/** Number of decimals of `n` as written by JavaScript (`0.1` → 1, `1e-7` → 7). */\nfunction decimalsOf(n: number): number {\n if (!Number.isFinite(n)) return 0;\n const [mantissa, exponent] = String(n).toLowerCase().split('e');\n const fraction = mantissa.split('.')[1]?.length ?? 0;\n return Math.max(0, fraction - (exponent ? Number(exponent) : 0));\n}\n\nfunction roundTo(n: number, decimals: number): number {\n return Number(n.toFixed(Math.min(decimals, 20)));\n}\n\nconst stepButtonClass = cn(\n // Padding and background set here (C-NATIVE): an app-wide `button` rule cannot fill them.\n 'flex h-8 w-8 shrink-0 items-center justify-center border-input bg-transparent p-0 text-foreground',\n 'not-disabled:not-aria-disabled:hover:bg-subtle-hover not-disabled:not-aria-disabled:active:bg-subtle-pressed',\n 'disabled:pointer-events-none',\n);\n\n/**\n * A numeric input with decrement/increment buttons (APG spinbutton pattern).\n *\n * - **Keyboard** on the input: ArrowUp/ArrowDown step by `step`, PageUp/PageDown by `largeStep`\n * (default ten steps), Home/End jump to `min`/`max` when they are finite. The −/+ buttons are\n * not tab stops and never take focus, so focus stays on the spinbutton and screen readers\n * announce the new value.\n * - **Typing** edits a draft: the value is parsed, clamped and committed on blur or Enter\n * (Escape reverts). Text that is not a number is flagged with `aria-invalid` and reverted on\n * blur. Steps (keys and buttons) start from the typed number, and the −/+ buttons are disabled\n * when that number is at `min`/`max`. Steps are rounded to the precision of `step` and of the\n * value, so `0.1 + 0.2` is `0.3`.\n * - **Routing**: `id`, ARIA, native input attributes and focus/keyboard handlers go to the\n * `<input role=\"spinbutton\">`; `className`, `style`, `data-*`, other handlers and `ref` stay on\n * the root (`controlRef` reaches the input). Inside a `Field` it picks up the label, hint, error\n * and required state automatically. It has no built-in name: pass `aria-label`/`aria-labelledby`\n * or use a label (development warning otherwise).\n * - **Forms**: with `name` the committed value is submitted; `required` makes the input natively\n * required; a form reset restores `defaultValue`.\n * - The −/+ buttons are named \"Decrement\"/\"Increment\"; `labels` localizes the names.\n *\n * @example\n * <SpinButton aria-label=\"Quantity\" min={1} max={10} value={qty} onValueChange={setQty} />\n */\nexport const SpinButton = ({\n value: valueProp,\n defaultValue,\n onValueChange,\n onChange,\n min = -Infinity,\n max = Infinity,\n step = 1,\n largeStep,\n disabled,\n name,\n form,\n labels,\n className,\n hidden,\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 'aria-valuetext': ariaValueText,\n required,\n readOnly,\n placeholder,\n maxLength,\n spellCheck,\n autoComplete = 'off',\n autoFocus,\n inputMode,\n enterKeyHint,\n tabIndex,\n onFocus,\n onBlur,\n onKeyDown,\n onKeyUp,\n ...rest\n}: SpinButtonProps) => {\n if (onChange !== undefined) warnDeprecated('SpinButton', 'onChange', 'onValueChange');\n const initialValue = defaultValue ?? 0;\n const [value, setValue] = useControllable(valueProp, initialValue, (next: number) => {\n onValueChange?.(next);\n onChange?.(next);\n });\n\n // The text is a draft while the user types (null = show the value).\n const [draft, setDraft] = React.useState<string | null>(null);\n // A value that changes from outside replaces the draft (adjust state during render, C-HOOKS).\n const [prevValue, setPrevValue] = React.useState(value);\n if (!Object.is(prevValue, value)) {\n setPrevValue(value);\n setDraft(null);\n }\n\n const draftNumber = draft === null ? null : parseNumberText(draft);\n // What stepping starts from: the typed draft when it is a number, else the value. The −/+\n // buttons are enabled by it too, so they agree with ArrowUp/ArrowDown while the user types.\n const current = draftNumber ?? value;\n const draftInvalid =\n draft !== null &&\n draftNumber === null &&\n draft.trim() !== '' &&\n !PARTIAL_NUMBER_TEXT.test(draft.trim());\n\n const clamp = (n: number) => Math.min(max, Math.max(min, n));\n const interactive = !disabled && !readOnly;\n\n const commit = (next: number) => {\n setDraft(null);\n setValue(clamp(next));\n };\n\n /** Steps from the typed draft when it is a number, else from the value. */\n const stepBy = (delta: number) => {\n const precision = Math.max(decimalsOf(step), decimalsOf(delta), decimalsOf(current));\n commit(roundTo(current + delta, precision));\n };\n\n const commitDraft = () => {\n if (draft === null) return;\n if (draftNumber === null) setDraft(null);\n else commit(draftNumber);\n };\n\n const inputRef = React.useRef<HTMLInputElement>(null);\n const mergedInputRef = useMergedRefs(inputRef, controlRef);\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 // Typed text that is not a number is invalid whatever the consumer says; otherwise the\n // consumer's or the Field's `aria-invalid` is passed through as is (`grammar` included), and the\n // error look follows the shared rule of the text controls.\n const ariaInvalidValue = draftInvalid ? true : fieldProps['aria-invalid'];\n const invalidLook = isInvalidLook(false, ariaInvalidValue);\n\n useFormReset(\n inputRef,\n () => {\n setDraft(null);\n setValue(initialValue);\n },\n form,\n );\n\n // No built-in name any more (\"Value\" named every instance the same): report unnamed inputs.\n React.useEffect(() => {\n const input = inputRef.current;\n if (!input) return;\n const named =\n input.hasAttribute('aria-label') ||\n input.hasAttribute('aria-labelledby') ||\n (input.labels?.length ?? 0) > 0 ||\n input.hasAttribute('title');\n if (!named) {\n warnOnce(\n 'SpinButton:unnamed',\n 'SpinButton: the spinbutton has no accessible name. Pass `aria-label` or `aria-labelledby`, use a <label htmlFor>, or render it inside a Field.',\n );\n }\n });\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n // Read-only: the keys keep their native caret behaviour and never change the value.\n if (!interactive || e.altKey || e.ctrlKey || e.metaKey) return;\n // Ten steps, rounded: step * 10 carries float error (0.07 * 10 = 0.7000000000000001) that\n // stepBy would otherwise keep, since it rounds to the precision of the delta too.\n const big = largeStep ?? roundTo(step * 10, decimalsOf(step));\n switch (e.key) {\n case 'ArrowUp':\n case 'ArrowDown':\n case 'PageUp':\n case 'PageDown': {\n e.preventDefault();\n const size = e.key === 'ArrowUp' || e.key === 'ArrowDown' ? step : big;\n stepBy(e.key === 'ArrowUp' || e.key === 'PageUp' ? size : -size);\n return;\n }\n case 'Home':\n case 'End': {\n const bound = e.key === 'Home' ? min : max;\n if (!Number.isFinite(bound)) return; // no bound: Home/End move the caret\n e.preventDefault();\n commit(bound);\n return;\n }\n case 'Enter':\n // Not prevented: Enter still submits the surrounding form, with the committed value.\n commitDraft();\n return;\n case 'Escape':\n if (draft !== null) {\n e.preventDefault(); // enclosing layers (a Dialog) ignore this Escape\n setDraft(null);\n }\n return;\n default:\n }\n };\n\n const defaultInputMode: React.HTMLAttributes<HTMLInputElement>['inputMode'] =\n min < 0 ? 'text' : decimalsOf(step) > 0 || decimalsOf(min) > 0 ? 'decimal' : 'numeric';\n\n // The step buttons never take focus: a pointer press leaves it where it is (on the input while\n // editing), so a button that becomes disabled at a bound cannot drop focus to <body>.\n const keepFocus = (e: React.MouseEvent) => e.preventDefault();\n\n return (\n <div\n ref={ref}\n className={cn(\n 'relative inline-flex items-center rounded border border-input border-b-stroke-accessible bg-background',\n inputFocusWithin,\n invalidLook && inputInvalidWithin,\n disabled && 'cursor-not-allowed opacity-50',\n className,\n )}\n hidden={hidden}\n {...rest}\n >\n <button\n type=\"button\"\n tabIndex={-1}\n onMouseDown={keepFocus}\n onClick={() => stepBy(-step)}\n disabled={!interactive || current <= min}\n aria-label={labels?.decrement ?? 'Decrement'}\n className={cn(stepButtonClass, 'border-e', !disabled && 'disabled:opacity-50')}\n >\n <SubtractIcon size={12} />\n </button>\n\n <input\n ref={mergedInputRef}\n type=\"text\"\n role=\"spinbutton\"\n inputMode={inputMode ?? defaultInputMode}\n autoComplete={autoComplete}\n autoFocus={autoFocus}\n enterKeyHint={enterKeyHint}\n placeholder={placeholder}\n maxLength={maxLength}\n spellCheck={spellCheck}\n tabIndex={tabIndex}\n readOnly={readOnly}\n form={form}\n {...fieldProps}\n aria-invalid={ariaInvalidValue}\n aria-errormessage={ariaErrorMessage}\n aria-details={ariaDetails}\n aria-valuenow={value}\n aria-valuemin={Number.isFinite(min) ? min : undefined}\n aria-valuemax={Number.isFinite(max) ? max : undefined}\n aria-valuetext={ariaValueText}\n value={draft ?? String(value)}\n onChange={(e) => setDraft(e.target.value)}\n onFocus={onFocus}\n onBlur={composeEventHandlers(onBlur, commitDraft, { checkDefaultPrevented: false })}\n onKeyDown={composeEventHandlers(onKeyDown, handleKeyDown)}\n onKeyUp={onKeyUp}\n disabled={disabled}\n className=\"h-8 w-12 min-w-0 border-none bg-transparent text-center text-body-1 text-foreground focus:outline-hidden disabled:cursor-not-allowed [appearance:textfield]\"\n />\n\n <button\n type=\"button\"\n tabIndex={-1}\n onMouseDown={keepFocus}\n onClick={() => stepBy(step)}\n disabled={!interactive || current >= max}\n aria-label={labels?.increment ?? 'Increment'}\n className={cn(stepButtonClass, 'border-s', !disabled && 'disabled:opacity-50')}\n >\n <AddIcon size={12} />\n </button>\n\n <HiddenInput name={name} form={form} disabled={disabled} value={String(value)} />\n </div>\n );\n};\n\nSpinButton.displayName = 'SpinButton';\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/dev.cjs"),r=require("../../lib/composeEventHandlers.cjs"),i=require("../../hooks/useControllable.cjs"),a=require("../../hooks/useRovingTabIndex.cjs"),o=require("../../hooks/useMergedRefs.cjs"),s=require("../../hooks/useFieldControl.cjs"),c=require("../../lib/styles.cjs"),l=require("../../lib/icons.cjs"),u=require("../../hooks/useFormReset.cjs"),d=require("../internal/HiddenInput.cjs"),f=require("./colorUtils.cjs");let p=require("react");p=e.__toESM(p,1);let m=require("react/jsx-runtime");var h={small:`w-6 h-6`,medium:`w-8 h-8`,large:`w-10 h-10`},g={small:12,medium:16,large:20},_={circular:`rounded-full`,square:`rounded-none`,rounded:`rounded`};function v({color:e,size:t}){let{glyph:n,halo:r}=f.getCheckColors(e);return(0,m.jsxs)(`span`,{"aria-hidden":`true`,className:`pointer-events-none grid`,children:[(0,m.jsx)(l.CheckIcon,{size:t,strokeWidth:4,className:`col-start-1 row-start-1`,style:{color:r}}),(0,m.jsx)(l.CheckIcon,{size:t,strokeWidth:2,className:`col-start-1 row-start-1`,style:{color:n}})]})}var y=({items:e,value:l,defaultValue:f,onValueChange:y,onChange:b,size:x=`medium`,shape:S=`circular`,name:C,required:w,form:T,className:E,id:D,"aria-label":O,"aria-labelledby":k,"aria-describedby":A,"aria-invalid":j,"aria-required":M,onKeyDown:N,onFocus:P,ref:F,...I})=>{b!==void 0&&n.warnDeprecated(`SwatchPicker`,`onChange`,`onValueChange`);let L=f??``,[R,z]=i.useControllable(l,L,e=>{y?.(e),b?.(e)}),{containerProps:B,getTabIndex:V}=a.useRovingTabIndex({activeValue:R||null,orientation:`both`,onFocusMove:e=>z(e)}),H=p.useRef(null),U=o.useMergedRefs(F,B.ref,H),W=s.useFieldContext(),G=s.useFieldControl({id:D,"aria-label":O,"aria-labelledby":k,"aria-describedby":A,"aria-invalid":j,"aria-required":M??w},{labelable:!1}),K=w??W?.required??!1,q=G[`aria-label`]===void 0&&G[`aria-labelledby`]===void 0,J=e.find(e=>!e.label)?.value;p.useEffect(()=>{q&&n.warnOnce(`SwatchPicker:unnamed`,"SwatchPicker: the radiogroup has no accessible name. Pass `aria-label` or `aria-labelledby`, or render it inside a Field.")},[q]),p.useEffect(()=>{J!==void 0&&n.warnOnce(`SwatchPicker:item-label`,`SwatchPicker: swatch "${J}" has no \`label\`, so it is announced by its color value. Give every item a \`label\`.`)},[J]),u.useFormReset(H,()=>z(L),T);let Y=()=>{H.current?.querySelector(`[data-roving-value][tabindex="0"]`)?.focus()};return(0,m.jsxs)(`div`,{role:`radiogroup`,...G,className:t.cn(`relative flex flex-wrap gap-2`,E),...I,ref:U,"data-roving-container":``,onKeyDown:r.composeEventHandlers(N,B.onKeyDown),onFocus:r.composeEventHandlers(P,B.onFocus,{checkDefaultPrevented:!1}),children:[e.map(e=>{let n=R===e.value;return(0,m.jsx)(`button`,{type:`button`,role:`radio`,"aria-checked":n,"aria-label":e.label||e.color,"data-roving-value":e.value,"data-selected":n?``:void 0,tabIndex:V(e.value),onClick:()=>z(e.value),className:t.cn(h[x],_[S],`relative flex shrink-0 items-center justify-center border-2 border-transparent p-0`,c.motionSafeTransition,`forced-colors:forced-color-adjust-none`,c.forcedColors.border,c.focusRing,`focus-visible:outline-offset-4`,n?`ring-2 ring-foreground ring-offset-2 ring-offset-background`:`hover:border-stroke-hover`),style:{backgroundColor:e.color},children:n&&(0,m.jsx)(v,{color:e.color,size:g[x]})},e.value)}),(0,m.jsx)(d.HiddenInput,{type:`radio`,name:C,form:T,value:R,required:K,onInvalid:Y})]})};y.displayName=`SwatchPicker`,exports.SwatchPicker=y;
|
|
2
|
+
//# sourceMappingURL=SwatchPicker.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SwatchPicker.cjs","names":["getCheckColors","CheckIcon","useControllable","useRovingTabIndex","React","useMergedRefs","useFieldContext","useFieldControl","cn","composeEventHandlers","motionSafeTransition","forcedColors","focusRing","HiddenInput","require_runtime","require_cn","require_dev","require_composeEventHandlers","require_useControllable","require_useRovingTabIndex","require_useMergedRefs","require_useFieldControl","require_styles","require_icons","require_useFormReset","require_HiddenInput","require_colorUtils","react","react_jsx_runtime","sizeMap","checkSizeMap","shapeMap","SwatchCheck","color","halo","glyph","SwatchPicker","valueProp","ariaLabel","ariaLabelledBy","ariaDescribedBy","ariaInvalid","ariaRequired","rest","onChange","initialValue","defaultValue","value","setValue","onValueChange","next","rootRef","mergedRef","ref","containerProps","field","fieldProps","required","isRequired","unnamed","unlabelledItem","items","item","form","focusTabStop","className","onKeyDown","onFocus","isSelected","getTabIndex","size","shape"],"sources":["../../../src/components/input/SwatchPicker.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { warnDeprecated, warnOnce } from '../../lib/dev';\nimport { CheckIcon } from '../../lib/icons';\nimport { focusRing, forcedColors, motionSafeTransition } from '../../lib/styles';\nimport type { Shape, Size } from '../../lib/types';\nimport { useControllable } from '../../hooks/useControllable';\nimport { useFieldContext, useFieldControl } from '../../hooks/useFieldControl';\nimport { useFormReset } from '../../hooks/useFormReset';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { useRovingTabIndex } from '../../hooks/useRovingTabIndex';\nimport { HiddenInput } from '../internal/HiddenInput';\nimport { getCheckColors } from './colorUtils';\n\n/** Represents a single color swatch option. */\nexport interface SwatchItem {\n /** Unique identifier for the swatch (the value `onValueChange` reports and a form submits). */\n value: string;\n /** CSS color value (e.g., hex, rgb) used as the swatch background. */\n color: string;\n /**\n * Accessible name of the swatch, e.g. `'Cranberry'`. **Required for accessibility**: without it\n * the swatch is announced by its raw color value (`'#d13438'`) and a development warning is\n * logged.\n */\n label?: string;\n}\n\n/** Size of the swatches. */\nexport type SwatchPickerSize = Extract<Size, 'small' | 'medium' | 'large'>;\n\n/** Properties for the SwatchPicker component. */\nexport interface SwatchPickerProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'onChange' | 'defaultValue'\n> {\n /** The swatches to display, in order (a readonly array is accepted; it is never modified). */\n items: readonly SwatchItem[];\n /** Controlled selected swatch value (`''` = nothing selected). */\n value?: string;\n /** Initial selected value for uncontrolled usage (also what a form reset restores).\n * @default ''\n */\n defaultValue?: string;\n /** Called with the new value when the selection changes (not when the selected swatch is chosen again). */\n onValueChange?: (value: string) => void;\n /**\n * Called with the new value when the selection changes.\n * @deprecated Use `onValueChange`.\n */\n onChange?: (value: string) => void;\n /** Size of each swatch button (24, 32 or 40px).\n * @default 'medium'\n */\n size?: SwatchPickerSize;\n /** Shape of each swatch button.\n * @default 'circular'\n */\n shape?: Shape;\n /**\n * Form field name. With a name, the selected swatch's `value` is submitted with the form\n * (nothing while no swatch is selected).\n */\n name?: string;\n /** A swatch must be selected before the form can be submitted (native validation). */\n required?: boolean;\n /** Id of the form the picker belongs to, when it is rendered outside that form. */\n form?: string;\n /** Ref to the `role=\"radiogroup\"` element. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\nconst sizeMap: Record<SwatchPickerSize, string> = {\n small: 'w-6 h-6',\n medium: 'w-8 h-8',\n large: 'w-10 h-10',\n};\n\nconst checkSizeMap: Record<SwatchPickerSize, number> = {\n small: 12,\n medium: 16,\n large: 20,\n};\n\nconst shapeMap: Record<Shape, string> = {\n circular: 'rounded-full',\n square: 'rounded-none',\n rounded: 'rounded',\n};\n\n/**\n * The check glyph of the selected swatch: black or white by the swatch's luminance, drawn over a\n * halo in the other color so it stays visible on any swatch (C-TOKENS exception for\n * user-supplied colors, `input-pickers#16`).\n */\nfunction SwatchCheck({ color, size }: { color: string; size: number }) {\n const { glyph, halo } = getCheckColors(color);\n return (\n <span aria-hidden=\"true\" className=\"pointer-events-none grid\">\n <CheckIcon\n size={size}\n strokeWidth={4}\n className=\"col-start-1 row-start-1\"\n style={{ color: halo }}\n />\n <CheckIcon\n size={size}\n strokeWidth={2}\n className=\"col-start-1 row-start-1\"\n style={{ color: glyph }}\n />\n </span>\n );\n}\n\n/**\n * A single-select grid of color swatches (`role=\"radiogroup\"` of `role=\"radio\"` buttons).\n *\n * - **Keyboard** (APG radio group): one tab stop — the selected swatch, else the first. All four\n * arrow keys move focus and select (Left/Right mirrored under `dir=\"rtl\"`), wrapping at the\n * ends; Home/End jump to the first/last swatch.\n * - **Selected indicator**: an offset ring in the foreground color (drawn on the page background,\n * not on the swatch) plus a check glyph whose color is picked by the swatch's luminance, so the\n * selection never relies on color alone.\n * - **Naming**: give the group a name with `aria-label`/`aria-labelledby` or render it inside a\n * `Field`, and give every item a `label`; both are reported in development when missing.\n * - **Forms**: with `name` (or `required`) it takes part in native forms; a form reset restores\n * `defaultValue`.\n *\n * @example\n * <SwatchPicker aria-label=\"Accent color\" items={[{ value: 'red', color: '#d13438', label: 'Red' }]} />\n */\nexport const SwatchPicker = ({\n items,\n value: valueProp,\n defaultValue,\n onValueChange,\n onChange,\n size = 'medium',\n shape = 'circular',\n name,\n required,\n form,\n className,\n id,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n 'aria-invalid': ariaInvalid,\n 'aria-required': ariaRequired,\n onKeyDown,\n onFocus,\n ref,\n ...rest\n}: SwatchPickerProps) => {\n if (onChange !== undefined) warnDeprecated('SwatchPicker', 'onChange', 'onValueChange');\n const initialValue = defaultValue ?? '';\n const [value, setValue] = useControllable(valueProp, initialValue, (next: string) => {\n onValueChange?.(next);\n onChange?.(next);\n });\n\n const { containerProps, getTabIndex } = useRovingTabIndex({\n activeValue: value || null,\n orientation: 'both',\n // APG radio group: moving focus also selects.\n onFocusMove: (next) => setValue(next),\n });\n\n const rootRef = React.useRef<HTMLDivElement>(null);\n const mergedRef = useMergedRefs<HTMLDivElement>(ref, containerProps.ref, rootRef);\n\n const field = useFieldContext();\n const fieldProps = useFieldControl(\n {\n id,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n 'aria-invalid': ariaInvalid,\n // An explicit `required={false}` wins over a required Field, so aria-required matches\n // `isRequired`.\n 'aria-required': ariaRequired ?? required,\n },\n { labelable: false },\n );\n const isRequired = required ?? field?.required ?? false;\n\n const unnamed =\n fieldProps['aria-label'] === undefined && fieldProps['aria-labelledby'] === undefined;\n const unlabelledItem = items.find((item) => !item.label)?.value;\n React.useEffect(() => {\n if (unnamed) {\n warnOnce(\n 'SwatchPicker:unnamed',\n 'SwatchPicker: the radiogroup has no accessible name. Pass `aria-label` or `aria-labelledby`, or render it inside a Field.',\n );\n }\n }, [unnamed]);\n React.useEffect(() => {\n if (unlabelledItem !== undefined) {\n warnOnce(\n 'SwatchPicker:item-label',\n `SwatchPicker: swatch \"${unlabelledItem}\" has no \\`label\\`, so it is announced by its color value. Give every item a \\`label\\`.`,\n );\n }\n }, [unlabelledItem]);\n\n useFormReset(rootRef, () => setValue(initialValue), form);\n\n const focusTabStop = () => {\n rootRef.current?.querySelector<HTMLElement>('[data-roving-value][tabindex=\"0\"]')?.focus();\n };\n\n return (\n <div\n role=\"radiogroup\"\n {...fieldProps}\n className={cn('relative flex flex-wrap gap-2', className)}\n {...rest}\n ref={mergedRef}\n data-roving-container=\"\"\n onKeyDown={composeEventHandlers(onKeyDown, containerProps.onKeyDown)}\n onFocus={composeEventHandlers(onFocus, containerProps.onFocus, {\n checkDefaultPrevented: false,\n })}\n >\n {items.map((item) => {\n const isSelected = value === item.value;\n return (\n <button\n key={item.value}\n type=\"button\"\n role=\"radio\"\n aria-checked={isSelected}\n aria-label={item.label || item.color}\n data-roving-value={item.value}\n data-selected={isSelected ? '' : undefined}\n tabIndex={getTabIndex(item.value)}\n onClick={() => setValue(item.value)}\n className={cn(\n sizeMap[size],\n shapeMap[shape],\n // The padding is set here (C-NATIVE); the swatch color is its background.\n 'relative flex shrink-0 items-center justify-center border-2 border-transparent p-0',\n motionSafeTransition,\n // User colors are the content: keep them (and the check glyph) in forced colors.\n 'forced-colors:forced-color-adjust-none',\n forcedColors.border,\n focusRing,\n // Outside the selection ring, so both stay visible together.\n 'focus-visible:outline-offset-4',\n isSelected\n ? 'ring-2 ring-foreground ring-offset-2 ring-offset-background'\n : 'hover:border-stroke-hover',\n )}\n style={{ backgroundColor: item.color }}\n >\n {isSelected && <SwatchCheck color={item.color} size={checkSizeMap[size]} />}\n </button>\n );\n })}\n <HiddenInput\n type=\"radio\"\n name={name}\n form={form}\n value={value}\n required={isRequired}\n onInvalid={focusTabStop}\n />\n </div>\n );\n};\n\nSwatchPicker.displayName = 'SwatchPicker';\n"],"mappings":"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"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn as e } from "../../lib/cn.mjs";
|
|
3
|
+
import { warnDeprecated as t, warnOnce as n } from "../../lib/dev.mjs";
|
|
4
|
+
import { composeEventHandlers as r } from "../../lib/composeEventHandlers.mjs";
|
|
5
|
+
import { useControllable as i } from "../../hooks/useControllable.mjs";
|
|
6
|
+
import { useRovingTabIndex as a } from "../../hooks/useRovingTabIndex.mjs";
|
|
7
|
+
import { useMergedRefs as o } from "../../hooks/useMergedRefs.mjs";
|
|
8
|
+
import { useFieldContext as s, useFieldControl as c } from "../../hooks/useFieldControl.mjs";
|
|
9
|
+
import { focusRing as l, forcedColors as u, motionSafeTransition as d } from "../../lib/styles.mjs";
|
|
10
|
+
import { CheckIcon as f } from "../../lib/icons.mjs";
|
|
11
|
+
import { useFormReset as p } from "../../hooks/useFormReset.mjs";
|
|
12
|
+
import { HiddenInput as m } from "../internal/HiddenInput.mjs";
|
|
13
|
+
import { getCheckColors as h } from "./colorUtils.mjs";
|
|
14
|
+
import * as g from "react";
|
|
15
|
+
import { jsx as _, jsxs as v } from "react/jsx-runtime";
|
|
16
|
+
//#region src/components/input/SwatchPicker.tsx
|
|
17
|
+
var y = {
|
|
18
|
+
small: "w-6 h-6",
|
|
19
|
+
medium: "w-8 h-8",
|
|
20
|
+
large: "w-10 h-10"
|
|
21
|
+
}, b = {
|
|
22
|
+
small: 12,
|
|
23
|
+
medium: 16,
|
|
24
|
+
large: 20
|
|
25
|
+
}, x = {
|
|
26
|
+
circular: "rounded-full",
|
|
27
|
+
square: "rounded-none",
|
|
28
|
+
rounded: "rounded"
|
|
29
|
+
};
|
|
30
|
+
function S({ color: e, size: t }) {
|
|
31
|
+
let { glyph: n, halo: r } = h(e);
|
|
32
|
+
return /* @__PURE__ */ v("span", {
|
|
33
|
+
"aria-hidden": "true",
|
|
34
|
+
className: "pointer-events-none grid",
|
|
35
|
+
children: [/* @__PURE__ */ _(f, {
|
|
36
|
+
size: t,
|
|
37
|
+
strokeWidth: 4,
|
|
38
|
+
className: "col-start-1 row-start-1",
|
|
39
|
+
style: { color: r }
|
|
40
|
+
}), /* @__PURE__ */ _(f, {
|
|
41
|
+
size: t,
|
|
42
|
+
strokeWidth: 2,
|
|
43
|
+
className: "col-start-1 row-start-1",
|
|
44
|
+
style: { color: n }
|
|
45
|
+
})]
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
var C = ({ items: f, value: h, defaultValue: C, onValueChange: w, onChange: T, size: E = "medium", shape: D = "circular", name: O, required: k, form: A, className: j, id: M, "aria-label": N, "aria-labelledby": P, "aria-describedby": F, "aria-invalid": I, "aria-required": L, onKeyDown: R, onFocus: z, ref: B, ...V }) => {
|
|
49
|
+
T !== void 0 && t("SwatchPicker", "onChange", "onValueChange");
|
|
50
|
+
let H = C ?? "", [U, W] = i(h, H, (e) => {
|
|
51
|
+
w?.(e), T?.(e);
|
|
52
|
+
}), { containerProps: G, getTabIndex: K } = a({
|
|
53
|
+
activeValue: U || null,
|
|
54
|
+
orientation: "both",
|
|
55
|
+
onFocusMove: (e) => W(e)
|
|
56
|
+
}), q = g.useRef(null), J = o(B, G.ref, q), Y = s(), X = c({
|
|
57
|
+
id: M,
|
|
58
|
+
"aria-label": N,
|
|
59
|
+
"aria-labelledby": P,
|
|
60
|
+
"aria-describedby": F,
|
|
61
|
+
"aria-invalid": I,
|
|
62
|
+
"aria-required": L ?? k
|
|
63
|
+
}, { labelable: !1 }), Z = k ?? Y?.required ?? !1, Q = X["aria-label"] === void 0 && X["aria-labelledby"] === void 0, $ = f.find((e) => !e.label)?.value;
|
|
64
|
+
g.useEffect(() => {
|
|
65
|
+
Q && n("SwatchPicker:unnamed", "SwatchPicker: the radiogroup has no accessible name. Pass `aria-label` or `aria-labelledby`, or render it inside a Field.");
|
|
66
|
+
}, [Q]), g.useEffect(() => {
|
|
67
|
+
$ !== void 0 && n("SwatchPicker:item-label", `SwatchPicker: swatch "${$}" has no \`label\`, so it is announced by its color value. Give every item a \`label\`.`);
|
|
68
|
+
}, [$]), p(q, () => W(H), A);
|
|
69
|
+
let ee = () => {
|
|
70
|
+
q.current?.querySelector("[data-roving-value][tabindex=\"0\"]")?.focus();
|
|
71
|
+
};
|
|
72
|
+
return /* @__PURE__ */ v("div", {
|
|
73
|
+
role: "radiogroup",
|
|
74
|
+
...X,
|
|
75
|
+
className: e("relative flex flex-wrap gap-2", j),
|
|
76
|
+
...V,
|
|
77
|
+
ref: J,
|
|
78
|
+
"data-roving-container": "",
|
|
79
|
+
onKeyDown: r(R, G.onKeyDown),
|
|
80
|
+
onFocus: r(z, G.onFocus, { checkDefaultPrevented: !1 }),
|
|
81
|
+
children: [f.map((t) => {
|
|
82
|
+
let n = U === t.value;
|
|
83
|
+
return /* @__PURE__ */ _("button", {
|
|
84
|
+
type: "button",
|
|
85
|
+
role: "radio",
|
|
86
|
+
"aria-checked": n,
|
|
87
|
+
"aria-label": t.label || t.color,
|
|
88
|
+
"data-roving-value": t.value,
|
|
89
|
+
"data-selected": n ? "" : void 0,
|
|
90
|
+
tabIndex: K(t.value),
|
|
91
|
+
onClick: () => W(t.value),
|
|
92
|
+
className: e(y[E], x[D], "relative flex shrink-0 items-center justify-center border-2 border-transparent p-0", d, "forced-colors:forced-color-adjust-none", u.border, l, "focus-visible:outline-offset-4", n ? "ring-2 ring-foreground ring-offset-2 ring-offset-background" : "hover:border-stroke-hover"),
|
|
93
|
+
style: { backgroundColor: t.color },
|
|
94
|
+
children: n && /* @__PURE__ */ _(S, {
|
|
95
|
+
color: t.color,
|
|
96
|
+
size: b[E]
|
|
97
|
+
})
|
|
98
|
+
}, t.value);
|
|
99
|
+
}), /* @__PURE__ */ _(m, {
|
|
100
|
+
type: "radio",
|
|
101
|
+
name: O,
|
|
102
|
+
form: A,
|
|
103
|
+
value: U,
|
|
104
|
+
required: Z,
|
|
105
|
+
onInvalid: ee
|
|
106
|
+
})]
|
|
107
|
+
});
|
|
108
|
+
};
|
|
109
|
+
C.displayName = "SwatchPicker";
|
|
110
|
+
//#endregion
|
|
111
|
+
export { C as SwatchPicker };
|
|
112
|
+
|
|
113
|
+
//# sourceMappingURL=SwatchPicker.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SwatchPicker.mjs","names":["React","sizeMap","checkSizeMap","shapeMap","SwatchCheck","getCheckColors","color","CheckIcon","halo","glyph","SwatchPicker","valueProp","ariaLabel","ariaLabelledBy","ariaDescribedBy","ariaInvalid","ariaRequired","rest","onChange","warnDeprecated","initialValue","defaultValue","value","setValue","useControllable","onValueChange","next","useRovingTabIndex","rootRef","mergedRef","useMergedRefs","ref","containerProps","field","useFieldContext","fieldProps","useFieldControl","required","isRequired","unnamed","unlabelledItem","items","item","warnOnce","useFormReset","form","focusTabStop","cn","className","composeEventHandlers","onKeyDown","onFocus","isSelected","getTabIndex","size","shape","motionSafeTransition","forcedColors","focusRing","HiddenInput"],"sources":["../../../src/components/input/SwatchPicker.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { warnDeprecated, warnOnce } from '../../lib/dev';\nimport { CheckIcon } from '../../lib/icons';\nimport { focusRing, forcedColors, motionSafeTransition } from '../../lib/styles';\nimport type { Shape, Size } from '../../lib/types';\nimport { useControllable } from '../../hooks/useControllable';\nimport { useFieldContext, useFieldControl } from '../../hooks/useFieldControl';\nimport { useFormReset } from '../../hooks/useFormReset';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { useRovingTabIndex } from '../../hooks/useRovingTabIndex';\nimport { HiddenInput } from '../internal/HiddenInput';\nimport { getCheckColors } from './colorUtils';\n\n/** Represents a single color swatch option. */\nexport interface SwatchItem {\n /** Unique identifier for the swatch (the value `onValueChange` reports and a form submits). */\n value: string;\n /** CSS color value (e.g., hex, rgb) used as the swatch background. */\n color: string;\n /**\n * Accessible name of the swatch, e.g. `'Cranberry'`. **Required for accessibility**: without it\n * the swatch is announced by its raw color value (`'#d13438'`) and a development warning is\n * logged.\n */\n label?: string;\n}\n\n/** Size of the swatches. */\nexport type SwatchPickerSize = Extract<Size, 'small' | 'medium' | 'large'>;\n\n/** Properties for the SwatchPicker component. */\nexport interface SwatchPickerProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'onChange' | 'defaultValue'\n> {\n /** The swatches to display, in order (a readonly array is accepted; it is never modified). */\n items: readonly SwatchItem[];\n /** Controlled selected swatch value (`''` = nothing selected). */\n value?: string;\n /** Initial selected value for uncontrolled usage (also what a form reset restores).\n * @default ''\n */\n defaultValue?: string;\n /** Called with the new value when the selection changes (not when the selected swatch is chosen again). */\n onValueChange?: (value: string) => void;\n /**\n * Called with the new value when the selection changes.\n * @deprecated Use `onValueChange`.\n */\n onChange?: (value: string) => void;\n /** Size of each swatch button (24, 32 or 40px).\n * @default 'medium'\n */\n size?: SwatchPickerSize;\n /** Shape of each swatch button.\n * @default 'circular'\n */\n shape?: Shape;\n /**\n * Form field name. With a name, the selected swatch's `value` is submitted with the form\n * (nothing while no swatch is selected).\n */\n name?: string;\n /** A swatch must be selected before the form can be submitted (native validation). */\n required?: boolean;\n /** Id of the form the picker belongs to, when it is rendered outside that form. */\n form?: string;\n /** Ref to the `role=\"radiogroup\"` element. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\nconst sizeMap: Record<SwatchPickerSize, string> = {\n small: 'w-6 h-6',\n medium: 'w-8 h-8',\n large: 'w-10 h-10',\n};\n\nconst checkSizeMap: Record<SwatchPickerSize, number> = {\n small: 12,\n medium: 16,\n large: 20,\n};\n\nconst shapeMap: Record<Shape, string> = {\n circular: 'rounded-full',\n square: 'rounded-none',\n rounded: 'rounded',\n};\n\n/**\n * The check glyph of the selected swatch: black or white by the swatch's luminance, drawn over a\n * halo in the other color so it stays visible on any swatch (C-TOKENS exception for\n * user-supplied colors, `input-pickers#16`).\n */\nfunction SwatchCheck({ color, size }: { color: string; size: number }) {\n const { glyph, halo } = getCheckColors(color);\n return (\n <span aria-hidden=\"true\" className=\"pointer-events-none grid\">\n <CheckIcon\n size={size}\n strokeWidth={4}\n className=\"col-start-1 row-start-1\"\n style={{ color: halo }}\n />\n <CheckIcon\n size={size}\n strokeWidth={2}\n className=\"col-start-1 row-start-1\"\n style={{ color: glyph }}\n />\n </span>\n );\n}\n\n/**\n * A single-select grid of color swatches (`role=\"radiogroup\"` of `role=\"radio\"` buttons).\n *\n * - **Keyboard** (APG radio group): one tab stop — the selected swatch, else the first. All four\n * arrow keys move focus and select (Left/Right mirrored under `dir=\"rtl\"`), wrapping at the\n * ends; Home/End jump to the first/last swatch.\n * - **Selected indicator**: an offset ring in the foreground color (drawn on the page background,\n * not on the swatch) plus a check glyph whose color is picked by the swatch's luminance, so the\n * selection never relies on color alone.\n * - **Naming**: give the group a name with `aria-label`/`aria-labelledby` or render it inside a\n * `Field`, and give every item a `label`; both are reported in development when missing.\n * - **Forms**: with `name` (or `required`) it takes part in native forms; a form reset restores\n * `defaultValue`.\n *\n * @example\n * <SwatchPicker aria-label=\"Accent color\" items={[{ value: 'red', color: '#d13438', label: 'Red' }]} />\n */\nexport const SwatchPicker = ({\n items,\n value: valueProp,\n defaultValue,\n onValueChange,\n onChange,\n size = 'medium',\n shape = 'circular',\n name,\n required,\n form,\n className,\n id,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n 'aria-invalid': ariaInvalid,\n 'aria-required': ariaRequired,\n onKeyDown,\n onFocus,\n ref,\n ...rest\n}: SwatchPickerProps) => {\n if (onChange !== undefined) warnDeprecated('SwatchPicker', 'onChange', 'onValueChange');\n const initialValue = defaultValue ?? '';\n const [value, setValue] = useControllable(valueProp, initialValue, (next: string) => {\n onValueChange?.(next);\n onChange?.(next);\n });\n\n const { containerProps, getTabIndex } = useRovingTabIndex({\n activeValue: value || null,\n orientation: 'both',\n // APG radio group: moving focus also selects.\n onFocusMove: (next) => setValue(next),\n });\n\n const rootRef = React.useRef<HTMLDivElement>(null);\n const mergedRef = useMergedRefs<HTMLDivElement>(ref, containerProps.ref, rootRef);\n\n const field = useFieldContext();\n const fieldProps = useFieldControl(\n {\n id,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n 'aria-invalid': ariaInvalid,\n // An explicit `required={false}` wins over a required Field, so aria-required matches\n // `isRequired`.\n 'aria-required': ariaRequired ?? required,\n },\n { labelable: false },\n );\n const isRequired = required ?? field?.required ?? false;\n\n const unnamed =\n fieldProps['aria-label'] === undefined && fieldProps['aria-labelledby'] === undefined;\n const unlabelledItem = items.find((item) => !item.label)?.value;\n React.useEffect(() => {\n if (unnamed) {\n warnOnce(\n 'SwatchPicker:unnamed',\n 'SwatchPicker: the radiogroup has no accessible name. Pass `aria-label` or `aria-labelledby`, or render it inside a Field.',\n );\n }\n }, [unnamed]);\n React.useEffect(() => {\n if (unlabelledItem !== undefined) {\n warnOnce(\n 'SwatchPicker:item-label',\n `SwatchPicker: swatch \"${unlabelledItem}\" has no \\`label\\`, so it is announced by its color value. Give every item a \\`label\\`.`,\n );\n }\n }, [unlabelledItem]);\n\n useFormReset(rootRef, () => setValue(initialValue), form);\n\n const focusTabStop = () => {\n rootRef.current?.querySelector<HTMLElement>('[data-roving-value][tabindex=\"0\"]')?.focus();\n };\n\n return (\n <div\n role=\"radiogroup\"\n {...fieldProps}\n className={cn('relative flex flex-wrap gap-2', className)}\n {...rest}\n ref={mergedRef}\n data-roving-container=\"\"\n onKeyDown={composeEventHandlers(onKeyDown, containerProps.onKeyDown)}\n onFocus={composeEventHandlers(onFocus, containerProps.onFocus, {\n checkDefaultPrevented: false,\n })}\n >\n {items.map((item) => {\n const isSelected = value === item.value;\n return (\n <button\n key={item.value}\n type=\"button\"\n role=\"radio\"\n aria-checked={isSelected}\n aria-label={item.label || item.color}\n data-roving-value={item.value}\n data-selected={isSelected ? '' : undefined}\n tabIndex={getTabIndex(item.value)}\n onClick={() => setValue(item.value)}\n className={cn(\n sizeMap[size],\n shapeMap[shape],\n // The padding is set here (C-NATIVE); the swatch color is its background.\n 'relative flex shrink-0 items-center justify-center border-2 border-transparent p-0',\n motionSafeTransition,\n // User colors are the content: keep them (and the check glyph) in forced colors.\n 'forced-colors:forced-color-adjust-none',\n forcedColors.border,\n focusRing,\n // Outside the selection ring, so both stay visible together.\n 'focus-visible:outline-offset-4',\n isSelected\n ? 'ring-2 ring-foreground ring-offset-2 ring-offset-background'\n : 'hover:border-stroke-hover',\n )}\n style={{ backgroundColor: item.color }}\n >\n {isSelected && <SwatchCheck color={item.color} size={checkSizeMap[size]} />}\n </button>\n );\n })}\n <HiddenInput\n type=\"radio\"\n name={name}\n form={form}\n value={value}\n required={isRequired}\n onInvalid={focusTabStop}\n />\n </div>\n );\n};\n\nSwatchPicker.displayName = 'SwatchPicker';\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/dev.cjs"),r=require("../../lib/slot.cjs"),i=require("../../lib/composeEventHandlers.cjs"),a=require("../../hooks/useControllable.cjs"),o=require("../../hooks/useId.cjs"),ee=require("../../hooks/useMergedRefs.cjs"),s=require("../../lib/aria.cjs"),c=require("../../hooks/useFieldControl.cjs"),l=require("../../lib/styles.cjs"),u=require("../../hooks/useFormReset.cjs"),d=require("../internal/HiddenInput.cjs");let f=require("react");f=e.__toESM(f,1);let p=require("react/jsx-runtime");var m=`forced-colors:border-[Highlight] forced-colors:bg-[Highlight]`,te=`forced-colors:border-[GrayText] forced-colors:bg-[Canvas]`,h=({checked:e,defaultChecked:h=!1,onCheckedChange:g,onChange:_,disabled:v=!1,disabledFocusable:y=!1,label:b,labelPosition:x=`after`,name:ne,value:re,required:S,form:C,id:ie,"aria-label":ae,"aria-labelledby":w,"aria-describedby":T,"aria-invalid":E,"aria-required":D,"aria-errormessage":O,"aria-details":k,"aria-disabled":A,autoFocus:j,tabIndex:M,onClick:N,onFocus:P,onBlur:F,onKeyDown:I,onKeyUp:L,controlRef:R,className:z,children:oe,ref:B,...V})=>{_!==void 0&&n.warnDeprecated(`Switch`,`onChange`,`onCheckedChange`);let H=r.slotRendersContent(oe);f.useEffect(()=>{H&&n.warnOnce(`Switch:children`,"Switch: children are not rendered. Pass the label in `label`.")},[H]);let[U,W]=a.useControllable(e,h,e=>{g?.(e),_?.(e)}),G=o.useId(`switch`),K=o.useId(`switch-label`),q=c.useFieldContext(),J=c.useFieldControl({id:ie,"aria-label":ae,"aria-labelledby":w,"aria-describedby":T,"aria-invalid":E,"aria-required":D??S}),se=S??q?.required??!1,Y=r.slotRendersContent(b),ce=Y&&J[`aria-label`]===void 0?s.joinIds(J[`aria-labelledby`],q&&J.id===q.controlId?q.labelId:void 0,K):J[`aria-labelledby`],X=f.useRef(null),le=ee.useMergedRefs(X,R);u.useFormReset(X,()=>W(h),C);let Z=Y?(0,p.jsx)(`span`,{id:K,className:`text-body-1 text-foreground`,children:r.materialiseSlotContent(b)}):null,Q=x===`before`||x===`above`,$=v||y;return(0,p.jsxs)(`label`,{ref:B,"data-label-position":x,className:t.cn(`relative inline-flex items-start gap-2 select-none`,x===`above`&&`flex-col gap-1`,$?`cursor-not-allowed opacity-50 has-focus-visible:opacity-100`:`cursor-pointer`,z),...V,children:[Q&&Z,(0,p.jsx)(`button`,{id:G,type:`button`,...J,"aria-labelledby":ce,"aria-errormessage":O,"aria-details":k,"aria-disabled":A,autoFocus:j,tabIndex:M,onFocus:P,onBlur:F,onKeyDown:I,onKeyUp:L,ref:le,role:`switch`,"aria-checked":U,disabled:v&&!y,...s.focusableDisabledProps(y,{reachable:!0}),onClick:y?e=>{e.preventDefault(),e.stopPropagation()}:i.composeEventHandlers(N,()=>W(e=>!e)),className:t.cn(`relative inline-flex h-[20px] w-[40px] shrink-0 items-center rounded-full border p-0 transition-colors duration-200 motion-reduce:transition-none`,l.focusRing,U?t.cn(`border-primary bg-primary`,$?te:m):t.cn(`border-stroke-accessible bg-transparent`,$?l.forcedColors.disabled:l.forcedColors.control)),children:(0,p.jsx)(`span`,{"aria-hidden":`true`,className:t.cn(`block h-[14px] w-[14px] rounded-full transition-transform duration-200 motion-reduce:transition-none forced-colors:forced-color-adjust-none`,U?`translate-x-[22px] wave-rtl:-translate-x-[22px] bg-primary-foreground`:`translate-x-[2px] wave-rtl:-translate-x-[2px] bg-stroke-accessible`,$?`forced-colors:bg-[GrayText]`:U?`forced-colors:bg-[HighlightText]`:`forced-colors:bg-[ButtonText]`)})}),!Q&&Z,(0,p.jsx)(d.HiddenInput,{type:`checkbox`,name:ne,form:C,disabled:$,value:re,checked:U,required:se,onInvalid:()=>X.current?.focus()})]})};h.displayName=`Switch`,exports.Switch=h;
|
|
2
|
+
//# sourceMappingURL=Switch.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Switch.cjs","names":["slotRendersContent","useControllable","useId","useFieldContext","useFieldControl","joinIds","React","useMergedRefs","materialiseSlotContent","cn","focusableDisabledProps","composeEventHandlers","focusRing","forcedColors","HiddenInput","require_runtime","require_cn","require_dev","require_slot","require_composeEventHandlers","require_useControllable","require_useId","require_useMergedRefs","require_aria","require_useFieldControl","require_styles","require_useFormReset","require_HiddenInput","react","react_jsx_runtime","onTrack","disabledOnTrack","Switch","checkedProp","ariaLabel","ariaLabelledBy","ariaDescribedBy","ariaInvalid","ariaRequired","ariaErrorMessage","ariaDetails","ariaDisabled","rest","onChange","hasChildren","children","checked","setChecked","defaultChecked","onCheckedChange","next","generatedId","labelTextId","field","fieldProps","required","isRequired","hasLabel","label","labelledBy","buttonRef","mergedControlRef","controlRef","form","labelText","labelFirst","labelPosition","unavailable","disabled","disabledFocusable","className","event","onClick","prev"],"sources":["../../../src/components/input/Switch.tsx"],"sourcesContent":["import * as React from 'react';\nimport { focusableDisabledProps, joinIds } from '../../lib/aria';\nimport { cn } from '../../lib/cn';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { warnDeprecated, warnOnce } from '../../lib/dev';\nimport { materialiseSlotContent, slotRendersContent } from '../../lib/slot';\nimport { focusRing, forcedColors } from '../../lib/styles';\nimport type { LabelPosition } from '../../lib/types';\nimport { useControllable } from '../../hooks/useControllable';\nimport { useFieldContext, useFieldControl } from '../../hooks/useFieldControl';\nimport { useFormReset } from '../../hooks/useFormReset';\nimport { useId } from '../../hooks/useId';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { HiddenInput } from '../internal/HiddenInput';\n\n/*\n * Forced colors: the focusable track keeps system-color utilities, so the browser still forces its\n * focus outline; only the thumb (the leaf indicator) opts out of forced colors. A disabled switch\n * draws a GrayText thumb and border on Canvas, without the Highlight fill.\n */\nconst onTrack = 'forced-colors:border-[Highlight] forced-colors:bg-[Highlight]';\nconst disabledOnTrack = 'forced-colors:border-[GrayText] forced-colors:bg-[Canvas]';\n\n/** Handlers that run on the `role=\"switch\"` button instead of the root label (C-ROUTING). */\ntype SwitchControlHandlers = 'onClick' | 'onFocus' | 'onBlur' | 'onKeyDown' | 'onKeyUp';\n\n/** Where a Switch renders its label: after the track (default), before it or above it. */\nexport type SwitchLabelPosition = Extract<LabelPosition, 'before' | 'after' | 'above'>;\n\n/** Properties for the Switch component. */\nexport interface SwitchProps extends Omit<\n React.HTMLAttributes<HTMLLabelElement>,\n 'onChange' | 'defaultChecked' | SwitchControlHandlers\n> {\n /** Controlled checked (on/off) state. */\n checked?: boolean;\n /** Initial checked state for uncontrolled usage (also the value a form reset restores).\n * @default false\n */\n defaultChecked?: boolean;\n /** Called with the new checked state when the switch is toggled (not for no-op updates). */\n onCheckedChange?: (checked: boolean) => void;\n /**\n * Called with the new checked state when the switch is toggled.\n * @deprecated Use `onCheckedChange`.\n */\n onChange?: (checked: boolean) => void;\n /** Whether the switch is disabled and non-interactive. */\n disabled?: boolean;\n /**\n * Marks the switch unavailable but keeps it focusable and in the tab order: for a disabled\n * switch that needs a Tooltip, or one in a toolbar. Renders `aria-disabled=\"true\"`,\n * `data-disabled` and `data-disabled-focusable` on the switch instead of the native `disabled`\n * attribute. The switch cannot be toggled and is not submitted with its form; your `onClick` is\n * not called, and a click on the switch (or Space and Enter) does not reach ancestor click\n * handlers, as for a natively disabled control. Wins over `disabled` when both are set. In a\n * roving container (a `Toolbar`) it stays in the arrow-key order.\n * @default false\n */\n disabledFocusable?: boolean;\n /**\n * Label next to the control (any phrasing content, links included, but no other form\n * controls). It names the control through `aria-labelledby`, after a consumer or Field\n * `aria-labelledby`; a consumer `aria-label` names it instead. Clicking its text toggles the\n * control; clicking a link inside it follows the link. `children` are not rendered: pass the\n * label here.\n */\n label?: React.ReactNode;\n /**\n * Where the label renders: after the control (default), before it, or above it. The DOM order\n * follows the visual order.\n * @default 'after'\n */\n labelPosition?: SwitchLabelPosition;\n /**\n * Form field name. With a name, the switch takes part in native form submission: it submits\n * `name=value` while on.\n */\n name?: string;\n /** Value submitted while on.\n * @default 'on'\n */\n value?: string;\n /** The form must not be submitted while the switch is off (native validation). */\n required?: boolean;\n /** Id of the form the switch belongs to, when it is rendered outside that form. */\n form?: string;\n /** Click handler of the switch control (the `role=\"switch\"` button). */\n onClick?: React.MouseEventHandler<HTMLButtonElement>;\n /** Focus handler of the switch control. */\n onFocus?: React.FocusEventHandler<HTMLButtonElement>;\n /** Blur handler of the switch control. */\n onBlur?: React.FocusEventHandler<HTMLButtonElement>;\n /** Keydown handler of the switch control. */\n onKeyDown?: React.KeyboardEventHandler<HTMLButtonElement>;\n /** Keyup handler of the switch control. */\n onKeyUp?: React.KeyboardEventHandler<HTMLButtonElement>;\n /** Ref to the focusable `role=\"switch\"` button. */\n controlRef?: React.Ref<HTMLButtonElement>;\n /** Ref to the root `<label>` element. */\n ref?: React.Ref<HTMLLabelElement>;\n}\n\n/**\n * An on/off toggle drawn as a `role=\"switch\"` button inside a `<label>`.\n *\n * - The root `<label>` receives `ref`, `className`, `style` and `data-*`; the control receives\n * `id`, `aria-label`/`-labelledby`/`-describedby`/`-invalid`/`-required`/`-errormessage`/\n * `-details`/`-disabled`, `tabIndex`, `autoFocus` and the click, focus and key handlers\n * (`controlRef` exposes it). A consumer `onClick` runs once per activation, before the toggle;\n * `preventDefault()` in it cancels the toggle.\n * - Inside a `Field` it is named by the Field label (followed by its own `label` text) and described\n * by the Field message and hint.\n * - With `name` (or `required`) it takes part in native forms like `<input type=\"checkbox\">`, and\n * a form reset restores `defaultChecked`.\n * - The thumb position mirrors when the switch itself is right-to-left (its nearest `dir`), so a\n * switch in an LTR subtree of an RTL page keeps the LTR layout.\n * - `label` takes rich content (a link) and renders after the switch, or before or above it with\n * `labelPosition` (the root carries `data-label-position`). Beside the label, the switch lines\n * up with the first line of a label that wraps or has a second line. `children` are not\n * rendered (a development warning says so).\n */\nexport const Switch = ({\n checked: checkedProp,\n defaultChecked = false,\n onCheckedChange,\n onChange,\n disabled = false,\n disabledFocusable = false,\n label,\n labelPosition = 'after',\n name,\n value,\n required,\n form,\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 'aria-disabled': ariaDisabled,\n autoFocus,\n tabIndex,\n onClick,\n onFocus,\n onBlur,\n onKeyDown,\n onKeyUp,\n controlRef,\n className,\n children,\n ref,\n ...rest\n}: SwitchProps) => {\n if (onChange !== undefined) warnDeprecated('Switch', 'onChange', 'onCheckedChange');\n const hasChildren = slotRendersContent(children);\n React.useEffect(() => {\n if (hasChildren) {\n warnOnce('Switch:children', 'Switch: children are not rendered. Pass the label in `label`.');\n }\n }, [hasChildren]);\n const [checked, setChecked] = useControllable(checkedProp, defaultChecked, (next: boolean) => {\n onCheckedChange?.(next);\n onChange?.(next);\n });\n\n const generatedId = useId('switch');\n const labelTextId = useId('switch-label');\n const field = useFieldContext();\n const fieldProps = useFieldControl({\n id,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n 'aria-invalid': ariaInvalid,\n // An explicit `required={false}` wins over a required Field, so aria-required always matches\n // the native validation below (`isRequired`).\n 'aria-required': ariaRequired ?? required,\n });\n const isRequired = required ?? field?.required ?? false;\n // `0` is a label; `null`, `false`, `''` and empty collections are not (C-SLOTS).\n const hasLabel = slotRendersContent(label);\n // The label text names the control through aria-labelledby, disabled or not: axe exempts the\n // dimmed text of a disabled control only when the control references it this way (its <label>\n // exemption covers native inputs only). A consumer aria-label still names the control alone.\n // The ids already there (the consumer's, the Field label from useFieldControl) come first, then\n // the Field label whose <label htmlFor> targets this control (aria-labelledby would hide it), so\n // the name keeps every label.\n const labelledBy =\n hasLabel && fieldProps['aria-label'] === undefined\n ? joinIds(\n fieldProps['aria-labelledby'],\n field && fieldProps.id === field.controlId ? field.labelId : undefined,\n labelTextId,\n )\n : fieldProps['aria-labelledby'];\n\n const buttonRef = React.useRef<HTMLButtonElement>(null);\n const mergedControlRef = useMergedRefs(buttonRef, controlRef);\n useFormReset(buttonRef, () => setChecked(defaultChecked), form);\n\n const labelText = hasLabel ? (\n <span id={labelTextId} className=\"text-body-1 text-foreground\">\n {materialiseSlotContent(label)}\n </span>\n ) : null;\n const labelFirst = labelPosition === 'before' || labelPosition === 'above';\n // Focusable-disabled wins over `disabled`: the switch stays focusable but looks and acts disabled.\n const unavailable = disabled || disabledFocusable;\n\n return (\n <label\n ref={ref}\n data-label-position={labelPosition}\n className={cn(\n // items-start: the 20px track lines up with the 20px first line of a label that wraps or\n // has a second line, not with its middle.\n 'relative inline-flex items-start gap-2 select-none',\n labelPosition === 'above' && 'flex-col gap-1',\n // The dimmed look lifts while a focus ring shows inside the root (the control's, under\n // disabledFocusable, or a link's in the label): opacity would dim the ring below 3:1.\n unavailable\n ? 'cursor-not-allowed opacity-50 has-focus-visible:opacity-100'\n : 'cursor-pointer',\n className,\n )}\n {...rest}\n >\n {labelFirst && labelText}\n <button\n id={generatedId}\n type=\"button\"\n {...fieldProps}\n aria-labelledby={labelledBy}\n aria-errormessage={ariaErrorMessage}\n aria-details={ariaDetails}\n aria-disabled={ariaDisabled}\n autoFocus={autoFocus}\n tabIndex={tabIndex}\n onFocus={onFocus}\n onBlur={onBlur}\n onKeyDown={onKeyDown}\n onKeyUp={onKeyUp}\n ref={mergedControlRef}\n role=\"switch\"\n aria-checked={checked}\n disabled={disabled && !disabledFocusable}\n {...focusableDisabledProps(disabledFocusable, { reachable: true })}\n onClick={\n disabledFocusable\n ? // Clicks, Space and Enter (which click a button) neither toggle nor reach `onClick`,\n // and, as a natively disabled control dispatches no click, no ancestor sees them.\n (event: React.MouseEvent<HTMLButtonElement>) => {\n event.preventDefault();\n event.stopPropagation();\n }\n : composeEventHandlers(onClick, () => setChecked((prev) => !prev))\n }\n className={cn(\n // The whole control is sized in px, like the Checkbox box and the radio circle: the thumb\n // and its offsets are px, so a track in rem would stop fitting them at any root font size\n // other than 16px. The 40x20 track (1px border) leaves a 2px inset around the 14px thumb.\n // p-0 is set here, not left to the native reset, which any app button style overrides\n // (C-NATIVE): the thumb offsets assume no padding.\n 'relative inline-flex h-[20px] w-[40px] shrink-0 items-center rounded-full border p-0 transition-colors duration-200 motion-reduce:transition-none',\n focusRing,\n checked\n ? cn('border-primary bg-primary', unavailable ? disabledOnTrack : onTrack)\n : cn(\n 'border-stroke-accessible bg-transparent',\n unavailable ? forcedColors.disabled : forcedColors.control,\n ),\n )}\n >\n <span\n aria-hidden=\"true\"\n className={cn(\n 'block h-[14px] w-[14px] rounded-full transition-transform duration-200 motion-reduce:transition-none forced-colors:forced-color-adjust-none',\n checked\n ? 'translate-x-[22px] wave-rtl:-translate-x-[22px] bg-primary-foreground'\n : 'translate-x-[2px] wave-rtl:-translate-x-[2px] bg-stroke-accessible',\n unavailable\n ? 'forced-colors:bg-[GrayText]'\n : checked\n ? 'forced-colors:bg-[HighlightText]'\n : 'forced-colors:bg-[ButtonText]',\n )}\n />\n </button>\n {!labelFirst && labelText}\n <HiddenInput\n type=\"checkbox\"\n name={name}\n form={form}\n disabled={unavailable}\n value={value}\n checked={checked}\n required={isRequired}\n onInvalid={() => buttonRef.current?.focus()}\n />\n </label>\n );\n};\n\nSwitch.displayName = 'Switch';\n"],"mappings":"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"}
|