@mortenbrudvik/waveui 0.7.0 → 0.9.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 +564 -155
- package/dist/components/button/Button.cjs +1 -1
- package/dist/components/button/Button.cjs.map +1 -1
- package/dist/components/button/Button.mjs +36 -35
- package/dist/components/button/Button.mjs.map +1 -1
- package/dist/components/button/Button.slots.cjs +1 -1
- package/dist/components/button/Button.slots.cjs.map +1 -1
- package/dist/components/button/Button.slots.mjs +31 -21
- package/dist/components/button/Button.slots.mjs.map +1 -1
- package/dist/components/button/CompoundButton.cjs +1 -1
- package/dist/components/button/CompoundButton.cjs.map +1 -1
- package/dist/components/button/CompoundButton.mjs +31 -29
- package/dist/components/button/CompoundButton.mjs.map +1 -1
- package/dist/components/button/Link.cjs +1 -1
- package/dist/components/button/Link.cjs.map +1 -1
- package/dist/components/button/Link.mjs +24 -23
- package/dist/components/button/Link.mjs.map +1 -1
- package/dist/components/button/MenuButton.cjs +1 -1
- package/dist/components/button/MenuButton.cjs.map +1 -1
- package/dist/components/button/MenuButton.mjs +29 -28
- package/dist/components/button/MenuButton.mjs.map +1 -1
- package/dist/components/button/SplitButton.cjs +1 -1
- package/dist/components/button/SplitButton.cjs.map +1 -1
- package/dist/components/button/SplitButton.mjs +46 -45
- package/dist/components/button/SplitButton.mjs.map +1 -1
- package/dist/components/button/ToggleButton.cjs +1 -1
- package/dist/components/button/ToggleButton.cjs.map +1 -1
- package/dist/components/button/ToggleButton.mjs +38 -35
- package/dist/components/button/ToggleButton.mjs.map +1 -1
- package/dist/components/button/Toolbar.cjs +1 -1
- package/dist/components/button/Toolbar.cjs.map +1 -1
- package/dist/components/button/Toolbar.mjs +43 -42
- package/dist/components/button/Toolbar.mjs.map +1 -1
- package/dist/components/button/Toolbar.parts.cjs +1 -1
- package/dist/components/button/Toolbar.parts.cjs.map +1 -1
- package/dist/components/button/Toolbar.parts.mjs +76 -81
- package/dist/components/button/Toolbar.parts.mjs.map +1 -1
- package/dist/components/data-display/Avatar.cjs +1 -1
- package/dist/components/data-display/Avatar.cjs.map +1 -1
- package/dist/components/data-display/Avatar.mjs +72 -67
- package/dist/components/data-display/Avatar.mjs.map +1 -1
- package/dist/components/data-display/AvatarGroup.cjs +1 -1
- package/dist/components/data-display/AvatarGroup.cjs.map +1 -1
- package/dist/components/data-display/AvatarGroup.mjs +89 -88
- package/dist/components/data-display/AvatarGroup.mjs.map +1 -1
- package/dist/components/data-display/Badge.cjs +1 -1
- package/dist/components/data-display/Badge.cjs.map +1 -1
- package/dist/components/data-display/Badge.mjs +17 -16
- package/dist/components/data-display/Badge.mjs.map +1 -1
- package/dist/components/data-display/CounterBadge.cjs +1 -1
- package/dist/components/data-display/CounterBadge.cjs.map +1 -1
- package/dist/components/data-display/CounterBadge.mjs +18 -17
- package/dist/components/data-display/CounterBadge.mjs.map +1 -1
- package/dist/components/data-display/Divider.cjs +1 -1
- package/dist/components/data-display/Divider.cjs.map +1 -1
- package/dist/components/data-display/Divider.mjs +31 -30
- package/dist/components/data-display/Divider.mjs.map +1 -1
- package/dist/components/data-display/Image.cjs +1 -1
- package/dist/components/data-display/Image.cjs.map +1 -1
- package/dist/components/data-display/Image.mjs +16 -15
- package/dist/components/data-display/Image.mjs.map +1 -1
- package/dist/components/data-display/InfoButton.cjs +2 -0
- package/dist/components/data-display/InfoButton.cjs.map +1 -0
- package/dist/components/data-display/InfoButton.mjs +173 -0
- package/dist/components/data-display/InfoButton.mjs.map +1 -0
- package/dist/components/data-display/InfoLabel.cjs +1 -1
- package/dist/components/data-display/InfoLabel.cjs.map +1 -1
- package/dist/components/data-display/InfoLabel.mjs +36 -92
- package/dist/components/data-display/InfoLabel.mjs.map +1 -1
- package/dist/components/data-display/List.cjs +1 -1
- package/dist/components/data-display/List.cjs.map +1 -1
- package/dist/components/data-display/List.mjs +175 -174
- package/dist/components/data-display/List.mjs.map +1 -1
- package/dist/components/data-display/Persona.cjs +1 -1
- package/dist/components/data-display/Persona.cjs.map +1 -1
- package/dist/components/data-display/Persona.mjs +31 -29
- package/dist/components/data-display/Persona.mjs.map +1 -1
- package/dist/components/data-display/PresenceBadge.cjs +1 -1
- package/dist/components/data-display/PresenceBadge.cjs.map +1 -1
- package/dist/components/data-display/PresenceBadge.mjs +25 -24
- package/dist/components/data-display/PresenceBadge.mjs.map +1 -1
- package/dist/components/data-display/Tag.cjs +1 -1
- package/dist/components/data-display/Tag.cjs.map +1 -1
- package/dist/components/data-display/Tag.mjs +87 -82
- package/dist/components/data-display/Tag.mjs.map +1 -1
- package/dist/components/feedback/MessageBar.cjs +1 -1
- package/dist/components/feedback/MessageBar.cjs.map +1 -1
- package/dist/components/feedback/MessageBar.mjs +129 -71
- package/dist/components/feedback/MessageBar.mjs.map +1 -1
- package/dist/components/feedback/MessageBar.parts.cjs +2 -0
- package/dist/components/feedback/MessageBar.parts.cjs.map +1 -0
- package/dist/components/feedback/MessageBar.parts.mjs +84 -0
- package/dist/components/feedback/MessageBar.parts.mjs.map +1 -0
- package/dist/components/feedback/MessageBar.reflow.cjs +2 -0
- package/dist/components/feedback/MessageBar.reflow.cjs.map +1 -0
- package/dist/components/feedback/MessageBar.reflow.mjs +74 -0
- package/dist/components/feedback/MessageBar.reflow.mjs.map +1 -0
- package/dist/components/feedback/MessageBar.status.cjs +1 -1
- package/dist/components/feedback/MessageBar.status.cjs.map +1 -1
- package/dist/components/feedback/MessageBar.status.mjs +2 -1
- package/dist/components/feedback/MessageBar.status.mjs.map +1 -1
- package/dist/components/feedback/ProgressBar.cjs +1 -1
- package/dist/components/feedback/ProgressBar.cjs.map +1 -1
- package/dist/components/feedback/ProgressBar.mjs +44 -43
- package/dist/components/feedback/ProgressBar.mjs.map +1 -1
- package/dist/components/feedback/Skeleton.cjs +1 -1
- package/dist/components/feedback/Skeleton.cjs.map +1 -1
- package/dist/components/feedback/Skeleton.mjs +26 -24
- package/dist/components/feedback/Skeleton.mjs.map +1 -1
- package/dist/components/feedback/Spinner.cjs +1 -1
- package/dist/components/feedback/Spinner.cjs.map +1 -1
- package/dist/components/feedback/Spinner.mjs +32 -31
- package/dist/components/feedback/Spinner.mjs.map +1 -1
- package/dist/components/feedback/Toast.cjs +1 -1
- package/dist/components/feedback/Toast.cjs.map +1 -1
- package/dist/components/feedback/Toast.context.cjs +2 -0
- package/dist/components/feedback/Toast.context.cjs.map +1 -0
- package/dist/components/feedback/Toast.context.mjs +23 -0
- package/dist/components/feedback/Toast.context.mjs.map +1 -0
- package/dist/components/feedback/Toast.mjs +10 -342
- package/dist/components/feedback/Toast.mjs.map +1 -1
- package/dist/components/feedback/Toast.parts.cjs +2 -0
- package/dist/components/feedback/Toast.parts.cjs.map +1 -0
- package/dist/components/feedback/Toast.parts.mjs +98 -0
- package/dist/components/feedback/Toast.parts.mjs.map +1 -0
- package/dist/components/feedback/Toast.root.cjs +2 -0
- package/dist/components/feedback/Toast.root.cjs.map +1 -0
- package/dist/components/feedback/Toast.root.mjs +109 -0
- package/dist/components/feedback/Toast.root.mjs.map +1 -0
- package/dist/components/feedback/Toaster.cjs +2 -0
- package/dist/components/feedback/Toaster.cjs.map +1 -0
- package/dist/components/feedback/Toaster.mjs +564 -0
- package/dist/components/feedback/Toaster.mjs.map +1 -0
- package/dist/components/input/AlphaSlider.cjs +2 -0
- package/dist/components/input/AlphaSlider.cjs.map +1 -0
- package/dist/components/input/AlphaSlider.mjs +115 -0
- package/dist/components/input/AlphaSlider.mjs.map +1 -0
- package/dist/components/input/Checkbox.cjs +1 -1
- package/dist/components/input/Checkbox.cjs.map +1 -1
- package/dist/components/input/Checkbox.mjs +87 -70
- package/dist/components/input/Checkbox.mjs.map +1 -1
- package/dist/components/input/ColorArea.cjs +2 -0
- package/dist/components/input/ColorArea.cjs.map +1 -0
- package/dist/components/input/ColorArea.mjs +204 -0
- package/dist/components/input/ColorArea.mjs.map +1 -0
- package/dist/components/input/ColorPicker.cjs +5 -5
- package/dist/components/input/ColorPicker.cjs.map +1 -1
- package/dist/components/input/ColorPicker.mjs +142 -165
- package/dist/components/input/ColorPicker.mjs.map +1 -1
- package/dist/components/input/ColorPicker.parts.cjs +2 -0
- package/dist/components/input/ColorPicker.parts.cjs.map +1 -0
- package/dist/components/input/ColorPicker.parts.mjs +192 -0
- package/dist/components/input/ColorPicker.parts.mjs.map +1 -0
- package/dist/components/input/ColorSlider.cjs +2 -0
- package/dist/components/input/ColorSlider.cjs.map +1 -0
- package/dist/components/input/ColorSlider.mjs +138 -0
- package/dist/components/input/ColorSlider.mjs.map +1 -0
- package/dist/components/input/Combobox.cjs +1 -1
- package/dist/components/input/Combobox.cjs.map +1 -1
- package/dist/components/input/Combobox.expand.cjs +1 -1
- package/dist/components/input/Combobox.expand.cjs.map +1 -1
- package/dist/components/input/Combobox.expand.mjs +22 -22
- package/dist/components/input/Combobox.expand.mjs.map +1 -1
- package/dist/components/input/Combobox.mjs +151 -141
- package/dist/components/input/Combobox.mjs.map +1 -1
- package/dist/components/input/DatePicker.cjs +1 -1
- package/dist/components/input/DatePicker.cjs.map +1 -1
- package/dist/components/input/DatePicker.mjs +239 -234
- package/dist/components/input/DatePicker.mjs.map +1 -1
- package/dist/components/input/Dropdown.cjs +1 -1
- package/dist/components/input/Dropdown.cjs.map +1 -1
- package/dist/components/input/Dropdown.mjs +109 -100
- package/dist/components/input/Dropdown.mjs.map +1 -1
- package/dist/components/input/Field.cjs +1 -1
- package/dist/components/input/Field.cjs.map +1 -1
- package/dist/components/input/Field.mjs +139 -105
- package/dist/components/input/Field.mjs.map +1 -1
- package/dist/components/input/Input.cjs +1 -1
- package/dist/components/input/Input.cjs.map +1 -1
- package/dist/components/input/Input.mjs +80 -55
- package/dist/components/input/Input.mjs.map +1 -1
- package/dist/components/input/Label.cjs +1 -1
- package/dist/components/input/Label.cjs.map +1 -1
- package/dist/components/input/Label.mjs +19 -12
- package/dist/components/input/Label.mjs.map +1 -1
- package/dist/components/input/Option.cjs +1 -1
- package/dist/components/input/Option.cjs.map +1 -1
- package/dist/components/input/Option.mjs +100 -98
- package/dist/components/input/Option.mjs.map +1 -1
- package/dist/components/input/RadioGroup.cjs +1 -1
- package/dist/components/input/RadioGroup.cjs.map +1 -1
- package/dist/components/input/RadioGroup.mjs +89 -88
- package/dist/components/input/RadioGroup.mjs.map +1 -1
- package/dist/components/input/Rating.cjs +1 -1
- package/dist/components/input/Rating.cjs.map +1 -1
- package/dist/components/input/Rating.item.cjs +2 -0
- package/dist/components/input/Rating.item.cjs.map +1 -0
- package/dist/components/input/Rating.item.mjs +255 -0
- package/dist/components/input/Rating.item.mjs.map +1 -0
- package/dist/components/input/Rating.mjs +152 -152
- package/dist/components/input/Rating.mjs.map +1 -1
- package/dist/components/input/SearchBox.cjs +1 -1
- package/dist/components/input/SearchBox.cjs.map +1 -1
- package/dist/components/input/SearchBox.mjs +162 -132
- package/dist/components/input/SearchBox.mjs.map +1 -1
- package/dist/components/input/Select.cjs +1 -1
- package/dist/components/input/Select.cjs.map +1 -1
- package/dist/components/input/Select.mjs +34 -24
- package/dist/components/input/Select.mjs.map +1 -1
- package/dist/components/input/Slider.cjs +1 -1
- package/dist/components/input/Slider.cjs.map +1 -1
- package/dist/components/input/Slider.mjs +78 -54
- package/dist/components/input/Slider.mjs.map +1 -1
- package/dist/components/input/SpinButton.cjs +1 -1
- package/dist/components/input/SpinButton.cjs.map +1 -1
- package/dist/components/input/SpinButton.mjs +202 -99
- package/dist/components/input/SpinButton.mjs.map +1 -1
- package/dist/components/input/SwatchPicker.cjs +1 -1
- package/dist/components/input/SwatchPicker.cjs.map +1 -1
- package/dist/components/input/SwatchPicker.mjs +38 -37
- package/dist/components/input/SwatchPicker.mjs.map +1 -1
- package/dist/components/input/Switch.cjs +1 -1
- package/dist/components/input/Switch.cjs.map +1 -1
- package/dist/components/input/Switch.mjs +75 -58
- package/dist/components/input/Switch.mjs.map +1 -1
- package/dist/components/input/TagPicker.cjs +1 -1
- package/dist/components/input/TagPicker.cjs.map +1 -1
- package/dist/components/input/TagPicker.mjs +199 -169
- package/dist/components/input/TagPicker.mjs.map +1 -1
- package/dist/components/input/Textarea.cjs +1 -1
- package/dist/components/input/Textarea.cjs.map +1 -1
- package/dist/components/input/Textarea.mjs +31 -23
- package/dist/components/input/Textarea.mjs.map +1 -1
- package/dist/components/input/TimePicker.cjs +1 -1
- package/dist/components/input/TimePicker.cjs.map +1 -1
- package/dist/components/input/TimePicker.mjs +185 -177
- package/dist/components/input/TimePicker.mjs.map +1 -1
- package/dist/components/input/colorName.cjs +2 -0
- package/dist/components/input/colorName.cjs.map +1 -0
- package/dist/components/input/colorName.mjs +30 -0
- package/dist/components/input/colorName.mjs.map +1 -0
- package/dist/components/input/colorUtils.cjs +1 -1
- package/dist/components/input/colorUtils.cjs.map +1 -1
- package/dist/components/input/colorUtils.mjs +154 -56
- package/dist/components/input/colorUtils.mjs.map +1 -1
- package/dist/components/input/fieldLabel.cjs +2 -0
- package/dist/components/input/fieldLabel.cjs.map +1 -0
- package/dist/components/input/fieldLabel.mjs +17 -0
- package/dist/components/input/fieldLabel.mjs.map +1 -0
- package/dist/components/input/inputLook.cjs +2 -0
- package/dist/components/input/inputLook.cjs.map +1 -0
- package/dist/components/input/inputLook.mjs +28 -0
- package/dist/components/input/inputLook.mjs.map +1 -0
- package/dist/components/input/pickerStyles.cjs +1 -1
- package/dist/components/input/pickerStyles.cjs.map +1 -1
- package/dist/components/input/pickerStyles.mjs +42 -4
- package/dist/components/input/pickerStyles.mjs.map +1 -1
- package/dist/components/layout/Accordion.cjs +1 -1
- package/dist/components/layout/Accordion.cjs.map +1 -1
- package/dist/components/layout/Accordion.mjs +130 -129
- package/dist/components/layout/Accordion.mjs.map +1 -1
- package/dist/components/layout/Card.cjs +1 -1
- package/dist/components/layout/Card.cjs.map +1 -1
- package/dist/components/layout/Card.mjs +78 -77
- package/dist/components/layout/Card.mjs.map +1 -1
- package/dist/components/layout/Carousel.cjs +1 -1
- package/dist/components/layout/Carousel.cjs.map +1 -1
- package/dist/components/layout/Carousel.mjs +111 -110
- package/dist/components/layout/Carousel.mjs.map +1 -1
- package/dist/components/layout/Flex.cjs +1 -1
- package/dist/components/layout/Flex.cjs.map +1 -1
- package/dist/components/layout/Flex.mjs +22 -21
- package/dist/components/layout/Flex.mjs.map +1 -1
- package/dist/components/layout/Grid.cjs +1 -1
- package/dist/components/layout/Grid.cjs.map +1 -1
- package/dist/components/layout/Grid.mjs +19 -18
- package/dist/components/layout/Grid.mjs.map +1 -1
- package/dist/components/layout/Overflow.cjs +1 -1
- package/dist/components/layout/Overflow.cjs.map +1 -1
- package/dist/components/layout/Overflow.mjs +92 -91
- package/dist/components/layout/Overflow.mjs.map +1 -1
- package/dist/components/layout/Stack.cjs +1 -1
- package/dist/components/layout/Stack.cjs.map +1 -1
- package/dist/components/layout/Stack.mjs +14 -13
- package/dist/components/layout/Stack.mjs.map +1 -1
- package/dist/components/layout/TabList.cjs +1 -1
- package/dist/components/layout/TabList.cjs.map +1 -1
- package/dist/components/layout/TabList.mjs +118 -117
- package/dist/components/layout/TabList.mjs.map +1 -1
- package/dist/components/layout/Tree.cjs +1 -1
- package/dist/components/layout/Tree.cjs.map +1 -1
- package/dist/components/layout/Tree.context.cjs +2 -0
- package/dist/components/layout/Tree.context.cjs.map +1 -0
- package/dist/components/layout/Tree.context.mjs +33 -0
- package/dist/components/layout/Tree.context.mjs.map +1 -0
- package/dist/components/layout/Tree.core.cjs +2 -0
- package/dist/components/layout/Tree.core.cjs.map +1 -0
- package/dist/components/layout/Tree.core.mjs +416 -0
- package/dist/components/layout/Tree.core.mjs.map +1 -0
- package/dist/components/layout/Tree.itemPersonaLayout.cjs +2 -0
- package/dist/components/layout/Tree.itemPersonaLayout.cjs.map +1 -0
- package/dist/components/layout/Tree.itemPersonaLayout.mjs +46 -0
- package/dist/components/layout/Tree.itemPersonaLayout.mjs.map +1 -0
- package/dist/components/layout/Tree.mjs +7 -215
- package/dist/components/layout/Tree.mjs.map +1 -1
- package/dist/components/layout/Tree.selection.cjs +2 -0
- package/dist/components/layout/Tree.selection.cjs.map +1 -0
- package/dist/components/layout/Tree.selection.mjs +73 -0
- package/dist/components/layout/Tree.selection.mjs.map +1 -0
- package/dist/components/navigation/Breadcrumb.cjs +1 -1
- package/dist/components/navigation/Breadcrumb.cjs.map +1 -1
- package/dist/components/navigation/Breadcrumb.mjs +76 -75
- package/dist/components/navigation/Breadcrumb.mjs.map +1 -1
- package/dist/components/navigation/Menu.group.cjs +1 -1
- package/dist/components/navigation/Menu.group.cjs.map +1 -1
- package/dist/components/navigation/Menu.group.mjs +39 -37
- package/dist/components/navigation/Menu.group.mjs.map +1 -1
- package/dist/components/navigation/Menu.items.cjs +1 -1
- package/dist/components/navigation/Menu.items.cjs.map +1 -1
- package/dist/components/navigation/Menu.items.mjs +67 -61
- package/dist/components/navigation/Menu.items.mjs.map +1 -1
- package/dist/components/navigation/Menu.link.cjs +1 -1
- package/dist/components/navigation/Menu.link.cjs.map +1 -1
- package/dist/components/navigation/Menu.link.mjs +34 -28
- package/dist/components/navigation/Menu.link.mjs.map +1 -1
- package/dist/components/navigation/Menu.popover.cjs +1 -1
- package/dist/components/navigation/Menu.popover.cjs.map +1 -1
- package/dist/components/navigation/Menu.popover.mjs +114 -113
- package/dist/components/navigation/Menu.popover.mjs.map +1 -1
- package/dist/components/navigation/Menu.root.cjs +1 -1
- package/dist/components/navigation/Menu.root.cjs.map +1 -1
- package/dist/components/navigation/Menu.root.mjs +171 -170
- package/dist/components/navigation/Menu.root.mjs.map +1 -1
- package/dist/components/navigation/Menu.selectable.cjs +1 -1
- package/dist/components/navigation/Menu.selectable.cjs.map +1 -1
- package/dist/components/navigation/Menu.selectable.mjs +85 -63
- package/dist/components/navigation/Menu.selectable.mjs.map +1 -1
- package/dist/components/navigation/Menu.splitGroup.cjs +1 -1
- package/dist/components/navigation/Menu.splitGroup.cjs.map +1 -1
- package/dist/components/navigation/Menu.splitGroup.mjs +27 -26
- package/dist/components/navigation/Menu.splitGroup.mjs.map +1 -1
- package/dist/components/navigation/Menu.trigger.cjs +1 -1
- package/dist/components/navigation/Menu.trigger.cjs.map +1 -1
- package/dist/components/navigation/Menu.trigger.mjs +6 -6
- package/dist/components/navigation/Nav.cjs +1 -1
- package/dist/components/navigation/Nav.cjs.map +1 -1
- package/dist/components/navigation/Nav.mjs +170 -155
- package/dist/components/navigation/Nav.mjs.map +1 -1
- package/dist/components/navigation/Pagination.cjs +1 -1
- package/dist/components/navigation/Pagination.cjs.map +1 -1
- package/dist/components/navigation/Pagination.mjs +73 -65
- package/dist/components/navigation/Pagination.mjs.map +1 -1
- package/dist/components/navigation/Stepper.cjs +1 -1
- package/dist/components/navigation/Stepper.cjs.map +1 -1
- package/dist/components/navigation/Stepper.mjs +110 -109
- package/dist/components/navigation/Stepper.mjs.map +1 -1
- package/dist/components/overlays/Dialog.cjs +1 -1
- package/dist/components/overlays/Dialog.cjs.map +1 -1
- package/dist/components/overlays/Dialog.mjs +109 -108
- package/dist/components/overlays/Dialog.mjs.map +1 -1
- package/dist/components/overlays/Drawer.cjs +1 -1
- package/dist/components/overlays/Drawer.cjs.map +1 -1
- package/dist/components/overlays/Drawer.mjs +110 -109
- package/dist/components/overlays/Drawer.mjs.map +1 -1
- package/dist/components/overlays/Popover.cjs +1 -1
- package/dist/components/overlays/Popover.cjs.map +1 -1
- package/dist/components/overlays/Popover.mjs +148 -151
- package/dist/components/overlays/Popover.mjs.map +1 -1
- package/dist/components/overlays/Popover.shared.cjs +1 -1
- package/dist/components/overlays/Popover.shared.cjs.map +1 -1
- package/dist/components/overlays/Popover.shared.mjs +82 -77
- package/dist/components/overlays/Popover.shared.mjs.map +1 -1
- package/dist/components/overlays/TeachingPopover.cjs +1 -1
- package/dist/components/overlays/TeachingPopover.cjs.map +1 -1
- package/dist/components/overlays/TeachingPopover.mjs +41 -37
- package/dist/components/overlays/TeachingPopover.mjs.map +1 -1
- package/dist/components/overlays/Tooltip.cjs +1 -1
- package/dist/components/overlays/Tooltip.cjs.map +1 -1
- package/dist/components/overlays/Tooltip.mjs +87 -86
- package/dist/components/overlays/Tooltip.mjs.map +1 -1
- package/dist/components/portal/Portal.cjs +1 -1
- package/dist/components/portal/Portal.cjs.map +1 -1
- package/dist/components/portal/Portal.mjs +33 -32
- package/dist/components/portal/Portal.mjs.map +1 -1
- package/dist/components/provider/WaveProvider.cjs +1 -1
- package/dist/components/provider/WaveProvider.cjs.map +1 -1
- package/dist/components/provider/WaveProvider.mjs +36 -29
- package/dist/components/provider/WaveProvider.mjs.map +1 -1
- package/dist/components/table/DataGrid.cjs +1 -1
- package/dist/components/table/DataGrid.cjs.map +1 -1
- package/dist/components/table/DataGrid.mjs +228 -227
- package/dist/components/table/DataGrid.mjs.map +1 -1
- package/dist/components/table/Table.cjs +1 -1
- package/dist/components/table/Table.cjs.map +1 -1
- package/dist/components/table/Table.mjs +60 -59
- package/dist/components/table/Table.mjs.map +1 -1
- package/dist/components/typography/Text.cjs +1 -1
- package/dist/components/typography/Text.cjs.map +1 -1
- package/dist/components/typography/Text.mjs +12 -11
- package/dist/components/typography/Text.mjs.map +1 -1
- package/dist/hooks/useFieldControl.cjs.map +1 -1
- package/dist/hooks/useFieldControl.mjs.map +1 -1
- package/dist/hooks/useMediaQuery.cjs +2 -0
- package/dist/hooks/useMediaQuery.cjs.map +1 -0
- package/dist/hooks/useMediaQuery.mjs +20 -0
- package/dist/hooks/useMediaQuery.mjs.map +1 -0
- package/dist/hooks/usePrefersReducedMotion.cjs +1 -1
- package/dist/hooks/usePrefersReducedMotion.cjs.map +1 -1
- package/dist/hooks/usePrefersReducedMotion.mjs +4 -18
- package/dist/hooks/usePrefersReducedMotion.mjs.map +1 -1
- package/dist/hooks/useRovingTabIndex.cjs +1 -1
- package/dist/hooks/useRovingTabIndex.cjs.map +1 -1
- package/dist/hooks/useRovingTabIndex.mjs +3 -3
- package/dist/hooks/useRovingTabIndex.mjs.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +2890 -197
- package/dist/index.d.ts +2890 -197
- package/dist/index.mjs +101 -87
- package/dist/lib/classNames.cjs +2 -0
- package/dist/lib/classNames.cjs.map +1 -0
- package/dist/lib/classNames.mjs +423 -0
- package/dist/lib/classNames.mjs.map +1 -0
- package/dist/lib/color.cjs +2 -0
- package/dist/lib/color.cjs.map +1 -0
- package/dist/lib/color.mjs +86 -0
- package/dist/lib/color.mjs.map +1 -0
- package/dist/lib/globalRegistry.cjs.map +1 -1
- package/dist/lib/globalRegistry.mjs.map +1 -1
- package/dist/lib/styles.cjs +1 -1
- package/dist/lib/styles.cjs.map +1 -1
- package/dist/lib/styles.mjs +21 -4
- package/dist/lib/styles.mjs.map +1 -1
- package/dist/lib/toaster.cjs +2 -0
- package/dist/lib/toaster.cjs.map +1 -0
- package/dist/lib/toaster.mjs +77 -0
- package/dist/lib/toaster.mjs.map +1 -0
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/src/styles/tokens.css +13 -0
|
@@ -2,98 +2,99 @@
|
|
|
2
2
|
import { cn as e } from "../../lib/cn.mjs";
|
|
3
3
|
import { flattenChildren as t, isElementOfType as n } from "../../lib/children.mjs";
|
|
4
4
|
import { warnDeprecated as r, warnOnce as i } from "../../lib/dev.mjs";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
5
|
+
import { tableBodyClassNames as a, tableCellClassNames as o, tableClassNames as s, tableHeaderCellClassNames as c, tableHeaderClassNames as l, tableRowClassNames as u } from "../../lib/classNames.mjs";
|
|
6
|
+
import { useId as d } from "../../hooks/useId.mjs";
|
|
7
|
+
import { useMergedRefs as f } from "../../hooks/useMergedRefs.mjs";
|
|
7
8
|
import "../../lib/styles.mjs";
|
|
8
|
-
import * as
|
|
9
|
-
import { jsx as
|
|
9
|
+
import * as p from "react";
|
|
10
|
+
import { jsx as m } from "react/jsx-runtime";
|
|
10
11
|
//#region src/components/table/Table.tsx
|
|
11
|
-
var
|
|
12
|
-
function
|
|
13
|
-
let t =
|
|
12
|
+
var h = () => () => {};
|
|
13
|
+
function g(e) {
|
|
14
|
+
let t = p.useCallback((t) => {
|
|
14
15
|
if (!e || typeof ResizeObserver > "u") return () => {};
|
|
15
16
|
let n = new ResizeObserver(t);
|
|
16
17
|
n.observe(e);
|
|
17
18
|
for (let t of Array.from(e.children)) n.observe(t);
|
|
18
19
|
return () => n.disconnect();
|
|
19
|
-
}, [e]), n =
|
|
20
|
-
return
|
|
20
|
+
}, [e]), n = p.useCallback(() => e ? e.scrollWidth > e.clientWidth : !1, [e]);
|
|
21
|
+
return p.useSyncExternalStore(e ? t : h, n, () => !1);
|
|
21
22
|
}
|
|
22
|
-
function
|
|
23
|
+
function _(e) {
|
|
23
24
|
return n(e, "caption");
|
|
24
25
|
}
|
|
25
|
-
var
|
|
26
|
-
let { className:
|
|
27
|
-
return
|
|
28
|
-
|
|
29
|
-
}, [
|
|
30
|
-
...
|
|
31
|
-
ref:
|
|
32
|
-
role:
|
|
33
|
-
tabIndex:
|
|
34
|
-
"aria-label":
|
|
35
|
-
"aria-labelledby":
|
|
36
|
-
className: e("overflow-x-auto rounded-md border border-border",
|
|
37
|
-
children: /* @__PURE__ */
|
|
38
|
-
ref:
|
|
26
|
+
var v = ({ striped: n = !1, containerProps: r, children: a, className: o, ref: c, ...l }) => {
|
|
27
|
+
let { className: u, ref: h, "aria-label": v, "aria-labelledby": y, ...b } = r ?? {}, [x, S] = p.useState(null), C = f(h, S), w = g(x), T = d("wave-table-caption"), E = t(a), D = E.findIndex(({ node: e }) => _(e)), O = D >= 0 ? E[D].node : null, k = O ? O.props.id ?? T : void 0, A = O && O.props.id === void 0 ? E.map(({ key: e, node: t }, n) => /* @__PURE__ */ m(p.Fragment, { children: n === D ? p.cloneElement(O, { id: T }) : t }, e)) : a, j = v ? void 0 : y ?? k, M = !!(v || j), N = w && M, P = b.role;
|
|
28
|
+
return p.useEffect(() => {
|
|
29
|
+
w && !M && i("Table:unnamed-scroll-region", "Table: the table scrolls horizontally but its scroll region has no name. Add a <caption> or containerProps[\"aria-label\"].");
|
|
30
|
+
}, [w, M]), /* @__PURE__ */ m("div", {
|
|
31
|
+
...b,
|
|
32
|
+
ref: C,
|
|
33
|
+
role: N ? "region" : P,
|
|
34
|
+
tabIndex: w ? 0 : b.tabIndex,
|
|
35
|
+
"aria-label": w || P !== void 0 ? v : void 0,
|
|
36
|
+
"aria-labelledby": N ? j : P === void 0 ? void 0 : y,
|
|
37
|
+
className: e(s.container, "overflow-x-auto rounded-md border border-border", w && "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring", u),
|
|
38
|
+
children: /* @__PURE__ */ m("table", {
|
|
39
|
+
ref: c,
|
|
39
40
|
"data-striped": n ? "" : void 0,
|
|
40
|
-
className: e("w-full border-separate border-spacing-0", n && "[:where(&>tbody>tr:nth-child(odd))]:bg-card",
|
|
41
|
-
...
|
|
42
|
-
children:
|
|
41
|
+
className: e(s.root, "w-full border-separate border-spacing-0", n && "[:where(&>tbody>tr:nth-child(odd))]:bg-card", o),
|
|
42
|
+
...l,
|
|
43
|
+
children: A
|
|
43
44
|
})
|
|
44
45
|
});
|
|
45
46
|
};
|
|
46
|
-
|
|
47
|
-
var
|
|
47
|
+
v.displayName = "Table";
|
|
48
|
+
var y = ({ children: t, className: n, ref: r, ...i }) => /* @__PURE__ */ m("thead", {
|
|
48
49
|
ref: r,
|
|
49
50
|
...i,
|
|
50
|
-
className: e("bg-card", n),
|
|
51
|
+
className: e(l.root, "bg-card", n),
|
|
51
52
|
children: t
|
|
52
53
|
});
|
|
53
|
-
|
|
54
|
-
var
|
|
54
|
+
y.displayName = "TableHeader";
|
|
55
|
+
var b = ({ children: t, className: n, ref: r, ...i }) => /* @__PURE__ */ m("th", {
|
|
55
56
|
ref: r,
|
|
56
57
|
scope: "col",
|
|
57
|
-
className: e("px-4 py-3 text-start font-semibold text-caption-1 uppercase tracking-wider border-b border-border", n),
|
|
58
|
+
className: e(c.root, "px-4 py-3 text-start font-semibold text-caption-1 uppercase tracking-wider border-b border-border", n),
|
|
58
59
|
...i,
|
|
59
60
|
children: t
|
|
60
61
|
});
|
|
61
|
-
|
|
62
|
-
var
|
|
63
|
-
|
|
64
|
-
var
|
|
65
|
-
|
|
66
|
-
var
|
|
67
|
-
ref:
|
|
68
|
-
...
|
|
69
|
-
className:
|
|
70
|
-
children:
|
|
62
|
+
b.displayName = "TableHeaderCell";
|
|
63
|
+
var x = (e) => (r("Table", "Table.Head", "Table.Header"), /* @__PURE__ */ m(y, { ...e }));
|
|
64
|
+
x.displayName = "TableHead";
|
|
65
|
+
var S = (e) => (r("Table", "Table.HeadCell", "Table.HeaderCell"), /* @__PURE__ */ m(b, { ...e }));
|
|
66
|
+
S.displayName = "TableHeadCell";
|
|
67
|
+
var C = ({ children: t, className: n, ref: r, ...i }) => /* @__PURE__ */ m("tbody", {
|
|
68
|
+
ref: r,
|
|
69
|
+
...i,
|
|
70
|
+
className: e(a.root, n),
|
|
71
|
+
children: t
|
|
71
72
|
});
|
|
72
|
-
|
|
73
|
-
var
|
|
73
|
+
C.displayName = "TableBody";
|
|
74
|
+
var w = ({ children: t, className: n, ref: r, ...i }) => /* @__PURE__ */ m("tr", {
|
|
74
75
|
ref: r,
|
|
75
|
-
className: e("hover:bg-subtle-hover transition-colors motion-reduce:transition-none", n),
|
|
76
|
+
className: e(u.root, "hover:bg-subtle-hover transition-colors motion-reduce:transition-none", n),
|
|
76
77
|
...i,
|
|
77
78
|
children: t
|
|
78
79
|
});
|
|
79
|
-
|
|
80
|
-
var
|
|
80
|
+
w.displayName = "TableRow";
|
|
81
|
+
var T = ({ children: t, className: n, ref: r, ...i }) => /* @__PURE__ */ m("td", {
|
|
81
82
|
ref: r,
|
|
82
|
-
className: e("px-4 py-3 text-body-1 border-b border-border", n),
|
|
83
|
+
className: e(o.root, "px-4 py-3 text-body-1 border-b border-border", n),
|
|
83
84
|
...i,
|
|
84
85
|
children: t
|
|
85
86
|
});
|
|
86
|
-
|
|
87
|
-
var
|
|
88
|
-
Header:
|
|
89
|
-
HeaderCell:
|
|
90
|
-
Head:
|
|
91
|
-
HeadCell:
|
|
92
|
-
Body:
|
|
93
|
-
Row:
|
|
94
|
-
Cell:
|
|
87
|
+
T.displayName = "TableCell";
|
|
88
|
+
var E = /* @__PURE__ */ Object.assign(v, {
|
|
89
|
+
Header: y,
|
|
90
|
+
HeaderCell: b,
|
|
91
|
+
Head: x,
|
|
92
|
+
HeadCell: S,
|
|
93
|
+
Body: C,
|
|
94
|
+
Row: w,
|
|
95
|
+
Cell: T
|
|
95
96
|
});
|
|
96
97
|
//#endregion
|
|
97
|
-
export {
|
|
98
|
+
export { E as Table, C as TableBody, T as TableCell, x as TableHead, S as TableHeadCell, y as TableHeader, b as TableHeaderCell, w as TableRow };
|
|
98
99
|
|
|
99
100
|
//# sourceMappingURL=Table.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Table.mjs","names":["useId","useId$1","React","noopSubscribe","useHorizontalOverflow","subscribe","wrapper","observer","onChange","child","getSnapshot","isCaption","isElementOfType","node","TableRoot","props","containerClassName","containerRef","containerLabel","containerLabelledBy","containerRest","containerProps","setWrapper","wrapperRef","useMergedRefs","scrollable","generatedCaptionId","flatChildren","flattenChildren","children","captionIndex","caption","captionId","content","index","key","regionLabelledBy","named","isRegion","consumerRole","warnOnce","cn","striped","className","TableHeader","rest","TableHeaderCell","TableHead","warnDeprecated","TableHeadCell","TableBody","TableRow","TableCell","Table"],"sources":["../../../src/components/table/Table.tsx"],"sourcesContent":["import * as React from 'react';\nimport { flattenChildren, isElementOfType } from '../../lib/children';\nimport { cn } from '../../lib/cn';\nimport { warnDeprecated, warnOnce } from '../../lib/dev';\nimport { focusRing } from '../../lib/styles';\nimport { useId } from '../../hooks/useId';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\n\n/** Properties for the Table component. */\nexport interface TableProps extends React.HTMLAttributes<HTMLTableElement> {\n /**\n * Whether to apply alternating row background colors (odd body rows). The stripe has zero\n * specificity, so a row's own background class (`<Table.Row className=\"bg-selected\">`) and its\n * hover color win over it.\n * @default false\n */\n striped?: boolean;\n /**\n * Props for the wrapper `<div>` around the `<table>`: a horizontally scrollable container\n * (`overflow-x-auto`). Use it for its className, style, ref or `aria-label`. While the table\n * scrolls horizontally, the wrapper is a keyboard-focusable `role=\"region\"` named by\n * `containerProps['aria-label']`/`['aria-labelledby']`, else by the table's `<caption>`. While\n * it does not scroll, the wrapper has no role and its `aria-label`/`aria-labelledby` are left\n * off, unless you also pass a `role` in `containerProps` (then they are always applied).\n */\n containerProps?: Omit<React.ComponentPropsWithRef<'div'>, 'children'>;\n /** Table caption, header, body and row elements. */\n children: React.ReactNode;\n /** Ref to the `<table>` element. */\n ref?: React.Ref<HTMLTableElement>;\n}\n\n/** Properties for the TableHeader sub-component. */\nexport interface TableHeaderProps extends React.HTMLAttributes<HTMLTableSectionElement> {\n /** Table header row elements. */\n children: React.ReactNode;\n /** Ref to the `<thead>` element. */\n ref?: React.Ref<HTMLTableSectionElement>;\n}\n\n/** Properties for the TableHeaderCell sub-component. */\nexport interface TableHeaderCellProps extends React.ThHTMLAttributes<HTMLTableCellElement> {\n /** Header cell content. */\n children: React.ReactNode;\n /** Ref to the `<th>` element. */\n ref?: React.Ref<HTMLTableCellElement>;\n}\n\n/** @deprecated Use `TableHeaderProps` (`Table.Header`). */\nexport type TableHeadProps = TableHeaderProps;\n\n/** @deprecated Use `TableHeaderCellProps` (`Table.HeaderCell`). */\nexport type TableHeadCellProps = TableHeaderCellProps;\n\n/** Properties for the TableBody sub-component. */\nexport interface TableBodyProps extends React.HTMLAttributes<HTMLTableSectionElement> {\n /** Table row elements. */\n children: React.ReactNode;\n /** Ref to the `<tbody>` element. */\n ref?: React.Ref<HTMLTableSectionElement>;\n}\n\n/** Properties for the TableRow sub-component. */\nexport interface TableRowProps extends React.HTMLAttributes<HTMLTableRowElement> {\n /** Table cell elements. */\n children: React.ReactNode;\n /** Ref to the `<tr>` element. */\n ref?: React.Ref<HTMLTableRowElement>;\n}\n\n/** Properties for the TableCell sub-component. */\nexport interface TableCellProps extends React.TdHTMLAttributes<HTMLTableCellElement> {\n /** Cell content. */\n children: React.ReactNode;\n /** Ref to the `<td>` element. */\n ref?: React.Ref<HTMLTableCellElement>;\n}\n\nconst noopSubscribe = () => () => {};\n\n/**\n * Whether `wrapper` scrolls horizontally, as an external store: a `ResizeObserver` on the wrapper\n * and the table re-checks `scrollWidth > clientWidth`. Without `ResizeObserver` (server, old\n * browsers, jsdom) the value is read on each render.\n */\nfunction useHorizontalOverflow(wrapper: HTMLDivElement | null): boolean {\n const subscribe = React.useCallback(\n (onChange: () => void) => {\n if (!wrapper || typeof ResizeObserver === 'undefined') return () => {};\n const observer = new ResizeObserver(onChange);\n observer.observe(wrapper);\n for (const child of Array.from(wrapper.children)) observer.observe(child);\n return () => observer.disconnect();\n },\n [wrapper],\n );\n const getSnapshot = React.useCallback(\n () => (wrapper ? wrapper.scrollWidth > wrapper.clientWidth : false),\n [wrapper],\n );\n return React.useSyncExternalStore(wrapper ? subscribe : noopSubscribe, getSnapshot, () => false);\n}\n\nfunction isCaption(node: React.ReactNode): node is React.ReactElement<{ id?: string }> {\n return isElementOfType(node, 'caption');\n}\n\n// The component-level JSDoc sits on the exported `Table` below.\nconst TableRoot = ({\n striped = false,\n containerProps,\n children,\n className,\n ref,\n ...props\n}: TableProps) => {\n const {\n className: containerClassName,\n ref: containerRef,\n 'aria-label': containerLabel,\n 'aria-labelledby': containerLabelledBy,\n ...containerRest\n } = containerProps ?? {};\n\n const [wrapper, setWrapper] = React.useState<HTMLDivElement | null>(null);\n const wrapperRef = useMergedRefs<HTMLDivElement>(containerRef, setWrapper);\n const scrollable = useHorizontalOverflow(wrapper);\n\n // Name the scroll region after the caption (also one inside a Fragment): keep its id, or give it\n // one. The flattened children are then rendered under their flattened keys.\n const generatedCaptionId = useId('wave-table-caption');\n const flatChildren = flattenChildren(children);\n const captionIndex = flatChildren.findIndex(({ node }) => isCaption(node));\n const caption =\n captionIndex >= 0\n ? (flatChildren[captionIndex].node as React.ReactElement<{ id?: string }>)\n : null;\n const captionId = caption ? (caption.props.id ?? generatedCaptionId) : undefined;\n const content =\n caption && caption.props.id === undefined\n ? flatChildren.map(({ key, node }, index) => (\n <React.Fragment key={key}>\n {index === captionIndex\n ? React.cloneElement(caption, { id: generatedCaptionId })\n : node}\n </React.Fragment>\n ))\n : children;\n\n const regionLabelledBy = containerLabel ? undefined : (containerLabelledBy ?? captionId);\n const named = Boolean(containerLabel || regionLabelledBy);\n const isRegion = scrollable && named;\n /** A role the consumer gave the wrapper: their name goes with it even while nothing scrolls. */\n const consumerRole = containerRest.role;\n\n React.useEffect(() => {\n if (scrollable && !named) {\n warnOnce(\n 'Table:unnamed-scroll-region',\n 'Table: the table scrolls horizontally but its scroll region has no name. Add a <caption> or containerProps[\"aria-label\"].',\n );\n }\n }, [scrollable, named]);\n\n return (\n <div\n {...containerRest}\n ref={wrapperRef}\n role={isRegion ? 'region' : consumerRole}\n tabIndex={scrollable ? 0 : containerRest.tabIndex}\n aria-label={scrollable || consumerRole !== undefined ? containerLabel : undefined}\n aria-labelledby={\n isRegion ? regionLabelledBy : consumerRole !== undefined ? containerLabelledBy : undefined\n }\n className={cn(\n 'overflow-x-auto rounded-md border border-border',\n scrollable && focusRing,\n containerClassName,\n )}\n >\n <table\n ref={ref}\n data-striped={striped ? '' : undefined}\n className={cn(\n 'w-full border-separate border-spacing-0',\n // `:where()` keeps the stripe at specificity 0, so any row class wins (C-CLASS).\n striped && '[:where(&>tbody>tr:nth-child(odd))]:bg-card',\n className,\n )}\n {...props}\n >\n {content}\n </table>\n </div>\n );\n};\nTableRoot.displayName = 'Table';\n\n/** The table's `<thead>`. */\nconst TableHeader = ({ children, className, ref, ...rest }: TableHeaderProps) => (\n <thead ref={ref} {...rest} className={cn('bg-card', className)}>\n {children}\n </thead>\n);\nTableHeader.displayName = 'TableHeader';\n\n/** A column header cell (`<th scope=\"col\">`). */\nconst TableHeaderCell = ({ children, className, ref, ...props }: TableHeaderCellProps) => (\n <th\n ref={ref}\n scope=\"col\"\n className={cn(\n 'px-4 py-3 text-start font-semibold text-caption-1 uppercase tracking-wider border-b border-border',\n className,\n )}\n {...props}\n >\n {children}\n </th>\n);\nTableHeaderCell.displayName = 'TableHeaderCell';\n\n/** @deprecated Use `Table.Header` (`TableHeader`). */\nconst TableHead = (props: TableHeadProps) => {\n warnDeprecated('Table', 'Table.Head', 'Table.Header');\n return <TableHeader {...props} />;\n};\nTableHead.displayName = 'TableHead';\n\n/** @deprecated Use `Table.HeaderCell` (`TableHeaderCell`). */\nconst TableHeadCell = (props: TableHeadCellProps) => {\n warnDeprecated('Table', 'Table.HeadCell', 'Table.HeaderCell');\n return <TableHeaderCell {...props} />;\n};\nTableHeadCell.displayName = 'TableHeadCell';\n\n/** The table's `<tbody>`. */\nconst TableBody = ({ children, className, ref, ...rest }: TableBodyProps) => (\n <tbody ref={ref} {...rest} className={className}>\n {children}\n </tbody>\n);\nTableBody.displayName = 'TableBody';\n\n/** A table row. Striping comes from the table (`striped`), so rows need no context. */\nconst TableRow = ({ children, className, ref, ...props }: TableRowProps) => (\n <tr\n ref={ref}\n className={cn(\n 'hover:bg-subtle-hover transition-colors motion-reduce:transition-none',\n className,\n )}\n {...props}\n >\n {children}\n </tr>\n);\nTableRow.displayName = 'TableRow';\n\n/** A data cell (`<td>`). */\nconst TableCell = ({ children, className, ref, ...props }: TableCellProps) => (\n <td\n ref={ref}\n className={cn('px-4 py-3 text-body-1 border-b border-border', className)}\n {...props}\n >\n {children}\n </td>\n);\nTableCell.displayName = 'TableCell';\n\nexport { TableHeader, TableHeaderCell, TableHead, TableHeadCell, TableBody, TableRow, TableCell };\n\n/**\n * A non-interactive data table with an optional striped body. The table sits in a horizontally\n * scrollable wrapper; while it scrolls, the wrapper is a focusable region (named by\n * `containerProps` or the `<caption>`) so keyboard users can scroll it.\n *\n * Sub-components are available as `Table.Header`, `Table.HeaderCell`, `Table.Body`, `Table.Row`\n * and `Table.Cell` in client components, and as the flat exports `TableHeader`,\n * `TableHeaderCell`, `TableBody`, `TableRow` and `TableCell` (the form React Server Components\n * can import). `Table.Head`/`Table.HeadCell` (`TableHead`/`TableHeadCell`) are deprecated aliases.\n */\nexport const Table = /* @__PURE__ */ Object.assign(TableRoot, {\n Header: TableHeader,\n HeaderCell: TableHeaderCell,\n /** @deprecated Use `Table.Header`. */\n Head: TableHead,\n /** @deprecated Use `Table.HeaderCell`. */\n HeadCell: TableHeadCell,\n Body: TableBody,\n Row: TableRow,\n Cell: TableCell,\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Table.mjs","names":["useId","useId$1","React","noopSubscribe","useHorizontalOverflow","subscribe","wrapper","observer","onChange","child","getSnapshot","isCaption","isElementOfType","node","TableRoot","props","containerClassName","containerRef","containerLabel","containerLabelledBy","containerRest","containerProps","setWrapper","wrapperRef","useMergedRefs","scrollable","generatedCaptionId","flatChildren","flattenChildren","children","captionIndex","caption","captionId","content","index","key","regionLabelledBy","named","isRegion","consumerRole","warnOnce","cn","tableClassNames","striped","className","TableHeader","rest","tableHeaderClassNames","TableHeaderCell","tableHeaderCellClassNames","TableHead","warnDeprecated","TableHeadCell","TableBody","tableBodyClassNames","TableRow","tableRowClassNames","TableCell","tableCellClassNames","Table"],"sources":["../../../src/components/table/Table.tsx"],"sourcesContent":["import * as React from 'react';\nimport { flattenChildren, isElementOfType } from '../../lib/children';\nimport { cn } from '../../lib/cn';\nimport {\n tableBodyClassNames,\n tableCellClassNames,\n tableClassNames,\n tableHeaderCellClassNames,\n tableHeaderClassNames,\n tableRowClassNames,\n} from '../../lib/classNames';\nimport { warnDeprecated, warnOnce } from '../../lib/dev';\nimport { focusRing } from '../../lib/styles';\nimport { useId } from '../../hooks/useId';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\n\n/** Properties for the Table component. */\nexport interface TableProps extends React.HTMLAttributes<HTMLTableElement> {\n /**\n * Whether to apply alternating row background colors (odd body rows). The stripe has zero\n * specificity, so a row's own background class (`<Table.Row className=\"bg-selected\">`) and its\n * hover color win over it.\n * @default false\n */\n striped?: boolean;\n /**\n * Props for the wrapper `<div>` around the `<table>`: a horizontally scrollable container\n * (`overflow-x-auto`). Use it for its className, style, ref or `aria-label`. While the table\n * scrolls horizontally, the wrapper is a keyboard-focusable `role=\"region\"` named by\n * `containerProps['aria-label']`/`['aria-labelledby']`, else by the table's `<caption>`. While\n * it does not scroll, the wrapper has no role and its `aria-label`/`aria-labelledby` are left\n * off, unless you also pass a `role` in `containerProps` (then they are always applied).\n */\n containerProps?: Omit<React.ComponentPropsWithRef<'div'>, 'children'>;\n /** Table caption, header, body and row elements. */\n children: React.ReactNode;\n /** Ref to the `<table>` element. */\n ref?: React.Ref<HTMLTableElement>;\n}\n\n/** Properties for the TableHeader sub-component. */\nexport interface TableHeaderProps extends React.HTMLAttributes<HTMLTableSectionElement> {\n /** Table header row elements. */\n children: React.ReactNode;\n /** Ref to the `<thead>` element. */\n ref?: React.Ref<HTMLTableSectionElement>;\n}\n\n/** Properties for the TableHeaderCell sub-component. */\nexport interface TableHeaderCellProps extends React.ThHTMLAttributes<HTMLTableCellElement> {\n /** Header cell content. */\n children: React.ReactNode;\n /** Ref to the `<th>` element. */\n ref?: React.Ref<HTMLTableCellElement>;\n}\n\n/** @deprecated Use `TableHeaderProps` (`Table.Header`). */\nexport type TableHeadProps = TableHeaderProps;\n\n/** @deprecated Use `TableHeaderCellProps` (`Table.HeaderCell`). */\nexport type TableHeadCellProps = TableHeaderCellProps;\n\n/** Properties for the TableBody sub-component. */\nexport interface TableBodyProps extends React.HTMLAttributes<HTMLTableSectionElement> {\n /** Table row elements. */\n children: React.ReactNode;\n /** Ref to the `<tbody>` element. */\n ref?: React.Ref<HTMLTableSectionElement>;\n}\n\n/** Properties for the TableRow sub-component. */\nexport interface TableRowProps extends React.HTMLAttributes<HTMLTableRowElement> {\n /** Table cell elements. */\n children: React.ReactNode;\n /** Ref to the `<tr>` element. */\n ref?: React.Ref<HTMLTableRowElement>;\n}\n\n/** Properties for the TableCell sub-component. */\nexport interface TableCellProps extends React.TdHTMLAttributes<HTMLTableCellElement> {\n /** Cell content. */\n children: React.ReactNode;\n /** Ref to the `<td>` element. */\n ref?: React.Ref<HTMLTableCellElement>;\n}\n\nconst noopSubscribe = () => () => {};\n\n/**\n * Whether `wrapper` scrolls horizontally, as an external store: a `ResizeObserver` on the wrapper\n * and the table re-checks `scrollWidth > clientWidth`. Without `ResizeObserver` (server, old\n * browsers, jsdom) the value is read on each render.\n */\nfunction useHorizontalOverflow(wrapper: HTMLDivElement | null): boolean {\n const subscribe = React.useCallback(\n (onChange: () => void) => {\n if (!wrapper || typeof ResizeObserver === 'undefined') return () => {};\n const observer = new ResizeObserver(onChange);\n observer.observe(wrapper);\n for (const child of Array.from(wrapper.children)) observer.observe(child);\n return () => observer.disconnect();\n },\n [wrapper],\n );\n const getSnapshot = React.useCallback(\n () => (wrapper ? wrapper.scrollWidth > wrapper.clientWidth : false),\n [wrapper],\n );\n return React.useSyncExternalStore(wrapper ? subscribe : noopSubscribe, getSnapshot, () => false);\n}\n\nfunction isCaption(node: React.ReactNode): node is React.ReactElement<{ id?: string }> {\n return isElementOfType(node, 'caption');\n}\n\n// The component-level JSDoc sits on the exported `Table` below.\nconst TableRoot = ({\n striped = false,\n containerProps,\n children,\n className,\n ref,\n ...props\n}: TableProps) => {\n const {\n className: containerClassName,\n ref: containerRef,\n 'aria-label': containerLabel,\n 'aria-labelledby': containerLabelledBy,\n ...containerRest\n } = containerProps ?? {};\n\n const [wrapper, setWrapper] = React.useState<HTMLDivElement | null>(null);\n const wrapperRef = useMergedRefs<HTMLDivElement>(containerRef, setWrapper);\n const scrollable = useHorizontalOverflow(wrapper);\n\n // Name the scroll region after the caption (also one inside a Fragment): keep its id, or give it\n // one. The flattened children are then rendered under their flattened keys.\n const generatedCaptionId = useId('wave-table-caption');\n const flatChildren = flattenChildren(children);\n const captionIndex = flatChildren.findIndex(({ node }) => isCaption(node));\n const caption =\n captionIndex >= 0\n ? (flatChildren[captionIndex].node as React.ReactElement<{ id?: string }>)\n : null;\n const captionId = caption ? (caption.props.id ?? generatedCaptionId) : undefined;\n const content =\n caption && caption.props.id === undefined\n ? flatChildren.map(({ key, node }, index) => (\n <React.Fragment key={key}>\n {index === captionIndex\n ? React.cloneElement(caption, { id: generatedCaptionId })\n : node}\n </React.Fragment>\n ))\n : children;\n\n const regionLabelledBy = containerLabel ? undefined : (containerLabelledBy ?? captionId);\n const named = Boolean(containerLabel || regionLabelledBy);\n const isRegion = scrollable && named;\n /** A role the consumer gave the wrapper: their name goes with it even while nothing scrolls. */\n const consumerRole = containerRest.role;\n\n React.useEffect(() => {\n if (scrollable && !named) {\n warnOnce(\n 'Table:unnamed-scroll-region',\n 'Table: the table scrolls horizontally but its scroll region has no name. Add a <caption> or containerProps[\"aria-label\"].',\n );\n }\n }, [scrollable, named]);\n\n return (\n <div\n {...containerRest}\n ref={wrapperRef}\n role={isRegion ? 'region' : consumerRole}\n tabIndex={scrollable ? 0 : containerRest.tabIndex}\n aria-label={scrollable || consumerRole !== undefined ? containerLabel : undefined}\n aria-labelledby={\n isRegion ? regionLabelledBy : consumerRole !== undefined ? containerLabelledBy : undefined\n }\n className={cn(\n tableClassNames.container,\n 'overflow-x-auto rounded-md border border-border',\n scrollable && focusRing,\n containerClassName,\n )}\n >\n <table\n ref={ref}\n data-striped={striped ? '' : undefined}\n className={cn(\n tableClassNames.root,\n 'w-full border-separate border-spacing-0',\n // `:where()` keeps the stripe at specificity 0, so any row class wins (C-CLASS).\n striped && '[:where(&>tbody>tr:nth-child(odd))]:bg-card',\n className,\n )}\n {...props}\n >\n {content}\n </table>\n </div>\n );\n};\nTableRoot.displayName = 'Table';\n\n/** The table's `<thead>`. */\nconst TableHeader = ({ children, className, ref, ...rest }: TableHeaderProps) => (\n <thead ref={ref} {...rest} className={cn(tableHeaderClassNames.root, 'bg-card', className)}>\n {children}\n </thead>\n);\nTableHeader.displayName = 'TableHeader';\n\n/** A column header cell (`<th scope=\"col\">`). */\nconst TableHeaderCell = ({ children, className, ref, ...props }: TableHeaderCellProps) => (\n <th\n ref={ref}\n scope=\"col\"\n className={cn(\n tableHeaderCellClassNames.root,\n 'px-4 py-3 text-start font-semibold text-caption-1 uppercase tracking-wider border-b border-border',\n className,\n )}\n {...props}\n >\n {children}\n </th>\n);\nTableHeaderCell.displayName = 'TableHeaderCell';\n\n/** @deprecated Use `Table.Header` (`TableHeader`). */\nconst TableHead = (props: TableHeadProps) => {\n warnDeprecated('Table', 'Table.Head', 'Table.Header');\n return <TableHeader {...props} />;\n};\nTableHead.displayName = 'TableHead';\n\n/** @deprecated Use `Table.HeaderCell` (`TableHeaderCell`). */\nconst TableHeadCell = (props: TableHeadCellProps) => {\n warnDeprecated('Table', 'Table.HeadCell', 'Table.HeaderCell');\n return <TableHeaderCell {...props} />;\n};\nTableHeadCell.displayName = 'TableHeadCell';\n\n/** The table's `<tbody>`. */\nconst TableBody = ({ children, className, ref, ...rest }: TableBodyProps) => (\n <tbody ref={ref} {...rest} className={cn(tableBodyClassNames.root, className)}>\n {children}\n </tbody>\n);\nTableBody.displayName = 'TableBody';\n\n/** A table row. Striping comes from the table (`striped`), so rows need no context. */\nconst TableRow = ({ children, className, ref, ...props }: TableRowProps) => (\n <tr\n ref={ref}\n className={cn(\n tableRowClassNames.root,\n 'hover:bg-subtle-hover transition-colors motion-reduce:transition-none',\n className,\n )}\n {...props}\n >\n {children}\n </tr>\n);\nTableRow.displayName = 'TableRow';\n\n/** A data cell (`<td>`). */\nconst TableCell = ({ children, className, ref, ...props }: TableCellProps) => (\n <td\n ref={ref}\n className={cn(\n tableCellClassNames.root,\n 'px-4 py-3 text-body-1 border-b border-border',\n className,\n )}\n {...props}\n >\n {children}\n </td>\n);\nTableCell.displayName = 'TableCell';\n\nexport { TableHeader, TableHeaderCell, TableHead, TableHeadCell, TableBody, TableRow, TableCell };\n\n/**\n * A non-interactive data table with an optional striped body. The table sits in a horizontally\n * scrollable wrapper; while it scrolls, the wrapper is a focusable region (named by\n * `containerProps` or the `<caption>`) so keyboard users can scroll it.\n *\n * Sub-components are available as `Table.Header`, `Table.HeaderCell`, `Table.Body`, `Table.Row`\n * and `Table.Cell` in client components, and as the flat exports `TableHeader`,\n * `TableHeaderCell`, `TableBody`, `TableRow` and `TableCell` (the form React Server Components\n * can import). `Table.Head`/`Table.HeadCell` (`TableHead`/`TableHeadCell`) are deprecated aliases.\n */\nexport const Table = /* @__PURE__ */ Object.assign(TableRoot, {\n Header: TableHeader,\n HeaderCell: TableHeaderCell,\n /** @deprecated Use `Table.Header`. */\n Head: TableHead,\n /** @deprecated Use `Table.HeaderCell`. */\n HeadCell: TableHeadCell,\n Body: TableBody,\n Row: TableRow,\n Cell: TableCell,\n});\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("../../lib/cn.cjs"),n=require("../../lib/dev.cjs");let
|
|
1
|
+
"use client";const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("../../lib/cn.cjs"),n=require("../../lib/dev.cjs"),r=require("../../lib/classNames.cjs");let i=require("react");i=e.__toESM(i,1);let a=require("react/jsx-runtime");var o={"caption-2":`text-caption-2`,"caption-1":`text-caption-1`,"body-1":`text-body-1`,"body-2":`text-body-2`,"subtitle-2":`text-subtitle-2`,"subtitle-1":`text-subtitle-1`,"title-3":`text-title-3`,"title-2":`text-title-2`,"title-1":`text-title-1`,"large-title":`text-large-title`,display:`text-display`},s={regular:`font-normal`,semibold:`font-semibold`,bold:`font-bold`},c={400:`regular`,600:`semibold`,700:`bold`},l=e=>{let{as:i,variant:l=`body-1`,weight:u,className:d,...f}=e,p;return typeof u==`number`?(p=Object.hasOwn(c,u)?c[u]:void 0,p&&n.warnDeprecated(`Text`,`weight={${u}}`,`weight="${p}"`)):u!==void 0&&Object.hasOwn(s,u)&&(p=u),(0,a.jsx)(i??`span`,{...f,className:t.cn(r.textClassNames.root,o[l],p&&s[p],d)})};l.displayName=`Text`,exports.Text=l;
|
|
2
2
|
//# sourceMappingURL=Text.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Text.cjs","names":["cn","require_runtime","require_cn","require_dev","react","react_jsx_runtime","variantClasses","weightClasses","numericWeights","Text","rest","props","resolvedWeight","weight","as","variant","className"],"sources":["../../../src/components/typography/Text.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { warnDeprecated } from '../../lib/dev';\nimport type { PolymorphicComponent, PolymorphicProps } from '../../lib/polymorphic';\nimport type { TextWeight, TypographyVariant } from '../../lib/types';\n\n/**\n * The Text's own props (the XOwnProps rule of `PolymorphicProps`: component-specific props only).\n * Every other prop comes from the rendered element (`as`, default `'span'`).\n */\nexport interface TextOwnProps {\n /** Typography variant controlling font size and line height (the Wave type ramp).\n * @default 'body-1'\n */\n variant?: TypographyVariant;\n /**\n * Font weight: `'regular'`, `'semibold'` or `'bold'`. Unset, the variant's own weight applies:\n * semibold for `'subtitle-2'` and every larger variant (`'subtitle-1'`, the titles,\n * `'large-title'`, `'display'`), inherited for the caption and body variants. Pass `'regular'`\n * for a title at regular weight. The numeric 0.4 values `400`, `600` and `700` still work but\n * are deprecated.\n */\n weight?: TextWeight | 400 | 600 | 700;\n}\n\n/**\n * The 0.4 numeric weights, kept as deprecated aliases of {@link TextWeight} (written out in\n * {@link TextOwnProps}, not a public name).\n */\ntype DeprecatedNumericWeight = Exclude<NonNullable<TextOwnProps['weight']>, TextWeight>;\n\n/**\n * Props of {@link Text} rendered as `C` (default `'span'`). `TextProps` without a type argument\n * is the 0.4 name: the props of a Text rendered as a `<span>`, including `ref`.\n */\nexport type TextProps<C extends React.ElementType = 'span'> = PolymorphicProps<C, TextOwnProps>;\n\n/** The props the implementation reads, for any `as`. */\ntype TextImplProps = TextOwnProps & {\n as?: React.ElementType;\n className?: string;\n};\n\nconst variantClasses: Record<TypographyVariant, string> = {\n 'caption-2': 'text-caption-2',\n 'caption-1': 'text-caption-1',\n 'body-1': 'text-body-1',\n 'body-2': 'text-body-2',\n 'subtitle-2': 'text-subtitle-2',\n 'subtitle-1': 'text-subtitle-1',\n 'title-3': 'text-title-3',\n 'title-2': 'text-title-2',\n 'title-1': 'text-title-1',\n 'large-title': 'text-large-title',\n display: 'text-display',\n};\n\nconst weightClasses: Record<TextWeight, string> = {\n regular: 'font-normal',\n semibold: 'font-semibold',\n bold: 'font-bold',\n};\n\nconst numericWeights: Record<DeprecatedNumericWeight, TextWeight> = {\n 400: 'regular',\n 600: 'semibold',\n 700: 'bold',\n};\n\n/**\n * Text in the Wave type ramp. Renders a `<span>` by default; `as` renders any element with\n * correctly typed props (`<Text as=\"h1\" variant=\"title-1\">`, `<Text as=\"label\" htmlFor=\"…\">`).\n *\n * Text sets no color: it inherits the surrounding color (the provider's foreground by default),\n * so it follows the theme. Add a color with `className` (`text-muted-foreground`); the variant\n * stays applied.\n *\n * @example\n * <Text as=\"h2\" variant=\"title-2\">Settings</Text>\n * <Text variant=\"body-1\" weight=\"semibold\">Unsaved changes</Text>\n * <Text variant=\"caption-1\" className=\"text-muted-foreground\">Last saved 2 minutes ago</Text>\n */\nexport const Text: PolymorphicComponent<'span', TextOwnProps> = (props) => {\n const { as, variant = 'body-1', weight, className, ...rest } = props as TextImplProps;\n\n let resolvedWeight: TextWeight | undefined;\n if (typeof weight === 'number') {\n resolvedWeight = Object.hasOwn(numericWeights, weight) ? numericWeights[weight] : undefined;\n // Warn-once during render is the sanctioned alias pattern (C-DEV).\n if (resolvedWeight) warnDeprecated('Text', `weight={${weight}}`, `weight=\"${resolvedWeight}\"`);\n } else if (weight !== undefined && Object.hasOwn(weightClasses, weight)) {\n resolvedWeight = weight;\n }\n\n const Component: React.ElementType = as ?? 'span';\n return (\n <Component\n {...rest}\n className={cn(\n variantClasses[variant],\n resolvedWeight && weightClasses[resolvedWeight],\n className,\n )}\n />\n );\n};\n\nText.displayName = 'Text';\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"Text.cjs","names":["cn","textClassNames","require_runtime","require_cn","require_dev","require_classNames","react","react_jsx_runtime","variantClasses","weightClasses","numericWeights","Text","rest","props","resolvedWeight","weight","as","variant","className"],"sources":["../../../src/components/typography/Text.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { warnDeprecated } from '../../lib/dev';\nimport { textClassNames } from '../../lib/classNames';\nimport type { PolymorphicComponent, PolymorphicProps } from '../../lib/polymorphic';\nimport type { TextWeight, TypographyVariant } from '../../lib/types';\n\n/**\n * The Text's own props (the XOwnProps rule of `PolymorphicProps`: component-specific props only).\n * Every other prop comes from the rendered element (`as`, default `'span'`).\n */\nexport interface TextOwnProps {\n /** Typography variant controlling font size and line height (the Wave type ramp).\n * @default 'body-1'\n */\n variant?: TypographyVariant;\n /**\n * Font weight: `'regular'`, `'semibold'` or `'bold'`. Unset, the variant's own weight applies:\n * semibold for `'subtitle-2'` and every larger variant (`'subtitle-1'`, the titles,\n * `'large-title'`, `'display'`), inherited for the caption and body variants. Pass `'regular'`\n * for a title at regular weight. The numeric 0.4 values `400`, `600` and `700` still work but\n * are deprecated.\n */\n weight?: TextWeight | 400 | 600 | 700;\n}\n\n/**\n * The 0.4 numeric weights, kept as deprecated aliases of {@link TextWeight} (written out in\n * {@link TextOwnProps}, not a public name).\n */\ntype DeprecatedNumericWeight = Exclude<NonNullable<TextOwnProps['weight']>, TextWeight>;\n\n/**\n * Props of {@link Text} rendered as `C` (default `'span'`). `TextProps` without a type argument\n * is the 0.4 name: the props of a Text rendered as a `<span>`, including `ref`.\n */\nexport type TextProps<C extends React.ElementType = 'span'> = PolymorphicProps<C, TextOwnProps>;\n\n/** The props the implementation reads, for any `as`. */\ntype TextImplProps = TextOwnProps & {\n as?: React.ElementType;\n className?: string;\n};\n\nconst variantClasses: Record<TypographyVariant, string> = {\n 'caption-2': 'text-caption-2',\n 'caption-1': 'text-caption-1',\n 'body-1': 'text-body-1',\n 'body-2': 'text-body-2',\n 'subtitle-2': 'text-subtitle-2',\n 'subtitle-1': 'text-subtitle-1',\n 'title-3': 'text-title-3',\n 'title-2': 'text-title-2',\n 'title-1': 'text-title-1',\n 'large-title': 'text-large-title',\n display: 'text-display',\n};\n\nconst weightClasses: Record<TextWeight, string> = {\n regular: 'font-normal',\n semibold: 'font-semibold',\n bold: 'font-bold',\n};\n\nconst numericWeights: Record<DeprecatedNumericWeight, TextWeight> = {\n 400: 'regular',\n 600: 'semibold',\n 700: 'bold',\n};\n\n/**\n * Text in the Wave type ramp. Renders a `<span>` by default; `as` renders any element with\n * correctly typed props (`<Text as=\"h1\" variant=\"title-1\">`, `<Text as=\"label\" htmlFor=\"…\">`).\n *\n * Text sets no color: it inherits the surrounding color (the provider's foreground by default),\n * so it follows the theme. Add a color with `className` (`text-muted-foreground`); the variant\n * stays applied.\n *\n * @example\n * <Text as=\"h2\" variant=\"title-2\">Settings</Text>\n * <Text variant=\"body-1\" weight=\"semibold\">Unsaved changes</Text>\n * <Text variant=\"caption-1\" className=\"text-muted-foreground\">Last saved 2 minutes ago</Text>\n */\nexport const Text: PolymorphicComponent<'span', TextOwnProps> = (props) => {\n const { as, variant = 'body-1', weight, className, ...rest } = props as TextImplProps;\n\n let resolvedWeight: TextWeight | undefined;\n if (typeof weight === 'number') {\n resolvedWeight = Object.hasOwn(numericWeights, weight) ? numericWeights[weight] : undefined;\n // Warn-once during render is the sanctioned alias pattern (C-DEV).\n if (resolvedWeight) warnDeprecated('Text', `weight={${weight}}`, `weight=\"${resolvedWeight}\"`);\n } else if (weight !== undefined && Object.hasOwn(weightClasses, weight)) {\n resolvedWeight = weight;\n }\n\n const Component: React.ElementType = as ?? 'span';\n return (\n <Component\n {...rest}\n className={cn(\n textClassNames.root,\n variantClasses[variant],\n resolvedWeight && weightClasses[resolvedWeight],\n className,\n )}\n />\n );\n};\n\nText.displayName = 'Text';\n"],"mappings":"mPA4CA,IAAMQ,EAAoD,CACxD,YAAa,iBACb,YAAa,iBACb,SAAU,cACV,SAAU,cACV,aAAc,kBACd,aAAc,kBACd,UAAW,eACX,UAAW,eACX,UAAW,eACX,cAAe,mBACf,QAAS,cACX,EAEMC,EAA4C,CAChD,QAAS,cACT,SAAU,gBACV,KAAM,WACR,EAEMC,EAA8D,CAClE,IAAK,UACL,IAAK,WACL,IAAK,MACP,EAeaC,EAAoD,GAAU,CACzE,GAAM,CAAE,KAAI,UAAU,SAAU,SAAQ,YAAW,GAAGC,GAASC,EAE3DC,EAUJ,OATI,OAAOC,GAAW,UACpB,EAAiB,OAAO,OAAOL,EAAgBK,CAAM,EAAIL,EAAeK,GAAU,IAAA,GAE9ED,GAAgBV,EAAA,eAAe,OAAQ,WAAWW,EAAO,GAAI,WAAWD,EAAe,EAAE,GACpFC,IAAW,IAAA,IAAa,OAAO,OAAON,EAAeM,CAAM,IACpE,EAAiBA,IAKjB,EAAAR,EAAA,IAAA,CAFmCS,GAAM,OAEzC,CACE,GAAIJ,EACJ,UAAWZ,EAAAA,GACTC,EAAAA,eAAe,KACfO,EAAeS,GACfH,GAAkBL,EAAcK,GAChCI,CACF,CACD,CAAA,CAEL,EAEA,EAAK,YAAc"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn as e } from "../../lib/cn.mjs";
|
|
3
3
|
import { warnDeprecated as t } from "../../lib/dev.mjs";
|
|
4
|
+
import { textClassNames as n } from "../../lib/classNames.mjs";
|
|
4
5
|
import "react";
|
|
5
|
-
import { jsx as
|
|
6
|
+
import { jsx as r } from "react/jsx-runtime";
|
|
6
7
|
//#region src/components/typography/Text.tsx
|
|
7
|
-
var
|
|
8
|
+
var i = {
|
|
8
9
|
"caption-2": "text-caption-2",
|
|
9
10
|
"caption-1": "text-caption-1",
|
|
10
11
|
"body-1": "text-body-1",
|
|
@@ -16,23 +17,23 @@ var r = {
|
|
|
16
17
|
"title-1": "text-title-1",
|
|
17
18
|
"large-title": "text-large-title",
|
|
18
19
|
display: "text-display"
|
|
19
|
-
},
|
|
20
|
+
}, a = {
|
|
20
21
|
regular: "font-normal",
|
|
21
22
|
semibold: "font-semibold",
|
|
22
23
|
bold: "font-bold"
|
|
23
|
-
},
|
|
24
|
+
}, o = {
|
|
24
25
|
400: "regular",
|
|
25
26
|
600: "semibold",
|
|
26
27
|
700: "bold"
|
|
27
|
-
},
|
|
28
|
-
let { as:
|
|
29
|
-
return typeof
|
|
30
|
-
...
|
|
31
|
-
className: e(
|
|
28
|
+
}, s = (s) => {
|
|
29
|
+
let { as: c, variant: l = "body-1", weight: u, className: d, ...f } = s, p;
|
|
30
|
+
return typeof u == "number" ? (p = Object.hasOwn(o, u) ? o[u] : void 0, p && t("Text", `weight={${u}}`, `weight="${p}"`)) : u !== void 0 && Object.hasOwn(a, u) && (p = u), /* @__PURE__ */ r(c ?? "span", {
|
|
31
|
+
...f,
|
|
32
|
+
className: e(n.root, i[l], p && a[p], d)
|
|
32
33
|
});
|
|
33
34
|
};
|
|
34
|
-
|
|
35
|
+
s.displayName = "Text";
|
|
35
36
|
//#endregion
|
|
36
|
-
export {
|
|
37
|
+
export { s as Text };
|
|
37
38
|
|
|
38
39
|
//# sourceMappingURL=Text.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Text.mjs","names":["variantClasses","weightClasses","numericWeights","Text","rest","props","resolvedWeight","weight","warnDeprecated","as","cn","variant","className"],"sources":["../../../src/components/typography/Text.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { warnDeprecated } from '../../lib/dev';\nimport type { PolymorphicComponent, PolymorphicProps } from '../../lib/polymorphic';\nimport type { TextWeight, TypographyVariant } from '../../lib/types';\n\n/**\n * The Text's own props (the XOwnProps rule of `PolymorphicProps`: component-specific props only).\n * Every other prop comes from the rendered element (`as`, default `'span'`).\n */\nexport interface TextOwnProps {\n /** Typography variant controlling font size and line height (the Wave type ramp).\n * @default 'body-1'\n */\n variant?: TypographyVariant;\n /**\n * Font weight: `'regular'`, `'semibold'` or `'bold'`. Unset, the variant's own weight applies:\n * semibold for `'subtitle-2'` and every larger variant (`'subtitle-1'`, the titles,\n * `'large-title'`, `'display'`), inherited for the caption and body variants. Pass `'regular'`\n * for a title at regular weight. The numeric 0.4 values `400`, `600` and `700` still work but\n * are deprecated.\n */\n weight?: TextWeight | 400 | 600 | 700;\n}\n\n/**\n * The 0.4 numeric weights, kept as deprecated aliases of {@link TextWeight} (written out in\n * {@link TextOwnProps}, not a public name).\n */\ntype DeprecatedNumericWeight = Exclude<NonNullable<TextOwnProps['weight']>, TextWeight>;\n\n/**\n * Props of {@link Text} rendered as `C` (default `'span'`). `TextProps` without a type argument\n * is the 0.4 name: the props of a Text rendered as a `<span>`, including `ref`.\n */\nexport type TextProps<C extends React.ElementType = 'span'> = PolymorphicProps<C, TextOwnProps>;\n\n/** The props the implementation reads, for any `as`. */\ntype TextImplProps = TextOwnProps & {\n as?: React.ElementType;\n className?: string;\n};\n\nconst variantClasses: Record<TypographyVariant, string> = {\n 'caption-2': 'text-caption-2',\n 'caption-1': 'text-caption-1',\n 'body-1': 'text-body-1',\n 'body-2': 'text-body-2',\n 'subtitle-2': 'text-subtitle-2',\n 'subtitle-1': 'text-subtitle-1',\n 'title-3': 'text-title-3',\n 'title-2': 'text-title-2',\n 'title-1': 'text-title-1',\n 'large-title': 'text-large-title',\n display: 'text-display',\n};\n\nconst weightClasses: Record<TextWeight, string> = {\n regular: 'font-normal',\n semibold: 'font-semibold',\n bold: 'font-bold',\n};\n\nconst numericWeights: Record<DeprecatedNumericWeight, TextWeight> = {\n 400: 'regular',\n 600: 'semibold',\n 700: 'bold',\n};\n\n/**\n * Text in the Wave type ramp. Renders a `<span>` by default; `as` renders any element with\n * correctly typed props (`<Text as=\"h1\" variant=\"title-1\">`, `<Text as=\"label\" htmlFor=\"…\">`).\n *\n * Text sets no color: it inherits the surrounding color (the provider's foreground by default),\n * so it follows the theme. Add a color with `className` (`text-muted-foreground`); the variant\n * stays applied.\n *\n * @example\n * <Text as=\"h2\" variant=\"title-2\">Settings</Text>\n * <Text variant=\"body-1\" weight=\"semibold\">Unsaved changes</Text>\n * <Text variant=\"caption-1\" className=\"text-muted-foreground\">Last saved 2 minutes ago</Text>\n */\nexport const Text: PolymorphicComponent<'span', TextOwnProps> = (props) => {\n const { as, variant = 'body-1', weight, className, ...rest } = props as TextImplProps;\n\n let resolvedWeight: TextWeight | undefined;\n if (typeof weight === 'number') {\n resolvedWeight = Object.hasOwn(numericWeights, weight) ? numericWeights[weight] : undefined;\n // Warn-once during render is the sanctioned alias pattern (C-DEV).\n if (resolvedWeight) warnDeprecated('Text', `weight={${weight}}`, `weight=\"${resolvedWeight}\"`);\n } else if (weight !== undefined && Object.hasOwn(weightClasses, weight)) {\n resolvedWeight = weight;\n }\n\n const Component: React.ElementType = as ?? 'span';\n return (\n <Component\n {...rest}\n className={cn(\n variantClasses[variant],\n resolvedWeight && weightClasses[resolvedWeight],\n className,\n )}\n />\n );\n};\n\nText.displayName = 'Text';\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"Text.mjs","names":["variantClasses","weightClasses","numericWeights","Text","rest","props","resolvedWeight","weight","warnDeprecated","as","cn","textClassNames","variant","className"],"sources":["../../../src/components/typography/Text.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { warnDeprecated } from '../../lib/dev';\nimport { textClassNames } from '../../lib/classNames';\nimport type { PolymorphicComponent, PolymorphicProps } from '../../lib/polymorphic';\nimport type { TextWeight, TypographyVariant } from '../../lib/types';\n\n/**\n * The Text's own props (the XOwnProps rule of `PolymorphicProps`: component-specific props only).\n * Every other prop comes from the rendered element (`as`, default `'span'`).\n */\nexport interface TextOwnProps {\n /** Typography variant controlling font size and line height (the Wave type ramp).\n * @default 'body-1'\n */\n variant?: TypographyVariant;\n /**\n * Font weight: `'regular'`, `'semibold'` or `'bold'`. Unset, the variant's own weight applies:\n * semibold for `'subtitle-2'` and every larger variant (`'subtitle-1'`, the titles,\n * `'large-title'`, `'display'`), inherited for the caption and body variants. Pass `'regular'`\n * for a title at regular weight. The numeric 0.4 values `400`, `600` and `700` still work but\n * are deprecated.\n */\n weight?: TextWeight | 400 | 600 | 700;\n}\n\n/**\n * The 0.4 numeric weights, kept as deprecated aliases of {@link TextWeight} (written out in\n * {@link TextOwnProps}, not a public name).\n */\ntype DeprecatedNumericWeight = Exclude<NonNullable<TextOwnProps['weight']>, TextWeight>;\n\n/**\n * Props of {@link Text} rendered as `C` (default `'span'`). `TextProps` without a type argument\n * is the 0.4 name: the props of a Text rendered as a `<span>`, including `ref`.\n */\nexport type TextProps<C extends React.ElementType = 'span'> = PolymorphicProps<C, TextOwnProps>;\n\n/** The props the implementation reads, for any `as`. */\ntype TextImplProps = TextOwnProps & {\n as?: React.ElementType;\n className?: string;\n};\n\nconst variantClasses: Record<TypographyVariant, string> = {\n 'caption-2': 'text-caption-2',\n 'caption-1': 'text-caption-1',\n 'body-1': 'text-body-1',\n 'body-2': 'text-body-2',\n 'subtitle-2': 'text-subtitle-2',\n 'subtitle-1': 'text-subtitle-1',\n 'title-3': 'text-title-3',\n 'title-2': 'text-title-2',\n 'title-1': 'text-title-1',\n 'large-title': 'text-large-title',\n display: 'text-display',\n};\n\nconst weightClasses: Record<TextWeight, string> = {\n regular: 'font-normal',\n semibold: 'font-semibold',\n bold: 'font-bold',\n};\n\nconst numericWeights: Record<DeprecatedNumericWeight, TextWeight> = {\n 400: 'regular',\n 600: 'semibold',\n 700: 'bold',\n};\n\n/**\n * Text in the Wave type ramp. Renders a `<span>` by default; `as` renders any element with\n * correctly typed props (`<Text as=\"h1\" variant=\"title-1\">`, `<Text as=\"label\" htmlFor=\"…\">`).\n *\n * Text sets no color: it inherits the surrounding color (the provider's foreground by default),\n * so it follows the theme. Add a color with `className` (`text-muted-foreground`); the variant\n * stays applied.\n *\n * @example\n * <Text as=\"h2\" variant=\"title-2\">Settings</Text>\n * <Text variant=\"body-1\" weight=\"semibold\">Unsaved changes</Text>\n * <Text variant=\"caption-1\" className=\"text-muted-foreground\">Last saved 2 minutes ago</Text>\n */\nexport const Text: PolymorphicComponent<'span', TextOwnProps> = (props) => {\n const { as, variant = 'body-1', weight, className, ...rest } = props as TextImplProps;\n\n let resolvedWeight: TextWeight | undefined;\n if (typeof weight === 'number') {\n resolvedWeight = Object.hasOwn(numericWeights, weight) ? numericWeights[weight] : undefined;\n // Warn-once during render is the sanctioned alias pattern (C-DEV).\n if (resolvedWeight) warnDeprecated('Text', `weight={${weight}}`, `weight=\"${resolvedWeight}\"`);\n } else if (weight !== undefined && Object.hasOwn(weightClasses, weight)) {\n resolvedWeight = weight;\n }\n\n const Component: React.ElementType = as ?? 'span';\n return (\n <Component\n {...rest}\n className={cn(\n textClassNames.root,\n variantClasses[variant],\n resolvedWeight && weightClasses[resolvedWeight],\n className,\n )}\n />\n );\n};\n\nText.displayName = 'Text';\n"],"mappings":";;;;;;;AA4CA,IAAMA,IAAoD;CACxD,aAAa;CACb,aAAa;CACb,UAAU;CACV,UAAU;CACV,cAAc;CACd,cAAc;CACd,WAAW;CACX,WAAW;CACX,WAAW;CACX,eAAe;CACf,SAAS;AACX,GAEMC,IAA4C;CAChD,SAAS;CACT,UAAU;CACV,MAAM;AACR,GAEMC,IAA8D;CAClE,KAAK;CACL,KAAK;CACL,KAAK;AACP,GAeaC,KAAoD,MAAU;CACzE,IAAM,EAAE,OAAI,aAAU,UAAU,WAAQ,cAAW,GAAGC,MAASC,GAE3DC;CAUJ,OATI,OAAOC,KAAW,YACpB,IAAiB,OAAO,OAAOL,GAAgBK,CAAM,IAAIL,EAAeK,KAAU,KAAA,GAE9ED,KAAgBE,EAAe,QAAQ,WAAWD,EAAO,IAAI,WAAWD,EAAe,EAAE,KACpFC,MAAW,KAAA,KAAa,OAAO,OAAON,GAAeM,CAAM,MACpE,IAAiBA,IAKjB,kBAFmCE,KAAM,QAEzC;EACE,GAAIL;EACJ,WAAWM,EACTC,EAAe,MACfX,EAAeY,IACfN,KAAkBL,EAAcK,IAChCO,CACF;CACD,CAAA;AAEL;AAEA,EAAK,cAAc"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useFieldControl.cjs","names":["React","useId","joinIds","require_runtime","require_useId","require_aria","react","FieldControlIdClaimStore","token","onChange","listener","createFieldControlIdClaim","subscribeNothing","noVersion","FieldContext","useFieldContext","useFieldControl","field","fallbackId","options","wantsControlId","props","claim","holdsControlId","id","labelledBy","labelable","describedBy","invalid","ariaRequired","required","nativeRequired","result"],"sources":["../../src/hooks/useFieldControl.ts"],"sourcesContent":["import * as React from 'react';\nimport { joinIds } from '../lib/aria';\nimport type { ValidationState } from '../lib/types';\nimport { useId } from './useId';\n\n/**\n * What a `Field` tells the controls inside it: the ids of its label, hint and validation message,\n * and its validation, invalid and required state. `Field` provides it; every library input reads\n * it through {@link useFieldControl}, and so can your own control.\n */\nexport interface FieldContextValue {\n /** The id the Field's `<label htmlFor>` points at. */\n controlId: string;\n /** The id of the Field's `<label>`, used for `aria-labelledby` on non-labelable controls. */\n labelId: string | undefined;\n /** The id of the rendered hint, if any. */\n hintId: string | undefined;\n /**\n * The id of the rendered error message, if any: set only while the validation message is an\n * error (see `validationMessageId` for every state).\n */\n errorId: string | undefined;\n /** Whether the Field is in an error state (only the `error` validation state is invalid). */\n invalid: boolean;\n /** Whether the Field is required. */\n required: boolean;\n /** Field renders the error message itself; controls with their own `error` must not repeat it. */\n hasErrorMessage: boolean;\n /**\n * Field already gave `controlId` to its first child, a label-for merge target (component,\n * labelable element, custom element), whether Field merged it or it was the child's own id; a\n * control that receives no `id` prop is then not that child (it is nested inside it, e.g.\n * `Field > Tooltip > Input`, or a later sibling) and must not reuse `controlId`.\n * {@link useFieldControl} gives such a control its own id and names it through\n * `aria-labelledby`. Absent or `false`: a control without an `id` uses `controlId`, subject to\n * `controlIdClaim`.\n */\n controlIdAssigned?: boolean;\n /**\n * Hands `controlId` to one control when `controlIdAssigned` is not set — Field left its first\n * child alone (a plain `<div>`, a Fragment), so every library control inside reads this context.\n * The first control without an `id` of its own takes `controlId`; the others get their own id\n * and are named through `aria-labelledby`, so no id is duplicated. `Field` creates one for each\n * Field. Absent: every control without an `id` uses `controlId`.\n */\n controlIdClaim?: FieldControlIdClaim;\n /**\n * The Field's validation state (`validationState`, or `'error'` from `error`). Absent in\n * contexts built before 0.6: read it as `invalid ? 'error' : 'none'`.\n */\n validationState?: ValidationState;\n /**\n * The id of the rendered validation message in any state (error, warning, success, neutral).\n * `errorId` is set only while that message is an error.\n */\n validationMessageId?: string;\n}\n\n/**\n * Decides which control inside a `Field` takes the Field's `controlId` (the id its\n * `<label htmlFor>` points at) when several library controls without an `id` of their own read\n * the same context. `Field` creates one for each Field and passes it as\n * {@link FieldContextValue.controlIdClaim}; {@link useFieldControl} calls the methods, so a\n * control never calls them itself.\n *\n * - The first control to render takes `controlId`: on the first render (and on the server, so\n * hydration matches) that is the first one in document order. It keeps it across re-renders.\n * - When the holder unmounts or stops wanting `controlId` (it gets an `id` of its own), the\n * subscribers are notified, re-render, and the first of them takes `controlId` over.\n * - A render that claimed `controlId` but never committed (a discarded concurrent render) does not\n * keep it: a mounted control that renders without `controlId` frees it.\n */\nexport interface FieldControlIdClaim {\n /**\n * During render, with the control's stable token (its `useId`): gives `controlId` to `token`\n * when no control holds it, and returns whether `token` holds it. Idempotent per token, so\n * StrictMode double renders and later re-renders agree.\n */\n claim(token: string): boolean;\n /**\n * From a layout effect while the control wants `controlId`: marks `token` mounted. The returned\n * cleanup frees `controlId` when `token` holds it and notifies the subscribers.\n */\n mount(token: string): () => void;\n /**\n * From a layout effect of the control that rendered with `controlId`: takes it again after a\n * StrictMode effect replay freed it; if another control took it meanwhile, notifies the\n * subscribers so both re-render and agree.\n */\n hold(token: string): void;\n /**\n * From a passive effect of a mounted control that rendered without `controlId`: frees\n * `controlId` when its holder is not mounted (its render was discarded) and notifies the\n * subscribers.\n */\n releaseStale(): void;\n /** Subscribes to changes of the holder (for `useSyncExternalStore`); returns the unsubscribe. */\n subscribe(onChange: () => void): () => void;\n /** A number that changes whenever the subscribers are notified (the store snapshot). */\n getVersion(): number;\n}\n\nclass FieldControlIdClaimStore implements FieldControlIdClaim {\n private holder: string | undefined = undefined;\n private readonly mounted = new Set<string>();\n private readonly listeners = new Set<() => void>();\n private version = 0;\n\n claim = (token: string): boolean => {\n if (this.holder === undefined) this.holder = token;\n return this.holder === token;\n };\n\n mount = (token: string): (() => void) => {\n this.mounted.add(token);\n return () => {\n this.mounted.delete(token);\n if (this.holder === token) this.free();\n };\n };\n\n hold = (token: string): void => {\n if (this.holder === undefined) this.holder = token;\n else if (this.holder !== token) this.notify();\n };\n\n releaseStale = (): void => {\n if (this.holder !== undefined && !this.mounted.has(this.holder)) this.free();\n };\n\n subscribe = (onChange: () => void): (() => void) => {\n this.listeners.add(onChange);\n return () => {\n this.listeners.delete(onChange);\n };\n };\n\n getVersion = (): number => this.version;\n\n private free(): void {\n this.holder = undefined;\n this.notify();\n }\n\n private notify(): void {\n this.version += 1;\n for (const listener of Array.from(this.listeners)) listener();\n }\n}\n\n/**\n * Creates the {@link FieldControlIdClaim} a Field puts into its context (one per Field instance,\n * e.g. `const [claim] = useState(createFieldControlIdClaim)`).\n *\n * @internal Not exported from the package.\n */\nexport function createFieldControlIdClaim(): FieldControlIdClaim {\n return new FieldControlIdClaimStore();\n}\n\nconst subscribeNothing = (): (() => void) => () => {};\nconst noVersion = (): number => 0;\n\n/**\n * Context provided by `Field`. `null` outside a Field (controls then use only their own props).\n */\nexport const FieldContext: React.Context<FieldContextValue | null> =\n React.createContext<FieldContextValue | null>(null);\nFieldContext.displayName = 'FieldContext';\n\n/** The surrounding Field's context value, or `null` when the control is not inside a Field. */\nexport function useFieldContext(): FieldContextValue | null {\n return React.useContext(FieldContext);\n}\n\n/** The labelling/validation props a control receives from its consumer and from its Field. */\nexport interface FieldControlProps {\n id?: string;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n 'aria-describedby'?: string;\n 'aria-invalid'?: React.AriaAttributes['aria-invalid'];\n 'aria-required'?: React.AriaAttributes['aria-required'];\n required?: boolean;\n}\n\n/** Options of {@link useFieldControl}. */\nexport interface UseFieldControlOptions {\n /**\n * Whether the focusable element can be the target of `<label htmlFor>` (`<input>`, `<button>`,\n * `<select>`, `<textarea>`). Non-labelable controls (`role=\"radiogroup\"`/`role=\"group\"` divs)\n * are named with `aria-labelledby` instead.\n * @default true\n */\n labelable?: boolean;\n /**\n * Whether the focusable element is a native form control (Input, Select, Textarea, Slider,\n * SpinButton's input), so the Field's `required` becomes the native `required` attribute and\n * constraint validation runs. Controls built on buttons or divs validate through `HiddenInput`.\n * @default false\n */\n nativeRequired?: boolean;\n}\n\n/**\n * Merges a control's own labelling props with its surrounding `Field`. Spread the result onto the\n * **focusable element** (for a control whose root wraps it, not onto the root). Consumer values\n * are merged, never overwritten, and only defined keys are returned, so spreading never clears an\n * attribute.\n *\n * - `id`: the consumer's id; else, when the Field already gave `controlId` to its first child\n * (`controlIdAssigned`) — so this control is nested inside that child or a later sibling — a\n * generated id of its own; else the Field's `controlId`, which only one control takes when the\n * Field provides a `controlIdClaim` (several controls inside a plain `<div>`: the first one\n * takes it, the others get a generated id of their own). The first child itself receives\n * `controlId` as its `id` prop from Field, so it keeps it.\n * - `aria-labelledby`: when the consumer set an `aria-label`, only the consumer's\n * `aria-labelledby`; otherwise, when the control is not labelable **or** its id is not the\n * Field's `controlId` (it carries its own id, or is not the Field's first child, so\n * `<label htmlFor>` does not reach it), the consumer's ids plus the Field's `labelId`.\n * - `aria-describedby`: the consumer's ids, then the Field's validation message\n * (`validationMessageId`, else `errorId`), then its hint (deduplicated). A warning, success or\n * neutral message describes the control too.\n * - `aria-invalid` / `aria-required`: the consumer's value, else `true` when the Field is\n * invalid/required (`aria-required`: not when the consumer passes `required={false}`). Only the\n * `error` validation state makes the Field invalid.\n * - `required`: only with `nativeRequired` — the consumer's value, else the Field's `required`.\n * - `aria-label`: passed through.\n *\n * @example\n * const fieldProps = useFieldControl({ id, 'aria-label': ariaLabel, 'aria-labelledby': labelledBy,\n * 'aria-describedby': describedBy, 'aria-invalid': ariaInvalid, 'aria-required': ariaRequired });\n * return <button role=\"switch\" {...fieldProps} />;\n */\nexport function useFieldControl(\n props: FieldControlProps,\n options: UseFieldControlOptions = {},\n): FieldControlProps {\n const field = useFieldContext();\n // Always called (stable hook order); used only when the Field's controlId is taken. It is also\n // the control's token in the Field's controlIdClaim.\n const fallbackId = useId('field-control');\n const { labelable = true, nativeRequired = false } = options;\n\n // A control without an id of its own wants the Field's controlId unless Field gave it to its\n // first child. With a claim, only the first such control takes it.\n const wantsControlId = field !== null && props.id === undefined && !field.controlIdAssigned;\n const claim = wantsControlId ? field.controlIdClaim : undefined;\n // Re-render when the controlId is freed, so the next control takes it over.\n React.useSyncExternalStore(\n claim ? claim.subscribe : subscribeNothing,\n claim ? claim.getVersion : noVersion,\n claim ? claim.getVersion : noVersion,\n );\n const holdsControlId = wantsControlId && (claim ? claim.claim(fallbackId) : true);\n // Layout effects do nothing on the server, and React 19 no longer warns about them there.\n React.useLayoutEffect(() => claim?.mount(fallbackId), [claim, fallbackId]);\n React.useLayoutEffect(() => {\n if (claim && holdsControlId) claim.hold(fallbackId);\n }, [claim, holdsControlId, fallbackId]);\n // After every commit (all layout effects of the commit, and so every mount, have run): a\n // control rendered without controlId frees one held by a render that never committed.\n React.useEffect(() => {\n if (claim && !holdsControlId) claim.releaseStale();\n });\n\n const id =\n props.id ?? (field === null ? undefined : holdsControlId ? field.controlId : fallbackId);\n\n let labelledBy = props['aria-labelledby'];\n if (field && props['aria-label'] === undefined && (!labelable || id !== field.controlId)) {\n labelledBy = joinIds(labelledBy, field.labelId);\n }\n\n // The message in any validation state (a context built before 0.6 has only `errorId`).\n const describedBy = field\n ? joinIds(props['aria-describedby'], field.validationMessageId ?? field.errorId, field.hintId)\n : props['aria-describedby'];\n const invalid = props['aria-invalid'] ?? (field?.invalid || undefined);\n // A consumer `required={false}` (native controls pass `required`) also keeps the Field's\n // required state out of aria-required, so the announced state matches native validation.\n const ariaRequired =\n props['aria-required'] ?? (props.required === false ? undefined : field?.required || undefined);\n const required = nativeRequired ? (props.required ?? (field?.required || undefined)) : undefined;\n\n const result: FieldControlProps = {};\n if (id !== undefined) result.id = id;\n if (props['aria-label'] !== undefined) result['aria-label'] = props['aria-label'];\n if (labelledBy !== undefined) result['aria-labelledby'] = labelledBy;\n if (describedBy !== undefined) result['aria-describedby'] = describedBy;\n if (invalid !== undefined) result['aria-invalid'] = invalid;\n if (ariaRequired !== undefined) result['aria-required'] = ariaRequired;\n if (required !== undefined) result.required = required;\n return result;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useFieldControl.cjs","names":["React","useId","joinIds","require_runtime","require_useId","require_aria","react","FieldControlIdClaimStore","token","onChange","listener","createFieldControlIdClaim","subscribeNothing","noVersion","FieldContext","useFieldContext","useFieldControl","field","fallbackId","options","wantsControlId","props","claim","holdsControlId","id","labelledBy","labelable","describedBy","invalid","ariaRequired","required","nativeRequired","result"],"sources":["../../src/hooks/useFieldControl.ts"],"sourcesContent":["import * as React from 'react';\nimport { joinIds } from '../lib/aria';\nimport type { CoreSize, ValidationState } from '../lib/types';\nimport { useId } from './useId';\n\n/**\n * What a `Field` tells the controls inside it: the ids of its label, hint and validation message,\n * and its validation, invalid and required state. `Field` provides it; every library input reads\n * it through {@link useFieldControl}, and so can your own control.\n */\nexport interface FieldContextValue {\n /** The id the Field's `<label htmlFor>` points at. */\n controlId: string;\n /** The id of the Field's `<label>`, used for `aria-labelledby` on non-labelable controls. */\n labelId: string | undefined;\n /** The id of the rendered hint, if any. */\n hintId: string | undefined;\n /**\n * The id of the rendered error message, if any: set only while the validation message is an\n * error (see `validationMessageId` for every state).\n */\n errorId: string | undefined;\n /** Whether the Field is in an error state (only the `error` validation state is invalid). */\n invalid: boolean;\n /** Whether the Field is required. */\n required: boolean;\n /** Field renders the error message itself; controls with their own `error` must not repeat it. */\n hasErrorMessage: boolean;\n /**\n * Field already gave `controlId` to its first child, a label-for merge target (component,\n * labelable element, custom element), whether Field merged it or it was the child's own id; a\n * control that receives no `id` prop is then not that child (it is nested inside it, e.g.\n * `Field > Tooltip > Input`, or a later sibling) and must not reuse `controlId`.\n * {@link useFieldControl} gives such a control its own id and names it through\n * `aria-labelledby`. Absent or `false`: a control without an `id` uses `controlId`, subject to\n * `controlIdClaim`.\n */\n controlIdAssigned?: boolean;\n /**\n * Hands `controlId` to one control when `controlIdAssigned` is not set — Field left its first\n * child alone (a plain `<div>`, a Fragment), so every library control inside reads this context.\n * The first control without an `id` of its own takes `controlId`; the others get their own id\n * and are named through `aria-labelledby`, so no id is duplicated. `Field` creates one for each\n * Field. Absent: every control without an `id` uses `controlId`.\n */\n controlIdClaim?: FieldControlIdClaim;\n /**\n * The Field's validation state (`validationState`, or `'error'` from `error`). Absent in\n * contexts built before 0.6: read it as `invalid ? 'error' : 'none'`.\n */\n validationState?: ValidationState;\n /**\n * The id of the rendered validation message in any state (error, warning, success, neutral).\n * `errorId` is set only while that message is an error.\n */\n validationMessageId?: string;\n /**\n * The Field's own `size` prop, when set: the default size of the text inputs and pickers inside\n * it (their own `size` wins). Absent when the Field has no `size` (the controls then fall back to\n * `WaveProvider inputDefaults`) and in contexts built before 0.9.\n */\n size?: CoreSize;\n}\n\n/**\n * Decides which control inside a `Field` takes the Field's `controlId` (the id its\n * `<label htmlFor>` points at) when several library controls without an `id` of their own read\n * the same context. `Field` creates one for each Field and passes it as\n * {@link FieldContextValue.controlIdClaim}; {@link useFieldControl} calls the methods, so a\n * control never calls them itself.\n *\n * - The first control to render takes `controlId`: on the first render (and on the server, so\n * hydration matches) that is the first one in document order. It keeps it across re-renders.\n * - When the holder unmounts or stops wanting `controlId` (it gets an `id` of its own), the\n * subscribers are notified, re-render, and the first of them takes `controlId` over.\n * - A render that claimed `controlId` but never committed (a discarded concurrent render) does not\n * keep it: a mounted control that renders without `controlId` frees it.\n */\nexport interface FieldControlIdClaim {\n /**\n * During render, with the control's stable token (its `useId`): gives `controlId` to `token`\n * when no control holds it, and returns whether `token` holds it. Idempotent per token, so\n * StrictMode double renders and later re-renders agree.\n */\n claim(token: string): boolean;\n /**\n * From a layout effect while the control wants `controlId`: marks `token` mounted. The returned\n * cleanup frees `controlId` when `token` holds it and notifies the subscribers.\n */\n mount(token: string): () => void;\n /**\n * From a layout effect of the control that rendered with `controlId`: takes it again after a\n * StrictMode effect replay freed it; if another control took it meanwhile, notifies the\n * subscribers so both re-render and agree.\n */\n hold(token: string): void;\n /**\n * From a passive effect of a mounted control that rendered without `controlId`: frees\n * `controlId` when its holder is not mounted (its render was discarded) and notifies the\n * subscribers.\n */\n releaseStale(): void;\n /** Subscribes to changes of the holder (for `useSyncExternalStore`); returns the unsubscribe. */\n subscribe(onChange: () => void): () => void;\n /** A number that changes whenever the subscribers are notified (the store snapshot). */\n getVersion(): number;\n}\n\nclass FieldControlIdClaimStore implements FieldControlIdClaim {\n private holder: string | undefined = undefined;\n private readonly mounted = new Set<string>();\n private readonly listeners = new Set<() => void>();\n private version = 0;\n\n claim = (token: string): boolean => {\n if (this.holder === undefined) this.holder = token;\n return this.holder === token;\n };\n\n mount = (token: string): (() => void) => {\n this.mounted.add(token);\n return () => {\n this.mounted.delete(token);\n if (this.holder === token) this.free();\n };\n };\n\n hold = (token: string): void => {\n if (this.holder === undefined) this.holder = token;\n else if (this.holder !== token) this.notify();\n };\n\n releaseStale = (): void => {\n if (this.holder !== undefined && !this.mounted.has(this.holder)) this.free();\n };\n\n subscribe = (onChange: () => void): (() => void) => {\n this.listeners.add(onChange);\n return () => {\n this.listeners.delete(onChange);\n };\n };\n\n getVersion = (): number => this.version;\n\n private free(): void {\n this.holder = undefined;\n this.notify();\n }\n\n private notify(): void {\n this.version += 1;\n for (const listener of Array.from(this.listeners)) listener();\n }\n}\n\n/**\n * Creates the {@link FieldControlIdClaim} a Field puts into its context (one per Field instance,\n * e.g. `const [claim] = useState(createFieldControlIdClaim)`).\n *\n * @internal Not exported from the package.\n */\nexport function createFieldControlIdClaim(): FieldControlIdClaim {\n return new FieldControlIdClaimStore();\n}\n\nconst subscribeNothing = (): (() => void) => () => {};\nconst noVersion = (): number => 0;\n\n/**\n * Context provided by `Field`. `null` outside a Field (controls then use only their own props).\n */\nexport const FieldContext: React.Context<FieldContextValue | null> =\n React.createContext<FieldContextValue | null>(null);\nFieldContext.displayName = 'FieldContext';\n\n/** The surrounding Field's context value, or `null` when the control is not inside a Field. */\nexport function useFieldContext(): FieldContextValue | null {\n return React.useContext(FieldContext);\n}\n\n/** The labelling/validation props a control receives from its consumer and from its Field. */\nexport interface FieldControlProps {\n id?: string;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n 'aria-describedby'?: string;\n 'aria-invalid'?: React.AriaAttributes['aria-invalid'];\n 'aria-required'?: React.AriaAttributes['aria-required'];\n required?: boolean;\n}\n\n/** Options of {@link useFieldControl}. */\nexport interface UseFieldControlOptions {\n /**\n * Whether the focusable element can be the target of `<label htmlFor>` (`<input>`, `<button>`,\n * `<select>`, `<textarea>`). Non-labelable controls (`role=\"radiogroup\"`/`role=\"group\"` divs)\n * are named with `aria-labelledby` instead.\n * @default true\n */\n labelable?: boolean;\n /**\n * Whether the focusable element is a native form control (Input, Select, Textarea, Slider,\n * SpinButton's input), so the Field's `required` becomes the native `required` attribute and\n * constraint validation runs. Controls built on buttons or divs validate through `HiddenInput`.\n * @default false\n */\n nativeRequired?: boolean;\n}\n\n/**\n * Merges a control's own labelling props with its surrounding `Field`. Spread the result onto the\n * **focusable element** (for a control whose root wraps it, not onto the root). Consumer values\n * are merged, never overwritten, and only defined keys are returned, so spreading never clears an\n * attribute.\n *\n * - `id`: the consumer's id; else, when the Field already gave `controlId` to its first child\n * (`controlIdAssigned`) — so this control is nested inside that child or a later sibling — a\n * generated id of its own; else the Field's `controlId`, which only one control takes when the\n * Field provides a `controlIdClaim` (several controls inside a plain `<div>`: the first one\n * takes it, the others get a generated id of their own). The first child itself receives\n * `controlId` as its `id` prop from Field, so it keeps it.\n * - `aria-labelledby`: when the consumer set an `aria-label`, only the consumer's\n * `aria-labelledby`; otherwise, when the control is not labelable **or** its id is not the\n * Field's `controlId` (it carries its own id, or is not the Field's first child, so\n * `<label htmlFor>` does not reach it), the consumer's ids plus the Field's `labelId`.\n * - `aria-describedby`: the consumer's ids, then the Field's validation message\n * (`validationMessageId`, else `errorId`), then its hint (deduplicated). A warning, success or\n * neutral message describes the control too.\n * - `aria-invalid` / `aria-required`: the consumer's value, else `true` when the Field is\n * invalid/required (`aria-required`: not when the consumer passes `required={false}`). Only the\n * `error` validation state makes the Field invalid.\n * - `required`: only with `nativeRequired` — the consumer's value, else the Field's `required`.\n * - `aria-label`: passed through.\n *\n * @example\n * const fieldProps = useFieldControl({ id, 'aria-label': ariaLabel, 'aria-labelledby': labelledBy,\n * 'aria-describedby': describedBy, 'aria-invalid': ariaInvalid, 'aria-required': ariaRequired });\n * return <button role=\"switch\" {...fieldProps} />;\n */\nexport function useFieldControl(\n props: FieldControlProps,\n options: UseFieldControlOptions = {},\n): FieldControlProps {\n const field = useFieldContext();\n // Always called (stable hook order); used only when the Field's controlId is taken. It is also\n // the control's token in the Field's controlIdClaim.\n const fallbackId = useId('field-control');\n const { labelable = true, nativeRequired = false } = options;\n\n // A control without an id of its own wants the Field's controlId unless Field gave it to its\n // first child. With a claim, only the first such control takes it.\n const wantsControlId = field !== null && props.id === undefined && !field.controlIdAssigned;\n const claim = wantsControlId ? field.controlIdClaim : undefined;\n // Re-render when the controlId is freed, so the next control takes it over.\n React.useSyncExternalStore(\n claim ? claim.subscribe : subscribeNothing,\n claim ? claim.getVersion : noVersion,\n claim ? claim.getVersion : noVersion,\n );\n const holdsControlId = wantsControlId && (claim ? claim.claim(fallbackId) : true);\n // Layout effects do nothing on the server, and React 19 no longer warns about them there.\n React.useLayoutEffect(() => claim?.mount(fallbackId), [claim, fallbackId]);\n React.useLayoutEffect(() => {\n if (claim && holdsControlId) claim.hold(fallbackId);\n }, [claim, holdsControlId, fallbackId]);\n // After every commit (all layout effects of the commit, and so every mount, have run): a\n // control rendered without controlId frees one held by a render that never committed.\n React.useEffect(() => {\n if (claim && !holdsControlId) claim.releaseStale();\n });\n\n const id =\n props.id ?? (field === null ? undefined : holdsControlId ? field.controlId : fallbackId);\n\n let labelledBy = props['aria-labelledby'];\n if (field && props['aria-label'] === undefined && (!labelable || id !== field.controlId)) {\n labelledBy = joinIds(labelledBy, field.labelId);\n }\n\n // The message in any validation state (a context built before 0.6 has only `errorId`).\n const describedBy = field\n ? joinIds(props['aria-describedby'], field.validationMessageId ?? field.errorId, field.hintId)\n : props['aria-describedby'];\n const invalid = props['aria-invalid'] ?? (field?.invalid || undefined);\n // A consumer `required={false}` (native controls pass `required`) also keeps the Field's\n // required state out of aria-required, so the announced state matches native validation.\n const ariaRequired =\n props['aria-required'] ?? (props.required === false ? undefined : field?.required || undefined);\n const required = nativeRequired ? (props.required ?? (field?.required || undefined)) : undefined;\n\n const result: FieldControlProps = {};\n if (id !== undefined) result.id = id;\n if (props['aria-label'] !== undefined) result['aria-label'] = props['aria-label'];\n if (labelledBy !== undefined) result['aria-labelledby'] = labelledBy;\n if (describedBy !== undefined) result['aria-describedby'] = describedBy;\n if (invalid !== undefined) result['aria-invalid'] = invalid;\n if (ariaRequired !== undefined) result['aria-required'] = ariaRequired;\n if (required !== undefined) result.required = required;\n return result;\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useFieldControl.mjs","names":["useId","useId$1","React","FieldControlIdClaimStore","token","onChange","listener","createFieldControlIdClaim","subscribeNothing","noVersion","FieldContext","useFieldContext","useFieldControl","field","fallbackId","options","wantsControlId","props","claim","holdsControlId","id","labelledBy","labelable","joinIds","describedBy","invalid","ariaRequired","required","nativeRequired","result"],"sources":["../../src/hooks/useFieldControl.ts"],"sourcesContent":["import * as React from 'react';\nimport { joinIds } from '../lib/aria';\nimport type { ValidationState } from '../lib/types';\nimport { useId } from './useId';\n\n/**\n * What a `Field` tells the controls inside it: the ids of its label, hint and validation message,\n * and its validation, invalid and required state. `Field` provides it; every library input reads\n * it through {@link useFieldControl}, and so can your own control.\n */\nexport interface FieldContextValue {\n /** The id the Field's `<label htmlFor>` points at. */\n controlId: string;\n /** The id of the Field's `<label>`, used for `aria-labelledby` on non-labelable controls. */\n labelId: string | undefined;\n /** The id of the rendered hint, if any. */\n hintId: string | undefined;\n /**\n * The id of the rendered error message, if any: set only while the validation message is an\n * error (see `validationMessageId` for every state).\n */\n errorId: string | undefined;\n /** Whether the Field is in an error state (only the `error` validation state is invalid). */\n invalid: boolean;\n /** Whether the Field is required. */\n required: boolean;\n /** Field renders the error message itself; controls with their own `error` must not repeat it. */\n hasErrorMessage: boolean;\n /**\n * Field already gave `controlId` to its first child, a label-for merge target (component,\n * labelable element, custom element), whether Field merged it or it was the child's own id; a\n * control that receives no `id` prop is then not that child (it is nested inside it, e.g.\n * `Field > Tooltip > Input`, or a later sibling) and must not reuse `controlId`.\n * {@link useFieldControl} gives such a control its own id and names it through\n * `aria-labelledby`. Absent or `false`: a control without an `id` uses `controlId`, subject to\n * `controlIdClaim`.\n */\n controlIdAssigned?: boolean;\n /**\n * Hands `controlId` to one control when `controlIdAssigned` is not set — Field left its first\n * child alone (a plain `<div>`, a Fragment), so every library control inside reads this context.\n * The first control without an `id` of its own takes `controlId`; the others get their own id\n * and are named through `aria-labelledby`, so no id is duplicated. `Field` creates one for each\n * Field. Absent: every control without an `id` uses `controlId`.\n */\n controlIdClaim?: FieldControlIdClaim;\n /**\n * The Field's validation state (`validationState`, or `'error'` from `error`). Absent in\n * contexts built before 0.6: read it as `invalid ? 'error' : 'none'`.\n */\n validationState?: ValidationState;\n /**\n * The id of the rendered validation message in any state (error, warning, success, neutral).\n * `errorId` is set only while that message is an error.\n */\n validationMessageId?: string;\n}\n\n/**\n * Decides which control inside a `Field` takes the Field's `controlId` (the id its\n * `<label htmlFor>` points at) when several library controls without an `id` of their own read\n * the same context. `Field` creates one for each Field and passes it as\n * {@link FieldContextValue.controlIdClaim}; {@link useFieldControl} calls the methods, so a\n * control never calls them itself.\n *\n * - The first control to render takes `controlId`: on the first render (and on the server, so\n * hydration matches) that is the first one in document order. It keeps it across re-renders.\n * - When the holder unmounts or stops wanting `controlId` (it gets an `id` of its own), the\n * subscribers are notified, re-render, and the first of them takes `controlId` over.\n * - A render that claimed `controlId` but never committed (a discarded concurrent render) does not\n * keep it: a mounted control that renders without `controlId` frees it.\n */\nexport interface FieldControlIdClaim {\n /**\n * During render, with the control's stable token (its `useId`): gives `controlId` to `token`\n * when no control holds it, and returns whether `token` holds it. Idempotent per token, so\n * StrictMode double renders and later re-renders agree.\n */\n claim(token: string): boolean;\n /**\n * From a layout effect while the control wants `controlId`: marks `token` mounted. The returned\n * cleanup frees `controlId` when `token` holds it and notifies the subscribers.\n */\n mount(token: string): () => void;\n /**\n * From a layout effect of the control that rendered with `controlId`: takes it again after a\n * StrictMode effect replay freed it; if another control took it meanwhile, notifies the\n * subscribers so both re-render and agree.\n */\n hold(token: string): void;\n /**\n * From a passive effect of a mounted control that rendered without `controlId`: frees\n * `controlId` when its holder is not mounted (its render was discarded) and notifies the\n * subscribers.\n */\n releaseStale(): void;\n /** Subscribes to changes of the holder (for `useSyncExternalStore`); returns the unsubscribe. */\n subscribe(onChange: () => void): () => void;\n /** A number that changes whenever the subscribers are notified (the store snapshot). */\n getVersion(): number;\n}\n\nclass FieldControlIdClaimStore implements FieldControlIdClaim {\n private holder: string | undefined = undefined;\n private readonly mounted = new Set<string>();\n private readonly listeners = new Set<() => void>();\n private version = 0;\n\n claim = (token: string): boolean => {\n if (this.holder === undefined) this.holder = token;\n return this.holder === token;\n };\n\n mount = (token: string): (() => void) => {\n this.mounted.add(token);\n return () => {\n this.mounted.delete(token);\n if (this.holder === token) this.free();\n };\n };\n\n hold = (token: string): void => {\n if (this.holder === undefined) this.holder = token;\n else if (this.holder !== token) this.notify();\n };\n\n releaseStale = (): void => {\n if (this.holder !== undefined && !this.mounted.has(this.holder)) this.free();\n };\n\n subscribe = (onChange: () => void): (() => void) => {\n this.listeners.add(onChange);\n return () => {\n this.listeners.delete(onChange);\n };\n };\n\n getVersion = (): number => this.version;\n\n private free(): void {\n this.holder = undefined;\n this.notify();\n }\n\n private notify(): void {\n this.version += 1;\n for (const listener of Array.from(this.listeners)) listener();\n }\n}\n\n/**\n * Creates the {@link FieldControlIdClaim} a Field puts into its context (one per Field instance,\n * e.g. `const [claim] = useState(createFieldControlIdClaim)`).\n *\n * @internal Not exported from the package.\n */\nexport function createFieldControlIdClaim(): FieldControlIdClaim {\n return new FieldControlIdClaimStore();\n}\n\nconst subscribeNothing = (): (() => void) => () => {};\nconst noVersion = (): number => 0;\n\n/**\n * Context provided by `Field`. `null` outside a Field (controls then use only their own props).\n */\nexport const FieldContext: React.Context<FieldContextValue | null> =\n React.createContext<FieldContextValue | null>(null);\nFieldContext.displayName = 'FieldContext';\n\n/** The surrounding Field's context value, or `null` when the control is not inside a Field. */\nexport function useFieldContext(): FieldContextValue | null {\n return React.useContext(FieldContext);\n}\n\n/** The labelling/validation props a control receives from its consumer and from its Field. */\nexport interface FieldControlProps {\n id?: string;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n 'aria-describedby'?: string;\n 'aria-invalid'?: React.AriaAttributes['aria-invalid'];\n 'aria-required'?: React.AriaAttributes['aria-required'];\n required?: boolean;\n}\n\n/** Options of {@link useFieldControl}. */\nexport interface UseFieldControlOptions {\n /**\n * Whether the focusable element can be the target of `<label htmlFor>` (`<input>`, `<button>`,\n * `<select>`, `<textarea>`). Non-labelable controls (`role=\"radiogroup\"`/`role=\"group\"` divs)\n * are named with `aria-labelledby` instead.\n * @default true\n */\n labelable?: boolean;\n /**\n * Whether the focusable element is a native form control (Input, Select, Textarea, Slider,\n * SpinButton's input), so the Field's `required` becomes the native `required` attribute and\n * constraint validation runs. Controls built on buttons or divs validate through `HiddenInput`.\n * @default false\n */\n nativeRequired?: boolean;\n}\n\n/**\n * Merges a control's own labelling props with its surrounding `Field`. Spread the result onto the\n * **focusable element** (for a control whose root wraps it, not onto the root). Consumer values\n * are merged, never overwritten, and only defined keys are returned, so spreading never clears an\n * attribute.\n *\n * - `id`: the consumer's id; else, when the Field already gave `controlId` to its first child\n * (`controlIdAssigned`) — so this control is nested inside that child or a later sibling — a\n * generated id of its own; else the Field's `controlId`, which only one control takes when the\n * Field provides a `controlIdClaim` (several controls inside a plain `<div>`: the first one\n * takes it, the others get a generated id of their own). The first child itself receives\n * `controlId` as its `id` prop from Field, so it keeps it.\n * - `aria-labelledby`: when the consumer set an `aria-label`, only the consumer's\n * `aria-labelledby`; otherwise, when the control is not labelable **or** its id is not the\n * Field's `controlId` (it carries its own id, or is not the Field's first child, so\n * `<label htmlFor>` does not reach it), the consumer's ids plus the Field's `labelId`.\n * - `aria-describedby`: the consumer's ids, then the Field's validation message\n * (`validationMessageId`, else `errorId`), then its hint (deduplicated). A warning, success or\n * neutral message describes the control too.\n * - `aria-invalid` / `aria-required`: the consumer's value, else `true` when the Field is\n * invalid/required (`aria-required`: not when the consumer passes `required={false}`). Only the\n * `error` validation state makes the Field invalid.\n * - `required`: only with `nativeRequired` — the consumer's value, else the Field's `required`.\n * - `aria-label`: passed through.\n *\n * @example\n * const fieldProps = useFieldControl({ id, 'aria-label': ariaLabel, 'aria-labelledby': labelledBy,\n * 'aria-describedby': describedBy, 'aria-invalid': ariaInvalid, 'aria-required': ariaRequired });\n * return <button role=\"switch\" {...fieldProps} />;\n */\nexport function useFieldControl(\n props: FieldControlProps,\n options: UseFieldControlOptions = {},\n): FieldControlProps {\n const field = useFieldContext();\n // Always called (stable hook order); used only when the Field's controlId is taken. It is also\n // the control's token in the Field's controlIdClaim.\n const fallbackId = useId('field-control');\n const { labelable = true, nativeRequired = false } = options;\n\n // A control without an id of its own wants the Field's controlId unless Field gave it to its\n // first child. With a claim, only the first such control takes it.\n const wantsControlId = field !== null && props.id === undefined && !field.controlIdAssigned;\n const claim = wantsControlId ? field.controlIdClaim : undefined;\n // Re-render when the controlId is freed, so the next control takes it over.\n React.useSyncExternalStore(\n claim ? claim.subscribe : subscribeNothing,\n claim ? claim.getVersion : noVersion,\n claim ? claim.getVersion : noVersion,\n );\n const holdsControlId = wantsControlId && (claim ? claim.claim(fallbackId) : true);\n // Layout effects do nothing on the server, and React 19 no longer warns about them there.\n React.useLayoutEffect(() => claim?.mount(fallbackId), [claim, fallbackId]);\n React.useLayoutEffect(() => {\n if (claim && holdsControlId) claim.hold(fallbackId);\n }, [claim, holdsControlId, fallbackId]);\n // After every commit (all layout effects of the commit, and so every mount, have run): a\n // control rendered without controlId frees one held by a render that never committed.\n React.useEffect(() => {\n if (claim && !holdsControlId) claim.releaseStale();\n });\n\n const id =\n props.id ?? (field === null ? undefined : holdsControlId ? field.controlId : fallbackId);\n\n let labelledBy = props['aria-labelledby'];\n if (field && props['aria-label'] === undefined && (!labelable || id !== field.controlId)) {\n labelledBy = joinIds(labelledBy, field.labelId);\n }\n\n // The message in any validation state (a context built before 0.6 has only `errorId`).\n const describedBy = field\n ? joinIds(props['aria-describedby'], field.validationMessageId ?? field.errorId, field.hintId)\n : props['aria-describedby'];\n const invalid = props['aria-invalid'] ?? (field?.invalid || undefined);\n // A consumer `required={false}` (native controls pass `required`) also keeps the Field's\n // required state out of aria-required, so the announced state matches native validation.\n const ariaRequired =\n props['aria-required'] ?? (props.required === false ? undefined : field?.required || undefined);\n const required = nativeRequired ? (props.required ?? (field?.required || undefined)) : undefined;\n\n const result: FieldControlProps = {};\n if (id !== undefined) result.id = id;\n if (props['aria-label'] !== undefined) result['aria-label'] = props['aria-label'];\n if (labelledBy !== undefined) result['aria-labelledby'] = labelledBy;\n if (describedBy !== undefined) result['aria-describedby'] = describedBy;\n if (invalid !== undefined) result['aria-invalid'] = invalid;\n if (ariaRequired !== undefined) result['aria-required'] = ariaRequired;\n if (required !== undefined) result.required = required;\n return result;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useFieldControl.mjs","names":["useId","useId$1","React","FieldControlIdClaimStore","token","onChange","listener","createFieldControlIdClaim","subscribeNothing","noVersion","FieldContext","useFieldContext","useFieldControl","field","fallbackId","options","wantsControlId","props","claim","holdsControlId","id","labelledBy","labelable","joinIds","describedBy","invalid","ariaRequired","required","nativeRequired","result"],"sources":["../../src/hooks/useFieldControl.ts"],"sourcesContent":["import * as React from 'react';\nimport { joinIds } from '../lib/aria';\nimport type { CoreSize, ValidationState } from '../lib/types';\nimport { useId } from './useId';\n\n/**\n * What a `Field` tells the controls inside it: the ids of its label, hint and validation message,\n * and its validation, invalid and required state. `Field` provides it; every library input reads\n * it through {@link useFieldControl}, and so can your own control.\n */\nexport interface FieldContextValue {\n /** The id the Field's `<label htmlFor>` points at. */\n controlId: string;\n /** The id of the Field's `<label>`, used for `aria-labelledby` on non-labelable controls. */\n labelId: string | undefined;\n /** The id of the rendered hint, if any. */\n hintId: string | undefined;\n /**\n * The id of the rendered error message, if any: set only while the validation message is an\n * error (see `validationMessageId` for every state).\n */\n errorId: string | undefined;\n /** Whether the Field is in an error state (only the `error` validation state is invalid). */\n invalid: boolean;\n /** Whether the Field is required. */\n required: boolean;\n /** Field renders the error message itself; controls with their own `error` must not repeat it. */\n hasErrorMessage: boolean;\n /**\n * Field already gave `controlId` to its first child, a label-for merge target (component,\n * labelable element, custom element), whether Field merged it or it was the child's own id; a\n * control that receives no `id` prop is then not that child (it is nested inside it, e.g.\n * `Field > Tooltip > Input`, or a later sibling) and must not reuse `controlId`.\n * {@link useFieldControl} gives such a control its own id and names it through\n * `aria-labelledby`. Absent or `false`: a control without an `id` uses `controlId`, subject to\n * `controlIdClaim`.\n */\n controlIdAssigned?: boolean;\n /**\n * Hands `controlId` to one control when `controlIdAssigned` is not set — Field left its first\n * child alone (a plain `<div>`, a Fragment), so every library control inside reads this context.\n * The first control without an `id` of its own takes `controlId`; the others get their own id\n * and are named through `aria-labelledby`, so no id is duplicated. `Field` creates one for each\n * Field. Absent: every control without an `id` uses `controlId`.\n */\n controlIdClaim?: FieldControlIdClaim;\n /**\n * The Field's validation state (`validationState`, or `'error'` from `error`). Absent in\n * contexts built before 0.6: read it as `invalid ? 'error' : 'none'`.\n */\n validationState?: ValidationState;\n /**\n * The id of the rendered validation message in any state (error, warning, success, neutral).\n * `errorId` is set only while that message is an error.\n */\n validationMessageId?: string;\n /**\n * The Field's own `size` prop, when set: the default size of the text inputs and pickers inside\n * it (their own `size` wins). Absent when the Field has no `size` (the controls then fall back to\n * `WaveProvider inputDefaults`) and in contexts built before 0.9.\n */\n size?: CoreSize;\n}\n\n/**\n * Decides which control inside a `Field` takes the Field's `controlId` (the id its\n * `<label htmlFor>` points at) when several library controls without an `id` of their own read\n * the same context. `Field` creates one for each Field and passes it as\n * {@link FieldContextValue.controlIdClaim}; {@link useFieldControl} calls the methods, so a\n * control never calls them itself.\n *\n * - The first control to render takes `controlId`: on the first render (and on the server, so\n * hydration matches) that is the first one in document order. It keeps it across re-renders.\n * - When the holder unmounts or stops wanting `controlId` (it gets an `id` of its own), the\n * subscribers are notified, re-render, and the first of them takes `controlId` over.\n * - A render that claimed `controlId` but never committed (a discarded concurrent render) does not\n * keep it: a mounted control that renders without `controlId` frees it.\n */\nexport interface FieldControlIdClaim {\n /**\n * During render, with the control's stable token (its `useId`): gives `controlId` to `token`\n * when no control holds it, and returns whether `token` holds it. Idempotent per token, so\n * StrictMode double renders and later re-renders agree.\n */\n claim(token: string): boolean;\n /**\n * From a layout effect while the control wants `controlId`: marks `token` mounted. The returned\n * cleanup frees `controlId` when `token` holds it and notifies the subscribers.\n */\n mount(token: string): () => void;\n /**\n * From a layout effect of the control that rendered with `controlId`: takes it again after a\n * StrictMode effect replay freed it; if another control took it meanwhile, notifies the\n * subscribers so both re-render and agree.\n */\n hold(token: string): void;\n /**\n * From a passive effect of a mounted control that rendered without `controlId`: frees\n * `controlId` when its holder is not mounted (its render was discarded) and notifies the\n * subscribers.\n */\n releaseStale(): void;\n /** Subscribes to changes of the holder (for `useSyncExternalStore`); returns the unsubscribe. */\n subscribe(onChange: () => void): () => void;\n /** A number that changes whenever the subscribers are notified (the store snapshot). */\n getVersion(): number;\n}\n\nclass FieldControlIdClaimStore implements FieldControlIdClaim {\n private holder: string | undefined = undefined;\n private readonly mounted = new Set<string>();\n private readonly listeners = new Set<() => void>();\n private version = 0;\n\n claim = (token: string): boolean => {\n if (this.holder === undefined) this.holder = token;\n return this.holder === token;\n };\n\n mount = (token: string): (() => void) => {\n this.mounted.add(token);\n return () => {\n this.mounted.delete(token);\n if (this.holder === token) this.free();\n };\n };\n\n hold = (token: string): void => {\n if (this.holder === undefined) this.holder = token;\n else if (this.holder !== token) this.notify();\n };\n\n releaseStale = (): void => {\n if (this.holder !== undefined && !this.mounted.has(this.holder)) this.free();\n };\n\n subscribe = (onChange: () => void): (() => void) => {\n this.listeners.add(onChange);\n return () => {\n this.listeners.delete(onChange);\n };\n };\n\n getVersion = (): number => this.version;\n\n private free(): void {\n this.holder = undefined;\n this.notify();\n }\n\n private notify(): void {\n this.version += 1;\n for (const listener of Array.from(this.listeners)) listener();\n }\n}\n\n/**\n * Creates the {@link FieldControlIdClaim} a Field puts into its context (one per Field instance,\n * e.g. `const [claim] = useState(createFieldControlIdClaim)`).\n *\n * @internal Not exported from the package.\n */\nexport function createFieldControlIdClaim(): FieldControlIdClaim {\n return new FieldControlIdClaimStore();\n}\n\nconst subscribeNothing = (): (() => void) => () => {};\nconst noVersion = (): number => 0;\n\n/**\n * Context provided by `Field`. `null` outside a Field (controls then use only their own props).\n */\nexport const FieldContext: React.Context<FieldContextValue | null> =\n React.createContext<FieldContextValue | null>(null);\nFieldContext.displayName = 'FieldContext';\n\n/** The surrounding Field's context value, or `null` when the control is not inside a Field. */\nexport function useFieldContext(): FieldContextValue | null {\n return React.useContext(FieldContext);\n}\n\n/** The labelling/validation props a control receives from its consumer and from its Field. */\nexport interface FieldControlProps {\n id?: string;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n 'aria-describedby'?: string;\n 'aria-invalid'?: React.AriaAttributes['aria-invalid'];\n 'aria-required'?: React.AriaAttributes['aria-required'];\n required?: boolean;\n}\n\n/** Options of {@link useFieldControl}. */\nexport interface UseFieldControlOptions {\n /**\n * Whether the focusable element can be the target of `<label htmlFor>` (`<input>`, `<button>`,\n * `<select>`, `<textarea>`). Non-labelable controls (`role=\"radiogroup\"`/`role=\"group\"` divs)\n * are named with `aria-labelledby` instead.\n * @default true\n */\n labelable?: boolean;\n /**\n * Whether the focusable element is a native form control (Input, Select, Textarea, Slider,\n * SpinButton's input), so the Field's `required` becomes the native `required` attribute and\n * constraint validation runs. Controls built on buttons or divs validate through `HiddenInput`.\n * @default false\n */\n nativeRequired?: boolean;\n}\n\n/**\n * Merges a control's own labelling props with its surrounding `Field`. Spread the result onto the\n * **focusable element** (for a control whose root wraps it, not onto the root). Consumer values\n * are merged, never overwritten, and only defined keys are returned, so spreading never clears an\n * attribute.\n *\n * - `id`: the consumer's id; else, when the Field already gave `controlId` to its first child\n * (`controlIdAssigned`) — so this control is nested inside that child or a later sibling — a\n * generated id of its own; else the Field's `controlId`, which only one control takes when the\n * Field provides a `controlIdClaim` (several controls inside a plain `<div>`: the first one\n * takes it, the others get a generated id of their own). The first child itself receives\n * `controlId` as its `id` prop from Field, so it keeps it.\n * - `aria-labelledby`: when the consumer set an `aria-label`, only the consumer's\n * `aria-labelledby`; otherwise, when the control is not labelable **or** its id is not the\n * Field's `controlId` (it carries its own id, or is not the Field's first child, so\n * `<label htmlFor>` does not reach it), the consumer's ids plus the Field's `labelId`.\n * - `aria-describedby`: the consumer's ids, then the Field's validation message\n * (`validationMessageId`, else `errorId`), then its hint (deduplicated). A warning, success or\n * neutral message describes the control too.\n * - `aria-invalid` / `aria-required`: the consumer's value, else `true` when the Field is\n * invalid/required (`aria-required`: not when the consumer passes `required={false}`). Only the\n * `error` validation state makes the Field invalid.\n * - `required`: only with `nativeRequired` — the consumer's value, else the Field's `required`.\n * - `aria-label`: passed through.\n *\n * @example\n * const fieldProps = useFieldControl({ id, 'aria-label': ariaLabel, 'aria-labelledby': labelledBy,\n * 'aria-describedby': describedBy, 'aria-invalid': ariaInvalid, 'aria-required': ariaRequired });\n * return <button role=\"switch\" {...fieldProps} />;\n */\nexport function useFieldControl(\n props: FieldControlProps,\n options: UseFieldControlOptions = {},\n): FieldControlProps {\n const field = useFieldContext();\n // Always called (stable hook order); used only when the Field's controlId is taken. It is also\n // the control's token in the Field's controlIdClaim.\n const fallbackId = useId('field-control');\n const { labelable = true, nativeRequired = false } = options;\n\n // A control without an id of its own wants the Field's controlId unless Field gave it to its\n // first child. With a claim, only the first such control takes it.\n const wantsControlId = field !== null && props.id === undefined && !field.controlIdAssigned;\n const claim = wantsControlId ? field.controlIdClaim : undefined;\n // Re-render when the controlId is freed, so the next control takes it over.\n React.useSyncExternalStore(\n claim ? claim.subscribe : subscribeNothing,\n claim ? claim.getVersion : noVersion,\n claim ? claim.getVersion : noVersion,\n );\n const holdsControlId = wantsControlId && (claim ? claim.claim(fallbackId) : true);\n // Layout effects do nothing on the server, and React 19 no longer warns about them there.\n React.useLayoutEffect(() => claim?.mount(fallbackId), [claim, fallbackId]);\n React.useLayoutEffect(() => {\n if (claim && holdsControlId) claim.hold(fallbackId);\n }, [claim, holdsControlId, fallbackId]);\n // After every commit (all layout effects of the commit, and so every mount, have run): a\n // control rendered without controlId frees one held by a render that never committed.\n React.useEffect(() => {\n if (claim && !holdsControlId) claim.releaseStale();\n });\n\n const id =\n props.id ?? (field === null ? undefined : holdsControlId ? field.controlId : fallbackId);\n\n let labelledBy = props['aria-labelledby'];\n if (field && props['aria-label'] === undefined && (!labelable || id !== field.controlId)) {\n labelledBy = joinIds(labelledBy, field.labelId);\n }\n\n // The message in any validation state (a context built before 0.6 has only `errorId`).\n const describedBy = field\n ? joinIds(props['aria-describedby'], field.validationMessageId ?? field.errorId, field.hintId)\n : props['aria-describedby'];\n const invalid = props['aria-invalid'] ?? (field?.invalid || undefined);\n // A consumer `required={false}` (native controls pass `required`) also keeps the Field's\n // required state out of aria-required, so the announced state matches native validation.\n const ariaRequired =\n props['aria-required'] ?? (props.required === false ? undefined : field?.required || undefined);\n const required = nativeRequired ? (props.required ?? (field?.required || undefined)) : undefined;\n\n const result: FieldControlProps = {};\n if (id !== undefined) result.id = id;\n if (props['aria-label'] !== undefined) result['aria-label'] = props['aria-label'];\n if (labelledBy !== undefined) result['aria-labelledby'] = labelledBy;\n if (describedBy !== undefined) result['aria-describedby'] = describedBy;\n if (invalid !== undefined) result['aria-invalid'] = invalid;\n if (ariaRequired !== undefined) result['aria-required'] = ariaRequired;\n if (required !== undefined) result.required = required;\n return result;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";let e=require("react");function t(e){return typeof window>`u`||typeof window.matchMedia!=`function`?null:window.matchMedia(e)}function n(){return!1}function r(r){let i=(0,e.useCallback)(e=>{let n=t(r);return n?typeof n.addEventListener==`function`?(n.addEventListener(`change`,e),()=>n.removeEventListener(`change`,e)):(n.addListener(e),()=>n.removeListener(e)):()=>{}},[r]),a=(0,e.useCallback)(()=>t(r)?.matches??!1,[r]);return(0,e.useSyncExternalStore)(i,a,n)}exports.useMediaQuery=r;
|
|
2
|
+
//# sourceMappingURL=useMediaQuery.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useMediaQuery.cjs","names":["useCallback","useSyncExternalStore","react","getMediaQueryList","query","getServerSnapshot","useMediaQuery","subscribe","mql","notify","getSnapshot"],"sources":["../../src/hooks/useMediaQuery.ts"],"sourcesContent":["import { useCallback, useSyncExternalStore } from 'react';\n\nfunction getMediaQueryList(query: string): MediaQueryList | null {\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') return null;\n return window.matchMedia(query);\n}\n\nfunction getServerSnapshot(): boolean {\n return false;\n}\n\n/**\n * `true` while `query` matches, updated when the answer changes. `false` on the server and where\n * `matchMedia` is unavailable. Internal: shared `useSyncExternalStore` plumbing for hooks and\n * components that need one media query, so they never duplicate it (`usePrefersReducedMotion`,\n * ColorArea's coarse-primary-pointer check).\n */\nexport function useMediaQuery(query: string): boolean {\n const subscribe = useCallback(\n (notify: () => void): (() => void) => {\n const mql = getMediaQueryList(query);\n if (!mql) return () => {};\n if (typeof mql.addEventListener === 'function') {\n mql.addEventListener('change', notify);\n return () => mql.removeEventListener('change', notify);\n }\n // Safari < 14\n mql.addListener(notify);\n return () => mql.removeListener(notify);\n },\n [query],\n );\n const getSnapshot = useCallback(() => getMediaQueryList(query)?.matches ?? false, [query]);\n return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n}\n"],"mappings":"oCAEA,SAASG,EAAkB,EAAsC,CAE/D,OADI,OAAO,OAAW,KAAe,OAAO,OAAO,YAAe,WAAmB,KAC9E,OAAO,WAAWC,CAAK,CAChC,CAEA,SAASC,GAA6B,CACpC,MAAO,EACT,CAQA,SAAgBC,EAAc,EAAwB,CACpD,IAAMC,GAAA,EAAYP,EAAAA,YAAAA,CACf,GAAqC,CACpC,IAAMQ,EAAML,EAAkBC,CAAK,EAQnC,OAPKI,EACD,OAAOA,EAAI,kBAAqB,YAClCA,EAAI,iBAAiB,SAAUC,CAAM,MACxBD,EAAI,oBAAoB,SAAUC,CAAM,IAGvDD,EAAI,YAAYC,CAAM,MACTD,EAAI,eAAeC,CAAM,OAPf,CAAC,CAQ1B,EACA,CAACL,CAAK,CACR,EACMM,GAAA,EAAcV,EAAAA,YAAAA,KAAkBG,EAAkBC,CAAK,CAAC,EAAE,SAAW,GAAO,CAACA,CAAK,CAAC,EACzF,OAAA,EAAOH,EAAAA,qBAAAA,CAAqBM,EAAWG,EAAaL,CAAiB,CACvE"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useCallback as e, useSyncExternalStore as t } from "react";
|
|
3
|
+
//#region src/hooks/useMediaQuery.ts
|
|
4
|
+
function n(e) {
|
|
5
|
+
return typeof window > "u" || typeof window.matchMedia != "function" ? null : window.matchMedia(e);
|
|
6
|
+
}
|
|
7
|
+
function r() {
|
|
8
|
+
return !1;
|
|
9
|
+
}
|
|
10
|
+
function i(i) {
|
|
11
|
+
let a = e((e) => {
|
|
12
|
+
let t = n(i);
|
|
13
|
+
return t ? typeof t.addEventListener == "function" ? (t.addEventListener("change", e), () => t.removeEventListener("change", e)) : (t.addListener(e), () => t.removeListener(e)) : () => {};
|
|
14
|
+
}, [i]), o = e(() => n(i)?.matches ?? !1, [i]);
|
|
15
|
+
return t(a, o, r);
|
|
16
|
+
}
|
|
17
|
+
//#endregion
|
|
18
|
+
export { i as useMediaQuery };
|
|
19
|
+
|
|
20
|
+
//# sourceMappingURL=useMediaQuery.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useMediaQuery.mjs","names":["getMediaQueryList","query","getServerSnapshot","useMediaQuery","subscribe","useCallback","mql","notify","getSnapshot","useSyncExternalStore"],"sources":["../../src/hooks/useMediaQuery.ts"],"sourcesContent":["import { useCallback, useSyncExternalStore } from 'react';\n\nfunction getMediaQueryList(query: string): MediaQueryList | null {\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') return null;\n return window.matchMedia(query);\n}\n\nfunction getServerSnapshot(): boolean {\n return false;\n}\n\n/**\n * `true` while `query` matches, updated when the answer changes. `false` on the server and where\n * `matchMedia` is unavailable. Internal: shared `useSyncExternalStore` plumbing for hooks and\n * components that need one media query, so they never duplicate it (`usePrefersReducedMotion`,\n * ColorArea's coarse-primary-pointer check).\n */\nexport function useMediaQuery(query: string): boolean {\n const subscribe = useCallback(\n (notify: () => void): (() => void) => {\n const mql = getMediaQueryList(query);\n if (!mql) return () => {};\n if (typeof mql.addEventListener === 'function') {\n mql.addEventListener('change', notify);\n return () => mql.removeEventListener('change', notify);\n }\n // Safari < 14\n mql.addListener(notify);\n return () => mql.removeListener(notify);\n },\n [query],\n );\n const getSnapshot = useCallback(() => getMediaQueryList(query)?.matches ?? false, [query]);\n return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n}\n"],"mappings":";;;AAEA,SAASA,EAAkB,GAAsC;CAE/D,OADI,OAAO,SAAW,OAAe,OAAO,OAAO,cAAe,aAAmB,OAC9E,OAAO,WAAWC,CAAK;AAChC;AAEA,SAASC,IAA6B;CACpC,OAAO;AACT;AAQA,SAAgBC,EAAc,GAAwB;CACpD,IAAMC,IAAYC,GACf,MAAqC;EACpC,IAAMC,IAAMN,EAAkBC,CAAK;EAQnC,OAPKK,IACD,OAAOA,EAAI,oBAAqB,cAClCA,EAAI,iBAAiB,UAAUC,CAAM,SACxBD,EAAI,oBAAoB,UAAUC,CAAM,MAGvDD,EAAI,YAAYC,CAAM,SACTD,EAAI,eAAeC,CAAM,WAPf,CAAC;CAQ1B,GACA,CAACN,CAAK,CACR,GACMO,IAAcH,QAAkBL,EAAkBC,CAAK,CAAC,EAAE,WAAW,IAAO,CAACA,CAAK,CAAC;CACzF,OAAOQ,EAAqBL,GAAWI,GAAaN,CAAiB;AACvE"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";
|
|
1
|
+
"use client";const e=require("./useMediaQuery.cjs");function t(){return e.useMediaQuery(`(prefers-reduced-motion: reduce)`)}exports.usePrefersReducedMotion=t;
|
|
2
2
|
//# sourceMappingURL=usePrefersReducedMotion.cjs.map
|