@mitcsutt/kiln-ui 0.2.1 → 0.3.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 +6 -6
- package/dist/assets/fonts/archivo-latin-ext-wdth-italic.woff2 +0 -0
- package/dist/assets/fonts/archivo-latin-ext-wdth-normal.woff2 +0 -0
- package/dist/assets/fonts/archivo-latin-wdth-italic.woff2 +0 -0
- package/dist/assets/fonts/archivo-latin-wdth-normal.woff2 +0 -0
- package/dist/assets/fonts/atkinson-hyperlegible-mono-latin-ext-wght-italic.woff2 +0 -0
- package/dist/assets/fonts/atkinson-hyperlegible-mono-latin-ext-wght-normal.woff2 +0 -0
- package/dist/assets/fonts/atkinson-hyperlegible-mono-latin-wght-italic.woff2 +0 -0
- package/dist/assets/fonts/atkinson-hyperlegible-mono-latin-wght-normal.woff2 +0 -0
- package/dist/assets/fonts/b612-latin-400-italic.woff2 +0 -0
- package/dist/assets/fonts/b612-latin-400-normal.woff2 +0 -0
- package/dist/assets/fonts/b612-latin-700-italic.woff2 +0 -0
- package/dist/assets/fonts/b612-latin-700-normal.woff2 +0 -0
- package/dist/assets/fonts/b612-mono-latin-400-italic.woff2 +0 -0
- package/dist/assets/fonts/b612-mono-latin-400-normal.woff2 +0 -0
- package/dist/assets/fonts/b612-mono-latin-700-italic.woff2 +0 -0
- package/dist/assets/fonts/b612-mono-latin-700-normal.woff2 +0 -0
- package/dist/assets/fonts/golos-text-latin-ext-wght-normal.woff2 +0 -0
- package/dist/assets/fonts/golos-text-latin-wght-normal.woff2 +0 -0
- package/dist/assets/fonts/licenses/archivo.txt +93 -0
- package/dist/assets/fonts/licenses/atkinson-hyperlegible-mono.txt +93 -0
- package/dist/assets/fonts/licenses/b612-mono.txt +93 -0
- package/dist/assets/fonts/licenses/b612.txt +93 -0
- package/dist/assets/fonts/licenses/golos-text.txt +93 -0
- package/dist/assets/fonts/licenses/shantell-sans.txt +93 -0
- package/dist/assets/fonts/shantell-sans-latin-ext-full-italic.woff2 +0 -0
- package/dist/assets/fonts/shantell-sans-latin-ext-full-normal.woff2 +0 -0
- package/dist/assets/fonts/shantell-sans-latin-full-italic.woff2 +0 -0
- package/dist/assets/fonts/shantell-sans-latin-full-normal.woff2 +0 -0
- package/dist/components/actions/Button/Button.d.ts +8 -0
- package/dist/components/actions/Button/Button.js.map +1 -1
- package/dist/components/actions/ChipGroup/ChipGroup.d.ts +9 -0
- package/dist/components/actions/ChipGroup/ChipGroup.js.map +1 -1
- package/dist/components/actions/IconButton/IconButton.d.ts +8 -0
- package/dist/components/actions/IconButton/IconButton.js.map +1 -1
- package/dist/components/actions/ModeToggle/ModeToggle.d.ts +8 -0
- package/dist/components/actions/ModeToggle/ModeToggle.js.map +1 -1
- package/dist/components/actions/SegmentedControl/SegmentedControl.d.ts +9 -0
- package/dist/components/actions/SegmentedControl/SegmentedControl.js.map +1 -1
- package/dist/components/actions/ToggleChip/ToggleChip.d.ts +9 -0
- package/dist/components/actions/ToggleChip/ToggleChip.js.map +1 -1
- package/dist/components/display/Avatar/Avatar.d.ts +11 -1
- package/dist/components/display/Avatar/Avatar.js.map +1 -1
- package/dist/components/display/AvatarGroup/AvatarGroup.d.ts +7 -0
- package/dist/components/display/AvatarGroup/AvatarGroup.js.map +1 -1
- package/dist/components/display/Badge/Badge.d.ts +7 -0
- package/dist/components/display/Badge/Badge.js.map +1 -1
- package/dist/components/display/Card/Card.js.map +1 -1
- package/dist/components/display/CodeBlock/CodeBlock.d.ts +9 -0
- package/dist/components/display/CodeBlock/CodeBlock.js.map +1 -1
- package/dist/components/display/DataList/DataList.js.map +1 -1
- package/dist/components/display/Delta/Delta.d.ts +9 -0
- package/dist/components/display/Delta/Delta.js.map +1 -1
- package/dist/components/display/EmptyState/EmptyState.d.ts +8 -0
- package/dist/components/display/EmptyState/EmptyState.js.map +1 -1
- package/dist/components/display/List/List.js.map +1 -1
- package/dist/components/display/Marquee/Marquee.d.ts +8 -0
- package/dist/components/display/Marquee/Marquee.js.map +1 -1
- package/dist/components/display/Media/Media.d.ts +7 -0
- package/dist/components/display/Media/Media.js.map +1 -1
- package/dist/components/display/Meter/Meter.d.ts +9 -0
- package/dist/components/display/Meter/Meter.js.map +1 -1
- package/dist/components/display/Progress/Progress.d.ts +8 -0
- package/dist/components/display/Progress/Progress.js.map +1 -1
- package/dist/components/display/Skeleton/Skeleton.js.map +1 -1
- package/dist/components/display/Stamp/Stamp.d.ts +8 -0
- package/dist/components/display/Stamp/Stamp.js.map +1 -1
- package/dist/components/display/Stat/Stat.d.ts +8 -0
- package/dist/components/display/Stat/Stat.js.map +1 -1
- package/dist/components/display/Table/Table.js.map +1 -1
- package/dist/components/display/Tag/Tag.d.ts +7 -0
- package/dist/components/display/Tag/Tag.js.map +1 -1
- package/dist/components/feedback/Alert/Alert.d.ts +10 -0
- package/dist/components/feedback/Alert/Alert.js.map +1 -1
- package/dist/components/feedback/LiveIndicator/LiveIndicator.d.ts +7 -0
- package/dist/components/feedback/LiveIndicator/LiveIndicator.js.map +1 -1
- package/dist/components/feedback/RelativeTime/RelativeTime.d.ts +8 -0
- package/dist/components/feedback/RelativeTime/RelativeTime.js.map +1 -1
- package/dist/components/feedback/Spinner/Spinner.d.ts +10 -1
- package/dist/components/feedback/Spinner/Spinner.js.map +1 -1
- package/dist/components/feedback/StatusDot/StatusDot.d.ts +10 -1
- package/dist/components/feedback/StatusDot/StatusDot.js.map +1 -1
- package/dist/components/inputs/AmountField/AmountField.d.ts +7 -0
- package/dist/components/inputs/AmountField/AmountField.js.map +1 -1
- package/dist/components/inputs/AmountInput/AmountInput.d.ts +8 -0
- package/dist/components/inputs/AmountInput/AmountInput.js.map +1 -1
- package/dist/components/inputs/Checkbox/Checkbox.d.ts +8 -0
- package/dist/components/inputs/Checkbox/Checkbox.js.map +1 -1
- package/dist/components/inputs/CheckboxField/CheckboxField.d.ts +7 -0
- package/dist/components/inputs/CheckboxField/CheckboxField.js.map +1 -1
- package/dist/components/inputs/CheckboxGroup/CheckboxGroup.d.ts +8 -0
- package/dist/components/inputs/CheckboxGroup/CheckboxGroup.js.map +1 -1
- package/dist/components/inputs/CheckboxGroupField/CheckboxGroupField.d.ts +7 -0
- package/dist/components/inputs/CheckboxGroupField/CheckboxGroupField.js.map +1 -1
- package/dist/components/inputs/ChipGroupField/ChipGroupField.d.ts +7 -0
- package/dist/components/inputs/ChipGroupField/ChipGroupField.js.map +1 -1
- package/dist/components/inputs/ChoiceCards/ChoiceCards.d.ts +9 -0
- package/dist/components/inputs/ChoiceCards/ChoiceCards.js.map +1 -1
- package/dist/components/inputs/ChoiceCardsField/ChoiceCardsField.d.ts +7 -0
- package/dist/components/inputs/ChoiceCardsField/ChoiceCardsField.js.map +1 -1
- package/dist/components/inputs/ColorField/ColorField.d.ts +6 -0
- package/dist/components/inputs/ColorField/ColorField.js.map +1 -1
- package/dist/components/inputs/ColorInput/ColorInput.d.ts +8 -0
- package/dist/components/inputs/ColorInput/ColorInput.js.map +1 -1
- package/dist/components/inputs/Combobox/Combobox.d.ts +9 -0
- package/dist/components/inputs/Combobox/Combobox.js.map +1 -1
- package/dist/components/inputs/ComboboxField/ComboboxField.d.ts +7 -0
- package/dist/components/inputs/ComboboxField/ComboboxField.js.map +1 -1
- package/dist/components/inputs/DateRangeField/DateRangeField.d.ts +7 -0
- package/dist/components/inputs/DateRangeField/DateRangeField.js.map +1 -1
- package/dist/components/inputs/Field/Field.d.ts +26 -0
- package/dist/components/inputs/Field/Field.js.map +1 -1
- package/dist/components/inputs/Fieldset/Fieldset.d.ts +8 -0
- package/dist/components/inputs/Fieldset/Fieldset.js.map +1 -1
- package/dist/components/inputs/FileDrop/FileDrop.d.ts +10 -0
- package/dist/components/inputs/FileDrop/FileDrop.js.map +1 -1
- package/dist/components/inputs/FileField/FileField.d.ts +7 -0
- package/dist/components/inputs/FileField/FileField.js.map +1 -1
- package/dist/components/inputs/Input/Input.d.ts +9 -0
- package/dist/components/inputs/Input/Input.js.map +1 -1
- package/dist/components/inputs/NumberField/NumberField.d.ts +7 -0
- package/dist/components/inputs/NumberField/NumberField.js.map +1 -1
- package/dist/components/inputs/NumberInput/NumberInput.d.ts +8 -0
- package/dist/components/inputs/NumberInput/NumberInput.js.map +1 -1
- package/dist/components/inputs/OneTimeCodeField/OneTimeCodeField.d.ts +7 -0
- package/dist/components/inputs/OneTimeCodeField/OneTimeCodeField.js.map +1 -1
- package/dist/components/inputs/OneTimeCodeInput/OneTimeCodeInput.d.ts +8 -0
- package/dist/components/inputs/OneTimeCodeInput/OneTimeCodeInput.js.map +1 -1
- package/dist/components/inputs/PasswordField/PasswordField.d.ts +7 -0
- package/dist/components/inputs/PasswordField/PasswordField.js.map +1 -1
- package/dist/components/inputs/PasswordInput/PasswordInput.d.ts +10 -0
- package/dist/components/inputs/PasswordInput/PasswordInput.js.map +1 -1
- package/dist/components/inputs/RadioGroup/RadioGroup.d.ts +9 -0
- package/dist/components/inputs/RadioGroup/RadioGroup.js.map +1 -1
- package/dist/components/inputs/RadioGroupField/RadioGroupField.d.ts +8 -0
- package/dist/components/inputs/RadioGroupField/RadioGroupField.js.map +1 -1
- package/dist/components/inputs/RangeSlider/RangeSlider.d.ts +8 -0
- package/dist/components/inputs/RangeSlider/RangeSlider.js.map +1 -1
- package/dist/components/inputs/RangeSliderField/RangeSliderField.d.ts +7 -0
- package/dist/components/inputs/RangeSliderField/RangeSliderField.js.map +1 -1
- package/dist/components/inputs/Rating/Rating.d.ts +8 -0
- package/dist/components/inputs/Rating/Rating.js.map +1 -1
- package/dist/components/inputs/RatingField/RatingField.d.ts +7 -0
- package/dist/components/inputs/RatingField/RatingField.js.map +1 -1
- package/dist/components/inputs/SegmentedField/SegmentedField.d.ts +7 -0
- package/dist/components/inputs/SegmentedField/SegmentedField.js.map +1 -1
- package/dist/components/inputs/Select/Select.d.ts +9 -0
- package/dist/components/inputs/Select/Select.js.map +1 -1
- package/dist/components/inputs/SelectField/SelectField.d.ts +7 -0
- package/dist/components/inputs/SelectField/SelectField.js.map +1 -1
- package/dist/components/inputs/Slider/Slider.d.ts +8 -0
- package/dist/components/inputs/Slider/Slider.js.map +1 -1
- package/dist/components/inputs/SliderField/SliderField.d.ts +7 -0
- package/dist/components/inputs/SliderField/SliderField.js.map +1 -1
- package/dist/components/inputs/Switch/Switch.d.ts +8 -0
- package/dist/components/inputs/Switch/Switch.js.map +1 -1
- package/dist/components/inputs/SwitchField/SwitchField.d.ts +8 -0
- package/dist/components/inputs/SwitchField/SwitchField.js.map +1 -1
- package/dist/components/inputs/TagsField/TagsField.d.ts +6 -0
- package/dist/components/inputs/TagsField/TagsField.js.map +1 -1
- package/dist/components/inputs/TagsInput/TagsInput.d.ts +8 -0
- package/dist/components/inputs/TagsInput/TagsInput.js.map +1 -1
- package/dist/components/inputs/TextField/TextField.d.ts +8 -0
- package/dist/components/inputs/TextField/TextField.js.map +1 -1
- package/dist/components/inputs/Textarea/Textarea.d.ts +8 -0
- package/dist/components/inputs/Textarea/Textarea.js.map +1 -1
- package/dist/components/inputs/TextareaField/TextareaField.d.ts +7 -0
- package/dist/components/inputs/TextareaField/TextareaField.js.map +1 -1
- package/dist/components/layout/ActionBar/ActionBar.d.ts +7 -0
- package/dist/components/layout/ActionBar/ActionBar.js.map +1 -1
- package/dist/components/layout/AppShell/AppShell.js.map +1 -1
- package/dist/components/layout/AspectRatio/AspectRatio.d.ts +8 -0
- package/dist/components/layout/AspectRatio/AspectRatio.js.map +1 -1
- package/dist/components/layout/Box/Box.d.ts +8 -0
- package/dist/components/layout/Box/Box.js.map +1 -1
- package/dist/components/layout/Container/Container.d.ts +17 -0
- package/dist/components/layout/Container/Container.js.map +1 -1
- package/dist/components/layout/Divider/Divider.d.ts +7 -0
- package/dist/components/layout/Divider/Divider.js.map +1 -1
- package/dist/components/layout/Grid/Grid.d.ts +9 -0
- package/dist/components/layout/Grid/Grid.js.map +1 -1
- package/dist/components/layout/Inline/Inline.d.ts +8 -0
- package/dist/components/layout/Inline/Inline.js.map +1 -1
- package/dist/components/layout/Section/Section.d.ts +15 -0
- package/dist/components/layout/Section/Section.js.map +1 -1
- package/dist/components/layout/Split/Split.d.ts +9 -0
- package/dist/components/layout/Split/Split.js.map +1 -1
- package/dist/components/layout/Stack/Stack.d.ts +12 -0
- package/dist/components/layout/Stack/Stack.js.map +1 -1
- package/dist/components/layout/VisuallyHidden/VisuallyHidden.d.ts +7 -0
- package/dist/components/layout/VisuallyHidden/VisuallyHidden.js.map +1 -1
- package/dist/components/navigation/Accordion/Accordion.d.ts +7 -0
- package/dist/components/navigation/Accordion/Accordion.js.map +1 -1
- package/dist/components/navigation/BottomNav/BottomNav.d.ts +9 -0
- package/dist/components/navigation/BottomNav/BottomNav.js.map +1 -1
- package/dist/components/navigation/NavLinks/NavLinks.d.ts +9 -0
- package/dist/components/navigation/NavLinks/NavLinks.js.map +1 -1
- package/dist/components/navigation/Stepper/Stepper.d.ts +7 -0
- package/dist/components/navigation/Stepper/Stepper.js.map +1 -1
- package/dist/components/navigation/Tabs/Tabs.d.ts +8 -0
- package/dist/components/navigation/Tabs/Tabs.js.map +1 -1
- package/dist/components/overlays/Dialog/Dialog.d.ts +13 -0
- package/dist/components/overlays/Dialog/Dialog.js.map +1 -1
- package/dist/components/overlays/DropdownMenu/DropdownMenu.d.ts +8 -0
- package/dist/components/overlays/DropdownMenu/DropdownMenu.js.map +1 -1
- package/dist/components/overlays/Popover/Popover.d.ts +7 -0
- package/dist/components/overlays/Popover/Popover.js.map +1 -1
- package/dist/components/overlays/Sheet/Sheet.d.ts +8 -0
- package/dist/components/overlays/Sheet/Sheet.js.map +1 -1
- package/dist/components/overlays/Tooltip/Tooltip.d.ts +8 -0
- package/dist/components/overlays/Tooltip/Tooltip.js.map +1 -1
- package/dist/components/typography/Amount/Amount.d.ts +8 -0
- package/dist/components/typography/Amount/Amount.js.map +1 -1
- package/dist/components/typography/Code/Code.d.ts +8 -0
- package/dist/components/typography/Code/Code.js.map +1 -1
- package/dist/components/typography/Heading/Heading.d.ts +8 -0
- package/dist/components/typography/Heading/Heading.js.map +1 -1
- package/dist/components/typography/Kbd/Kbd.d.ts +6 -0
- package/dist/components/typography/Kbd/Kbd.js.map +1 -1
- package/dist/components/typography/Link/Link.d.ts +9 -0
- package/dist/components/typography/Link/Link.js.map +1 -1
- package/dist/components/typography/Numeral/Numeral.d.ts +8 -0
- package/dist/components/typography/Numeral/Numeral.js.map +1 -1
- package/dist/components/typography/Prose/Prose.d.ts +9 -0
- package/dist/components/typography/Prose/Prose.js.map +1 -1
- package/dist/components/typography/Quote/Quote.d.ts +7 -0
- package/dist/components/typography/Quote/Quote.js.map +1 -1
- package/dist/components/typography/SectionHeader/SectionHeader.d.ts +8 -0
- package/dist/components/typography/SectionHeader/SectionHeader.js.map +1 -1
- package/dist/components/typography/Text/Text.d.ts +8 -0
- package/dist/components/typography/Text/Text.js.map +1 -1
- package/dist/icons/Icon.d.ts +1 -1
- package/dist/icons/Icon.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/theme/ThemeProvider.d.ts +4 -4
- package/dist/theme/ThemeProvider.js.map +1 -1
- package/dist/theme/themes.d.ts +1 -1
- package/dist/theme/themes.js +15 -3
- package/dist/theme/themes.js.map +1 -1
- package/dist/themes/fiesta.css +1 -1
- package/dist/themes/flightdeck.css +1 -0
- package/dist/themes/ledger.css +1 -1
- package/dist/themes/monograph.css +1 -1
- package/dist/themes/riso.css +1 -0
- package/package.json +4 -2
- package/skills/custom-theme/SKILL.md +45 -43
- package/skills/custom-theme/references/colour.md +1 -1
- package/skills/custom-theme/references/motion.md +2 -2
- package/skills/custom-theme/references/tokens.md +42 -42
- package/skills/custom-theme/references/type.md +13 -10
- package/skills/design-rules/SKILL.md +31 -3
- package/skills/layout-composition/SKILL.md +27 -88
- package/skills/layout-composition/references/action-bar.md +3 -3
- package/skills/layout-composition/references/app-shell.md +10 -3
- package/skills/layout-composition/references/aspect-ratio.md +2 -0
- package/skills/layout-composition/references/box.md +6 -6
- package/skills/layout-composition/references/container.md +14 -12
- package/skills/layout-composition/references/divider.md +4 -4
- package/skills/layout-composition/references/section.md +69 -0
- package/skills/layout-composition/references/visually-hidden.md +3 -3
- package/skills/setup-and-theming/SKILL.md +10 -6
- package/skills/setup-and-theming/references/fiesta.md +3 -1
- package/skills/setup-and-theming/references/flightdeck.md +39 -0
- package/skills/setup-and-theming/references/ledger.md +7 -7
- package/skills/setup-and-theming/references/monograph.md +4 -0
- package/skills/setup-and-theming/references/paper.md +7 -7
- package/skills/setup-and-theming/references/riso.md +32 -0
|
@@ -21,6 +21,21 @@ export interface SectionProps extends HTMLAttributes<HTMLElement>, VisibilityPro
|
|
|
21
21
|
as?: SectionElement;
|
|
22
22
|
}
|
|
23
23
|
/**
|
|
24
|
+
* A full-bleed band of vertical space, with an optional surface and rules. Put a Container inside
|
|
25
|
+
* it for width.
|
|
26
|
+
*
|
|
27
|
+
* @remarks
|
|
28
|
+
* `Section` is how a page gets its rhythm: each band pads itself top and bottom with a step from
|
|
29
|
+
* the space scale, and can paint a surface across the full width. Width is the `Container`'s job,
|
|
30
|
+
* so a section is almost always `Section` then `Container`.
|
|
31
|
+
*
|
|
32
|
+
* ## Surfaces and bands
|
|
33
|
+
*
|
|
34
|
+
* `surface` is `canvas`, `surface`, `sunken`, `inverse` or `accent`. On `inverse` and `accent`,
|
|
35
|
+
* the colour roles flip for everything inside, so text, links, focus rings and buttons stay
|
|
36
|
+
* legible with no extra props. `divider` adds a rule at the `top`, `bottom` or `both`.
|
|
37
|
+
*
|
|
38
|
+
* @privateRemarks
|
|
24
39
|
* A full-bleed band of vertical rhythm. Put a `Container` inside for width.
|
|
25
40
|
*
|
|
26
41
|
* <Section space={{ base: 7, md: 9 }} surface="sunken" divider="both">
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Section.js","names":["styles","Section_module_default","Section","forwardRef","spaceProp","Comp","rest","cx","visibilityClass","className","surface","divider","mergeStyles","responsiveVars","space","style"],"sources":["../../../../src/components/layout/Section/Section.tsx"],"sourcesContent":["import { forwardRef, type HTMLAttributes } from 'react'\nimport { cx } from '#utils/cx'\nimport { mergeStyles, responsiveVars, type Responsive } from '#utils/responsive'\nimport { space, type Space } from '#utils/tokens'\nimport styles from './Section.module.css'\nimport { visibilityClass, type VisibilityProps } from '#utils/visibility'\n\nexport type SectionElement = 'section' | 'div' | 'article' | 'aside' | 'header' | 'footer'\nexport type SectionSurface = 'canvas' | 'surface' | 'sunken' | 'inverse' | 'accent'\nexport type SectionDivider = 'top' | 'bottom' | 'both'\n\nexport interface SectionProps extends HTMLAttributes<HTMLElement>, VisibilityProps {\n /**\n * Block padding (top and bottom), as a step on the space scale. Responsive.\n * Vary it: adjacent sections should not share the same step. Default `8`.\n */\n space?: Responsive<Space>\n /**\n * Full-bleed band colour. Omit to stay transparent on the canvas. `inverse` and\n * `accent` re-point the ink, line and focus colours so children stay legible.\n */\n surface?: SectionSurface\n /** A hairline across the full bleed at the top, bottom or both edges. */\n divider?: SectionDivider\n as?: SectionElement\n}\n\n/**\n * A full-bleed band of vertical rhythm. Put a `Container` inside for width.\n *\n * <Section space={{ base: 7, md: 9 }} surface=\"sunken\" divider=\"both\">\n * <Container>…</Container>\n * </Section>\n */\nexport const Section = forwardRef<HTMLElement, SectionProps>(function Section(\n {\n space: spaceProp,\n surface,\n divider,\n as: Comp = 'section',\n hideBelow,\n hideAbove,\n className,\n style,\n ...rest\n },\n ref,\n) {\n return (\n <Comp\n // @ts-expect-error — polymorphic ref across a union of intrinsic elements is safe here\n ref={ref}\n className={cx(styles.section, visibilityClass({ hideBelow, hideAbove }), className)}\n data-surface={surface}\n data-divider={divider}\n style={mergeStyles(responsiveVars('section-space', spaceProp, space), style)}\n {...rest}\n />\n )\n})\n"],"mappings":";;;;;;;;
|
|
1
|
+
{"version":3,"file":"Section.js","names":["styles","Section_module_default","Section","forwardRef","spaceProp","Comp","rest","cx","visibilityClass","className","surface","divider","mergeStyles","responsiveVars","space","style"],"sources":["../../../../src/components/layout/Section/Section.tsx"],"sourcesContent":["import { forwardRef, type HTMLAttributes } from 'react'\nimport { cx } from '#utils/cx'\nimport { mergeStyles, responsiveVars, type Responsive } from '#utils/responsive'\nimport { space, type Space } from '#utils/tokens'\nimport styles from './Section.module.css'\nimport { visibilityClass, type VisibilityProps } from '#utils/visibility'\n\nexport type SectionElement = 'section' | 'div' | 'article' | 'aside' | 'header' | 'footer'\nexport type SectionSurface = 'canvas' | 'surface' | 'sunken' | 'inverse' | 'accent'\nexport type SectionDivider = 'top' | 'bottom' | 'both'\n\nexport interface SectionProps extends HTMLAttributes<HTMLElement>, VisibilityProps {\n /**\n * Block padding (top and bottom), as a step on the space scale. Responsive.\n * Vary it: adjacent sections should not share the same step. Default `8`.\n */\n space?: Responsive<Space>\n /**\n * Full-bleed band colour. Omit to stay transparent on the canvas. `inverse` and\n * `accent` re-point the ink, line and focus colours so children stay legible.\n */\n surface?: SectionSurface\n /** A hairline across the full bleed at the top, bottom or both edges. */\n divider?: SectionDivider\n as?: SectionElement\n}\n\n/**\n * A full-bleed band of vertical space, with an optional surface and rules. Put a Container inside\n * it for width.\n *\n * @remarks\n * `Section` is how a page gets its rhythm: each band pads itself top and bottom with a step from\n * the space scale, and can paint a surface across the full width. Width is the `Container`'s job,\n * so a section is almost always `Section` then `Container`.\n *\n * ## Surfaces and bands\n *\n * `surface` is `canvas`, `surface`, `sunken`, `inverse` or `accent`. On `inverse` and `accent`,\n * the colour roles flip for everything inside, so text, links, focus rings and buttons stay\n * legible with no extra props. `divider` adds a rule at the `top`, `bottom` or `both`.\n *\n * @privateRemarks\n * A full-bleed band of vertical rhythm. Put a `Container` inside for width.\n *\n * <Section space={{ base: 7, md: 9 }} surface=\"sunken\" divider=\"both\">\n * <Container>…</Container>\n * </Section>\n */\nexport const Section = forwardRef<HTMLElement, SectionProps>(function Section(\n {\n space: spaceProp,\n surface,\n divider,\n as: Comp = 'section',\n hideBelow,\n hideAbove,\n className,\n style,\n ...rest\n },\n ref,\n) {\n return (\n <Comp\n // @ts-expect-error — polymorphic ref across a union of intrinsic elements is safe here\n ref={ref}\n className={cx(styles.section, visibilityClass({ hideBelow, hideAbove }), className)}\n data-surface={surface}\n data-divider={divider}\n style={mergeStyles(responsiveVars('section-space', spaceProp, space), style)}\n {...rest}\n />\n )\n})\n"],"mappings":";;;;;;;;AAiDA,IAAaE,IAAUC,EAAsC,SAC3D,EACE,OAAOC,GACP,YACA,YACA,IAAIC,IAAO,WACX,cACA,cACA,cACA,UACA,GAAGC,KAEL,GACA;CACA,OACE,kBAACD,GAAD;EAEO;EACL,WAAWE,EAAGP,EAAO,SAASQ,EAAgB;GAAE;GAAW;EAAU,CAAC,GAAGC,CAAS;EAClF,gBAAcC;EACd,gBAAcC;EACd,OAAOC,EAAYC,EAAe,iBAAiBT,GAAWU,CAAK,GAAGC,CAAK;EAC3E,GAAIT;CACL,CAAA;AAEL,CAAC"}
|
|
@@ -21,6 +21,15 @@ export interface SplitProps extends Omit<HTMLAttributes<HTMLElement>, 'children'
|
|
|
21
21
|
as?: SplitElement;
|
|
22
22
|
}
|
|
23
23
|
/**
|
|
24
|
+
* An asymmetric two-column layout that stacks on small screens. A heading beside its list, a label
|
|
25
|
+
* beside its content.
|
|
26
|
+
*
|
|
27
|
+
* @remarks
|
|
28
|
+
* `Split` takes exactly two children and puts them side by side in a ratio. Asymmetric splits read
|
|
29
|
+
* as designed; a 50/50 split of a heading and a list rarely does. Below `collapseBelow` (`md` by
|
|
30
|
+
* default) the two stack, first child on top.
|
|
31
|
+
*
|
|
32
|
+
* @privateRemarks
|
|
24
33
|
* An asymmetric two-column layout: a heading beside its list, a label hang column,
|
|
25
34
|
* media beside copy. Stacks below `collapseBelow`.
|
|
26
35
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Split.js","names":["styles","Split_module_default","columns","a","b","ratio","first","second","reverse","Split","forwardRef","Comp","rest","cx","className","collapseBelow","mergeStyles","responsiveVars","gap","space","align","alignCss","style"],"sources":["../../../../src/components/layout/Split/Split.tsx"],"sourcesContent":["import { forwardRef, type CSSProperties, type HTMLAttributes, type ReactNode } from 'react'\nimport { cx } from '#utils/cx'\nimport { mergeStyles, responsiveVars, type Responsive } from '#utils/responsive'\nimport { alignCss, space, type Align, type Space } from '#utils/tokens'\nimport styles from './Split.module.css'\n\n/** First : second, on a 12-column basis. */\nexport type SplitRatio = '1/1' | '1/2' | '2/1' | '1/3' | '3/1' | '5/7' | '7/5' | '4/8' | '8/4'\nexport type SplitCollapse = 'sm' | 'md' | 'lg'\nexport type SplitElement = 'div' | 'section' | 'article' | 'header' | 'footer'\n\nexport interface SplitProps extends Omit<HTMLAttributes<HTMLElement>, 'children'> {\n /** Width of the first child to the second. Default `5/7` — asymmetric on purpose. */\n ratio?: SplitRatio\n /** Stack the two children vertically below this breakpoint. Default `md`. */\n collapseBelow?: SplitCollapse\n /** Space between the two sides (and between them when stacked). Responsive. */\n gap?: Responsive<Space>\n /** Block-axis alignment of the two sides. Default `start`. Responsive. */\n align?: Responsive<Align>\n /** Put the second child first *visually* when split. DOM (and stacked) order is unchanged. */\n reverse?: boolean\n /** Exactly two children: the first and second side. */\n children: [ReactNode, ReactNode]\n as?: SplitElement\n}\n\nconst columns = (ratio: SplitRatio, reverse: boolean): string => {\n const [a, b] = ratio.split('/')\n const [first, second] = reverse ? [b, a] : [a, b]\n return `minmax(0, ${String(first)}fr) minmax(0, ${String(second)}fr)`\n}\n\n/**\n * An asymmetric two-column layout: a heading beside its list, a label hang column,\n * media beside copy. Stacks below `collapseBelow`.\n *\n * <Split ratio=\"5/7\" gap={{ base: 5, md: 7 }}>\n * <Heading>Recent releases</Heading>\n * <Stack dividers>…</Stack>\n * </Split>\n */\nexport const Split = forwardRef<HTMLElement, SplitProps>(function Split(\n {\n ratio = '5/7',\n collapseBelow = 'md',\n gap,\n align,\n reverse = false,\n as: Comp = 'div',\n className,\n style,\n children,\n ...rest\n },\n ref,\n) {\n return (\n <Comp\n // @ts-expect-error — polymorphic ref across a union of intrinsic elements is safe here\n ref={ref}\n className={cx(styles.split, className)}\n data-ratio={ratio}\n data-collapse-below={collapseBelow}\n data-reverse={reverse || undefined}\n style={mergeStyles(\n { '--split-columns': columns(ratio, reverse) } as CSSProperties,\n responsiveVars('split-gap', gap, space),\n responsiveVars('split-align', align, alignCss),\n style,\n )}\n {...rest}\n >\n {children}\n </Comp>\n )\n})\n"],"mappings":";;;;;;;AA2BA,IAAME,KAAW,GAAmB,MAA6B;CAC/D,IAAM,CAACC,GAAGC,KAAKC,EAAM,MAAM,GAAG,GACxB,CAACC,GAAOC,KAAUC,IAAU,CAACJ,GAAGD,CAAC,IAAI,CAACA,GAAGC,CAAC;CAChD,OAAO,aAAa,OAAOE,CAAK,EAAE,gBAAgB,OAAOC,CAAM,EAAE;AACnE,
|
|
1
|
+
{"version":3,"file":"Split.js","names":["styles","Split_module_default","columns","a","b","ratio","first","second","reverse","Split","forwardRef","Comp","rest","cx","className","collapseBelow","mergeStyles","responsiveVars","gap","space","align","alignCss","style"],"sources":["../../../../src/components/layout/Split/Split.tsx"],"sourcesContent":["import { forwardRef, type CSSProperties, type HTMLAttributes, type ReactNode } from 'react'\nimport { cx } from '#utils/cx'\nimport { mergeStyles, responsiveVars, type Responsive } from '#utils/responsive'\nimport { alignCss, space, type Align, type Space } from '#utils/tokens'\nimport styles from './Split.module.css'\n\n/** First : second, on a 12-column basis. */\nexport type SplitRatio = '1/1' | '1/2' | '2/1' | '1/3' | '3/1' | '5/7' | '7/5' | '4/8' | '8/4'\nexport type SplitCollapse = 'sm' | 'md' | 'lg'\nexport type SplitElement = 'div' | 'section' | 'article' | 'header' | 'footer'\n\nexport interface SplitProps extends Omit<HTMLAttributes<HTMLElement>, 'children'> {\n /** Width of the first child to the second. Default `5/7` — asymmetric on purpose. */\n ratio?: SplitRatio\n /** Stack the two children vertically below this breakpoint. Default `md`. */\n collapseBelow?: SplitCollapse\n /** Space between the two sides (and between them when stacked). Responsive. */\n gap?: Responsive<Space>\n /** Block-axis alignment of the two sides. Default `start`. Responsive. */\n align?: Responsive<Align>\n /** Put the second child first *visually* when split. DOM (and stacked) order is unchanged. */\n reverse?: boolean\n /** Exactly two children: the first and second side. */\n children: [ReactNode, ReactNode]\n as?: SplitElement\n}\n\nconst columns = (ratio: SplitRatio, reverse: boolean): string => {\n const [a, b] = ratio.split('/')\n const [first, second] = reverse ? [b, a] : [a, b]\n return `minmax(0, ${String(first)}fr) minmax(0, ${String(second)}fr)`\n}\n\n/**\n * An asymmetric two-column layout that stacks on small screens. A heading beside its list, a label\n * beside its content.\n *\n * @remarks\n * `Split` takes exactly two children and puts them side by side in a ratio. Asymmetric splits read\n * as designed; a 50/50 split of a heading and a list rarely does. Below `collapseBelow` (`md` by\n * default) the two stack, first child on top.\n *\n * @privateRemarks\n * An asymmetric two-column layout: a heading beside its list, a label hang column,\n * media beside copy. Stacks below `collapseBelow`.\n *\n * <Split ratio=\"5/7\" gap={{ base: 5, md: 7 }}>\n * <Heading>Recent releases</Heading>\n * <Stack dividers>…</Stack>\n * </Split>\n */\nexport const Split = forwardRef<HTMLElement, SplitProps>(function Split(\n {\n ratio = '5/7',\n collapseBelow = 'md',\n gap,\n align,\n reverse = false,\n as: Comp = 'div',\n className,\n style,\n children,\n ...rest\n },\n ref,\n) {\n return (\n <Comp\n // @ts-expect-error — polymorphic ref across a union of intrinsic elements is safe here\n ref={ref}\n className={cx(styles.split, className)}\n data-ratio={ratio}\n data-collapse-below={collapseBelow}\n data-reverse={reverse || undefined}\n style={mergeStyles(\n { '--split-columns': columns(ratio, reverse) } as CSSProperties,\n responsiveVars('split-gap', gap, space),\n responsiveVars('split-align', align, alignCss),\n style,\n )}\n {...rest}\n >\n {children}\n </Comp>\n )\n})\n"],"mappings":";;;;;;;AA2BA,IAAME,KAAW,GAAmB,MAA6B;CAC/D,IAAM,CAACC,GAAGC,KAAKC,EAAM,MAAM,GAAG,GACxB,CAACC,GAAOC,KAAUC,IAAU,CAACJ,GAAGD,CAAC,IAAI,CAACA,GAAGC,CAAC;CAChD,OAAO,aAAa,OAAOE,CAAK,EAAE,gBAAgB,OAAOC,CAAM,EAAE;AACnE,GAoBaE,IAAQC,EAAoC,SACvD,EACE,WAAQ,OACR,mBAAgB,MAChB,QACA,UACA,aAAU,IACV,IAAIC,IAAO,OACX,cACA,UACA,aACA,GAAGC,KAEL,GACA;CACA,OACE,kBAACD,GAAD;EAEO;EACL,WAAWE,EAAGb,EAAO,OAAOc,CAAS;EACrC,cAAYT;EACZ,uBAAqBU;EACrB,gBAAcP,KAAW,KAAA;EACzB,OAAOQ,EACL,EAAE,mBAAmBd,EAAQG,GAAOG,CAAO,EAAE,GAC7CS,EAAe,aAAaC,GAAKC,CAAK,GACtCF,EAAe,eAAeG,GAAOC,CAAQ,GAC7CC,CACF;EACA,GAAIV;EAEH;CACG,CAAA;AAEV,CAAC"}
|
|
@@ -14,6 +14,18 @@ export interface StackProps extends HTMLAttributes<HTMLElement>, VisibilityProps
|
|
|
14
14
|
as?: StackElement;
|
|
15
15
|
}
|
|
16
16
|
/**
|
|
17
|
+
* A column of things with consistent space between them. The layout you'll reach for most.
|
|
18
|
+
*
|
|
19
|
+
* @remarks
|
|
20
|
+
* `Stack` lays its children out vertically with a gap from the space scale. Most screens are
|
|
21
|
+
* stacks of stacks, so most spacing in a Kiln app is a `gap` prop rather than a margin.
|
|
22
|
+
*
|
|
23
|
+
* ## Responsive gaps and elements
|
|
24
|
+
*
|
|
25
|
+
* `gap` and `align` take responsive values: `gap={{ base: 3, md: 4 }}`. Render a list with
|
|
26
|
+
* `as="ul"` (or `ol`) and list semantics are kept even though the bullets are gone.
|
|
27
|
+
*
|
|
28
|
+
* @privateRemarks
|
|
17
29
|
* Vertical flow. The most common layout: a column of things with consistent space.
|
|
18
30
|
*
|
|
19
31
|
* <Stack gap={{ base: 4, md: 6 }} dividers>…</Stack>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Stack.js","names":["styles","Stack_module_default","Stack","forwardRef","Comp","rest","cx","visibilityClass","className","dividers","mergeStyles","responsiveVars","gap","space","align","alignCss","style"],"sources":["../../../../src/components/layout/Stack/Stack.tsx"],"sourcesContent":["import { forwardRef, type HTMLAttributes } from 'react'\nimport { cx } from '#utils/cx'\nimport { mergeStyles, responsiveVars, type Responsive } from '#utils/responsive'\nimport { alignCss, space, type Align, type Space } from '#utils/tokens'\nimport styles from './Stack.module.css'\nimport { visibilityClass, type VisibilityProps } from '#utils/visibility'\n\nexport type StackElement =\n | 'div'\n | 'section'\n | 'article'\n | 'aside'\n | 'header'\n | 'footer'\n | 'main'\n | 'nav'\n | 'ul'\n | 'ol'\n | 'li'\n | 'form'\n | 'fieldset'\n\nexport interface StackProps extends HTMLAttributes<HTMLElement>, VisibilityProps {\n /** Space between children, as a step on the theme's space scale. Responsive. */\n gap?: Responsive<Space>\n /** Cross-axis alignment. Responsive. Default `stretch`. */\n align?: Responsive<Align>\n /** Draw a hairline rule between children (the rule sits in the middle of the gap). */\n dividers?: boolean\n /** Render as a different element. Lists get `role=\"list\"` semantics preserved. */\n as?: StackElement\n}\n\n/**\n * Vertical flow. The most common layout: a column of things with consistent space.\n *\n * <Stack gap={{ base: 4, md: 6 }} dividers>…</Stack>\n */\nexport const Stack = forwardRef<HTMLElement, StackProps>(function Stack(\n {\n gap,\n align,\n dividers = false,\n as: Comp = 'div',\n hideBelow,\n hideAbove,\n className,\n style,\n ...rest\n },\n ref,\n) {\n return (\n <Comp\n // @ts-expect-error — polymorphic ref across a union of intrinsic elements is safe here\n ref={ref}\n className={cx(styles.stack, visibilityClass({ hideBelow, hideAbove }), className)}\n data-dividers={dividers || undefined}\n role={Comp === 'ul' || Comp === 'ol' ? 'list' : undefined}\n style={mergeStyles(\n responsiveVars('stack-gap', gap, space),\n responsiveVars('stack-align', align, alignCss),\n style,\n )}\n {...rest}\n />\n )\n})\n"],"mappings":";;;;;;;;
|
|
1
|
+
{"version":3,"file":"Stack.js","names":["styles","Stack_module_default","Stack","forwardRef","Comp","rest","cx","visibilityClass","className","dividers","mergeStyles","responsiveVars","gap","space","align","alignCss","style"],"sources":["../../../../src/components/layout/Stack/Stack.tsx"],"sourcesContent":["import { forwardRef, type HTMLAttributes } from 'react'\nimport { cx } from '#utils/cx'\nimport { mergeStyles, responsiveVars, type Responsive } from '#utils/responsive'\nimport { alignCss, space, type Align, type Space } from '#utils/tokens'\nimport styles from './Stack.module.css'\nimport { visibilityClass, type VisibilityProps } from '#utils/visibility'\n\nexport type StackElement =\n | 'div'\n | 'section'\n | 'article'\n | 'aside'\n | 'header'\n | 'footer'\n | 'main'\n | 'nav'\n | 'ul'\n | 'ol'\n | 'li'\n | 'form'\n | 'fieldset'\n\nexport interface StackProps extends HTMLAttributes<HTMLElement>, VisibilityProps {\n /** Space between children, as a step on the theme's space scale. Responsive. */\n gap?: Responsive<Space>\n /** Cross-axis alignment. Responsive. Default `stretch`. */\n align?: Responsive<Align>\n /** Draw a hairline rule between children (the rule sits in the middle of the gap). */\n dividers?: boolean\n /** Render as a different element. Lists get `role=\"list\"` semantics preserved. */\n as?: StackElement\n}\n\n/**\n * A column of things with consistent space between them. The layout you'll reach for most.\n *\n * @remarks\n * `Stack` lays its children out vertically with a gap from the space scale. Most screens are\n * stacks of stacks, so most spacing in a Kiln app is a `gap` prop rather than a margin.\n *\n * ## Responsive gaps and elements\n *\n * `gap` and `align` take responsive values: `gap={{ base: 3, md: 4 }}`. Render a list with\n * `as=\"ul\"` (or `ol`) and list semantics are kept even though the bullets are gone.\n *\n * @privateRemarks\n * Vertical flow. The most common layout: a column of things with consistent space.\n *\n * <Stack gap={{ base: 4, md: 6 }} dividers>…</Stack>\n */\nexport const Stack = forwardRef<HTMLElement, StackProps>(function Stack(\n {\n gap,\n align,\n dividers = false,\n as: Comp = 'div',\n hideBelow,\n hideAbove,\n className,\n style,\n ...rest\n },\n ref,\n) {\n return (\n <Comp\n // @ts-expect-error — polymorphic ref across a union of intrinsic elements is safe here\n ref={ref}\n className={cx(styles.stack, visibilityClass({ hideBelow, hideAbove }), className)}\n data-dividers={dividers || undefined}\n role={Comp === 'ul' || Comp === 'ol' ? 'list' : undefined}\n style={mergeStyles(\n responsiveVars('stack-gap', gap, space),\n responsiveVars('stack-align', align, alignCss),\n style,\n )}\n {...rest}\n />\n )\n})\n"],"mappings":";;;;;;;;AAkDA,IAAaE,IAAQC,EAAoC,SACvD,EACE,QACA,UACA,cAAW,IACX,IAAIC,IAAO,OACX,cACA,cACA,cACA,UACA,GAAGC,KAEL,GACA;CACA,OACE,kBAACD,GAAD;EAEO;EACL,WAAWE,EAAGN,EAAO,OAAOO,EAAgB;GAAE;GAAW;EAAU,CAAC,GAAGC,CAAS;EAChF,iBAAeC,KAAY,KAAA;EAC3B,MAAML,MAAS,QAAQA,MAAS,OAAO,SAAS,KAAA;EAChD,OAAOM,EACLC,EAAe,aAAaC,GAAKC,CAAK,GACtCF,EAAe,eAAeG,GAAOC,CAAQ,GAC7CC,CACF;EACA,GAAIX;CACL,CAAA;AAEL,CAAC"}
|
|
@@ -12,6 +12,13 @@ export interface VisuallyHiddenProps extends HTMLAttributes<HTMLElement> {
|
|
|
12
12
|
href?: string;
|
|
13
13
|
}
|
|
14
14
|
/**
|
|
15
|
+
* Content that screen readers announce and sighted readers don't need to see.
|
|
16
|
+
*
|
|
17
|
+
* @remarks
|
|
18
|
+
* `VisuallyHidden` keeps text in the accessibility tree while hiding it from view: the rest of a
|
|
19
|
+
* sentence a glyph implies, a heading the layout already makes obvious, a table caption.
|
|
20
|
+
*
|
|
21
|
+
* @privateRemarks
|
|
15
22
|
* Content for screen readers only: a label for an icon-only control, a table caption,
|
|
16
23
|
* a heading that the visual layout already implies.
|
|
17
24
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VisuallyHidden.js","names":["styles","VisuallyHidden_module_default","VisuallyHidden","forwardRef","Comp","rest","cx","className","focusable"],"sources":["../../../../src/components/layout/VisuallyHidden/VisuallyHidden.tsx"],"sourcesContent":["import { forwardRef, type HTMLAttributes } from 'react'\nimport { cx } from '#utils/cx'\nimport styles from './VisuallyHidden.module.css'\n\nexport type VisuallyHiddenElement = 'span' | 'div' | 'a' | 'h1' | 'h2' | 'h3' | 'label'\n\nexport interface VisuallyHiddenProps extends HTMLAttributes<HTMLElement> {\n /**\n * Reveal the content while it (or something inside it) has keyboard focus —\n * for skip links and other keyboard-only affordances.\n */\n focusable?: boolean\n /** Default `span`. */\n as?: VisuallyHiddenElement\n /** Only for `as=\"a\"`. */\n href?: string\n}\n\n/**\n * Content for screen readers only: a label for an icon-only control, a table caption,\n * a heading that the visual layout already implies.\n *\n * <VisuallyHidden as=\"h2\">Open invoices</VisuallyHidden>\n */\nexport const VisuallyHidden = forwardRef<HTMLElement, VisuallyHiddenProps>(function VisuallyHidden(\n { focusable = false, as: Comp = 'span', className, ...rest },\n ref,\n) {\n return (\n <Comp\n // @ts-expect-error — polymorphic ref across a union of intrinsic elements is safe here\n ref={ref}\n className={cx(styles.hidden, className)}\n data-focusable={focusable || undefined}\n {...rest}\n />\n )\n})\n"],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"VisuallyHidden.js","names":["styles","VisuallyHidden_module_default","VisuallyHidden","forwardRef","Comp","rest","cx","className","focusable"],"sources":["../../../../src/components/layout/VisuallyHidden/VisuallyHidden.tsx"],"sourcesContent":["import { forwardRef, type HTMLAttributes } from 'react'\nimport { cx } from '#utils/cx'\nimport styles from './VisuallyHidden.module.css'\n\nexport type VisuallyHiddenElement = 'span' | 'div' | 'a' | 'h1' | 'h2' | 'h3' | 'label'\n\nexport interface VisuallyHiddenProps extends HTMLAttributes<HTMLElement> {\n /**\n * Reveal the content while it (or something inside it) has keyboard focus —\n * for skip links and other keyboard-only affordances.\n */\n focusable?: boolean\n /** Default `span`. */\n as?: VisuallyHiddenElement\n /** Only for `as=\"a\"`. */\n href?: string\n}\n\n/**\n * Content that screen readers announce and sighted readers don't need to see.\n *\n * @remarks\n * `VisuallyHidden` keeps text in the accessibility tree while hiding it from view: the rest of a\n * sentence a glyph implies, a heading the layout already makes obvious, a table caption.\n *\n * @privateRemarks\n * Content for screen readers only: a label for an icon-only control, a table caption,\n * a heading that the visual layout already implies.\n *\n * <VisuallyHidden as=\"h2\">Open invoices</VisuallyHidden>\n */\nexport const VisuallyHidden = forwardRef<HTMLElement, VisuallyHiddenProps>(function VisuallyHidden(\n { focusable = false, as: Comp = 'span', className, ...rest },\n ref,\n) {\n return (\n <Comp\n // @ts-expect-error — polymorphic ref across a union of intrinsic elements is safe here\n ref={ref}\n className={cx(styles.hidden, className)}\n data-focusable={focusable || undefined}\n {...rest}\n />\n )\n})\n"],"mappings":";;;;;AA+BA,IAAaE,IAAiBC,EAA6C,SACzE,EAAE,eAAY,IAAO,IAAIC,IAAO,QAAQ,cAAW,GAAGC,KACtD,GACA;CACA,OACE,kBAACD,GAAD;EAEO;EACL,WAAWE,EAAGN,EAAO,QAAQO,CAAS;EACtC,kBAAgBC,KAAa,KAAA;EAC7B,GAAIH;CACL,CAAA;AAEL,CAAC"}
|
|
@@ -16,6 +16,13 @@ export interface AccordionTriggerProps extends ComponentPropsWithoutRef<typeof A
|
|
|
16
16
|
}
|
|
17
17
|
export type AccordionContentProps = ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>;
|
|
18
18
|
/**
|
|
19
|
+
* Expandable sections with a turning chevron. Also Kiln's disclosure, for a single "why?" note.
|
|
20
|
+
*
|
|
21
|
+
* @remarks
|
|
22
|
+
* `Accordion` stacks sections whose content expands under their heading. It's Radix Accordion
|
|
23
|
+
* underneath, so triggers are buttons inside headings, and arrow keys move between them.
|
|
24
|
+
*
|
|
25
|
+
* @privateRemarks
|
|
19
26
|
* Radix Accordion: expandable sections with a rotating chevron and a height animation.
|
|
20
27
|
* Also the library's disclosure: use one `type="single"` item for an inline "why?" note.
|
|
21
28
|
* Single accordions are `collapsible` unless you pass `collapsible={false}`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Accordion.js","names":["Accordion","AccordionPrimitive","styles","Accordion_module_default","SizeContext","createContext","AccordionRoot","forwardRef","rest","props","size","Accordion","cx","className","variant","AccordionItem","AccordionTrigger","useContext","Heading","headingTag","level","ChevronDownIcon","AccordionContent","Accordion$1"],"sources":["../../../../src/components/navigation/Accordion/Accordion.tsx"],"sourcesContent":["import { createContext, forwardRef, useContext, type ComponentPropsWithoutRef } from 'react'\nimport { Accordion as AccordionPrimitive } from 'radix-ui'\nimport { cx } from '#utils/cx'\nimport { ChevronDownIcon } from '#icons'\nimport styles from './Accordion.module.css'\nimport { headingTag } from '#utils/heading'\n\nexport type AccordionVariant = 'divided' | 'contained'\nexport type AccordionSize = 'sm' | 'md'\n\ninterface AccordionOwnProps {\n /** `divided` (default): hairlines between items, no box. `contained`: a bordered surface. */\n variant?: AccordionVariant\n /** `sm` for inline notes (\"Why is this invoice overdue?\"); `md` for FAQs and sections. */\n size?: AccordionSize\n}\n\nexport type AccordionProps = (\n AccordionPrimitive.AccordionSingleProps | AccordionPrimitive.AccordionMultipleProps\n) &\n AccordionOwnProps\n\nconst SizeContext = createContext<AccordionSize>('md')\n\nconst AccordionRoot = forwardRef<HTMLDivElement, AccordionProps>(function Accordion(\n { variant = 'divided', size = 'md', className, ...rest },\n ref,\n) {\n const props = rest.type === 'single' ? { collapsible: true, ...rest } : rest // single items can close by default\n return (\n <SizeContext.Provider value={size}>\n <AccordionPrimitive.Root\n ref={ref}\n className={cx(styles.root, className)}\n data-variant={variant}\n data-size={size}\n {...props}\n />\n </SizeContext.Provider>\n )\n})\n\nexport type AccordionItemProps = ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>\n\nconst AccordionItem = forwardRef<HTMLDivElement, AccordionItemProps>(function AccordionItem(\n { className, ...rest },\n ref,\n) {\n return <AccordionPrimitive.Item ref={ref} className={cx(styles.item, className)} {...rest} />\n})\n\nexport interface AccordionTriggerProps extends ComponentPropsWithoutRef<\n typeof AccordionPrimitive.Trigger\n> {\n /** Heading level wrapping the trigger, for the document outline. Default 3. */\n level?: 2 | 3 | 4 | 5 | 6\n}\n\nconst AccordionTrigger = forwardRef<HTMLButtonElement, AccordionTriggerProps>(\n function AccordionTrigger({ level = 3, className, children, ...rest }, ref) {\n const size = useContext(SizeContext)\n const Heading = headingTag(level)\n return (\n <AccordionPrimitive.Header asChild>\n <Heading className={styles.header}>\n <AccordionPrimitive.Trigger\n ref={ref}\n className={cx(styles.trigger, className)}\n data-size={size}\n {...rest}\n >\n <span className={styles.triggerLabel}>{children}</span>\n <ChevronDownIcon className={styles.chevron} />\n </AccordionPrimitive.Trigger>\n </Heading>\n </AccordionPrimitive.Header>\n )\n },\n)\n\nexport type AccordionContentProps = ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>\n\nconst AccordionContent = forwardRef<HTMLDivElement, AccordionContentProps>(\n function AccordionContent({ className, children, ...rest }, ref) {\n const size = useContext(SizeContext)\n return (\n <AccordionPrimitive.Content\n ref={ref}\n className={cx(styles.content, className)}\n data-size={size}\n {...rest}\n >\n <div className={styles.contentInner}>{children}</div>\n </AccordionPrimitive.Content>\n )\n },\n)\n\n/**\n * Radix Accordion: expandable sections with a rotating chevron and a height animation.\n * Also the library's disclosure: use one `type=\"single\"` item for an inline \"why?\" note.\n * Single accordions are `collapsible` unless you pass `collapsible={false}`.\n *\n * <Accordion type=\"single\">\n * <Accordion.Item value=\"scoring\">\n * <Accordion.Trigger>How scoring works</Accordion.Trigger>\n * <Accordion.Content>…</Accordion.Content>\n * </Accordion.Item>\n * </Accordion>\n */\nexport const Accordion = Object.assign(AccordionRoot, {\n Item: AccordionItem,\n Trigger: AccordionTrigger,\n Content: AccordionContent,\n})\n"],"mappings":";;;;;;;;AAsBA,IAAMI,IAAcC,EAA6B,IAAI,GAE/CC,IAAgBC,EAA2C,SAC/D,EAAE,aAAU,WAAW,UAAO,MAAM,cAAW,GAAGC,KAClD,GACA;CACA,IAAMC,IAAQD,EAAK,SAAS,WAAW;EAAE,aAAa;EAAM,GAAGA;CAAK,IAAIA;CACxE,OACE,kBAACJ,EAAY,UAAb;EAAsB,OAAOM;EAC3B,UAAA,kBAACT,EAAmB,MAApB;GACO;GACL,WAAWW,EAAGV,EAAO,MAAMW,CAAS;GACpC,gBAAcC;GACd,aAAWJ;GACX,GAAID;EACL,CAAA;CACmB,CAAA;AAE1B,CAAC,GAIKM,IAAgBR,EAA+C,SACnE,EAAE,cAAW,GAAGC,KAChB,GACA;CACA,OAAO,kBAACP,EAAmB,MAApB;EAA8B;EAAK,WAAWW,EAAGV,EAAO,MAAMW,CAAS;EAAG,GAAIL;CAAO,CAAA;AAC9F,CAAC,GASKQ,IAAmBT,EACvB,SAA0B,EAAE,WAAQ,GAAG,cAAW,aAAU,GAAGC,KAAQ,GAAK;CAC1E,IAAME,IAAOO,EAAWb,CAAW,GAC7Bc,IAAUC,EAAWC,CAAK;CAChC,OACE,kBAACnB,EAAmB,QAApB;EAA2B,SAAA;EACzB,UAAA,kBAACiB,GAAD;GAAS,WAAWhB,EAAO;GACzB,UAAA,kBAACD,EAAmB,SAApB;IACO;IACL,WAAWW,EAAGV,EAAO,SAASW,CAAS;IACvC,aAAWH;IACX,GAAIF;IAJN,UAAA,CAME,kBAAC,QAAD;KAAM,WAAWN,EAAO;KAAe;IAAe,CAAA,GACtD,kBAACmB,GAAD,EAAiB,WAAWnB,EAAO,QAAU,CAAA,CACnB;;EACrB,CAAA;CACgB,CAAA;AAE/B,CACF,GAIMoB,IAAmBf,EACvB,SAA0B,EAAE,cAAW,aAAU,GAAGC,KAAQ,GAAK;CAC/D,IAAME,IAAOO,EAAWb,CAAW;CACnC,OACE,kBAACH,EAAmB,SAApB;EACO;EACL,WAAWW,EAAGV,EAAO,SAASW,CAAS;EACvC,aAAWH;EACX,GAAIF;EAEJ,UAAA,kBAAC,OAAD;GAAK,WAAWN,EAAO;GAAe;EAAc,CAAA;CAC1B,CAAA;AAEhC,CACF,
|
|
1
|
+
{"version":3,"file":"Accordion.js","names":["Accordion","AccordionPrimitive","styles","Accordion_module_default","SizeContext","createContext","AccordionRoot","forwardRef","rest","props","size","Accordion","cx","className","variant","AccordionItem","AccordionTrigger","useContext","Heading","headingTag","level","ChevronDownIcon","AccordionContent","Accordion$1"],"sources":["../../../../src/components/navigation/Accordion/Accordion.tsx"],"sourcesContent":["import { createContext, forwardRef, useContext, type ComponentPropsWithoutRef } from 'react'\nimport { Accordion as AccordionPrimitive } from 'radix-ui'\nimport { cx } from '#utils/cx'\nimport { ChevronDownIcon } from '#icons'\nimport styles from './Accordion.module.css'\nimport { headingTag } from '#utils/heading'\n\nexport type AccordionVariant = 'divided' | 'contained'\nexport type AccordionSize = 'sm' | 'md'\n\ninterface AccordionOwnProps {\n /** `divided` (default): hairlines between items, no box. `contained`: a bordered surface. */\n variant?: AccordionVariant\n /** `sm` for inline notes (\"Why is this invoice overdue?\"); `md` for FAQs and sections. */\n size?: AccordionSize\n}\n\nexport type AccordionProps = (\n AccordionPrimitive.AccordionSingleProps | AccordionPrimitive.AccordionMultipleProps\n) &\n AccordionOwnProps\n\nconst SizeContext = createContext<AccordionSize>('md')\n\nconst AccordionRoot = forwardRef<HTMLDivElement, AccordionProps>(function Accordion(\n { variant = 'divided', size = 'md', className, ...rest },\n ref,\n) {\n const props = rest.type === 'single' ? { collapsible: true, ...rest } : rest // single items can close by default\n return (\n <SizeContext.Provider value={size}>\n <AccordionPrimitive.Root\n ref={ref}\n className={cx(styles.root, className)}\n data-variant={variant}\n data-size={size}\n {...props}\n />\n </SizeContext.Provider>\n )\n})\n\nexport type AccordionItemProps = ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>\n\nconst AccordionItem = forwardRef<HTMLDivElement, AccordionItemProps>(function AccordionItem(\n { className, ...rest },\n ref,\n) {\n return <AccordionPrimitive.Item ref={ref} className={cx(styles.item, className)} {...rest} />\n})\n\nexport interface AccordionTriggerProps extends ComponentPropsWithoutRef<\n typeof AccordionPrimitive.Trigger\n> {\n /** Heading level wrapping the trigger, for the document outline. Default 3. */\n level?: 2 | 3 | 4 | 5 | 6\n}\n\nconst AccordionTrigger = forwardRef<HTMLButtonElement, AccordionTriggerProps>(\n function AccordionTrigger({ level = 3, className, children, ...rest }, ref) {\n const size = useContext(SizeContext)\n const Heading = headingTag(level)\n return (\n <AccordionPrimitive.Header asChild>\n <Heading className={styles.header}>\n <AccordionPrimitive.Trigger\n ref={ref}\n className={cx(styles.trigger, className)}\n data-size={size}\n {...rest}\n >\n <span className={styles.triggerLabel}>{children}</span>\n <ChevronDownIcon className={styles.chevron} />\n </AccordionPrimitive.Trigger>\n </Heading>\n </AccordionPrimitive.Header>\n )\n },\n)\n\nexport type AccordionContentProps = ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>\n\nconst AccordionContent = forwardRef<HTMLDivElement, AccordionContentProps>(\n function AccordionContent({ className, children, ...rest }, ref) {\n const size = useContext(SizeContext)\n return (\n <AccordionPrimitive.Content\n ref={ref}\n className={cx(styles.content, className)}\n data-size={size}\n {...rest}\n >\n <div className={styles.contentInner}>{children}</div>\n </AccordionPrimitive.Content>\n )\n },\n)\n\n/**\n * Expandable sections with a turning chevron. Also Kiln's disclosure, for a single \"why?\" note.\n *\n * @remarks\n * `Accordion` stacks sections whose content expands under their heading. It's Radix Accordion\n * underneath, so triggers are buttons inside headings, and arrow keys move between them.\n *\n * @privateRemarks\n * Radix Accordion: expandable sections with a rotating chevron and a height animation.\n * Also the library's disclosure: use one `type=\"single\"` item for an inline \"why?\" note.\n * Single accordions are `collapsible` unless you pass `collapsible={false}`.\n *\n * <Accordion type=\"single\">\n * <Accordion.Item value=\"scoring\">\n * <Accordion.Trigger>How scoring works</Accordion.Trigger>\n * <Accordion.Content>…</Accordion.Content>\n * </Accordion.Item>\n * </Accordion>\n */\nexport const Accordion = Object.assign(AccordionRoot, {\n Item: AccordionItem,\n Trigger: AccordionTrigger,\n Content: AccordionContent,\n})\n"],"mappings":";;;;;;;;AAsBA,IAAMI,IAAcC,EAA6B,IAAI,GAE/CC,IAAgBC,EAA2C,SAC/D,EAAE,aAAU,WAAW,UAAO,MAAM,cAAW,GAAGC,KAClD,GACA;CACA,IAAMC,IAAQD,EAAK,SAAS,WAAW;EAAE,aAAa;EAAM,GAAGA;CAAK,IAAIA;CACxE,OACE,kBAACJ,EAAY,UAAb;EAAsB,OAAOM;EAC3B,UAAA,kBAACT,EAAmB,MAApB;GACO;GACL,WAAWW,EAAGV,EAAO,MAAMW,CAAS;GACpC,gBAAcC;GACd,aAAWJ;GACX,GAAID;EACL,CAAA;CACmB,CAAA;AAE1B,CAAC,GAIKM,IAAgBR,EAA+C,SACnE,EAAE,cAAW,GAAGC,KAChB,GACA;CACA,OAAO,kBAACP,EAAmB,MAApB;EAA8B;EAAK,WAAWW,EAAGV,EAAO,MAAMW,CAAS;EAAG,GAAIL;CAAO,CAAA;AAC9F,CAAC,GASKQ,IAAmBT,EACvB,SAA0B,EAAE,WAAQ,GAAG,cAAW,aAAU,GAAGC,KAAQ,GAAK;CAC1E,IAAME,IAAOO,EAAWb,CAAW,GAC7Bc,IAAUC,EAAWC,CAAK;CAChC,OACE,kBAACnB,EAAmB,QAApB;EAA2B,SAAA;EACzB,UAAA,kBAACiB,GAAD;GAAS,WAAWhB,EAAO;GACzB,UAAA,kBAACD,EAAmB,SAApB;IACO;IACL,WAAWW,EAAGV,EAAO,SAASW,CAAS;IACvC,aAAWH;IACX,GAAIF;IAJN,UAAA,CAME,kBAAC,QAAD;KAAM,WAAWN,EAAO;KAAe;IAAe,CAAA,GACtD,kBAACmB,GAAD,EAAiB,WAAWnB,EAAO,QAAU,CAAA,CACnB;;EACrB,CAAA;CACgB,CAAA;AAE/B,CACF,GAIMoB,IAAmBf,EACvB,SAA0B,EAAE,cAAW,aAAU,GAAGC,KAAQ,GAAK;CAC/D,IAAME,IAAOO,EAAWb,CAAW;CACnC,OACE,kBAACH,EAAmB,SAApB;EACO;EACL,WAAWW,EAAGV,EAAO,SAASW,CAAS;EACvC,aAAWH;EACX,GAAIF;EAEJ,UAAA,kBAAC,OAAD;GAAK,WAAWN,EAAO;GAAe;EAAc,CAAA;CAC1B,CAAA;AAEhC,CACF,GAqBaF,IAAY,OAAO,OAAOM,GAAe;CACpD,MAAMS;CACN,SAASC;CACT,SAASM;AACX,CAAC"}
|
|
@@ -27,6 +27,15 @@ export interface BottomNavItemProps extends Omit<AnchorHTMLAttributes<HTMLAnchor
|
|
|
27
27
|
children?: ReactNode;
|
|
28
28
|
}
|
|
29
29
|
/**
|
|
30
|
+
* A phone's tab bar. Three to five destinations, icon over label, pinned to the bottom of the
|
|
31
|
+
* screen.
|
|
32
|
+
*
|
|
33
|
+
* @remarks
|
|
34
|
+
* `BottomNav` is the bar of destinations at the bottom of a phone screen. It's fixed to the bottom
|
|
35
|
+
* with room for the home indicator, and hidden from `md` up by default, where header `NavLinks`
|
|
36
|
+
* take over.
|
|
37
|
+
*
|
|
38
|
+
* @privateRemarks
|
|
30
39
|
* Mobile tab bar: 3–5 destinations, icon over label, pinned to the bottom with the
|
|
31
40
|
* safe-area inset. Hidden from `md` up by default, where `NavLinks` takes over.
|
|
32
41
|
* Pair the breakpoints: `<BottomNav hideAbove="md">` with `<NavLinks hideBelow="md">`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BottomNav.js","names":["styles","BottomNav_module_default","BottomNavRoot","forwardRef","rest","label","cx","className","hideAbove","position","BottomNavItem","Comp","asChild","Slot","count","badge","active","icon","BottomNav"],"sources":["../../../../src/components/navigation/BottomNav/BottomNav.tsx"],"sourcesContent":["import { forwardRef, type AnchorHTMLAttributes, type HTMLAttributes, type ReactNode } from 'react'\nimport { Slot } from 'radix-ui'\nimport { cx } from '#utils/cx'\nimport styles from './BottomNav.module.css'\n\nexport interface BottomNavProps extends HTMLAttributes<HTMLElement> {\n /** Names the landmark. Default \"Main\". */\n label?: string\n /**\n * Hide at and above this breakpoint, where a top nav takes over. Default `md`.\n * `false` keeps it at every width. Inside `AppShell.BottomBar`, use the shell's\n * `navBreakpoint` (default `lg`) so the bar and the nav leave together, and give the\n * desktop nav the matching `hideBelow`.\n */\n hideAbove?: 'md' | 'lg' | false\n /** `fixed` (default) pins it to the viewport bottom; `static` leaves it in flow. */\n position?: 'fixed' | 'static'\n}\n\nconst BottomNavRoot = forwardRef<HTMLElement, BottomNavProps>(function BottomNav(\n { label = 'Main', hideAbove = 'md', position = 'fixed', className, children, ...rest },\n ref,\n) {\n return (\n <nav\n ref={ref}\n aria-label={label}\n className={cx(styles.nav, className)}\n data-hide-above={hideAbove || undefined}\n data-position={position}\n {...rest}\n >\n <ul className={styles.list} role=\"list\">\n {children}\n </ul>\n </nav>\n )\n})\n\nexport interface BottomNavItemProps extends Omit<\n AnchorHTMLAttributes<HTMLAnchorElement>,\n 'children'\n> {\n icon: ReactNode\n /** Always visible — icon-only tab bars are guesswork. Keep it to one short word. */\n label: string\n active?: boolean\n /**\n * `true` for an unread dot; a number for a count (shown as 99+ above 99). The count is\n * announced after the label.\n */\n badge?: boolean | number\n /** Render the single child (e.g. a router `<Link>`) as the item. */\n asChild?: boolean\n children?: ReactNode\n}\n\nconst BottomNavItem = forwardRef<HTMLAnchorElement, BottomNavItemProps>(function BottomNavItem(\n { icon, label, active = false, badge, asChild = false, className, children, ...rest },\n ref,\n) {\n const Comp = asChild ? Slot.Root : 'a'\n const count = typeof badge === 'number' && badge > 0 ? badge : undefined\n return (\n <li className={styles.item}>\n <Comp\n ref={ref}\n className={cx(styles.link, className)}\n data-active={active || undefined}\n aria-current={active ? 'page' : undefined}\n {...rest}\n >\n <span className={styles.iconWrap} aria-hidden=\"true\">\n <span className={styles.icon}>{icon}</span>\n {count !== undefined ? (\n <span className={styles.badge} data-kind=\"count\">\n {count > 99 ? '99+' : count}\n </span>\n ) : badge === true ? (\n <span className={styles.badge} data-kind=\"dot\" />\n ) : null}\n </span>\n <span className={styles.label}>{label}</span>\n {count !== undefined ? (\n <span className={styles.srOnly}>{`, ${String(count)} new`}</span>\n ) : null}\n {badge === true ? <span className={styles.srOnly}>, new</span> : null}\n <Slot.Slottable>{children}</Slot.Slottable>\n </Comp>\n </li>\n )\n})\n\n/**\n * Mobile tab bar: 3–5 destinations, icon over label, pinned to the bottom with the\n * safe-area inset. Hidden from `md` up by default, where `NavLinks` takes over.\n * Pair the breakpoints: `<BottomNav hideAbove=\"md\">` with `<NavLinks hideBelow=\"md\">`.\n *\n * <BottomNav>\n * <BottomNav.Item asChild icon={<TableIcon />} label=\"Projects\" active>\n * <Link to=\"/projects\" />\n * </BottomNav.Item>\n * </BottomNav>\n */\nexport const BottomNav = Object.assign(BottomNavRoot, { Item: BottomNavItem })\n"],"mappings":";;;;;;AAmBA,IAAME,IAAgBC,EAAwC,SAC5D,EAAE,WAAQ,QAAQ,eAAY,MAAM,cAAW,SAAS,cAAW,aAAU,GAAGC,KAChF,GACA;CACA,OACE,kBAAC,OAAD;EACO;EACL,cAAYC;EACZ,WAAWC,EAAGN,EAAO,KAAKO,CAAS;EACnC,mBAAiBC,KAAa,KAAA;EAC9B,iBAAeC;EACf,GAAIL;EAEJ,UAAA,kBAAC,MAAD;GAAI,WAAWJ,EAAO;GAAM,MAAK;GAC9B;EACC,CAAA;CACD,CAAA;AAET,CAAC,GAoBKU,IAAgBP,EAAkD,SACtE,EAAE,SAAM,UAAO,YAAS,IAAO,UAAO,aAAU,IAAO,cAAW,aAAU,GAAGC,KAC/E,GACA;CACA,IAAMO,IAAOC,IAAUC,EAAK,OAAO,KAC7BC,IAAQ,OAAOC,KAAU,YAAYA,IAAQ,IAAIA,IAAQ,KAAA;CAC/D,OACE,kBAAC,MAAD;EAAI,WAAWf,EAAO;EACpB,UAAA,kBAACW,GAAD;GACO;GACL,WAAWL,EAAGN,EAAO,MAAMO,CAAS;GACpC,eAAaS,KAAU,KAAA;GACvB,gBAAcA,IAAS,SAAS,KAAA;GAChC,GAAIZ;GALN,UAAA;IAOE,kBAAC,QAAD;KAAM,WAAWJ,EAAO;KAAU,eAAY;KAA9C,UAAA,CACE,kBAAC,QAAD;MAAM,WAAWA,EAAO;MAAO,UAAAiB;KAAW,CAAA,GACzCH,MAAU,KAAA,IAIPC,MAAU,KACZ,kBAAC,QAAD;MAAM,WAAWf,EAAO;MAAO,aAAU;KAAO,CAAA,IAC9C,OALF,kBAAC,QAAD;MAAM,WAAWA,EAAO;MAAO,aAAU;MACtC,UAAAc,IAAQ,KAAK,QAAQA;KAClB,CAAA,CAIJ;;IACN,kBAAC,QAAD;KAAM,WAAWd,EAAO;KAAQ,UAAAK;IAAY,CAAA;IAC3CS,MAAU,KAAA,IAEP,OADF,kBAAC,QAAD;KAAM,WAAWd,EAAO;KAAS,UAAA,KAAK,OAAOc,CAAK,EAAE;IAAY,CAAA;IAEjEC,MAAU,KAAO,kBAAC,QAAD;KAAM,WAAWf,EAAO;KAAQ,UAAA;IAAW,CAAA,IAAI;IACjE,kBAACa,EAAK,WAAN,EAAiB,YAAyB,CAAA;GACtC;;CACJ,CAAA;AAER,CAAC,
|
|
1
|
+
{"version":3,"file":"BottomNav.js","names":["styles","BottomNav_module_default","BottomNavRoot","forwardRef","rest","label","cx","className","hideAbove","position","BottomNavItem","Comp","asChild","Slot","count","badge","active","icon","BottomNav"],"sources":["../../../../src/components/navigation/BottomNav/BottomNav.tsx"],"sourcesContent":["import { forwardRef, type AnchorHTMLAttributes, type HTMLAttributes, type ReactNode } from 'react'\nimport { Slot } from 'radix-ui'\nimport { cx } from '#utils/cx'\nimport styles from './BottomNav.module.css'\n\nexport interface BottomNavProps extends HTMLAttributes<HTMLElement> {\n /** Names the landmark. Default \"Main\". */\n label?: string\n /**\n * Hide at and above this breakpoint, where a top nav takes over. Default `md`.\n * `false` keeps it at every width. Inside `AppShell.BottomBar`, use the shell's\n * `navBreakpoint` (default `lg`) so the bar and the nav leave together, and give the\n * desktop nav the matching `hideBelow`.\n */\n hideAbove?: 'md' | 'lg' | false\n /** `fixed` (default) pins it to the viewport bottom; `static` leaves it in flow. */\n position?: 'fixed' | 'static'\n}\n\nconst BottomNavRoot = forwardRef<HTMLElement, BottomNavProps>(function BottomNav(\n { label = 'Main', hideAbove = 'md', position = 'fixed', className, children, ...rest },\n ref,\n) {\n return (\n <nav\n ref={ref}\n aria-label={label}\n className={cx(styles.nav, className)}\n data-hide-above={hideAbove || undefined}\n data-position={position}\n {...rest}\n >\n <ul className={styles.list} role=\"list\">\n {children}\n </ul>\n </nav>\n )\n})\n\nexport interface BottomNavItemProps extends Omit<\n AnchorHTMLAttributes<HTMLAnchorElement>,\n 'children'\n> {\n icon: ReactNode\n /** Always visible — icon-only tab bars are guesswork. Keep it to one short word. */\n label: string\n active?: boolean\n /**\n * `true` for an unread dot; a number for a count (shown as 99+ above 99). The count is\n * announced after the label.\n */\n badge?: boolean | number\n /** Render the single child (e.g. a router `<Link>`) as the item. */\n asChild?: boolean\n children?: ReactNode\n}\n\nconst BottomNavItem = forwardRef<HTMLAnchorElement, BottomNavItemProps>(function BottomNavItem(\n { icon, label, active = false, badge, asChild = false, className, children, ...rest },\n ref,\n) {\n const Comp = asChild ? Slot.Root : 'a'\n const count = typeof badge === 'number' && badge > 0 ? badge : undefined\n return (\n <li className={styles.item}>\n <Comp\n ref={ref}\n className={cx(styles.link, className)}\n data-active={active || undefined}\n aria-current={active ? 'page' : undefined}\n {...rest}\n >\n <span className={styles.iconWrap} aria-hidden=\"true\">\n <span className={styles.icon}>{icon}</span>\n {count !== undefined ? (\n <span className={styles.badge} data-kind=\"count\">\n {count > 99 ? '99+' : count}\n </span>\n ) : badge === true ? (\n <span className={styles.badge} data-kind=\"dot\" />\n ) : null}\n </span>\n <span className={styles.label}>{label}</span>\n {count !== undefined ? (\n <span className={styles.srOnly}>{`, ${String(count)} new`}</span>\n ) : null}\n {badge === true ? <span className={styles.srOnly}>, new</span> : null}\n <Slot.Slottable>{children}</Slot.Slottable>\n </Comp>\n </li>\n )\n})\n\n/**\n * A phone's tab bar. Three to five destinations, icon over label, pinned to the bottom of the\n * screen.\n *\n * @remarks\n * `BottomNav` is the bar of destinations at the bottom of a phone screen. It's fixed to the bottom\n * with room for the home indicator, and hidden from `md` up by default, where header `NavLinks`\n * take over.\n *\n * @privateRemarks\n * Mobile tab bar: 3–5 destinations, icon over label, pinned to the bottom with the\n * safe-area inset. Hidden from `md` up by default, where `NavLinks` takes over.\n * Pair the breakpoints: `<BottomNav hideAbove=\"md\">` with `<NavLinks hideBelow=\"md\">`.\n *\n * <BottomNav>\n * <BottomNav.Item asChild icon={<TableIcon />} label=\"Projects\" active>\n * <Link to=\"/projects\" />\n * </BottomNav.Item>\n * </BottomNav>\n */\nexport const BottomNav = Object.assign(BottomNavRoot, { Item: BottomNavItem })\n"],"mappings":";;;;;;AAmBA,IAAME,IAAgBC,EAAwC,SAC5D,EAAE,WAAQ,QAAQ,eAAY,MAAM,cAAW,SAAS,cAAW,aAAU,GAAGC,KAChF,GACA;CACA,OACE,kBAAC,OAAD;EACO;EACL,cAAYC;EACZ,WAAWC,EAAGN,EAAO,KAAKO,CAAS;EACnC,mBAAiBC,KAAa,KAAA;EAC9B,iBAAeC;EACf,GAAIL;EAEJ,UAAA,kBAAC,MAAD;GAAI,WAAWJ,EAAO;GAAM,MAAK;GAC9B;EACC,CAAA;CACD,CAAA;AAET,CAAC,GAoBKU,IAAgBP,EAAkD,SACtE,EAAE,SAAM,UAAO,YAAS,IAAO,UAAO,aAAU,IAAO,cAAW,aAAU,GAAGC,KAC/E,GACA;CACA,IAAMO,IAAOC,IAAUC,EAAK,OAAO,KAC7BC,IAAQ,OAAOC,KAAU,YAAYA,IAAQ,IAAIA,IAAQ,KAAA;CAC/D,OACE,kBAAC,MAAD;EAAI,WAAWf,EAAO;EACpB,UAAA,kBAACW,GAAD;GACO;GACL,WAAWL,EAAGN,EAAO,MAAMO,CAAS;GACpC,eAAaS,KAAU,KAAA;GACvB,gBAAcA,IAAS,SAAS,KAAA;GAChC,GAAIZ;GALN,UAAA;IAOE,kBAAC,QAAD;KAAM,WAAWJ,EAAO;KAAU,eAAY;KAA9C,UAAA,CACE,kBAAC,QAAD;MAAM,WAAWA,EAAO;MAAO,UAAAiB;KAAW,CAAA,GACzCH,MAAU,KAAA,IAIPC,MAAU,KACZ,kBAAC,QAAD;MAAM,WAAWf,EAAO;MAAO,aAAU;KAAO,CAAA,IAC9C,OALF,kBAAC,QAAD;MAAM,WAAWA,EAAO;MAAO,aAAU;MACtC,UAAAc,IAAQ,KAAK,QAAQA;KAClB,CAAA,CAIJ;;IACN,kBAAC,QAAD;KAAM,WAAWd,EAAO;KAAQ,UAAAK;IAAY,CAAA;IAC3CS,MAAU,KAAA,IAEP,OADF,kBAAC,QAAD;KAAM,WAAWd,EAAO;KAAS,UAAA,KAAK,OAAOc,CAAK,EAAE;IAAY,CAAA;IAEjEC,MAAU,KAAO,kBAAC,QAAD;KAAM,WAAWf,EAAO;KAAQ,UAAA;IAAW,CAAA,IAAI;IACjE,kBAACa,EAAK,WAAN,EAAiB,YAAyB,CAAA;GACtC;;CACJ,CAAA;AAER,CAAC,GAsBYK,IAAY,OAAO,OAAOhB,GAAe,EAAE,MAAMQ,EAAc,CAAC"}
|
|
@@ -23,6 +23,15 @@ export interface NavLinksItemProps extends AnchorHTMLAttributes<HTMLAnchorElemen
|
|
|
23
23
|
asChild?: boolean;
|
|
24
24
|
}
|
|
25
25
|
/**
|
|
26
|
+
* A labelled navigation landmark with a list of links. Horizontal for headers, vertical for
|
|
27
|
+
* sidebars.
|
|
28
|
+
*
|
|
29
|
+
* @remarks
|
|
30
|
+
* `NavLinks` is a `<nav>` with a list of links. The current page is marked with a short accent bar
|
|
31
|
+
* under the label (horizontal) or an accent dot beside it (vertical), and gets
|
|
32
|
+
* `aria-current="page"`. These docs' header and sidebar are `NavLinks`.
|
|
33
|
+
*
|
|
34
|
+
* @privateRemarks
|
|
26
35
|
* Site / app navigation: a labelled `<nav>` with a list of links. The current page is
|
|
27
36
|
* marked with a short accent bar under the label (horizontal) or an accent dot beside
|
|
28
37
|
* it (vertical) — a mark, not a glowing pill.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NavLinks.js","names":["styles","NavLinks_module_default","NavLinksContext","createContext","NavLinksRoot","forwardRef","rest","label","cx","visibilityClass","className","orientation","size","gap","space","NavLinksItem","useContext","Comp","asChild","Slot","active","NavLinks"],"sources":["../../../../src/components/navigation/NavLinks/NavLinks.tsx"],"sourcesContent":["import {\n createContext,\n forwardRef,\n useContext,\n type AnchorHTMLAttributes,\n type CSSProperties,\n type HTMLAttributes,\n} from 'react'\nimport { Slot } from 'radix-ui'\nimport { cx } from '#utils/cx'\nimport { space, type Space } from '#utils/tokens'\nimport { visibilityClass, type VisibilityProps } from '#utils/visibility'\nimport styles from './NavLinks.module.css'\n\nexport type NavLinksOrientation = 'horizontal' | 'vertical'\nexport type NavLinksSize = 'sm' | 'md'\n\nexport interface NavLinksProps extends HTMLAttributes<HTMLElement>, VisibilityProps {\n /** Names the landmark. Required when a page has more than one nav. Default \"Main\". */\n label?: string\n /** `horizontal` (default) for headers; `vertical` for sidebars and footers. */\n orientation?: NavLinksOrientation\n /**\n * Space between links, as a step on the space scale. Default `5` horizontal, `0`\n * vertical (vertical items are already a full control tall).\n */\n gap?: Space\n /** `md` (default) for page headers; `sm` for dense toolbars, footers and sub-navs. */\n size?: NavLinksSize\n}\n\ninterface NavLinksContextValue {\n orientation: NavLinksOrientation\n size: NavLinksSize\n}\n\nconst NavLinksContext = createContext<NavLinksContextValue>({\n orientation: 'horizontal',\n size: 'md',\n})\n\nconst NavLinksRoot = forwardRef<HTMLElement, NavLinksProps>(function NavLinks(\n {\n label = 'Main',\n orientation = 'horizontal',\n gap,\n size = 'md',\n hideBelow,\n hideAbove,\n className,\n children,\n ...rest\n },\n ref,\n) {\n return (\n <NavLinksContext.Provider value={{ orientation, size }}>\n <nav\n ref={ref}\n aria-label={label}\n className={cx(styles.nav, visibilityClass({ hideBelow, hideAbove }), className)}\n data-orientation={orientation}\n data-size={size}\n {...rest}\n >\n <ul\n className={styles.list}\n role=\"list\"\n style={gap === undefined ? undefined : ({ '--_gap': space(gap) } as CSSProperties)}\n >\n {children}\n </ul>\n </nav>\n </NavLinksContext.Provider>\n )\n})\n\nexport interface NavLinksItemProps\n extends AnchorHTMLAttributes<HTMLAnchorElement>, VisibilityProps {\n /** The current page. Sets `aria-current=\"page\"` and draws the marker. */\n active?: boolean\n /** Render the single child (e.g. a router `<Link>`) instead of an `<a>`. */\n asChild?: boolean\n}\n\n/**\n * One link. For router links: `<NavLinks.Item asChild active={isActive}><Link to=\"/work\">Work</Link></NavLinks.Item>`.\n * `hideBelow`/`hideAbove` hide the whole list item (e.g. a secondary link on phones).\n */\nconst NavLinksItem = forwardRef<HTMLAnchorElement, NavLinksItemProps>(function NavLinksItem(\n { active = false, asChild = false, hideBelow, hideAbove, className, ...rest },\n ref,\n) {\n const { orientation, size } = useContext(NavLinksContext)\n const Comp = asChild ? Slot.Root : 'a'\n return (\n <li className={cx(styles.item, visibilityClass({ hideBelow, hideAbove }))}>\n <Comp\n ref={ref}\n className={cx(styles.link, className)}\n data-orientation={orientation}\n data-size={size}\n data-active={active || undefined}\n aria-current={active ? 'page' : undefined}\n {...rest}\n />\n </li>\n )\n})\n\n/**\n * Site / app navigation: a labelled `<nav>` with a list of links. The current page is\n * marked with a short accent bar under the label (horizontal) or an accent dot beside\n * it (vertical) — a mark, not a glowing pill.\n */\nexport const NavLinks = Object.assign(NavLinksRoot, { Item: NavLinksItem })\n"],"mappings":";;;;;;;;AAoCA,IAAME,IAAkBC,EAAoC;CAC1D,aAAa;CACb,MAAM;AACR,CAAC,GAEKC,IAAeC,EAAuC,SAC1D,EACE,WAAQ,QACR,iBAAc,cACd,QACA,UAAO,MACP,cACA,cACA,cACA,aACA,GAAGC,KAEL,GACA;CACA,OACE,kBAACJ,EAAgB,UAAjB;EAA0B,OAAO;GAAE;GAAa;EAAK;EACnD,UAAA,kBAAC,OAAD;GACO;GACL,cAAYK;GACZ,WAAWC,EAAGR,EAAO,KAAKS,EAAgB;IAAE;IAAW;GAAU,CAAC,GAAGC,CAAS;GAC9E,oBAAkBC;GAClB,aAAWC;GACX,GAAIN;GAEJ,UAAA,kBAAC,MAAD;IACE,WAAWN,EAAO;IAClB,MAAK;IACL,OAAOa,MAAQ,KAAA,IAAY,KAAA,IAAa,EAAE,UAAUC,EAAMD,CAAG,EAAE;IAE9D;GACC,CAAA;EACD,CAAA;CACmB,CAAA;AAE9B,CAAC,GAcKE,IAAeV,EAAiD,SACpE,EAAE,YAAS,IAAO,aAAU,IAAO,cAAW,cAAW,cAAW,GAAGC,KACvE,GACA;CACA,IAAM,EAAE,gBAAa,YAASU,EAAWd,CAAe,GAClDe,IAAOC,IAAUC,EAAK,OAAO;CACnC,OACE,kBAAC,MAAD;EAAI,WAAWX,EAAGR,EAAO,MAAMS,EAAgB;GAAE;GAAW;EAAU,CAAC,CAAC;EACtE,UAAA,kBAACQ,GAAD;GACO;GACL,WAAWT,EAAGR,EAAO,MAAMU,CAAS;GACpC,oBAAkBC;GAClB,aAAWC;GACX,eAAaQ,KAAU,KAAA;GACvB,gBAAcA,IAAS,SAAS,KAAA;GAChC,GAAId;EACL,CAAA;CACC,CAAA;AAER,CAAC,
|
|
1
|
+
{"version":3,"file":"NavLinks.js","names":["styles","NavLinks_module_default","NavLinksContext","createContext","NavLinksRoot","forwardRef","rest","label","cx","visibilityClass","className","orientation","size","gap","space","NavLinksItem","useContext","Comp","asChild","Slot","active","NavLinks"],"sources":["../../../../src/components/navigation/NavLinks/NavLinks.tsx"],"sourcesContent":["import {\n createContext,\n forwardRef,\n useContext,\n type AnchorHTMLAttributes,\n type CSSProperties,\n type HTMLAttributes,\n} from 'react'\nimport { Slot } from 'radix-ui'\nimport { cx } from '#utils/cx'\nimport { space, type Space } from '#utils/tokens'\nimport { visibilityClass, type VisibilityProps } from '#utils/visibility'\nimport styles from './NavLinks.module.css'\n\nexport type NavLinksOrientation = 'horizontal' | 'vertical'\nexport type NavLinksSize = 'sm' | 'md'\n\nexport interface NavLinksProps extends HTMLAttributes<HTMLElement>, VisibilityProps {\n /** Names the landmark. Required when a page has more than one nav. Default \"Main\". */\n label?: string\n /** `horizontal` (default) for headers; `vertical` for sidebars and footers. */\n orientation?: NavLinksOrientation\n /**\n * Space between links, as a step on the space scale. Default `5` horizontal, `0`\n * vertical (vertical items are already a full control tall).\n */\n gap?: Space\n /** `md` (default) for page headers; `sm` for dense toolbars, footers and sub-navs. */\n size?: NavLinksSize\n}\n\ninterface NavLinksContextValue {\n orientation: NavLinksOrientation\n size: NavLinksSize\n}\n\nconst NavLinksContext = createContext<NavLinksContextValue>({\n orientation: 'horizontal',\n size: 'md',\n})\n\nconst NavLinksRoot = forwardRef<HTMLElement, NavLinksProps>(function NavLinks(\n {\n label = 'Main',\n orientation = 'horizontal',\n gap,\n size = 'md',\n hideBelow,\n hideAbove,\n className,\n children,\n ...rest\n },\n ref,\n) {\n return (\n <NavLinksContext.Provider value={{ orientation, size }}>\n <nav\n ref={ref}\n aria-label={label}\n className={cx(styles.nav, visibilityClass({ hideBelow, hideAbove }), className)}\n data-orientation={orientation}\n data-size={size}\n {...rest}\n >\n <ul\n className={styles.list}\n role=\"list\"\n style={gap === undefined ? undefined : ({ '--_gap': space(gap) } as CSSProperties)}\n >\n {children}\n </ul>\n </nav>\n </NavLinksContext.Provider>\n )\n})\n\nexport interface NavLinksItemProps\n extends AnchorHTMLAttributes<HTMLAnchorElement>, VisibilityProps {\n /** The current page. Sets `aria-current=\"page\"` and draws the marker. */\n active?: boolean\n /** Render the single child (e.g. a router `<Link>`) instead of an `<a>`. */\n asChild?: boolean\n}\n\n/**\n * One link. For router links: `<NavLinks.Item asChild active={isActive}><Link to=\"/work\">Work</Link></NavLinks.Item>`.\n * `hideBelow`/`hideAbove` hide the whole list item (e.g. a secondary link on phones).\n */\nconst NavLinksItem = forwardRef<HTMLAnchorElement, NavLinksItemProps>(function NavLinksItem(\n { active = false, asChild = false, hideBelow, hideAbove, className, ...rest },\n ref,\n) {\n const { orientation, size } = useContext(NavLinksContext)\n const Comp = asChild ? Slot.Root : 'a'\n return (\n <li className={cx(styles.item, visibilityClass({ hideBelow, hideAbove }))}>\n <Comp\n ref={ref}\n className={cx(styles.link, className)}\n data-orientation={orientation}\n data-size={size}\n data-active={active || undefined}\n aria-current={active ? 'page' : undefined}\n {...rest}\n />\n </li>\n )\n})\n\n/**\n * A labelled navigation landmark with a list of links. Horizontal for headers, vertical for\n * sidebars.\n *\n * @remarks\n * `NavLinks` is a `<nav>` with a list of links. The current page is marked with a short accent bar\n * under the label (horizontal) or an accent dot beside it (vertical), and gets\n * `aria-current=\"page\"`. These docs' header and sidebar are `NavLinks`.\n *\n * @privateRemarks\n * Site / app navigation: a labelled `<nav>` with a list of links. The current page is\n * marked with a short accent bar under the label (horizontal) or an accent dot beside\n * it (vertical) — a mark, not a glowing pill.\n */\nexport const NavLinks = Object.assign(NavLinksRoot, { Item: NavLinksItem })\n"],"mappings":";;;;;;;;AAoCA,IAAME,IAAkBC,EAAoC;CAC1D,aAAa;CACb,MAAM;AACR,CAAC,GAEKC,IAAeC,EAAuC,SAC1D,EACE,WAAQ,QACR,iBAAc,cACd,QACA,UAAO,MACP,cACA,cACA,cACA,aACA,GAAGC,KAEL,GACA;CACA,OACE,kBAACJ,EAAgB,UAAjB;EAA0B,OAAO;GAAE;GAAa;EAAK;EACnD,UAAA,kBAAC,OAAD;GACO;GACL,cAAYK;GACZ,WAAWC,EAAGR,EAAO,KAAKS,EAAgB;IAAE;IAAW;GAAU,CAAC,GAAGC,CAAS;GAC9E,oBAAkBC;GAClB,aAAWC;GACX,GAAIN;GAEJ,UAAA,kBAAC,MAAD;IACE,WAAWN,EAAO;IAClB,MAAK;IACL,OAAOa,MAAQ,KAAA,IAAY,KAAA,IAAa,EAAE,UAAUC,EAAMD,CAAG,EAAE;IAE9D;GACC,CAAA;EACD,CAAA;CACmB,CAAA;AAE9B,CAAC,GAcKE,IAAeV,EAAiD,SACpE,EAAE,YAAS,IAAO,aAAU,IAAO,cAAW,cAAW,cAAW,GAAGC,KACvE,GACA;CACA,IAAM,EAAE,gBAAa,YAASU,EAAWd,CAAe,GAClDe,IAAOC,IAAUC,EAAK,OAAO;CACnC,OACE,kBAAC,MAAD;EAAI,WAAWX,EAAGR,EAAO,MAAMS,EAAgB;GAAE;GAAW;EAAU,CAAC,CAAC;EACtE,UAAA,kBAACQ,GAAD;GACO;GACL,WAAWT,EAAGR,EAAO,MAAMU,CAAS;GACpC,oBAAkBC;GAClB,aAAWC;GACX,eAAaQ,KAAU,KAAA;GACvB,gBAAcA,IAAS,SAAS,KAAA;GAChC,GAAId;EACL,CAAA;CACC,CAAA;AAER,CAAC,GAgBYe,IAAW,OAAO,OAAOjB,GAAc,EAAE,MAAMW,EAAa,CAAC"}
|
|
@@ -33,6 +33,13 @@ export interface StepperProps extends Omit<HTMLAttributes<HTMLOListElement>, 'on
|
|
|
33
33
|
};
|
|
34
34
|
}
|
|
35
35
|
/**
|
|
36
|
+
* Where you are in a multi-step flow. A step indicator, not a form control.
|
|
37
|
+
*
|
|
38
|
+
* @remarks
|
|
39
|
+
* `Stepper` shows the steps of a flow and which one you're on. It doesn't hold the form: drive it
|
|
40
|
+
* and the step content from the same state, and pair it with an `ActionBar` for back and next.
|
|
41
|
+
*
|
|
42
|
+
* @privateRemarks
|
|
36
43
|
* A step indicator for a multi-step flow — not a form control. Pair with `ActionBar`
|
|
37
44
|
* for the Back / Next / Submit row and drive both from the same current-step state.
|
|
38
45
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Stepper.js","names":["_Fragment","styles","Stepper_module_default","Fragment$1","defaultFormatCompact","index","total","label","resolveStatus","step","currentIndex","Stepper","forwardRef","rest","autoId","useId","baseId","id","steps","value","currentStep","completeSuffix","statusLabels","errorSuffix","cx","className","compactBelow","mergeStyles","style","formatCompact","orientation","status","hasErrors","stepId","marker","ErrorIcon","CheckIcon","inner","VisuallyHidden","onStepSelect"],"sources":["../../../../src/components/navigation/Stepper/Stepper.tsx"],"sourcesContent":["import { forwardRef, useId, type CSSProperties, type HTMLAttributes, type ReactNode } from 'react'\nimport { cx } from '#utils/cx'\nimport { mergeStyles } from '#utils/responsive'\nimport { CheckIcon, ErrorIcon } from '#icons'\nimport { VisuallyHidden } from '#components/layout/VisuallyHidden'\nimport styles from './Stepper.module.css'\n\nexport type StepperStatus = 'complete' | 'current' | 'upcoming' | 'error'\n\nexport interface StepperStep {\n /** Stable identifier — matched against `value` and passed to `onStepSelect`. */\n value: string\n label: ReactNode\n description?: ReactNode\n /** Overrides the status this step would otherwise derive from its position relative to `value`. */\n status?: StepperStatus\n /**\n * The step has errors. Independent of `status` (which keeps describing progress): an invalid\n * step gets the critical glyph and text, and the hidden error suffix in place of the complete one;\n * a current invalid step keeps `aria-current=\"step\"`. `status: 'error'` is the same treatment for a step whose progress\n * you don't report.\n */\n invalid?: boolean\n}\n\nexport interface StepperProps extends Omit<HTMLAttributes<HTMLOListElement>, 'onSelect'> {\n steps: readonly StepperStep[]\n /** The current step's `value` (`aria-current=\"step\"`). */\n value: string\n /** Steps become buttons when set — lets people jump to a visited or upcoming step. */\n onStepSelect?: (value: string) => void\n /** Default `horizontal`. */\n orientation?: 'horizontal' | 'vertical'\n /** Below this breakpoint, collapse to a single line of text (`formatCompact`). */\n compactBelow?: 'sm' | 'md'\n formatCompact?: (index: number, total: number, label: ReactNode) => ReactNode\n /** Visually-hidden suffixes announced after a step's label. */\n statusLabels?: { complete?: string; error?: string }\n}\n\nconst defaultFormatCompact = (index: number, total: number, label: ReactNode): ReactNode => (\n <>\n Step {index + 1} of {total} · {label}\n </>\n)\n\nfunction resolveStatus(step: StepperStep, index: number, currentIndex: number): StepperStatus {\n if (step.status) return step.status\n if (currentIndex < 0) return 'upcoming'\n if (index === currentIndex) return 'current'\n return index < currentIndex ? 'complete' : 'upcoming'\n}\n\n/**\n * A step indicator for a multi-step flow — not a form control. Pair with `ActionBar`\n * for the Back / Next / Submit row and drive both from the same current-step state.\n *\n * <Stepper\n * steps={[{ value: 'you', label: 'You' }, { value: 'team', label: 'Team' }]}\n * value={step}\n * onStepSelect={setStep}\n * />\n */\nexport const Stepper = forwardRef<HTMLOListElement, StepperProps>(function Stepper(\n {\n steps,\n value,\n onStepSelect,\n orientation = 'horizontal',\n compactBelow,\n formatCompact = defaultFormatCompact,\n statusLabels,\n className,\n id,\n style,\n ...rest\n },\n ref,\n) {\n const autoId = useId()\n const baseId = id ?? autoId\n const total = steps.length\n const currentIndex = steps.findIndex((step) => step.value === value)\n const currentStep = currentIndex >= 0 ? steps[currentIndex] : undefined\n const completeSuffix = statusLabels?.complete ?? 'completed'\n const errorSuffix = statusLabels?.error ?? 'has errors'\n\n return (\n <div\n className={cx(styles.root, className)}\n data-compact-below={compactBelow}\n style={mergeStyles({ '--_count': total } as CSSProperties, style)}\n >\n {compactBelow ? (\n <p className={styles.compact}>\n {formatCompact(Math.max(currentIndex, 0), total, currentStep?.label ?? '')}\n </p>\n ) : null}\n <ol ref={ref} id={baseId} className={styles.list} data-orientation={orientation} {...rest}>\n {steps.map((step, index) => {\n const status = resolveStatus(step, index, currentIndex)\n const hasErrors = status === 'error' || step.invalid === true\n const stepId = `${baseId}-${step.value}`\n const marker = hasErrors ? (\n <ErrorIcon size=\"sm\" />\n ) : status === 'complete' ? (\n <CheckIcon size=\"sm\" />\n ) : (\n <span className={styles.number}>{index + 1}</span>\n )\n const inner = (\n <>\n <span className={styles.markerCol}>\n <span className={styles.marker}>{marker}</span>\n {index < total - 1 ? (\n <span className={styles.connector} data-status={status} />\n ) : null}\n </span>\n <span className={styles.text}>\n <span className={styles.label}>\n {step.label}\n {status === 'complete' && !hasErrors ? (\n <VisuallyHidden>{` ${completeSuffix}`}</VisuallyHidden>\n ) : null}\n {hasErrors ? <VisuallyHidden>{` ${errorSuffix}`}</VisuallyHidden> : null}\n </span>\n {step.description ? (\n <span className={styles.description}>{step.description}</span>\n ) : null}\n </span>\n </>\n )\n return (\n <li\n key={step.value}\n className={styles.item}\n data-status={status}\n data-invalid={hasErrors || undefined}\n >\n {onStepSelect ? (\n <button\n type=\"button\"\n id={stepId}\n className={styles.control}\n data-status={status}\n data-invalid={hasErrors || undefined}\n aria-current={status === 'current' ? 'step' : undefined}\n onClick={() => {\n onStepSelect(step.value)\n }}\n >\n {inner}\n </button>\n ) : (\n <span\n id={stepId}\n className={styles.control}\n data-status={status}\n data-invalid={hasErrors || undefined}\n aria-current={status === 'current' ? 'step' : undefined}\n >\n {inner}\n </span>\n )}\n </li>\n )\n })}\n </ol>\n </div>\n )\n})\n"],"mappings":";;;;;;;;AAwCA,IAAMI,KAAwB,GAAe,GAAe,MAC1D,kBAAAJ,GAAA,EAAA,UAAA;CAAE;CACMK,IAAQ;CAAE;CAAKC;CAAM;CAAIC;AAC/B,EAAA,CAAA;AAGJ,SAASC,EAAc,GAAmB,GAAe,GAAqC;CAI5F,OAHIC,EAAK,SAAeA,EAAK,SACzBC,IAAe,IAAU,aACzBL,MAAUK,IAAqB,YAC5BL,IAAQK,IAAe,aAAa;AAC7C;
|
|
1
|
+
{"version":3,"file":"Stepper.js","names":["_Fragment","styles","Stepper_module_default","Fragment$1","defaultFormatCompact","index","total","label","resolveStatus","step","currentIndex","Stepper","forwardRef","rest","autoId","useId","baseId","id","steps","value","currentStep","completeSuffix","statusLabels","errorSuffix","cx","className","compactBelow","mergeStyles","style","formatCompact","orientation","status","hasErrors","stepId","marker","ErrorIcon","CheckIcon","inner","VisuallyHidden","onStepSelect"],"sources":["../../../../src/components/navigation/Stepper/Stepper.tsx"],"sourcesContent":["import { forwardRef, useId, type CSSProperties, type HTMLAttributes, type ReactNode } from 'react'\nimport { cx } from '#utils/cx'\nimport { mergeStyles } from '#utils/responsive'\nimport { CheckIcon, ErrorIcon } from '#icons'\nimport { VisuallyHidden } from '#components/layout/VisuallyHidden'\nimport styles from './Stepper.module.css'\n\nexport type StepperStatus = 'complete' | 'current' | 'upcoming' | 'error'\n\nexport interface StepperStep {\n /** Stable identifier — matched against `value` and passed to `onStepSelect`. */\n value: string\n label: ReactNode\n description?: ReactNode\n /** Overrides the status this step would otherwise derive from its position relative to `value`. */\n status?: StepperStatus\n /**\n * The step has errors. Independent of `status` (which keeps describing progress): an invalid\n * step gets the critical glyph and text, and the hidden error suffix in place of the complete one;\n * a current invalid step keeps `aria-current=\"step\"`. `status: 'error'` is the same treatment for a step whose progress\n * you don't report.\n */\n invalid?: boolean\n}\n\nexport interface StepperProps extends Omit<HTMLAttributes<HTMLOListElement>, 'onSelect'> {\n steps: readonly StepperStep[]\n /** The current step's `value` (`aria-current=\"step\"`). */\n value: string\n /** Steps become buttons when set — lets people jump to a visited or upcoming step. */\n onStepSelect?: (value: string) => void\n /** Default `horizontal`. */\n orientation?: 'horizontal' | 'vertical'\n /** Below this breakpoint, collapse to a single line of text (`formatCompact`). */\n compactBelow?: 'sm' | 'md'\n formatCompact?: (index: number, total: number, label: ReactNode) => ReactNode\n /** Visually-hidden suffixes announced after a step's label. */\n statusLabels?: { complete?: string; error?: string }\n}\n\nconst defaultFormatCompact = (index: number, total: number, label: ReactNode): ReactNode => (\n <>\n Step {index + 1} of {total} · {label}\n </>\n)\n\nfunction resolveStatus(step: StepperStep, index: number, currentIndex: number): StepperStatus {\n if (step.status) return step.status\n if (currentIndex < 0) return 'upcoming'\n if (index === currentIndex) return 'current'\n return index < currentIndex ? 'complete' : 'upcoming'\n}\n\n/**\n * Where you are in a multi-step flow. A step indicator, not a form control.\n *\n * @remarks\n * `Stepper` shows the steps of a flow and which one you're on. It doesn't hold the form: drive it\n * and the step content from the same state, and pair it with an `ActionBar` for back and next.\n *\n * @privateRemarks\n * A step indicator for a multi-step flow — not a form control. Pair with `ActionBar`\n * for the Back / Next / Submit row and drive both from the same current-step state.\n *\n * <Stepper\n * steps={[{ value: 'you', label: 'You' }, { value: 'team', label: 'Team' }]}\n * value={step}\n * onStepSelect={setStep}\n * />\n */\nexport const Stepper = forwardRef<HTMLOListElement, StepperProps>(function Stepper(\n {\n steps,\n value,\n onStepSelect,\n orientation = 'horizontal',\n compactBelow,\n formatCompact = defaultFormatCompact,\n statusLabels,\n className,\n id,\n style,\n ...rest\n },\n ref,\n) {\n const autoId = useId()\n const baseId = id ?? autoId\n const total = steps.length\n const currentIndex = steps.findIndex((step) => step.value === value)\n const currentStep = currentIndex >= 0 ? steps[currentIndex] : undefined\n const completeSuffix = statusLabels?.complete ?? 'completed'\n const errorSuffix = statusLabels?.error ?? 'has errors'\n\n return (\n <div\n className={cx(styles.root, className)}\n data-compact-below={compactBelow}\n style={mergeStyles({ '--_count': total } as CSSProperties, style)}\n >\n {compactBelow ? (\n <p className={styles.compact}>\n {formatCompact(Math.max(currentIndex, 0), total, currentStep?.label ?? '')}\n </p>\n ) : null}\n <ol ref={ref} id={baseId} className={styles.list} data-orientation={orientation} {...rest}>\n {steps.map((step, index) => {\n const status = resolveStatus(step, index, currentIndex)\n const hasErrors = status === 'error' || step.invalid === true\n const stepId = `${baseId}-${step.value}`\n const marker = hasErrors ? (\n <ErrorIcon size=\"sm\" />\n ) : status === 'complete' ? (\n <CheckIcon size=\"sm\" />\n ) : (\n <span className={styles.number}>{index + 1}</span>\n )\n const inner = (\n <>\n <span className={styles.markerCol}>\n <span className={styles.marker}>{marker}</span>\n {index < total - 1 ? (\n <span className={styles.connector} data-status={status} />\n ) : null}\n </span>\n <span className={styles.text}>\n <span className={styles.label}>\n {step.label}\n {status === 'complete' && !hasErrors ? (\n <VisuallyHidden>{` ${completeSuffix}`}</VisuallyHidden>\n ) : null}\n {hasErrors ? <VisuallyHidden>{` ${errorSuffix}`}</VisuallyHidden> : null}\n </span>\n {step.description ? (\n <span className={styles.description}>{step.description}</span>\n ) : null}\n </span>\n </>\n )\n return (\n <li\n key={step.value}\n className={styles.item}\n data-status={status}\n data-invalid={hasErrors || undefined}\n >\n {onStepSelect ? (\n <button\n type=\"button\"\n id={stepId}\n className={styles.control}\n data-status={status}\n data-invalid={hasErrors || undefined}\n aria-current={status === 'current' ? 'step' : undefined}\n onClick={() => {\n onStepSelect(step.value)\n }}\n >\n {inner}\n </button>\n ) : (\n <span\n id={stepId}\n className={styles.control}\n data-status={status}\n data-invalid={hasErrors || undefined}\n aria-current={status === 'current' ? 'step' : undefined}\n >\n {inner}\n </span>\n )}\n </li>\n )\n })}\n </ol>\n </div>\n )\n})\n"],"mappings":";;;;;;;;AAwCA,IAAMI,KAAwB,GAAe,GAAe,MAC1D,kBAAAJ,GAAA,EAAA,UAAA;CAAE;CACMK,IAAQ;CAAE;CAAKC;CAAM;CAAIC;AAC/B,EAAA,CAAA;AAGJ,SAASC,EAAc,GAAmB,GAAe,GAAqC;CAI5F,OAHIC,EAAK,SAAeA,EAAK,SACzBC,IAAe,IAAU,aACzBL,MAAUK,IAAqB,YAC5BL,IAAQK,IAAe,aAAa;AAC7C;AAmBA,IAAaC,IAAUC,EAA2C,SAChE,EACE,UACA,UACA,iBACA,iBAAc,cACd,iBACA,mBAAgBR,GAChB,iBACA,cACA,OACA,UACA,GAAGS,KAEL,GACA;CACA,IAAMC,IAASC,EAAM,GACfC,IAASC,KAAMH,GACfR,IAAQY,EAAM,QACdR,IAAeQ,EAAM,WAAW,MAAST,EAAK,UAAUU,CAAK,GAC7DC,IAAcV,KAAgB,IAAIQ,EAAMR,KAAgB,KAAA,GACxDW,IAAiBC,GAAc,YAAY,aAC3CC,IAAcD,GAAc,SAAS;CAE3C,OACE,kBAAC,OAAD;EACE,WAAWE,EAAGvB,EAAO,MAAMwB,CAAS;EACpC,sBAAoBC;EACpB,OAAOC,EAAY,EAAE,YAAYrB,EAAM,GAAoBsB,CAAK;EAHlE,UAAA,CAKGF,IACC,kBAAC,KAAD;GAAG,WAAWzB,EAAO;GAClB,UAAA4B,EAAc,KAAK,IAAInB,GAAc,CAAC,GAAGJ,GAAOc,GAAa,SAAS,EAAE;EACxE,CAAA,IACD,MACJ,kBAAC,MAAD;GAAS;GAAK,IAAIJ;GAAQ,WAAWf,EAAO;GAAM,oBAAkB6B;GAAa,GAAIjB;GAClF,UAAAK,EAAM,KAAK,GAAM,MAAU;IAC1B,IAAMa,IAASvB,EAAcC,GAAMJ,GAAOK,CAAY,GAChDsB,IAAYD,MAAW,WAAWtB,EAAK,YAAY,IACnDwB,IAAS,GAAGjB,EAAO,GAAGP,EAAK,SAC3ByB,IAASF,IACb,kBAACG,GAAD,EAAW,MAAK,KAAM,CAAA,IACpBJ,MAAW,aACb,kBAACK,GAAD,EAAW,MAAK,KAAM,CAAA,IAEtB,kBAAC,QAAD;KAAM,WAAWnC,EAAO;KAAS,UAAAI,IAAQ;IAAQ,CAAA,GAE7CgC,IACJ,kBAAArC,GAAA,EAAA,UAAA,CACE,kBAAC,QAAD;KAAM,WAAWC,EAAO;KAAxB,UAAA,CACE,kBAAC,QAAD;MAAM,WAAWA,EAAO;MAAS,UAAAiC;KAAa,CAAA,GAC7C7B,IAAQC,IAAQ,IACf,kBAAC,QAAD;MAAM,WAAWL,EAAO;MAAW,eAAa8B;KAAS,CAAA,IACvD,IACA;IACN,CAAA,GAAA,kBAAC,QAAD;KAAM,WAAW9B,EAAO;KAAxB,UAAA,CACE,kBAAC,QAAD;MAAM,WAAWA,EAAO;MAAxB,UAAA;OACGQ,EAAK;OACLsB,MAAW,cAAc,CAACC,IACzB,kBAACM,GAAD,EAAA,UAAiB,IAAIjB,IAAiC,CAAA,IACpD;OACHW,IAAY,kBAACM,GAAD,EAAA,UAAiB,IAAIf,IAA8B,CAAA,IAAI;MAChE;KACL,CAAA,GAAAd,EAAK,cACJ,kBAAC,QAAD;MAAM,WAAWR,EAAO;MAAc,UAAAQ,EAAK;KAAkB,CAAA,IAC3D,IACA;IACN,CAAA,CAAA,EAAA,CAAA;IAEJ,OACE,kBAAC,MAAD;KAEE,WAAWR,EAAO;KAClB,eAAa8B;KACb,gBAAcC,KAAa,KAAA;KAE1B,UAAAO,IACC,kBAAC,UAAD;MACE,MAAK;MACL,IAAIN;MACJ,WAAWhC,EAAO;MAClB,eAAa8B;MACb,gBAAcC,KAAa,KAAA;MAC3B,gBAAcD,MAAW,YAAY,SAAS,KAAA;MAC9C,eAAe;OACb,EAAatB,EAAK,KAAK;MACzB;MAEC,UAAA4B;KACK,CAAA,IAER,kBAAC,QAAD;MACE,IAAIJ;MACJ,WAAWhC,EAAO;MAClB,eAAa8B;MACb,gBAAcC,KAAa,KAAA;MAC3B,gBAAcD,MAAW,YAAY,SAAS,KAAA;MAE7C,UAAAM;KACG,CAAA;IAEN,GA9BG5B,EAAK,KA8BR;GAER,CAAC;EACC,CAAA,CACD;;AAET,CAAC"}
|
|
@@ -13,6 +13,14 @@ export type TabsListProps = ComponentPropsWithoutRef<typeof TabsPrimitive.List>;
|
|
|
13
13
|
export type TabsTriggerProps = ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>;
|
|
14
14
|
export type TabsContentProps = ComponentPropsWithoutRef<typeof TabsPrimitive.Content>;
|
|
15
15
|
/**
|
|
16
|
+
* Sections of one view, one visible at a time, switched with arrow keys.
|
|
17
|
+
*
|
|
18
|
+
* @remarks
|
|
19
|
+
* `Tabs` splits one view into sections that share a place on the page. It's Radix Tabs underneath:
|
|
20
|
+
* arrow keys move between triggers, and the panel follows focus (pass `activationMode="manual"` to
|
|
21
|
+
* require Enter). Hidden panels stay out of the tab order.
|
|
22
|
+
*
|
|
23
|
+
* @privateRemarks
|
|
16
24
|
* Radix Tabs with the library's look. Arrow keys move between triggers (roving focus);
|
|
17
25
|
* activation follows focus by default (`activationMode="manual"` to require Enter).
|
|
18
26
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tabs.js","names":["Tabs","TabsPrimitive","styles","Tabs_module_default","VariantContext","createContext","TabsRoot","forwardRef","rest","variant","Tabs","cx","className","TabsList","useContext","TabsTrigger","TabsContent","Tabs$1"],"sources":["../../../../src/components/navigation/Tabs/Tabs.tsx"],"sourcesContent":["import { createContext, forwardRef, useContext, type ComponentPropsWithoutRef } from 'react'\nimport { Tabs as TabsPrimitive } from 'radix-ui'\nimport { cx } from '#utils/cx'\nimport styles from './Tabs.module.css'\n\nexport type TabsVariant = 'underline' | 'pill'\n\nconst VariantContext = createContext<TabsVariant>('underline')\n\nexport interface TabsProps extends ComponentPropsWithoutRef<typeof TabsPrimitive.Root> {\n /**\n * `underline` (default): triggers sit on a hairline and the current one is marked\n * with an accent bar — page-level sections. `pill`: compact, filled current tab —\n * for switching views inside a card or panel.\n */\n variant?: TabsVariant\n}\n\nconst TabsRoot = forwardRef<HTMLDivElement, TabsProps>(function Tabs(\n { variant = 'underline', className, ...rest },\n ref,\n) {\n return (\n <VariantContext.Provider value={variant}>\n <TabsPrimitive.Root\n ref={ref}\n className={cx(styles.root, className)}\n data-variant={variant}\n {...rest}\n />\n </VariantContext.Provider>\n )\n})\n\nexport type TabsListProps = ComponentPropsWithoutRef<typeof TabsPrimitive.List>\n\n/** The row of triggers. Scrolls horizontally when it overflows (phones), never wraps. */\nconst TabsList = forwardRef<HTMLDivElement, TabsListProps>(function TabsList(\n { className, ...rest },\n ref,\n) {\n const variant = useContext(VariantContext)\n return (\n <TabsPrimitive.List\n ref={ref}\n className={cx(styles.list, className)}\n data-variant={variant}\n {...rest}\n />\n )\n})\n\nexport type TabsTriggerProps = ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>\n\nconst TabsTrigger = forwardRef<HTMLButtonElement, TabsTriggerProps>(function TabsTrigger(\n { className, ...rest },\n ref,\n) {\n const variant = useContext(VariantContext)\n return (\n <TabsPrimitive.Trigger\n ref={ref}\n className={cx(styles.trigger, className)}\n data-variant={variant}\n {...rest}\n />\n )\n})\n\nexport type TabsContentProps = ComponentPropsWithoutRef<typeof TabsPrimitive.Content>\n\nconst TabsContent = forwardRef<HTMLDivElement, TabsContentProps>(function TabsContent(\n { className, ...rest },\n ref,\n) {\n return <TabsPrimitive.Content ref={ref} className={cx(styles.content, className)} {...rest} />\n})\n\n/**\n * Radix Tabs with the library's look. Arrow keys move between triggers (roving focus);\n * activation follows focus by default (`activationMode=\"manual\"` to require Enter).\n *\n * <Tabs defaultValue=\"tasks\">\n * <Tabs.List aria-label=\"Atlas redesign\">\n * <Tabs.Trigger value=\"tasks\">Tasks</Tabs.Trigger>\n * <Tabs.Trigger value=\"people\">People</Tabs.Trigger>\n * </Tabs.List>\n * <Tabs.Content value=\"tasks\">…</Tabs.Content>\n * </Tabs>\n */\nexport const Tabs = Object.assign(TabsRoot, {\n List: TabsList,\n Trigger: TabsTrigger,\n Content: TabsContent,\n})\n"],"mappings":";;;;;;AAOA,IAAMI,IAAiBC,EAA2B,WAAW,GAWvDC,IAAWC,EAAsC,SACrD,EAAE,aAAU,aAAa,cAAW,GAAGC,KACvC,GACA;CACA,OACE,kBAACJ,EAAe,UAAhB;EAAyB,OAAOK;EAC9B,UAAA,kBAACR,EAAc,MAAf;GACO;GACL,WAAWU,EAAGT,EAAO,MAAMU,CAAS;GACpC,gBAAcH;GACd,GAAID;EACL,CAAA;CACsB,CAAA;AAE7B,CAAC,GAKKK,IAAWN,EAA0C,SACzD,EAAE,cAAW,GAAGC,KAChB,GACA;CACA,IAAMC,IAAUK,EAAWV,CAAc;CACzC,OACE,kBAACH,EAAc,MAAf;EACO;EACL,WAAWU,EAAGT,EAAO,MAAMU,CAAS;EACpC,gBAAcH;EACd,GAAID;CACL,CAAA;AAEL,CAAC,GAIKO,IAAcR,EAAgD,SAClE,EAAE,cAAW,GAAGC,KAChB,GACA;CACA,IAAMC,IAAUK,EAAWV,CAAc;CACzC,OACE,kBAACH,EAAc,SAAf;EACO;EACL,WAAWU,EAAGT,EAAO,SAASU,CAAS;EACvC,gBAAcH;EACd,GAAID;CACL,CAAA;AAEL,CAAC,GAIKQ,IAAcT,EAA6C,SAC/D,EAAE,cAAW,GAAGC,KAChB,GACA;CACA,OAAO,kBAACP,EAAc,SAAf;EAA4B;EAAK,WAAWU,EAAGT,EAAO,SAASU,CAAS;EAAG,GAAIJ;CAAO,CAAA;AAC/F,CAAC,
|
|
1
|
+
{"version":3,"file":"Tabs.js","names":["Tabs","TabsPrimitive","styles","Tabs_module_default","VariantContext","createContext","TabsRoot","forwardRef","rest","variant","Tabs","cx","className","TabsList","useContext","TabsTrigger","TabsContent","Tabs$1"],"sources":["../../../../src/components/navigation/Tabs/Tabs.tsx"],"sourcesContent":["import { createContext, forwardRef, useContext, type ComponentPropsWithoutRef } from 'react'\nimport { Tabs as TabsPrimitive } from 'radix-ui'\nimport { cx } from '#utils/cx'\nimport styles from './Tabs.module.css'\n\nexport type TabsVariant = 'underline' | 'pill'\n\nconst VariantContext = createContext<TabsVariant>('underline')\n\nexport interface TabsProps extends ComponentPropsWithoutRef<typeof TabsPrimitive.Root> {\n /**\n * `underline` (default): triggers sit on a hairline and the current one is marked\n * with an accent bar — page-level sections. `pill`: compact, filled current tab —\n * for switching views inside a card or panel.\n */\n variant?: TabsVariant\n}\n\nconst TabsRoot = forwardRef<HTMLDivElement, TabsProps>(function Tabs(\n { variant = 'underline', className, ...rest },\n ref,\n) {\n return (\n <VariantContext.Provider value={variant}>\n <TabsPrimitive.Root\n ref={ref}\n className={cx(styles.root, className)}\n data-variant={variant}\n {...rest}\n />\n </VariantContext.Provider>\n )\n})\n\nexport type TabsListProps = ComponentPropsWithoutRef<typeof TabsPrimitive.List>\n\n/** The row of triggers. Scrolls horizontally when it overflows (phones), never wraps. */\nconst TabsList = forwardRef<HTMLDivElement, TabsListProps>(function TabsList(\n { className, ...rest },\n ref,\n) {\n const variant = useContext(VariantContext)\n return (\n <TabsPrimitive.List\n ref={ref}\n className={cx(styles.list, className)}\n data-variant={variant}\n {...rest}\n />\n )\n})\n\nexport type TabsTriggerProps = ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>\n\nconst TabsTrigger = forwardRef<HTMLButtonElement, TabsTriggerProps>(function TabsTrigger(\n { className, ...rest },\n ref,\n) {\n const variant = useContext(VariantContext)\n return (\n <TabsPrimitive.Trigger\n ref={ref}\n className={cx(styles.trigger, className)}\n data-variant={variant}\n {...rest}\n />\n )\n})\n\nexport type TabsContentProps = ComponentPropsWithoutRef<typeof TabsPrimitive.Content>\n\nconst TabsContent = forwardRef<HTMLDivElement, TabsContentProps>(function TabsContent(\n { className, ...rest },\n ref,\n) {\n return <TabsPrimitive.Content ref={ref} className={cx(styles.content, className)} {...rest} />\n})\n\n/**\n * Sections of one view, one visible at a time, switched with arrow keys.\n *\n * @remarks\n * `Tabs` splits one view into sections that share a place on the page. It's Radix Tabs underneath:\n * arrow keys move between triggers, and the panel follows focus (pass `activationMode=\"manual\"` to\n * require Enter). Hidden panels stay out of the tab order.\n *\n * @privateRemarks\n * Radix Tabs with the library's look. Arrow keys move between triggers (roving focus);\n * activation follows focus by default (`activationMode=\"manual\"` to require Enter).\n *\n * <Tabs defaultValue=\"tasks\">\n * <Tabs.List aria-label=\"Atlas redesign\">\n * <Tabs.Trigger value=\"tasks\">Tasks</Tabs.Trigger>\n * <Tabs.Trigger value=\"people\">People</Tabs.Trigger>\n * </Tabs.List>\n * <Tabs.Content value=\"tasks\">…</Tabs.Content>\n * </Tabs>\n */\nexport const Tabs = Object.assign(TabsRoot, {\n List: TabsList,\n Trigger: TabsTrigger,\n Content: TabsContent,\n})\n"],"mappings":";;;;;;AAOA,IAAMI,IAAiBC,EAA2B,WAAW,GAWvDC,IAAWC,EAAsC,SACrD,EAAE,aAAU,aAAa,cAAW,GAAGC,KACvC,GACA;CACA,OACE,kBAACJ,EAAe,UAAhB;EAAyB,OAAOK;EAC9B,UAAA,kBAACR,EAAc,MAAf;GACO;GACL,WAAWU,EAAGT,EAAO,MAAMU,CAAS;GACpC,gBAAcH;GACd,GAAID;EACL,CAAA;CACsB,CAAA;AAE7B,CAAC,GAKKK,IAAWN,EAA0C,SACzD,EAAE,cAAW,GAAGC,KAChB,GACA;CACA,IAAMC,IAAUK,EAAWV,CAAc;CACzC,OACE,kBAACH,EAAc,MAAf;EACO;EACL,WAAWU,EAAGT,EAAO,MAAMU,CAAS;EACpC,gBAAcH;EACd,GAAID;CACL,CAAA;AAEL,CAAC,GAIKO,IAAcR,EAAgD,SAClE,EAAE,cAAW,GAAGC,KAChB,GACA;CACA,IAAMC,IAAUK,EAAWV,CAAc;CACzC,OACE,kBAACH,EAAc,SAAf;EACO;EACL,WAAWU,EAAGT,EAAO,SAASU,CAAS;EACvC,gBAAcH;EACd,GAAID;CACL,CAAA;AAEL,CAAC,GAIKQ,IAAcT,EAA6C,SAC/D,EAAE,cAAW,GAAGC,KAChB,GACA;CACA,OAAO,kBAACP,EAAc,SAAf;EAA4B;EAAK,WAAWU,EAAGT,EAAO,SAASU,CAAS;EAAG,GAAIJ;CAAO,CAAA;AAC/F,CAAC,GAsBYR,IAAO,OAAO,OAAOM,GAAU;CAC1C,MAAMO;CACN,SAASE;CACT,SAASC;AACX,CAAC"}
|
|
@@ -3,6 +3,19 @@ import { Dialog as DialogPrimitive } from 'radix-ui';
|
|
|
3
3
|
export type DialogSize = 'sm' | 'md' | 'lg';
|
|
4
4
|
export type DialogProps = ComponentPropsWithoutRef<typeof DialogPrimitive.Root>;
|
|
5
5
|
/**
|
|
6
|
+
* A modal dialog that traps focus, closes on Escape, and returns focus to whatever opened it.
|
|
7
|
+
*
|
|
8
|
+
* @remarks
|
|
9
|
+
* `Dialog` interrupts to ask for a decision or a small piece of input. It's Radix Dialog
|
|
10
|
+
* underneath: focus moves into it and is trapped there, Escape and the scrim close it, page scroll
|
|
11
|
+
* locks, and focus returns to the trigger when it closes.
|
|
12
|
+
*
|
|
13
|
+
* ## Themes
|
|
14
|
+
*
|
|
15
|
+
* A dialog opened inside a `ThemeScope` renders in that scope's theme, even though it's portalled
|
|
16
|
+
* to the end of the document.
|
|
17
|
+
*
|
|
18
|
+
* @privateRemarks
|
|
6
19
|
* Modal dialog root. Controlled (`open` + `onOpenChange`) or uncontrolled (`defaultOpen`).
|
|
7
20
|
* Focus is trapped while open, Escape and the scrim close it, and focus returns to the
|
|
8
21
|
* trigger on close.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Dialog.js","names":["DialogPrimitive","styles","Dialog","Dialog_module_default","DialogRoot","anchor","usePortalAnchorRef","PortalAnchorContext","Dialog","props","DialogTrigger","forwardRef","usePortalAnchor","composeRefs","ref","Overlay","theme","usePortalTheme","container","ContentInner","rest","cx","className","size","title","description","hideClose","children","OverlayClose","closeLabel","DialogContent","DialogFooter","DialogTitle","DialogDescription","DialogClose","Dialog$1"],"sources":["../../../../src/components/overlays/Dialog/Dialog.tsx"],"sourcesContent":["import {\n forwardRef,\n type ComponentPropsWithoutRef,\n type ComponentRef,\n type HTMLAttributes,\n type ReactNode,\n} from 'react'\nimport { Dialog as DialogPrimitive } from 'radix-ui'\nimport { cx } from '#utils/cx'\nimport {\n PortalAnchorContext,\n composeRefs,\n usePortalAnchor,\n usePortalAnchorRef,\n usePortalTheme,\n} from '#components/overlays/usePortalTheme'\nimport { OverlayClose } from '#components/overlays/OverlayClose'\nimport styles from './Dialog.module.css'\n\nexport type DialogSize = 'sm' | 'md' | 'lg'\n\nexport type DialogProps = ComponentPropsWithoutRef<typeof DialogPrimitive.Root>\n\n/**\n * Modal dialog root. Controlled (`open` + `onOpenChange`) or uncontrolled (`defaultOpen`).\n * Focus is trapped while open, Escape and the scrim close it, and focus returns to the\n * trigger on close.\n *\n * <Dialog>\n * <Dialog.Trigger asChild><Button>Delete</Button></Dialog.Trigger>\n * <Dialog.Content title=\"Delete invoice?\" description=\"…\">\n * <Dialog.Footer>…</Dialog.Footer>\n * </Dialog.Content>\n * </Dialog>\n */\nfunction DialogRoot(props: DialogProps) {\n const anchor = usePortalAnchorRef()\n return (\n <PortalAnchorContext.Provider value={anchor}>\n <DialogPrimitive.Root {...props} />\n </PortalAnchorContext.Provider>\n )\n}\n\nexport type DialogTriggerProps = ComponentPropsWithoutRef<typeof DialogPrimitive.Trigger>\n\n/** Opens the dialog. Use `asChild` to render your own button. Its theme scope themes the dialog. */\nconst DialogTrigger = forwardRef<ComponentRef<typeof DialogPrimitive.Trigger>, DialogTriggerProps>(\n function DialogTrigger(props, ref) {\n const anchor = usePortalAnchor()\n return <DialogPrimitive.Trigger ref={composeRefs(ref, anchor)} {...props} />\n },\n)\n\n/* Rendered inside the Portal so they mount on open and read the theme at that moment. */\nconst Overlay = forwardRef<HTMLDivElement, { container?: HTMLElement | null }>(function Overlay(\n { container },\n ref,\n) {\n const theme = usePortalTheme(container)\n return <DialogPrimitive.Overlay ref={ref} className={styles.overlay} {...theme} />\n})\n\nexport interface DialogContentProps extends Omit<\n ComponentPropsWithoutRef<typeof DialogPrimitive.Content>,\n 'title'\n> {\n /** Width step. `sm` for confirmations, `md` (default) for short forms, `lg` for reading. */\n size?: DialogSize\n /**\n * Heading, rendered as the accessible title. If you omit it, render a `<Dialog.Title>`\n * yourself — every dialog needs a name.\n */\n title?: ReactNode\n /** Supporting sentence under the title, wired to `aria-describedby`. */\n description?: ReactNode\n /** Hide the corner close button (keep a `Dialog.Close` in the footer instead). */\n hideClose?: boolean\n /** Accessible name of the corner close button. Default \"Close\". */\n closeLabel?: string\n /** Portal target. Defaults to `document.body`; its theme scope is also used. */\n container?: HTMLElement | null\n}\n\nconst ContentInner = forwardRef<HTMLDivElement, DialogContentProps>(function ContentInner(\n {\n size = 'md',\n title,\n description,\n hideClose = false,\n closeLabel,\n container,\n className,\n children,\n ...rest\n },\n ref,\n) {\n const theme = usePortalTheme(container)\n return (\n <DialogPrimitive.Content\n ref={ref}\n className={cx(styles.content, className)}\n data-size={size}\n {...theme}\n {...rest}\n >\n {title !== undefined || description !== undefined ? (\n <div className={styles.header} data-has-close={hideClose ? undefined : ''}>\n {title !== undefined ? (\n <DialogPrimitive.Title className={styles.title}>{title}</DialogPrimitive.Title>\n ) : null}\n {description !== undefined ? (\n <DialogPrimitive.Description className={styles.description}>\n {description}\n </DialogPrimitive.Description>\n ) : null}\n </div>\n ) : null}\n {children}\n {hideClose ? null : <OverlayClose className={styles.close} label={closeLabel} />}\n </DialogPrimitive.Content>\n )\n})\n\n/**\n * The dialog panel, its scrim and the portal. Centred, scrolls internally when tall.\n */\nconst DialogContent = forwardRef<HTMLDivElement, DialogContentProps>(function DialogContent(\n { container, forceMount, ...rest },\n ref,\n) {\n return (\n <DialogPrimitive.Portal container={container} forceMount={forceMount}>\n <Overlay container={container} />\n <ContentInner ref={ref} container={container} forceMount={forceMount} {...rest} />\n </DialogPrimitive.Portal>\n )\n})\n\nexport type DialogFooterProps = HTMLAttributes<HTMLDivElement>\n\n/** Actions row. Primary action last (rightmost); it wraps and stacks on narrow screens. */\nconst DialogFooter = forwardRef<HTMLDivElement, DialogFooterProps>(function DialogFooter(\n { className, ...rest },\n ref,\n) {\n return <div ref={ref} className={cx(styles.footer, className)} {...rest} />\n})\n\nexport type DialogTitleProps = ComponentPropsWithoutRef<typeof DialogPrimitive.Title>\n\n/** For custom headers when the `title` prop isn't enough. */\nconst DialogTitle = forwardRef<ComponentRef<typeof DialogPrimitive.Title>, DialogTitleProps>(\n function DialogTitle({ className, ...rest }, ref) {\n return <DialogPrimitive.Title ref={ref} className={cx(styles.title, className)} {...rest} />\n },\n)\n\nexport type DialogDescriptionProps = ComponentPropsWithoutRef<typeof DialogPrimitive.Description>\n\nconst DialogDescription = forwardRef<\n ComponentRef<typeof DialogPrimitive.Description>,\n DialogDescriptionProps\n>(function DialogDescription({ className, ...rest }, ref) {\n return (\n <DialogPrimitive.Description\n ref={ref}\n className={cx(styles.description, className)}\n {...rest}\n />\n )\n})\n\nexport type DialogCloseProps = ComponentPropsWithoutRef<typeof DialogPrimitive.Close>\n\n/** Closes the dialog. Use `asChild` with a Button for \"Cancel\". */\nconst DialogClose = DialogPrimitive.Close\n\nexport const Dialog = Object.assign(DialogRoot, {\n Root: DialogRoot,\n Trigger: DialogTrigger,\n Content: DialogContent,\n Footer: DialogFooter,\n Title: DialogTitle,\n Description: DialogDescription,\n Close: DialogClose,\n})\n"],"mappings":";;;;;;;;
|
|
1
|
+
{"version":3,"file":"Dialog.js","names":["DialogPrimitive","styles","Dialog","Dialog_module_default","DialogRoot","anchor","usePortalAnchorRef","PortalAnchorContext","Dialog","props","DialogTrigger","forwardRef","usePortalAnchor","composeRefs","ref","Overlay","theme","usePortalTheme","container","ContentInner","rest","cx","className","size","title","description","hideClose","children","OverlayClose","closeLabel","DialogContent","DialogFooter","DialogTitle","DialogDescription","DialogClose","Dialog$1"],"sources":["../../../../src/components/overlays/Dialog/Dialog.tsx"],"sourcesContent":["import {\n forwardRef,\n type ComponentPropsWithoutRef,\n type ComponentRef,\n type HTMLAttributes,\n type ReactNode,\n} from 'react'\nimport { Dialog as DialogPrimitive } from 'radix-ui'\nimport { cx } from '#utils/cx'\nimport {\n PortalAnchorContext,\n composeRefs,\n usePortalAnchor,\n usePortalAnchorRef,\n usePortalTheme,\n} from '#components/overlays/usePortalTheme'\nimport { OverlayClose } from '#components/overlays/OverlayClose'\nimport styles from './Dialog.module.css'\n\nexport type DialogSize = 'sm' | 'md' | 'lg'\n\nexport type DialogProps = ComponentPropsWithoutRef<typeof DialogPrimitive.Root>\n\n/**\n * A modal dialog that traps focus, closes on Escape, and returns focus to whatever opened it.\n *\n * @remarks\n * `Dialog` interrupts to ask for a decision or a small piece of input. It's Radix Dialog\n * underneath: focus moves into it and is trapped there, Escape and the scrim close it, page scroll\n * locks, and focus returns to the trigger when it closes.\n *\n * ## Themes\n *\n * A dialog opened inside a `ThemeScope` renders in that scope's theme, even though it's portalled\n * to the end of the document.\n *\n * @privateRemarks\n * Modal dialog root. Controlled (`open` + `onOpenChange`) or uncontrolled (`defaultOpen`).\n * Focus is trapped while open, Escape and the scrim close it, and focus returns to the\n * trigger on close.\n *\n * <Dialog>\n * <Dialog.Trigger asChild><Button>Delete</Button></Dialog.Trigger>\n * <Dialog.Content title=\"Delete invoice?\" description=\"…\">\n * <Dialog.Footer>…</Dialog.Footer>\n * </Dialog.Content>\n * </Dialog>\n */\nfunction DialogRoot(props: DialogProps) {\n const anchor = usePortalAnchorRef()\n return (\n <PortalAnchorContext.Provider value={anchor}>\n <DialogPrimitive.Root {...props} />\n </PortalAnchorContext.Provider>\n )\n}\n\nexport type DialogTriggerProps = ComponentPropsWithoutRef<typeof DialogPrimitive.Trigger>\n\n/** Opens the dialog. Use `asChild` to render your own button. Its theme scope themes the dialog. */\nconst DialogTrigger = forwardRef<ComponentRef<typeof DialogPrimitive.Trigger>, DialogTriggerProps>(\n function DialogTrigger(props, ref) {\n const anchor = usePortalAnchor()\n return <DialogPrimitive.Trigger ref={composeRefs(ref, anchor)} {...props} />\n },\n)\n\n/* Rendered inside the Portal so they mount on open and read the theme at that moment. */\nconst Overlay = forwardRef<HTMLDivElement, { container?: HTMLElement | null }>(function Overlay(\n { container },\n ref,\n) {\n const theme = usePortalTheme(container)\n return <DialogPrimitive.Overlay ref={ref} className={styles.overlay} {...theme} />\n})\n\nexport interface DialogContentProps extends Omit<\n ComponentPropsWithoutRef<typeof DialogPrimitive.Content>,\n 'title'\n> {\n /** Width step. `sm` for confirmations, `md` (default) for short forms, `lg` for reading. */\n size?: DialogSize\n /**\n * Heading, rendered as the accessible title. If you omit it, render a `<Dialog.Title>`\n * yourself — every dialog needs a name.\n */\n title?: ReactNode\n /** Supporting sentence under the title, wired to `aria-describedby`. */\n description?: ReactNode\n /** Hide the corner close button (keep a `Dialog.Close` in the footer instead). */\n hideClose?: boolean\n /** Accessible name of the corner close button. Default \"Close\". */\n closeLabel?: string\n /** Portal target. Defaults to `document.body`; its theme scope is also used. */\n container?: HTMLElement | null\n}\n\nconst ContentInner = forwardRef<HTMLDivElement, DialogContentProps>(function ContentInner(\n {\n size = 'md',\n title,\n description,\n hideClose = false,\n closeLabel,\n container,\n className,\n children,\n ...rest\n },\n ref,\n) {\n const theme = usePortalTheme(container)\n return (\n <DialogPrimitive.Content\n ref={ref}\n className={cx(styles.content, className)}\n data-size={size}\n {...theme}\n {...rest}\n >\n {title !== undefined || description !== undefined ? (\n <div className={styles.header} data-has-close={hideClose ? undefined : ''}>\n {title !== undefined ? (\n <DialogPrimitive.Title className={styles.title}>{title}</DialogPrimitive.Title>\n ) : null}\n {description !== undefined ? (\n <DialogPrimitive.Description className={styles.description}>\n {description}\n </DialogPrimitive.Description>\n ) : null}\n </div>\n ) : null}\n {children}\n {hideClose ? null : <OverlayClose className={styles.close} label={closeLabel} />}\n </DialogPrimitive.Content>\n )\n})\n\n/**\n * The dialog panel, its scrim and the portal. Centred, scrolls internally when tall.\n */\nconst DialogContent = forwardRef<HTMLDivElement, DialogContentProps>(function DialogContent(\n { container, forceMount, ...rest },\n ref,\n) {\n return (\n <DialogPrimitive.Portal container={container} forceMount={forceMount}>\n <Overlay container={container} />\n <ContentInner ref={ref} container={container} forceMount={forceMount} {...rest} />\n </DialogPrimitive.Portal>\n )\n})\n\nexport type DialogFooterProps = HTMLAttributes<HTMLDivElement>\n\n/** Actions row. Primary action last (rightmost); it wraps and stacks on narrow screens. */\nconst DialogFooter = forwardRef<HTMLDivElement, DialogFooterProps>(function DialogFooter(\n { className, ...rest },\n ref,\n) {\n return <div ref={ref} className={cx(styles.footer, className)} {...rest} />\n})\n\nexport type DialogTitleProps = ComponentPropsWithoutRef<typeof DialogPrimitive.Title>\n\n/** For custom headers when the `title` prop isn't enough. */\nconst DialogTitle = forwardRef<ComponentRef<typeof DialogPrimitive.Title>, DialogTitleProps>(\n function DialogTitle({ className, ...rest }, ref) {\n return <DialogPrimitive.Title ref={ref} className={cx(styles.title, className)} {...rest} />\n },\n)\n\nexport type DialogDescriptionProps = ComponentPropsWithoutRef<typeof DialogPrimitive.Description>\n\nconst DialogDescription = forwardRef<\n ComponentRef<typeof DialogPrimitive.Description>,\n DialogDescriptionProps\n>(function DialogDescription({ className, ...rest }, ref) {\n return (\n <DialogPrimitive.Description\n ref={ref}\n className={cx(styles.description, className)}\n {...rest}\n />\n )\n})\n\nexport type DialogCloseProps = ComponentPropsWithoutRef<typeof DialogPrimitive.Close>\n\n/** Closes the dialog. Use `asChild` with a Button for \"Cancel\". */\nconst DialogClose = DialogPrimitive.Close\n\nexport const Dialog = Object.assign(DialogRoot, {\n Root: DialogRoot,\n Trigger: DialogTrigger,\n Content: DialogContent,\n Footer: DialogFooter,\n Title: DialogTitle,\n Description: DialogDescription,\n Close: DialogClose,\n})\n"],"mappings":";;;;;;;;AAgDA,SAASI,EAAW,GAAoB;CACtC,IAAMC,IAASC,EAAmB;CAClC,OACE,kBAACC,EAAoB,UAArB;EAA8B,OAAOF;EACnC,UAAA,kBAACL,EAAgB,MAAjB,EAAsB,GAAIS,EAAQ,CAAA;CACN,CAAA;AAElC;AAKA,IAAMC,IAAgBC,EACpB,SAAuB,GAAO,GAAK;CACjC,IAAMN,IAASO,EAAgB;CAC/B,OAAO,kBAACZ,EAAgB,SAAjB;EAAyB,KAAKa,EAAYC,GAAKT,CAAM;EAAG,GAAII;CAAQ,CAAA;AAC7E,CACF,GAGMM,IAAUJ,EAA+D,SAC7E,EAAE,gBACF,GACA;CACA,IAAMK,IAAQC,EAAeC,CAAS;CACtC,OAAO,kBAAClB,EAAgB,SAAjB;EAA8B;EAAK,WAAWC,EAAO;EAAS,GAAIe;CAAQ,CAAA;AACnF,CAAC,GAuBKG,IAAeR,EAA+C,SAClE,EACE,UAAO,MACP,UACA,gBACA,eAAY,IACZ,eACA,cACA,cACA,aACA,GAAGS,KAEL,GACA;CACA,IAAMJ,IAAQC,EAAeC,CAAS;CACtC,OACE,kBAAClB,EAAgB,SAAjB;EACO;EACL,WAAWqB,EAAGpB,EAAO,SAASqB,CAAS;EACvC,aAAWC;EACX,GAAIP;EACJ,GAAII;EALN,UAAA;GAOGI,MAAU,KAAA,KAAaC,MAAgB,KAAA,IACtC,kBAAC,OAAD;IAAK,WAAWxB,EAAO;IAAQ,kBAAgByB,IAAY,KAAA,IAAY;IAAvE,UAAA,CACGF,MAAU,KAAA,IAEP,OADF,kBAACxB,EAAgB,OAAjB;KAAuB,WAAWC,EAAO;KAAQ,UAAAuB;IAA6B,CAAA,GAE/EC,MAAgB,KAAA,IAIb,OAHF,kBAACzB,EAAgB,aAAjB;KAA6B,WAAWC,EAAO;KAC5C,UAAAwB;IAC0B,CAAA,CAE5B;GACH,CAAA,IAAA;GACHE;GACAD,IAAY,OAAO,kBAACE,GAAD;IAAc,WAAW3B,EAAO;IAAO,OAAO4B;GAAa,CAAA;EACxD;;AAE7B,CAAC,GAKKC,IAAgBnB,EAA+C,SACnE,EAAE,cAAW,eAAY,GAAGS,KAC5B,GACA;CACA,OACE,kBAACpB,EAAgB,QAAjB;EAAmC;EAAuB;EAA1D,UAAA,CACE,kBAACe,GAAD,EAAoB,aAAY,CAAA,GAChC,kBAACI,GAAD;GAAmB;GAAgB;GAAuB;GAAY,GAAIC;EAAO,CAAA,CAC3D;;AAE5B,CAAC,GAKKW,IAAepB,EAA8C,SACjE,EAAE,cAAW,GAAGS,KAChB,GACA;CACA,OAAO,kBAAC,OAAD;EAAU;EAAK,WAAWC,EAAGpB,EAAO,QAAQqB,CAAS;EAAG,GAAIF;CAAO,CAAA;AAC5E,CAAC,GAKKY,IAAcrB,EAClB,SAAqB,EAAE,cAAW,GAAGS,KAAQ,GAAK;CAChD,OAAO,kBAACpB,EAAgB,OAAjB;EAA4B;EAAK,WAAWqB,EAAGpB,EAAO,OAAOqB,CAAS;EAAG,GAAIF;CAAO,CAAA;AAC7F,CACF,GAIMa,IAAoBtB,EAGxB,SAA2B,EAAE,cAAW,GAAGS,KAAQ,GAAK;CACxD,OACE,kBAACpB,EAAgB,aAAjB;EACO;EACL,WAAWqB,EAAGpB,EAAO,aAAaqB,CAAS;EAC3C,GAAIF;CACL,CAAA;AAEL,CAAC,GAKKc,IAAclC,EAAgB,OAEvBE,IAAS,OAAO,OAAOE,GAAY;CAC9C,MAAMA;CACN,SAASM;CACT,SAASoB;CACT,QAAQC;CACR,OAAOC;CACP,aAAaC;CACb,OAAOC;AACT,CAAC"}
|
|
@@ -2,6 +2,14 @@ import { type ComponentPropsWithoutRef, type ReactNode } from 'react';
|
|
|
2
2
|
import { DropdownMenu as MenuPrimitive } from 'radix-ui';
|
|
3
3
|
export type DropdownMenuProps = ComponentPropsWithoutRef<typeof MenuPrimitive.Root>;
|
|
4
4
|
/**
|
|
5
|
+
* A list of commands behind a button, with checkboxes, radio groups, submenus and full keyboard
|
|
6
|
+
* support.
|
|
7
|
+
*
|
|
8
|
+
* @remarks
|
|
9
|
+
* `DropdownMenu` holds the actions you don't need to see all the time: a row's options, a sort
|
|
10
|
+
* order. It's Radix Menu underneath, so arrow keys, typeahead, Home, End and Escape all work.
|
|
11
|
+
*
|
|
12
|
+
* @privateRemarks
|
|
5
13
|
* A list of commands behind a button: row actions, a member's options, sort order.
|
|
6
14
|
* Full keyboard support (arrows, typeahead, Home/End, Escape) from Radix.
|
|
7
15
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DropdownMenu.js","names":["MenuPrimitive","styles","DropdownMenu","DropdownMenu_module_default","DropdownMenuRoot","anchor","usePortalAnchorRef","PortalAnchorContext","DropdownMenu","props","DropdownMenuTrigger","forwardRef","usePortalAnchor","composeRefs","ref","ContentInner","rest","theme","usePortalTheme","container","cx","className","DropdownMenuContent","DropdownMenuItem","tone","leadingIcon","shortcut","DropdownMenuCheckboxItem","CheckIcon","DropdownMenuRadioGroup","DropdownMenuRadioItem","DropdownMenuLabel","DropdownMenuSeparator","DropdownMenuGroup","DropdownMenuSub","DropdownMenuSubTrigger","ChevronRightIcon","SubContentInner","DropdownMenuSubContent","DropdownMenu$1"],"sources":["../../../../src/components/overlays/DropdownMenu/DropdownMenu.tsx"],"sourcesContent":["import { forwardRef, type ComponentPropsWithoutRef, type ComponentRef, type ReactNode } from 'react'\nimport { DropdownMenu as MenuPrimitive } from 'radix-ui'\nimport { CheckIcon, ChevronRightIcon } from '#icons'\nimport { cx } from '#utils/cx'\nimport {\n PortalAnchorContext,\n composeRefs,\n usePortalAnchor,\n usePortalAnchorRef,\n usePortalTheme,\n} from '#components/overlays/usePortalTheme'\nimport styles from './DropdownMenu.module.css'\n\nexport type DropdownMenuProps = ComponentPropsWithoutRef<typeof MenuPrimitive.Root>\n\n/**\n * A list of commands behind a button: row actions, a member's options, sort order.\n * Full keyboard support (arrows, typeahead, Home/End, Escape) from Radix.\n *\n * <DropdownMenu>\n * <DropdownMenu.Trigger asChild><Button>Options</Button></DropdownMenu.Trigger>\n * <DropdownMenu.Content>\n * <DropdownMenu.Item shortcut=\"⌘E\">Edit</DropdownMenu.Item>\n * <DropdownMenu.Separator />\n * <DropdownMenu.Item tone=\"critical\">Remove</DropdownMenu.Item>\n * </DropdownMenu.Content>\n * </DropdownMenu>\n */\nfunction DropdownMenuRoot(props: DropdownMenuProps) {\n const anchor = usePortalAnchorRef()\n return (\n <PortalAnchorContext.Provider value={anchor}>\n <MenuPrimitive.Root {...props} />\n </PortalAnchorContext.Provider>\n )\n}\n\nexport type DropdownMenuTriggerProps = ComponentPropsWithoutRef<typeof MenuPrimitive.Trigger>\n\nconst DropdownMenuTrigger = forwardRef<\n ComponentRef<typeof MenuPrimitive.Trigger>,\n DropdownMenuTriggerProps\n>(function DropdownMenuTrigger(props, ref) {\n const anchor = usePortalAnchor()\n return <MenuPrimitive.Trigger ref={composeRefs(ref, anchor)} {...props} />\n})\n\nexport interface DropdownMenuContentProps extends ComponentPropsWithoutRef<\n typeof MenuPrimitive.Content\n> {\n /** Portal target. Defaults to `document.body`; its theme scope is also used. */\n container?: HTMLElement | null\n}\n\nconst ContentInner = forwardRef<HTMLDivElement, DropdownMenuContentProps>(function ContentInner(\n { container, align = 'start', sideOffset = 6, className, ...rest },\n ref,\n) {\n const theme = usePortalTheme(container)\n return (\n <MenuPrimitive.Content\n ref={ref}\n className={cx(styles.content, className)}\n align={align}\n sideOffset={sideOffset}\n collisionPadding={8}\n {...theme}\n {...rest}\n />\n )\n})\n\n/** The menu panel. Aligns to the trigger's start edge by default and flips to stay on screen. */\nconst DropdownMenuContent = forwardRef<HTMLDivElement, DropdownMenuContentProps>(\n function DropdownMenuContent({ container, forceMount, ...rest }, ref) {\n return (\n <MenuPrimitive.Portal container={container} forceMount={forceMount}>\n <ContentInner ref={ref} container={container} forceMount={forceMount} {...rest} />\n </MenuPrimitive.Portal>\n )\n },\n)\n\nexport type DropdownMenuItemTone = 'neutral' | 'critical'\n\nexport interface DropdownMenuItemProps extends ComponentPropsWithoutRef<typeof MenuPrimitive.Item> {\n /** `critical` for destructive commands. Put them last, after a separator. */\n tone?: DropdownMenuItemTone\n /** Icon before the label. Use sparingly — one menu, icons on all items or none. */\n leadingIcon?: ReactNode\n /** Keyboard shortcut hint, shown right-aligned. Display only; wire the shortcut yourself. */\n shortcut?: ReactNode\n}\n\nconst DropdownMenuItem = forwardRef<ComponentRef<typeof MenuPrimitive.Item>, DropdownMenuItemProps>(\n function DropdownMenuItem(\n { tone = 'neutral', leadingIcon, shortcut, className, children, ...rest },\n ref,\n ) {\n return (\n <MenuPrimitive.Item\n ref={ref}\n className={cx(styles.item, className)}\n data-tone={tone}\n {...rest}\n >\n {leadingIcon ? <span className={styles.icon}>{leadingIcon}</span> : null}\n <span className={styles.label}>{children}</span>\n {shortcut ? <kbd className={styles.shortcut}>{shortcut}</kbd> : null}\n </MenuPrimitive.Item>\n )\n },\n)\n\nexport interface DropdownMenuCheckboxItemProps extends ComponentPropsWithoutRef<\n typeof MenuPrimitive.CheckboxItem\n> {\n shortcut?: ReactNode\n}\n\n/** A toggle. Controlled with `checked` + `onCheckedChange`. Stays open on select only if you `preventDefault`. */\nconst DropdownMenuCheckboxItem = forwardRef<\n ComponentRef<typeof MenuPrimitive.CheckboxItem>,\n DropdownMenuCheckboxItemProps\n>(function DropdownMenuCheckboxItem({ shortcut, className, children, ...rest }, ref) {\n return (\n <MenuPrimitive.CheckboxItem\n ref={ref}\n className={cx(styles.item, className)}\n data-selectable=\"\"\n {...rest}\n >\n <span className={styles.indicator}>\n <MenuPrimitive.ItemIndicator>\n <CheckIcon />\n </MenuPrimitive.ItemIndicator>\n </span>\n <span className={styles.label}>{children}</span>\n {shortcut ? <kbd className={styles.shortcut}>{shortcut}</kbd> : null}\n </MenuPrimitive.CheckboxItem>\n )\n})\n\nexport type DropdownMenuRadioGroupProps = ComponentPropsWithoutRef<typeof MenuPrimitive.RadioGroup>\n\n/** One-of-many choice. `value` + `onValueChange`. */\nconst DropdownMenuRadioGroup = MenuPrimitive.RadioGroup\n\nexport type DropdownMenuRadioItemProps = ComponentPropsWithoutRef<typeof MenuPrimitive.RadioItem>\n\nconst DropdownMenuRadioItem = forwardRef<\n ComponentRef<typeof MenuPrimitive.RadioItem>,\n DropdownMenuRadioItemProps\n>(function DropdownMenuRadioItem({ className, children, ...rest }, ref) {\n return (\n <MenuPrimitive.RadioItem\n ref={ref}\n className={cx(styles.item, className)}\n data-selectable=\"\"\n {...rest}\n >\n <span className={styles.indicator}>\n <MenuPrimitive.ItemIndicator className={styles.dot} />\n </span>\n <span className={styles.label}>{children}</span>\n </MenuPrimitive.RadioItem>\n )\n})\n\nexport type DropdownMenuLabelProps = ComponentPropsWithoutRef<typeof MenuPrimitive.Label>\n\n/** A non-interactive heading for the group below it. */\nconst DropdownMenuLabel = forwardRef<\n ComponentRef<typeof MenuPrimitive.Label>,\n DropdownMenuLabelProps\n>(function DropdownMenuLabel({ className, ...rest }, ref) {\n return <MenuPrimitive.Label ref={ref} className={cx(styles.menuLabel, className)} {...rest} />\n})\n\nexport type DropdownMenuSeparatorProps = ComponentPropsWithoutRef<typeof MenuPrimitive.Separator>\n\nconst DropdownMenuSeparator = forwardRef<\n ComponentRef<typeof MenuPrimitive.Separator>,\n DropdownMenuSeparatorProps\n>(function DropdownMenuSeparator({ className, ...rest }, ref) {\n return <MenuPrimitive.Separator ref={ref} className={cx(styles.separator, className)} {...rest} />\n})\n\nexport type DropdownMenuGroupProps = ComponentPropsWithoutRef<typeof MenuPrimitive.Group>\n\nconst DropdownMenuGroup = MenuPrimitive.Group\n\nexport type DropdownMenuSubProps = ComponentPropsWithoutRef<typeof MenuPrimitive.Sub>\n\nconst DropdownMenuSub = MenuPrimitive.Sub\n\nexport interface DropdownMenuSubTriggerProps extends ComponentPropsWithoutRef<\n typeof MenuPrimitive.SubTrigger\n> {\n leadingIcon?: ReactNode\n}\n\n/** Opens a submenu on hover, click, or → . */\nconst DropdownMenuSubTrigger = forwardRef<\n ComponentRef<typeof MenuPrimitive.SubTrigger>,\n DropdownMenuSubTriggerProps\n>(function DropdownMenuSubTrigger({ leadingIcon, className, children, ...rest }, ref) {\n return (\n <MenuPrimitive.SubTrigger\n ref={ref}\n className={cx(styles.item, className)}\n data-tone=\"neutral\"\n {...rest}\n >\n {leadingIcon ? <span className={styles.icon}>{leadingIcon}</span> : null}\n <span className={styles.label}>{children}</span>\n <span className={styles.chevron}>\n <ChevronRightIcon />\n </span>\n </MenuPrimitive.SubTrigger>\n )\n})\n\nexport interface DropdownMenuSubContentProps extends ComponentPropsWithoutRef<\n typeof MenuPrimitive.SubContent\n> {\n container?: HTMLElement | null\n}\n\nconst SubContentInner = forwardRef<HTMLDivElement, DropdownMenuSubContentProps>(\n function SubContentInner({ container, sideOffset = 4, className, ...rest }, ref) {\n const theme = usePortalTheme(container)\n return (\n <MenuPrimitive.SubContent\n ref={ref}\n className={cx(styles.content, className)}\n sideOffset={sideOffset}\n collisionPadding={8}\n {...theme}\n {...rest}\n />\n )\n },\n)\n\nconst DropdownMenuSubContent = forwardRef<HTMLDivElement, DropdownMenuSubContentProps>(\n function DropdownMenuSubContent({ container, forceMount, ...rest }, ref) {\n return (\n <MenuPrimitive.Portal container={container} forceMount={forceMount}>\n <SubContentInner ref={ref} container={container} forceMount={forceMount} {...rest} />\n </MenuPrimitive.Portal>\n )\n },\n)\n\nexport const DropdownMenu = Object.assign(DropdownMenuRoot, {\n Root: DropdownMenuRoot,\n Trigger: DropdownMenuTrigger,\n Content: DropdownMenuContent,\n Item: DropdownMenuItem,\n CheckboxItem: DropdownMenuCheckboxItem,\n RadioGroup: DropdownMenuRadioGroup,\n RadioItem: DropdownMenuRadioItem,\n Label: DropdownMenuLabel,\n Separator: DropdownMenuSeparator,\n Group: DropdownMenuGroup,\n Sub: DropdownMenuSub,\n SubTrigger: DropdownMenuSubTrigger,\n SubContent: DropdownMenuSubContent,\n})\n"],"mappings":";;;;;;;;AA4BA,SAASI,EAAiB,GAA0B;CAClD,IAAMC,IAASC,EAAmB;CAClC,OACE,kBAACC,EAAoB,UAArB;EAA8B,OAAOF;EACnC,UAAA,kBAACL,EAAc,MAAf,EAAoB,GAAIS,EAAQ,CAAA;CACJ,CAAA;AAElC;AAIA,IAAMC,IAAsBC,EAG1B,SAA6B,GAAO,GAAK;CACzC,IAAMN,IAASO,EAAgB;CAC/B,OAAO,kBAACZ,EAAc,SAAf;EAAuB,KAAKa,EAAYC,GAAKT,CAAM;EAAG,GAAII;CAAQ,CAAA;AAC3E,CAAC,GASKM,IAAeJ,EAAqD,SACxE,EAAE,cAAW,WAAQ,SAAS,gBAAa,GAAG,cAAW,GAAGK,KAC5D,GACA;CACA,IAAMC,IAAQC,EAAeC,CAAS;CACtC,OACE,kBAACnB,EAAc,SAAf;EACO;EACL,WAAWoB,EAAGnB,EAAO,SAASoB,CAAS;EAChC;EACK;EACZ,kBAAkB;EAClB,GAAIJ;EACJ,GAAID;CACL,CAAA;AAEL,CAAC,GAGKM,IAAsBX,EAC1B,SAA6B,EAAE,cAAW,eAAY,GAAGK,KAAQ,GAAK;CACpE,OACE,kBAAChB,EAAc,QAAf;EAAiC;EAAuB;EACtD,UAAA,kBAACe,GAAD;GAAmB;GAAgB;GAAuB;GAAY,GAAIC;EAAO,CAAA;CAC7D,CAAA;AAE1B,CACF,GAaMO,IAAmBZ,EACvB,SACE,EAAE,UAAO,WAAW,gBAAa,aAAU,cAAW,aAAU,GAAGK,KACnE,GACA;CACA,OACE,kBAAChB,EAAc,MAAf;EACO;EACL,WAAWoB,EAAGnB,EAAO,MAAMoB,CAAS;EACpC,aAAWG;EACX,GAAIR;EAJN,UAAA;GAMGS,IAAc,kBAAC,QAAD;IAAM,WAAWxB,EAAO;IAAO,UAAAwB;GAAkB,CAAA,IAAI;GACpE,kBAAC,QAAD;IAAM,WAAWxB,EAAO;IAAQ;GAAe,CAAA;GAC9CyB,IAAW,kBAAC,OAAD;IAAK,WAAWzB,EAAO;IAAW,UAAAyB;GAAc,CAAA,IAAI;EAC9C;;AAExB,CACF,GASMC,IAA2BhB,EAG/B,SAAkC,EAAE,aAAU,cAAW,aAAU,GAAGK,KAAQ,GAAK;CACnF,OACE,kBAAChB,EAAc,cAAf;EACO;EACL,WAAWoB,EAAGnB,EAAO,MAAMoB,CAAS;EACpC,mBAAgB;EAChB,GAAIL;EAJN,UAAA;GAME,kBAAC,QAAD;IAAM,WAAWf,EAAO;IACtB,UAAA,kBAACD,EAAc,eAAf,EAAA,UACE,kBAAC4B,GAAD,CAAY,CAAA,EACe,CAAA;GACzB,CAAA;GACN,kBAAC,QAAD;IAAM,WAAW3B,EAAO;IAAQ;GAAe,CAAA;GAC9CyB,IAAW,kBAAC,OAAD;IAAK,WAAWzB,EAAO;IAAW,UAAAyB;GAAc,CAAA,IAAI;EACtC;;AAEhC,CAAC,GAKKG,IAAyB7B,EAAc,YAIvC8B,IAAwBnB,EAG5B,SAA+B,EAAE,cAAW,aAAU,GAAGK,KAAQ,GAAK;CACtE,OACE,kBAAChB,EAAc,WAAf;EACO;EACL,WAAWoB,EAAGnB,EAAO,MAAMoB,CAAS;EACpC,mBAAgB;EAChB,GAAIL;EAJN,UAAA,CAME,kBAAC,QAAD;GAAM,WAAWf,EAAO;GACtB,UAAA,kBAACD,EAAc,eAAf,EAA6B,WAAWC,EAAO,IAAM,CAAA;EACjD,CAAA,GACN,kBAAC,QAAD;GAAM,WAAWA,EAAO;GAAQ;EAAe,CAAA,CACxB;;AAE7B,CAAC,GAKK8B,IAAoBpB,EAGxB,SAA2B,EAAE,cAAW,GAAGK,KAAQ,GAAK;CACxD,OAAO,kBAAChB,EAAc,OAAf;EAA0B;EAAK,WAAWoB,EAAGnB,EAAO,WAAWoB,CAAS;EAAG,GAAIL;CAAO,CAAA;AAC/F,CAAC,GAIKgB,IAAwBrB,EAG5B,SAA+B,EAAE,cAAW,GAAGK,KAAQ,GAAK;CAC5D,OAAO,kBAAChB,EAAc,WAAf;EAA8B;EAAK,WAAWoB,EAAGnB,EAAO,WAAWoB,CAAS;EAAG,GAAIL;CAAO,CAAA;AACnG,CAAC,GAIKiB,IAAoBjC,EAAc,OAIlCkC,IAAkBlC,EAAc,KAShCmC,IAAyBxB,EAG7B,SAAgC,EAAE,gBAAa,cAAW,aAAU,GAAGK,KAAQ,GAAK;CACpF,OACE,kBAAChB,EAAc,YAAf;EACO;EACL,WAAWoB,EAAGnB,EAAO,MAAMoB,CAAS;EACpC,aAAU;EACV,GAAIL;EAJN,UAAA;GAMGS,IAAc,kBAAC,QAAD;IAAM,WAAWxB,EAAO;IAAO,UAAAwB;GAAkB,CAAA,IAAI;GACpE,kBAAC,QAAD;IAAM,WAAWxB,EAAO;IAAQ;GAAe,CAAA;GAC/C,kBAAC,QAAD;IAAM,WAAWA,EAAO;IACtB,UAAA,kBAACmC,GAAD,CAAmB,CAAA;GACf,CAAA;EACkB;;AAE9B,CAAC,GAQKC,IAAkB1B,EACtB,SAAyB,EAAE,cAAW,gBAAa,GAAG,cAAW,GAAGK,KAAQ,GAAK;CAC/E,IAAMC,IAAQC,EAAeC,CAAS;CACtC,OACE,kBAACnB,EAAc,YAAf;EACO;EACL,WAAWoB,EAAGnB,EAAO,SAASoB,CAAS;EAC3B;EACZ,kBAAkB;EAClB,GAAIJ;EACJ,GAAID;CACL,CAAA;AAEL,CACF,GAEMsB,IAAyB3B,EAC7B,SAAgC,EAAE,cAAW,eAAY,GAAGK,KAAQ,GAAK;CACvE,OACE,kBAAChB,EAAc,QAAf;EAAiC;EAAuB;EACtD,UAAA,kBAACqC,GAAD;GAAsB;GAAgB;GAAuB;GAAY,GAAIrB;EAAO,CAAA;CAChE,CAAA;AAE1B,CACF,GAEad,IAAe,OAAO,OAAOE,GAAkB;CAC1D,MAAMA;CACN,SAASM;CACT,SAASY;CACT,MAAMC;CACN,cAAcI;CACd,YAAYE;CACZ,WAAWC;CACX,OAAOC;CACP,WAAWC;CACX,OAAOC;CACP,KAAKC;CACL,YAAYC;CACZ,YAAYG;AACd,CAAC"}
|
|
1
|
+
{"version":3,"file":"DropdownMenu.js","names":["MenuPrimitive","styles","DropdownMenu","DropdownMenu_module_default","DropdownMenuRoot","anchor","usePortalAnchorRef","PortalAnchorContext","DropdownMenu","props","DropdownMenuTrigger","forwardRef","usePortalAnchor","composeRefs","ref","ContentInner","rest","theme","usePortalTheme","container","cx","className","DropdownMenuContent","DropdownMenuItem","tone","leadingIcon","shortcut","DropdownMenuCheckboxItem","CheckIcon","DropdownMenuRadioGroup","DropdownMenuRadioItem","DropdownMenuLabel","DropdownMenuSeparator","DropdownMenuGroup","DropdownMenuSub","DropdownMenuSubTrigger","ChevronRightIcon","SubContentInner","DropdownMenuSubContent","DropdownMenu$1"],"sources":["../../../../src/components/overlays/DropdownMenu/DropdownMenu.tsx"],"sourcesContent":["import { forwardRef, type ComponentPropsWithoutRef, type ComponentRef, type ReactNode } from 'react'\nimport { DropdownMenu as MenuPrimitive } from 'radix-ui'\nimport { CheckIcon, ChevronRightIcon } from '#icons'\nimport { cx } from '#utils/cx'\nimport {\n PortalAnchorContext,\n composeRefs,\n usePortalAnchor,\n usePortalAnchorRef,\n usePortalTheme,\n} from '#components/overlays/usePortalTheme'\nimport styles from './DropdownMenu.module.css'\n\nexport type DropdownMenuProps = ComponentPropsWithoutRef<typeof MenuPrimitive.Root>\n\n/**\n * A list of commands behind a button, with checkboxes, radio groups, submenus and full keyboard\n * support.\n *\n * @remarks\n * `DropdownMenu` holds the actions you don't need to see all the time: a row's options, a sort\n * order. It's Radix Menu underneath, so arrow keys, typeahead, Home, End and Escape all work.\n *\n * @privateRemarks\n * A list of commands behind a button: row actions, a member's options, sort order.\n * Full keyboard support (arrows, typeahead, Home/End, Escape) from Radix.\n *\n * <DropdownMenu>\n * <DropdownMenu.Trigger asChild><Button>Options</Button></DropdownMenu.Trigger>\n * <DropdownMenu.Content>\n * <DropdownMenu.Item shortcut=\"⌘E\">Edit</DropdownMenu.Item>\n * <DropdownMenu.Separator />\n * <DropdownMenu.Item tone=\"critical\">Remove</DropdownMenu.Item>\n * </DropdownMenu.Content>\n * </DropdownMenu>\n */\nfunction DropdownMenuRoot(props: DropdownMenuProps) {\n const anchor = usePortalAnchorRef()\n return (\n <PortalAnchorContext.Provider value={anchor}>\n <MenuPrimitive.Root {...props} />\n </PortalAnchorContext.Provider>\n )\n}\n\nexport type DropdownMenuTriggerProps = ComponentPropsWithoutRef<typeof MenuPrimitive.Trigger>\n\nconst DropdownMenuTrigger = forwardRef<\n ComponentRef<typeof MenuPrimitive.Trigger>,\n DropdownMenuTriggerProps\n>(function DropdownMenuTrigger(props, ref) {\n const anchor = usePortalAnchor()\n return <MenuPrimitive.Trigger ref={composeRefs(ref, anchor)} {...props} />\n})\n\nexport interface DropdownMenuContentProps extends ComponentPropsWithoutRef<\n typeof MenuPrimitive.Content\n> {\n /** Portal target. Defaults to `document.body`; its theme scope is also used. */\n container?: HTMLElement | null\n}\n\nconst ContentInner = forwardRef<HTMLDivElement, DropdownMenuContentProps>(function ContentInner(\n { container, align = 'start', sideOffset = 6, className, ...rest },\n ref,\n) {\n const theme = usePortalTheme(container)\n return (\n <MenuPrimitive.Content\n ref={ref}\n className={cx(styles.content, className)}\n align={align}\n sideOffset={sideOffset}\n collisionPadding={8}\n {...theme}\n {...rest}\n />\n )\n})\n\n/** The menu panel. Aligns to the trigger's start edge by default and flips to stay on screen. */\nconst DropdownMenuContent = forwardRef<HTMLDivElement, DropdownMenuContentProps>(\n function DropdownMenuContent({ container, forceMount, ...rest }, ref) {\n return (\n <MenuPrimitive.Portal container={container} forceMount={forceMount}>\n <ContentInner ref={ref} container={container} forceMount={forceMount} {...rest} />\n </MenuPrimitive.Portal>\n )\n },\n)\n\nexport type DropdownMenuItemTone = 'neutral' | 'critical'\n\nexport interface DropdownMenuItemProps extends ComponentPropsWithoutRef<typeof MenuPrimitive.Item> {\n /** `critical` for destructive commands. Put them last, after a separator. */\n tone?: DropdownMenuItemTone\n /** Icon before the label. Use sparingly — one menu, icons on all items or none. */\n leadingIcon?: ReactNode\n /** Keyboard shortcut hint, shown right-aligned. Display only; wire the shortcut yourself. */\n shortcut?: ReactNode\n}\n\nconst DropdownMenuItem = forwardRef<ComponentRef<typeof MenuPrimitive.Item>, DropdownMenuItemProps>(\n function DropdownMenuItem(\n { tone = 'neutral', leadingIcon, shortcut, className, children, ...rest },\n ref,\n ) {\n return (\n <MenuPrimitive.Item\n ref={ref}\n className={cx(styles.item, className)}\n data-tone={tone}\n {...rest}\n >\n {leadingIcon ? <span className={styles.icon}>{leadingIcon}</span> : null}\n <span className={styles.label}>{children}</span>\n {shortcut ? <kbd className={styles.shortcut}>{shortcut}</kbd> : null}\n </MenuPrimitive.Item>\n )\n },\n)\n\nexport interface DropdownMenuCheckboxItemProps extends ComponentPropsWithoutRef<\n typeof MenuPrimitive.CheckboxItem\n> {\n shortcut?: ReactNode\n}\n\n/** A toggle. Controlled with `checked` + `onCheckedChange`. Stays open on select only if you `preventDefault`. */\nconst DropdownMenuCheckboxItem = forwardRef<\n ComponentRef<typeof MenuPrimitive.CheckboxItem>,\n DropdownMenuCheckboxItemProps\n>(function DropdownMenuCheckboxItem({ shortcut, className, children, ...rest }, ref) {\n return (\n <MenuPrimitive.CheckboxItem\n ref={ref}\n className={cx(styles.item, className)}\n data-selectable=\"\"\n {...rest}\n >\n <span className={styles.indicator}>\n <MenuPrimitive.ItemIndicator>\n <CheckIcon />\n </MenuPrimitive.ItemIndicator>\n </span>\n <span className={styles.label}>{children}</span>\n {shortcut ? <kbd className={styles.shortcut}>{shortcut}</kbd> : null}\n </MenuPrimitive.CheckboxItem>\n )\n})\n\nexport type DropdownMenuRadioGroupProps = ComponentPropsWithoutRef<typeof MenuPrimitive.RadioGroup>\n\n/** One-of-many choice. `value` + `onValueChange`. */\nconst DropdownMenuRadioGroup = MenuPrimitive.RadioGroup\n\nexport type DropdownMenuRadioItemProps = ComponentPropsWithoutRef<typeof MenuPrimitive.RadioItem>\n\nconst DropdownMenuRadioItem = forwardRef<\n ComponentRef<typeof MenuPrimitive.RadioItem>,\n DropdownMenuRadioItemProps\n>(function DropdownMenuRadioItem({ className, children, ...rest }, ref) {\n return (\n <MenuPrimitive.RadioItem\n ref={ref}\n className={cx(styles.item, className)}\n data-selectable=\"\"\n {...rest}\n >\n <span className={styles.indicator}>\n <MenuPrimitive.ItemIndicator className={styles.dot} />\n </span>\n <span className={styles.label}>{children}</span>\n </MenuPrimitive.RadioItem>\n )\n})\n\nexport type DropdownMenuLabelProps = ComponentPropsWithoutRef<typeof MenuPrimitive.Label>\n\n/** A non-interactive heading for the group below it. */\nconst DropdownMenuLabel = forwardRef<\n ComponentRef<typeof MenuPrimitive.Label>,\n DropdownMenuLabelProps\n>(function DropdownMenuLabel({ className, ...rest }, ref) {\n return <MenuPrimitive.Label ref={ref} className={cx(styles.menuLabel, className)} {...rest} />\n})\n\nexport type DropdownMenuSeparatorProps = ComponentPropsWithoutRef<typeof MenuPrimitive.Separator>\n\nconst DropdownMenuSeparator = forwardRef<\n ComponentRef<typeof MenuPrimitive.Separator>,\n DropdownMenuSeparatorProps\n>(function DropdownMenuSeparator({ className, ...rest }, ref) {\n return <MenuPrimitive.Separator ref={ref} className={cx(styles.separator, className)} {...rest} />\n})\n\nexport type DropdownMenuGroupProps = ComponentPropsWithoutRef<typeof MenuPrimitive.Group>\n\nconst DropdownMenuGroup = MenuPrimitive.Group\n\nexport type DropdownMenuSubProps = ComponentPropsWithoutRef<typeof MenuPrimitive.Sub>\n\nconst DropdownMenuSub = MenuPrimitive.Sub\n\nexport interface DropdownMenuSubTriggerProps extends ComponentPropsWithoutRef<\n typeof MenuPrimitive.SubTrigger\n> {\n leadingIcon?: ReactNode\n}\n\n/** Opens a submenu on hover, click, or → . */\nconst DropdownMenuSubTrigger = forwardRef<\n ComponentRef<typeof MenuPrimitive.SubTrigger>,\n DropdownMenuSubTriggerProps\n>(function DropdownMenuSubTrigger({ leadingIcon, className, children, ...rest }, ref) {\n return (\n <MenuPrimitive.SubTrigger\n ref={ref}\n className={cx(styles.item, className)}\n data-tone=\"neutral\"\n {...rest}\n >\n {leadingIcon ? <span className={styles.icon}>{leadingIcon}</span> : null}\n <span className={styles.label}>{children}</span>\n <span className={styles.chevron}>\n <ChevronRightIcon />\n </span>\n </MenuPrimitive.SubTrigger>\n )\n})\n\nexport interface DropdownMenuSubContentProps extends ComponentPropsWithoutRef<\n typeof MenuPrimitive.SubContent\n> {\n container?: HTMLElement | null\n}\n\nconst SubContentInner = forwardRef<HTMLDivElement, DropdownMenuSubContentProps>(\n function SubContentInner({ container, sideOffset = 4, className, ...rest }, ref) {\n const theme = usePortalTheme(container)\n return (\n <MenuPrimitive.SubContent\n ref={ref}\n className={cx(styles.content, className)}\n sideOffset={sideOffset}\n collisionPadding={8}\n {...theme}\n {...rest}\n />\n )\n },\n)\n\nconst DropdownMenuSubContent = forwardRef<HTMLDivElement, DropdownMenuSubContentProps>(\n function DropdownMenuSubContent({ container, forceMount, ...rest }, ref) {\n return (\n <MenuPrimitive.Portal container={container} forceMount={forceMount}>\n <SubContentInner ref={ref} container={container} forceMount={forceMount} {...rest} />\n </MenuPrimitive.Portal>\n )\n },\n)\n\nexport const DropdownMenu = Object.assign(DropdownMenuRoot, {\n Root: DropdownMenuRoot,\n Trigger: DropdownMenuTrigger,\n Content: DropdownMenuContent,\n Item: DropdownMenuItem,\n CheckboxItem: DropdownMenuCheckboxItem,\n RadioGroup: DropdownMenuRadioGroup,\n RadioItem: DropdownMenuRadioItem,\n Label: DropdownMenuLabel,\n Separator: DropdownMenuSeparator,\n Group: DropdownMenuGroup,\n Sub: DropdownMenuSub,\n SubTrigger: DropdownMenuSubTrigger,\n SubContent: DropdownMenuSubContent,\n})\n"],"mappings":"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"}
|
|
@@ -2,6 +2,13 @@ import { type ComponentPropsWithoutRef } from 'react';
|
|
|
2
2
|
import { Popover as PopoverPrimitive } from 'radix-ui';
|
|
3
3
|
export type PopoverProps = ComponentPropsWithoutRef<typeof PopoverPrimitive.Root>;
|
|
4
4
|
/**
|
|
5
|
+
* A non-modal panel anchored to its trigger, for details, a filter or a small form.
|
|
6
|
+
*
|
|
7
|
+
* @remarks
|
|
8
|
+
* `Popover` opens a floating panel beside its trigger. It's non-modal: the rest of the page stays
|
|
9
|
+
* usable, and it closes on Escape or a click outside, returning focus to the trigger.
|
|
10
|
+
*
|
|
11
|
+
* @privateRemarks
|
|
5
12
|
* Non-modal floating panel anchored to a trigger: invoice details, a filter, a small
|
|
6
13
|
* form. Opens on click, closes on Escape or an outside click, returns focus. For
|
|
7
14
|
* hover-only hints use `Tooltip`; for a list of commands use `DropdownMenu`.
|