@elmeragroup/fuse 0.1.0-canary.13 → 0.1.0-canary.15
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 +9 -0
- 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 +24 -4
- 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/field/field-frame.js +1 -1
- 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/radio-group/radio-group.js +1 -1
- package/components/toast/toast.js +1 -1
- package/icons.js +1 -1
- package/package.json +2 -2
- package/styles/fuse.css +17 -0
- package/styles.css +66 -0
- package/themes.css +32 -0
package/README.md
CHANGED
|
@@ -48,6 +48,15 @@ A host that migrates one component at a time can keep its own design tokens and
|
|
|
48
48
|
|
|
49
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
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
|
+
|
|
51
60
|
## Non-Tailwind
|
|
52
61
|
|
|
53
62
|
```css
|
|
@@ -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 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", 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,5 +1,5 @@
|
|
|
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
|
|
@@ -24,10 +24,25 @@ type ButtonSharedProps = ButtonPrimitiveProps & Omit<VariantProps<typeof buttonV
|
|
|
24
24
|
*/
|
|
25
25
|
isVisuallyDisabled?: boolean;
|
|
26
26
|
/**
|
|
27
|
-
*
|
|
28
|
-
*
|
|
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.
|
|
29
35
|
*/
|
|
30
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;
|
|
31
46
|
/** Pixels the hit rect is inflated on every side when predicting pointer intent. */
|
|
32
47
|
predictionZoneSize?: number;
|
|
33
48
|
/**
|
|
@@ -60,7 +75,12 @@ export type IconButtonProps = ButtonSharedProps & {
|
|
|
60
75
|
* {@link IconButtonProps} instead, or distribute the omit over the union.
|
|
61
76
|
*/
|
|
62
77
|
export type ButtonProps = LabelButtonProps | IconButtonProps;
|
|
63
|
-
|
|
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;
|
|
64
84
|
export declare namespace Button {
|
|
65
85
|
var displayName: string;
|
|
66
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\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 *
|
|
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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { cn } from "../../styles/cn.js";
|
|
2
2
|
import { iconCrossfadeHidden, iconCrossfadeShown, iconCrossfadeTransition } from "../../styles/utils.js";
|
|
3
|
-
import { Check } from "../../icons/generated/check.js";
|
|
4
3
|
import { SpinnerGap } from "../../icons/generated/spinner-gap.js";
|
|
4
|
+
import { Check } from "../../icons/generated/check.js";
|
|
5
5
|
import { FieldDescription, FieldError, FieldLabel, FieldLegend, FieldRoot, FieldSet } from "./field.js";
|
|
6
6
|
import { tv } from "tailwind-variants";
|
|
7
7
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -33,30 +33,32 @@ export declare const inputGroupAddonVariants: import("tailwind-variants").TVRetu
|
|
|
33
33
|
* four values are addon chrome inside the group, NOT the four-rung control box
|
|
34
34
|
* (`xs`/`sm`/`md`/`lg`), so they are an explicit shell-local exemption from the
|
|
35
35
|
* density ladder and must never grow a
|
|
36
|
-
* fifth `--control-*` rung.
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
36
|
+
* fifth `--control-*` rung. InputGroup.Button applies the values as extra classes over
|
|
37
|
+
* Button's default size, the md label. Every size swaps Button's own icon edge back to the
|
|
38
|
+
* md control icon edge, and `sm`, which keeps that label's box, also swaps Button's inset
|
|
39
|
+
* back to the md control inset, the field's own padding, so Button's wider comfortable inset
|
|
40
|
+
* and icon edge never reach a field. An addon button sits inside the field box, so it pads and
|
|
41
|
+
* rounds like the field chrome and never takes Button's `--radius-button`. The `sm` sizes keep
|
|
42
|
+
* `rounded-md`, and the `xs` sizes take the kbd's inset corner.
|
|
41
43
|
*/
|
|
42
44
|
export declare const inputGroupButtonVariants: import("tailwind-variants").TVReturnType<{
|
|
43
45
|
size: {
|
|
44
46
|
xs: "h-6 gap-1 px-1.5 [&>svg:not([class*='size-'])]:size-3.5";
|
|
45
|
-
sm:
|
|
47
|
+
sm: string;
|
|
46
48
|
"icon-xs": "size-6 p-0 has-[>svg]:p-0";
|
|
47
49
|
"icon-sm": "size-8 p-0 has-[>svg]:p-0";
|
|
48
50
|
};
|
|
49
|
-
}, undefined,
|
|
51
|
+
}, undefined, string, {
|
|
50
52
|
size: {
|
|
51
53
|
xs: "h-6 gap-1 px-1.5 [&>svg:not([class*='size-'])]:size-3.5";
|
|
52
|
-
sm:
|
|
54
|
+
sm: string;
|
|
53
55
|
"icon-xs": "size-6 p-0 has-[>svg]:p-0";
|
|
54
56
|
"icon-sm": "size-8 p-0 has-[>svg]:p-0";
|
|
55
57
|
};
|
|
56
58
|
}, undefined, import("tailwind-variants").TVReturnTypeLike<{
|
|
57
59
|
size: {
|
|
58
60
|
xs: "h-6 gap-1 px-1.5 [&>svg:not([class*='size-'])]:size-3.5";
|
|
59
|
-
sm:
|
|
61
|
+
sm: string;
|
|
60
62
|
"icon-xs": "size-6 p-0 has-[>svg]:p-0";
|
|
61
63
|
"icon-sm": "size-8 p-0 has-[>svg]:p-0";
|
|
62
64
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input-group-variants.d.ts","names":[],"sources":["../../../src/components/input-group/input-group-variants.ts"],"mappings":";;;;;;;;
|
|
1
|
+
{"version":3,"file":"input-group-variants.d.ts","names":[],"sources":["../../../src/components/input-group/input-group-variants.ts"],"mappings":";;;;;;;;qBAaa,qDAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAiCvB,sDAAwB"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { cn } from "../../styles/cn.js";
|
|
2
|
+
import { controlMd } from "../../styles/control-size-md.js";
|
|
2
3
|
import { insetCornerClass, kbdInsetCornerClass } from "../../styles/corner-radius.js";
|
|
3
4
|
import { tv } from "tailwind-variants";
|
|
4
5
|
//#region src/components/input-group/input-group-variants.ts
|
|
@@ -24,17 +25,19 @@ const inputGroupAddonVariants = tv({
|
|
|
24
25
|
* four values are addon chrome inside the group, NOT the four-rung control box
|
|
25
26
|
* (`xs`/`sm`/`md`/`lg`), so they are an explicit shell-local exemption from the
|
|
26
27
|
* density ladder and must never grow a
|
|
27
|
-
* fifth `--control-*` rung.
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
28
|
+
* fifth `--control-*` rung. InputGroup.Button applies the values as extra classes over
|
|
29
|
+
* Button's default size, the md label. Every size swaps Button's own icon edge back to the
|
|
30
|
+
* md control icon edge, and `sm`, which keeps that label's box, also swaps Button's inset
|
|
31
|
+
* back to the md control inset, the field's own padding, so Button's wider comfortable inset
|
|
32
|
+
* and icon edge never reach a field. An addon button sits inside the field box, so it pads and
|
|
33
|
+
* rounds like the field chrome and never takes Button's `--radius-button`. The `sm` sizes keep
|
|
34
|
+
* `rounded-md`, and the `xs` sizes take the kbd's inset corner.
|
|
32
35
|
*/
|
|
33
36
|
const inputGroupButtonVariants = tv({
|
|
34
|
-
base: "text-sm flex items-center gap-2 rounded-md shadow-none",
|
|
37
|
+
base: cn("text-sm flex items-center gap-2 rounded-md shadow-none", controlMd.iconEdge()),
|
|
35
38
|
variants: { size: {
|
|
36
39
|
xs: "h-6 gap-1 px-1.5 [&>svg:not([class*='size-'])]:size-3.5",
|
|
37
|
-
sm:
|
|
40
|
+
sm: controlMd.inset(),
|
|
38
41
|
"icon-xs": "size-6 p-0 has-[>svg]:p-0",
|
|
39
42
|
"icon-sm": "size-8 p-0 has-[>svg]:p-0"
|
|
40
43
|
} },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input-group-variants.js","names":[],"sources":["../../../src/components/input-group/input-group-variants.ts"],"sourcesContent":["import { tv } from \"tailwind-variants\";\n\nimport { cn } from \"../../styles/cn\";\nimport { insetCornerClass, kbdInsetCornerClass } from \"../../styles/corner-radius\";\n\n/**\n * Module-private recipe for the group's addon rail. `align` places\n * the rail inline (leading/trailing) or as a full-width block row; the Root\n * switches to a column and re-pads the input from the emitted `data-align`.\n * The kbd takes the inset corner, 5px inside `--radius` in external themes and the one\n * radius in the internal variant.\n */\nexport const inputGroupAddonVariants = tv({\n base: cn(\n \"text-sm font-medium flex h-auto cursor-text items-center justify-center gap-2 py-1.5 text-muted-foreground select-none [&>svg:not([class*='size-'])]:size-4\",\n kbdInsetCornerClass\n ),\n variants: {\n align: {\n \"inline-start\": \"order-first pl-2 has-[>button]:-ml-1 has-[>kbd]:ml-[-0.15rem]\",\n \"inline-end\": \"order-last pr-2 has-[>button]:-mr-1 has-[>kbd]:mr-[-0.15rem]\",\n \"block-start\":\n \"order-first w-full justify-start px-2.5 pt-2 group-has-[>input]/input-group:pt-2 [.border-b]:pb-2\",\n \"block-end\":\n \"order-last w-full justify-start px-2.5 pb-2 group-has-[>input]/input-group:pb-2 [.border-t]:pt-2\",\n },\n },\n defaultVariants: {\n align: \"inline-start\",\n },\n});\n\n/**\n * Module-private recipe for the compact addon-button axis. These\n * four values are addon chrome inside the group, NOT the four-rung control box\n * (`xs`/`sm`/`md`/`lg`), so they are an explicit shell-local exemption from the\n * density ladder and must never grow a\n * fifth `--control-*` rung.
|
|
1
|
+
{"version":3,"file":"input-group-variants.js","names":[],"sources":["../../../src/components/input-group/input-group-variants.ts"],"sourcesContent":["import { tv } from \"tailwind-variants\";\n\nimport { cn } from \"../../styles/cn\";\nimport { controlMd } from \"../../styles/control-size-md\";\nimport { insetCornerClass, kbdInsetCornerClass } from \"../../styles/corner-radius\";\n\n/**\n * Module-private recipe for the group's addon rail. `align` places\n * the rail inline (leading/trailing) or as a full-width block row; the Root\n * switches to a column and re-pads the input from the emitted `data-align`.\n * The kbd takes the inset corner, 5px inside `--radius` in external themes and the one\n * radius in the internal variant.\n */\nexport const inputGroupAddonVariants = tv({\n base: cn(\n \"text-sm font-medium flex h-auto cursor-text items-center justify-center gap-2 py-1.5 text-muted-foreground select-none [&>svg:not([class*='size-'])]:size-4\",\n kbdInsetCornerClass\n ),\n variants: {\n align: {\n \"inline-start\": \"order-first pl-2 has-[>button]:-ml-1 has-[>kbd]:ml-[-0.15rem]\",\n \"inline-end\": \"order-last pr-2 has-[>button]:-mr-1 has-[>kbd]:mr-[-0.15rem]\",\n \"block-start\":\n \"order-first w-full justify-start px-2.5 pt-2 group-has-[>input]/input-group:pt-2 [.border-b]:pb-2\",\n \"block-end\":\n \"order-last w-full justify-start px-2.5 pb-2 group-has-[>input]/input-group:pb-2 [.border-t]:pt-2\",\n },\n },\n defaultVariants: {\n align: \"inline-start\",\n },\n});\n\n/**\n * Module-private recipe for the compact addon-button axis. These\n * four values are addon chrome inside the group, NOT the four-rung control box\n * (`xs`/`sm`/`md`/`lg`), so they are an explicit shell-local exemption from the\n * density ladder and must never grow a\n * fifth `--control-*` rung. InputGroup.Button applies the values as extra classes over\n * Button's default size, the md label. Every size swaps Button's own icon edge back to the\n * md control icon edge, and `sm`, which keeps that label's box, also swaps Button's inset\n * back to the md control inset, the field's own padding, so Button's wider comfortable inset\n * and icon edge never reach a field. An addon button sits inside the field box, so it pads and\n * rounds like the field chrome and never takes Button's `--radius-button`. The `sm` sizes keep\n * `rounded-md`, and the `xs` sizes take the kbd's inset corner.\n */\nexport const inputGroupButtonVariants = tv({\n base: cn(\"text-sm flex items-center gap-2 rounded-md shadow-none\", controlMd.iconEdge()),\n variants: {\n size: {\n // oxlint-disable-next-line elmera/no-hardcoded-density-metrics -- compact addon chrome, not a control rung\n xs: \"h-6 gap-1 px-1.5 [&>svg:not([class*='size-'])]:size-3.5\",\n sm: controlMd.inset(),\n // oxlint-disable-next-line elmera/no-hardcoded-density-metrics -- compact addon chrome, not a control rung\n \"icon-xs\": \"size-6 p-0 has-[>svg]:p-0\",\n // oxlint-disable-next-line elmera/no-hardcoded-density-metrics -- compact addon chrome, not a control rung\n \"icon-sm\": \"size-8 p-0 has-[>svg]:p-0\",\n },\n },\n compoundVariants: [{ size: [\"xs\", \"icon-xs\"], class: insetCornerClass }],\n defaultVariants: {\n size: \"xs\",\n },\n});\n"],"mappings":";;;;;;;;;;;;AAaA,MAAa,0BAA0B,GAAG;CACxC,MAAM,GACJ,+JACA,mBACF;CACA,UAAU,EACR,OAAO;EACL,gBAAgB;EAChB,cAAc;EACd,eACE;EACF,aACE;CACJ,EACF;CACA,iBAAiB,EACf,OAAO,eACT;AACF,CAAC;;;;;;;;;;;;;;AAeD,MAAa,2BAA2B,GAAG;CACzC,MAAM,GAAG,0DAA0D,UAAU,SAAS,CAAC;CACvF,UAAU,EACR,MAAM;EAEJ,IAAI;EACJ,IAAI,UAAU,MAAM;EAEpB,WAAW;EAEX,WAAW;CACb,EACF;CACA,kBAAkB,CAAC;EAAE,MAAM,CAAC,MAAM,SAAS;EAAG,OAAO;CAAiB,CAAC;CACvE,iBAAiB,EACf,MAAM,KACR;AACF,CAAC"}
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import { cn } from "../../styles/cn.js";
|
|
3
3
|
import { dataStateFaceClass } from "../../styles/state-face.js";
|
|
4
4
|
import { selfFocusRingClass } from "../../styles/utils.js";
|
|
5
|
-
import { definedProps } from "../../internal/defined-props.js";
|
|
6
5
|
import { SpinnerGap } from "../../icons/generated/spinner-gap.js";
|
|
6
|
+
import { definedProps } from "../../internal/defined-props.js";
|
|
7
7
|
import { FieldItem } from "../field/field.js";
|
|
8
8
|
import { FieldFrame } from "../field/field-frame.js";
|
|
9
9
|
import { selectionGroupOrientationVariants } from "../selection-item/selection-item-variants.js";
|
|
@@ -3,6 +3,7 @@ import { selfFocusRingClass } from "../../styles/utils.js";
|
|
|
3
3
|
import { useLocalizedStrings } from "../../hooks/use-localized-strings.js";
|
|
4
4
|
import { Info } from "../../icons/generated/info.js";
|
|
5
5
|
import { WarningOctagon } from "../../icons/generated/warning-octagon.js";
|
|
6
|
+
import { SpinnerGap } from "../../icons/generated/spinner-gap.js";
|
|
6
7
|
import { Button } from "../button/button.js";
|
|
7
8
|
import { mergeClassName } from "../../styles/merge-class-name.js";
|
|
8
9
|
import { overlayCloseStrings } from "../overlay/intl/index.js";
|
|
@@ -11,7 +12,6 @@ import { X } from "../../icons/generated/x.js";
|
|
|
11
12
|
import { OverlayPortal } from "../overlay/overlay-portal.js";
|
|
12
13
|
import { CheckCircle } from "../../icons/generated/check-circle.js";
|
|
13
14
|
import { Warning } from "../../icons/generated/warning.js";
|
|
14
|
-
import { SpinnerGap } from "../../icons/generated/spinner-gap.js";
|
|
15
15
|
import { toastVariants } from "./toast-variants.js";
|
|
16
16
|
import { useMemo } from "react";
|
|
17
17
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
package/icons.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { CaretDown } from "./icons/generated/caret-down.js";
|
|
2
2
|
import { Info } from "./icons/generated/info.js";
|
|
3
3
|
import { WarningOctagon } from "./icons/generated/warning-octagon.js";
|
|
4
|
+
import { SpinnerGap } from "./icons/generated/spinner-gap.js";
|
|
4
5
|
import { X } from "./icons/generated/x.js";
|
|
5
6
|
import { CheckCircle } from "./icons/generated/check-circle.js";
|
|
6
7
|
import { Warning } from "./icons/generated/warning.js";
|
|
@@ -9,7 +10,6 @@ import { DotsThree } from "./icons/generated/dots-three.js";
|
|
|
9
10
|
import { Circle } from "./icons/generated/circle.js";
|
|
10
11
|
import { Check } from "./icons/generated/check.js";
|
|
11
12
|
import { Minus } from "./icons/generated/minus.js";
|
|
12
|
-
import { SpinnerGap } from "./icons/generated/spinner-gap.js";
|
|
13
13
|
import { SlidersHorizontal } from "./icons/generated/sliders-horizontal.js";
|
|
14
14
|
import { CaretDoubleLeft } from "./icons/generated/caret-double-left.js";
|
|
15
15
|
import { CaretDoubleRight } from "./icons/generated/caret-double-right.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elmeragroup/fuse",
|
|
3
|
-
"version": "0.1.0-canary.
|
|
3
|
+
"version": "0.1.0-canary.15",
|
|
4
4
|
"description": "Fuse — whitelabel React components for Elmera Group's energy brands. One package, twenty theme permutations, ESM-only.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -359,7 +359,7 @@
|
|
|
359
359
|
"access": "public"
|
|
360
360
|
},
|
|
361
361
|
"elmeraRelease": {
|
|
362
|
-
"commit": "
|
|
362
|
+
"commit": "1936fdd7dad8279399f8434898745cfb63838016",
|
|
363
363
|
"channel": "canary"
|
|
364
364
|
}
|
|
365
365
|
}
|
package/styles/fuse.css
CHANGED
|
@@ -17,6 +17,14 @@
|
|
|
17
17
|
--control-px-icon-sm: 0.375rem;
|
|
18
18
|
--control-px-icon-md: 0.5rem;
|
|
19
19
|
--control-px-icon-lg: 0.5rem;
|
|
20
|
+
--control-px-button-xs: 0.5rem;
|
|
21
|
+
--control-px-button-sm: 0.625rem;
|
|
22
|
+
--control-px-button-md: 0.625rem;
|
|
23
|
+
--control-px-button-lg: 0.625rem;
|
|
24
|
+
--control-px-button-icon-xs: 0.375rem;
|
|
25
|
+
--control-px-button-icon-sm: 0.375rem;
|
|
26
|
+
--control-px-button-icon-md: 0.5rem;
|
|
27
|
+
--control-px-button-icon-lg: 0.5rem;
|
|
20
28
|
--control-gap-xs: 0.25rem;
|
|
21
29
|
--control-gap-sm: 0.25rem;
|
|
22
30
|
--control-gap-md: 0.375rem;
|
|
@@ -38,6 +46,14 @@
|
|
|
38
46
|
--control-px-icon-sm: 0.625rem;
|
|
39
47
|
--control-px-icon-md: 0.75rem;
|
|
40
48
|
--control-px-icon-lg: 0.75rem;
|
|
49
|
+
--control-px-button-xs: 0.75rem;
|
|
50
|
+
--control-px-button-sm: 1rem;
|
|
51
|
+
--control-px-button-md: 2rem;
|
|
52
|
+
--control-px-button-lg: 2rem;
|
|
53
|
+
--control-px-button-icon-xs: 0.625rem;
|
|
54
|
+
--control-px-button-icon-sm: 0.75rem;
|
|
55
|
+
--control-px-button-icon-md: 1.5rem;
|
|
56
|
+
--control-px-button-icon-lg: 1.5rem;
|
|
41
57
|
--control-gap-xs: 0.375rem;
|
|
42
58
|
--control-gap-sm: 0.375rem;
|
|
43
59
|
--control-gap-md: 0.5rem;
|
|
@@ -94,6 +110,7 @@
|
|
|
94
110
|
--color-border: var(--border);
|
|
95
111
|
--color-input: var(--input);
|
|
96
112
|
--color-ring: var(--ring);
|
|
113
|
+
--color-button-outline: var(--button-outline, var(--border));
|
|
97
114
|
--color-sidebar: var(--sidebar);
|
|
98
115
|
--color-sidebar-foreground: var(--sidebar-foreground);
|
|
99
116
|
--color-sidebar-accent: var(--sidebar-accent);
|
package/styles.css
CHANGED
|
@@ -1108,6 +1108,10 @@
|
|
|
1108
1108
|
border-style: var(--tw-border-style);
|
|
1109
1109
|
border-width: 0px;
|
|
1110
1110
|
}
|
|
1111
|
+
.border-\[length\:var\(--button-outline-width\,1px\)\] {
|
|
1112
|
+
border-style: var(--tw-border-style);
|
|
1113
|
+
border-width: var(--button-outline-width,1px);
|
|
1114
|
+
}
|
|
1111
1115
|
.border-s {
|
|
1112
1116
|
border-inline-start-style: var(--tw-border-style);
|
|
1113
1117
|
border-inline-start-width: 1px;
|
|
@@ -1138,6 +1142,9 @@
|
|
|
1138
1142
|
.border-border {
|
|
1139
1143
|
border-color: var(--border);
|
|
1140
1144
|
}
|
|
1145
|
+
.border-button-outline {
|
|
1146
|
+
border-color: var(--button-outline, var(--border));
|
|
1147
|
+
}
|
|
1141
1148
|
.border-error {
|
|
1142
1149
|
border-color: var(--error);
|
|
1143
1150
|
}
|
|
@@ -1351,6 +1358,18 @@
|
|
|
1351
1358
|
.p-px {
|
|
1352
1359
|
padding: 1px;
|
|
1353
1360
|
}
|
|
1361
|
+
.px-\(--control-px-button-lg\) {
|
|
1362
|
+
padding-inline: var(--control-px-button-lg);
|
|
1363
|
+
}
|
|
1364
|
+
.px-\(--control-px-button-md\) {
|
|
1365
|
+
padding-inline: var(--control-px-button-md);
|
|
1366
|
+
}
|
|
1367
|
+
.px-\(--control-px-button-sm\) {
|
|
1368
|
+
padding-inline: var(--control-px-button-sm);
|
|
1369
|
+
}
|
|
1370
|
+
.px-\(--control-px-button-xs\) {
|
|
1371
|
+
padding-inline: var(--control-px-button-xs);
|
|
1372
|
+
}
|
|
1354
1373
|
.px-\(--control-px-icon-lg\) {
|
|
1355
1374
|
padding-inline: var(--control-px-icon-lg);
|
|
1356
1375
|
}
|
|
@@ -1790,6 +1809,10 @@
|
|
|
1790
1809
|
--tw-shadow: 0 0 0 1px var(--tw-shadow-color, var(--sidebar-border));
|
|
1791
1810
|
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
|
1792
1811
|
}
|
|
1812
|
+
.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\)\] {
|
|
1813
|
+
--tw-shadow: 0 1px max(0px, 4px - 2 * var(--button-outline-width,1px)) min(0px, 2px - 2 * var(--button-outline-width,1px)) var(--tw-shadow-color, rgb(0 0 0/0.05));
|
|
1814
|
+
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
|
1815
|
+
}
|
|
1793
1816
|
.shadow-lg {
|
|
1794
1817
|
--tw-shadow: 0 10px 15px -3px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 4px 6px -4px var(--tw-shadow-color, rgb(0 0 0 / 0.1));
|
|
1795
1818
|
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
|
@@ -2965,6 +2988,18 @@
|
|
|
2965
2988
|
.has-disabled\:cursor-not-allowed:has(:is(:where([data-rac])[data-disabled], :where(:not([data-rac])):disabled)) {
|
|
2966
2989
|
cursor: not-allowed;
|
|
2967
2990
|
}
|
|
2991
|
+
.has-data-\[icon\=inline-end\]\:pr-\(--control-px-button-icon-lg\):has([data-icon="inline-end"]) {
|
|
2992
|
+
padding-right: var(--control-px-button-icon-lg);
|
|
2993
|
+
}
|
|
2994
|
+
.has-data-\[icon\=inline-end\]\:pr-\(--control-px-button-icon-md\):has([data-icon="inline-end"]) {
|
|
2995
|
+
padding-right: var(--control-px-button-icon-md);
|
|
2996
|
+
}
|
|
2997
|
+
.has-data-\[icon\=inline-end\]\:pr-\(--control-px-button-icon-sm\):has([data-icon="inline-end"]) {
|
|
2998
|
+
padding-right: var(--control-px-button-icon-sm);
|
|
2999
|
+
}
|
|
3000
|
+
.has-data-\[icon\=inline-end\]\:pr-\(--control-px-button-icon-xs\):has([data-icon="inline-end"]) {
|
|
3001
|
+
padding-right: var(--control-px-button-icon-xs);
|
|
3002
|
+
}
|
|
2968
3003
|
.has-data-\[icon\=inline-end\]\:pr-\(--control-px-icon-lg\):has([data-icon="inline-end"]) {
|
|
2969
3004
|
padding-right: var(--control-px-icon-lg);
|
|
2970
3005
|
}
|
|
@@ -2977,6 +3012,18 @@
|
|
|
2977
3012
|
.has-data-\[icon\=inline-end\]\:pr-\(--control-px-icon-xs\):has([data-icon="inline-end"]) {
|
|
2978
3013
|
padding-right: var(--control-px-icon-xs);
|
|
2979
3014
|
}
|
|
3015
|
+
.has-data-\[icon\=inline-start\]\:pl-\(--control-px-button-icon-lg\):has([data-icon="inline-start"]) {
|
|
3016
|
+
padding-left: var(--control-px-button-icon-lg);
|
|
3017
|
+
}
|
|
3018
|
+
.has-data-\[icon\=inline-start\]\:pl-\(--control-px-button-icon-md\):has([data-icon="inline-start"]) {
|
|
3019
|
+
padding-left: var(--control-px-button-icon-md);
|
|
3020
|
+
}
|
|
3021
|
+
.has-data-\[icon\=inline-start\]\:pl-\(--control-px-button-icon-sm\):has([data-icon="inline-start"]) {
|
|
3022
|
+
padding-left: var(--control-px-button-icon-sm);
|
|
3023
|
+
}
|
|
3024
|
+
.has-data-\[icon\=inline-start\]\:pl-\(--control-px-button-icon-xs\):has([data-icon="inline-start"]) {
|
|
3025
|
+
padding-left: var(--control-px-button-icon-xs);
|
|
3026
|
+
}
|
|
2980
3027
|
.has-data-\[icon\=inline-start\]\:pl-\(--control-px-icon-lg\):has([data-icon="inline-start"]) {
|
|
2981
3028
|
padding-left: var(--control-px-icon-lg);
|
|
2982
3029
|
}
|
|
@@ -4510,6 +4557,9 @@
|
|
|
4510
4557
|
width: calc(0.25rem * 4);
|
|
4511
4558
|
height: calc(0.25rem * 4);
|
|
4512
4559
|
}
|
|
4560
|
+
.data-\[pending-indicator\]\:\[\&\>svg\:not\(\[data-icon\=inline-end\]\)\]\:hidden[data-pending-indicator] > svg:not([data-icon=inline-end]) {
|
|
4561
|
+
display: none;
|
|
4562
|
+
}
|
|
4513
4563
|
.\[\&\>tr\]\:last\:border-b-0 > tr:last-child {
|
|
4514
4564
|
border-bottom-style: var(--tw-border-style);
|
|
4515
4565
|
border-bottom-width: 0px;
|
|
@@ -4666,6 +4716,14 @@ td:last-child .\[td\:last-child_\&\]\:rounded-e-full {
|
|
|
4666
4716
|
--control-px-icon-sm: 0.375rem;
|
|
4667
4717
|
--control-px-icon-md: 0.5rem;
|
|
4668
4718
|
--control-px-icon-lg: 0.5rem;
|
|
4719
|
+
--control-px-button-xs: 0.5rem;
|
|
4720
|
+
--control-px-button-sm: 0.625rem;
|
|
4721
|
+
--control-px-button-md: 0.625rem;
|
|
4722
|
+
--control-px-button-lg: 0.625rem;
|
|
4723
|
+
--control-px-button-icon-xs: 0.375rem;
|
|
4724
|
+
--control-px-button-icon-sm: 0.375rem;
|
|
4725
|
+
--control-px-button-icon-md: 0.5rem;
|
|
4726
|
+
--control-px-button-icon-lg: 0.5rem;
|
|
4669
4727
|
--control-gap-xs: 0.25rem;
|
|
4670
4728
|
--control-gap-sm: 0.25rem;
|
|
4671
4729
|
--control-gap-md: 0.375rem;
|
|
@@ -4686,6 +4744,14 @@ td:last-child .\[td\:last-child_\&\]\:rounded-e-full {
|
|
|
4686
4744
|
--control-px-icon-sm: 0.625rem;
|
|
4687
4745
|
--control-px-icon-md: 0.75rem;
|
|
4688
4746
|
--control-px-icon-lg: 0.75rem;
|
|
4747
|
+
--control-px-button-xs: 0.75rem;
|
|
4748
|
+
--control-px-button-sm: 1rem;
|
|
4749
|
+
--control-px-button-md: 2rem;
|
|
4750
|
+
--control-px-button-lg: 2rem;
|
|
4751
|
+
--control-px-button-icon-xs: 0.625rem;
|
|
4752
|
+
--control-px-button-icon-sm: 0.75rem;
|
|
4753
|
+
--control-px-button-icon-md: 1.5rem;
|
|
4754
|
+
--control-px-button-icon-lg: 1.5rem;
|
|
4689
4755
|
--control-gap-xs: 0.375rem;
|
|
4690
4756
|
--control-gap-sm: 0.375rem;
|
|
4691
4757
|
--control-gap-md: 0.5rem;
|
package/themes.css
CHANGED
|
@@ -75,6 +75,7 @@
|
|
|
75
75
|
--border: oklch(0.9219 0 0);
|
|
76
76
|
--input: oklch(0.9219 0 0);
|
|
77
77
|
--ring: oklch(0.4844 0.20509 296.29);
|
|
78
|
+
--button-outline: var(--border);
|
|
78
79
|
--sidebar: oklch(0.9851 0 0);
|
|
79
80
|
--sidebar-foreground: oklch(0.16 0 0);
|
|
80
81
|
--sidebar-accent: oklch(0.9219 0 0);
|
|
@@ -105,6 +106,7 @@
|
|
|
105
106
|
--radius: 0.375rem;
|
|
106
107
|
--radius-button: var(--radius);
|
|
107
108
|
--radius-step: 0px;
|
|
109
|
+
--button-outline-width: 1px;
|
|
108
110
|
--font-sans: Roboto, ui-sans-serif, system-ui, sans-serif;
|
|
109
111
|
--font-heading: var(--font-sans);
|
|
110
112
|
}
|
|
@@ -174,9 +176,11 @@
|
|
|
174
176
|
--feature-foreground: oklch(0.16 0 0);
|
|
175
177
|
--border: oklch(0.9219 0 0);
|
|
176
178
|
--input: oklch(0.9219 0 0);
|
|
179
|
+
--button-outline: var(--border);
|
|
177
180
|
--radius: 0.375rem;
|
|
178
181
|
--radius-button: var(--radius);
|
|
179
182
|
--radius-step: 0px;
|
|
183
|
+
--button-outline-width: 1px;
|
|
180
184
|
--font-heading: var(--font-sans);
|
|
181
185
|
color-scheme: light;
|
|
182
186
|
}
|
|
@@ -204,9 +208,11 @@
|
|
|
204
208
|
--feature-foreground: oklch(0.80097 0.10434 49.42);
|
|
205
209
|
--border: oklch(0.9232 0.0026 48.72);
|
|
206
210
|
--input: oklch(0.9232 0.0026 48.72);
|
|
211
|
+
--button-outline: var(--foreground);
|
|
207
212
|
--radius: 0.75rem;
|
|
208
213
|
--radius-button: 1.8125rem;
|
|
209
214
|
--radius-step: 2px;
|
|
215
|
+
--button-outline-width: 2px;
|
|
210
216
|
--font-heading: "Neo Sans", var(--font-sans);
|
|
211
217
|
color-scheme: light;
|
|
212
218
|
}
|
|
@@ -254,9 +260,11 @@
|
|
|
254
260
|
--feature-foreground: oklch(0.90178 0.09399 190.62);
|
|
255
261
|
--border: oklch(0.929 0.0126 255.53);
|
|
256
262
|
--input: oklch(0.929 0.0126 255.53);
|
|
263
|
+
--button-outline: var(--foreground);
|
|
257
264
|
--radius: 0.95rem;
|
|
258
265
|
--radius-button: 0.95rem;
|
|
259
266
|
--radius-step: 2px;
|
|
267
|
+
--button-outline-width: 2px;
|
|
260
268
|
--font-heading: var(--font-sans);
|
|
261
269
|
color-scheme: light;
|
|
262
270
|
}
|
|
@@ -284,9 +292,11 @@
|
|
|
284
292
|
--feature-foreground: oklch(0.84919 0.07412 279.64);
|
|
285
293
|
--border: oklch(0.929 0.0126 255.53);
|
|
286
294
|
--input: oklch(0.929 0.0126 255.53);
|
|
295
|
+
--button-outline: var(--foreground);
|
|
287
296
|
--radius: 0.5rem;
|
|
288
297
|
--radius-button: 0.5rem;
|
|
289
298
|
--radius-step: 2px;
|
|
299
|
+
--button-outline-width: 2px;
|
|
290
300
|
--font-heading: var(--font-sans);
|
|
291
301
|
color-scheme: light;
|
|
292
302
|
}
|
|
@@ -314,9 +324,11 @@
|
|
|
314
324
|
--feature-foreground: oklch(0.80097 0.10434 49.42);
|
|
315
325
|
--border: oklch(0.9232 0.0026 48.72);
|
|
316
326
|
--input: oklch(0.9232 0.0026 48.72);
|
|
327
|
+
--button-outline: var(--foreground);
|
|
317
328
|
--radius: 0.75rem;
|
|
318
329
|
--radius-button: 1.8125rem;
|
|
319
330
|
--radius-step: 2px;
|
|
331
|
+
--button-outline-width: 2px;
|
|
320
332
|
--font-heading: "Neo Sans", var(--font-sans);
|
|
321
333
|
color-scheme: light;
|
|
322
334
|
}
|
|
@@ -344,9 +356,11 @@
|
|
|
344
356
|
--feature-foreground: oklch(0.90492 0.09477 206.46);
|
|
345
357
|
--border: oklch(0.9232 0.0026 48.72);
|
|
346
358
|
--input: oklch(0.9232 0.0026 48.72);
|
|
359
|
+
--button-outline: var(--foreground);
|
|
347
360
|
--radius: 0.75rem;
|
|
348
361
|
--radius-button: 1.8125rem;
|
|
349
362
|
--radius-step: 2px;
|
|
363
|
+
--button-outline-width: 2px;
|
|
350
364
|
--font-heading: var(--font-sans);
|
|
351
365
|
color-scheme: light;
|
|
352
366
|
}
|
|
@@ -374,9 +388,11 @@
|
|
|
374
388
|
--feature-foreground: oklch(0.9094 0.046626 220.6);
|
|
375
389
|
--border: oklch(0.9219 0 0);
|
|
376
390
|
--input: oklch(0.9219 0 0);
|
|
391
|
+
--button-outline: var(--foreground);
|
|
377
392
|
--radius: 0.375rem;
|
|
378
393
|
--radius-button: 0.375rem;
|
|
379
394
|
--radius-step: 2px;
|
|
395
|
+
--button-outline-width: 2px;
|
|
380
396
|
--font-heading: var(--font-sans);
|
|
381
397
|
color-scheme: light;
|
|
382
398
|
}
|
|
@@ -428,6 +444,7 @@
|
|
|
428
444
|
--border: oklch(1 0 0 / 10%);
|
|
429
445
|
--input: oklch(1 0 0 / 40%);
|
|
430
446
|
--ring: oklch(0.556 0 0);
|
|
447
|
+
--button-outline: var(--border);
|
|
431
448
|
--sidebar: oklch(0.205 0 0);
|
|
432
449
|
--sidebar-foreground: oklch(0.985 0 0);
|
|
433
450
|
--sidebar-accent: oklch(0.269 0 0);
|
|
@@ -456,6 +473,7 @@
|
|
|
456
473
|
--radius: 0.375rem;
|
|
457
474
|
--radius-button: var(--radius);
|
|
458
475
|
--radius-step: 0px;
|
|
476
|
+
--button-outline-width: 1px;
|
|
459
477
|
--font-heading: var(--font-sans);
|
|
460
478
|
color-scheme: dark;
|
|
461
479
|
}
|
|
@@ -507,6 +525,7 @@
|
|
|
507
525
|
--border: oklch(0.3956915 0.0031178 164.9356);
|
|
508
526
|
--input: oklch(0.6543689 0.0037291 145.5328);
|
|
509
527
|
--ring: oklch(0.8299788 0.0546884 280.5235);
|
|
528
|
+
--button-outline: var(--foreground);
|
|
510
529
|
--sidebar: oklch(0.1749487 0.003804 164.5613);
|
|
511
530
|
--sidebar-foreground: oklch(0.9604175 0.0214022 46.9889);
|
|
512
531
|
--sidebar-accent: oklch(0.2661671 0.0034366 164.8011);
|
|
@@ -535,6 +554,7 @@
|
|
|
535
554
|
--radius: 0.75rem;
|
|
536
555
|
--radius-button: 1.8125rem;
|
|
537
556
|
--radius-step: 2px;
|
|
557
|
+
--button-outline-width: 2px;
|
|
538
558
|
--font-heading: "Neo Sans", var(--font-sans);
|
|
539
559
|
color-scheme: dark;
|
|
540
560
|
}
|
|
@@ -586,6 +606,7 @@
|
|
|
586
606
|
--border: oklch(0.3956915 0.0031178 164.9356);
|
|
587
607
|
--input: oklch(0.6543689 0.0037291 145.5328);
|
|
588
608
|
--ring: oklch(0.8299788 0.0546884 280.5235);
|
|
609
|
+
--button-outline: var(--foreground);
|
|
589
610
|
--sidebar: oklch(0.1749487 0.003804 164.5613);
|
|
590
611
|
--sidebar-foreground: oklch(0.9822955 0.0142785 213.0969);
|
|
591
612
|
--sidebar-accent: oklch(0.2661671 0.0034366 164.8011);
|
|
@@ -614,6 +635,7 @@
|
|
|
614
635
|
--radius: 0.75rem;
|
|
615
636
|
--radius-button: 1.8125rem;
|
|
616
637
|
--radius-step: 2px;
|
|
638
|
+
--button-outline-width: 2px;
|
|
617
639
|
--font-heading: "Neo Sans", var(--font-sans);
|
|
618
640
|
color-scheme: dark;
|
|
619
641
|
}
|
|
@@ -665,6 +687,7 @@
|
|
|
665
687
|
--border: oklch(0.3956915 0.0031178 164.9356);
|
|
666
688
|
--input: oklch(0.6543689 0.0037291 145.5328);
|
|
667
689
|
--ring: oklch(0.8299788 0.0546884 280.5235);
|
|
690
|
+
--button-outline: var(--foreground);
|
|
668
691
|
--sidebar: oklch(0.1749487 0.003804 164.5613);
|
|
669
692
|
--sidebar-foreground: oklch(0.9790218 0.0292767 188.8731);
|
|
670
693
|
--sidebar-accent: oklch(0.2661671 0.0034366 164.8011);
|
|
@@ -693,6 +716,7 @@
|
|
|
693
716
|
--radius: 0.95rem;
|
|
694
717
|
--radius-button: 0.95rem;
|
|
695
718
|
--radius-step: 2px;
|
|
719
|
+
--button-outline-width: 2px;
|
|
696
720
|
--font-heading: var(--font-sans);
|
|
697
721
|
color-scheme: dark;
|
|
698
722
|
}
|
|
@@ -744,6 +768,7 @@
|
|
|
744
768
|
--border: oklch(0.3956915 0.0031178 164.9356);
|
|
745
769
|
--input: oklch(0.6543689 0.0037291 145.5328);
|
|
746
770
|
--ring: oklch(0.8299788 0.0546884 280.5235);
|
|
771
|
+
--button-outline: var(--foreground);
|
|
747
772
|
--sidebar: oklch(0.2029294 0.0334602 267.7195);
|
|
748
773
|
--sidebar-foreground: oklch(0.9592915 0.0326656 74.8018);
|
|
749
774
|
--sidebar-accent: oklch(0.2717674 0.038702 268.9648);
|
|
@@ -772,6 +797,7 @@
|
|
|
772
797
|
--radius: 0.5rem;
|
|
773
798
|
--radius-button: 0.5rem;
|
|
774
799
|
--radius-step: 2px;
|
|
800
|
+
--button-outline-width: 2px;
|
|
775
801
|
--font-heading: var(--font-sans);
|
|
776
802
|
color-scheme: dark;
|
|
777
803
|
}
|
|
@@ -823,6 +849,7 @@
|
|
|
823
849
|
--border: oklch(0.3956915 0.0031178 164.9356);
|
|
824
850
|
--input: oklch(0.6543689 0.0037291 145.5328);
|
|
825
851
|
--ring: oklch(0.8299788 0.0546884 280.5235);
|
|
852
|
+
--button-outline: var(--foreground);
|
|
826
853
|
--sidebar: oklch(0.1749487 0.003804 164.5613);
|
|
827
854
|
--sidebar-foreground: oklch(0.9604175 0.0214022 46.9889);
|
|
828
855
|
--sidebar-accent: oklch(0.2661671 0.0034366 164.8011);
|
|
@@ -851,6 +878,7 @@
|
|
|
851
878
|
--radius: 0.75rem;
|
|
852
879
|
--radius-button: 1.8125rem;
|
|
853
880
|
--radius-step: 2px;
|
|
881
|
+
--button-outline-width: 2px;
|
|
854
882
|
--font-heading: "Neo Sans", var(--font-sans);
|
|
855
883
|
color-scheme: dark;
|
|
856
884
|
}
|
|
@@ -902,6 +930,7 @@
|
|
|
902
930
|
--border: oklch(0.3956915 0.0031178 164.9356);
|
|
903
931
|
--input: oklch(0.6543689 0.0037291 145.5328);
|
|
904
932
|
--ring: oklch(0.8299788 0.0546884 280.5235);
|
|
933
|
+
--button-outline: var(--foreground);
|
|
905
934
|
--sidebar: oklch(0.1842633 0.0454734 244.0362);
|
|
906
935
|
--sidebar-foreground: oklch(0.9801435 0.0172884 210.1893);
|
|
907
936
|
--sidebar-accent: oklch(0.2250318 0.0601105 247.6754);
|
|
@@ -930,6 +959,7 @@
|
|
|
930
959
|
--radius: 0.75rem;
|
|
931
960
|
--radius-button: 1.8125rem;
|
|
932
961
|
--radius-step: 2px;
|
|
962
|
+
--button-outline-width: 2px;
|
|
933
963
|
--font-heading: var(--font-sans);
|
|
934
964
|
color-scheme: dark;
|
|
935
965
|
}
|
|
@@ -981,6 +1011,7 @@
|
|
|
981
1011
|
--border: oklch(0.3956915 0.0031178 164.9356);
|
|
982
1012
|
--input: oklch(0.6543689 0.0037291 145.5328);
|
|
983
1013
|
--ring: oklch(0.8299788 0.0546884 280.5235);
|
|
1014
|
+
--button-outline: var(--foreground);
|
|
984
1015
|
--sidebar: oklch(0.176932 0.0026206 247.9754);
|
|
985
1016
|
--sidebar-foreground: oklch(0.9817745 0.0118616 223.5201);
|
|
986
1017
|
--sidebar-accent: oklch(0.2675764 0.0014668 197.0689);
|
|
@@ -1009,6 +1040,7 @@
|
|
|
1009
1040
|
--radius: 0.375rem;
|
|
1010
1041
|
--radius-button: 0.375rem;
|
|
1011
1042
|
--radius-step: 2px;
|
|
1043
|
+
--button-outline-width: 2px;
|
|
1012
1044
|
--font-heading: var(--font-sans);
|
|
1013
1045
|
color-scheme: dark;
|
|
1014
1046
|
}
|