@elmeragroup/fuse 0.1.0-canary.2 → 0.1.0-canary.20
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 +42 -0
- package/button.d.ts +2 -2
- package/components/button/button-variants.d.ts +3 -3
- package/components/button/button-variants.d.ts.map +1 -1
- package/components/button/button-variants.js +9 -6
- package/components/button/button-variants.js.map +1 -1
- package/components/button/button.d.ts +49 -10
- package/components/button/button.d.ts.map +1 -1
- package/components/button/button.js +23 -4
- package/components/button/button.js.map +1 -1
- package/components/checkbox/checkbox.d.ts +4 -1
- package/components/checkbox/checkbox.d.ts.map +1 -1
- package/components/checkbox/checkbox.js.map +1 -1
- package/components/data-table/actions-column.d.ts +50 -0
- package/components/data-table/actions-column.d.ts.map +1 -0
- package/components/data-table/actions-column.js +31 -0
- package/components/data-table/actions-column.js.map +1 -0
- package/components/data-table/create-fuse-table-hook.d.ts +119 -0
- package/components/data-table/create-fuse-table-hook.d.ts.map +1 -0
- package/components/data-table/create-fuse-table-hook.js +76 -0
- package/components/data-table/create-fuse-table-hook.js.map +1 -0
- package/components/data-table/data-table-cells.d.ts +64 -0
- package/components/data-table/data-table-cells.d.ts.map +1 -0
- package/components/data-table/data-table-cells.js +71 -0
- package/components/data-table/data-table-cells.js.map +1 -0
- package/components/data-table/data-table-column-toggle.d.ts +28 -0
- package/components/data-table/data-table-column-toggle.d.ts.map +1 -0
- package/components/data-table/data-table-column-toggle.js +40 -0
- package/components/data-table/data-table-column-toggle.js.map +1 -0
- package/components/data-table/data-table-contexts.d.ts +14 -0
- package/components/data-table/data-table-contexts.d.ts.map +1 -0
- package/components/data-table/data-table-contexts.js +17 -0
- package/components/data-table/data-table-contexts.js.map +1 -0
- package/components/data-table/data-table-format.d.ts +19 -0
- package/components/data-table/data-table-format.d.ts.map +1 -0
- package/components/data-table/data-table-format.js +69 -0
- package/components/data-table/data-table-format.js.map +1 -0
- package/components/data-table/data-table-pagination-status.d.ts +44 -0
- package/components/data-table/data-table-pagination-status.d.ts.map +1 -0
- package/components/data-table/data-table-pagination-status.js +34 -0
- package/components/data-table/data-table-pagination-status.js.map +1 -0
- package/components/data-table/data-table-pagination.d.ts +40 -0
- package/components/data-table/data-table-pagination.d.ts.map +1 -0
- package/components/data-table/data-table-pagination.js +121 -0
- package/components/data-table/data-table-pagination.js.map +1 -0
- package/components/data-table/data-table-registered.d.ts +69 -0
- package/components/data-table/data-table-registered.d.ts.map +1 -0
- package/components/data-table/data-table-registered.js +205 -0
- package/components/data-table/data-table-registered.js.map +1 -0
- package/components/data-table/data-table-row-actions.d.ts +34 -0
- package/components/data-table/data-table-row-actions.d.ts.map +1 -0
- package/components/data-table/data-table-row-actions.js +61 -0
- package/components/data-table/data-table-row-actions.js.map +1 -0
- package/components/data-table/data-table-selection.d.ts +35 -0
- package/components/data-table/data-table-selection.d.ts.map +1 -0
- package/components/data-table/data-table-selection.js +44 -0
- package/components/data-table/data-table-selection.js.map +1 -0
- package/components/data-table/data-table-sort-button.d.ts +22 -0
- package/components/data-table/data-table-sort-button.d.ts.map +1 -0
- package/components/data-table/data-table-sort-button.js +43 -0
- package/components/data-table/data-table-sort-button.js.map +1 -0
- package/components/data-table/data-table-source.d.ts +99 -0
- package/components/data-table/data-table-source.d.ts.map +1 -0
- package/components/data-table/data-table-source.js +0 -0
- package/components/data-table/data-table-variants.d.ts +61 -0
- package/components/data-table/data-table-variants.d.ts.map +1 -0
- package/components/data-table/data-table-variants.js +30 -0
- package/components/data-table/data-table-variants.js.map +1 -0
- package/components/data-table/data-table.d.ts +108 -0
- package/components/data-table/data-table.d.ts.map +1 -0
- package/components/data-table/data-table.js +209 -0
- package/components/data-table/data-table.js.map +1 -0
- package/components/data-table/index.d.ts +27 -0
- package/components/data-table/index.d.ts.map +1 -0
- package/components/data-table/index.js +34 -0
- package/components/data-table/index.js.map +1 -0
- package/components/data-table/intl/en-US.d.ts +19 -0
- package/components/data-table/intl/en-US.d.ts.map +1 -0
- package/components/data-table/intl/en-US.js +20 -0
- package/components/data-table/intl/en-US.js.map +1 -0
- package/components/data-table/intl/fi-FI.d.ts +19 -0
- package/components/data-table/intl/fi-FI.d.ts.map +1 -0
- package/components/data-table/intl/fi-FI.js +20 -0
- package/components/data-table/intl/fi-FI.js.map +1 -0
- package/components/data-table/intl/index.d.ts +5 -0
- package/components/data-table/intl/index.d.ts.map +1 -0
- package/components/data-table/intl/index.js +17 -0
- package/components/data-table/intl/index.js.map +1 -0
- package/components/data-table/intl/nb-NO.d.ts +19 -0
- package/components/data-table/intl/nb-NO.d.ts.map +1 -0
- package/components/data-table/intl/nb-NO.js +20 -0
- package/components/data-table/intl/nb-NO.js.map +1 -0
- package/components/data-table/intl/sv-SE.d.ts +19 -0
- package/components/data-table/intl/sv-SE.d.ts.map +1 -0
- package/components/data-table/intl/sv-SE.js +20 -0
- package/components/data-table/intl/sv-SE.js.map +1 -0
- package/components/data-table/select-column.d.ts +47 -0
- package/components/data-table/select-column.d.ts.map +1 -0
- package/components/data-table/select-column.js +29 -0
- package/components/data-table/select-column.js.map +1 -0
- package/components/dropdown-menu/dropdown-menu-variants.d.ts +40 -0
- package/components/dropdown-menu/dropdown-menu-variants.d.ts.map +1 -0
- package/components/field/field-frame.d.ts +3 -16
- package/components/field/field-frame.d.ts.map +1 -1
- package/components/field/field-frame.js +3 -5
- package/components/field/field-frame.js.map +1 -1
- package/components/field/field.d.ts +10 -1
- package/components/field/field.d.ts.map +1 -1
- package/components/field/field.js +17 -2
- package/components/field/field.js.map +1 -1
- package/components/form/form.d.ts +19 -0
- package/components/form/form.d.ts.map +1 -0
- package/components/form/form.js +23 -0
- package/components/form/form.js.map +1 -0
- package/components/input-group/input-group-variants.d.ts +11 -9
- package/components/input-group/input-group-variants.d.ts.map +1 -1
- package/components/input-group/input-group-variants.js +10 -7
- package/components/input-group/input-group-variants.js.map +1 -1
- package/components/input-group/input-group.d.ts.map +1 -1
- package/components/input-group/input-group.js +4 -3
- package/components/input-group/input-group.js.map +1 -1
- package/components/meter/meter-tone.d.ts +1 -80
- package/components/meter/meter-tone.d.ts.map +1 -1
- package/components/meter/meter-tone.js +1 -1
- package/components/meter/meter-tone.js.map +1 -1
- package/components/navigation-menu/index.d.ts +14 -0
- package/components/navigation-menu/index.d.ts.map +1 -0
- package/components/navigation-menu/index.js +21 -0
- package/components/navigation-menu/index.js.map +1 -0
- package/components/navigation-menu/navigation-menu-variants.d.ts +115 -0
- package/components/navigation-menu/navigation-menu-variants.d.ts.map +1 -0
- package/components/navigation-menu/navigation-menu-variants.js +86 -0
- package/components/navigation-menu/navigation-menu-variants.js.map +1 -0
- package/components/navigation-menu/navigation-menu.d.ts +99 -0
- package/components/navigation-menu/navigation-menu.d.ts.map +1 -0
- package/components/navigation-menu/navigation-menu.js +156 -0
- package/components/navigation-menu/navigation-menu.js.map +1 -0
- package/components/number-field/number-field.d.ts +4 -1
- package/components/number-field/number-field.d.ts.map +1 -1
- package/components/number-field/number-field.js.map +1 -1
- package/components/overlay/overlay-classes.d.ts +9 -5
- package/components/overlay/overlay-classes.d.ts.map +1 -1
- package/components/overlay/overlay-classes.js +1 -1
- package/components/overlay/overlay-classes.js.map +1 -1
- package/components/phone-number-field/phone-engine.d.ts +0 -2
- package/components/phone-number-field/phone-engine.d.ts.map +1 -1
- package/components/phone-number-field/phone-engine.js +1 -1
- package/components/phone-number-field/phone-engine.js.map +1 -1
- package/components/phone-number-field/phone-number-field.d.ts +5 -1
- package/components/phone-number-field/phone-number-field.d.ts.map +1 -1
- package/components/phone-number-field/phone-number-field.js +4 -4
- package/components/phone-number-field/phone-number-field.js.map +1 -1
- package/components/radio-group/radio-group.d.ts +4 -1
- package/components/radio-group/radio-group.d.ts.map +1 -1
- package/components/radio-group/radio-group.js +1 -1
- package/components/radio-group/radio-group.js.map +1 -1
- package/components/select/fixed-containing-block.d.ts +16 -0
- package/components/select/fixed-containing-block.d.ts.map +1 -0
- package/components/select/fixed-containing-block.js +34 -0
- package/components/select/fixed-containing-block.js.map +1 -0
- package/components/select/select.d.ts +10 -1
- package/components/select/select.d.ts.map +1 -1
- package/components/select/select.js +52 -6
- package/components/select/select.js.map +1 -1
- package/components/selection-item/selection-item.d.ts +0 -1
- package/components/selection-item/selection-item.d.ts.map +1 -1
- package/components/selection-item/selection-item.js +3 -3
- package/components/selection-item/selection-item.js.map +1 -1
- package/components/sidebar/sidebar.d.ts.map +1 -1
- package/components/sidebar/sidebar.js +17 -9
- package/components/sidebar/sidebar.js.map +1 -1
- package/components/text-field/text-field.d.ts +11 -2
- package/components/text-field/text-field.d.ts.map +1 -1
- package/components/text-field/text-field.js +48 -1
- package/components/text-field/text-field.js.map +1 -1
- package/components/textarea-field/textarea-field.d.ts +4 -1
- package/components/textarea-field/textarea-field.d.ts.map +1 -1
- package/components/textarea-field/textarea-field.js.map +1 -1
- package/components/toast/toast.js +3 -3
- package/components/toast/toast.js.map +1 -1
- package/data-table.d.ts +14 -0
- package/data-table.js +6 -0
- package/form.d.ts +2 -0
- package/form.js +2 -0
- package/icons/bespoke/trondelagkraft-logo-full.js +55 -392
- package/icons/bespoke/trondelagkraft-logo-full.js.map +1 -1
- package/icons/generated/caret-double-left.d.ts +10 -0
- package/icons/generated/caret-double-left.d.ts.map +1 -0
- package/icons/generated/caret-double-left.js +13 -0
- package/icons/generated/caret-double-left.js.map +1 -0
- package/icons/generated/caret-double-right.d.ts +10 -0
- package/icons/generated/caret-double-right.d.ts.map +1 -0
- package/icons/generated/caret-double-right.js +13 -0
- package/icons/generated/caret-double-right.js.map +1 -0
- package/icons.d.ts +3 -1
- package/icons.js +8 -6
- package/index.d.ts +9 -4
- package/index.js +5 -3
- package/navigation-menu.d.ts +3 -0
- package/navigation-menu.js +2 -0
- package/package.json +18 -2
- package/react-aria/calendar/calendar.js +1 -1
- package/react-aria/internal/compose-tailwind-render-props.d.ts +5 -0
- package/react-aria/internal/compose-tailwind-render-props.d.ts.map +1 -1
- package/react-aria/internal/compose-tailwind-render-props.js +5 -0
- package/react-aria/internal/compose-tailwind-render-props.js.map +1 -1
- package/react-aria/internal/field.js +4 -0
- package/react-aria/internal/field.js.map +1 -1
- package/react-aria/internal/popover.d.ts +1 -1
- package/react-aria/internal/popover.d.ts.map +1 -1
- package/react-aria/internal/popover.js +57 -2
- package/react-aria/internal/popover.js.map +1 -1
- package/styles/control-size-md.d.ts +11 -0
- package/styles/control-size-md.d.ts.map +1 -1
- package/styles/control-size-md.js +12 -1
- package/styles/control-size-md.js.map +1 -1
- package/styles/control-size.d.ts +2 -9
- package/styles/control-size.d.ts.map +1 -1
- package/styles/control-size.js.map +1 -1
- package/styles/corner-radius.d.ts.map +1 -1
- package/styles/corner-radius.js +5 -5
- package/styles/corner-radius.js.map +1 -1
- package/styles/field-box.d.ts +10 -2
- package/styles/field-box.d.ts.map +1 -1
- package/styles/field-box.js +11 -3
- package/styles/field-box.js.map +1 -1
- package/styles/fuse.css +27 -6
- package/styles.css +257 -44
- package/theme/color-scheme-runtime.d.ts +1 -1
- package/theme/color-scheme-runtime.d.ts.map +1 -1
- package/theme/color-scheme-runtime.js.map +1 -1
- package/theme/theme-context.d.ts +1 -1
- package/theme/theme-context.d.ts.map +1 -1
- package/theme/theme-context.js.map +1 -1
- package/theme.d.ts +1 -1
- package/themes.css +39 -7
package/README.md
CHANGED
|
@@ -15,6 +15,48 @@ Requires Tailwind CSS 4.1 or newer. Published code is not scanned by a consumer
|
|
|
15
15
|
|
|
16
16
|
Adjust the `@source` path only when the stylesheet is not one directory below the app root.
|
|
17
17
|
|
|
18
|
+
### What `fuse/css` changes in your theme
|
|
19
|
+
|
|
20
|
+
`@elmeragroup/fuse/css` is not only the components' variants and control metrics. Importing it into a Tailwind build also changes these parts of the host theme, whether or not `themes.css` is imported:
|
|
21
|
+
|
|
22
|
+
- **Role and primitive colours.** Its `@theme inline` block maps every role token (`--color-primary` → `var(--primary)` and so on) and remaps Tailwind's `neutral-50` to `neutral-950` palette onto `--neutral-*`. `themes.css` defines those; without it, `bg-neutral-200` and the other stock neutral utilities resolve to an undefined colour until you define `--neutral-*` yourself.
|
|
23
|
+
- **Radius scale.** `rounded-xs` to `rounded-xl` become whole `--radius-step` multiples from `--radius` instead of Tailwind's fixed rems. The step falls back to `0px`, so with your own `--radius` and no `themes.css` every rung is that one radius; `--radius` itself has no fallback. Button rounds with `--radius-button`, which `themes.css` sets per theme; define it (`--radius-button: var(--radius)`) when you skip `themes.css`.
|
|
24
|
+
- **State variants.** It declares `data-open`, `data-closed`, `data-checked`, `data-unchecked`, `data-selected`, `data-disabled`, `data-active`, `data-horizontal` and `data-vertical` as static variants, wrapped in `:where()`. They replace Tailwind's functional `data-*` variants of the same name in your own classes too: their specificity drops to one class, so a plain `hover:` rule beats a `data-selected:` rule, `data-open:` and the like also match Radix-style `data-state` values, and `data-selected:` matches only `data-selected="true"`. Other `data-*` names are untouched.
|
|
25
|
+
- **Also:** `enabled-hover:`, `enabled-active:`, `disabled-state:`, `hit-area-*`, `no-scrollbar`, the `rounded-button`, `font-sans`, `font-heading` and `font-mono` utilities, the `xs`, `lg` and `3xl` breakpoints, `--spacing: 0.25rem`, the `overshoot` easing, `tw-animate-css`, the React Aria Tailwind plugin, and a reduced-motion rule that switches off transform and layout transitions document-wide.
|
|
26
|
+
|
|
27
|
+
### Keeping your own tokens
|
|
28
|
+
|
|
29
|
+
A host that migrates one component at a time can keep its own design tokens and skip `themes.css`:
|
|
30
|
+
|
|
31
|
+
```css
|
|
32
|
+
@import "tailwindcss";
|
|
33
|
+
@import "@elmeragroup/fuse/css";
|
|
34
|
+
@source "../node_modules/@elmeragroup/fuse";
|
|
35
|
+
|
|
36
|
+
@theme {
|
|
37
|
+
/* Your tokens. This block comes after fuse/css, so where both define a theme variable, yours wins. */
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
:root {
|
|
41
|
+
/* Map the role tokens the components you use read, in any colour notation. */
|
|
42
|
+
--primary: var(--your-brand);
|
|
43
|
+
--primary-foreground: #fff;
|
|
44
|
+
--radius: 0.5rem;
|
|
45
|
+
--radius-button: var(--radius);
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Import `fuse/css` before your own `@theme` so your values win where both define one. Each component page in the docs lists the tokens that component reads under "Tokens consumed"; map those, and add the next component's list when you adopt it. Role tokens are whole colours (`oklch()`, `hsl()`, hex), not channel triplets.
|
|
50
|
+
|
|
51
|
+
Button's `outline` variant reads `--button-outline` and `--button-outline-width`. Without them it draws a 1px hairline in your `--border`, as internal themes do. For the external themes' outline, a 2px ring in the text colour with no shadow, set both:
|
|
52
|
+
|
|
53
|
+
```css
|
|
54
|
+
:root {
|
|
55
|
+
--button-outline: var(--foreground);
|
|
56
|
+
--button-outline-width: 2px;
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
18
60
|
## Non-Tailwind
|
|
19
61
|
|
|
20
62
|
```css
|
package/button.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { buttonVariants } from "./components/button/button-variants.js";
|
|
2
|
-
import { Button, ButtonProps } from "./components/button/button.js";
|
|
3
|
-
export { Button, type ButtonProps, buttonVariants };
|
|
2
|
+
import { Button, ButtonProps, ButtonSize, IconButtonProps, IconButtonSize, LabelButtonProps, LabelButtonSize } from "./components/button/button.js";
|
|
3
|
+
export { Button, type ButtonProps, type ButtonSize, type IconButtonProps, type IconButtonSize, type LabelButtonProps, type LabelButtonSize, buttonVariants };
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
export declare const buttonVariants: import("tailwind-variants").TVReturnType<{
|
|
3
3
|
variant: {
|
|
4
4
|
default: "bg-primary text-primary-foreground enabled-hover:bg-primary/80";
|
|
5
|
-
outline: "
|
|
5
|
+
outline: "border-[length:var(--button-outline-width,1px)] border-button-outline bg-background shadow-[0_1px_max(0px,4px-2*var(--button-outline-width,1px))_min(0px,2px-2*var(--button-outline-width,1px))_rgb(0_0_0/0.05)] aria-expanded:bg-muted aria-expanded:text-foreground enabled-hover:bg-muted enabled-hover:text-foreground";
|
|
6
6
|
secondary: "bg-secondary text-secondary-foreground aria-expanded:bg-secondary aria-expanded:text-secondary-foreground enabled-hover:bg-secondary-hover";
|
|
7
7
|
ghost: "aria-expanded:bg-muted aria-expanded:text-foreground enabled-hover:bg-muted enabled-hover:text-foreground";
|
|
8
8
|
destructive: "border-error/20 bg-error/10 text-error enabled-hover:border-error enabled-hover:bg-error/20";
|
|
@@ -23,7 +23,7 @@ export declare const buttonVariants: import("tailwind-variants").TVReturnType<{
|
|
|
23
23
|
}, undefined, string, {
|
|
24
24
|
variant: {
|
|
25
25
|
default: "bg-primary text-primary-foreground enabled-hover:bg-primary/80";
|
|
26
|
-
outline: "
|
|
26
|
+
outline: "border-[length:var(--button-outline-width,1px)] border-button-outline bg-background shadow-[0_1px_max(0px,4px-2*var(--button-outline-width,1px))_min(0px,2px-2*var(--button-outline-width,1px))_rgb(0_0_0/0.05)] aria-expanded:bg-muted aria-expanded:text-foreground enabled-hover:bg-muted enabled-hover:text-foreground";
|
|
27
27
|
secondary: "bg-secondary text-secondary-foreground aria-expanded:bg-secondary aria-expanded:text-secondary-foreground enabled-hover:bg-secondary-hover";
|
|
28
28
|
ghost: "aria-expanded:bg-muted aria-expanded:text-foreground enabled-hover:bg-muted enabled-hover:text-foreground";
|
|
29
29
|
destructive: "border-error/20 bg-error/10 text-error enabled-hover:border-error enabled-hover:bg-error/20";
|
|
@@ -44,7 +44,7 @@ export declare const buttonVariants: import("tailwind-variants").TVReturnType<{
|
|
|
44
44
|
}, undefined, import("tailwind-variants").TVReturnTypeLike<{
|
|
45
45
|
variant: {
|
|
46
46
|
default: "bg-primary text-primary-foreground enabled-hover:bg-primary/80";
|
|
47
|
-
outline: "
|
|
47
|
+
outline: "border-[length:var(--button-outline-width,1px)] border-button-outline bg-background shadow-[0_1px_max(0px,4px-2*var(--button-outline-width,1px))_min(0px,2px-2*var(--button-outline-width,1px))_rgb(0_0_0/0.05)] aria-expanded:bg-muted aria-expanded:text-foreground enabled-hover:bg-muted enabled-hover:text-foreground";
|
|
48
48
|
secondary: "bg-secondary text-secondary-foreground aria-expanded:bg-secondary aria-expanded:text-secondary-foreground enabled-hover:bg-secondary-hover";
|
|
49
49
|
ghost: "aria-expanded:bg-muted aria-expanded:text-foreground enabled-hover:bg-muted enabled-hover:text-foreground";
|
|
50
50
|
destructive: "border-error/20 bg-error/10 text-error enabled-hover:border-error enabled-hover:bg-error/20";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"button-variants.d.ts","names":[],"sources":["../../../src/components/button/button-variants.ts"],"mappings":";
|
|
1
|
+
{"version":3,"file":"button-variants.d.ts","names":[],"sources":["../../../src/components/button/button-variants.ts"],"mappings":";qBAkDa,4CAAc"}
|
|
@@ -5,11 +5,11 @@ import { controlSize } from "../../styles/control-size.js";
|
|
|
5
5
|
import { tv } from "tailwind-variants";
|
|
6
6
|
//#region src/components/button/button-variants.ts
|
|
7
7
|
const buttonVariants = tv({
|
|
8
|
-
base: cn("group/button font-medium box-border inline-flex shrink-0 items-center justify-center rounded-(--radius-button) border border-transparent bg-clip-padding p-0 whitespace-nowrap transition-[color,background-color,border-color,box-shadow,translate,opacity] select-none in-data-[slot=button-group]:rounded-md enabled-active:not-aria-[haspopup]:translate-y-px [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", selfFocusRingClass, nativeStateFaceClass, dataStateFaceClass),
|
|
8
|
+
base: cn("group/button font-medium box-border inline-flex shrink-0 cursor-pointer items-center justify-center rounded-(--radius-button) border border-transparent bg-clip-padding p-0 whitespace-nowrap transition-[color,background-color,border-color,box-shadow,translate,opacity] select-none in-data-[slot=button-group]:rounded-md enabled-active:not-aria-[haspopup]:translate-y-px [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-[pending-indicator]:[&>svg:not([data-icon=inline-end])]:hidden", selfFocusRingClass, nativeStateFaceClass, dataStateFaceClass),
|
|
9
9
|
variants: {
|
|
10
10
|
variant: {
|
|
11
11
|
default: "bg-primary text-primary-foreground enabled-hover:bg-primary/80",
|
|
12
|
-
outline: "
|
|
12
|
+
outline: "border-[length:var(--button-outline-width,1px)] border-button-outline bg-background shadow-[0_1px_max(0px,4px-2*var(--button-outline-width,1px))_min(0px,2px-2*var(--button-outline-width,1px))_rgb(0_0_0/0.05)] aria-expanded:bg-muted aria-expanded:text-foreground enabled-hover:bg-muted enabled-hover:text-foreground",
|
|
13
13
|
secondary: "bg-secondary text-secondary-foreground aria-expanded:bg-secondary aria-expanded:text-secondary-foreground enabled-hover:bg-secondary-hover",
|
|
14
14
|
ghost: "aria-expanded:bg-muted aria-expanded:text-foreground enabled-hover:bg-muted enabled-hover:text-foreground",
|
|
15
15
|
destructive: "border-error/20 bg-error/10 text-error enabled-hover:border-error enabled-hover:bg-error/20",
|
|
@@ -19,20 +19,23 @@ const buttonVariants = tv({
|
|
|
19
19
|
size: {
|
|
20
20
|
default: controlSize({
|
|
21
21
|
size: "md",
|
|
22
|
-
fit: "label"
|
|
22
|
+
fit: "label",
|
|
23
|
+
class: "px-(--control-px-button-md) has-data-[icon=inline-end]:pr-(--control-px-button-icon-md) has-data-[icon=inline-start]:pl-(--control-px-button-icon-md)"
|
|
23
24
|
}),
|
|
24
25
|
xs: controlSize({
|
|
25
26
|
size: "xs",
|
|
26
27
|
fit: "label",
|
|
27
|
-
class: "[&_svg:not([class*='size-'])]:size-3"
|
|
28
|
+
class: "px-(--control-px-button-xs) has-data-[icon=inline-end]:pr-(--control-px-button-icon-xs) has-data-[icon=inline-start]:pl-(--control-px-button-icon-xs) [&_svg:not([class*='size-'])]:size-3"
|
|
28
29
|
}),
|
|
29
30
|
sm: controlSize({
|
|
30
31
|
size: "sm",
|
|
31
|
-
fit: "label"
|
|
32
|
+
fit: "label",
|
|
33
|
+
class: "px-(--control-px-button-sm) has-data-[icon=inline-end]:pr-(--control-px-button-icon-sm) has-data-[icon=inline-start]:pl-(--control-px-button-icon-sm)"
|
|
32
34
|
}),
|
|
33
35
|
lg: controlSize({
|
|
34
36
|
size: "lg",
|
|
35
|
-
fit: "label"
|
|
37
|
+
fit: "label",
|
|
38
|
+
class: "px-(--control-px-button-lg) has-data-[icon=inline-end]:pr-(--control-px-button-icon-lg) has-data-[icon=inline-start]:pl-(--control-px-button-icon-lg)"
|
|
36
39
|
}),
|
|
37
40
|
icon: controlSize({
|
|
38
41
|
size: "md",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"button-variants.js","names":[],"sources":["../../../src/components/button/button-variants.ts"],"sourcesContent":["import { tv } from \"tailwind-variants\";\n\nimport { cn } from \"../../styles/cn\";\nimport { controlSize } from \"../../styles/control-size\";\nimport { dataStateFaceClass, nativeStateFaceClass } from \"../../styles/state-face\";\nimport { selfFocusRingClass } from \"../../styles/utils\";\n\n// Runtime-free recipe so other components can borrow it without Button's client graph.\n// The state face composes two targets. `native` covers a native <button> that borrows\n// the recipe, and `data` covers Base UI roots that never match `:disabled`, such as\n// `render={<a />}` or `focusableWhenDisabled`. Both carry the `aria-disabled` arm, which\n// covers `isVisuallyDisabled` and a consumer's own `aria-disabled`. No target drops pointer events, so a Tooltip on a\n// disabled button still opens, and Base UI already cancels clicks on a disabled root.\n// Hover and press styles use the `enabled-hover:` and `enabled-active:` variants from\n// fuse.css, so a disabled root never changes fill, border, text or position under the\n// pointer. `aria-expanded:` follows an open popup, not the pointer, so it has no gate.\n// The text and icon sizes take their box from the control-size recipe: `default` is the md\n// label, `icon*` the squares. The xs glyph size and `icon-inline`, a square as tall as the
|
|
1
|
+
{"version":3,"file":"button-variants.js","names":[],"sources":["../../../src/components/button/button-variants.ts"],"sourcesContent":["import { tv } from \"tailwind-variants\";\n\nimport { cn } from \"../../styles/cn\";\nimport { controlSize } from \"../../styles/control-size\";\nimport { dataStateFaceClass, nativeStateFaceClass } from \"../../styles/state-face\";\nimport { selfFocusRingClass } from \"../../styles/utils\";\n\n// Runtime-free recipe so other components can borrow it without Button's client graph.\n// The state face composes two targets. `native` covers a native <button> that borrows\n// the recipe, and `data` covers Base UI roots that never match `:disabled`, such as\n// `render={<a />}` or `focusableWhenDisabled`. Both carry the `aria-disabled` arm, which\n// covers `isVisuallyDisabled` and a consumer's own `aria-disabled`. No target drops pointer events, so a Tooltip on a\n// disabled button still opens, and Base UI already cancels clicks on a disabled root.\n// Hover and press styles use the `enabled-hover:` and `enabled-active:` variants from\n// fuse.css, so a disabled root never changes fill, border, text or position under the\n// pointer. `aria-expanded:` follows an open popup, not the pointer, so it has no gate.\n// The text and icon sizes take their box from the control-size recipe: `default` is the md\n// label, `icon*` the squares. The labels replace the control inset with Button's own,\n// `--control-px-button-*`, which comfortable density widens to the customer-facing\n// reference's side padding while fields, Select and Toggle keep the control inset. The icon\n// edge follows it: `--control-px-button-icon-*` replaces the control icon edge, so a leading\n// or trailing icon does not sit tight against one end of a wide button. The xs\n// glyph size and `icon-inline`, a square as tall as the surrounding line that follows no\n// density, stay local.\n// Every size rounds with the theme's `--radius-button`. The arbitrary value keeps\n// tailwind-merge able to replace it with a consumer `rounded-*` class, which the custom\n// `rounded-button` utility would not be.\n// Inside a ButtonGroup a button keeps the group radius, `rounded-md`, not the button role.\n// The group joins its buttons edge to edge, often with inputs and text, into one bar that\n// rounds like a field, and a pill button would bulge out of that outline.\n// The pointer cursor is the library's policy for an interactive control, as on the\n// Accordion trigger and the selection labels. The state face's `disabled:`,\n// `data-disabled:` and `aria-disabled:` cursors are variants, so they sort after this\n// plain utility and a disabled button keeps `not-allowed`.\n// While Button renders a pending indicator it stamps `data-pending-indicator`, and the\n// recipe then hides the button's own leading and bare direct SVG children, so the indicator\n// takes a leading icon's place, an icon-only square shows the indicator alone, and a spinner\n// a consumer still places by hand is not doubled. A trailing `data-icon=\"inline-end\"` icon\n// stays, as its marker keeps the end inset tight either way, and text stays. With\n// `pendingIndicator={null}` the attribute is absent and nothing hides.\n// The outline border reads the theme's `--button-outline` at `--button-outline-width`: a 1px\n// `--border` hairline in internal themes and the reference's 2px ring in the text color in\n// external ones. A host without themes.css declares neither, so both fall back to the 1px\n// `--border` hairline. Only the hairline casts `shadow-xs`, so the shadow spells out\n// Tailwind's `shadow-xs` value as a function of the width, which a host `--shadow-xs`\n// override does not reach. It equals `shadow-xs` at 1px. From 2px its blur is 0 and its\n// spread plus blur plus y offset is negative, so it stays inside the border box, where an\n// outer shadow never paints. It\n// starts with two plain lengths, so tailwind-merge still files it as a shadow, and a\n// consumer's own `shadow-*` utility replaces it.\nexport const buttonVariants = tv({\n base: cn(\n \"group/button font-medium box-border inline-flex shrink-0 cursor-pointer items-center justify-center rounded-(--radius-button) border border-transparent bg-clip-padding p-0 whitespace-nowrap transition-[color,background-color,border-color,box-shadow,translate,opacity] select-none in-data-[slot=button-group]:rounded-md enabled-active:not-aria-[haspopup]:translate-y-px [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-[pending-indicator]:[&>svg:not([data-icon=inline-end])]:hidden\",\n selfFocusRingClass,\n nativeStateFaceClass,\n dataStateFaceClass\n ),\n variants: {\n variant: {\n default: \"bg-primary text-primary-foreground enabled-hover:bg-primary/80\",\n outline:\n \"border-[length:var(--button-outline-width,1px)] border-button-outline bg-background shadow-[0_1px_max(0px,4px-2*var(--button-outline-width,1px))_min(0px,2px-2*var(--button-outline-width,1px))_rgb(0_0_0/0.05)] aria-expanded:bg-muted aria-expanded:text-foreground enabled-hover:bg-muted enabled-hover:text-foreground\",\n secondary:\n \"bg-secondary text-secondary-foreground aria-expanded:bg-secondary aria-expanded:text-secondary-foreground enabled-hover:bg-secondary-hover\",\n ghost:\n \"aria-expanded:bg-muted aria-expanded:text-foreground enabled-hover:bg-muted enabled-hover:text-foreground\",\n destructive:\n \"border-error/20 bg-error/10 text-error enabled-hover:border-error enabled-hover:bg-error/20\",\n success:\n \"border-success/20 bg-success/10 text-success enabled-hover:border-success enabled-hover:bg-success/20\",\n link: \"text-primary underline-offset-4 enabled-hover:underline\",\n },\n size: {\n default: controlSize({\n size: \"md\",\n fit: \"label\",\n class:\n \"px-(--control-px-button-md) has-data-[icon=inline-end]:pr-(--control-px-button-icon-md) has-data-[icon=inline-start]:pl-(--control-px-button-icon-md)\",\n }),\n xs: controlSize({\n size: \"xs\",\n fit: \"label\",\n class:\n \"px-(--control-px-button-xs) has-data-[icon=inline-end]:pr-(--control-px-button-icon-xs) has-data-[icon=inline-start]:pl-(--control-px-button-icon-xs) [&_svg:not([class*='size-'])]:size-3\",\n }),\n sm: controlSize({\n size: \"sm\",\n fit: \"label\",\n class:\n \"px-(--control-px-button-sm) has-data-[icon=inline-end]:pr-(--control-px-button-icon-sm) has-data-[icon=inline-start]:pl-(--control-px-button-icon-sm)\",\n }),\n lg: controlSize({\n size: \"lg\",\n fit: \"label\",\n class:\n \"px-(--control-px-button-lg) has-data-[icon=inline-end]:pr-(--control-px-button-icon-lg) has-data-[icon=inline-start]:pl-(--control-px-button-icon-lg)\",\n }),\n icon: controlSize({ size: \"md\", fit: \"square\" }),\n \"icon-xs\": controlSize({ size: \"xs\", fit: \"square\", class: \"[&_svg:not([class*='size-'])]:size-3\" }),\n \"icon-sm\": controlSize({ size: \"sm\", fit: \"square\" }),\n \"icon-inline\": \"hit-area-1 aspect-square h-lh w-auto\",\n \"icon-lg\": controlSize({ size: \"lg\", fit: \"square\" }),\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n});\n"],"mappings":";;;;;;AAkDA,MAAa,iBAAiB,GAAG;CAC/B,MAAM,GACJ,0gBACA,oBACA,sBACA,kBACF;CACA,UAAU;EACR,SAAS;GACP,SAAS;GACT,SACE;GACF,WACE;GACF,OACE;GACF,aACE;GACF,SACE;GACF,MAAM;EACR;EACA,MAAM;GACJ,SAAS,YAAY;IACnB,MAAM;IACN,KAAK;IACL,OACE;GACJ,CAAC;GACD,IAAI,YAAY;IACd,MAAM;IACN,KAAK;IACL,OACE;GACJ,CAAC;GACD,IAAI,YAAY;IACd,MAAM;IACN,KAAK;IACL,OACE;GACJ,CAAC;GACD,IAAI,YAAY;IACd,MAAM;IACN,KAAK;IACL,OACE;GACJ,CAAC;GACD,MAAM,YAAY;IAAE,MAAM;IAAM,KAAK;GAAS,CAAC;GAC/C,WAAW,YAAY;IAAE,MAAM;IAAM,KAAK;IAAU,OAAO;GAAuC,CAAC;GACnG,WAAW,YAAY;IAAE,MAAM;IAAM,KAAK;GAAS,CAAC;GACpD,eAAe;GACf,WAAW,YAAY;IAAE,MAAM;IAAM,KAAK;GAAS,CAAC;EACtD;CACF;CACA,iBAAiB;EACf,SAAS;EACT,MAAM;CACR;AACF,CAAC"}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { buttonVariants } from "./button-variants.js";
|
|
2
|
-
import { ComponentProps, ReactElement } from "react";
|
|
2
|
+
import { ComponentProps, ReactElement, ReactNode } from "react";
|
|
3
3
|
import { VariantProps } from "tailwind-variants";
|
|
4
4
|
import { Button as Button$1 } from "@base-ui/react/button";
|
|
5
5
|
//#region src/components/button/button.d.ts
|
|
6
|
-
|
|
7
|
-
type
|
|
8
|
-
|
|
6
|
+
/** Every `size` the Button recipe knows: the label sizes plus the square `icon*` sizes. */
|
|
7
|
+
export type ButtonSize = NonNullable<VariantProps<typeof buttonVariants>["size"]>;
|
|
8
|
+
/** The square icon-only sizes. A button at one of these requires an `aria-label`. */
|
|
9
|
+
export type IconButtonSize = Extract<ButtonSize, `icon${string}`>;
|
|
10
|
+
/** The label sizes: `xs`, `sm`, `default` and `lg`. */
|
|
11
|
+
export type LabelButtonSize = Exclude<ButtonSize, IconButtonSize>;
|
|
9
12
|
type ButtonPrimitiveProps = Omit<ComponentProps<typeof Button$1>, "className">;
|
|
10
13
|
type ButtonSharedProps = ButtonPrimitiveProps & Omit<VariantProps<typeof buttonVariants>, "size"> & {
|
|
11
14
|
/** Extra classes, merged last through `cn`. */
|
|
@@ -21,10 +24,25 @@ type ButtonSharedProps = ButtonPrimitiveProps & Omit<VariantProps<typeof buttonV
|
|
|
21
24
|
*/
|
|
22
25
|
isVisuallyDisabled?: boolean;
|
|
23
26
|
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
27
|
+
* The in-flight state of an async action. Stamps `data-pending` and `aria-busy`, blocks
|
|
28
|
+
* activation (effective disabled is `disabled || isPending`) and renders the disabled
|
|
29
|
+
* treatment, but keeps the button in the focus order like `focusableWhenDisabled`, so a
|
|
30
|
+
* keyboard user who activated it is still on it when the result arrives. Shows the
|
|
31
|
+
* `pendingIndicator` in the leading icon position meanwhile. An explicit
|
|
32
|
+
* `focusableWhenDisabled={false}` restores the native `disabled` attribute while pending.
|
|
33
|
+
* `aria-busy` announces nothing by itself: say what is happening through the label
|
|
34
|
+
* ("Saving") or a `role="status"` region outside the button.
|
|
26
35
|
*/
|
|
27
36
|
isPending?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* What the button shows while pending. Omitted: a spinning `SpinnerGap` in the leading icon
|
|
39
|
+
* position, and the button's own leading and bare SVG children hide so the spinner takes
|
|
40
|
+
* their place (a trailing `data-icon="inline-end"` icon stays). A node: rendered in that same
|
|
41
|
+
* place instead of the spinner, as a decorative `aria-hidden` slot; animate it yourself. `null`
|
|
42
|
+
* or `false`: no indicator and nothing hidden, so the call site owns the pending markup, for
|
|
43
|
+
* example a brand button that keeps its logo and centres its own spinner over it.
|
|
44
|
+
*/
|
|
45
|
+
pendingIndicator?: ReactNode;
|
|
28
46
|
/** Pixels the hit rect is inflated on every side when predicting pointer intent. */
|
|
29
47
|
predictionZoneSize?: number;
|
|
30
48
|
/**
|
|
@@ -33,15 +51,36 @@ type ButtonSharedProps = ButtonPrimitiveProps & Omit<VariantProps<typeof buttonV
|
|
|
33
51
|
*/
|
|
34
52
|
onIntent?: () => void;
|
|
35
53
|
};
|
|
36
|
-
|
|
54
|
+
/**
|
|
55
|
+
* The props of a button with a visible label: every size except the square `icon*` ones, so
|
|
56
|
+
* an accessible name is optional. A wrapper that supplies its own label types its props as
|
|
57
|
+
* `Omit<LabelButtonProps, "children">` and keeps the size union in sync with the recipe.
|
|
58
|
+
*/
|
|
59
|
+
export type LabelButtonProps = ButtonSharedProps & {
|
|
37
60
|
/** Recipe size axis. The `icon*` sizes are square and additionally require an `aria-label`. */
|
|
38
61
|
size?: LabelButtonSize;
|
|
39
|
-
}
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* The props of a square icon-only button: one of the `icon*` sizes plus the `aria-label` that
|
|
65
|
+
* names it, since the icon is the whole content.
|
|
66
|
+
*/
|
|
67
|
+
export type IconButtonProps = ButtonSharedProps & {
|
|
40
68
|
/** Recipe size axis. The `icon*` sizes are square and additionally require an `aria-label`. */
|
|
41
69
|
size: IconButtonSize;
|
|
42
70
|
"aria-label": string;
|
|
43
|
-
}
|
|
44
|
-
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* `LabelButtonProps | IconButtonProps`. `Omit` on this union collapses it and lets an icon
|
|
74
|
+
* size through without its name; omit from {@link LabelButtonProps} or
|
|
75
|
+
* {@link IconButtonProps} instead, or distribute the omit over the union.
|
|
76
|
+
*/
|
|
77
|
+
export type ButtonProps = LabelButtonProps | IconButtonProps;
|
|
78
|
+
/**
|
|
79
|
+
* Triggers an action. Mark a leading or trailing icon child with `data-icon="inline-start"` or
|
|
80
|
+
* `data-icon="inline-end"`, on your own icon components too, so that side takes the icon
|
|
81
|
+
* padding instead of the wider label padding. The attribute must reach the rendered element.
|
|
82
|
+
*/
|
|
83
|
+
export declare function Button({ className, variant, size, isVisuallyDisabled, disabled, isPending, pendingIndicator, predictionZoneSize, onIntent, onMouseDown, children, ref, ...props }: ButtonProps): ReactElement;
|
|
45
84
|
export declare namespace Button {
|
|
46
85
|
var displayName: string;
|
|
47
86
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"button.d.ts","names":[],"sources":["../../../src/components/button/button.tsx"],"mappings":"
|
|
1
|
+
{"version":3,"file":"button.d.ts","names":[],"sources":["../../../src/components/button/button.tsx"],"mappings":";;;;;;YAeY,aAAa,YAAY,oBAAoB;;YAG7C,iBAAiB,QAAQ;;YAGzB,kBAAkB,QAAQ,YAAY;KAE7C,uBAAuB,KAAK,sBAAsB;KAElD,oBAAoB,uBACvB,KAAK,oBAAoB;;EAEvB;;;;;;;;;;EAUA;;;;;;;;;;;EAWA;;;;;;;;;EASA,mBAAmB;;EAEnB;;;;;EAKA;;;;;;;YAQQ,mBAAmB;;EAE7B,OAAO;;;;;;YAOG,kBAAkB;;EAE5B,MAAM;EACN;;;;;;;YAQU,cAAc,mBAAmB;;;;;;wBAO7B,SACd,WACA,SACA,MACA,oBACA,UACA,WACA,kBACA,oBACA,UACA,aACA,UACA,QACG,SACF,cAAc;yBAdD;MAAA"}
|
|
@@ -2,22 +2,34 @@
|
|
|
2
2
|
import { cn } from "../../styles/cn.js";
|
|
3
3
|
import { useMergedRefs } from "../../hooks/use-merged-refs.js";
|
|
4
4
|
import { usePredictedEvents } from "../../hooks/use-predicted-events.js";
|
|
5
|
+
import { SpinnerGap } from "../../icons/generated/spinner-gap.js";
|
|
5
6
|
import { definedProps } from "../../internal/defined-props.js";
|
|
6
7
|
import { buttonVariants } from "./button-variants.js";
|
|
7
|
-
import { jsx } from "react/jsx-runtime";
|
|
8
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
9
|
import { Button as Button$1 } from "@base-ui/react/button";
|
|
9
10
|
//#region src/components/button/button.tsx
|
|
10
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Triggers an action. Mark a leading or trailing icon child with `data-icon="inline-start"` or
|
|
13
|
+
* `data-icon="inline-end"`, on your own icon components too, so that side takes the icon
|
|
14
|
+
* padding instead of the wider label padding. The attribute must reach the rendered element.
|
|
15
|
+
*/
|
|
16
|
+
function Button({ className, variant, size, isVisuallyDisabled = false, disabled = false, isPending = false, pendingIndicator, predictionZoneSize = 30, onIntent, onMouseDown, children, ref, ...props }) {
|
|
11
17
|
const { ref: predictedRef } = usePredictedEvents({
|
|
12
18
|
predictionZoneSize,
|
|
13
19
|
onIntent,
|
|
14
20
|
enabled: !disabled && !isPending && !isVisuallyDisabled && onIntent !== void 0
|
|
15
21
|
});
|
|
16
22
|
const mergedRef = useMergedRefs(ref, onIntent === void 0 ? null : predictedRef);
|
|
17
|
-
|
|
23
|
+
const showsIndicator = isPending && pendingIndicator !== null && pendingIndicator !== false;
|
|
24
|
+
return /* @__PURE__ */ jsxs(Button$1, {
|
|
18
25
|
"data-slot": "button",
|
|
19
26
|
"data-pending": isPending || void 0,
|
|
27
|
+
"data-pending-indicator": showsIndicator || void 0,
|
|
20
28
|
disabled: disabled || isPending,
|
|
29
|
+
...definedProps({
|
|
30
|
+
focusableWhenDisabled: isPending || void 0,
|
|
31
|
+
"aria-busy": isPending || void 0
|
|
32
|
+
}),
|
|
21
33
|
...definedProps({ "aria-disabled": isVisuallyDisabled || void 0 }),
|
|
22
34
|
className: cn(buttonVariants({
|
|
23
35
|
variant,
|
|
@@ -28,7 +40,14 @@ function Button({ className, variant, size, isVisuallyDisabled = false, disabled
|
|
|
28
40
|
onMouseDown?.(event);
|
|
29
41
|
},
|
|
30
42
|
...definedProps(props),
|
|
31
|
-
ref: mergedRef
|
|
43
|
+
ref: mergedRef,
|
|
44
|
+
children: [showsIndicator ? /* @__PURE__ */ jsx("span", {
|
|
45
|
+
"data-slot": "button-pending-indicator",
|
|
46
|
+
"data-icon": "inline-start",
|
|
47
|
+
"aria-hidden": true,
|
|
48
|
+
className: "pointer-events-none inline-flex shrink-0 items-center justify-center",
|
|
49
|
+
children: pendingIndicator ?? /* @__PURE__ */ jsx(SpinnerGap, { className: "animate-spin" })
|
|
50
|
+
}) : null, children]
|
|
32
51
|
});
|
|
33
52
|
}
|
|
34
53
|
Button.displayName = "Button";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"button.js","names":["ButtonPrimitive"],"sources":["../../../src/components/button/button.tsx"],"sourcesContent":["\"use client\";\n\nimport type { ComponentProps, ReactElement } from \"react\";\n\nimport { Button as ButtonPrimitive } from \"@base-ui/react/button\";\nimport type { VariantProps } from \"tailwind-variants\";\n\nimport { useMergedRefs } from \"../../hooks/use-merged-refs\";\nimport { usePredictedEvents } from \"../../hooks/use-predicted-events\";\nimport { definedProps } from \"../../internal/defined-props\";\nimport { cn } from \"../../styles/cn\";\nimport { buttonVariants } from \"./button-variants\";\n\
|
|
1
|
+
{"version":3,"file":"button.js","names":["ButtonPrimitive"],"sources":["../../../src/components/button/button.tsx"],"sourcesContent":["\"use client\";\n\nimport type { ComponentProps, ReactElement, ReactNode } from \"react\";\n\nimport { Button as ButtonPrimitive } from \"@base-ui/react/button\";\nimport type { VariantProps } from \"tailwind-variants\";\n\nimport { useMergedRefs } from \"../../hooks/use-merged-refs\";\nimport { usePredictedEvents } from \"../../hooks/use-predicted-events\";\nimport { SpinnerGap } from \"../../icons/generated/spinner-gap\";\nimport { definedProps } from \"../../internal/defined-props\";\nimport { cn } from \"../../styles/cn\";\nimport { buttonVariants } from \"./button-variants\";\n\n/** Every `size` the Button recipe knows: the label sizes plus the square `icon*` sizes. */\nexport type ButtonSize = NonNullable<VariantProps<typeof buttonVariants>[\"size\"]>;\n\n/** The square icon-only sizes. A button at one of these requires an `aria-label`. */\nexport type IconButtonSize = Extract<ButtonSize, `icon${string}`>;\n\n/** The label sizes: `xs`, `sm`, `default` and `lg`. */\nexport type LabelButtonSize = Exclude<ButtonSize, IconButtonSize>;\n\ntype ButtonPrimitiveProps = Omit<ComponentProps<typeof ButtonPrimitive>, \"className\">;\n\ntype ButtonSharedProps = ButtonPrimitiveProps &\n Omit<VariantProps<typeof buttonVariants>, \"size\"> & {\n /** Extra classes, merged last through `cn`. */\n className?: string;\n /**\n * Stamps `aria-disabled` (an explicit consumer value wins), which renders the disabled\n * treatment (`opacity-50`, the `not-allowed` cursor, no hover or press paint), and\n * suppresses focus-on-press while the button stays fully interactive — click, keyboard\n * and focus-visible all still work, and a Tooltip on it still opens. For \"looks\n * disabled but explains itself on activation\" flows. The treatment keys off\n * `aria-disabled`, so an explicit `aria-disabled={false}` also turns it off: the button\n * then looks and announces enabled and only the focus-on-press suppression remains.\n */\n isVisuallyDisabled?: boolean;\n /**\n * The in-flight state of an async action. Stamps `data-pending` and `aria-busy`, blocks\n * activation (effective disabled is `disabled || isPending`) and renders the disabled\n * treatment, but keeps the button in the focus order like `focusableWhenDisabled`, so a\n * keyboard user who activated it is still on it when the result arrives. Shows the\n * `pendingIndicator` in the leading icon position meanwhile. An explicit\n * `focusableWhenDisabled={false}` restores the native `disabled` attribute while pending.\n * `aria-busy` announces nothing by itself: say what is happening through the label\n * (\"Saving\") or a `role=\"status\"` region outside the button.\n */\n isPending?: boolean;\n /**\n * What the button shows while pending. Omitted: a spinning `SpinnerGap` in the leading icon\n * position, and the button's own leading and bare SVG children hide so the spinner takes\n * their place (a trailing `data-icon=\"inline-end\"` icon stays). A node: rendered in that same\n * place instead of the spinner, as a decorative `aria-hidden` slot; animate it yourself. `null`\n * or `false`: no indicator and nothing hidden, so the call site owns the pending markup, for\n * example a brand button that keeps its logo and centres its own spinner over it.\n */\n pendingIndicator?: ReactNode;\n /** Pixels the hit rect is inflated on every side when predicting pointer intent. */\n predictionZoneSize?: number;\n /**\n * Predictive-prefetch callback. Fires once when the pointer's predicted trajectory\n * lands inside the inflated hit rect; browsers without the prediction API fail soft.\n */\n onIntent?: () => void;\n };\n\n/**\n * The props of a button with a visible label: every size except the square `icon*` ones, so\n * an accessible name is optional. A wrapper that supplies its own label types its props as\n * `Omit<LabelButtonProps, \"children\">` and keeps the size union in sync with the recipe.\n */\nexport type LabelButtonProps = ButtonSharedProps & {\n /** Recipe size axis. The `icon*` sizes are square and additionally require an `aria-label`. */\n size?: LabelButtonSize;\n};\n\n/**\n * The props of a square icon-only button: one of the `icon*` sizes plus the `aria-label` that\n * names it, since the icon is the whole content.\n */\nexport type IconButtonProps = ButtonSharedProps & {\n /** Recipe size axis. The `icon*` sizes are square and additionally require an `aria-label`. */\n size: IconButtonSize;\n \"aria-label\": string;\n};\n\n/**\n * `LabelButtonProps | IconButtonProps`. `Omit` on this union collapses it and lets an icon\n * size through without its name; omit from {@link LabelButtonProps} or\n * {@link IconButtonProps} instead, or distribute the omit over the union.\n */\nexport type ButtonProps = LabelButtonProps | IconButtonProps;\n\n/**\n * Triggers an action. Mark a leading or trailing icon child with `data-icon=\"inline-start\"` or\n * `data-icon=\"inline-end\"`, on your own icon components too, so that side takes the icon\n * padding instead of the wider label padding. The attribute must reach the rendered element.\n */\nexport function Button({\n className,\n variant,\n size,\n isVisuallyDisabled = false,\n disabled = false,\n isPending = false,\n pendingIndicator,\n predictionZoneSize = 30,\n onIntent,\n onMouseDown,\n children,\n ref,\n ...props\n}: ButtonProps): ReactElement {\n const { ref: predictedRef } = usePredictedEvents({\n predictionZoneSize,\n onIntent,\n enabled: !disabled && !isPending && !isVisuallyDisabled && onIntent !== undefined,\n });\n const mergedRef = useMergedRefs(ref, onIntent === undefined ? null : predictedRef);\n // `null` and `false` opt out of the indicator and of the icon swap; every other value, `0`\n // included, is a node to show, and `undefined` is the default spinner.\n const showsIndicator = isPending && pendingIndicator !== null && pendingIndicator !== false;\n\n return (\n <ButtonPrimitive\n data-slot=\"button\"\n data-pending={isPending || undefined}\n // Present only while an indicator renders: the recipe's icon swap keys off it, so a\n // `null` indicator hides nothing.\n data-pending-indicator={showsIndicator || undefined}\n disabled={disabled || isPending}\n // A pending button stays in the focus order and announces busy: Base UI then drops the\n // native `disabled`, stamps `aria-disabled` and `data-disabled` and still cancels click\n // and keyboard activation. Both keys are omitted, not undefined, when not pending, so a\n // consumer's own `focusableWhenDisabled` for a plain `disabled` button flows through the\n // later {...definedProps(props)} spread, where an explicit value also wins while pending.\n {...definedProps({\n focusableWhenDisabled: isPending || undefined,\n \"aria-busy\": isPending || undefined,\n })}\n // Announced as unavailable without being disabled: the button still activates so\n // the flow that explains itself can run. An explicit consumer value wins through the\n // later {...definedProps(props)} spread. When not visually disabled the key is omitted,\n // not undefined, so Base UI's own aria-disabled (focusableWhenDisabled, non-native\n // disabled) survives.\n {...definedProps({ \"aria-disabled\": isVisuallyDisabled || undefined })}\n className={cn(buttonVariants({ variant, size }), className)}\n onMouseDown={(event) => {\n if (isVisuallyDisabled) {\n event.preventDefault();\n }\n onMouseDown?.(event);\n }}\n // Filtered so a forwarded undefined cannot erase what Base UI's Button sets itself,\n // such as aria-disabled, type and role.\n {...definedProps(props)}\n ref={mergedRef}>\n {showsIndicator ? (\n // Decorative: the state is announced through aria-busy and the label. The slot is a\n // leading icon, so the icon edge tightens the start inset as for any inline-start child,\n // and the recipe hides the button's own leading and bare SVG children while it shows. A\n // consumer's node rides in the same slot, so it gets the same place and the same\n // aria-hidden; only the default spinner animates. `null` never reaches this branch, so\n // the coalescing only fills in `undefined`.\n <span\n data-slot=\"button-pending-indicator\"\n data-icon=\"inline-start\"\n aria-hidden\n className=\"pointer-events-none inline-flex shrink-0 items-center justify-center\">\n {pendingIndicator ?? <SpinnerGap className=\"animate-spin\" />}\n </span>\n ) : null}\n {children}\n </ButtonPrimitive>\n );\n}\n\nButton.displayName = \"Button\";\n"],"mappings":";;;;;;;;;;;;;;;AAoGA,SAAgB,OAAO,EACrB,WACA,SACA,MACA,qBAAqB,OACrB,WAAW,OACX,YAAY,OACZ,kBACA,qBAAqB,IACrB,UACA,aACA,UACA,KACA,GAAG,SACyB;CAC5B,MAAM,EAAE,KAAK,iBAAiB,mBAAmB;EAC/C;EACA;EACA,SAAS,CAAC,YAAY,CAAC,aAAa,CAAC,sBAAsB,aAAa,KAAA;CAC1E,CAAC;CACD,MAAM,YAAY,cAAc,KAAK,aAAa,KAAA,IAAY,OAAO,YAAY;CAGjF,MAAM,iBAAiB,aAAa,qBAAqB,QAAQ,qBAAqB;CAEtF,OACE,qBAACA,UAAD;EACE,aAAU;EACV,gBAAc,aAAa,KAAA;EAG3B,0BAAwB,kBAAkB,KAAA;EAC1C,UAAU,YAAY;EAMtB,GAAI,aAAa;GACf,uBAAuB,aAAa,KAAA;GACpC,aAAa,aAAa,KAAA;EAC5B,CAAC;EAMD,GAAI,aAAa,EAAE,iBAAiB,sBAAsB,KAAA,EAAU,CAAC;EACrE,WAAW,GAAG,eAAe;GAAE;GAAS;EAAK,CAAC,GAAG,SAAS;EAC1D,cAAc,UAAU;GACtB,IAAI,oBACF,MAAM,eAAe;GAEvB,cAAc,KAAK;EACrB;EAGA,GAAI,aAAa,KAAK;EACtB,KAAK;EAhCP,UAAA,CAiCG,iBAOC,oBAAC,QAAD;GACE,aAAU;GACV,aAAU;GACV,eAAA;GACA,WAAU;GACT,UAAA,oBAAoB,oBAAC,YAAD,EAAY,WAAU,eAAgB,CAAA;EACvD,CAAA,IACJ,MACH,QACc;;AAErB;AAEA,OAAO,cAAc"}
|
|
@@ -18,7 +18,10 @@ export type CheckboxGroupProps = {
|
|
|
18
18
|
label?: string;
|
|
19
19
|
/** Supporting copy, rendered as `Field.Description`. */
|
|
20
20
|
description?: string;
|
|
21
|
-
/**
|
|
21
|
+
/**
|
|
22
|
+
* Error copy, rendered as `Field.Error` when truthy. Accepts any `ReactNode`. Falsy, the
|
|
23
|
+
* field shows its own validation error instead, such as a native constraint message.
|
|
24
|
+
*/
|
|
22
25
|
errorMessage?: ReactNode;
|
|
23
26
|
/**
|
|
24
27
|
* Layout of the group primitive, and of CheckboxItemGroup's stacked-card list.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkbox.d.ts","names":[],"sources":["../../../src/components/checkbox/checkbox.tsx"],"mappings":";;;;;;;;;;;wBA4BgB,WACd,cACG,SACF,sBAAsB,WAAkB,QAAQ;yBAHnC;MAAA;;YA+BJ;;EAEV;;EAEA
|
|
1
|
+
{"version":3,"file":"checkbox.d.ts","names":[],"sources":["../../../src/components/checkbox/checkbox.tsx"],"mappings":";;;;;;;;;;;wBA4BgB,WACd,cACG,SACF,sBAAsB,WAAkB,QAAQ;yBAHnC;MAAA;;YA+BJ;;EAEV;;EAEA;;;;;EAKA,eAAe;;;;;;;EAOf;;EAEA;;EAEA;;EAEA,YAAY;;;;;EAKZ;;EAEA;;EAEA;;;;;;EAMA;;EAEA;;EAEA;;EAEA,WAAW;;;;;;wBAOG,gBACd,OACA,aACA,cACA,aACA,OACA,cACA,UACA,WACA,YACA,WACA,MACA,IACA,WACA,YACC,qBAAqB;yBAfR;MAAA;;;;;;;;wBA8CA,oBAAoB,gBAA6B,SAAS,qBAAqB;yBAA/E;MAAA;;YAUJ;;EAEV,WAAW;;;;;;EAMX,cAAc;;;;;;wBAOA,sBAAsB,UAAU,eAAe,2BAA2B;yBAA1E;MAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkbox.js","names":["CheckboxPrimitive","CheckboxGroupPrimitive"],"sources":["../../../src/components/checkbox/checkbox.tsx"],"sourcesContent":["\"use client\";\n\nimport type { ComponentProps, ReactElement, ReactNode } from \"react\";\n\nimport { Checkbox as CheckboxPrimitive } from \"@base-ui/react/checkbox\";\nimport { CheckboxGroup as CheckboxGroupPrimitive } from \"@base-ui/react/checkbox-group\";\n\nimport { Check } from \"../../icons/generated/check\";\nimport { Minus } from \"../../icons/generated/minus\";\nimport { definedProps } from \"../../internal/defined-props\";\nimport { isTextNode } from \"../../internal/is-text-node\";\nimport { cn } from \"../../styles/cn\";\nimport { checkboxCornerClass } from \"../../styles/corner-radius\";\nimport { mergeClassName } from \"../../styles/merge-class-name\";\nimport { dataStateFaceClass } from \"../../styles/state-face\";\nimport { selfFocusRingClass } from \"../../styles/utils\";\nimport { FieldFrame } from \"../field/field-frame\";\nimport { SelectionGroupLayout, SelectionItemGroup } from \"../selection-item/selection-item\";\nimport { selectionGroupOrientationVariants } from \"../selection-item/selection-item-variants\";\n\n/**\n * Unlabeled 16px checkbox over the base-ui primitive. Client component, because base-ui\n * Checkbox owns the checked state. The indicator is internal: Phosphor regular `Minus`\n * when indeterminate, `Check` otherwise. Labeled usage composes `Field.Root` and\n * `Field.Label`, or `CheckboxItem`. A disabled checkbox dims to 50% on its own, also\n * outside a field. Internal themes round the box with the one radius, and external themes\n * keep the reference's 4px corner.\n */\nexport function Checkbox({\n className,\n ...props\n}: ComponentProps<typeof CheckboxPrimitive.Root>): ReactElement {\n return (\n <CheckboxPrimitive.Root\n data-slot=\"checkbox\"\n className={mergeClassName(\n className,\n // The root is a <span>, which never matches `:disabled`, so the state face keys off\n // Base UI's `data-disabled` and `data-invalid` attributes, plus a consumer's\n // `aria-invalid`. A checked invalid box keeps its primary border beside the ring.\n // oxlint-disable-next-line elmera/no-local-focus-ring -- native outline off; ring comes from the shared adapter\n \"peer shadow-xs ease-out relative flex size-4 max-w-4 shrink-0 items-center justify-center border border-input bg-card transition-[color,background-color,border-color,box-shadow] duration-150 outline-none after:absolute after:-inset-x-3 after:-inset-y-2 after:content-[''] data-indeterminate:border-primary data-indeterminate:bg-primary data-indeterminate:text-primary-foreground data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground\",\n checkboxCornerClass,\n selfFocusRingClass,\n dataStateFaceClass,\n \"aria-invalid:aria-checked:border-primary data-invalid:aria-checked:border-primary\"\n )}\n {...definedProps(props)}>\n <CheckboxPrimitive.Indicator\n data-slot=\"checkbox-indicator\"\n className=\"grid place-content-center text-current transition-none [&>svg]:size-3.5\"\n render={(indicatorProps, state) => (\n <span {...indicatorProps}>{state.indeterminate ? <Minus /> : <Check />}</span>\n )}\n />\n </CheckboxPrimitive.Root>\n );\n}\n\nexport type CheckboxGroupProps = {\n /** Fieldset legend, rendered as `Field.Legend variant=\"label\"`. The legend row is omitted when absent. */\n label?: string;\n /** Supporting copy, rendered as `Field.Description`. */\n description?: string;\n
|
|
1
|
+
{"version":3,"file":"checkbox.js","names":["CheckboxPrimitive","CheckboxGroupPrimitive"],"sources":["../../../src/components/checkbox/checkbox.tsx"],"sourcesContent":["\"use client\";\n\nimport type { ComponentProps, ReactElement, ReactNode } from \"react\";\n\nimport { Checkbox as CheckboxPrimitive } from \"@base-ui/react/checkbox\";\nimport { CheckboxGroup as CheckboxGroupPrimitive } from \"@base-ui/react/checkbox-group\";\n\nimport { Check } from \"../../icons/generated/check\";\nimport { Minus } from \"../../icons/generated/minus\";\nimport { definedProps } from \"../../internal/defined-props\";\nimport { isTextNode } from \"../../internal/is-text-node\";\nimport { cn } from \"../../styles/cn\";\nimport { checkboxCornerClass } from \"../../styles/corner-radius\";\nimport { mergeClassName } from \"../../styles/merge-class-name\";\nimport { dataStateFaceClass } from \"../../styles/state-face\";\nimport { selfFocusRingClass } from \"../../styles/utils\";\nimport { FieldFrame } from \"../field/field-frame\";\nimport { SelectionGroupLayout, SelectionItemGroup } from \"../selection-item/selection-item\";\nimport { selectionGroupOrientationVariants } from \"../selection-item/selection-item-variants\";\n\n/**\n * Unlabeled 16px checkbox over the base-ui primitive. Client component, because base-ui\n * Checkbox owns the checked state. The indicator is internal: Phosphor regular `Minus`\n * when indeterminate, `Check` otherwise. Labeled usage composes `Field.Root` and\n * `Field.Label`, or `CheckboxItem`. A disabled checkbox dims to 50% on its own, also\n * outside a field. Internal themes round the box with the one radius, and external themes\n * keep the reference's 4px corner.\n */\nexport function Checkbox({\n className,\n ...props\n}: ComponentProps<typeof CheckboxPrimitive.Root>): ReactElement {\n return (\n <CheckboxPrimitive.Root\n data-slot=\"checkbox\"\n className={mergeClassName(\n className,\n // The root is a <span>, which never matches `:disabled`, so the state face keys off\n // Base UI's `data-disabled` and `data-invalid` attributes, plus a consumer's\n // `aria-invalid`. A checked invalid box keeps its primary border beside the ring.\n // oxlint-disable-next-line elmera/no-local-focus-ring -- native outline off; ring comes from the shared adapter\n \"peer shadow-xs ease-out relative flex size-4 max-w-4 shrink-0 items-center justify-center border border-input bg-card transition-[color,background-color,border-color,box-shadow] duration-150 outline-none after:absolute after:-inset-x-3 after:-inset-y-2 after:content-[''] data-indeterminate:border-primary data-indeterminate:bg-primary data-indeterminate:text-primary-foreground data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground\",\n checkboxCornerClass,\n selfFocusRingClass,\n dataStateFaceClass,\n \"aria-invalid:aria-checked:border-primary data-invalid:aria-checked:border-primary\"\n )}\n {...definedProps(props)}>\n <CheckboxPrimitive.Indicator\n data-slot=\"checkbox-indicator\"\n className=\"grid place-content-center text-current transition-none [&>svg]:size-3.5\"\n render={(indicatorProps, state) => (\n <span {...indicatorProps}>{state.indeterminate ? <Minus /> : <Check />}</span>\n )}\n />\n </CheckboxPrimitive.Root>\n );\n}\n\nexport type CheckboxGroupProps = {\n /** Fieldset legend, rendered as `Field.Legend variant=\"label\"`. The legend row is omitted when absent. */\n label?: string;\n /** Supporting copy, rendered as `Field.Description`. */\n description?: string;\n /**\n * Error copy, rendered as `Field.Error` when truthy. Accepts any `ReactNode`. Falsy, the\n * field shows its own validation error instead, such as a native constraint message.\n */\n errorMessage?: ReactNode;\n /**\n * Layout of the group primitive, and of CheckboxItemGroup's stacked-card list.\n * Vertical: primitive `flex-col gap-2`; item list connected `flex-col gap-0`.\n * Horizontal: primitive `flex-wrap gap-4`; item list `flex-row flex-wrap gap-4`\n * with individually rounded cards. Maps through `selectionGroupOrientationVariants`.\n */\n orientation?: \"vertical\" | \"horizontal\";\n /** Controlled selected values. */\n value?: string[];\n /** Uncontrolled initial selected values. */\n defaultValue?: string[];\n /** Called with the selected `string[]`, not the event. Mapped to base-ui `onValueChange`. */\n onChange?: (value: string[]) => void;\n /**\n * Enables the tri-state `parent` checkbox. Base-ui derives checked/indeterminate\n * from whether the group's value is a subset of these members.\n */\n allValues?: string[];\n /** Forwards `disabled` to `Field.Root` and the group primitive. */\n isDisabled?: boolean;\n /** Forwards `invalid` to `Field.Root`. */\n isInvalid?: boolean;\n /**\n * Set on `Field.Root`, not the group primitive. Base-ui's CheckboxGroup has no\n * `name`; Field context threads it to member hidden inputs. RadioGroup puts\n * `name` on its primitive — the face is the same `name?: string` either way.\n */\n name?: string;\n /** Forwarded to the group primitive. */\n id?: string;\n /** Extra classes, merged onto the group primitive via `cn`. */\n className?: string;\n /** Group members — typically `Checkbox` or `CheckboxItem`. */\n children?: ReactNode;\n};\n\n/**\n * Labeled checkbox group composite over Field and base-ui CheckboxGroup. Client component,\n * because it wires Field validity and the group primitive.\n */\nexport function CheckboxGroup({\n label,\n description,\n errorMessage,\n orientation = \"vertical\",\n value,\n defaultValue,\n onChange,\n allValues,\n isDisabled,\n isInvalid,\n name,\n id,\n className,\n children,\n}: CheckboxGroupProps): ReactElement {\n return (\n <FieldFrame\n heading=\"legend\"\n label={label}\n description={description}\n errorMessage={errorMessage}\n name={name}\n invalid={isInvalid}\n disabled={isDisabled}>\n <CheckboxGroupPrimitive\n data-slot=\"checkbox-group\"\n id={id}\n value={value}\n defaultValue={defaultValue}\n onValueChange={onChange}\n allValues={allValues}\n disabled={isDisabled}\n className={cn(selectionGroupOrientationVariants({ orientation }).group(), className)}>\n <SelectionGroupLayout orientation={orientation}>{children}</SelectionGroupLayout>\n </CheckboxGroupPrimitive>\n </FieldFrame>\n );\n}\n\n/**\n * Stacked-card group: `CheckboxGroup` wrapping children in the private\n * SelectionItem list (`role=\"list\"`). `orientation` is forwarded to the labeled\n * outer group and to that list: vertical remains connected `flex-col gap-0`;\n * horizontal is `flex-row flex-wrap gap-4` with individually rounded cards.\n */\nexport function CheckboxItemGroup({ orientation = \"vertical\", ...props }: CheckboxGroupProps): ReactElement {\n // The default is spelled here because the docs API extractor reads a part's\n // documented defaults out of its own destructuring.\n return (\n <CheckboxGroup {...props} orientation={orientation}>\n <SelectionItemGroup orientation={orientation}>{props.children}</SelectionItemGroup>\n </CheckboxGroup>\n );\n}\n\nexport type CheckboxDescriptionProps = {\n /** Typically a `Checkbox`. */\n children?: ReactNode;\n /**\n * Trailing note. A string renders as a muted `<small>`; any other node renders\n * intact. Visual-only — not wired to `aria-describedby`. Use Field description\n * wiring when programmatic association is required.\n */\n describedBy?: ReactNode;\n};\n\n/**\n * Inline \"checkbox + trailing note\" row. The note is\n * visual-only; it does not become an accessible description.\n */\nexport function CheckboxDescription({ children, describedBy }: CheckboxDescriptionProps): ReactElement {\n // Only a string `describedBy` becomes the muted `<small>` note.\n return (\n <div className=\"flex items-start gap-2\">\n {children}\n {isTextNode(describedBy) ? (\n <small className=\"text-sm text-muted-foreground\">{describedBy}</small>\n ) : (\n describedBy\n )}\n </div>\n );\n}\n\nCheckbox.displayName = \"Checkbox\";\nCheckboxGroup.displayName = \"CheckboxGroup\";\nCheckboxItemGroup.displayName = \"CheckboxItemGroup\";\nCheckboxDescription.displayName = \"CheckboxDescription\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AA4BA,SAAgB,SAAS,EACvB,WACA,GAAG,SAC2D;CAC9D,OACE,oBAACA,WAAkB,MAAnB;EACE,aAAU;EACV,WAAW,eACT,WAKA,udACA,qBACA,oBACA,oBACA,mFACF;EACA,GAAI,aAAa,KAAK;EACtB,UAAA,oBAACA,WAAkB,WAAnB;GACE,aAAU;GACV,WAAU;GACV,SAAS,gBAAgB,UACvB,oBAAC,QAAD;IAAM,GAAI;IAAiB,UAAA,MAAM,gBAAgB,oBAAC,OAAD,CAAQ,CAAA,IAAI,oBAAC,OAAD,CAAQ,CAAA;GAAQ,CAAA;EAEhF,CAAA;CACqB,CAAA;AAE5B;;;;;AAoDA,SAAgB,cAAc,EAC5B,OACA,aACA,cACA,cAAc,YACd,OACA,cACA,UACA,WACA,YACA,WACA,MACA,IACA,WACA,YACmC;CACnC,OACE,oBAAC,YAAD;EACE,SAAQ;EACD;EACM;EACC;EACR;EACN,SAAS;EACT,UAAU;EACV,UAAA,oBAACC,iBAAD;GACE,aAAU;GACN;GACG;GACO;GACd,eAAe;GACJ;GACX,UAAU;GACV,WAAW,GAAG,kCAAkC,EAAE,YAAY,CAAC,CAAC,CAAC,MAAM,GAAG,SAAS;GACnF,UAAA,oBAAC,sBAAD;IAAmC;IAAc;GAA+B,CAAA;EAC1D,CAAA;CACd,CAAA;AAEhB;;;;;;;AAQA,SAAgB,kBAAkB,EAAE,cAAc,YAAY,GAAG,SAA2C;CAG1G,OACE,oBAAC,eAAD;EAAe,GAAI;EAAoB;EACrC,UAAA,oBAAC,oBAAD;GAAiC;GAAc,UAAA,MAAM;EAA6B,CAAA;CACrE,CAAA;AAEnB;;;;;AAiBA,SAAgB,oBAAoB,EAAE,UAAU,eAAuD;CAErG,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACG,UACA,WAAW,WAAW,IACrB,oBAAC,SAAD;GAAO,WAAU;GAAiC,UAAA;EAAmB,CAAA,IAErE,WAEC;;AAET;AAEA,SAAS,cAAc;AACvB,cAAc,cAAc;AAC5B,kBAAkB,cAAc;AAChC,oBAAoB,cAAc"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { DisplayColumnHelper } from "./data-table-source.js";
|
|
2
|
+
import { ReactNode } from "react";
|
|
3
|
+
//#region src/components/data-table/actions-column.d.ts
|
|
4
|
+
/** The cell render context the actions column reads. */
|
|
5
|
+
type ActionsCellContext<TData> = {
|
|
6
|
+
readonly row: {
|
|
7
|
+
readonly original: TData;
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* The display column `actionsColumn` builds. It reads only the row's data, so it needs no table
|
|
12
|
+
* feature.
|
|
13
|
+
*/
|
|
14
|
+
export type ActionsColumnDef<TData> = {
|
|
15
|
+
readonly id: "actions";
|
|
16
|
+
readonly enableSorting: false;
|
|
17
|
+
readonly enableHiding: false;
|
|
18
|
+
readonly header: () => ReactNode;
|
|
19
|
+
readonly cell: (context: ActionsCellContext<TData>) => ReactNode;
|
|
20
|
+
};
|
|
21
|
+
/** `DisplayColumnHelper` for `actionsColumn`. */
|
|
22
|
+
export type ActionsColumnHelper<TData, TColumn> = DisplayColumnHelper<ActionsColumnDef<TData>, TColumn>;
|
|
23
|
+
/** Options for `actionsColumn`. */
|
|
24
|
+
export type ActionsColumnOptions<TData> = {
|
|
25
|
+
/**
|
|
26
|
+
* The row's own name, such as `(product) => product.name`. Fuse builds the trigger's localized
|
|
27
|
+
* accessible name from it ("Actions for 4K Ultra HD Monitor"), so no two triggers share a name.
|
|
28
|
+
*/
|
|
29
|
+
getRowName: (row: TData) => string;
|
|
30
|
+
/**
|
|
31
|
+
* The menu items for a row: `DropdownMenu.Item`, including `variant="destructive"`, and
|
|
32
|
+
* `DropdownMenu.Separator`.
|
|
33
|
+
*/
|
|
34
|
+
items: (row: TData) => ReactNode;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Build the row-actions column: `DataTable.RowActions` in each cell, right-aligned, with a
|
|
38
|
+
* per-row accessible name. The header names the column "Actions" for assistive technology without
|
|
39
|
+
* visible text, the column shrinks to the trigger, and sorting and hiding are disabled. Clicks in
|
|
40
|
+
* the open menu do not press a pressable row.
|
|
41
|
+
*
|
|
42
|
+
* @template TData - The row data type, inferred from the column helper.
|
|
43
|
+
* @template TColumn - The column definition type the helper returns.
|
|
44
|
+
* @param columnHelper - A column helper for the table.
|
|
45
|
+
* @param options - The row's name and its menu items.
|
|
46
|
+
* @returns A display column with the id `"actions"`.
|
|
47
|
+
*/
|
|
48
|
+
export declare function actionsColumn<TData, TColumn>(columnHelper: ActionsColumnHelper<TData, TColumn>, { getRowName, items }: ActionsColumnOptions<NoInfer<TData>>): TColumn;
|
|
49
|
+
//#endregion
|
|
50
|
+
//# sourceMappingURL=actions-column.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actions-column.d.ts","names":[],"sources":["../../../src/components/data-table/actions-column.tsx"],"mappings":";;;;KAMK,mBAAmB;WAAoB;aAAgB,UAAU;;;;;;;YAM1D,iBAAiB;WAClB;WACA;WACA;WACA,cAAc;WACd,OAAO,SAAS,mBAAmB,WAAW;;;YAI7C,oBAAoB,OAAO,WAAW,oBAAoB,iBAAiB,QAAQ;;YAGnF,qBAAqB;;;;;EAK/B,aAAa,KAAK;;;;;EAKlB,QAAQ,KAAK,UAAU;;;;;;;;;;;;;;wBAeT,cAAc,OAAO,SACnC,cAAc,oBAAoB,OAAO,YACvC,YAAY,SAAS,qBAAqB,QAAQ,UACnD"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { RowActionsCell, RowActionsHeader } from "./data-table-row-actions.js";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
//#region src/components/data-table/actions-column.tsx
|
|
4
|
+
/**
|
|
5
|
+
* Build the row-actions column: `DataTable.RowActions` in each cell, right-aligned, with a
|
|
6
|
+
* per-row accessible name. The header names the column "Actions" for assistive technology without
|
|
7
|
+
* visible text, the column shrinks to the trigger, and sorting and hiding are disabled. Clicks in
|
|
8
|
+
* the open menu do not press a pressable row.
|
|
9
|
+
*
|
|
10
|
+
* @template TData - The row data type, inferred from the column helper.
|
|
11
|
+
* @template TColumn - The column definition type the helper returns.
|
|
12
|
+
* @param columnHelper - A column helper for the table.
|
|
13
|
+
* @param options - The row's name and its menu items.
|
|
14
|
+
* @returns A display column with the id `"actions"`.
|
|
15
|
+
*/
|
|
16
|
+
function actionsColumn(columnHelper, { getRowName, items }) {
|
|
17
|
+
return columnHelper.display({
|
|
18
|
+
id: "actions",
|
|
19
|
+
enableSorting: false,
|
|
20
|
+
enableHiding: false,
|
|
21
|
+
header: () => /* @__PURE__ */ jsx(RowActionsHeader, {}),
|
|
22
|
+
cell: ({ row }) => /* @__PURE__ */ jsx(RowActionsCell, {
|
|
23
|
+
name: getRowName(row.original),
|
|
24
|
+
children: items(row.original)
|
|
25
|
+
})
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
//#endregion
|
|
29
|
+
export { actionsColumn };
|
|
30
|
+
|
|
31
|
+
//# sourceMappingURL=actions-column.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actions-column.js","names":[],"sources":["../../../src/components/data-table/actions-column.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\n\nimport { RowActionsCell, RowActionsHeader } from \"./data-table-row-actions\";\nimport type { DisplayColumnHelper } from \"./data-table-source\";\n\n/** The cell render context the actions column reads. */\ntype ActionsCellContext<TData> = { readonly row: { readonly original: TData } };\n\n/**\n * The display column `actionsColumn` builds. It reads only the row's data, so it needs no table\n * feature.\n */\nexport type ActionsColumnDef<TData> = {\n readonly id: \"actions\";\n readonly enableSorting: false;\n readonly enableHiding: false;\n readonly header: () => ReactNode;\n readonly cell: (context: ActionsCellContext<TData>) => ReactNode;\n};\n\n/** `DisplayColumnHelper` for `actionsColumn`. */\nexport type ActionsColumnHelper<TData, TColumn> = DisplayColumnHelper<ActionsColumnDef<TData>, TColumn>;\n\n/** Options for `actionsColumn`. */\nexport type ActionsColumnOptions<TData> = {\n /**\n * The row's own name, such as `(product) => product.name`. Fuse builds the trigger's localized\n * accessible name from it (\"Actions for 4K Ultra HD Monitor\"), so no two triggers share a name.\n */\n getRowName: (row: TData) => string;\n /**\n * The menu items for a row: `DropdownMenu.Item`, including `variant=\"destructive\"`, and\n * `DropdownMenu.Separator`.\n */\n items: (row: TData) => ReactNode;\n};\n\n/**\n * Build the row-actions column: `DataTable.RowActions` in each cell, right-aligned, with a\n * per-row accessible name. The header names the column \"Actions\" for assistive technology without\n * visible text, the column shrinks to the trigger, and sorting and hiding are disabled. Clicks in\n * the open menu do not press a pressable row.\n *\n * @template TData - The row data type, inferred from the column helper.\n * @template TColumn - The column definition type the helper returns.\n * @param columnHelper - A column helper for the table.\n * @param options - The row's name and its menu items.\n * @returns A display column with the id `\"actions\"`.\n */\nexport function actionsColumn<TData, TColumn>(\n columnHelper: ActionsColumnHelper<TData, TColumn>,\n { getRowName, items }: ActionsColumnOptions<NoInfer<TData>>\n): TColumn {\n return columnHelper.display({\n id: \"actions\",\n enableSorting: false,\n enableHiding: false,\n header: () => <RowActionsHeader />,\n cell: ({ row }) => <RowActionsCell name={getRowName(row.original)}>{items(row.original)}</RowActionsCell>,\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;AAiDA,SAAgB,cACd,cACA,EAAE,YAAY,SACL;CACT,OAAO,aAAa,QAAQ;EAC1B,IAAI;EACJ,eAAe;EACf,cAAc;EACd,cAAc,oBAAC,kBAAD,CAAmB,CAAA;EACjC,OAAO,EAAE,UAAU,oBAAC,gBAAD;GAAgB,MAAM,WAAW,IAAI,QAAQ;GAAI,UAAA,MAAM,IAAI,QAAQ;EAAkB,CAAA;CAC1G,CAAC;AACH"}
|