@mortenbrudvik/waveui 0.4.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1221 -173
- package/dist/_virtual/_rolldown/runtime.cjs +1 -0
- package/dist/components/button/Button.cjs +2 -0
- package/dist/components/button/Button.cjs.map +1 -0
- package/dist/components/button/Button.mjs +50 -0
- package/dist/components/button/Button.mjs.map +1 -0
- package/dist/components/button/Button.semantics.cjs +2 -0
- package/dist/components/button/Button.semantics.cjs.map +1 -0
- package/dist/components/button/Button.semantics.mjs +61 -0
- package/dist/components/button/Button.semantics.mjs.map +1 -0
- package/dist/components/button/Button.slots.cjs +2 -0
- package/dist/components/button/Button.slots.cjs.map +1 -0
- package/dist/components/button/Button.slots.mjs +47 -0
- package/dist/components/button/Button.slots.mjs.map +1 -0
- package/dist/components/button/CompoundButton.cjs +2 -0
- package/dist/components/button/CompoundButton.cjs.map +1 -0
- package/dist/components/button/CompoundButton.mjs +53 -0
- package/dist/components/button/CompoundButton.mjs.map +1 -0
- package/dist/components/button/Link.cjs +2 -0
- package/dist/components/button/Link.cjs.map +1 -0
- package/dist/components/button/Link.mjs +37 -0
- package/dist/components/button/Link.mjs.map +1 -0
- package/dist/components/button/MenuButton.cjs +2 -0
- package/dist/components/button/MenuButton.cjs.map +1 -0
- package/dist/components/button/MenuButton.mjs +45 -0
- package/dist/components/button/MenuButton.mjs.map +1 -0
- package/dist/components/button/SplitButton.cjs +2 -0
- package/dist/components/button/SplitButton.cjs.map +1 -0
- package/dist/components/button/SplitButton.mjs +66 -0
- package/dist/components/button/SplitButton.mjs.map +1 -0
- package/dist/components/button/ToggleButton.cjs +2 -0
- package/dist/components/button/ToggleButton.cjs.map +1 -0
- package/dist/components/button/ToggleButton.mjs +65 -0
- package/dist/components/button/ToggleButton.mjs.map +1 -0
- package/dist/components/button/Toolbar.cjs +2 -0
- package/dist/components/button/Toolbar.cjs.map +1 -0
- package/dist/components/button/Toolbar.context.cjs +2 -0
- package/dist/components/button/Toolbar.context.cjs.map +1 -0
- package/dist/components/button/Toolbar.context.mjs +31 -0
- package/dist/components/button/Toolbar.context.mjs.map +1 -0
- package/dist/components/button/Toolbar.mjs +63 -0
- package/dist/components/button/Toolbar.mjs.map +1 -0
- package/dist/components/button/Toolbar.parts.cjs +2 -0
- package/dist/components/button/Toolbar.parts.cjs.map +1 -0
- package/dist/components/button/Toolbar.parts.mjs +131 -0
- package/dist/components/button/Toolbar.parts.mjs.map +1 -0
- package/dist/components/button/buttonStyles.cjs +2 -0
- package/dist/components/button/buttonStyles.cjs.map +1 -0
- package/dist/components/button/buttonStyles.mjs +39 -0
- package/dist/components/button/buttonStyles.mjs.map +1 -0
- package/dist/components/data-display/Avatar.cjs +2 -0
- package/dist/components/data-display/Avatar.cjs.map +1 -0
- package/dist/components/data-display/Avatar.mjs +157 -0
- package/dist/components/data-display/Avatar.mjs.map +1 -0
- package/dist/components/data-display/AvatarGroup.cjs +2 -0
- package/dist/components/data-display/AvatarGroup.cjs.map +1 -0
- package/dist/components/data-display/AvatarGroup.mjs +134 -0
- package/dist/components/data-display/AvatarGroup.mjs.map +1 -0
- package/dist/components/data-display/Badge.cjs +2 -0
- package/dist/components/data-display/Badge.cjs.map +1 -0
- package/dist/components/data-display/Badge.colors.cjs +2 -0
- package/dist/components/data-display/Badge.colors.cjs.map +1 -0
- package/dist/components/data-display/Badge.colors.mjs +58 -0
- package/dist/components/data-display/Badge.colors.mjs.map +1 -0
- package/dist/components/data-display/Badge.mjs +32 -0
- package/dist/components/data-display/Badge.mjs.map +1 -0
- package/dist/components/data-display/CounterBadge.cjs +2 -0
- package/dist/components/data-display/CounterBadge.cjs.map +1 -0
- package/dist/components/data-display/CounterBadge.mjs +28 -0
- package/dist/components/data-display/CounterBadge.mjs.map +1 -0
- package/dist/components/data-display/Divider.cjs +2 -0
- package/dist/components/data-display/Divider.cjs.map +1 -0
- package/dist/components/data-display/Divider.mjs +52 -0
- package/dist/components/data-display/Divider.mjs.map +1 -0
- package/dist/components/data-display/Image.cjs +2 -0
- package/dist/components/data-display/Image.cjs.map +1 -0
- package/dist/components/data-display/Image.mjs +32 -0
- package/dist/components/data-display/Image.mjs.map +1 -0
- package/dist/components/data-display/InfoLabel.cjs +2 -0
- package/dist/components/data-display/InfoLabel.cjs.map +1 -0
- package/dist/components/data-display/InfoLabel.mjs +104 -0
- package/dist/components/data-display/InfoLabel.mjs.map +1 -0
- package/dist/components/data-display/List.cjs +2 -0
- package/dist/components/data-display/List.cjs.map +1 -0
- package/dist/components/data-display/List.mjs +381 -0
- package/dist/components/data-display/List.mjs.map +1 -0
- package/dist/components/data-display/List.registry.cjs +2 -0
- package/dist/components/data-display/List.registry.cjs.map +1 -0
- package/dist/components/data-display/List.registry.mjs +101 -0
- package/dist/components/data-display/List.registry.mjs.map +1 -0
- package/dist/components/data-display/Persona.cjs +2 -0
- package/dist/components/data-display/Persona.cjs.map +1 -0
- package/dist/components/data-display/Persona.mjs +48 -0
- package/dist/components/data-display/Persona.mjs.map +1 -0
- package/dist/components/data-display/PresenceBadge.cjs +2 -0
- package/dist/components/data-display/PresenceBadge.cjs.map +1 -0
- package/dist/components/data-display/PresenceBadge.mjs +71 -0
- package/dist/components/data-display/PresenceBadge.mjs.map +1 -0
- package/dist/components/data-display/Tag.cjs +2 -0
- package/dist/components/data-display/Tag.cjs.map +1 -0
- package/dist/components/data-display/Tag.mjs +147 -0
- package/dist/components/data-display/Tag.mjs.map +1 -0
- package/dist/components/feedback/MessageBar.cjs +2 -0
- package/dist/components/feedback/MessageBar.cjs.map +1 -0
- package/dist/components/feedback/MessageBar.mjs +144 -0
- package/dist/components/feedback/MessageBar.mjs.map +1 -0
- package/dist/components/feedback/MessageBar.status.cjs +2 -0
- package/dist/components/feedback/MessageBar.status.cjs.map +1 -0
- package/dist/components/feedback/MessageBar.status.mjs +45 -0
- package/dist/components/feedback/MessageBar.status.mjs.map +1 -0
- package/dist/components/feedback/ProgressBar.cjs +2 -0
- package/dist/components/feedback/ProgressBar.cjs.map +1 -0
- package/dist/components/feedback/ProgressBar.mjs +72 -0
- package/dist/components/feedback/ProgressBar.mjs.map +1 -0
- package/dist/components/feedback/Skeleton.cjs +2 -0
- package/dist/components/feedback/Skeleton.cjs.map +1 -0
- package/dist/components/feedback/Skeleton.mjs +47 -0
- package/dist/components/feedback/Skeleton.mjs.map +1 -0
- package/dist/components/feedback/Spinner.cjs +2 -0
- package/dist/components/feedback/Spinner.cjs.map +1 -0
- package/dist/components/feedback/Spinner.mjs +60 -0
- package/dist/components/feedback/Spinner.mjs.map +1 -0
- package/dist/components/feedback/Toast.cjs +2 -0
- package/dist/components/feedback/Toast.cjs.map +1 -0
- package/dist/components/feedback/Toast.mjs +347 -0
- package/dist/components/feedback/Toast.mjs.map +1 -0
- package/dist/components/input/Checkbox.cjs +2 -0
- package/dist/components/input/Checkbox.cjs.map +1 -0
- package/dist/components/input/Checkbox.mjs +96 -0
- package/dist/components/input/Checkbox.mjs.map +1 -0
- package/dist/components/input/ColorPicker.cjs +6 -0
- package/dist/components/input/ColorPicker.cjs.map +1 -0
- package/dist/components/input/ColorPicker.mjs +236 -0
- package/dist/components/input/ColorPicker.mjs.map +1 -0
- package/dist/components/input/Combobox.cjs +2 -0
- package/dist/components/input/Combobox.cjs.map +1 -0
- package/dist/components/input/Combobox.expand.cjs +2 -0
- package/dist/components/input/Combobox.expand.cjs.map +1 -0
- package/dist/components/input/Combobox.expand.mjs +38 -0
- package/dist/components/input/Combobox.expand.mjs.map +1 -0
- package/dist/components/input/Combobox.mjs +187 -0
- package/dist/components/input/Combobox.mjs.map +1 -0
- package/dist/components/input/DatePicker.cjs +2 -0
- package/dist/components/input/DatePicker.cjs.map +1 -0
- package/dist/components/input/DatePicker.mjs +340 -0
- package/dist/components/input/DatePicker.mjs.map +1 -0
- package/dist/components/input/Dropdown.cjs +2 -0
- package/dist/components/input/Dropdown.cjs.map +1 -0
- package/dist/components/input/Dropdown.mjs +128 -0
- package/dist/components/input/Dropdown.mjs.map +1 -0
- package/dist/components/input/Field.cjs +2 -0
- package/dist/components/input/Field.cjs.map +1 -0
- package/dist/components/input/Field.mjs +200 -0
- package/dist/components/input/Field.mjs.map +1 -0
- package/dist/components/input/Input.cjs +2 -0
- package/dist/components/input/Input.cjs.map +1 -0
- package/dist/components/input/Input.mjs +81 -0
- package/dist/components/input/Input.mjs.map +1 -0
- package/dist/components/input/Label.cjs +2 -0
- package/dist/components/input/Label.cjs.map +1 -0
- package/dist/components/input/Label.mjs +28 -0
- package/dist/components/input/Label.mjs.map +1 -0
- package/dist/components/input/Option.cjs +2 -0
- package/dist/components/input/Option.cjs.map +1 -0
- package/dist/components/input/Option.mjs +169 -0
- package/dist/components/input/Option.mjs.map +1 -0
- package/dist/components/input/RadioGroup.cjs +2 -0
- package/dist/components/input/RadioGroup.cjs.map +1 -0
- package/dist/components/input/RadioGroup.mjs +139 -0
- package/dist/components/input/RadioGroup.mjs.map +1 -0
- package/dist/components/input/Rating.cjs +2 -0
- package/dist/components/input/Rating.cjs.map +1 -0
- package/dist/components/input/Rating.mjs +196 -0
- package/dist/components/input/Rating.mjs.map +1 -0
- package/dist/components/input/SearchBox.cjs +2 -0
- package/dist/components/input/SearchBox.cjs.map +1 -0
- package/dist/components/input/SearchBox.mjs +205 -0
- package/dist/components/input/SearchBox.mjs.map +1 -0
- package/dist/components/input/Select.cjs +2 -0
- package/dist/components/input/Select.cjs.map +1 -0
- package/dist/components/input/Select.mjs +33 -0
- package/dist/components/input/Select.mjs.map +1 -0
- package/dist/components/input/Slider.cjs +2 -0
- package/dist/components/input/Slider.cjs.map +1 -0
- package/dist/components/input/Slider.mjs +79 -0
- package/dist/components/input/Slider.mjs.map +1 -0
- package/dist/components/input/SpinButton.cjs +2 -0
- package/dist/components/input/SpinButton.cjs.map +1 -0
- package/dist/components/input/SpinButton.mjs +157 -0
- package/dist/components/input/SpinButton.mjs.map +1 -0
- package/dist/components/input/SwatchPicker.cjs +2 -0
- package/dist/components/input/SwatchPicker.cjs.map +1 -0
- package/dist/components/input/SwatchPicker.mjs +113 -0
- package/dist/components/input/SwatchPicker.mjs.map +1 -0
- package/dist/components/input/Switch.cjs +2 -0
- package/dist/components/input/Switch.cjs.map +1 -0
- package/dist/components/input/Switch.mjs +92 -0
- package/dist/components/input/Switch.mjs.map +1 -0
- package/dist/components/input/TagPicker.cjs +2 -0
- package/dist/components/input/TagPicker.cjs.map +1 -0
- package/dist/components/input/TagPicker.mjs +249 -0
- package/dist/components/input/TagPicker.mjs.map +1 -0
- package/dist/components/input/Textarea.cjs +2 -0
- package/dist/components/input/Textarea.cjs.map +1 -0
- package/dist/components/input/Textarea.mjs +32 -0
- package/dist/components/input/Textarea.mjs.map +1 -0
- package/dist/components/input/TimePicker.cjs +2 -0
- package/dist/components/input/TimePicker.cjs.map +1 -0
- package/dist/components/input/TimePicker.mjs +292 -0
- package/dist/components/input/TimePicker.mjs.map +1 -0
- package/dist/components/input/colorUtils.cjs +2 -0
- package/dist/components/input/colorUtils.cjs.map +1 -0
- package/dist/components/input/colorUtils.mjs +96 -0
- package/dist/components/input/colorUtils.mjs.map +1 -0
- package/dist/components/input/dateUtils.cjs +2 -0
- package/dist/components/input/dateUtils.cjs.map +1 -0
- package/dist/components/input/dateUtils.mjs +250 -0
- package/dist/components/input/dateUtils.mjs.map +1 -0
- package/dist/components/input/pickerStyles.cjs +2 -0
- package/dist/components/input/pickerStyles.cjs.map +1 -0
- package/dist/components/input/pickerStyles.mjs +10 -0
- package/dist/components/input/pickerStyles.mjs.map +1 -0
- package/dist/components/internal/HiddenInput.cjs +2 -0
- package/dist/components/internal/HiddenInput.cjs.map +1 -0
- package/dist/components/internal/HiddenInput.mjs +88 -0
- package/dist/components/internal/HiddenInput.mjs.map +1 -0
- package/dist/components/layout/Accordion.cjs +2 -0
- package/dist/components/layout/Accordion.cjs.map +1 -0
- package/dist/components/layout/Accordion.mjs +236 -0
- package/dist/components/layout/Accordion.mjs.map +1 -0
- package/dist/components/layout/Card.cjs +2 -0
- package/dist/components/layout/Card.cjs.map +1 -0
- package/dist/components/layout/Card.mjs +121 -0
- package/dist/components/layout/Card.mjs.map +1 -0
- package/dist/components/layout/Carousel.cjs +2 -0
- package/dist/components/layout/Carousel.cjs.map +1 -0
- package/dist/components/layout/Carousel.mjs +205 -0
- package/dist/components/layout/Carousel.mjs.map +1 -0
- package/dist/components/layout/Flex.cjs +2 -0
- package/dist/components/layout/Flex.cjs.map +1 -0
- package/dist/components/layout/Flex.mjs +54 -0
- package/dist/components/layout/Flex.mjs.map +1 -0
- package/dist/components/layout/Grid.cjs +2 -0
- package/dist/components/layout/Grid.cjs.map +1 -0
- package/dist/components/layout/Grid.mjs +62 -0
- package/dist/components/layout/Grid.mjs.map +1 -0
- package/dist/components/layout/Overflow.cjs +2 -0
- package/dist/components/layout/Overflow.cjs.map +1 -0
- package/dist/components/layout/Overflow.mjs +269 -0
- package/dist/components/layout/Overflow.mjs.map +1 -0
- package/dist/components/layout/Stack.cjs +2 -0
- package/dist/components/layout/Stack.cjs.map +1 -0
- package/dist/components/layout/Stack.mjs +39 -0
- package/dist/components/layout/Stack.mjs.map +1 -0
- package/dist/components/layout/TabList.cjs +2 -0
- package/dist/components/layout/TabList.cjs.map +1 -0
- package/dist/components/layout/TabList.mjs +238 -0
- package/dist/components/layout/TabList.mjs.map +1 -0
- package/dist/components/layout/Tree.cjs +2 -0
- package/dist/components/layout/Tree.cjs.map +1 -0
- package/dist/components/layout/Tree.mjs +220 -0
- package/dist/components/layout/Tree.mjs.map +1 -0
- package/dist/components/layout/disclosureIds.cjs +2 -0
- package/dist/components/layout/disclosureIds.cjs.map +1 -0
- package/dist/components/layout/disclosureIds.mjs +12 -0
- package/dist/components/layout/disclosureIds.mjs.map +1 -0
- package/dist/components/motion/Presence.cjs +2 -0
- package/dist/components/motion/Presence.cjs.map +1 -0
- package/dist/components/motion/Presence.mjs +35 -0
- package/dist/components/motion/Presence.mjs.map +1 -0
- package/dist/components/navigation/Breadcrumb.cjs +2 -0
- package/dist/components/navigation/Breadcrumb.cjs.map +1 -0
- package/dist/components/navigation/Breadcrumb.mjs +144 -0
- package/dist/components/navigation/Breadcrumb.mjs.map +1 -0
- package/dist/components/navigation/Menu.cjs +2 -0
- package/dist/components/navigation/Menu.cjs.map +1 -0
- package/dist/components/navigation/Menu.context.cjs +2 -0
- package/dist/components/navigation/Menu.context.cjs.map +1 -0
- package/dist/components/navigation/Menu.context.mjs +82 -0
- package/dist/components/navigation/Menu.context.mjs.map +1 -0
- package/dist/components/navigation/Menu.group.cjs +2 -0
- package/dist/components/navigation/Menu.group.cjs.map +1 -0
- package/dist/components/navigation/Menu.group.mjs +58 -0
- package/dist/components/navigation/Menu.group.mjs.map +1 -0
- package/dist/components/navigation/Menu.items.cjs +2 -0
- package/dist/components/navigation/Menu.items.cjs.map +1 -0
- package/dist/components/navigation/Menu.items.mjs +127 -0
- package/dist/components/navigation/Menu.items.mjs.map +1 -0
- package/dist/components/navigation/Menu.link.cjs +2 -0
- package/dist/components/navigation/Menu.link.cjs.map +1 -0
- package/dist/components/navigation/Menu.link.mjs +41 -0
- package/dist/components/navigation/Menu.link.mjs.map +1 -0
- package/dist/components/navigation/Menu.mjs +27 -0
- package/dist/components/navigation/Menu.mjs.map +1 -0
- package/dist/components/navigation/Menu.popover.cjs +2 -0
- package/dist/components/navigation/Menu.popover.cjs.map +1 -0
- package/dist/components/navigation/Menu.popover.mjs +231 -0
- package/dist/components/navigation/Menu.popover.mjs.map +1 -0
- package/dist/components/navigation/Menu.root.cjs +2 -0
- package/dist/components/navigation/Menu.root.cjs.map +1 -0
- package/dist/components/navigation/Menu.root.mjs +308 -0
- package/dist/components/navigation/Menu.root.mjs.map +1 -0
- package/dist/components/navigation/Menu.selectable.cjs +2 -0
- package/dist/components/navigation/Menu.selectable.cjs.map +1 -0
- package/dist/components/navigation/Menu.selectable.mjs +89 -0
- package/dist/components/navigation/Menu.selectable.mjs.map +1 -0
- package/dist/components/navigation/Menu.shared.cjs +2 -0
- package/dist/components/navigation/Menu.shared.cjs.map +1 -0
- package/dist/components/navigation/Menu.shared.mjs +23 -0
- package/dist/components/navigation/Menu.shared.mjs.map +1 -0
- package/dist/components/navigation/Menu.splitGroup.cjs +2 -0
- package/dist/components/navigation/Menu.splitGroup.cjs.map +1 -0
- package/dist/components/navigation/Menu.splitGroup.mjs +51 -0
- package/dist/components/navigation/Menu.splitGroup.mjs.map +1 -0
- package/dist/components/navigation/Menu.trigger.cjs +2 -0
- package/dist/components/navigation/Menu.trigger.cjs.map +1 -0
- package/dist/components/navigation/Menu.trigger.mjs +79 -0
- package/dist/components/navigation/Menu.trigger.mjs.map +1 -0
- package/dist/components/navigation/Nav.cjs +2 -0
- package/dist/components/navigation/Nav.cjs.map +1 -0
- package/dist/components/navigation/Nav.mjs +276 -0
- package/dist/components/navigation/Nav.mjs.map +1 -0
- package/dist/components/navigation/Pagination.cjs +2 -0
- package/dist/components/navigation/Pagination.cjs.map +1 -0
- package/dist/components/navigation/Pagination.mjs +110 -0
- package/dist/components/navigation/Pagination.mjs.map +1 -0
- package/dist/components/navigation/Stepper.cjs +2 -0
- package/dist/components/navigation/Stepper.cjs.map +1 -0
- package/dist/components/navigation/Stepper.mjs +204 -0
- package/dist/components/navigation/Stepper.mjs.map +1 -0
- package/dist/components/overlays/Dialog.cjs +2 -0
- package/dist/components/overlays/Dialog.cjs.map +1 -0
- package/dist/components/overlays/Dialog.mjs +180 -0
- package/dist/components/overlays/Dialog.mjs.map +1 -0
- package/dist/components/overlays/Dialog.shared.cjs +2 -0
- package/dist/components/overlays/Dialog.shared.cjs.map +1 -0
- package/dist/components/overlays/Dialog.shared.mjs +227 -0
- package/dist/components/overlays/Dialog.shared.mjs.map +1 -0
- package/dist/components/overlays/Drawer.cjs +2 -0
- package/dist/components/overlays/Drawer.cjs.map +1 -0
- package/dist/components/overlays/Drawer.mjs +192 -0
- package/dist/components/overlays/Drawer.mjs.map +1 -0
- package/dist/components/overlays/Popover.cjs +2 -0
- package/dist/components/overlays/Popover.cjs.map +1 -0
- package/dist/components/overlays/Popover.mjs +365 -0
- package/dist/components/overlays/Popover.mjs.map +1 -0
- package/dist/components/overlays/Popover.shared.cjs +2 -0
- package/dist/components/overlays/Popover.shared.cjs.map +1 -0
- package/dist/components/overlays/Popover.shared.mjs +182 -0
- package/dist/components/overlays/Popover.shared.mjs.map +1 -0
- package/dist/components/overlays/TeachingPopover.cjs +2 -0
- package/dist/components/overlays/TeachingPopover.cjs.map +1 -0
- package/dist/components/overlays/TeachingPopover.mjs +181 -0
- package/dist/components/overlays/TeachingPopover.mjs.map +1 -0
- package/dist/components/overlays/Tooltip.cjs +2 -0
- package/dist/components/overlays/Tooltip.cjs.map +1 -0
- package/dist/components/overlays/Tooltip.mjs +160 -0
- package/dist/components/overlays/Tooltip.mjs.map +1 -0
- package/dist/components/portal/Portal.cjs +2 -0
- package/dist/components/portal/Portal.cjs.map +1 -0
- package/dist/components/portal/Portal.mjs +45 -0
- package/dist/components/portal/Portal.mjs.map +1 -0
- package/dist/components/provider/WaveProvider.cjs +2 -0
- package/dist/components/provider/WaveProvider.cjs.map +1 -0
- package/dist/components/provider/WaveProvider.mjs +51 -0
- package/dist/components/provider/WaveProvider.mjs.map +1 -0
- package/dist/components/table/DataGrid.cjs +2 -0
- package/dist/components/table/DataGrid.cjs.map +1 -0
- package/dist/components/table/DataGrid.mjs +489 -0
- package/dist/components/table/DataGrid.mjs.map +1 -0
- package/dist/components/table/Table.cjs +2 -0
- package/dist/components/table/Table.cjs.map +1 -0
- package/dist/components/table/Table.mjs +99 -0
- package/dist/components/table/Table.mjs.map +1 -0
- package/dist/components/table/useGridNavigation.cjs +2 -0
- package/dist/components/table/useGridNavigation.cjs.map +1 -0
- package/dist/components/table/useGridNavigation.mjs +336 -0
- package/dist/components/table/useGridNavigation.mjs.map +1 -0
- package/dist/components/typography/Text.cjs +2 -0
- package/dist/components/typography/Text.cjs.map +1 -0
- package/dist/components/typography/Text.mjs +38 -0
- package/dist/components/typography/Text.mjs.map +1 -0
- package/dist/hooks/useAnnounce.cjs +2 -0
- package/dist/hooks/useAnnounce.cjs.map +1 -0
- package/dist/hooks/useAnnounce.mjs +88 -0
- package/dist/hooks/useAnnounce.mjs.map +1 -0
- package/dist/hooks/useCheckedValues.cjs +2 -0
- package/dist/hooks/useCheckedValues.cjs.map +1 -0
- package/dist/hooks/useCheckedValues.mjs +102 -0
- package/dist/hooks/useCheckedValues.mjs.map +1 -0
- package/dist/hooks/useContextMenuAnchor.cjs +2 -0
- package/dist/hooks/useContextMenuAnchor.cjs.map +1 -0
- package/dist/hooks/useContextMenuAnchor.mjs +132 -0
- package/dist/hooks/useContextMenuAnchor.mjs.map +1 -0
- package/dist/hooks/useControllable.cjs +2 -0
- package/dist/hooks/useControllable.cjs.map +1 -0
- package/dist/hooks/useControllable.mjs +37 -0
- package/dist/hooks/useControllable.mjs.map +1 -0
- package/dist/hooks/useDirection.cjs +2 -0
- package/dist/hooks/useDirection.cjs.map +1 -0
- package/dist/hooks/useDirection.mjs +57 -0
- package/dist/hooks/useDirection.mjs.map +1 -0
- package/dist/hooks/useDismiss.cjs +2 -0
- package/dist/hooks/useDismiss.cjs.map +1 -0
- package/dist/hooks/useDismiss.mjs +57 -0
- package/dist/hooks/useDismiss.mjs.map +1 -0
- package/dist/hooks/useEventCallback.cjs +2 -0
- package/dist/hooks/useEventCallback.cjs.map +1 -0
- package/dist/hooks/useEventCallback.mjs +16 -0
- package/dist/hooks/useEventCallback.mjs.map +1 -0
- package/dist/hooks/useFieldControl.cjs +2 -0
- package/dist/hooks/useFieldControl.cjs.map +1 -0
- package/dist/hooks/useFieldControl.mjs +62 -0
- package/dist/hooks/useFieldControl.mjs.map +1 -0
- package/dist/hooks/useFocusTrap.cjs +2 -0
- package/dist/hooks/useFocusTrap.cjs.map +1 -0
- package/dist/hooks/useFocusTrap.mjs +266 -0
- package/dist/hooks/useFocusTrap.mjs.map +1 -0
- package/dist/hooks/useFormReset.cjs +2 -0
- package/dist/hooks/useFormReset.cjs.map +1 -0
- package/dist/hooks/useFormReset.mjs +33 -0
- package/dist/hooks/useFormReset.mjs.map +1 -0
- package/dist/hooks/useHoverIntent.cjs +2 -0
- package/dist/hooks/useHoverIntent.cjs.map +1 -0
- package/dist/hooks/useHoverIntent.mjs +201 -0
- package/dist/hooks/useHoverIntent.mjs.map +1 -0
- package/dist/hooks/useId.cjs +2 -0
- package/dist/hooks/useId.cjs.map +1 -0
- package/dist/hooks/useId.mjs +11 -0
- package/dist/hooks/useId.mjs.map +1 -0
- package/dist/hooks/useIsClient.cjs +2 -0
- package/dist/hooks/useIsClient.cjs.map +1 -0
- package/dist/hooks/useIsClient.mjs +19 -0
- package/dist/hooks/useIsClient.mjs.map +1 -0
- package/dist/hooks/useListbox.cjs +2 -0
- package/dist/hooks/useListbox.cjs.map +1 -0
- package/dist/hooks/useListbox.mjs +492 -0
- package/dist/hooks/useListbox.mjs.map +1 -0
- package/dist/hooks/useMergedRefs.cjs +2 -0
- package/dist/hooks/useMergedRefs.cjs.map +1 -0
- package/dist/hooks/useMergedRefs.mjs +57 -0
- package/dist/hooks/useMergedRefs.mjs.map +1 -0
- package/dist/hooks/useModalIsolation.cjs +2 -0
- package/dist/hooks/useModalIsolation.cjs.map +1 -0
- package/dist/hooks/useModalIsolation.mjs +87 -0
- package/dist/hooks/useModalIsolation.mjs.map +1 -0
- package/dist/hooks/useModalLayer.cjs +2 -0
- package/dist/hooks/useModalLayer.cjs.map +1 -0
- package/dist/hooks/useModalLayer.mjs +30 -0
- package/dist/hooks/useModalLayer.mjs.map +1 -0
- package/dist/hooks/usePopupPosition.cjs +2 -0
- package/dist/hooks/usePopupPosition.cjs.map +1 -0
- package/dist/hooks/usePopupPosition.mjs +117 -0
- package/dist/hooks/usePopupPosition.mjs.map +1 -0
- package/dist/hooks/usePrefersReducedMotion.cjs +2 -0
- package/dist/hooks/usePrefersReducedMotion.cjs.map +1 -0
- package/dist/hooks/usePrefersReducedMotion.mjs +24 -0
- package/dist/hooks/usePrefersReducedMotion.mjs.map +1 -0
- package/dist/hooks/usePresence.cjs +2 -0
- package/dist/hooks/usePresence.cjs.map +1 -0
- package/dist/hooks/usePresence.mjs +136 -0
- package/dist/hooks/usePresence.mjs.map +1 -0
- package/dist/hooks/usePreserveFocus.cjs +2 -0
- package/dist/hooks/usePreserveFocus.cjs.map +1 -0
- package/dist/hooks/usePreserveFocus.mjs +50 -0
- package/dist/hooks/usePreserveFocus.mjs.map +1 -0
- package/dist/hooks/useRestoreFocus.cjs +2 -0
- package/dist/hooks/useRestoreFocus.cjs.map +1 -0
- package/dist/hooks/useRestoreFocus.mjs +271 -0
- package/dist/hooks/useRestoreFocus.mjs.map +1 -0
- package/dist/hooks/useRovingTabIndex.cjs +2 -0
- package/dist/hooks/useRovingTabIndex.cjs.map +1 -0
- package/dist/hooks/useRovingTabIndex.mjs +389 -0
- package/dist/hooks/useRovingTabIndex.mjs.map +1 -0
- package/dist/hooks/useScrollLock.cjs +2 -0
- package/dist/hooks/useScrollLock.cjs.map +1 -0
- package/dist/hooks/useScrollLock.mjs +71 -0
- package/dist/hooks/useScrollLock.mjs.map +1 -0
- package/dist/hooks/useTriggerElement.cjs +2 -0
- package/dist/hooks/useTriggerElement.cjs.map +1 -0
- package/dist/hooks/useTriggerElement.mjs +126 -0
- package/dist/hooks/useTriggerElement.mjs.map +1 -0
- package/dist/hooks/useTypeahead.cjs +2 -0
- package/dist/hooks/useTypeahead.cjs.map +1 -0
- package/dist/hooks/useTypeahead.mjs +38 -0
- package/dist/hooks/useTypeahead.mjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +9099 -0
- package/dist/index.d.ts +7688 -1027
- package/dist/index.mjs +91 -5695
- package/dist/lib/aria.cjs +2 -0
- package/dist/lib/aria.cjs.map +1 -0
- package/dist/lib/aria.mjs +29 -0
- package/dist/lib/aria.mjs.map +1 -0
- package/dist/lib/children.cjs +2 -0
- package/dist/lib/children.cjs.map +1 -0
- package/dist/lib/children.mjs +37 -0
- package/dist/lib/children.mjs.map +1 -0
- package/dist/lib/cn.cjs +2 -0
- package/dist/lib/cn.cjs.map +1 -0
- package/dist/lib/cn.mjs +64 -0
- package/dist/lib/cn.mjs.map +1 -0
- package/dist/lib/composeEventHandlers.cjs +2 -0
- package/dist/lib/composeEventHandlers.cjs.map +1 -0
- package/dist/lib/composeEventHandlers.mjs +11 -0
- package/dist/lib/composeEventHandlers.mjs.map +1 -0
- package/dist/lib/dev.cjs +2 -0
- package/dist/lib/dev.cjs.map +1 -0
- package/dist/lib/dev.mjs +42 -0
- package/dist/lib/dev.mjs.map +1 -0
- package/dist/lib/direction.cjs +2 -0
- package/dist/lib/direction.cjs.map +1 -0
- package/dist/lib/direction.mjs +35 -0
- package/dist/lib/direction.mjs.map +1 -0
- package/dist/lib/events.cjs +2 -0
- package/dist/lib/events.cjs.map +1 -0
- package/dist/lib/events.mjs +31 -0
- package/dist/lib/events.mjs.map +1 -0
- package/dist/lib/focus.cjs +2 -0
- package/dist/lib/focus.cjs.map +1 -0
- package/dist/lib/focus.mjs +119 -0
- package/dist/lib/focus.mjs.map +1 -0
- package/dist/lib/globalRegistry.cjs +2 -0
- package/dist/lib/globalRegistry.cjs.map +1 -0
- package/dist/lib/globalRegistry.mjs +13 -0
- package/dist/lib/globalRegistry.mjs.map +1 -0
- package/dist/lib/icons.cjs +2 -0
- package/dist/lib/icons.cjs.map +1 -0
- package/dist/lib/icons.mjs +254 -0
- package/dist/lib/icons.mjs.map +1 -0
- package/dist/lib/labelInName.cjs +2 -0
- package/dist/lib/labelInName.cjs.map +1 -0
- package/dist/lib/labelInName.mjs +54 -0
- package/dist/lib/labelInName.mjs.map +1 -0
- package/dist/lib/layers.cjs +2 -0
- package/dist/lib/layers.cjs.map +1 -0
- package/dist/lib/layers.mjs +224 -0
- package/dist/lib/layers.mjs.map +1 -0
- package/dist/lib/mergeProps.cjs +2 -0
- package/dist/lib/mergeProps.cjs.map +1 -0
- package/dist/lib/mergeProps.mjs +21 -0
- package/dist/lib/mergeProps.mjs.map +1 -0
- package/dist/lib/mergeRefs.cjs +2 -0
- package/dist/lib/mergeRefs.cjs.map +1 -0
- package/dist/lib/mergeRefs.mjs +29 -0
- package/dist/lib/mergeRefs.mjs.map +1 -0
- package/dist/lib/renderTrigger.cjs +2 -0
- package/dist/lib/renderTrigger.cjs.map +1 -0
- package/dist/lib/renderTrigger.mjs +29 -0
- package/dist/lib/renderTrigger.mjs.map +1 -0
- package/dist/lib/slot.cjs +2 -0
- package/dist/lib/slot.cjs.map +1 -0
- package/dist/lib/slot.mjs +122 -0
- package/dist/lib/slot.mjs.map +1 -0
- package/dist/lib/styles.cjs +2 -0
- package/dist/lib/styles.cjs.map +1 -0
- package/dist/lib/styles.mjs +16 -0
- package/dist/lib/styles.mjs.map +1 -0
- package/dist/lib/theme.cjs +2 -0
- package/dist/lib/theme.cjs.map +1 -0
- package/dist/lib/theme.mjs +16 -0
- package/dist/lib/theme.mjs.map +1 -0
- package/dist/preflight.css +2 -0
- package/dist/styles.css +2 -0
- package/package.json +149 -100
- package/src/styles/animations.css +7 -39
- package/src/styles/base.css +103 -0
- package/src/styles/globals.css +10 -22
- package/src/styles/legacy-tokens.css +184 -0
- package/src/styles/preflight.css +7 -0
- package/src/styles/styles.css +32 -0
- package/src/styles/tailwind.css +17 -0
- package/src/styles/tokens.css +561 -221
- package/src/styles/variants.css +29 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Toolbar.parts.cjs","names":["Button","slotRendersContent","resolveSlot","useToolbarContext","cn","ToggleButton","composeEventHandlers","getArrowIntent","getDirection","forcedColors","require_runtime","require_cn","require_dev","require_slot","require_composeEventHandlers","require_direction","require_styles","require_Button","require_ToggleButton","require_Toolbar_context","react","react_jsx_runtime","BaseButton","verticalButtonClasses","verticalIconBoxClasses","withIconBox","icon","resolved","box","ToolbarButton","rest","props","toolbar","effectiveSize","size","vertical","className","useRegisterCheckable","register","name","value","ToolbarToggleButton","checked","onClick","event","ToolbarRadioButton","ToolbarRadioGroup","ariaLabel","ariaLabelledBy","handleCrossAxisKeyDown","group","intent","orientation","radios","current","radio","step","count","offset","candidate","onKeyDown","ToolbarGroup","named","role","ToolbarDivider"],"sources":["../../../src/components/button/Toolbar.parts.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { warnOnce } from '../../lib/dev';\nimport { getArrowIntent, getDirection } from '../../lib/direction';\nimport type { PolymorphicComponent, PolymorphicProps } from '../../lib/polymorphic';\nimport { resolveSlot, slotRendersContent } from '../../lib/slot';\nimport type { SlotObject } from '../../lib/slot';\nimport { forcedColors } from '../../lib/styles';\nimport type { Size, Slot } from '../../lib/types';\nimport { Button } from './Button';\nimport type { ButtonOwnProps } from './Button';\nimport { ToggleButton } from './ToggleButton';\nimport type { ToggleButtonProps } from './ToggleButton';\nimport { useToolbarContext } from './Toolbar.context';\n\n/*\n * The parts of a Toolbar: `Toolbar.Button`, `Toolbar.ToggleButton`, `Toolbar.RadioGroup`,\n * `Toolbar.RadioButton`, `Toolbar.Group` and `Toolbar.Divider` (attached in `Toolbar.tsx`, which\n * also exports their flat names).\n */\n\n// ---------------------------------------------------------------------------\n// Toolbar.Button\n// ---------------------------------------------------------------------------\n\n/** Toolbar.Button's own props: Button's, plus `vertical`. Default appearance `'subtle'`. */\nexport interface ToolbarButtonOwnProps extends ButtonOwnProps {\n /** The icon above the label (a 24 px icon box and a caption-size label). @default false */\n vertical?: boolean;\n}\n\n/** Props of {@link ToolbarButton} rendered as `C` (default `'button'`), including `ref`. */\nexport type ToolbarButtonProps<C extends React.ElementType = 'button'> = PolymorphicProps<\n C,\n ToolbarButtonOwnProps\n>;\n\n/** The props the implementation reads, for any `as`. */\ntype ToolbarButtonImplProps = ToolbarButtonOwnProps & { className?: string };\n\n/** `Button` widened to any element props, so `as` and the rest props pass through untyped. */\nconst BaseButton = Button as React.ElementType;\n\n/** The layout of a vertical button: the icon above a caption-size label, no minimum width. */\nconst verticalButtonClasses = 'h-auto min-w-0 flex-col gap-0.5 px-2 py-1 text-caption-1';\n\n/** The icon box of a vertical button per size: 24 px, 20 px at the two small sizes. */\nconst verticalIconBoxClasses: Record<Size, string> = {\n 'extra-small': 'size-5 justify-center [&>svg]:size-full',\n small: 'size-5 justify-center [&>svg]:size-full',\n medium: 'size-6 justify-center [&>svg]:size-full',\n large: 'size-6 justify-center [&>svg]:size-full',\n 'extra-large': 'size-6 justify-center [&>svg]:size-full',\n};\n\n/**\n * `icon` as a slot object whose element also carries `box`: shorthand content becomes the\n * children of a span with `box`, a slot object keeps its element and attributes and gets `box`\n * before its own classes. An icon that renders nothing stays as it is (no icon).\n */\nfunction withIconBox(icon: Slot<'span'> | undefined, box: string): Slot<'span'> | undefined {\n if (!slotRendersContent(icon)) return icon;\n const resolved = resolveSlot(icon, 'span', box);\n if (!resolved) return icon;\n return {\n ...resolved.props,\n as: resolved.Component,\n children: resolved.children,\n } as SlotObject<'span'>;\n}\n\n/**\n * A Button with the toolbar's size and the `subtle` appearance by default (your `size` and\n * `appearance` win). `vertical` puts the icon above a caption-size label, for ribbon-style\n * toolbars. Polymorphic like Button (`as=\"a\"`, a router link). Must be rendered inside a\n * {@link Toolbar}; flat export for React Server Components (`Toolbar.Button` in client files).\n *\n * @example\n * <Toolbar.Button icon={<ShareIcon />}>Share</Toolbar.Button>\n * <Toolbar.Button vertical icon={<PasteIcon />}>Paste</Toolbar.Button>\n */\nexport const ToolbarButton: PolymorphicComponent<'button', ToolbarButtonOwnProps> = (props) => {\n const {\n vertical = false,\n appearance = 'subtle',\n size,\n icon,\n className,\n ...rest\n } = props as ToolbarButtonImplProps;\n const toolbar = useToolbarContext('Toolbar.Button');\n const effectiveSize = size ?? toolbar.size;\n return (\n <BaseButton\n {...rest}\n appearance={appearance}\n size={effectiveSize}\n icon={vertical ? withIconBox(icon, verticalIconBoxClasses[effectiveSize]) : icon}\n data-vertical={vertical ? '' : undefined}\n className={cn(vertical && verticalButtonClasses, className)}\n />\n );\n};\nToolbarButton.displayName = 'ToolbarButton';\n\n// ---------------------------------------------------------------------------\n// Toolbar.ToggleButton and Toolbar.RadioButton\n// ---------------------------------------------------------------------------\n\n/** Properties for Toolbar.ToggleButton: ToggleButton's, bound to the Toolbar's `checkedValues`. */\nexport interface ToolbarToggleButtonProps extends Omit<\n ToggleButtonProps,\n 'pressed' | 'defaultPressed' | 'onPressedChange' | 'name' | 'value'\n> {\n /** The group: a key of the Toolbar's `checkedValues`. */\n name: string;\n /** The value in `checkedValues[name]` while the toggle is pressed. */\n value: string;\n}\n\n/** Properties for Toolbar.RadioButton: one choice of a `Toolbar.RadioGroup`. */\nexport interface ToolbarRadioButtonProps extends Omit<\n ToggleButtonProps,\n 'pressed' | 'defaultPressed' | 'onPressedChange' | 'name' | 'value' | 'role'\n> {\n /** The group: a key of the Toolbar's `checkedValues`; radio buttons of one `name` are exclusive. */\n name: string;\n /** The group's value while this radio is checked. */\n value: string;\n}\n\n/** Registers a part's `name`/`value` with its toolbar (the duplicate-pair warning). */\nfunction useRegisterCheckable(\n register: (name: string, value: string) => () => void,\n name: string,\n value: string,\n): void {\n React.useEffect(() => register(name, value), [register, name, value]);\n}\n\n/**\n * A ToggleButton with the toolbar's size and the `subtle` appearance by default, pressed while\n * `value` is in the Toolbar's `checkedValues[name]`. A click adds or removes it (your `onClick`\n * runs first; `event.preventDefault()` cancels the change) and calls the Toolbar's\n * `onCheckedValuesChange`. `name` and `value` are binding keys, not rendered as attributes.\n * `isAccessible` and `disabledFocusable` work as on ToggleButton. Must be rendered inside a\n * {@link Toolbar}; flat export for React Server Components (`Toolbar.ToggleButton` in client\n * files).\n *\n * @example\n * <Toolbar aria-label=\"Formatting\" defaultCheckedValues={{ format: ['bold'] }}>\n * <Toolbar.ToggleButton name=\"format\" value=\"bold\" icon={<BoldIcon />} aria-label=\"Bold\" />\n * </Toolbar>\n */\nexport const ToolbarToggleButton = ({\n name,\n value,\n appearance = 'subtle',\n size,\n onClick,\n ...rest\n}: ToolbarToggleButtonProps) => {\n const toolbar = useToolbarContext('Toolbar.ToggleButton');\n const { checked } = toolbar;\n useRegisterCheckable(toolbar.registerCheckable, name, value);\n return (\n <ToggleButton\n {...rest}\n appearance={appearance}\n size={size ?? toolbar.size}\n pressed={checked.isChecked(name, value)}\n onClick={composeEventHandlers(onClick, (event) =>\n checked.toggle(name, value, event.nativeEvent),\n )}\n />\n );\n};\nToolbarToggleButton.displayName = 'ToolbarToggleButton';\n\n/**\n * A ToggleButton with `role=\"radio\"` (it reports its state with `aria-checked` and\n * `data-checked`, besides `data-pressed`), the toolbar's size and the `subtle` appearance by\n * default: one choice of a `Toolbar.RadioGroup`, checked while `value` is the Toolbar's\n * `checkedValues[name]`. Space, Enter or a click checks it (your `onClick` runs first;\n * `event.preventDefault()` cancels); the arrow keys only move focus. A click on the checked radio\n * changes nothing. Must be rendered inside a {@link Toolbar}; flat export for React Server\n * Components (`Toolbar.RadioButton` in client files).\n *\n * @example\n * <Toolbar.RadioGroup aria-label=\"Text alignment\">\n * <Toolbar.RadioButton name=\"align\" value=\"left\" icon={<AlignLeftIcon />} aria-label=\"Left\" />\n * <Toolbar.RadioButton name=\"align\" value=\"center\" icon={<AlignCenterIcon />} aria-label=\"Center\" />\n * </Toolbar.RadioGroup>\n */\nexport const ToolbarRadioButton = ({\n name,\n value,\n appearance = 'subtle',\n size,\n onClick,\n ...rest\n}: ToolbarRadioButtonProps) => {\n const toolbar = useToolbarContext('Toolbar.RadioButton');\n const { checked } = toolbar;\n useRegisterCheckable(toolbar.registerCheckable, name, value);\n return (\n <ToggleButton\n {...rest}\n role=\"radio\"\n appearance={appearance}\n size={size ?? toolbar.size}\n pressed={checked.isChecked(name, value)}\n onClick={composeEventHandlers(onClick, (event) =>\n checked.select(name, value, event.nativeEvent),\n )}\n />\n );\n};\nToolbarRadioButton.displayName = 'ToolbarRadioButton';\n\n// ---------------------------------------------------------------------------\n// Toolbar.RadioGroup\n// ---------------------------------------------------------------------------\n\n/** Properties for Toolbar.RadioGroup. */\nexport interface ToolbarRadioGroupProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Ref to the group element. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/**\n * A set of `Toolbar.RadioButton`s of which one is checked (`role=\"radiogroup\"`; name it with\n * `aria-label`). Its radios are part of the toolbar's arrow-key order; Up and Down (Left and Right\n * in a vertical toolbar) also move among the group's radios, wrapping inside the group. Arrows\n * only move focus; Space, Enter or a click checks.\n *\n * - The cross-axis keys skip natively disabled radios; a `disabledFocusable` one stays reachable,\n * as in the toolbar's own arrow order. A consumer `onKeyDown` runs first\n * (`event.preventDefault()` cancels the move).\n * - Without `aria-label` or `aria-labelledby` it warns once in development.\n * - Its `role` is always `radiogroup` (a `role` you pass is ignored): its radios need it.\n * - Must be rendered inside a {@link Toolbar}; flat export for React Server Components\n * (`Toolbar.RadioGroup` in client files).\n *\n * @example\n * <Toolbar.RadioGroup aria-label=\"Text alignment\">\n * <Toolbar.RadioButton name=\"align\" value=\"left\">Left</Toolbar.RadioButton>\n * <Toolbar.RadioButton name=\"align\" value=\"right\">Right</Toolbar.RadioButton>\n * </Toolbar.RadioGroup>\n */\nexport const ToolbarRadioGroup = ({\n className,\n onKeyDown,\n ref,\n ...rest\n}: ToolbarRadioGroupProps) => {\n const { orientation } = useToolbarContext('Toolbar.RadioGroup');\n const ariaLabel = rest['aria-label'];\n const ariaLabelledBy = rest['aria-labelledby'];\n React.useEffect(() => {\n if (ariaLabel || ariaLabelledBy) return;\n warnOnce(\n 'Toolbar.RadioGroup:name',\n 'Toolbar.RadioGroup: a radio group needs an accessible name that says what it chooses (e.g. \"Text alignment\"). Pass `aria-label` or `aria-labelledby`.',\n );\n }, [ariaLabel, ariaLabelledBy]);\n\n // The cross axis (APG Toolbar): Down/Up in a horizontal toolbar, \"next\"/\"previous\" of Left/Right\n // in a vertical one, move among the group's radios with wrap and check nothing. The toolbar's\n // roving hook records the newly focused radio as its tab stop through its focus handler.\n const handleCrossAxisKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.metaKey || event.ctrlKey || event.altKey) return;\n const group = event.currentTarget;\n const intent =\n orientation === 'vertical'\n ? getArrowIntent(event.key, { orientation: 'horizontal', dir: getDirection(group) })\n : getArrowIntent(event.key, { orientation: 'vertical', dir: 'ltr' });\n if (!intent) return;\n const radios = Array.from(group.querySelectorAll<HTMLElement>('[role=\"radio\"]'));\n const current = radios.findIndex((radio) => radio.contains(event.target as Node));\n if (current === -1) return;\n event.preventDefault();\n const step = intent === 'next' ? 1 : -1;\n const count = radios.length;\n for (let offset = 1; offset < count; offset++) {\n const candidate = radios[(((current + step * offset) % count) + count) % count];\n if (candidate.matches(':disabled')) continue;\n candidate.focus();\n // A radio that CSS hides does not take focus: try the next one.\n if (candidate.ownerDocument.activeElement === candidate) return;\n }\n };\n\n return (\n <div\n {...rest}\n ref={ref}\n // Its radios and the cross-axis keys need the radiogroup: the role is not replaceable.\n role=\"radiogroup\"\n data-roving-transparent=\"\"\n onKeyDown={composeEventHandlers(onKeyDown, handleCrossAxisKeyDown)}\n className={cn('flex gap-1', orientation === 'vertical' && 'flex-col', className)}\n />\n );\n};\nToolbarRadioGroup.displayName = 'ToolbarRadioGroup';\n\n// ---------------------------------------------------------------------------\n// Toolbar.Group and Toolbar.Divider\n// ---------------------------------------------------------------------------\n\n/** Properties for Toolbar.Group. */\nexport interface ToolbarGroupProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Ref to the group element. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/**\n * Lays out related controls in the toolbar's direction. It is `role=\"presentation\"`, or\n * `role=\"group\"` when you name it with `aria-label` or `aria-labelledby` (a `role` you pass\n * wins). Its controls stay in the toolbar's arrow-key order. Renders `data-orientation`. Must be\n * rendered inside a {@link Toolbar}; flat export for React Server Components (`Toolbar.Group` in\n * client files).\n *\n * @example\n * <Toolbar.Group aria-label=\"Sharing\">\n * <Toolbar.Button>Share</Toolbar.Button>\n * </Toolbar.Group>\n */\nexport const ToolbarGroup = ({ role, className, ref, ...rest }: ToolbarGroupProps) => {\n const { orientation } = useToolbarContext('Toolbar.Group');\n const named = Boolean(rest['aria-label'] || rest['aria-labelledby']);\n return (\n <div\n role={role ?? (named ? 'group' : 'presentation')}\n data-orientation={orientation}\n {...rest}\n ref={ref}\n className={cn('flex gap-1', orientation === 'vertical' && 'flex-col', className)}\n />\n );\n};\nToolbarGroup.displayName = 'ToolbarGroup';\n\n/** Properties for Toolbar.Divider. */\nexport interface ToolbarDividerProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'children'\n> {\n /** Ref to the separator element. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/**\n * A separator between groups, drawn across the toolbar (vertical in a horizontal toolbar):\n * `role=\"separator\"` with `aria-orientation`. It is not focusable, so the arrow keys pass it.\n * Must be rendered inside a {@link Toolbar}; flat export for React Server Components\n * (`Toolbar.Divider` in client files).\n */\nexport const ToolbarDivider = ({ className, ref, ...rest }: ToolbarDividerProps) => {\n const { orientation } = useToolbarContext('Toolbar.Divider');\n const vertical = orientation === 'vertical';\n return (\n <div\n role=\"separator\"\n aria-orientation={vertical ? 'horizontal' : 'vertical'}\n {...rest}\n ref={ref}\n className={cn(\n vertical\n ? 'my-1 h-0 shrink-0 self-stretch border-t border-border'\n : 'mx-1 w-0 shrink-0 self-stretch border-s border-border',\n forcedColors.border,\n className,\n )}\n />\n );\n};\nToolbarDivider.displayName = 'ToolbarDivider';\n"],"mappings":"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"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn as e } from "../../lib/cn.mjs";
|
|
3
|
+
import { warnOnce as t } from "../../lib/dev.mjs";
|
|
4
|
+
import { resolveSlot as n, slotRendersContent as r } from "../../lib/slot.mjs";
|
|
5
|
+
import { composeEventHandlers as i } from "../../lib/composeEventHandlers.mjs";
|
|
6
|
+
import { getArrowIntent as a, getDirection as o } from "../../lib/direction.mjs";
|
|
7
|
+
import { forcedColors as s } from "../../lib/styles.mjs";
|
|
8
|
+
import { Button as c } from "./Button.mjs";
|
|
9
|
+
import { ToggleButton as l } from "./ToggleButton.mjs";
|
|
10
|
+
import { useToolbarContext as u } from "./Toolbar.context.mjs";
|
|
11
|
+
import * as d from "react";
|
|
12
|
+
import { jsx as f } from "react/jsx-runtime";
|
|
13
|
+
//#region src/components/button/Toolbar.parts.tsx
|
|
14
|
+
var p = c, m = "h-auto min-w-0 flex-col gap-0.5 px-2 py-1 text-caption-1", h = {
|
|
15
|
+
"extra-small": "size-5 justify-center [&>svg]:size-full",
|
|
16
|
+
small: "size-5 justify-center [&>svg]:size-full",
|
|
17
|
+
medium: "size-6 justify-center [&>svg]:size-full",
|
|
18
|
+
large: "size-6 justify-center [&>svg]:size-full",
|
|
19
|
+
"extra-large": "size-6 justify-center [&>svg]:size-full"
|
|
20
|
+
};
|
|
21
|
+
function g(e, t) {
|
|
22
|
+
if (!r(e)) return e;
|
|
23
|
+
let i = n(e, "span", t);
|
|
24
|
+
return i ? {
|
|
25
|
+
...i.props,
|
|
26
|
+
as: i.Component,
|
|
27
|
+
children: i.children
|
|
28
|
+
} : e;
|
|
29
|
+
}
|
|
30
|
+
var _ = (t) => {
|
|
31
|
+
let { vertical: n = !1, appearance: r = "subtle", size: i, icon: a, className: o, ...s } = t, c = u("Toolbar.Button"), l = i ?? c.size;
|
|
32
|
+
return /* @__PURE__ */ f(p, {
|
|
33
|
+
...s,
|
|
34
|
+
appearance: r,
|
|
35
|
+
size: l,
|
|
36
|
+
icon: n ? g(a, h[l]) : a,
|
|
37
|
+
"data-vertical": n ? "" : void 0,
|
|
38
|
+
className: e(n && m, o)
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
_.displayName = "ToolbarButton";
|
|
42
|
+
function v(e, t, n) {
|
|
43
|
+
d.useEffect(() => e(t, n), [
|
|
44
|
+
e,
|
|
45
|
+
t,
|
|
46
|
+
n
|
|
47
|
+
]);
|
|
48
|
+
}
|
|
49
|
+
var y = ({ name: e, value: t, appearance: n = "subtle", size: r, onClick: a, ...o }) => {
|
|
50
|
+
let s = u("Toolbar.ToggleButton"), { checked: c } = s;
|
|
51
|
+
return v(s.registerCheckable, e, t), /* @__PURE__ */ f(l, {
|
|
52
|
+
...o,
|
|
53
|
+
appearance: n,
|
|
54
|
+
size: r ?? s.size,
|
|
55
|
+
pressed: c.isChecked(e, t),
|
|
56
|
+
onClick: i(a, (n) => c.toggle(e, t, n.nativeEvent))
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
y.displayName = "ToolbarToggleButton";
|
|
60
|
+
var b = ({ name: e, value: t, appearance: n = "subtle", size: r, onClick: a, ...o }) => {
|
|
61
|
+
let s = u("Toolbar.RadioButton"), { checked: c } = s;
|
|
62
|
+
return v(s.registerCheckable, e, t), /* @__PURE__ */ f(l, {
|
|
63
|
+
...o,
|
|
64
|
+
role: "radio",
|
|
65
|
+
appearance: n,
|
|
66
|
+
size: r ?? s.size,
|
|
67
|
+
pressed: c.isChecked(e, t),
|
|
68
|
+
onClick: i(a, (n) => c.select(e, t, n.nativeEvent))
|
|
69
|
+
});
|
|
70
|
+
};
|
|
71
|
+
b.displayName = "ToolbarRadioButton";
|
|
72
|
+
var x = ({ className: n, onKeyDown: r, ref: s, ...c }) => {
|
|
73
|
+
let { orientation: l } = u("Toolbar.RadioGroup"), p = c["aria-label"], m = c["aria-labelledby"];
|
|
74
|
+
d.useEffect(() => {
|
|
75
|
+
p || m || t("Toolbar.RadioGroup:name", "Toolbar.RadioGroup: a radio group needs an accessible name that says what it chooses (e.g. \"Text alignment\"). Pass `aria-label` or `aria-labelledby`.");
|
|
76
|
+
}, [p, m]);
|
|
77
|
+
let h = (e) => {
|
|
78
|
+
if (e.metaKey || e.ctrlKey || e.altKey) return;
|
|
79
|
+
let t = e.currentTarget, n = l === "vertical" ? a(e.key, {
|
|
80
|
+
orientation: "horizontal",
|
|
81
|
+
dir: o(t)
|
|
82
|
+
}) : a(e.key, {
|
|
83
|
+
orientation: "vertical",
|
|
84
|
+
dir: "ltr"
|
|
85
|
+
});
|
|
86
|
+
if (!n) return;
|
|
87
|
+
let r = Array.from(t.querySelectorAll("[role=\"radio\"]")), i = r.findIndex((t) => t.contains(e.target));
|
|
88
|
+
if (i === -1) return;
|
|
89
|
+
e.preventDefault();
|
|
90
|
+
let s = n === "next" ? 1 : -1, c = r.length;
|
|
91
|
+
for (let e = 1; e < c; e++) {
|
|
92
|
+
let t = r[((i + s * e) % c + c) % c];
|
|
93
|
+
if (!t.matches(":disabled") && (t.focus(), t.ownerDocument.activeElement === t)) return;
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
return /* @__PURE__ */ f("div", {
|
|
97
|
+
...c,
|
|
98
|
+
ref: s,
|
|
99
|
+
role: "radiogroup",
|
|
100
|
+
"data-roving-transparent": "",
|
|
101
|
+
onKeyDown: i(r, h),
|
|
102
|
+
className: e("flex gap-1", l === "vertical" && "flex-col", n)
|
|
103
|
+
});
|
|
104
|
+
};
|
|
105
|
+
x.displayName = "ToolbarRadioGroup";
|
|
106
|
+
var S = ({ role: t, className: n, ref: r, ...i }) => {
|
|
107
|
+
let { orientation: a } = u("Toolbar.Group"), o = !!(i["aria-label"] || i["aria-labelledby"]);
|
|
108
|
+
return /* @__PURE__ */ f("div", {
|
|
109
|
+
role: t ?? (o ? "group" : "presentation"),
|
|
110
|
+
"data-orientation": a,
|
|
111
|
+
...i,
|
|
112
|
+
ref: r,
|
|
113
|
+
className: e("flex gap-1", a === "vertical" && "flex-col", n)
|
|
114
|
+
});
|
|
115
|
+
};
|
|
116
|
+
S.displayName = "ToolbarGroup";
|
|
117
|
+
var C = ({ className: t, ref: n, ...r }) => {
|
|
118
|
+
let { orientation: i } = u("Toolbar.Divider"), a = i === "vertical";
|
|
119
|
+
return /* @__PURE__ */ f("div", {
|
|
120
|
+
role: "separator",
|
|
121
|
+
"aria-orientation": a ? "horizontal" : "vertical",
|
|
122
|
+
...r,
|
|
123
|
+
ref: n,
|
|
124
|
+
className: e(a ? "my-1 h-0 shrink-0 self-stretch border-t border-border" : "mx-1 w-0 shrink-0 self-stretch border-s border-border", s.border, t)
|
|
125
|
+
});
|
|
126
|
+
};
|
|
127
|
+
C.displayName = "ToolbarDivider";
|
|
128
|
+
//#endregion
|
|
129
|
+
export { _ as ToolbarButton, C as ToolbarDivider, S as ToolbarGroup, b as ToolbarRadioButton, x as ToolbarRadioGroup, y as ToolbarToggleButton };
|
|
130
|
+
|
|
131
|
+
//# sourceMappingURL=Toolbar.parts.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Toolbar.parts.mjs","names":["React","BaseButton","Button","verticalButtonClasses","verticalIconBoxClasses","withIconBox","slotRendersContent","icon","resolved","resolveSlot","box","ToolbarButton","rest","props","toolbar","useToolbarContext","effectiveSize","size","vertical","cn","className","useRegisterCheckable","register","name","value","ToolbarToggleButton","ToggleButton","checked","composeEventHandlers","onClick","event","ToolbarRadioButton","ToolbarRadioGroup","ariaLabel","ariaLabelledBy","warnOnce","handleCrossAxisKeyDown","group","intent","orientation","getArrowIntent","getDirection","radios","current","radio","step","count","offset","candidate","onKeyDown","ToolbarGroup","named","role","ToolbarDivider","forcedColors"],"sources":["../../../src/components/button/Toolbar.parts.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { warnOnce } from '../../lib/dev';\nimport { getArrowIntent, getDirection } from '../../lib/direction';\nimport type { PolymorphicComponent, PolymorphicProps } from '../../lib/polymorphic';\nimport { resolveSlot, slotRendersContent } from '../../lib/slot';\nimport type { SlotObject } from '../../lib/slot';\nimport { forcedColors } from '../../lib/styles';\nimport type { Size, Slot } from '../../lib/types';\nimport { Button } from './Button';\nimport type { ButtonOwnProps } from './Button';\nimport { ToggleButton } from './ToggleButton';\nimport type { ToggleButtonProps } from './ToggleButton';\nimport { useToolbarContext } from './Toolbar.context';\n\n/*\n * The parts of a Toolbar: `Toolbar.Button`, `Toolbar.ToggleButton`, `Toolbar.RadioGroup`,\n * `Toolbar.RadioButton`, `Toolbar.Group` and `Toolbar.Divider` (attached in `Toolbar.tsx`, which\n * also exports their flat names).\n */\n\n// ---------------------------------------------------------------------------\n// Toolbar.Button\n// ---------------------------------------------------------------------------\n\n/** Toolbar.Button's own props: Button's, plus `vertical`. Default appearance `'subtle'`. */\nexport interface ToolbarButtonOwnProps extends ButtonOwnProps {\n /** The icon above the label (a 24 px icon box and a caption-size label). @default false */\n vertical?: boolean;\n}\n\n/** Props of {@link ToolbarButton} rendered as `C` (default `'button'`), including `ref`. */\nexport type ToolbarButtonProps<C extends React.ElementType = 'button'> = PolymorphicProps<\n C,\n ToolbarButtonOwnProps\n>;\n\n/** The props the implementation reads, for any `as`. */\ntype ToolbarButtonImplProps = ToolbarButtonOwnProps & { className?: string };\n\n/** `Button` widened to any element props, so `as` and the rest props pass through untyped. */\nconst BaseButton = Button as React.ElementType;\n\n/** The layout of a vertical button: the icon above a caption-size label, no minimum width. */\nconst verticalButtonClasses = 'h-auto min-w-0 flex-col gap-0.5 px-2 py-1 text-caption-1';\n\n/** The icon box of a vertical button per size: 24 px, 20 px at the two small sizes. */\nconst verticalIconBoxClasses: Record<Size, string> = {\n 'extra-small': 'size-5 justify-center [&>svg]:size-full',\n small: 'size-5 justify-center [&>svg]:size-full',\n medium: 'size-6 justify-center [&>svg]:size-full',\n large: 'size-6 justify-center [&>svg]:size-full',\n 'extra-large': 'size-6 justify-center [&>svg]:size-full',\n};\n\n/**\n * `icon` as a slot object whose element also carries `box`: shorthand content becomes the\n * children of a span with `box`, a slot object keeps its element and attributes and gets `box`\n * before its own classes. An icon that renders nothing stays as it is (no icon).\n */\nfunction withIconBox(icon: Slot<'span'> | undefined, box: string): Slot<'span'> | undefined {\n if (!slotRendersContent(icon)) return icon;\n const resolved = resolveSlot(icon, 'span', box);\n if (!resolved) return icon;\n return {\n ...resolved.props,\n as: resolved.Component,\n children: resolved.children,\n } as SlotObject<'span'>;\n}\n\n/**\n * A Button with the toolbar's size and the `subtle` appearance by default (your `size` and\n * `appearance` win). `vertical` puts the icon above a caption-size label, for ribbon-style\n * toolbars. Polymorphic like Button (`as=\"a\"`, a router link). Must be rendered inside a\n * {@link Toolbar}; flat export for React Server Components (`Toolbar.Button` in client files).\n *\n * @example\n * <Toolbar.Button icon={<ShareIcon />}>Share</Toolbar.Button>\n * <Toolbar.Button vertical icon={<PasteIcon />}>Paste</Toolbar.Button>\n */\nexport const ToolbarButton: PolymorphicComponent<'button', ToolbarButtonOwnProps> = (props) => {\n const {\n vertical = false,\n appearance = 'subtle',\n size,\n icon,\n className,\n ...rest\n } = props as ToolbarButtonImplProps;\n const toolbar = useToolbarContext('Toolbar.Button');\n const effectiveSize = size ?? toolbar.size;\n return (\n <BaseButton\n {...rest}\n appearance={appearance}\n size={effectiveSize}\n icon={vertical ? withIconBox(icon, verticalIconBoxClasses[effectiveSize]) : icon}\n data-vertical={vertical ? '' : undefined}\n className={cn(vertical && verticalButtonClasses, className)}\n />\n );\n};\nToolbarButton.displayName = 'ToolbarButton';\n\n// ---------------------------------------------------------------------------\n// Toolbar.ToggleButton and Toolbar.RadioButton\n// ---------------------------------------------------------------------------\n\n/** Properties for Toolbar.ToggleButton: ToggleButton's, bound to the Toolbar's `checkedValues`. */\nexport interface ToolbarToggleButtonProps extends Omit<\n ToggleButtonProps,\n 'pressed' | 'defaultPressed' | 'onPressedChange' | 'name' | 'value'\n> {\n /** The group: a key of the Toolbar's `checkedValues`. */\n name: string;\n /** The value in `checkedValues[name]` while the toggle is pressed. */\n value: string;\n}\n\n/** Properties for Toolbar.RadioButton: one choice of a `Toolbar.RadioGroup`. */\nexport interface ToolbarRadioButtonProps extends Omit<\n ToggleButtonProps,\n 'pressed' | 'defaultPressed' | 'onPressedChange' | 'name' | 'value' | 'role'\n> {\n /** The group: a key of the Toolbar's `checkedValues`; radio buttons of one `name` are exclusive. */\n name: string;\n /** The group's value while this radio is checked. */\n value: string;\n}\n\n/** Registers a part's `name`/`value` with its toolbar (the duplicate-pair warning). */\nfunction useRegisterCheckable(\n register: (name: string, value: string) => () => void,\n name: string,\n value: string,\n): void {\n React.useEffect(() => register(name, value), [register, name, value]);\n}\n\n/**\n * A ToggleButton with the toolbar's size and the `subtle` appearance by default, pressed while\n * `value` is in the Toolbar's `checkedValues[name]`. A click adds or removes it (your `onClick`\n * runs first; `event.preventDefault()` cancels the change) and calls the Toolbar's\n * `onCheckedValuesChange`. `name` and `value` are binding keys, not rendered as attributes.\n * `isAccessible` and `disabledFocusable` work as on ToggleButton. Must be rendered inside a\n * {@link Toolbar}; flat export for React Server Components (`Toolbar.ToggleButton` in client\n * files).\n *\n * @example\n * <Toolbar aria-label=\"Formatting\" defaultCheckedValues={{ format: ['bold'] }}>\n * <Toolbar.ToggleButton name=\"format\" value=\"bold\" icon={<BoldIcon />} aria-label=\"Bold\" />\n * </Toolbar>\n */\nexport const ToolbarToggleButton = ({\n name,\n value,\n appearance = 'subtle',\n size,\n onClick,\n ...rest\n}: ToolbarToggleButtonProps) => {\n const toolbar = useToolbarContext('Toolbar.ToggleButton');\n const { checked } = toolbar;\n useRegisterCheckable(toolbar.registerCheckable, name, value);\n return (\n <ToggleButton\n {...rest}\n appearance={appearance}\n size={size ?? toolbar.size}\n pressed={checked.isChecked(name, value)}\n onClick={composeEventHandlers(onClick, (event) =>\n checked.toggle(name, value, event.nativeEvent),\n )}\n />\n );\n};\nToolbarToggleButton.displayName = 'ToolbarToggleButton';\n\n/**\n * A ToggleButton with `role=\"radio\"` (it reports its state with `aria-checked` and\n * `data-checked`, besides `data-pressed`), the toolbar's size and the `subtle` appearance by\n * default: one choice of a `Toolbar.RadioGroup`, checked while `value` is the Toolbar's\n * `checkedValues[name]`. Space, Enter or a click checks it (your `onClick` runs first;\n * `event.preventDefault()` cancels); the arrow keys only move focus. A click on the checked radio\n * changes nothing. Must be rendered inside a {@link Toolbar}; flat export for React Server\n * Components (`Toolbar.RadioButton` in client files).\n *\n * @example\n * <Toolbar.RadioGroup aria-label=\"Text alignment\">\n * <Toolbar.RadioButton name=\"align\" value=\"left\" icon={<AlignLeftIcon />} aria-label=\"Left\" />\n * <Toolbar.RadioButton name=\"align\" value=\"center\" icon={<AlignCenterIcon />} aria-label=\"Center\" />\n * </Toolbar.RadioGroup>\n */\nexport const ToolbarRadioButton = ({\n name,\n value,\n appearance = 'subtle',\n size,\n onClick,\n ...rest\n}: ToolbarRadioButtonProps) => {\n const toolbar = useToolbarContext('Toolbar.RadioButton');\n const { checked } = toolbar;\n useRegisterCheckable(toolbar.registerCheckable, name, value);\n return (\n <ToggleButton\n {...rest}\n role=\"radio\"\n appearance={appearance}\n size={size ?? toolbar.size}\n pressed={checked.isChecked(name, value)}\n onClick={composeEventHandlers(onClick, (event) =>\n checked.select(name, value, event.nativeEvent),\n )}\n />\n );\n};\nToolbarRadioButton.displayName = 'ToolbarRadioButton';\n\n// ---------------------------------------------------------------------------\n// Toolbar.RadioGroup\n// ---------------------------------------------------------------------------\n\n/** Properties for Toolbar.RadioGroup. */\nexport interface ToolbarRadioGroupProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Ref to the group element. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/**\n * A set of `Toolbar.RadioButton`s of which one is checked (`role=\"radiogroup\"`; name it with\n * `aria-label`). Its radios are part of the toolbar's arrow-key order; Up and Down (Left and Right\n * in a vertical toolbar) also move among the group's radios, wrapping inside the group. Arrows\n * only move focus; Space, Enter or a click checks.\n *\n * - The cross-axis keys skip natively disabled radios; a `disabledFocusable` one stays reachable,\n * as in the toolbar's own arrow order. A consumer `onKeyDown` runs first\n * (`event.preventDefault()` cancels the move).\n * - Without `aria-label` or `aria-labelledby` it warns once in development.\n * - Its `role` is always `radiogroup` (a `role` you pass is ignored): its radios need it.\n * - Must be rendered inside a {@link Toolbar}; flat export for React Server Components\n * (`Toolbar.RadioGroup` in client files).\n *\n * @example\n * <Toolbar.RadioGroup aria-label=\"Text alignment\">\n * <Toolbar.RadioButton name=\"align\" value=\"left\">Left</Toolbar.RadioButton>\n * <Toolbar.RadioButton name=\"align\" value=\"right\">Right</Toolbar.RadioButton>\n * </Toolbar.RadioGroup>\n */\nexport const ToolbarRadioGroup = ({\n className,\n onKeyDown,\n ref,\n ...rest\n}: ToolbarRadioGroupProps) => {\n const { orientation } = useToolbarContext('Toolbar.RadioGroup');\n const ariaLabel = rest['aria-label'];\n const ariaLabelledBy = rest['aria-labelledby'];\n React.useEffect(() => {\n if (ariaLabel || ariaLabelledBy) return;\n warnOnce(\n 'Toolbar.RadioGroup:name',\n 'Toolbar.RadioGroup: a radio group needs an accessible name that says what it chooses (e.g. \"Text alignment\"). Pass `aria-label` or `aria-labelledby`.',\n );\n }, [ariaLabel, ariaLabelledBy]);\n\n // The cross axis (APG Toolbar): Down/Up in a horizontal toolbar, \"next\"/\"previous\" of Left/Right\n // in a vertical one, move among the group's radios with wrap and check nothing. The toolbar's\n // roving hook records the newly focused radio as its tab stop through its focus handler.\n const handleCrossAxisKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.metaKey || event.ctrlKey || event.altKey) return;\n const group = event.currentTarget;\n const intent =\n orientation === 'vertical'\n ? getArrowIntent(event.key, { orientation: 'horizontal', dir: getDirection(group) })\n : getArrowIntent(event.key, { orientation: 'vertical', dir: 'ltr' });\n if (!intent) return;\n const radios = Array.from(group.querySelectorAll<HTMLElement>('[role=\"radio\"]'));\n const current = radios.findIndex((radio) => radio.contains(event.target as Node));\n if (current === -1) return;\n event.preventDefault();\n const step = intent === 'next' ? 1 : -1;\n const count = radios.length;\n for (let offset = 1; offset < count; offset++) {\n const candidate = radios[(((current + step * offset) % count) + count) % count];\n if (candidate.matches(':disabled')) continue;\n candidate.focus();\n // A radio that CSS hides does not take focus: try the next one.\n if (candidate.ownerDocument.activeElement === candidate) return;\n }\n };\n\n return (\n <div\n {...rest}\n ref={ref}\n // Its radios and the cross-axis keys need the radiogroup: the role is not replaceable.\n role=\"radiogroup\"\n data-roving-transparent=\"\"\n onKeyDown={composeEventHandlers(onKeyDown, handleCrossAxisKeyDown)}\n className={cn('flex gap-1', orientation === 'vertical' && 'flex-col', className)}\n />\n );\n};\nToolbarRadioGroup.displayName = 'ToolbarRadioGroup';\n\n// ---------------------------------------------------------------------------\n// Toolbar.Group and Toolbar.Divider\n// ---------------------------------------------------------------------------\n\n/** Properties for Toolbar.Group. */\nexport interface ToolbarGroupProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Ref to the group element. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/**\n * Lays out related controls in the toolbar's direction. It is `role=\"presentation\"`, or\n * `role=\"group\"` when you name it with `aria-label` or `aria-labelledby` (a `role` you pass\n * wins). Its controls stay in the toolbar's arrow-key order. Renders `data-orientation`. Must be\n * rendered inside a {@link Toolbar}; flat export for React Server Components (`Toolbar.Group` in\n * client files).\n *\n * @example\n * <Toolbar.Group aria-label=\"Sharing\">\n * <Toolbar.Button>Share</Toolbar.Button>\n * </Toolbar.Group>\n */\nexport const ToolbarGroup = ({ role, className, ref, ...rest }: ToolbarGroupProps) => {\n const { orientation } = useToolbarContext('Toolbar.Group');\n const named = Boolean(rest['aria-label'] || rest['aria-labelledby']);\n return (\n <div\n role={role ?? (named ? 'group' : 'presentation')}\n data-orientation={orientation}\n {...rest}\n ref={ref}\n className={cn('flex gap-1', orientation === 'vertical' && 'flex-col', className)}\n />\n );\n};\nToolbarGroup.displayName = 'ToolbarGroup';\n\n/** Properties for Toolbar.Divider. */\nexport interface ToolbarDividerProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'children'\n> {\n /** Ref to the separator element. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/**\n * A separator between groups, drawn across the toolbar (vertical in a horizontal toolbar):\n * `role=\"separator\"` with `aria-orientation`. It is not focusable, so the arrow keys pass it.\n * Must be rendered inside a {@link Toolbar}; flat export for React Server Components\n * (`Toolbar.Divider` in client files).\n */\nexport const ToolbarDivider = ({ className, ref, ...rest }: ToolbarDividerProps) => {\n const { orientation } = useToolbarContext('Toolbar.Divider');\n const vertical = orientation === 'vertical';\n return (\n <div\n role=\"separator\"\n aria-orientation={vertical ? 'horizontal' : 'vertical'}\n {...rest}\n ref={ref}\n className={cn(\n vertical\n ? 'my-1 h-0 shrink-0 self-stretch border-t border-border'\n : 'mx-1 w-0 shrink-0 self-stretch border-s border-border',\n forcedColors.border,\n className,\n )}\n />\n );\n};\nToolbarDivider.displayName = 'ToolbarDivider';\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";const e=require("../../lib/cn.cjs"),t=require("../../lib/styles.cjs");var n=`inline-flex items-center justify-center rounded font-semibold no-underline transition-colors motion-reduce:transition-none ${t.focusRing}`,r={"extra-small":`h-5 min-w-24 px-1.5 text-caption-2`,small:`h-6 min-w-24 px-2 text-caption-1`,medium:`h-8 min-w-24 px-3 text-body-1`,large:`h-10 min-w-24 px-4 text-body-2`,"extra-large":`h-12 min-w-24 px-5 text-[18px]/[24px]`},i={"extra-small":`h-5 w-5 px-0 text-caption-2`,small:`h-6 w-6 px-0 text-caption-1`,medium:`h-8 w-8 px-0 text-body-1`,large:`h-10 w-10 px-0 text-body-2`,"extra-large":`h-12 w-12 px-0 text-[18px]/[24px]`},a={primary:`border border-transparent bg-primary text-primary-foreground not-disabled:not-aria-disabled:hover:bg-primary-hover not-disabled:not-aria-disabled:active:bg-primary-pressed`,outline:`border border-stroke bg-background text-foreground not-disabled:not-aria-disabled:hover:border-stroke-hover not-disabled:not-aria-disabled:hover:bg-subtle-hover not-disabled:not-aria-disabled:active:bg-subtle-pressed`,subtle:`border border-transparent bg-transparent text-foreground not-disabled:not-aria-disabled:hover:bg-subtle-hover not-disabled:not-aria-disabled:active:bg-subtle-pressed`,transparent:`border border-transparent bg-transparent text-primary not-disabled:not-aria-disabled:hover:underline`},o={primary:`bg-primary-pressed text-primary-foreground not-disabled:not-aria-disabled:hover:bg-primary-pressed`,outline:`border-primary bg-selected text-selected-foreground not-disabled:not-aria-disabled:hover:border-primary not-disabled:not-aria-disabled:hover:bg-selected`,subtle:`bg-selected text-selected-foreground not-disabled:not-aria-disabled:hover:bg-selected`,transparent:`bg-selected text-selected-foreground not-disabled:not-aria-disabled:hover:bg-selected`},s={primary:`bg-primary-pressed text-primary-foreground inset-ring-2 inset-ring-primary-foreground not-disabled:not-aria-disabled:hover:bg-primary-pressed`,outline:`border-primary bg-primary text-primary-foreground not-disabled:not-aria-disabled:hover:border-primary-hover not-disabled:not-aria-disabled:hover:bg-primary-hover not-disabled:not-aria-disabled:active:bg-primary-pressed`,subtle:`bg-primary text-primary-foreground not-disabled:not-aria-disabled:hover:bg-primary-hover not-disabled:not-aria-disabled:active:bg-primary-pressed`,transparent:`bg-primary text-primary-foreground not-disabled:not-aria-disabled:hover:bg-primary-hover not-disabled:not-aria-disabled:active:bg-primary-pressed`},c=`${t.forcedColors.selectedContainer} forced-colors:border-[Highlight]`,l=`forced-colors:outline-[GrayText]`,u=`cursor-not-allowed opacity-50 aria-disabled:focus-visible:opacity-100 ${t.forcedColors.disabled}`;function d({appearance:t=`outline`,size:d=`medium`,disabled:f=!1,iconOnly:p=!1,pressed:m=!1,accessible:h=!1}={}){return e.cn(n,p?i[d]:r[d],a[t],m&&(h?s:o)[t],m&&c,f&&u,m&&f&&l)}exports.buttonAppearanceClasses=a,exports.buttonBaseClasses=n,exports.buttonClassName=d,exports.buttonDisabledClasses=u,exports.buttonIconOnlySizeClasses=i,exports.buttonPressedAccessibleClasses=s,exports.buttonPressedClasses=o,exports.buttonSizeClasses=r;
|
|
2
|
+
//# sourceMappingURL=buttonStyles.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buttonStyles.cjs","names":["focusRing","forcedColors","cn","require_cn","require_styles","buttonBaseClasses","buttonSizeClasses","buttonIconOnlySizeClasses","buttonAppearanceClasses","buttonPressedClasses","buttonPressedAccessibleClasses","buttonPressedForcedColors","buttonPressedDisabledForcedColors","buttonDisabledClasses","buttonClassName","iconOnly","size","appearance","pressed","accessible","disabled"],"sources":["../../../src/components/button/buttonStyles.ts"],"sourcesContent":["/**\n * Shared class maps of the button family (Button, ToggleButton, MenuButton, SplitButton,\n * CompoundButton). Internal to `src/components/button/` (spec §5.7): other packages render the\n * public `Button` instead of importing these maps.\n *\n * Rules (C-TOKENS, C-FOCUS, C-MOTION):\n * - Theme tokens only — the maps follow the provider theme (light, dark, high contrast).\n * - Hover and pressed styles are gated with the literal prefixes\n * `not-disabled:not-aria-disabled:hover:` / `not-disabled:not-aria-disabled:active:`, so they\n * work for `<a>` and `role=\"button\"` elements (`Button as=\"a\"`) and never fire on a disabled or\n * `aria-disabled` control. The `enabled:` variant is never used (it only matches form controls).\n * - The gate raises the specificity of those classes (`:not(:disabled):not([aria-disabled=\"true\"])\n * :hover` is 0,4,0; a bare `hover:` class is 0,2,0), and `cn()` keeps both because their variants\n * differ. A consumer overrides a hover/pressed color with the same gate prefix\n * (`not-disabled:not-aria-disabled:hover:bg-error`, which `cn()` merges over the built-in class)\n * or with the important modifier (`hover:bg-error!`).\n * - Class strings stay literal so Tailwind's scanner sees every utility.\n */\nimport { cn } from '../../lib/cn';\nimport { focusRing, forcedColors } from '../../lib/styles';\nimport type { Appearance, Size } from '../../lib/types';\n\n/**\n * Layout, typography, focus ring and color transition shared by every button. `no-underline`\n * keeps `Button as=\"a\"` from showing the browser's link underline.\n */\nexport const buttonBaseClasses = `inline-flex items-center justify-center rounded font-semibold no-underline transition-colors motion-reduce:transition-none ${focusRing}`;\n\n/**\n * Height, horizontal padding, minimum width and font size per size. The font size grows with the\n * ramp: 10 / 12 / 14 / 16 / 18 px (extra-large is larger than large).\n *\n * Every font size is in px, so the order holds at any root font size: the type-ramp tokens\n * (`text-caption-2` … `text-body-2`) are px, and extra-large uses `text-[18px]/[24px]` (Fluent's\n * base 450 step, which the Wave type ramp does not have). A rem size (Tailwind's 1.125rem step)\n * would shrink below the 16px large size in an app with a root font size under about 14.2px.\n */\nexport const buttonSizeClasses: Record<Size, string> = {\n 'extra-small': 'h-5 min-w-24 px-1.5 text-caption-2',\n small: 'h-6 min-w-24 px-2 text-caption-1',\n medium: 'h-8 min-w-24 px-3 text-body-1',\n large: 'h-10 min-w-24 px-4 text-body-2',\n 'extra-large': 'h-12 min-w-24 px-5 text-[18px]/[24px]',\n};\n\n/** Square sizes for icon-only buttons (no minimum width, no horizontal padding). */\nexport const buttonIconOnlySizeClasses: Record<Size, string> = {\n 'extra-small': 'h-5 w-5 px-0 text-caption-2',\n small: 'h-6 w-6 px-0 text-caption-1',\n medium: 'h-8 w-8 px-0 text-body-1',\n large: 'h-10 w-10 px-0 text-body-2',\n 'extra-large': 'h-12 w-12 px-0 text-[18px]/[24px]',\n};\n\n/**\n * Colors per appearance. Every appearance draws a 1px border (transparent unless `outline`) so all\n * appearances have the same size and forced-colors mode shows the button's edge.\n */\nexport const buttonAppearanceClasses: Record<Appearance, string> = {\n primary:\n 'border border-transparent bg-primary text-primary-foreground not-disabled:not-aria-disabled:hover:bg-primary-hover not-disabled:not-aria-disabled:active:bg-primary-pressed',\n outline:\n 'border border-stroke bg-background text-foreground not-disabled:not-aria-disabled:hover:border-stroke-hover not-disabled:not-aria-disabled:hover:bg-subtle-hover not-disabled:not-aria-disabled:active:bg-subtle-pressed',\n subtle:\n 'border border-transparent bg-transparent text-foreground not-disabled:not-aria-disabled:hover:bg-subtle-hover not-disabled:not-aria-disabled:active:bg-subtle-pressed',\n transparent:\n 'border border-transparent bg-transparent text-primary not-disabled:not-aria-disabled:hover:underline',\n};\n\n/**\n * Pressed/checked colors per appearance (ToggleButton). Layer them **after** the appearance\n * classes with `cn()` (or use `buttonClassName({ pressed: true })`); tailwind-merge then replaces\n * the conflicting appearance colors. Hover keeps the pressed color so the state stays visible.\n */\nexport const buttonPressedClasses: Record<Appearance, string> = {\n primary:\n 'bg-primary-pressed text-primary-foreground not-disabled:not-aria-disabled:hover:bg-primary-pressed',\n outline:\n 'border-primary bg-selected text-selected-foreground not-disabled:not-aria-disabled:hover:border-primary not-disabled:not-aria-disabled:hover:bg-selected',\n subtle: 'bg-selected text-selected-foreground not-disabled:not-aria-disabled:hover:bg-selected',\n transparent:\n 'bg-selected text-selected-foreground not-disabled:not-aria-disabled:hover:bg-selected',\n};\n\n/**\n * The accessible pressed colors per appearance (ToggleButton `isAccessible`): a brand fill with\n * on-brand text, so the state never depends on a light tint; `primary`, already a brand fill,\n * keeps its pressed fill and adds an inset on-brand stroke. Layer them after the appearance\n * classes, in place of {@link buttonPressedClasses} (`buttonClassName({ pressed: true,\n * accessible: true })`). The forced-colors treatment is the same as without them.\n */\nexport const buttonPressedAccessibleClasses: Record<Appearance, string> = {\n primary:\n 'bg-primary-pressed text-primary-foreground inset-ring-2 inset-ring-primary-foreground not-disabled:not-aria-disabled:hover:bg-primary-pressed',\n outline:\n 'border-primary bg-primary text-primary-foreground not-disabled:not-aria-disabled:hover:border-primary-hover not-disabled:not-aria-disabled:hover:bg-primary-hover not-disabled:not-aria-disabled:active:bg-primary-pressed',\n subtle:\n 'bg-primary text-primary-foreground not-disabled:not-aria-disabled:hover:bg-primary-hover not-disabled:not-aria-disabled:active:bg-primary-pressed',\n transparent:\n 'bg-primary text-primary-foreground not-disabled:not-aria-disabled:hover:bg-primary-hover not-disabled:not-aria-disabled:active:bg-primary-pressed',\n};\n\n/**\n * Forced-colors treatment of a pressed button: the **container** recipe, a Highlight outline inside\n * a Highlight border. Never `forcedColors.selectedLeaf`: a button is a container, and the\n * inherited `forced-color-adjust: none` would take its label, icons, child content and focus ring\n * out of forced colors.\n */\nconst buttonPressedForcedColors = `${forcedColors.selectedContainer} forced-colors:border-[Highlight]`;\n\n/**\n * Pressed and disabled: the pressed outline turns GrayText like the disabled text and border (a\n * Highlight indicator next to GrayText would read as available).\n */\nconst buttonPressedDisabledForcedColors = 'forced-colors:outline-[GrayText]';\n\n/**\n * Disabled look (native `disabled`, `aria-disabled` or a non-button `as`), incl. forced colors.\n * `opacity` dims the element's own focus ring too, so a focusable disabled button\n * (`disabledFocusable`, a consumer `aria-disabled`) shows at full opacity while its ring is\n * visible: the ring keeps its 3:1 contrast, and `aria-disabled` still reports the state.\n */\nexport const buttonDisabledClasses = `cursor-not-allowed opacity-50 aria-disabled:focus-visible:opacity-100 ${forcedColors.disabled}`;\n\n/** Options of {@link buttonClassName}. */\nexport interface ButtonClassNameOptions {\n /** @default 'outline' */\n appearance?: Appearance;\n /** @default 'medium' */\n size?: Size;\n /** Adds the disabled look. @default false */\n disabled?: boolean;\n /** Square, icon-only sizing without a minimum width. @default false */\n iconOnly?: boolean;\n /** Adds the pressed/checked colors (ToggleButton). @default false */\n pressed?: boolean;\n /**\n * With `pressed`: the accessible pressed colors ({@link buttonPressedAccessibleClasses}) instead\n * of the selected tint. No effect on an unpressed button. @default false\n */\n accessible?: boolean;\n}\n\n/**\n * The complete class string of a button: base, size (or icon-only size), appearance, and the\n * optional pressed and disabled layers. Consumers' `className` goes after it in `cn()`.\n *\n * @example\n * <button className={cn(buttonClassName({ appearance: 'primary', size: 'small' }), className)} />\n */\nexport function buttonClassName({\n appearance = 'outline',\n size = 'medium',\n disabled = false,\n iconOnly = false,\n pressed = false,\n accessible = false,\n}: ButtonClassNameOptions = {}): string {\n return cn(\n buttonBaseClasses,\n iconOnly ? buttonIconOnlySizeClasses[size] : buttonSizeClasses[size],\n buttonAppearanceClasses[appearance],\n pressed && (accessible ? buttonPressedAccessibleClasses : buttonPressedClasses)[appearance],\n pressed && buttonPressedForcedColors,\n disabled && buttonDisabledClasses,\n pressed && disabled && buttonPressedDisabledForcedColors,\n );\n}\n"],"mappings":"mFA0BA,IAAaK,EAAoB,8HAA8HL,EAAAA,YAWlJM,EAA0C,CACrD,cAAe,qCACf,MAAO,mCACP,OAAQ,gCACR,MAAO,iCACP,cAAe,uCACjB,EAGaC,EAAkD,CAC7D,cAAe,8BACf,MAAO,8BACP,OAAQ,2BACR,MAAO,6BACP,cAAe,mCACjB,EAMaC,EAAsD,CACjE,QACE,8KACF,QACE,2NACF,OACE,wKACF,YACE,sGACJ,EAOaC,EAAmD,CAC9D,QACE,qGACF,QACE,2JACF,OAAQ,wFACR,YACE,uFACJ,EASaC,EAA6D,CACxE,QACE,gJACF,QACE,6NACF,OACE,oJACF,YACE,mJACJ,EAQMC,EAA4B,GAAGV,EAAAA,aAAa,kBAAkB,mCAM9DW,EAAoC,mCAQ7BC,EAAwB,yEAAyEZ,EAAAA,aAAa,WA4B3H,SAAgBa,EAAgB,CAC9B,aAAa,UACb,OAAO,SACP,WAAW,GACX,WAAW,GACX,UAAU,GACV,aAAa,IACa,CAAC,EAAW,CACtC,OAAOZ,EAAAA,GACLG,EACAU,EAAWR,EAA0BS,GAAQV,EAAkBU,GAC/DR,EAAwBS,GACxBC,IAAYC,EAAaT,EAAiCD,EAAA,CAAsBQ,GAChFC,GAAWP,EACXS,GAAYP,EACZK,GAAWE,GAAYR,CACzB,CACF"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn as e } from "../../lib/cn.mjs";
|
|
3
|
+
import { focusRing as t, forcedColors as n } from "../../lib/styles.mjs";
|
|
4
|
+
//#region src/components/button/buttonStyles.ts
|
|
5
|
+
var r = `inline-flex items-center justify-center rounded font-semibold no-underline transition-colors motion-reduce:transition-none ${t}`, i = {
|
|
6
|
+
"extra-small": "h-5 min-w-24 px-1.5 text-caption-2",
|
|
7
|
+
small: "h-6 min-w-24 px-2 text-caption-1",
|
|
8
|
+
medium: "h-8 min-w-24 px-3 text-body-1",
|
|
9
|
+
large: "h-10 min-w-24 px-4 text-body-2",
|
|
10
|
+
"extra-large": "h-12 min-w-24 px-5 text-[18px]/[24px]"
|
|
11
|
+
}, a = {
|
|
12
|
+
"extra-small": "h-5 w-5 px-0 text-caption-2",
|
|
13
|
+
small: "h-6 w-6 px-0 text-caption-1",
|
|
14
|
+
medium: "h-8 w-8 px-0 text-body-1",
|
|
15
|
+
large: "h-10 w-10 px-0 text-body-2",
|
|
16
|
+
"extra-large": "h-12 w-12 px-0 text-[18px]/[24px]"
|
|
17
|
+
}, o = {
|
|
18
|
+
primary: "border border-transparent bg-primary text-primary-foreground not-disabled:not-aria-disabled:hover:bg-primary-hover not-disabled:not-aria-disabled:active:bg-primary-pressed",
|
|
19
|
+
outline: "border border-stroke bg-background text-foreground not-disabled:not-aria-disabled:hover:border-stroke-hover not-disabled:not-aria-disabled:hover:bg-subtle-hover not-disabled:not-aria-disabled:active:bg-subtle-pressed",
|
|
20
|
+
subtle: "border border-transparent bg-transparent text-foreground not-disabled:not-aria-disabled:hover:bg-subtle-hover not-disabled:not-aria-disabled:active:bg-subtle-pressed",
|
|
21
|
+
transparent: "border border-transparent bg-transparent text-primary not-disabled:not-aria-disabled:hover:underline"
|
|
22
|
+
}, s = {
|
|
23
|
+
primary: "bg-primary-pressed text-primary-foreground not-disabled:not-aria-disabled:hover:bg-primary-pressed",
|
|
24
|
+
outline: "border-primary bg-selected text-selected-foreground not-disabled:not-aria-disabled:hover:border-primary not-disabled:not-aria-disabled:hover:bg-selected",
|
|
25
|
+
subtle: "bg-selected text-selected-foreground not-disabled:not-aria-disabled:hover:bg-selected",
|
|
26
|
+
transparent: "bg-selected text-selected-foreground not-disabled:not-aria-disabled:hover:bg-selected"
|
|
27
|
+
}, c = {
|
|
28
|
+
primary: "bg-primary-pressed text-primary-foreground inset-ring-2 inset-ring-primary-foreground not-disabled:not-aria-disabled:hover:bg-primary-pressed",
|
|
29
|
+
outline: "border-primary bg-primary text-primary-foreground not-disabled:not-aria-disabled:hover:border-primary-hover not-disabled:not-aria-disabled:hover:bg-primary-hover not-disabled:not-aria-disabled:active:bg-primary-pressed",
|
|
30
|
+
subtle: "bg-primary text-primary-foreground not-disabled:not-aria-disabled:hover:bg-primary-hover not-disabled:not-aria-disabled:active:bg-primary-pressed",
|
|
31
|
+
transparent: "bg-primary text-primary-foreground not-disabled:not-aria-disabled:hover:bg-primary-hover not-disabled:not-aria-disabled:active:bg-primary-pressed"
|
|
32
|
+
}, l = `${n.selectedContainer} forced-colors:border-[Highlight]`, u = "forced-colors:outline-[GrayText]", d = `cursor-not-allowed opacity-50 aria-disabled:focus-visible:opacity-100 ${n.disabled}`;
|
|
33
|
+
function f({ appearance: t = "outline", size: n = "medium", disabled: f = !1, iconOnly: p = !1, pressed: m = !1, accessible: h = !1 } = {}) {
|
|
34
|
+
return e(r, p ? a[n] : i[n], o[t], m && (h ? c : s)[t], m && l, f && d, m && f && u);
|
|
35
|
+
}
|
|
36
|
+
//#endregion
|
|
37
|
+
export { o as buttonAppearanceClasses, r as buttonBaseClasses, f as buttonClassName, d as buttonDisabledClasses, a as buttonIconOnlySizeClasses, c as buttonPressedAccessibleClasses, s as buttonPressedClasses, i as buttonSizeClasses };
|
|
38
|
+
|
|
39
|
+
//# sourceMappingURL=buttonStyles.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buttonStyles.mjs","names":["buttonBaseClasses","focusRing","buttonSizeClasses","buttonIconOnlySizeClasses","buttonAppearanceClasses","buttonPressedClasses","buttonPressedAccessibleClasses","buttonPressedForcedColors","forcedColors","buttonPressedDisabledForcedColors","buttonDisabledClasses","buttonClassName","cn","iconOnly","size","appearance","pressed","accessible","disabled"],"sources":["../../../src/components/button/buttonStyles.ts"],"sourcesContent":["/**\n * Shared class maps of the button family (Button, ToggleButton, MenuButton, SplitButton,\n * CompoundButton). Internal to `src/components/button/` (spec §5.7): other packages render the\n * public `Button` instead of importing these maps.\n *\n * Rules (C-TOKENS, C-FOCUS, C-MOTION):\n * - Theme tokens only — the maps follow the provider theme (light, dark, high contrast).\n * - Hover and pressed styles are gated with the literal prefixes\n * `not-disabled:not-aria-disabled:hover:` / `not-disabled:not-aria-disabled:active:`, so they\n * work for `<a>` and `role=\"button\"` elements (`Button as=\"a\"`) and never fire on a disabled or\n * `aria-disabled` control. The `enabled:` variant is never used (it only matches form controls).\n * - The gate raises the specificity of those classes (`:not(:disabled):not([aria-disabled=\"true\"])\n * :hover` is 0,4,0; a bare `hover:` class is 0,2,0), and `cn()` keeps both because their variants\n * differ. A consumer overrides a hover/pressed color with the same gate prefix\n * (`not-disabled:not-aria-disabled:hover:bg-error`, which `cn()` merges over the built-in class)\n * or with the important modifier (`hover:bg-error!`).\n * - Class strings stay literal so Tailwind's scanner sees every utility.\n */\nimport { cn } from '../../lib/cn';\nimport { focusRing, forcedColors } from '../../lib/styles';\nimport type { Appearance, Size } from '../../lib/types';\n\n/**\n * Layout, typography, focus ring and color transition shared by every button. `no-underline`\n * keeps `Button as=\"a\"` from showing the browser's link underline.\n */\nexport const buttonBaseClasses = `inline-flex items-center justify-center rounded font-semibold no-underline transition-colors motion-reduce:transition-none ${focusRing}`;\n\n/**\n * Height, horizontal padding, minimum width and font size per size. The font size grows with the\n * ramp: 10 / 12 / 14 / 16 / 18 px (extra-large is larger than large).\n *\n * Every font size is in px, so the order holds at any root font size: the type-ramp tokens\n * (`text-caption-2` … `text-body-2`) are px, and extra-large uses `text-[18px]/[24px]` (Fluent's\n * base 450 step, which the Wave type ramp does not have). A rem size (Tailwind's 1.125rem step)\n * would shrink below the 16px large size in an app with a root font size under about 14.2px.\n */\nexport const buttonSizeClasses: Record<Size, string> = {\n 'extra-small': 'h-5 min-w-24 px-1.5 text-caption-2',\n small: 'h-6 min-w-24 px-2 text-caption-1',\n medium: 'h-8 min-w-24 px-3 text-body-1',\n large: 'h-10 min-w-24 px-4 text-body-2',\n 'extra-large': 'h-12 min-w-24 px-5 text-[18px]/[24px]',\n};\n\n/** Square sizes for icon-only buttons (no minimum width, no horizontal padding). */\nexport const buttonIconOnlySizeClasses: Record<Size, string> = {\n 'extra-small': 'h-5 w-5 px-0 text-caption-2',\n small: 'h-6 w-6 px-0 text-caption-1',\n medium: 'h-8 w-8 px-0 text-body-1',\n large: 'h-10 w-10 px-0 text-body-2',\n 'extra-large': 'h-12 w-12 px-0 text-[18px]/[24px]',\n};\n\n/**\n * Colors per appearance. Every appearance draws a 1px border (transparent unless `outline`) so all\n * appearances have the same size and forced-colors mode shows the button's edge.\n */\nexport const buttonAppearanceClasses: Record<Appearance, string> = {\n primary:\n 'border border-transparent bg-primary text-primary-foreground not-disabled:not-aria-disabled:hover:bg-primary-hover not-disabled:not-aria-disabled:active:bg-primary-pressed',\n outline:\n 'border border-stroke bg-background text-foreground not-disabled:not-aria-disabled:hover:border-stroke-hover not-disabled:not-aria-disabled:hover:bg-subtle-hover not-disabled:not-aria-disabled:active:bg-subtle-pressed',\n subtle:\n 'border border-transparent bg-transparent text-foreground not-disabled:not-aria-disabled:hover:bg-subtle-hover not-disabled:not-aria-disabled:active:bg-subtle-pressed',\n transparent:\n 'border border-transparent bg-transparent text-primary not-disabled:not-aria-disabled:hover:underline',\n};\n\n/**\n * Pressed/checked colors per appearance (ToggleButton). Layer them **after** the appearance\n * classes with `cn()` (or use `buttonClassName({ pressed: true })`); tailwind-merge then replaces\n * the conflicting appearance colors. Hover keeps the pressed color so the state stays visible.\n */\nexport const buttonPressedClasses: Record<Appearance, string> = {\n primary:\n 'bg-primary-pressed text-primary-foreground not-disabled:not-aria-disabled:hover:bg-primary-pressed',\n outline:\n 'border-primary bg-selected text-selected-foreground not-disabled:not-aria-disabled:hover:border-primary not-disabled:not-aria-disabled:hover:bg-selected',\n subtle: 'bg-selected text-selected-foreground not-disabled:not-aria-disabled:hover:bg-selected',\n transparent:\n 'bg-selected text-selected-foreground not-disabled:not-aria-disabled:hover:bg-selected',\n};\n\n/**\n * The accessible pressed colors per appearance (ToggleButton `isAccessible`): a brand fill with\n * on-brand text, so the state never depends on a light tint; `primary`, already a brand fill,\n * keeps its pressed fill and adds an inset on-brand stroke. Layer them after the appearance\n * classes, in place of {@link buttonPressedClasses} (`buttonClassName({ pressed: true,\n * accessible: true })`). The forced-colors treatment is the same as without them.\n */\nexport const buttonPressedAccessibleClasses: Record<Appearance, string> = {\n primary:\n 'bg-primary-pressed text-primary-foreground inset-ring-2 inset-ring-primary-foreground not-disabled:not-aria-disabled:hover:bg-primary-pressed',\n outline:\n 'border-primary bg-primary text-primary-foreground not-disabled:not-aria-disabled:hover:border-primary-hover not-disabled:not-aria-disabled:hover:bg-primary-hover not-disabled:not-aria-disabled:active:bg-primary-pressed',\n subtle:\n 'bg-primary text-primary-foreground not-disabled:not-aria-disabled:hover:bg-primary-hover not-disabled:not-aria-disabled:active:bg-primary-pressed',\n transparent:\n 'bg-primary text-primary-foreground not-disabled:not-aria-disabled:hover:bg-primary-hover not-disabled:not-aria-disabled:active:bg-primary-pressed',\n};\n\n/**\n * Forced-colors treatment of a pressed button: the **container** recipe, a Highlight outline inside\n * a Highlight border. Never `forcedColors.selectedLeaf`: a button is a container, and the\n * inherited `forced-color-adjust: none` would take its label, icons, child content and focus ring\n * out of forced colors.\n */\nconst buttonPressedForcedColors = `${forcedColors.selectedContainer} forced-colors:border-[Highlight]`;\n\n/**\n * Pressed and disabled: the pressed outline turns GrayText like the disabled text and border (a\n * Highlight indicator next to GrayText would read as available).\n */\nconst buttonPressedDisabledForcedColors = 'forced-colors:outline-[GrayText]';\n\n/**\n * Disabled look (native `disabled`, `aria-disabled` or a non-button `as`), incl. forced colors.\n * `opacity` dims the element's own focus ring too, so a focusable disabled button\n * (`disabledFocusable`, a consumer `aria-disabled`) shows at full opacity while its ring is\n * visible: the ring keeps its 3:1 contrast, and `aria-disabled` still reports the state.\n */\nexport const buttonDisabledClasses = `cursor-not-allowed opacity-50 aria-disabled:focus-visible:opacity-100 ${forcedColors.disabled}`;\n\n/** Options of {@link buttonClassName}. */\nexport interface ButtonClassNameOptions {\n /** @default 'outline' */\n appearance?: Appearance;\n /** @default 'medium' */\n size?: Size;\n /** Adds the disabled look. @default false */\n disabled?: boolean;\n /** Square, icon-only sizing without a minimum width. @default false */\n iconOnly?: boolean;\n /** Adds the pressed/checked colors (ToggleButton). @default false */\n pressed?: boolean;\n /**\n * With `pressed`: the accessible pressed colors ({@link buttonPressedAccessibleClasses}) instead\n * of the selected tint. No effect on an unpressed button. @default false\n */\n accessible?: boolean;\n}\n\n/**\n * The complete class string of a button: base, size (or icon-only size), appearance, and the\n * optional pressed and disabled layers. Consumers' `className` goes after it in `cn()`.\n *\n * @example\n * <button className={cn(buttonClassName({ appearance: 'primary', size: 'small' }), className)} />\n */\nexport function buttonClassName({\n appearance = 'outline',\n size = 'medium',\n disabled = false,\n iconOnly = false,\n pressed = false,\n accessible = false,\n}: ButtonClassNameOptions = {}): string {\n return cn(\n buttonBaseClasses,\n iconOnly ? buttonIconOnlySizeClasses[size] : buttonSizeClasses[size],\n buttonAppearanceClasses[appearance],\n pressed && (accessible ? buttonPressedAccessibleClasses : buttonPressedClasses)[appearance],\n pressed && buttonPressedForcedColors,\n disabled && buttonDisabledClasses,\n pressed && disabled && buttonPressedDisabledForcedColors,\n );\n}\n"],"mappings":";;;;AA0BA,IAAaA,IAAoB,8HAA8HC,KAWlJC,IAA0C;CACrD,eAAe;CACf,OAAO;CACP,QAAQ;CACR,OAAO;CACP,eAAe;AACjB,GAGaC,IAAkD;CAC7D,eAAe;CACf,OAAO;CACP,QAAQ;CACR,OAAO;CACP,eAAe;AACjB,GAMaC,IAAsD;CACjE,SACE;CACF,SACE;CACF,QACE;CACF,aACE;AACJ,GAOaC,IAAmD;CAC9D,SACE;CACF,SACE;CACF,QAAQ;CACR,aACE;AACJ,GASaC,IAA6D;CACxE,SACE;CACF,SACE;CACF,QACE;CACF,aACE;AACJ,GAQMC,IAA4B,GAAGC,EAAa,kBAAkB,oCAM9DC,IAAoC,oCAQ7BC,IAAwB,yEAAyEF,EAAa;AA4B3H,SAAgBG,EAAgB,EAC9B,gBAAa,WACb,UAAO,UACP,cAAW,IACX,cAAW,IACX,aAAU,IACV,gBAAa,OACa,CAAC,GAAW;CACtC,OAAOC,EACLZ,GACAa,IAAWV,EAA0BW,KAAQZ,EAAkBY,IAC/DV,EAAwBW,IACxBC,MAAYC,IAAaX,IAAiCD,EAAA,CAAsBU,IAChFC,KAAWT,GACXW,KAAYR,GACZM,KAAWE,KAAYT,CACzB;AACF"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("../../lib/cn.cjs"),n=require("../../lib/slot.cjs"),r=require("../../lib/composeEventHandlers.cjs"),i=require("../../hooks/useMergedRefs.cjs"),ee=require("../../lib/aria.cjs"),te=require("../../lib/icons.cjs");let a=require("react");a=e.__toESM(a,1);let o=require("react/jsx-runtime");var s={"extra-small":`w-6 h-6 text-[10px]`,small:`w-8 h-8 text-xs`,medium:`w-10 h-10 text-sm`,large:`w-12 h-12 text-base`,"extra-large":`w-14 h-14 text-lg`},c=`w-full h-full object-cover`;function ne(e){let t=e.trim().split(/\s+/).filter(Boolean);return t.length===0?``:((Array.from(t[0])[0]??``)+(t.length>1?Array.from(t[t.length-1])[0]??``:``)).toUpperCase()}function l(e){return e?.trim().replace(/\s+/g,` `)||void 0}function re(e){if(a.isValidElement(e))return e.props;if(typeof e==`object`&&e&&!(Symbol.iterator in e))return e}function ie(e,t,n){if(e===void 0)return[void 0,void 0,n||void 0,void 0];if(typeof e==`string`)return[void 0,void 0,e,void 0];let r=a.isValidElement(e)?e:void 0;return[r?.type,r?.key,t?.src,t?.srcSet]}function u(e){if(typeof e!=`object`||!e)return!1;let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}function d(e,t){if(Object.is(e,t))return!0;if(!u(e)||!u(t))return!1;let n=Object.keys(e);return n.length===Object.keys(t).length&&n.every(n=>Object.prototype.hasOwnProperty.call(t,n)&&Object.is(e[n],t[n]))}function ae(e,t){return e.every((e,n)=>d(e,t[n]))}var f=({src:e,name:u,size:d=`medium`,icon:f,image:p,badge:m,decorative:h=!1,className:g,ref:_,role:v,"aria-label":y,"aria-labelledby":b,"aria-describedby":x,"aria-description":S,"aria-details":C,...w})=>{let T=p==null||typeof p==`boolean`||p===``?void 0:p,E=re(T),D=ie(T,E,e),[oe,O]=a.useState(!1),[k,A]=a.useState(D);ae(k,D)||(A(D),O(!1));let j=a.useRef(null);a.useLayoutEffect(()=>{let e=j.current?.querySelector(`img`);if(!e||!e.complete||e.naturalWidth!==0)return;let t=!0,n=e.getAttribute(`src`),r=e.getAttribute(`srcset`),i=()=>{t&&e.isConnected&&e.getAttribute(`src`)===n&&e.getAttribute(`srcset`)===r&&O(!0)};return typeof e.decode==`function`?e.decode().then(void 0,i):queueMicrotask(i),()=>{t=!1}},[]);let M=i.useMergedRefs(_,j),N=y!==void 0||b!==void 0,P=v!==void 0&&v!==`presentation`&&v!==`none`,F=l(u),I=h||N||P?``:F??``,L=()=>O(!0),R=E?.alt,z=R!=null,B=z?R:I,V={"aria-describedby":x,"aria-description":S,"aria-details":C},H=!h&&!N&&!P&&typeof B==`string`&&B.trim()!==``,U=H?V:{},W=null;if(!oe){if(typeof T==`string`)W=(0,o.jsx)(`img`,{src:T,alt:I,...U,className:c,onError:L});else if(T!==void 0){let e={onError:r.composeEventHandlers(E?.onError,L)};if(z||(e.alt=I),H){let t=E?.[`aria-describedby`];e[`aria-describedby`]=ee.joinIds(x,typeof t==`string`?t:void 0)}let t=a.isValidElement(T)?a.cloneElement(T,e):E?{...T,...e}:T;W=n.renderSlot(t,`img`,c,{alt:I,...U})}else e&&(W=(0,o.jsx)(`img`,{src:e,alt:I,...U,className:c,onError:L}))}let G=W!==null&&H?{}:V,K=W===null&&f&&n.slotRendersContent(f)?n.renderSlot(f,`span`,`inline-flex`,{"aria-hidden":!0}):null,q=W===null&&K===null&&u?ne(u):``,J,Y;W===null?K===null?q?(J=(0,o.jsx)(`span`,{"aria-hidden":`true`,children:q}),Y=`bg-primary text-primary-foreground`):(J=(0,o.jsx)(te.PersonIcon,{size:`60%`}),Y=`bg-muted text-muted-foreground`):(J=K,Y=`bg-muted text-muted-foreground`):J=W;let se=W!==null&&P&&typeof B==`string`?l(B):void 0,ce=typeof R==`string`?l(R):void 0,X=y??(W===null?F??ce:P?se??F:void 0),Z;Z=h?{"aria-hidden":!0,...G}:X!==void 0||b!==void 0?{role:v??`img`,"aria-label":X,"aria-labelledby":b,...G}:W!==null||v!==void 0?{role:v,...G}:{"aria-hidden":!0,...G};let Q=m&&n.slotRendersContent(m)?n.renderSlot(m,`span`,`absolute bottom-0 end-0 inline-flex`):null,le=Q!==null,$=t.cn(`inline-flex items-center justify-center rounded-full overflow-hidden shrink-0 font-bold`,s[d],Y);return le?(0,o.jsxs)(`span`,{ref:_,...w,className:t.cn(`relative inline-flex shrink-0`,g),children:[(0,o.jsx)(`span`,{ref:j,...Z,className:$,children:J}),Q]}):(0,o.jsx)(`span`,{ref:M,...Z,...w,className:t.cn($,g),children:J})};f.displayName=`Avatar`,exports.Avatar=f,exports.avatarSizeClasses=s;
|
|
2
|
+
//# sourceMappingURL=Avatar.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Avatar.cjs","names":["React","useMergedRefs","composeEventHandlers","joinIds","renderSlot","slotRendersContent","PersonIcon","cn","require_runtime","require_cn","require_slot","require_composeEventHandlers","require_useMergedRefs","require_aria","require_icons","react","react_jsx_runtime","avatarSizeClasses","IMAGE_CLASS","getInitials","parts","name","normaliseName","readSlotProps","slot","getImageKey","imageSlot","src","element","slotProps","isPlainObject","value","proto","sameKeyPart","a","b","keys","k","sameImageKey","part","i","Avatar","ariaLabel","ariaLabelledBy","ariaDescribedBy","ariaDescription","ariaDetails","rest","image","imageKey","failed","setFailed","prevImageKey","setPrevImageKey","visualRef","img","active","checkedSrc","checkedSrcSet","markFailed","rootVisualRef","ref","hasConsumerName","roleCarriesName","role","normalisedName","imageAlt","decorative","handleError","ownAlt","hasOwnAlt","renderedAlt","description","imageIsNamed","imageDescription","imageNode","overrides","ownIds","visualDescription","iconNode","icon","initials","content","colorClass","imageName","slotAltName","label","a11yProps","badgeNode","badge","hasBadge","visualClassName","size","className"],"sources":["../../../src/components/data-display/Avatar.tsx"],"sourcesContent":["import * as React from 'react';\nimport { joinIds } from '../../lib/aria';\nimport { cn } from '../../lib/cn';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { PersonIcon } from '../../lib/icons';\nimport type { Size, Slot } from '../../lib/types';\nimport { renderSlot, slotRendersContent } from '../../lib/slot';\n\n/** Properties for the Avatar component. */\nexport interface AvatarProps extends React.HTMLAttributes<HTMLSpanElement> {\n /**\n * URL of the avatar image. When it fails to load (also before hydration, for server-rendered\n * markup), the avatar falls back to its icon or initials; a new `src` is tried again.\n */\n src?: string;\n /**\n * Full name of the person. It names the avatar for assistive technology (the image `alt`; in\n * initials and icon mode, or with a consumer `role`, the avatar's `aria-label`, with\n * `role=\"img\"` unless `role` is given) and generates the initials shown when there is no image.\n */\n name?: string;\n /** Size of the avatar.\n * @default 'medium'\n */\n size?: Size;\n /**\n * Icon shown instead of the initials when there is no image. Rendered in an `aria-hidden`\n * `<span>` (a slot object can override its attributes). A falsy value (`null`, `false`, `''`,\n * `0`, `NaN`, e.g. `icon={count && <Icon />}`) counts as no icon, as in 0.4, and so does an\n * array, `Set` or generator whose items render nothing. Without `icon` and without a usable\n * `name`, a generic person glyph is shown.\n */\n icon?: Slot<'span'>;\n /**\n * Custom image. Accepts a URL string (treated like `src`), an element (rendered as the image\n * itself, e.g. `<img>` or a framework image component) or an object of `<img>` attributes\n * (`{ src, alt, … }`). Takes precedence over `src`; its `alt` defaults to `name` (an `alt` that\n * is `undefined` counts as not given). When its alt names the avatar, the avatar's\n * `aria-describedby` ids are joined with the slot's own, while the slot's own `aria-description`\n * and `aria-details` win over the avatar's. When the image fails to load, an avatar without a\n * `name` keeps the name of the slot's own `alt`. After a load failure, a new image is tried\n * again: another `src` or `srcSet` of any type (an equal inline object is the same image), or\n * for an element slot another component type or `key`.\n */\n image?: Slot<'img'>;\n /**\n * Badge shown at the bottom end corner, e.g. `<PresenceBadge status=\"busy\" />`. With a badge\n * the avatar is wrapped in an outer `<span>` that receives `ref`, `className` and the other\n * props; `role`, `aria-label`, `aria-labelledby`, `aria-describedby`, `aria-description` and\n * `aria-details` stay on the avatar visual, so the badge keeps its own accessible name. A falsy\n * value (`null`, `false`, `''`, `0`, `NaN`, e.g. `badge={count && <CounterBadge count={count} />}`)\n * counts as no badge, as in 0.4, and so does an array, `Set` or generator whose items render\n * nothing: the avatar then renders without the wrapper.\n */\n badge?: Slot<'span'>;\n /**\n * Hides the avatar visual from assistive technology (`aria-hidden`, empty image `alt`, no\n * `role=\"img\"`). Use it when the name is already shown next to the avatar (Persona). A badge\n * stays exposed.\n * @default false\n */\n decorative?: boolean;\n /** Ref to the root `<span>`: the avatar itself, or the badge wrapper when `badge` is set. */\n ref?: React.Ref<HTMLSpanElement>;\n}\n\n/**\n * Width, height and text size classes of the avatar per `size`. Module-only (not in the barrel):\n * AvatarGroup sizes its overflow button with the same classes, so the two always match.\n */\nexport const avatarSizeClasses: Readonly<Record<Size, string>> = {\n 'extra-small': 'w-6 h-6 text-[10px]', // 24px\n small: 'w-8 h-8 text-xs', // 32px\n medium: 'w-10 h-10 text-sm', // 40px\n large: 'w-12 h-12 text-base', // 48px\n 'extra-large': 'w-14 h-14 text-lg', // 56px\n};\n\nconst IMAGE_CLASS = 'w-full h-full object-cover';\n\n/** First letter of the first and last word, upper-cased; `''` for a blank name. */\nfunction getInitials(name: string): string {\n const parts = name.trim().split(/\\s+/).filter(Boolean);\n if (parts.length === 0) return '';\n const first = Array.from(parts[0]!)[0] ?? '';\n const last = parts.length > 1 ? (Array.from(parts[parts.length - 1]!)[0] ?? '') : '';\n return (first + last).toUpperCase();\n}\n\n/** A name with its whitespace collapsed, or `undefined` when it is blank. */\nfunction normaliseName(name: string | undefined): string | undefined {\n return name?.trim().replace(/\\s+/g, ' ') || undefined;\n}\n\ntype ImageErrorHandler = React.ReactEventHandler<HTMLImageElement>;\n\n/** Description props that go to the element carrying the avatar's name (data-display#19). */\ntype DescriptionProps = Pick<\n React.HTMLAttributes<HTMLElement>,\n 'aria-describedby' | 'aria-description' | 'aria-details'\n>;\n\n/** Props the avatar sets on an element or object image slot, over the slot's own. */\ninterface SlotOverrides {\n onError: ImageErrorHandler;\n alt?: string;\n 'aria-describedby'?: string;\n}\n\n/** The props of an element or object image slot that the avatar reads. */\ninterface ImageSlotProps {\n src?: unknown;\n srcSet?: unknown;\n alt?: unknown;\n onError?: unknown;\n 'aria-describedby'?: unknown;\n}\n\n/** The props of an element or object image slot (to read its `src`, `alt` and handlers). */\nfunction readSlotProps(slot: unknown): ImageSlotProps | undefined {\n if (React.isValidElement(slot)) return slot.props as ImageSlotProps;\n if (typeof slot === 'object' && slot !== null && !(Symbol.iterator in slot)) {\n return slot as ImageSlotProps;\n }\n return undefined;\n}\n\n/**\n * What identifies the image, so a load failure is kept for it and a new image is tried again\n * (data-display#4): the `src` and `srcSet`, of any type (a framework image component may take a\n * static-import object), and for an element slot also its type and `key`.\n */\ntype ImageKey = readonly [type: unknown, key: unknown, src: unknown, srcSet: unknown];\n\nfunction getImageKey(\n imageSlot: unknown,\n slotProps: ImageSlotProps | undefined,\n src: string | undefined,\n): ImageKey {\n if (imageSlot === undefined) return [undefined, undefined, src || undefined, undefined];\n if (typeof imageSlot === 'string') return [undefined, undefined, imageSlot, undefined];\n const element = React.isValidElement(imageSlot) ? imageSlot : undefined;\n return [element?.type, element?.key, slotProps?.src, slotProps?.srcSet];\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== 'object' || value === null) return false;\n const proto: unknown = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\n/** Same value, or plain objects with the same entries (an inline `src={{ … }}` on each render). */\nfunction sameKeyPart(a: unknown, b: unknown): boolean {\n if (Object.is(a, b)) return true;\n if (!isPlainObject(a) || !isPlainObject(b)) return false;\n const keys = Object.keys(a);\n return (\n keys.length === Object.keys(b).length &&\n keys.every((k) => Object.prototype.hasOwnProperty.call(b, k) && Object.is(a[k], b[k]))\n );\n}\n\nfunction sameImageKey(a: ImageKey, b: ImageKey): boolean {\n return a.every((part, i) => sameKeyPart(part, b[i]));\n}\n\n/**\n * A circular picture of a person: their image, an icon, or the initials of their `name`.\n *\n * - **Image**: `image` (URL string, element or `{ src, alt }` object) or `src`. If the image fails\n * to load, the avatar falls back to `icon`, the initials or a person glyph, with their\n * background; a new image is tried again. A server-rendered image that failed before hydration\n * is detected after mount (settled without a natural size, confirmed by `decode()`).\n * - **Accessible name**: an image uses `name` (whitespace collapsed) as its `alt`, or `''` when the\n * name is blank. Without an image (none given, or it failed to load) the avatar is `role=\"img\"`\n * with `aria-label={name}` (without a name: the image slot's own `alt`) and the initials/icon\n * are hidden; without either (and without `aria-label`/`aria-labelledby`) it is decorative\n * (`aria-hidden`). A consumer `aria-label`, `aria-labelledby` or `role` (other than\n * `presentation`/`none`) puts the name on the avatar visual, and an image inside it gets\n * `alt=\"\"`. `decorative` hides it in every mode. `aria-describedby`, `aria-description` and\n * `aria-details` go to the element that carries the name: the `<img>` when a non-blank `alt`\n * names it, otherwise the avatar visual (never an `alt=\"\"` image).\n * - **Badge**: `badge` renders at the bottom end corner (logical, RTL-safe) as a sibling of the\n * avatar visual, so a `PresenceBadge` keeps its own name. With a badge, `ref`, `className` and\n * the rest props go to the outer wrapper.\n *\n * @example\n * <Avatar name=\"Jane Doe\" src=\"/jane.jpg\" badge={<PresenceBadge status=\"available\" />} />\n */\nexport const Avatar = ({\n src,\n name,\n size = 'medium',\n icon,\n image,\n badge,\n decorative = false,\n className,\n ref,\n role,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n 'aria-description': ariaDescription,\n 'aria-details': ariaDetails,\n ...rest\n}: AvatarProps) => {\n const imageSlot =\n image === null || image === undefined || typeof image === 'boolean' || image === ''\n ? undefined\n : image;\n const slotProps = readSlotProps(imageSlot);\n const imageKey = getImageKey(imageSlot, slotProps, src);\n\n // Load failure of the current image; a new image is tried again (C-HOOKS: adjust state during\n // render on prop change).\n const [failed, setFailed] = React.useState(false);\n const [prevImageKey, setPrevImageKey] = React.useState(imageKey);\n if (!sameImageKey(prevImageKey, imageKey)) {\n setPrevImageKey(imageKey);\n setFailed(false);\n }\n\n // An image that failed before hydration (a fast 404 of server-rendered markup) never reaches\n // `onError`: React attaches the listener while hydrating and does not replay the event. After\n // mount, a settled image without a natural size is broken, unless it is an SVG without one, so\n // `decode()` (which rejects for a broken image) confirms it where the browser supports it. Later\n // images, rendered by the client, report their errors through `onError`.\n const visualRef = React.useRef<HTMLSpanElement>(null);\n React.useLayoutEffect(() => {\n const img = visualRef.current?.querySelector('img');\n if (!img || !img.complete || img.naturalWidth !== 0) return;\n let active = true;\n const checkedSrc = img.getAttribute('src');\n const checkedSrcSet = img.getAttribute('srcset');\n const markFailed = () => {\n // Deferred (C-HOOKS); skipped if the image was replaced or got another source meanwhile.\n if (\n active &&\n img.isConnected &&\n img.getAttribute('src') === checkedSrc &&\n img.getAttribute('srcset') === checkedSrcSet\n ) {\n setFailed(true);\n }\n };\n if (typeof img.decode === 'function') img.decode().then(undefined, markFailed);\n else queueMicrotask(markFailed);\n return () => {\n active = false;\n };\n }, []);\n const rootVisualRef = useMergedRefs(ref, visualRef);\n\n const hasConsumerName = ariaLabel !== undefined || ariaLabelledBy !== undefined;\n // A consumer role goes to the visual span together with the name (data-display#19), so the\n // image inside it is presentational (`alt=\"\"`), as with a consumer `aria-label`: the children\n // of `role=\"img\"` are not exposed. A presentational role (`presentation`, `none`) cannot carry\n // a name, so the image keeps it.\n const roleCarriesName = role !== undefined && role !== 'presentation' && role !== 'none';\n const normalisedName = normaliseName(name);\n const imageAlt = decorative || hasConsumerName || roleCarriesName ? '' : (normalisedName ?? '');\n const handleError: ImageErrorHandler = () => setFailed(true);\n\n // The alt text the image renders with: an element or object slot's own `alt` wins over ours. An\n // `alt` that is `undefined` (an optional `alt: user.photoAlt`, a wrapper forwarding `alt={alt}`)\n // or `null` is not given, so ours applies (the slot's own value would otherwise override it).\n const ownAlt = slotProps?.alt;\n const hasOwnAlt = ownAlt !== undefined && ownAlt !== null;\n const renderedAlt: unknown = hasOwnAlt ? ownAlt : imageAlt;\n\n // The description goes to the element that carries the name: the image itself when a non-blank\n // `alt` names it (the visual span then has no role, or a presentational one), otherwise the\n // visual span. An image with an empty `alt` is presentational, and a description on it would\n // conflict with that role.\n const description: DescriptionProps = {\n 'aria-describedby': ariaDescribedBy,\n 'aria-description': ariaDescription,\n 'aria-details': ariaDetails,\n };\n const imageIsNamed =\n !decorative &&\n !hasConsumerName &&\n !roleCarriesName &&\n typeof renderedAlt === 'string' &&\n renderedAlt.trim() !== '';\n const imageDescription: DescriptionProps = imageIsNamed ? description : {};\n\n let imageNode: React.ReactNode = null;\n if (!failed) {\n if (typeof imageSlot === 'string') {\n imageNode = (\n <img\n src={imageSlot}\n alt={imageAlt}\n {...imageDescription}\n className={IMAGE_CLASS}\n onError={handleError}\n />\n );\n } else if (imageSlot !== undefined) {\n // The slot's own props win over renderSlot's defaults, so the composed `onError`, the\n // default `alt` (when the slot gives none) and the joined `aria-describedby` (the avatar's\n // ids, then the slot's) are set on the slot itself. A slot's own `aria-description` and\n // `aria-details` win over the avatar's.\n const overrides: SlotOverrides = {\n onError: composeEventHandlers(\n slotProps?.onError as ImageErrorHandler | undefined,\n handleError,\n ),\n };\n if (!hasOwnAlt) overrides.alt = imageAlt;\n if (imageIsNamed) {\n const ownIds = slotProps?.['aria-describedby'];\n overrides['aria-describedby'] = joinIds(\n ariaDescribedBy,\n typeof ownIds === 'string' ? ownIds : undefined,\n );\n }\n const slot = React.isValidElement(imageSlot)\n ? React.cloneElement(imageSlot as React.ReactElement<SlotOverrides>, overrides)\n : slotProps\n ? { ...(imageSlot as object), ...overrides }\n : imageSlot;\n imageNode = renderSlot(slot as Slot<'img'>, 'img', IMAGE_CLASS, {\n alt: imageAlt,\n ...imageDescription,\n });\n } else if (src) {\n imageNode = (\n <img\n src={src}\n alt={imageAlt}\n {...imageDescription}\n className={IMAGE_CLASS}\n onError={handleError}\n />\n );\n }\n }\n const visualDescription = imageNode !== null && imageIsNamed ? {} : description;\n\n // A falsy icon (`icon={count && <Icon />}` with count 0) is no icon, as in 0.4, and so is a\n // collection whose items render nothing (`icon={items.map(…)}` mapping to nothing). The check\n // does not consume a generator: renderSlot still renders its items.\n const iconNode =\n imageNode === null && icon && slotRendersContent(icon)\n ? renderSlot(icon, 'span', 'inline-flex', { 'aria-hidden': true })\n : null;\n const initials = imageNode === null && iconNode === null && name ? getInitials(name) : '';\n\n let content: React.ReactNode;\n let colorClass: string | undefined;\n if (imageNode !== null) {\n content = imageNode;\n } else if (iconNode !== null) {\n content = iconNode;\n colorClass = 'bg-muted text-muted-foreground';\n } else if (initials) {\n content = <span aria-hidden=\"true\">{initials}</span>;\n colorClass = 'bg-primary text-primary-foreground';\n } else {\n content = <PersonIcon size=\"60%\" />;\n colorClass = 'bg-muted text-muted-foreground';\n }\n\n // Accessible name of the avatar visual (data-display#19, #27). With a consumer role and an\n // image it is the name the image would carry: an element or object slot's own alt, else `name`.\n // Without an image (none given, or it failed to load) it is `name`, else the slot's own alt: an\n // avatar named only by its image alt keeps that name when the image fails.\n const imageName =\n imageNode !== null && roleCarriesName && typeof renderedAlt === 'string'\n ? normaliseName(renderedAlt)\n : undefined;\n const slotAltName = typeof ownAlt === 'string' ? normaliseName(ownAlt) : undefined;\n const label =\n ariaLabel ??\n (imageNode === null\n ? (normalisedName ?? slotAltName)\n : roleCarriesName\n ? (imageName ?? normalisedName)\n : undefined);\n let a11yProps: React.HTMLAttributes<HTMLSpanElement>;\n if (decorative) {\n a11yProps = { 'aria-hidden': true, ...visualDescription };\n } else if (label !== undefined || ariaLabelledBy !== undefined) {\n a11yProps = {\n role: role ?? 'img',\n 'aria-label': label,\n 'aria-labelledby': ariaLabelledBy,\n ...visualDescription,\n };\n } else if (imageNode !== null || role !== undefined) {\n a11yProps = { role, ...visualDescription };\n } else {\n a11yProps = { 'aria-hidden': true, ...visualDescription };\n }\n\n // A falsy or empty badge (`badge={count && <CounterBadge … />}` with count 0) is no badge, as in\n // 0.4 and like `icon`: no stray \"0\" in the corner, and no wrapper taking the root props.\n const badgeNode =\n badge && slotRendersContent(badge)\n ? renderSlot(badge, 'span', 'absolute bottom-0 end-0 inline-flex')\n : null;\n const hasBadge = badgeNode !== null;\n\n const visualClassName = cn(\n 'inline-flex items-center justify-center rounded-full overflow-hidden shrink-0 font-bold',\n avatarSizeClasses[size],\n colorClass,\n );\n\n if (!hasBadge) {\n return (\n <span ref={rootVisualRef} {...a11yProps} {...rest} className={cn(visualClassName, className)}>\n {content}\n </span>\n );\n }\n\n return (\n <span ref={ref} {...rest} className={cn('relative inline-flex shrink-0', className)}>\n <span ref={visualRef} {...a11yProps} className={visualClassName}>\n {content}\n </span>\n {badgeNode}\n </span>\n );\n};\n\nAvatar.displayName = 'Avatar';\n"],"mappings":"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"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn as e } from "../../lib/cn.mjs";
|
|
3
|
+
import { renderSlot as t, slotRendersContent as n } from "../../lib/slot.mjs";
|
|
4
|
+
import { composeEventHandlers as r } from "../../lib/composeEventHandlers.mjs";
|
|
5
|
+
import { useMergedRefs as i } from "../../hooks/useMergedRefs.mjs";
|
|
6
|
+
import { joinIds as ee } from "../../lib/aria.mjs";
|
|
7
|
+
import { PersonIcon as te } from "../../lib/icons.mjs";
|
|
8
|
+
import * as a from "react";
|
|
9
|
+
import { jsx as o, jsxs as ne } from "react/jsx-runtime";
|
|
10
|
+
//#region src/components/data-display/Avatar.tsx
|
|
11
|
+
var s = {
|
|
12
|
+
"extra-small": "w-6 h-6 text-[10px]",
|
|
13
|
+
small: "w-8 h-8 text-xs",
|
|
14
|
+
medium: "w-10 h-10 text-sm",
|
|
15
|
+
large: "w-12 h-12 text-base",
|
|
16
|
+
"extra-large": "w-14 h-14 text-lg"
|
|
17
|
+
}, c = "w-full h-full object-cover";
|
|
18
|
+
function re(e) {
|
|
19
|
+
let t = e.trim().split(/\s+/).filter(Boolean);
|
|
20
|
+
return t.length === 0 ? "" : ((Array.from(t[0])[0] ?? "") + (t.length > 1 ? Array.from(t[t.length - 1])[0] ?? "" : "")).toUpperCase();
|
|
21
|
+
}
|
|
22
|
+
function l(e) {
|
|
23
|
+
return e?.trim().replace(/\s+/g, " ") || void 0;
|
|
24
|
+
}
|
|
25
|
+
function u(e) {
|
|
26
|
+
if (a.isValidElement(e)) return e.props;
|
|
27
|
+
if (typeof e == "object" && e && !(Symbol.iterator in e)) return e;
|
|
28
|
+
}
|
|
29
|
+
function ie(e, t, n) {
|
|
30
|
+
if (e === void 0) return [
|
|
31
|
+
void 0,
|
|
32
|
+
void 0,
|
|
33
|
+
n || void 0,
|
|
34
|
+
void 0
|
|
35
|
+
];
|
|
36
|
+
if (typeof e == "string") return [
|
|
37
|
+
void 0,
|
|
38
|
+
void 0,
|
|
39
|
+
e,
|
|
40
|
+
void 0
|
|
41
|
+
];
|
|
42
|
+
let r = a.isValidElement(e) ? e : void 0;
|
|
43
|
+
return [
|
|
44
|
+
r?.type,
|
|
45
|
+
r?.key,
|
|
46
|
+
t?.src,
|
|
47
|
+
t?.srcSet
|
|
48
|
+
];
|
|
49
|
+
}
|
|
50
|
+
function d(e) {
|
|
51
|
+
if (typeof e != "object" || !e) return !1;
|
|
52
|
+
let t = Object.getPrototypeOf(e);
|
|
53
|
+
return t === Object.prototype || t === null;
|
|
54
|
+
}
|
|
55
|
+
function f(e, t) {
|
|
56
|
+
if (Object.is(e, t)) return !0;
|
|
57
|
+
if (!d(e) || !d(t)) return !1;
|
|
58
|
+
let n = Object.keys(e);
|
|
59
|
+
return n.length === Object.keys(t).length && n.every((n) => Object.prototype.hasOwnProperty.call(t, n) && Object.is(e[n], t[n]));
|
|
60
|
+
}
|
|
61
|
+
function ae(e, t) {
|
|
62
|
+
return e.every((e, n) => f(e, t[n]));
|
|
63
|
+
}
|
|
64
|
+
var p = ({ src: d, name: f, size: p = "medium", icon: m, image: h, badge: g, decorative: _ = !1, className: v, ref: y, role: b, "aria-label": x, "aria-labelledby": S, "aria-describedby": C, "aria-description": oe, "aria-details": se, ...w }) => {
|
|
65
|
+
let T = h == null || typeof h == "boolean" || h === "" ? void 0 : h, E = u(T), D = ie(T, E, d), [ce, O] = a.useState(!1), [k, A] = a.useState(D);
|
|
66
|
+
ae(k, D) || (A(D), O(!1));
|
|
67
|
+
let j = a.useRef(null);
|
|
68
|
+
a.useLayoutEffect(() => {
|
|
69
|
+
let e = j.current?.querySelector("img");
|
|
70
|
+
if (!e || !e.complete || e.naturalWidth !== 0) return;
|
|
71
|
+
let t = !0, n = e.getAttribute("src"), r = e.getAttribute("srcset"), i = () => {
|
|
72
|
+
t && e.isConnected && e.getAttribute("src") === n && e.getAttribute("srcset") === r && O(!0);
|
|
73
|
+
};
|
|
74
|
+
return typeof e.decode == "function" ? e.decode().then(void 0, i) : queueMicrotask(i), () => {
|
|
75
|
+
t = !1;
|
|
76
|
+
};
|
|
77
|
+
}, []);
|
|
78
|
+
let M = i(y, j), N = x !== void 0 || S !== void 0, P = b !== void 0 && b !== "presentation" && b !== "none", F = l(f), I = _ || N || P ? "" : F ?? "", L = () => O(!0), R = E?.alt, z = R != null, B = z ? R : I, V = {
|
|
79
|
+
"aria-describedby": C,
|
|
80
|
+
"aria-description": oe,
|
|
81
|
+
"aria-details": se
|
|
82
|
+
}, H = !_ && !N && !P && typeof B == "string" && B.trim() !== "", U = H ? V : {}, W = null;
|
|
83
|
+
if (!ce) {
|
|
84
|
+
if (typeof T == "string") W = /* @__PURE__ */ o("img", {
|
|
85
|
+
src: T,
|
|
86
|
+
alt: I,
|
|
87
|
+
...U,
|
|
88
|
+
className: c,
|
|
89
|
+
onError: L
|
|
90
|
+
});
|
|
91
|
+
else if (T !== void 0) {
|
|
92
|
+
let e = { onError: r(E?.onError, L) };
|
|
93
|
+
if (z || (e.alt = I), H) {
|
|
94
|
+
let t = E?.["aria-describedby"];
|
|
95
|
+
e["aria-describedby"] = ee(C, typeof t == "string" ? t : void 0);
|
|
96
|
+
}
|
|
97
|
+
let n = a.isValidElement(T) ? a.cloneElement(T, e) : E ? {
|
|
98
|
+
...T,
|
|
99
|
+
...e
|
|
100
|
+
} : T;
|
|
101
|
+
W = t(n, "img", c, {
|
|
102
|
+
alt: I,
|
|
103
|
+
...U
|
|
104
|
+
});
|
|
105
|
+
} else d && (W = /* @__PURE__ */ o("img", {
|
|
106
|
+
src: d,
|
|
107
|
+
alt: I,
|
|
108
|
+
...U,
|
|
109
|
+
className: c,
|
|
110
|
+
onError: L
|
|
111
|
+
}));
|
|
112
|
+
}
|
|
113
|
+
let G = W !== null && H ? {} : V, K = W === null && m && n(m) ? t(m, "span", "inline-flex", { "aria-hidden": !0 }) : null, q = W === null && K === null && f ? re(f) : "", J, Y;
|
|
114
|
+
W === null ? K === null ? q ? (J = /* @__PURE__ */ o("span", {
|
|
115
|
+
"aria-hidden": "true",
|
|
116
|
+
children: q
|
|
117
|
+
}), Y = "bg-primary text-primary-foreground") : (J = /* @__PURE__ */ o(te, { size: "60%" }), Y = "bg-muted text-muted-foreground") : (J = K, Y = "bg-muted text-muted-foreground") : J = W;
|
|
118
|
+
let le = W !== null && P && typeof B == "string" ? l(B) : void 0, ue = typeof R == "string" ? l(R) : void 0, X = x ?? (W === null ? F ?? ue : P ? le ?? F : void 0), Z;
|
|
119
|
+
Z = _ ? {
|
|
120
|
+
"aria-hidden": !0,
|
|
121
|
+
...G
|
|
122
|
+
} : X !== void 0 || S !== void 0 ? {
|
|
123
|
+
role: b ?? "img",
|
|
124
|
+
"aria-label": X,
|
|
125
|
+
"aria-labelledby": S,
|
|
126
|
+
...G
|
|
127
|
+
} : W !== null || b !== void 0 ? {
|
|
128
|
+
role: b,
|
|
129
|
+
...G
|
|
130
|
+
} : {
|
|
131
|
+
"aria-hidden": !0,
|
|
132
|
+
...G
|
|
133
|
+
};
|
|
134
|
+
let Q = g && n(g) ? t(g, "span", "absolute bottom-0 end-0 inline-flex") : null, de = Q !== null, $ = e("inline-flex items-center justify-center rounded-full overflow-hidden shrink-0 font-bold", s[p], Y);
|
|
135
|
+
return de ? /* @__PURE__ */ ne("span", {
|
|
136
|
+
ref: y,
|
|
137
|
+
...w,
|
|
138
|
+
className: e("relative inline-flex shrink-0", v),
|
|
139
|
+
children: [/* @__PURE__ */ o("span", {
|
|
140
|
+
ref: j,
|
|
141
|
+
...Z,
|
|
142
|
+
className: $,
|
|
143
|
+
children: J
|
|
144
|
+
}), Q]
|
|
145
|
+
}) : /* @__PURE__ */ o("span", {
|
|
146
|
+
ref: M,
|
|
147
|
+
...Z,
|
|
148
|
+
...w,
|
|
149
|
+
className: e($, v),
|
|
150
|
+
children: J
|
|
151
|
+
});
|
|
152
|
+
};
|
|
153
|
+
p.displayName = "Avatar";
|
|
154
|
+
//#endregion
|
|
155
|
+
export { p as Avatar, s as avatarSizeClasses };
|
|
156
|
+
|
|
157
|
+
//# sourceMappingURL=Avatar.mjs.map
|