@gridui/button 1.0.0 → 2.1.1
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 +30 -10
- package/dist/index.js +20 -5
- package/dist/index.js.map +2 -2
- package/dist/style.d.ts +7 -4
- package/dist/styles.css +11 -2
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -29,16 +29,21 @@ Use a real button when the action needs native disabled behavior.
|
|
|
29
29
|
|
|
30
30
|
## Appearance and icons
|
|
31
31
|
|
|
32
|
-
The variants are `primary`, `secondary`, `quiet`, and `
|
|
32
|
+
The variants are `primary`, `secondary`, `quiet`, `highlight`, `text`, and `underlined`. Sizes are
|
|
33
33
|
`standard` (2.75rem minimum height) and `small` (2.25rem). The existing `standard`,
|
|
34
|
-
`icon`, `entry`, and `rail` layouts
|
|
34
|
+
`icon`, `entry`, and `rail` layouts, plus the full-region `cell` layout, are
|
|
35
|
+
available for non-text/non-underlined variants.
|
|
35
36
|
Small icon controls retain a 2.75rem touch target on coarse pointers.
|
|
36
37
|
|
|
37
|
-
`text`
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
`text` and `underlined` accept only `layout="standard"`, which may be omitted.
|
|
39
|
+
Both use a transparent surface, the surrounding foreground, and no inline padding.
|
|
40
|
+
`text` has no underline, including on hover. `underlined` has a fixed bottom
|
|
41
|
+
border that does not appear or move on hover. Give both a visible label in
|
|
42
|
+
`children`; use another variant's icon layout for icon-only actions. All variants
|
|
43
|
+
retain the theme's native keyboard focus treatment.
|
|
44
|
+
|
|
45
|
+
Consumers that previously used `text` for a permanent underline must switch to
|
|
46
|
+
`underlined`. Keep `text` for unlined actions and navigation links.
|
|
42
47
|
There are no application colors or implicit icon transforms.
|
|
43
48
|
|
|
44
49
|
`startIcon` and `endIcon` accept decorative React nodes before and after the
|
|
@@ -53,6 +58,20 @@ omit the border. Secondary and quiet surfaces use `surface-hover` while enabled.
|
|
|
53
58
|
Disabled buttons keep their base fill and reduced opacity. Standard and small
|
|
54
59
|
sizes scale with the consumer's root font size.
|
|
55
60
|
|
|
61
|
+
`highlight` uses the neutral `surface` fill and normal foreground. Use it for a
|
|
62
|
+
persistent selected action, with `quiet` for its unselected peers. Choose the
|
|
63
|
+
variant from application state and supply the matching native semantics, such as
|
|
64
|
+
`aria-pressed` for a toggle or `aria-current="page"` for navigation. The variant
|
|
65
|
+
does not create selection behavior, and ARIA attributes do not choose a variant.
|
|
66
|
+
|
|
67
|
+
Appearance and layout are independent. `standard` and `icon` retain standalone
|
|
68
|
+
control geometry. `entry` fills the available width with entry spacing; it does
|
|
69
|
+
not replace the chosen variant's background. `cell` fills both the width and
|
|
70
|
+
height of its containing region, uses square corners and no button border, and
|
|
71
|
+
keeps content padding inside the hit area. Grid or another structural parent
|
|
72
|
+
owns any surrounding seams. Put a cell button in `GridItem padding={0}` to avoid
|
|
73
|
+
an inset selected surface. See the [composition recipe](../../docs/usage/composition.md#full-region-actions).
|
|
74
|
+
|
|
56
75
|
`buttonClass(variants, className?)` exposes the same appearance and text-layout
|
|
57
76
|
constraints for caller-owned native elements. `startIcon` and `endIcon` are
|
|
58
77
|
component props, not styling variants. It uses `cn` for consumer class overrides.
|
|
@@ -75,6 +94,7 @@ the browser has had time to consume it. Callers own the Blob contents and name.
|
|
|
75
94
|
|
|
76
95
|
Package unit tests cover native action/link semantics, decorative icon isolation,
|
|
77
96
|
busy-state scheduling and failure cleanup. Type fixtures compile with the package
|
|
78
|
-
and reject text/icon-layout combinations, missing link destinations, and icon
|
|
79
|
-
nodes passed as style variants. Storybook includes
|
|
80
|
-
|
|
97
|
+
and reject text and underlined/icon-layout combinations, missing link destinations, and icon
|
|
98
|
+
nodes passed as style variants. Storybook includes standalone, icon, full-cell,
|
|
99
|
+
and disabled highlight states, text and underlined actions and links, decorative
|
|
100
|
+
icon slots, long labels, loading, and the existing variants.
|
package/dist/index.js
CHANGED
|
@@ -72,13 +72,25 @@ var buttonQuietStyles = cva(cn(
|
|
|
72
72
|
"text-foreground bg-transparent",
|
|
73
73
|
"[&:hover:not(:disabled)]:bg-surface-hover"
|
|
74
74
|
));
|
|
75
|
+
var buttonHighlightStyles = cva(cn(
|
|
76
|
+
"gridui-button-highlight",
|
|
77
|
+
"text-foreground bg-surface"
|
|
78
|
+
));
|
|
75
79
|
var buttonTextStyles = cva(cn(
|
|
76
80
|
"gridui-button-text",
|
|
81
|
+
"text-foreground bg-transparent border-0 rounded-none"
|
|
82
|
+
));
|
|
83
|
+
var buttonUnderlinedStyles = cva(cn(
|
|
84
|
+
"gridui-button-underlined",
|
|
77
85
|
"text-foreground bg-transparent border-0 border-b border-foreground rounded-none"
|
|
78
86
|
));
|
|
79
87
|
var buttonEntryStyles = cva(cn(
|
|
80
88
|
"gridui-button-entry",
|
|
81
|
-
"justify-between w-full py-gridui-16 px-gridui-24
|
|
89
|
+
"justify-between w-full py-gridui-16 px-gridui-24"
|
|
90
|
+
));
|
|
91
|
+
var buttonCellStyles = cva(cn(
|
|
92
|
+
"gridui-button-cell",
|
|
93
|
+
"w-full h-full justify-start rounded-none border-0 py-gridui-16 px-gridui-24 text-left"
|
|
82
94
|
));
|
|
83
95
|
var buttonRailStyles = cva(cn(
|
|
84
96
|
"gridui-button-rail",
|
|
@@ -97,7 +109,9 @@ var buttonVariants = cva(buttonStyles(), {
|
|
|
97
109
|
primary: buttonPrimaryStyles(),
|
|
98
110
|
secondary: buttonSecondaryStyles(),
|
|
99
111
|
quiet: buttonQuietStyles(),
|
|
100
|
-
|
|
112
|
+
highlight: buttonHighlightStyles(),
|
|
113
|
+
text: buttonTextStyles(),
|
|
114
|
+
underlined: buttonUnderlinedStyles()
|
|
101
115
|
},
|
|
102
116
|
size: {
|
|
103
117
|
small: buttonSmallStyles(),
|
|
@@ -107,6 +121,7 @@ var buttonVariants = cva(buttonStyles(), {
|
|
|
107
121
|
standard: "",
|
|
108
122
|
icon: buttonIconStyles(),
|
|
109
123
|
entry: buttonEntryStyles(),
|
|
124
|
+
cell: buttonCellStyles(),
|
|
110
125
|
rail: buttonRailStyles()
|
|
111
126
|
}
|
|
112
127
|
},
|
|
@@ -120,7 +135,7 @@ var buttonClass = (variants = {}, className) => {
|
|
|
120
135
|
variant: variants.variant,
|
|
121
136
|
size: variants.size,
|
|
122
137
|
layout: variants.layout
|
|
123
|
-
}), variants.variant === "text" && "px-0", className);
|
|
138
|
+
}), (variants.variant === "text" || variants.variant === "underlined") && "px-0", className);
|
|
124
139
|
};
|
|
125
140
|
|
|
126
141
|
// src/button.tsx
|
|
@@ -139,7 +154,7 @@ var Button = (props) => {
|
|
|
139
154
|
endIcon,
|
|
140
155
|
...restProps
|
|
141
156
|
} = props;
|
|
142
|
-
const variants = variant === "text" ? {
|
|
157
|
+
const variants = variant === "text" || variant === "underlined" ? {
|
|
143
158
|
variant,
|
|
144
159
|
size,
|
|
145
160
|
layout: "standard"
|
|
@@ -191,7 +206,7 @@ var ButtonLink = (props) => {
|
|
|
191
206
|
endIcon,
|
|
192
207
|
...restProps
|
|
193
208
|
} = props;
|
|
194
|
-
const variants = variant === "text" ? {
|
|
209
|
+
const variants = variant === "text" || variant === "underlined" ? {
|
|
195
210
|
variant,
|
|
196
211
|
size,
|
|
197
212
|
layout: "standard"
|
package/dist/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/async-action.ts", "../src/style.ts", "../src/button.tsx", "../src/download.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @author WMXPY\n * @package Button\n * @namespace Root\n * @description Async Action\n */\n\nimport { useRef, useState } from \"react\";\n\ntype Action = () => void | Promise<void>;\n\nexport const performAsyncAction = async ({ action, onStart, onPendingChange }: {\n readonly action: Action;\n readonly onStart?: Action;\n readonly onPendingChange: (pending: boolean) => void;\n}): Promise<void> => {\n onPendingChange(true);\n try {\n await onStart?.();\n await new Promise<void>((resolve) => {\n setTimeout(resolve, 0);\n });\n await action();\n } finally {\n onPendingChange(false);\n }\n};\n\nexport const useAsyncAction = ({ action, onStart, disabled = false }: {\n readonly action: Action;\n readonly onStart?: Action;\n readonly disabled?: boolean;\n}) => {\n const [\n pending,\n setPending,\n ] = useState(false);\n const active = useRef(false);\n return {\n pending,\n async run(): Promise<void> {\n if (disabled || active.current) {\n return;\n }\n active.current = true;\n try {\n await performAsyncAction({\n action,\n ...(onStart ? { onStart } : {}),\n onPendingChange: setPending,\n });\n } finally {\n active.current = false;\n }\n },\n };\n};\n", "/**\n * @author WMXPY\n * @package Button\n * @namespace Root\n * @description Style\n */\n\nimport { cn } from \"@gridui/style-utils\";\nimport type { VariantProps } from \"class-variance-authority\";\nimport { cva } from \"class-variance-authority\";\n\nexport const buttonStyles = cva(cn(\n \"gridui-button\",\n \"inline-flex w-fit max-w-full min-w-0 items-center justify-center gap-gridui-8 border border-solid border-transparent rounded-control type-ui text-center no-underline wrap-anywhere cursor-pointer transition-colors duration-(--gridui-motion-duration-quick) ease-(--gridui-motion-ease-out)\",\n \"[&_svg]:w-gridui-16 [&_svg]:h-gridui-16 [&_svg]:shrink-0 [&_svg]:pointer-events-none\",\n \"disabled:opacity-50 disabled:cursor-not-allowed\",\n \"[&:hover:not(:disabled)]:border-foreground\",\n \"[&:active:not(:disabled)]:opacity-[0.8]\",\n \"motion-reduce:transition-none\",\n));\n\nexport const buttonStandardStyles = cva(cn(\n \"gridui-button-standard\",\n \"min-h-11 py-gridui-8 px-gridui-16\",\n));\n\nexport const buttonSmallStyles = cva(cn(\n \"gridui-button-small\",\n \"min-h-9 py-gridui-4 px-gridui-8\",\n));\n\nexport const buttonPrimaryStyles = cva(cn(\n \"gridui-button-primary\",\n \"text-accent-foreground bg-accent-background border-accent-background\",\n));\n\nexport const buttonSecondaryStyles = cva(cn(\n \"gridui-button-secondary\",\n \"text-foreground bg-transparent border-border\",\n \"[&:hover:not(:disabled)]:bg-surface-hover\",\n));\n\nexport const buttonQuietStyles = cva(cn(\n \"gridui-button-quiet\",\n \"text-foreground bg-transparent\",\n \"[&:hover:not(:disabled)]:bg-surface-hover\",\n));\n\nexport const buttonTextStyles = cva(cn(\n \"gridui-button-text\",\n \"text-foreground bg-transparent border-0 border-b border-foreground rounded-none\",\n));\n\nexport const buttonEntryStyles = cva(cn(\n \"gridui-button-entry\",\n \"justify-between w-full py-gridui-16 px-gridui-24
|
|
5
|
-
"mappings": ";AAOA,SAAS,QAAQ,gBAAgB;AAI1B,IAAM,qBAAqB,OAAO,EAAE,QAAQ,SAAS,gBAAgB,MAIvD;AACjB,kBAAgB,IAAI;AACpB,MAAI;AACA,UAAM,UAAU;AAChB,UAAM,IAAI,QAAc,CAAC,YAAY;AACjC,iBAAW,SAAS,CAAC;AAAA,IACzB,CAAC;AACD,UAAM,OAAO;AAAA,EACjB,UAAE;AACE,oBAAgB,KAAK;AAAA,EACzB;AACJ;AAEO,IAAM,iBAAiB,CAAC,EAAE,QAAQ,SAAS,WAAW,MAAM,MAI7D;AACF,QAAM;AAAA,IACF;AAAA,IACA;AAAA,EACJ,IAAI,SAAS,KAAK;AAClB,QAAM,SAAS,OAAO,KAAK;AAC3B,SAAO;AAAA,IACH;AAAA,IACA,MAAM,MAAqB;AACvB,UAAI,YAAY,OAAO,SAAS;AAC5B;AAAA,MACJ;AACA,aAAO,UAAU;AACjB,UAAI;AACA,cAAM,mBAAmB;AAAA,UACrB;AAAA,UACA,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;AAAA,UAC7B,iBAAiB;AAAA,QACrB,CAAC;AAAA,MACL,UAAE;AACE,eAAO,UAAU;AAAA,MACrB;AAAA,IACJ;AAAA,EACJ;AACJ;;;ACjDA,SAAS,UAAU;AAEnB,SAAS,WAAW;AAEb,IAAM,eAAe,IAAI;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ,CAAC;AAEM,IAAM,uBAAuB,IAAI;AAAA,EACpC;AAAA,EACA;AACJ,CAAC;AAEM,IAAM,oBAAoB,IAAI;AAAA,EACjC;AAAA,EACA;AACJ,CAAC;AAEM,IAAM,sBAAsB,IAAI;AAAA,EACnC;AAAA,EACA;AACJ,CAAC;AAEM,IAAM,wBAAwB,IAAI;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AACJ,CAAC;AAEM,IAAM,oBAAoB,IAAI;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AACJ,CAAC;AAEM,IAAM,mBAAmB,IAAI;AAAA,EAChC;AAAA,EACA;AACJ,CAAC;AAEM,IAAM,oBAAoB,IAAI;AAAA,EACjC;AAAA,EACA;AACJ,CAAC;AAEM,IAAM,mBAAmB,IAAI;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AACJ,CAAC;AAEM,IAAM,mBAAmB,IAAI;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ,CAAC;AAEM,IAAM,iBAAiB,IAAI,aAAa,GAAG;AAAA,EAC9C,UAAU;AAAA,IACN,SAAS;AAAA,MACL,SAAS,oBAAoB;AAAA,MAC7B,WAAW,sBAAsB;AAAA,MACjC,OAAO,kBAAkB;AAAA,MACzB,MAAM,iBAAiB;AAAA,
|
|
4
|
+
"sourcesContent": ["/**\n * @author WMXPY\n * @package Button\n * @namespace Root\n * @description Async Action\n */\n\nimport { useRef, useState } from \"react\";\n\ntype Action = () => void | Promise<void>;\n\nexport const performAsyncAction = async ({ action, onStart, onPendingChange }: {\n readonly action: Action;\n readonly onStart?: Action;\n readonly onPendingChange: (pending: boolean) => void;\n}): Promise<void> => {\n onPendingChange(true);\n try {\n await onStart?.();\n await new Promise<void>((resolve) => {\n setTimeout(resolve, 0);\n });\n await action();\n } finally {\n onPendingChange(false);\n }\n};\n\nexport const useAsyncAction = ({ action, onStart, disabled = false }: {\n readonly action: Action;\n readonly onStart?: Action;\n readonly disabled?: boolean;\n}) => {\n const [\n pending,\n setPending,\n ] = useState(false);\n const active = useRef(false);\n return {\n pending,\n async run(): Promise<void> {\n if (disabled || active.current) {\n return;\n }\n active.current = true;\n try {\n await performAsyncAction({\n action,\n ...(onStart ? { onStart } : {}),\n onPendingChange: setPending,\n });\n } finally {\n active.current = false;\n }\n },\n };\n};\n", "/**\n * @author WMXPY\n * @package Button\n * @namespace Root\n * @description Style\n */\n\nimport { cn } from \"@gridui/style-utils\";\nimport type { VariantProps } from \"class-variance-authority\";\nimport { cva } from \"class-variance-authority\";\n\nexport const buttonStyles = cva(cn(\n \"gridui-button\",\n \"inline-flex w-fit max-w-full min-w-0 items-center justify-center gap-gridui-8 border border-solid border-transparent rounded-control type-ui text-center no-underline wrap-anywhere cursor-pointer transition-colors duration-(--gridui-motion-duration-quick) ease-(--gridui-motion-ease-out)\",\n \"[&_svg]:w-gridui-16 [&_svg]:h-gridui-16 [&_svg]:shrink-0 [&_svg]:pointer-events-none\",\n \"disabled:opacity-50 disabled:cursor-not-allowed\",\n \"[&:hover:not(:disabled)]:border-foreground\",\n \"[&:active:not(:disabled)]:opacity-[0.8]\",\n \"motion-reduce:transition-none\",\n));\n\nexport const buttonStandardStyles = cva(cn(\n \"gridui-button-standard\",\n \"min-h-11 py-gridui-8 px-gridui-16\",\n));\n\nexport const buttonSmallStyles = cva(cn(\n \"gridui-button-small\",\n \"min-h-9 py-gridui-4 px-gridui-8\",\n));\n\nexport const buttonPrimaryStyles = cva(cn(\n \"gridui-button-primary\",\n \"text-accent-foreground bg-accent-background border-accent-background\",\n));\n\nexport const buttonSecondaryStyles = cva(cn(\n \"gridui-button-secondary\",\n \"text-foreground bg-transparent border-border\",\n \"[&:hover:not(:disabled)]:bg-surface-hover\",\n));\n\nexport const buttonQuietStyles = cva(cn(\n \"gridui-button-quiet\",\n \"text-foreground bg-transparent\",\n \"[&:hover:not(:disabled)]:bg-surface-hover\",\n));\n\nexport const buttonHighlightStyles = cva(cn(\n \"gridui-button-highlight\",\n \"text-foreground bg-surface\",\n));\n\nexport const buttonTextStyles = cva(cn(\n \"gridui-button-text\",\n \"text-foreground bg-transparent border-0 rounded-none\",\n));\n\nexport const buttonUnderlinedStyles = cva(cn(\n \"gridui-button-underlined\",\n \"text-foreground bg-transparent border-0 border-b border-foreground rounded-none\",\n));\n\nexport const buttonEntryStyles = cva(cn(\n \"gridui-button-entry\",\n \"justify-between w-full py-gridui-16 px-gridui-24\",\n));\n\nexport const buttonCellStyles = cva(cn(\n \"gridui-button-cell\",\n \"w-full h-full justify-start rounded-none border-0 py-gridui-16 px-gridui-24 text-left\",\n));\n\nexport const buttonRailStyles = cva(cn(\n \"gridui-button-rail\",\n \"w-full min-w-gridui-24 flex-col py-gridui-8 px-0\",\n \"[&_>_span]:[writing-mode:vertical-rl] [&_>_span]:whitespace-nowrap\",\n));\n\nexport const buttonIconStyles = cva(cn(\n \"gridui-button-icon\",\n \"w-11 h-11 shrink-0 p-0\",\n \"[&.gridui-button-small]:w-9 [&.gridui-button-small]:h-9\",\n \"pointer-coarse:[&.gridui-button-small]:w-11 pointer-coarse:[&.gridui-button-small]:h-11\",\n));\n\nexport const buttonVariants = cva(buttonStyles(), {\n variants: {\n variant: {\n primary: buttonPrimaryStyles(),\n secondary: buttonSecondaryStyles(),\n quiet: buttonQuietStyles(),\n highlight: buttonHighlightStyles(),\n text: buttonTextStyles(),\n underlined: buttonUnderlinedStyles(),\n },\n size: {\n small: buttonSmallStyles(),\n standard: buttonStandardStyles(),\n },\n layout: {\n standard: \"\",\n icon: buttonIconStyles(),\n entry: buttonEntryStyles(),\n cell: buttonCellStyles(),\n rail: buttonRailStyles(),\n },\n },\n defaultVariants: {\n variant: \"primary\",\n size: \"standard\",\n },\n});\n\ntype ButtonStyleVariants = VariantProps<typeof buttonVariants>;\n\nexport type ButtonVariants = Omit<ButtonStyleVariants, \"variant\" | \"layout\"> & (\n | {\n readonly variant: \"text\" | \"underlined\";\n readonly layout?: \"standard\" | null | undefined;\n }\n | {\n readonly variant?: Exclude<ButtonStyleVariants[\"variant\"], \"text\" | \"underlined\">;\n readonly layout?: ButtonStyleVariants[\"layout\"];\n }\n);\n\nexport const buttonClass = (variants: ButtonVariants = {}, className?: string): string => {\n return cn(buttonVariants({\n variant: variants.variant,\n size: variants.size,\n layout: variants.layout,\n }), (variants.variant === \"text\" || variants.variant === \"underlined\") && \"px-0\", className);\n};\n", "/**\n * @author WMXPY\n * @package Button\n * @namespace Root\n * @description Button\n */\n\nimport type { ButtonVariants } from \"./style\";\nimport { buttonClass } from \"./style\";\nimport type { ComponentPropsWithRef, FC, ReactNode } from \"react\";\n\nexport type ButtonProps = ComponentPropsWithRef<\"button\"> & ButtonVariants & {\n readonly loading?: boolean;\n readonly startIcon?: ReactNode;\n readonly endIcon?: ReactNode;\n};\n\nexport const Button: FC<ButtonProps> = (props: ButtonProps) => {\n const {\n variant,\n size,\n layout,\n loading = false,\n disabled,\n type = \"button\",\n className,\n children,\n startIcon,\n endIcon,\n ...restProps\n } = props;\n const variants: ButtonVariants = (variant === \"text\" || variant === \"underlined\") ? {\n variant,\n size,\n layout: \"standard\",\n } : {\n variant,\n size,\n layout,\n };\n return (<button\n {...restProps}\n type={type}\n disabled={disabled || loading}\n aria-busy={loading || restProps[\"aria-busy\"]}\n className={buttonClass(variants, className)}\n >\n {startIcon !== undefined && startIcon !== null && typeof startIcon !== \"boolean\" && (<span\n className=\"gridui-button-adornment inline-flex shrink-0 items-center pointer-events-none\"\n aria-hidden=\"true\"\n inert\n >\n {startIcon}\n </span>)}\n {children}\n {endIcon !== undefined && endIcon !== null && typeof endIcon !== \"boolean\" && (<span\n className=\"gridui-button-adornment inline-flex shrink-0 items-center pointer-events-none\"\n aria-hidden=\"true\"\n inert\n >\n {endIcon}\n </span>)}\n </button>);\n};\n\nexport type ButtonLinkProps = ComponentPropsWithRef<\"a\"> & ButtonVariants & {\n readonly href: string;\n readonly startIcon?: ReactNode;\n readonly endIcon?: ReactNode;\n};\n\nexport const ButtonLink: FC<ButtonLinkProps> = (props: ButtonLinkProps) => {\n const {\n variant = \"secondary\",\n size,\n layout,\n className,\n children,\n startIcon,\n endIcon,\n ...restProps\n } = props;\n const variants: ButtonVariants = (variant === \"text\" || variant === \"underlined\") ? {\n variant,\n size,\n layout: \"standard\",\n } : {\n variant,\n size,\n layout,\n };\n return (<a\n {...restProps}\n className={buttonClass(variants, className)}\n >\n {startIcon !== undefined && startIcon !== null && typeof startIcon !== \"boolean\" && (<span\n className=\"gridui-button-adornment inline-flex shrink-0 items-center pointer-events-none\"\n aria-hidden=\"true\"\n inert\n >\n {startIcon}\n </span>)}\n {children}\n {endIcon !== undefined && endIcon !== null && typeof endIcon !== \"boolean\" && (<span\n className=\"gridui-button-adornment inline-flex shrink-0 items-center pointer-events-none\"\n aria-hidden=\"true\"\n inert\n >\n {endIcon}\n </span>)}\n </a>);\n};\n", "/**\n * @author WMXPY\n * @package Button\n * @namespace Root\n * @description Download\n */\n\nexport const downloadBlob = (blob: Blob, filename: string): void => {\n const url = URL.createObjectURL(blob);\n const link = document.createElement(\"a\");\n link.href = url;\n link.download = filename;\n document.body.appendChild(link);\n link.click();\n link.remove();\n window.setTimeout(() => {\n URL.revokeObjectURL(url);\n }, 30000);\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/style.d.ts
CHANGED
|
@@ -11,21 +11,24 @@ export declare const buttonSmallStyles: (props?: import("class-variance-authorit
|
|
|
11
11
|
export declare const buttonPrimaryStyles: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
|
|
12
12
|
export declare const buttonSecondaryStyles: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
|
|
13
13
|
export declare const buttonQuietStyles: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
|
|
14
|
+
export declare const buttonHighlightStyles: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
|
|
14
15
|
export declare const buttonTextStyles: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
|
|
16
|
+
export declare const buttonUnderlinedStyles: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
|
|
15
17
|
export declare const buttonEntryStyles: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
|
|
18
|
+
export declare const buttonCellStyles: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
|
|
16
19
|
export declare const buttonRailStyles: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
|
|
17
20
|
export declare const buttonIconStyles: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
|
|
18
21
|
export declare const buttonVariants: (props?: ({
|
|
19
|
-
variant?: "primary" | "secondary" | "quiet" | "text" | null | undefined;
|
|
22
|
+
variant?: "primary" | "secondary" | "quiet" | "highlight" | "text" | "underlined" | null | undefined;
|
|
20
23
|
size?: "small" | "standard" | null | undefined;
|
|
21
|
-
layout?: "standard" | "icon" | "entry" | "rail" | null | undefined;
|
|
24
|
+
layout?: "standard" | "icon" | "entry" | "cell" | "rail" | null | undefined;
|
|
22
25
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
23
26
|
type ButtonStyleVariants = VariantProps<typeof buttonVariants>;
|
|
24
27
|
export type ButtonVariants = Omit<ButtonStyleVariants, "variant" | "layout"> & ({
|
|
25
|
-
readonly variant: "text";
|
|
28
|
+
readonly variant: "text" | "underlined";
|
|
26
29
|
readonly layout?: "standard" | null | undefined;
|
|
27
30
|
} | {
|
|
28
|
-
readonly variant?: Exclude<ButtonStyleVariants["variant"], "text">;
|
|
31
|
+
readonly variant?: Exclude<ButtonStyleVariants["variant"], "text" | "underlined">;
|
|
29
32
|
readonly layout?: ButtonStyleVariants["layout"];
|
|
30
33
|
});
|
|
31
34
|
export declare const buttonClass: (variants?: ButtonVariants, className?: string) => string;
|
package/dist/styles.css
CHANGED
|
@@ -18,6 +18,9 @@
|
|
|
18
18
|
.h-11 {
|
|
19
19
|
height: calc(var(--spacing) * 11);
|
|
20
20
|
}
|
|
21
|
+
.h-full {
|
|
22
|
+
height: 100%;
|
|
23
|
+
}
|
|
21
24
|
.min-h-9 {
|
|
22
25
|
min-height: calc(var(--spacing) * 9);
|
|
23
26
|
}
|
|
@@ -60,6 +63,9 @@
|
|
|
60
63
|
.justify-center {
|
|
61
64
|
justify-content: center;
|
|
62
65
|
}
|
|
66
|
+
.justify-start {
|
|
67
|
+
justify-content: flex-start;
|
|
68
|
+
}
|
|
63
69
|
.gap-gridui-8 {
|
|
64
70
|
gap: var(--gridui-space-8);
|
|
65
71
|
}
|
|
@@ -100,8 +106,8 @@
|
|
|
100
106
|
.bg-accent-background {
|
|
101
107
|
background-color: var(--gridui-accent-background);
|
|
102
108
|
}
|
|
103
|
-
.bg-
|
|
104
|
-
background-color: var(--gridui-
|
|
109
|
+
.bg-surface {
|
|
110
|
+
background-color: var(--gridui-surface);
|
|
105
111
|
}
|
|
106
112
|
.bg-transparent {
|
|
107
113
|
background-color: transparent;
|
|
@@ -133,6 +139,9 @@
|
|
|
133
139
|
.text-center {
|
|
134
140
|
text-align: center;
|
|
135
141
|
}
|
|
142
|
+
.text-left {
|
|
143
|
+
text-align: left;
|
|
144
|
+
}
|
|
136
145
|
.type-ui {
|
|
137
146
|
font: var(--gridui-type-ui);
|
|
138
147
|
letter-spacing: normal;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gridui/button",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "2.1.1",
|
|
4
4
|
"description": "GridUI React buttons and action helpers",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"type": "module",
|
|
@@ -27,20 +27,20 @@
|
|
|
27
27
|
"access": "public"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@gridui/style-utils": "^2.1.
|
|
31
|
-
"@gridui/theme": "^2.1.
|
|
30
|
+
"@gridui/style-utils": "^2.1.2",
|
|
31
|
+
"@gridui/theme": "^2.1.2",
|
|
32
32
|
"class-variance-authority": "0.7.1"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@gridui-internal/configuration": "0.0.0",
|
|
36
36
|
"@jest/globals": "30.5.2",
|
|
37
|
-
"@storybook/react-vite": "10.6.
|
|
37
|
+
"@storybook/react-vite": "10.6.5",
|
|
38
38
|
"@types/jest": "30.0.0",
|
|
39
39
|
"@types/node": "26.6.5",
|
|
40
40
|
"@types/react": "19.3.0",
|
|
41
41
|
"@types/react-dom": "19.3.0",
|
|
42
42
|
"jest": "30.5.2",
|
|
43
|
-
"lucide-react": "1.
|
|
43
|
+
"lucide-react": "1.62.0",
|
|
44
44
|
"react": "19.3.1",
|
|
45
45
|
"react-dom": "19.3.1",
|
|
46
46
|
"typescript": "6.0.3"
|