@gridui/button 0.0.0-stage → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +79 -2
- package/dist/async-action.d.ts +21 -0
- package/dist/button.d.ts +20 -0
- package/dist/download.d.ts +7 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +253 -0
- package/dist/index.js.map +7 -0
- package/dist/style.d.ts +32 -0
- package/dist/styles.css +239 -0
- package/package.json +55 -3
package/README.md
CHANGED
|
@@ -1,3 +1,80 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Button
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
`@gridui/button` owns native buttons, button-styled links, shared button classes,
|
|
4
|
+
async action scheduling, and browser download lifecycle. It has no domain,
|
|
5
|
+
route, locale, or Layout dependency. Load `@gridui/button/styles.css` after
|
|
6
|
+
the theme styles.
|
|
7
|
+
|
|
8
|
+
```tsx
|
|
9
|
+
import { Button, ButtonLink } from "@gridui/button";
|
|
10
|
+
import "@gridui/button/styles.css";
|
|
11
|
+
|
|
12
|
+
<Button type="submit" loading={saving}>Save changes</Button>;
|
|
13
|
+
<ButtonLink href="/guide" variant="text" endIcon={<ArrowUpRight />}>
|
|
14
|
+
Read the guide
|
|
15
|
+
</ButtonLink>;
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Native behavior
|
|
19
|
+
|
|
20
|
+
`Button` forwards native button props and refs. It defaults to `type="button"`;
|
|
21
|
+
use `type="submit"` for a form action. `loading` disables the native button and
|
|
22
|
+
exposes `aria-busy` without replacing the visible action name. Native `disabled`
|
|
23
|
+
remains available independently of loading.
|
|
24
|
+
|
|
25
|
+
`ButtonLink` forwards native anchor props and refs and requires `href`. It
|
|
26
|
+
defaults to the secondary variant and retains navigation, modified-click,
|
|
27
|
+
download, target, and rel behavior. It has no loading or disabled button API.
|
|
28
|
+
Use a real button when the action needs native disabled behavior.
|
|
29
|
+
|
|
30
|
+
## Appearance and icons
|
|
31
|
+
|
|
32
|
+
The variants are `primary`, `secondary`, `quiet`, and `text`. Sizes are
|
|
33
|
+
`standard` (2.75rem minimum height) and `small` (2.25rem). The existing `standard`,
|
|
34
|
+
`icon`, `entry`, and `rail` layouts remain available for non-text variants.
|
|
35
|
+
Small icon controls retain a 2.75rem touch target on coarse pointers.
|
|
36
|
+
|
|
37
|
+
`text` accepts only `layout="standard"`, which may be omitted. Give it a visible
|
|
38
|
+
label in `children`; use a non-text icon layout for an icon-only action. Its
|
|
39
|
+
transparent surface has a fixed bottom underline and no inline padding. The
|
|
40
|
+
underline does not appear or move on hover. Text uses the surrounding region's
|
|
41
|
+
foreground and all variants retain the theme's native keyboard focus treatment.
|
|
42
|
+
There are no application colors or implicit icon transforms.
|
|
43
|
+
|
|
44
|
+
`startIcon` and `endIcon` accept decorative React nodes before and after the
|
|
45
|
+
existing `children`. Their wrappers are hidden from assistive technology and
|
|
46
|
+
inert, so the visible label remains the accessible name. Do not put interactive
|
|
47
|
+
content in these slots. Existing icons passed directly in `children` keep their
|
|
48
|
+
original rendering and accessibility responsibilities.
|
|
49
|
+
|
|
50
|
+
Primary buttons use `accent-background` and `accent-foreground`. Secondary
|
|
51
|
+
buttons use a transparent fill, foreground text, and a border; quiet buttons
|
|
52
|
+
omit the border. Secondary and quiet surfaces use `surface-hover` while enabled.
|
|
53
|
+
Disabled buttons keep their base fill and reduced opacity. Standard and small
|
|
54
|
+
sizes scale with the consumer's root font size.
|
|
55
|
+
|
|
56
|
+
`buttonClass(variants, className?)` exposes the same appearance and text-layout
|
|
57
|
+
constraints for caller-owned native elements. `startIcon` and `endIcon` are
|
|
58
|
+
component props, not styling variants. It uses `cn` for consumer class overrides.
|
|
59
|
+
Callers using the class helper own native semantics, icon accessibility, and
|
|
60
|
+
loading behavior.
|
|
61
|
+
|
|
62
|
+
## Action helpers
|
|
63
|
+
|
|
64
|
+
`useAsyncAction({ action, onStart?, disabled? })` returns `pending` and `run`.
|
|
65
|
+
It publishes pending state and optional start feedback before yielding to the
|
|
66
|
+
browser event loop, runs the action, and releases pending state on success or
|
|
67
|
+
failure. Disabled actions and repeated activation while pending are ignored.
|
|
68
|
+
Callers own business error handling and generated bytes.
|
|
69
|
+
|
|
70
|
+
`downloadBlob(blob, filename)` creates the download anchor and object URL,
|
|
71
|
+
activates the native download, removes the anchor, and releases the URL after
|
|
72
|
+
the browser has had time to consume it. Callers own the Blob contents and name.
|
|
73
|
+
|
|
74
|
+
## Verification
|
|
75
|
+
|
|
76
|
+
Package unit tests cover native action/link semantics, decorative icon isolation,
|
|
77
|
+
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 text actions and links,
|
|
80
|
+
decorative icon slots, long labels, loading, and the existing variants.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author WMXPY
|
|
3
|
+
* @package Button
|
|
4
|
+
* @namespace Root
|
|
5
|
+
* @description Async Action
|
|
6
|
+
*/
|
|
7
|
+
type Action = () => void | Promise<void>;
|
|
8
|
+
export declare const performAsyncAction: ({ action, onStart, onPendingChange }: {
|
|
9
|
+
readonly action: Action;
|
|
10
|
+
readonly onStart?: Action;
|
|
11
|
+
readonly onPendingChange: (pending: boolean) => void;
|
|
12
|
+
}) => Promise<void>;
|
|
13
|
+
export declare const useAsyncAction: ({ action, onStart, disabled }: {
|
|
14
|
+
readonly action: Action;
|
|
15
|
+
readonly onStart?: Action;
|
|
16
|
+
readonly disabled?: boolean;
|
|
17
|
+
}) => {
|
|
18
|
+
pending: boolean;
|
|
19
|
+
run(): Promise<void>;
|
|
20
|
+
};
|
|
21
|
+
export {};
|
package/dist/button.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author WMXPY
|
|
3
|
+
* @package Button
|
|
4
|
+
* @namespace Root
|
|
5
|
+
* @description Button
|
|
6
|
+
*/
|
|
7
|
+
import type { ButtonVariants } from "./style";
|
|
8
|
+
import type { ComponentPropsWithRef, FC, ReactNode } from "react";
|
|
9
|
+
export type ButtonProps = ComponentPropsWithRef<"button"> & ButtonVariants & {
|
|
10
|
+
readonly loading?: boolean;
|
|
11
|
+
readonly startIcon?: ReactNode;
|
|
12
|
+
readonly endIcon?: ReactNode;
|
|
13
|
+
};
|
|
14
|
+
export declare const Button: FC<ButtonProps>;
|
|
15
|
+
export type ButtonLinkProps = ComponentPropsWithRef<"a"> & ButtonVariants & {
|
|
16
|
+
readonly href: string;
|
|
17
|
+
readonly startIcon?: ReactNode;
|
|
18
|
+
readonly endIcon?: ReactNode;
|
|
19
|
+
};
|
|
20
|
+
export declare const ButtonLink: FC<ButtonLinkProps>;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author WMXPY
|
|
3
|
+
* @package Button
|
|
4
|
+
* @namespace Root
|
|
5
|
+
* @description Index
|
|
6
|
+
*/
|
|
7
|
+
export { useAsyncAction } from "./async-action";
|
|
8
|
+
export type { ButtonLinkProps, ButtonProps } from "./button";
|
|
9
|
+
export { Button, ButtonLink } from "./button";
|
|
10
|
+
export { downloadBlob } from "./download";
|
|
11
|
+
export type { ButtonVariants } from "./style";
|
|
12
|
+
export { buttonClass } from "./style";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
// src/async-action.ts
|
|
2
|
+
import { useRef, useState } from "react";
|
|
3
|
+
var performAsyncAction = async ({ action, onStart, onPendingChange }) => {
|
|
4
|
+
onPendingChange(true);
|
|
5
|
+
try {
|
|
6
|
+
await onStart?.();
|
|
7
|
+
await new Promise((resolve) => {
|
|
8
|
+
setTimeout(resolve, 0);
|
|
9
|
+
});
|
|
10
|
+
await action();
|
|
11
|
+
} finally {
|
|
12
|
+
onPendingChange(false);
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
var useAsyncAction = ({ action, onStart, disabled = false }) => {
|
|
16
|
+
const [
|
|
17
|
+
pending,
|
|
18
|
+
setPending
|
|
19
|
+
] = useState(false);
|
|
20
|
+
const active = useRef(false);
|
|
21
|
+
return {
|
|
22
|
+
pending,
|
|
23
|
+
async run() {
|
|
24
|
+
if (disabled || active.current) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
active.current = true;
|
|
28
|
+
try {
|
|
29
|
+
await performAsyncAction({
|
|
30
|
+
action,
|
|
31
|
+
...onStart ? { onStart } : {},
|
|
32
|
+
onPendingChange: setPending
|
|
33
|
+
});
|
|
34
|
+
} finally {
|
|
35
|
+
active.current = false;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
// src/style.ts
|
|
42
|
+
import { cn } from "@gridui/style-utils";
|
|
43
|
+
import { cva } from "class-variance-authority";
|
|
44
|
+
var buttonStyles = cva(cn(
|
|
45
|
+
"gridui-button",
|
|
46
|
+
"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)",
|
|
47
|
+
"[&_svg]:w-gridui-16 [&_svg]:h-gridui-16 [&_svg]:shrink-0 [&_svg]:pointer-events-none",
|
|
48
|
+
"disabled:opacity-50 disabled:cursor-not-allowed",
|
|
49
|
+
"[&:hover:not(:disabled)]:border-foreground",
|
|
50
|
+
"[&:active:not(:disabled)]:opacity-[0.8]",
|
|
51
|
+
"motion-reduce:transition-none"
|
|
52
|
+
));
|
|
53
|
+
var buttonStandardStyles = cva(cn(
|
|
54
|
+
"gridui-button-standard",
|
|
55
|
+
"min-h-11 py-gridui-8 px-gridui-16"
|
|
56
|
+
));
|
|
57
|
+
var buttonSmallStyles = cva(cn(
|
|
58
|
+
"gridui-button-small",
|
|
59
|
+
"min-h-9 py-gridui-4 px-gridui-8"
|
|
60
|
+
));
|
|
61
|
+
var buttonPrimaryStyles = cva(cn(
|
|
62
|
+
"gridui-button-primary",
|
|
63
|
+
"text-accent-foreground bg-accent-background border-accent-background"
|
|
64
|
+
));
|
|
65
|
+
var buttonSecondaryStyles = cva(cn(
|
|
66
|
+
"gridui-button-secondary",
|
|
67
|
+
"text-foreground bg-transparent border-border",
|
|
68
|
+
"[&:hover:not(:disabled)]:bg-surface-hover"
|
|
69
|
+
));
|
|
70
|
+
var buttonQuietStyles = cva(cn(
|
|
71
|
+
"gridui-button-quiet",
|
|
72
|
+
"text-foreground bg-transparent",
|
|
73
|
+
"[&:hover:not(:disabled)]:bg-surface-hover"
|
|
74
|
+
));
|
|
75
|
+
var buttonTextStyles = cva(cn(
|
|
76
|
+
"gridui-button-text",
|
|
77
|
+
"text-foreground bg-transparent border-0 border-b border-foreground rounded-none"
|
|
78
|
+
));
|
|
79
|
+
var buttonEntryStyles = cva(cn(
|
|
80
|
+
"gridui-button-entry",
|
|
81
|
+
"justify-between w-full py-gridui-16 px-gridui-24 bg-background"
|
|
82
|
+
));
|
|
83
|
+
var buttonRailStyles = cva(cn(
|
|
84
|
+
"gridui-button-rail",
|
|
85
|
+
"w-full min-w-gridui-24 flex-col py-gridui-8 px-0",
|
|
86
|
+
"[&_>_span]:[writing-mode:vertical-rl] [&_>_span]:whitespace-nowrap"
|
|
87
|
+
));
|
|
88
|
+
var buttonIconStyles = cva(cn(
|
|
89
|
+
"gridui-button-icon",
|
|
90
|
+
"w-11 h-11 shrink-0 p-0",
|
|
91
|
+
"[&.gridui-button-small]:w-9 [&.gridui-button-small]:h-9",
|
|
92
|
+
"pointer-coarse:[&.gridui-button-small]:w-11 pointer-coarse:[&.gridui-button-small]:h-11"
|
|
93
|
+
));
|
|
94
|
+
var buttonVariants = cva(buttonStyles(), {
|
|
95
|
+
variants: {
|
|
96
|
+
variant: {
|
|
97
|
+
primary: buttonPrimaryStyles(),
|
|
98
|
+
secondary: buttonSecondaryStyles(),
|
|
99
|
+
quiet: buttonQuietStyles(),
|
|
100
|
+
text: buttonTextStyles()
|
|
101
|
+
},
|
|
102
|
+
size: {
|
|
103
|
+
small: buttonSmallStyles(),
|
|
104
|
+
standard: buttonStandardStyles()
|
|
105
|
+
},
|
|
106
|
+
layout: {
|
|
107
|
+
standard: "",
|
|
108
|
+
icon: buttonIconStyles(),
|
|
109
|
+
entry: buttonEntryStyles(),
|
|
110
|
+
rail: buttonRailStyles()
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
defaultVariants: {
|
|
114
|
+
variant: "primary",
|
|
115
|
+
size: "standard"
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
var buttonClass = (variants = {}, className) => {
|
|
119
|
+
return cn(buttonVariants({
|
|
120
|
+
variant: variants.variant,
|
|
121
|
+
size: variants.size,
|
|
122
|
+
layout: variants.layout
|
|
123
|
+
}), variants.variant === "text" && "px-0", className);
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
// src/button.tsx
|
|
127
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
128
|
+
var Button = (props) => {
|
|
129
|
+
const {
|
|
130
|
+
variant,
|
|
131
|
+
size,
|
|
132
|
+
layout,
|
|
133
|
+
loading = false,
|
|
134
|
+
disabled,
|
|
135
|
+
type = "button",
|
|
136
|
+
className,
|
|
137
|
+
children,
|
|
138
|
+
startIcon,
|
|
139
|
+
endIcon,
|
|
140
|
+
...restProps
|
|
141
|
+
} = props;
|
|
142
|
+
const variants = variant === "text" ? {
|
|
143
|
+
variant,
|
|
144
|
+
size,
|
|
145
|
+
layout: "standard"
|
|
146
|
+
} : {
|
|
147
|
+
variant,
|
|
148
|
+
size,
|
|
149
|
+
layout
|
|
150
|
+
};
|
|
151
|
+
return /* @__PURE__ */ jsxs(
|
|
152
|
+
"button",
|
|
153
|
+
{
|
|
154
|
+
...restProps,
|
|
155
|
+
type,
|
|
156
|
+
disabled: disabled || loading,
|
|
157
|
+
"aria-busy": loading || restProps["aria-busy"],
|
|
158
|
+
className: buttonClass(variants, className),
|
|
159
|
+
children: [
|
|
160
|
+
startIcon !== void 0 && startIcon !== null && typeof startIcon !== "boolean" && /* @__PURE__ */ jsx(
|
|
161
|
+
"span",
|
|
162
|
+
{
|
|
163
|
+
className: "gridui-button-adornment inline-flex shrink-0 items-center pointer-events-none",
|
|
164
|
+
"aria-hidden": "true",
|
|
165
|
+
inert: true,
|
|
166
|
+
children: startIcon
|
|
167
|
+
}
|
|
168
|
+
),
|
|
169
|
+
children,
|
|
170
|
+
endIcon !== void 0 && endIcon !== null && typeof endIcon !== "boolean" && /* @__PURE__ */ jsx(
|
|
171
|
+
"span",
|
|
172
|
+
{
|
|
173
|
+
className: "gridui-button-adornment inline-flex shrink-0 items-center pointer-events-none",
|
|
174
|
+
"aria-hidden": "true",
|
|
175
|
+
inert: true,
|
|
176
|
+
children: endIcon
|
|
177
|
+
}
|
|
178
|
+
)
|
|
179
|
+
]
|
|
180
|
+
}
|
|
181
|
+
);
|
|
182
|
+
};
|
|
183
|
+
var ButtonLink = (props) => {
|
|
184
|
+
const {
|
|
185
|
+
variant = "secondary",
|
|
186
|
+
size,
|
|
187
|
+
layout,
|
|
188
|
+
className,
|
|
189
|
+
children,
|
|
190
|
+
startIcon,
|
|
191
|
+
endIcon,
|
|
192
|
+
...restProps
|
|
193
|
+
} = props;
|
|
194
|
+
const variants = variant === "text" ? {
|
|
195
|
+
variant,
|
|
196
|
+
size,
|
|
197
|
+
layout: "standard"
|
|
198
|
+
} : {
|
|
199
|
+
variant,
|
|
200
|
+
size,
|
|
201
|
+
layout
|
|
202
|
+
};
|
|
203
|
+
return /* @__PURE__ */ jsxs(
|
|
204
|
+
"a",
|
|
205
|
+
{
|
|
206
|
+
...restProps,
|
|
207
|
+
className: buttonClass(variants, className),
|
|
208
|
+
children: [
|
|
209
|
+
startIcon !== void 0 && startIcon !== null && typeof startIcon !== "boolean" && /* @__PURE__ */ jsx(
|
|
210
|
+
"span",
|
|
211
|
+
{
|
|
212
|
+
className: "gridui-button-adornment inline-flex shrink-0 items-center pointer-events-none",
|
|
213
|
+
"aria-hidden": "true",
|
|
214
|
+
inert: true,
|
|
215
|
+
children: startIcon
|
|
216
|
+
}
|
|
217
|
+
),
|
|
218
|
+
children,
|
|
219
|
+
endIcon !== void 0 && endIcon !== null && typeof endIcon !== "boolean" && /* @__PURE__ */ jsx(
|
|
220
|
+
"span",
|
|
221
|
+
{
|
|
222
|
+
className: "gridui-button-adornment inline-flex shrink-0 items-center pointer-events-none",
|
|
223
|
+
"aria-hidden": "true",
|
|
224
|
+
inert: true,
|
|
225
|
+
children: endIcon
|
|
226
|
+
}
|
|
227
|
+
)
|
|
228
|
+
]
|
|
229
|
+
}
|
|
230
|
+
);
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
// src/download.ts
|
|
234
|
+
var downloadBlob = (blob, filename) => {
|
|
235
|
+
const url = URL.createObjectURL(blob);
|
|
236
|
+
const link = document.createElement("a");
|
|
237
|
+
link.href = url;
|
|
238
|
+
link.download = filename;
|
|
239
|
+
document.body.appendChild(link);
|
|
240
|
+
link.click();
|
|
241
|
+
link.remove();
|
|
242
|
+
window.setTimeout(() => {
|
|
243
|
+
URL.revokeObjectURL(url);
|
|
244
|
+
}, 3e4);
|
|
245
|
+
};
|
|
246
|
+
export {
|
|
247
|
+
Button,
|
|
248
|
+
ButtonLink,
|
|
249
|
+
buttonClass,
|
|
250
|
+
downloadBlob,
|
|
251
|
+
useAsyncAction
|
|
252
|
+
};
|
|
253
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 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 bg-background\",\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 text: buttonTextStyles(),\n },\n size: {\n small: buttonSmallStyles(),\n standard: buttonStandardStyles(),\n },\n layout: {\n standard: \"\",\n icon: buttonIconStyles(),\n entry: buttonEntryStyles(),\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\";\n readonly layout?: \"standard\" | null | undefined;\n }\n | {\n readonly variant?: Exclude<ButtonStyleVariants[\"variant\"], \"text\">;\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\" && \"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\" ? {\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\" ? {\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
|
+
"names": []
|
|
7
|
+
}
|
package/dist/style.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author WMXPY
|
|
3
|
+
* @package Button
|
|
4
|
+
* @namespace Root
|
|
5
|
+
* @description Style
|
|
6
|
+
*/
|
|
7
|
+
import type { VariantProps } from "class-variance-authority";
|
|
8
|
+
export declare const buttonStyles: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
|
|
9
|
+
export declare const buttonStandardStyles: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
|
|
10
|
+
export declare const buttonSmallStyles: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
|
|
11
|
+
export declare const buttonPrimaryStyles: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
|
|
12
|
+
export declare const buttonSecondaryStyles: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
|
|
13
|
+
export declare const buttonQuietStyles: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
|
|
14
|
+
export declare const buttonTextStyles: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
|
|
15
|
+
export declare const buttonEntryStyles: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
|
|
16
|
+
export declare const buttonRailStyles: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
|
|
17
|
+
export declare const buttonIconStyles: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
|
|
18
|
+
export declare const buttonVariants: (props?: ({
|
|
19
|
+
variant?: "primary" | "secondary" | "quiet" | "text" | null | undefined;
|
|
20
|
+
size?: "small" | "standard" | null | undefined;
|
|
21
|
+
layout?: "standard" | "icon" | "entry" | "rail" | null | undefined;
|
|
22
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
23
|
+
type ButtonStyleVariants = VariantProps<typeof buttonVariants>;
|
|
24
|
+
export type ButtonVariants = Omit<ButtonStyleVariants, "variant" | "layout"> & ({
|
|
25
|
+
readonly variant: "text";
|
|
26
|
+
readonly layout?: "standard" | null | undefined;
|
|
27
|
+
} | {
|
|
28
|
+
readonly variant?: Exclude<ButtonStyleVariants["variant"], "text">;
|
|
29
|
+
readonly layout?: ButtonStyleVariants["layout"];
|
|
30
|
+
});
|
|
31
|
+
export declare const buttonClass: (variants?: ButtonVariants, className?: string) => string;
|
|
32
|
+
export {};
|
package/dist/styles.css
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
|
|
2
|
+
@layer properties;
|
|
3
|
+
@layer theme, base, components, utilities;
|
|
4
|
+
@layer theme {
|
|
5
|
+
:root, :host {
|
|
6
|
+
--spacing: 0.25rem;
|
|
7
|
+
--default-transition-duration: 150ms;
|
|
8
|
+
--default-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
@layer utilities {
|
|
12
|
+
.pointer-events-none {
|
|
13
|
+
pointer-events: none;
|
|
14
|
+
}
|
|
15
|
+
.inline-flex {
|
|
16
|
+
display: inline-flex;
|
|
17
|
+
}
|
|
18
|
+
.h-11 {
|
|
19
|
+
height: calc(var(--spacing) * 11);
|
|
20
|
+
}
|
|
21
|
+
.min-h-9 {
|
|
22
|
+
min-height: calc(var(--spacing) * 9);
|
|
23
|
+
}
|
|
24
|
+
.min-h-11 {
|
|
25
|
+
min-height: calc(var(--spacing) * 11);
|
|
26
|
+
}
|
|
27
|
+
.w-11 {
|
|
28
|
+
width: calc(var(--spacing) * 11);
|
|
29
|
+
}
|
|
30
|
+
.w-fit {
|
|
31
|
+
width: fit-content;
|
|
32
|
+
}
|
|
33
|
+
.w-full {
|
|
34
|
+
width: 100%;
|
|
35
|
+
}
|
|
36
|
+
.max-w-full {
|
|
37
|
+
max-width: 100%;
|
|
38
|
+
}
|
|
39
|
+
.min-w-0 {
|
|
40
|
+
min-width: 0px;
|
|
41
|
+
}
|
|
42
|
+
.min-w-gridui-24 {
|
|
43
|
+
min-width: var(--gridui-space-24);
|
|
44
|
+
}
|
|
45
|
+
.shrink-0 {
|
|
46
|
+
flex-shrink: 0;
|
|
47
|
+
}
|
|
48
|
+
.cursor-pointer {
|
|
49
|
+
cursor: pointer;
|
|
50
|
+
}
|
|
51
|
+
.flex-col {
|
|
52
|
+
flex-direction: column;
|
|
53
|
+
}
|
|
54
|
+
.items-center {
|
|
55
|
+
align-items: center;
|
|
56
|
+
}
|
|
57
|
+
.justify-between {
|
|
58
|
+
justify-content: space-between;
|
|
59
|
+
}
|
|
60
|
+
.justify-center {
|
|
61
|
+
justify-content: center;
|
|
62
|
+
}
|
|
63
|
+
.gap-gridui-8 {
|
|
64
|
+
gap: var(--gridui-space-8);
|
|
65
|
+
}
|
|
66
|
+
.rounded-control {
|
|
67
|
+
border-radius: var(--gridui-control-radius);
|
|
68
|
+
}
|
|
69
|
+
.rounded-none {
|
|
70
|
+
border-radius: 0;
|
|
71
|
+
}
|
|
72
|
+
.border {
|
|
73
|
+
border-style: var(--tw-border-style);
|
|
74
|
+
border-width: 1px;
|
|
75
|
+
}
|
|
76
|
+
.border-0 {
|
|
77
|
+
border-style: var(--tw-border-style);
|
|
78
|
+
border-width: 0px;
|
|
79
|
+
}
|
|
80
|
+
.border-b {
|
|
81
|
+
border-bottom-style: var(--tw-border-style);
|
|
82
|
+
border-bottom-width: 1px;
|
|
83
|
+
}
|
|
84
|
+
.border-solid {
|
|
85
|
+
--tw-border-style: solid;
|
|
86
|
+
border-style: solid;
|
|
87
|
+
}
|
|
88
|
+
.border-accent-background {
|
|
89
|
+
border-color: var(--gridui-accent-background);
|
|
90
|
+
}
|
|
91
|
+
.border-border {
|
|
92
|
+
border-color: var(--gridui-border);
|
|
93
|
+
}
|
|
94
|
+
.border-foreground {
|
|
95
|
+
border-color: var(--gridui-foreground);
|
|
96
|
+
}
|
|
97
|
+
.border-transparent {
|
|
98
|
+
border-color: transparent;
|
|
99
|
+
}
|
|
100
|
+
.bg-accent-background {
|
|
101
|
+
background-color: var(--gridui-accent-background);
|
|
102
|
+
}
|
|
103
|
+
.bg-background {
|
|
104
|
+
background-color: var(--gridui-background);
|
|
105
|
+
}
|
|
106
|
+
.bg-transparent {
|
|
107
|
+
background-color: transparent;
|
|
108
|
+
}
|
|
109
|
+
.p-0 {
|
|
110
|
+
padding: 0px;
|
|
111
|
+
}
|
|
112
|
+
.px-0 {
|
|
113
|
+
padding-inline: 0px;
|
|
114
|
+
}
|
|
115
|
+
.px-gridui-8 {
|
|
116
|
+
padding-inline: var(--gridui-space-8);
|
|
117
|
+
}
|
|
118
|
+
.px-gridui-16 {
|
|
119
|
+
padding-inline: var(--gridui-space-16);
|
|
120
|
+
}
|
|
121
|
+
.px-gridui-24 {
|
|
122
|
+
padding-inline: var(--gridui-space-24);
|
|
123
|
+
}
|
|
124
|
+
.py-gridui-4 {
|
|
125
|
+
padding-block: var(--gridui-space-4);
|
|
126
|
+
}
|
|
127
|
+
.py-gridui-8 {
|
|
128
|
+
padding-block: var(--gridui-space-8);
|
|
129
|
+
}
|
|
130
|
+
.py-gridui-16 {
|
|
131
|
+
padding-block: var(--gridui-space-16);
|
|
132
|
+
}
|
|
133
|
+
.text-center {
|
|
134
|
+
text-align: center;
|
|
135
|
+
}
|
|
136
|
+
.type-ui {
|
|
137
|
+
font: var(--gridui-type-ui);
|
|
138
|
+
letter-spacing: normal;
|
|
139
|
+
}
|
|
140
|
+
.wrap-anywhere {
|
|
141
|
+
overflow-wrap: anywhere;
|
|
142
|
+
}
|
|
143
|
+
.text-accent-foreground {
|
|
144
|
+
color: var(--gridui-accent-foreground);
|
|
145
|
+
}
|
|
146
|
+
.text-foreground {
|
|
147
|
+
color: var(--gridui-foreground);
|
|
148
|
+
}
|
|
149
|
+
.no-underline {
|
|
150
|
+
text-decoration-line: none;
|
|
151
|
+
}
|
|
152
|
+
.transition-colors {
|
|
153
|
+
transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to;
|
|
154
|
+
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
|
|
155
|
+
transition-duration: var(--tw-duration, var(--default-transition-duration));
|
|
156
|
+
}
|
|
157
|
+
.duration-\(--gridui-motion-duration-quick\) {
|
|
158
|
+
--tw-duration: var(--gridui-motion-duration-quick);
|
|
159
|
+
transition-duration: var(--gridui-motion-duration-quick);
|
|
160
|
+
}
|
|
161
|
+
.ease-\(--gridui-motion-ease-out\) {
|
|
162
|
+
--tw-ease: var(--gridui-motion-ease-out);
|
|
163
|
+
transition-timing-function: var(--gridui-motion-ease-out);
|
|
164
|
+
}
|
|
165
|
+
.disabled\:cursor-not-allowed:disabled {
|
|
166
|
+
cursor: not-allowed;
|
|
167
|
+
}
|
|
168
|
+
.disabled\:opacity-50:disabled {
|
|
169
|
+
opacity: 50%;
|
|
170
|
+
}
|
|
171
|
+
@media (prefers-reduced-motion: reduce) {
|
|
172
|
+
.motion-reduce\:transition-none {
|
|
173
|
+
transition-property: none;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
.\[\&_\>_span\]\:whitespace-nowrap > span {
|
|
177
|
+
white-space: nowrap;
|
|
178
|
+
}
|
|
179
|
+
.\[\&_\>_span\]\:\[writing-mode\:vertical-rl\] > span {
|
|
180
|
+
writing-mode: vertical-rl;
|
|
181
|
+
}
|
|
182
|
+
.\[\&_svg\]\:pointer-events-none svg {
|
|
183
|
+
pointer-events: none;
|
|
184
|
+
}
|
|
185
|
+
.\[\&_svg\]\:h-gridui-16 svg {
|
|
186
|
+
height: var(--gridui-space-16);
|
|
187
|
+
}
|
|
188
|
+
.\[\&_svg\]\:w-gridui-16 svg {
|
|
189
|
+
width: var(--gridui-space-16);
|
|
190
|
+
}
|
|
191
|
+
.\[\&_svg\]\:shrink-0 svg {
|
|
192
|
+
flex-shrink: 0;
|
|
193
|
+
}
|
|
194
|
+
.\[\&\.gridui-button-small\]\:h-9.gridui-button-small {
|
|
195
|
+
height: calc(var(--spacing) * 9);
|
|
196
|
+
}
|
|
197
|
+
.\[\&\.gridui-button-small\]\:w-9.gridui-button-small {
|
|
198
|
+
width: calc(var(--spacing) * 9);
|
|
199
|
+
}
|
|
200
|
+
@media (pointer: coarse) {
|
|
201
|
+
.pointer-coarse\:\[\&\.gridui-button-small\]\:h-11.gridui-button-small {
|
|
202
|
+
height: calc(var(--spacing) * 11);
|
|
203
|
+
}
|
|
204
|
+
.pointer-coarse\:\[\&\.gridui-button-small\]\:w-11.gridui-button-small {
|
|
205
|
+
width: calc(var(--spacing) * 11);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
.\[\&\:active\:not\(\:disabled\)\]\:opacity-\[0\.8\]:active:not(:disabled) {
|
|
209
|
+
opacity: 0.8;
|
|
210
|
+
}
|
|
211
|
+
.\[\&\:hover\:not\(\:disabled\)\]\:border-foreground:hover:not(:disabled) {
|
|
212
|
+
border-color: var(--gridui-foreground);
|
|
213
|
+
}
|
|
214
|
+
.\[\&\:hover\:not\(\:disabled\)\]\:bg-surface-hover:hover:not(:disabled) {
|
|
215
|
+
background-color: var(--gridui-surface-hover);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
@property --tw-border-style {
|
|
219
|
+
syntax: "*";
|
|
220
|
+
inherits: false;
|
|
221
|
+
initial-value: solid;
|
|
222
|
+
}
|
|
223
|
+
@property --tw-duration {
|
|
224
|
+
syntax: "*";
|
|
225
|
+
inherits: false;
|
|
226
|
+
}
|
|
227
|
+
@property --tw-ease {
|
|
228
|
+
syntax: "*";
|
|
229
|
+
inherits: false;
|
|
230
|
+
}
|
|
231
|
+
@layer properties {
|
|
232
|
+
@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) {
|
|
233
|
+
*, ::before, ::after, ::backdrop {
|
|
234
|
+
--tw-border-style: solid;
|
|
235
|
+
--tw-duration: initial;
|
|
236
|
+
--tw-ease: initial;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,58 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gridui/button",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "GridUI React buttons and action helpers",
|
|
5
|
+
"license": "UNLICENSED",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/sudo-ui/GridUI-React-Monorepo.git",
|
|
10
|
+
"directory": "packages/button"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"dist",
|
|
14
|
+
"README.md"
|
|
15
|
+
],
|
|
16
|
+
"sideEffects": [
|
|
17
|
+
"**/*.css"
|
|
18
|
+
],
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
22
|
+
"import": "./dist/index.js"
|
|
23
|
+
},
|
|
24
|
+
"./styles.css": "./dist/styles.css"
|
|
25
|
+
},
|
|
26
|
+
"publishConfig": {
|
|
27
|
+
"access": "public"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@gridui/style-utils": "^2.1.1",
|
|
31
|
+
"@gridui/theme": "^2.1.1",
|
|
32
|
+
"class-variance-authority": "0.7.1"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@gridui-internal/configuration": "0.0.0",
|
|
36
|
+
"@jest/globals": "30.5.2",
|
|
37
|
+
"@storybook/react-vite": "10.6.3",
|
|
38
|
+
"@types/jest": "30.0.0",
|
|
39
|
+
"@types/node": "26.6.5",
|
|
40
|
+
"@types/react": "19.3.0",
|
|
41
|
+
"@types/react-dom": "19.3.0",
|
|
42
|
+
"jest": "30.5.2",
|
|
43
|
+
"lucide-react": "1.61.0",
|
|
44
|
+
"react": "19.3.1",
|
|
45
|
+
"react-dom": "19.3.1",
|
|
46
|
+
"typescript": "6.0.3"
|
|
47
|
+
},
|
|
48
|
+
"peerDependencies": {
|
|
49
|
+
"react": "^19.2.0",
|
|
50
|
+
"react-dom": "^19.2.0"
|
|
51
|
+
},
|
|
52
|
+
"scripts": {
|
|
53
|
+
"build": "node ../../scripts/compilation/package.ts",
|
|
54
|
+
"compile": "tsc --project tsconfig.json",
|
|
55
|
+
"test": "jest",
|
|
56
|
+
"coverage": "jest --coverage"
|
|
57
|
+
}
|
|
6
58
|
}
|