@gridui/button 2.1.3 → 3.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 CHANGED
@@ -1,7 +1,7 @@
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,
4
+ and async action scheduling. It has no domain,
5
5
  route, locale, or Layout dependency. Load `@gridui/button/styles.css` after
6
6
  the theme styles.
7
7
 
@@ -20,7 +20,9 @@ import "@gridui/button/styles.css";
20
20
  `Button` forwards native button props and refs. It defaults to `type="button"`;
21
21
  use `type="submit"` for a form action. `loading` disables the native button and
22
22
  exposes `aria-busy` without replacing the visible action name. Native `disabled`
23
- remains available independently of loading.
23
+ remains available independently of loading. For a focusable unavailable action,
24
+ supply `aria-disabled` and guard activation in its owner. ARIA/data-disabled
25
+ attributes share the disabled appearance; native `disabled` blocks activation.
24
26
 
25
27
  `ButtonLink` forwards native anchor props and refs and requires `href`. It
26
28
  defaults to the secondary variant and retains navigation, modified-click,
@@ -29,10 +31,19 @@ Use a real button when the action needs native disabled behavior.
29
31
 
30
32
  ## Appearance and icons
31
33
 
32
- The variants are `primary`, `secondary`, `quiet`, `highlight`, `text`, and `underlined`. Sizes are
33
- `standard` (2.75rem minimum height) and `small` (2.25rem). The existing `standard`,
34
- `icon`, `entry`, and `rail` layouts, plus the full-region `cell` layout, are
35
- available for non-text/non-underlined variants.
34
+ The variants are `primary`, `secondary`, `quiet`, `highlight`, `text`, and `underlined`.
35
+ Sizes scale with the consumer's root font size:
36
+
37
+ | Size | Minimum height | Inline padding | Icon size |
38
+ | --- | --- | --- | --- |
39
+ | `small` | 2.25rem | 0.5rem | 1rem |
40
+ | `standard` | 2.75rem | 1rem | 1rem |
41
+ | `large` | 3rem | 1.5rem | 1.25rem |
42
+ | `extra-large` | 4.5rem | 1.5rem | 1.25rem |
43
+
44
+ The `standard`, `icon`, `entry`, `cell`, `rail`, and `divided` layouts are
45
+ available for non-text/non-underlined variants. Layouts own their structural
46
+ padding; the size table describes standalone controls and divided labels.
36
47
  Small icon controls retain a 2.75rem touch target on coarse pointers.
37
48
 
38
49
  `text` and `underlined` accept only `layout="standard"`, which may be omitted.
@@ -44,7 +55,9 @@ retain the theme's native keyboard focus treatment.
44
55
 
45
56
  Consumers that previously used `text` for a permanent underline must switch to
46
57
  `underlined`. Keep `text` for unlined actions and navigation links.
47
- There are no application colors or implicit icon transforms.
58
+ There are no application colors or implicit icon transforms. Large and
59
+ extra-large text/underlined actions use supporting typography and a 2rem gap
60
+ between the label and decorative icons. Smaller sizes retain the normal 0.5rem gap.
48
61
 
49
62
  `startIcon` and `endIcon` accept decorative React nodes before and after the
50
63
  existing `children`. Their wrappers are hidden from assistive technology and
@@ -52,13 +65,22 @@ inert, so the visible label remains the accessible name. Do not put interactive
52
65
  content in these slots. Existing icons passed directly in `children` keep their
53
66
  original rendering and accessibility responsibilities.
54
67
 
68
+ `iconMotion="outward"` opts the `endIcon` into a small hover translation upward
69
+ and toward the inline end. It follows inherited text direction, leaves any
70
+ dividing line fixed, and does not animate disabled or loading buttons. Reduced
71
+ motion removes both the translation and transition. The default is `none`;
72
+ keyboard focus never requires motion to remain visible. Supply an icon whose
73
+ direction matches the action and locale.
74
+
55
75
  Primary buttons use `accent-background` and `accent-foreground`. Secondary
56
76
  buttons use a transparent fill, foreground text, and a border; quiet buttons
57
- omit the border. Secondary and quiet surfaces use `surface-hover` while enabled.
58
- Disabled buttons keep their base fill and reduced opacity. Standard and small
77
+ omit the border. All variants use Theme's shared hover and keyboard-focus outlines. Pressing
78
+ overlays the existing background without fading the label or icon. Highlight
79
+ buttons use `brand-tint` for persistent selection. Disabled buttons keep their
80
+ base fill and reduced opacity. Standard and small
59
81
  sizes scale with the consumer's root font size.
60
82
 
61
- `highlight` uses the neutral `surface` fill and normal foreground. Use it for a
83
+ `highlight` uses the local `brand-tint` fill and normal foreground. Use it for a
62
84
  persistent selected action, with `quiet` for its unselected peers. Choose the
63
85
  variant from application state and supply the matching native semantics, such as
64
86
  `aria-pressed` for a toggle or `aria-current="page"` for navigation. The variant
@@ -70,7 +92,7 @@ not replace the chosen variant's background. `cell` fills both the width and
70
92
  height of its containing region, uses square corners and no button border, and
71
93
  keeps content padding inside the hit area. Grid or another structural parent
72
94
  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).
95
+ an inset selected surface. See the [composition recipe](https://github.com/sudo-ui/GridUI-React-Monorepo/blob/main/docs/usage/composition.md#full-region-actions).
74
96
 
75
97
  `buttonClass(variants, className?)` exposes the same appearance and text-layout
76
98
  constraints for caller-owned native elements. `startIcon` and `endIcon` are
@@ -78,6 +100,40 @@ component props, not styling variants. It uses `cn` for consumer class overrides
78
100
  Callers using the class helper own native semantics, icon accessibility, and
79
101
  loading behavior.
80
102
 
103
+ ## Divided actions
104
+
105
+ `layout="divided"` fills its available width, uses square corners, and keeps
106
+ the label and trailing decorative icon in separate visual regions. Both regions
107
+ remain inside one native button or anchor. The trailing region is inert and
108
+ hidden from assistive technology; it never introduces another action or tab stop.
109
+ Omitting an empty or conditional `endIcon` removes that region and its separator.
110
+
111
+ The label uses the selected size's padding. The trailing region is 2.25rem,
112
+ 2.75rem, 3rem, or 4rem wide for small through extra-large sizes. Both regions
113
+ stretch together when a long label wraps. The separator uses the inherited
114
+ foreground with reduced opacity and follows logical text direction. Appearance
115
+ still comes from `variant`; the layout does not choose a brand, fill, or route.
116
+ The containing page owns its maximum width.
117
+
118
+ ```tsx
119
+ <ButtonLink href="/projects" variant="secondary" layout="divided"
120
+ size="extra-large" endIcon={<ArrowUpRight />}>
121
+ View projects
122
+ </ButtonLink>;
123
+
124
+ <Button variant="underlined" size="large" iconMotion="outward"
125
+ endIcon={<ArrowUpRight />} onClick={reviewProject}>
126
+ Review project
127
+ </Button>;
128
+ ```
129
+
130
+ These forms work in public pages, dashboards, and tools. Use Tabs for switching
131
+ content panels, Choice or RadioGroup for choices, Collection for structured
132
+ multi-line entries, and Sidebar for application navigation. Keep brand artwork,
133
+ identity lookup, routes, and selection state with their application owners.
134
+ Use `Button` and `ButtonLink` to construct divided regions; `buttonClass` styles
135
+ the outer native control and does not construct content or decorative slots.
136
+
81
137
  ## Action helpers
82
138
 
83
139
  `useAsyncAction({ action, onStart?, disabled? })` returns `pending` and `run`.
@@ -86,10 +142,6 @@ browser event loop, runs the action, and releases pending state on success or
86
142
  failure. Disabled actions and repeated activation while pending are ignored.
87
143
  Callers own business error handling and generated bytes.
88
144
 
89
- `downloadBlob(blob, filename)` creates the download anchor and object URL,
90
- activates the native download, removes the anchor, and releases the URL after
91
- the browser has had time to consume it. Callers own the Blob contents and name.
92
-
93
145
  ## Verification
94
146
 
95
147
  Package unit tests cover native action/link semantics, decorative icon isolation,
@@ -97,4 +149,7 @@ busy-state scheduling and failure cleanup. Type fixtures compile with the packag
97
149
  and reject text and underlined/icon-layout combinations, missing link destinations, and icon
98
150
  nodes passed as style variants. Storybook includes standalone, icon, full-cell,
99
151
  and disabled highlight states, text and underlined actions and links, decorative
100
- icon slots, long labels, loading, and the existing variants.
152
+ icon slots, long labels, loading, and the existing variants. Divided-layout browser
153
+ checks cover one-action hit areas, native keyboard activation, busy-state
154
+ transitions, RTL seams and motion, long labels at text zoom, and the
155
+ viewport/theme/reduced-motion matrix.
package/dist/index.d.ts CHANGED
@@ -7,7 +7,6 @@
7
7
  export { useAsyncAction } from "./button/async-action";
8
8
  export type { ButtonProps } from "./button/button";
9
9
  export { Button } from "./button/button";
10
- export { downloadBlob } from "./button/download";
11
10
  export type { ButtonLinkProps } from "./button-link/button-link";
12
11
  export { ButtonLink } from "./button-link/button-link";
13
12
  export type { ButtonVariants } from "./shared/style";
package/dist/index.js CHANGED
@@ -43,66 +43,106 @@ import { cn } from "@gridui/style-utils";
43
43
  import { cva } from "class-variance-authority";
44
44
  var buttonStyles = cva(cn(
45
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"
46
+ "gridui-u-inline-flex gridui-u-w-fit gridui-u-max-w-full gridui-u-min-w-0 gridui-u-items-center gridui-u-justify-center gridui-u-gap-gridui-8 gridui-u-border gridui-u-border-solid gridui-u-border-transparent gridui-u-rounded-control gridui-u-type-ui gridui-u-text-center gridui-u-no-underline gridui-u-wrap-anywhere gridui-u-cursor-pointer gridui-u-transition-colors gridui-u-duration-(--gridui-motion-duration-quick) gridui-u-ease-(--gridui-motion-ease-out)",
47
+ "gridui-u-[&_svg]:w-gridui-16 gridui-u-[&_svg]:h-gridui-16 gridui-u-[&_svg]:shrink-0 gridui-u-[&_svg]:pointer-events-none",
48
+ "gridui-u-disabled:opacity-50 gridui-u-disabled:cursor-not-allowed",
49
+ "gridui-u-aria-disabled:opacity-50 gridui-u-aria-disabled:cursor-not-allowed",
50
+ "gridui-u-data-disabled:opacity-50 gridui-u-data-disabled:cursor-not-allowed",
51
+ "gridui-u-motion-reduce:transition-none"
52
52
  ));
53
53
  var buttonStandardStyles = cva(cn(
54
54
  "gridui-button-standard",
55
- "min-h-11 py-gridui-8 px-gridui-16"
55
+ "gridui-u-min-h-11 gridui-u-py-gridui-8 gridui-u-px-gridui-16"
56
56
  ));
57
57
  var buttonSmallStyles = cva(cn(
58
58
  "gridui-button-small",
59
- "min-h-9 py-gridui-4 px-gridui-8"
59
+ "gridui-u-min-h-9 gridui-u-py-gridui-4 gridui-u-px-gridui-8"
60
+ ));
61
+ var buttonLargeStyles = cva(cn(
62
+ "gridui-button-large",
63
+ "gridui-u-min-h-12 gridui-u-py-gridui-8 gridui-u-px-gridui-24 gridui-u-[&_svg]:w-5 gridui-u-[&_svg]:h-5"
64
+ ));
65
+ var buttonExtraLargeStyles = cva(cn(
66
+ "gridui-button-extra-large",
67
+ "gridui-u-min-h-18 gridui-u-py-gridui-16 gridui-u-px-gridui-24 gridui-u-[&_svg]:w-5 gridui-u-[&_svg]:h-5"
60
68
  ));
61
69
  var buttonPrimaryStyles = cva(cn(
62
70
  "gridui-button-primary",
63
- "text-accent-foreground bg-accent-background border-accent-background"
71
+ "gridui-u-text-accent-foreground gridui-u-bg-accent-background gridui-u-border-accent-background"
64
72
  ));
65
73
  var buttonSecondaryStyles = cva(cn(
66
74
  "gridui-button-secondary",
67
- "text-foreground bg-transparent border-border",
68
- "[&:hover:not(:disabled)]:bg-surface-hover"
75
+ "gridui-u-text-foreground gridui-u-bg-transparent gridui-u-border-border"
69
76
  ));
70
77
  var buttonQuietStyles = cva(cn(
71
78
  "gridui-button-quiet",
72
- "text-foreground bg-transparent",
73
- "[&:hover:not(:disabled)]:bg-surface-hover"
79
+ "gridui-u-text-foreground gridui-u-bg-transparent"
74
80
  ));
75
81
  var buttonHighlightStyles = cva(cn(
76
82
  "gridui-button-highlight",
77
- "text-foreground bg-surface"
83
+ "gridui-u-text-foreground gridui-u-bg-brand-tint"
78
84
  ));
79
85
  var buttonTextStyles = cva(cn(
80
86
  "gridui-button-text",
81
- "text-foreground bg-transparent border-0 rounded-none"
87
+ "gridui-u-text-foreground gridui-u-bg-transparent gridui-u-border-0 gridui-u-rounded-none"
82
88
  ));
83
89
  var buttonUnderlinedStyles = cva(cn(
84
90
  "gridui-button-underlined",
85
- "text-foreground bg-transparent border-0 border-b border-foreground rounded-none"
91
+ "gridui-u-text-foreground gridui-u-bg-transparent gridui-u-border-0 gridui-u-border-b gridui-u-border-foreground gridui-u-rounded-none"
86
92
  ));
87
93
  var buttonEntryStyles = cva(cn(
88
94
  "gridui-button-entry",
89
- "justify-between w-full py-gridui-16 px-gridui-24"
95
+ "gridui-u-justify-between gridui-u-w-full gridui-u-py-gridui-16 gridui-u-px-gridui-24"
90
96
  ));
91
97
  var buttonCellStyles = cva(cn(
92
98
  "gridui-button-cell gridui-interaction-boundary",
93
- "w-full h-full justify-start rounded-none border-0 py-gridui-16 px-gridui-24 text-left"
99
+ "gridui-u-w-full gridui-u-h-full gridui-u-justify-start gridui-u-rounded-none gridui-u-border-0 gridui-u-py-gridui-16 gridui-u-px-gridui-24 gridui-u-text-left"
94
100
  ));
95
101
  var buttonRailStyles = cva(cn(
96
102
  "gridui-button-rail gridui-interaction-boundary",
97
- "w-full min-w-gridui-24 flex-col py-gridui-8 px-0",
98
- "[&_>_span]:[writing-mode:vertical-rl] [&_>_span]:whitespace-nowrap"
103
+ "gridui-u-w-full gridui-u-min-w-gridui-24 gridui-u-flex-col gridui-u-py-gridui-8 gridui-u-px-0",
104
+ "gridui-u-[&_>_span]:[writing-mode:vertical-rl] gridui-u-[&_>_span]:whitespace-nowrap"
99
105
  ));
100
106
  var buttonIconStyles = cva(cn(
101
107
  "gridui-button-icon",
102
- "w-11 h-11 shrink-0 p-0",
103
- "[&.gridui-button-small]:w-9 [&.gridui-button-small]:h-9",
104
- "pointer-coarse:[&.gridui-button-small]:w-11 pointer-coarse:[&.gridui-button-small]:h-11"
108
+ "gridui-u-w-11 gridui-u-h-11 gridui-u-shrink-0 gridui-u-p-0",
109
+ "gridui-u-[&.gridui-button-small]:w-9 gridui-u-[&.gridui-button-small]:h-9",
110
+ "gridui-u-[&.gridui-button-large]:w-12 gridui-u-[&.gridui-button-large]:h-12",
111
+ "gridui-u-[&.gridui-button-extra-large]:w-18 gridui-u-[&.gridui-button-extra-large]:h-18",
112
+ "gridui-u-pointer-coarse:[&.gridui-button-small]:w-11 gridui-u-pointer-coarse:[&.gridui-button-small]:h-11"
113
+ ));
114
+ var buttonDividedStyles = cva(cn(
115
+ "gridui-button-divided",
116
+ "gridui-u-w-full gridui-u-items-stretch gridui-u-justify-between gridui-u-gap-0 gridui-u-rounded-none gridui-u-p-0 gridui-u-text-start"
105
117
  ));
118
+ var buttonLabelStyles = cva(cn(
119
+ "gridui-button-label",
120
+ "gridui-u-inline-flex gridui-u-min-w-0 gridui-u-flex-1 gridui-u-items-center gridui-u-gap-gridui-8"
121
+ ), {
122
+ variants: {
123
+ size: {
124
+ small: "gridui-u-py-gridui-4 gridui-u-px-gridui-8",
125
+ standard: "gridui-u-py-gridui-8 gridui-u-px-gridui-16",
126
+ large: "gridui-u-py-gridui-8 gridui-u-px-gridui-24",
127
+ "extra-large": "gridui-u-py-gridui-16 gridui-u-px-gridui-24"
128
+ }
129
+ },
130
+ defaultVariants: { size: "standard" }
131
+ });
132
+ var buttonEndRegionStyles = cva(cn(
133
+ "gridui-button-end-region",
134
+ "gridui-u-justify-center gridui-u-self-stretch gridui-u-border-s gridui-u-border-solid gridui-u-border-current/25"
135
+ ), {
136
+ variants: {
137
+ size: {
138
+ small: "gridui-u-w-9",
139
+ standard: "gridui-u-w-11",
140
+ large: "gridui-u-w-12",
141
+ "extra-large": "gridui-u-w-gridui-64"
142
+ }
143
+ },
144
+ defaultVariants: { size: "standard" }
145
+ });
106
146
  var buttonVariants = cva(buttonStyles(), {
107
147
  variants: {
108
148
  variant: {
@@ -115,16 +155,36 @@ var buttonVariants = cva(buttonStyles(), {
115
155
  },
116
156
  size: {
117
157
  small: buttonSmallStyles(),
118
- standard: buttonStandardStyles()
158
+ standard: buttonStandardStyles(),
159
+ large: buttonLargeStyles(),
160
+ "extra-large": buttonExtraLargeStyles()
119
161
  },
120
162
  layout: {
121
163
  standard: "",
122
164
  icon: buttonIconStyles(),
123
165
  entry: buttonEntryStyles(),
124
166
  cell: buttonCellStyles(),
125
- rail: buttonRailStyles()
167
+ rail: buttonRailStyles(),
168
+ divided: buttonDividedStyles()
169
+ },
170
+ iconMotion: {
171
+ none: "",
172
+ outward: "gridui-button-icon-motion-outward"
126
173
  }
127
174
  },
175
+ compoundVariants: [
176
+ {
177
+ variant: [
178
+ "text",
179
+ "underlined"
180
+ ],
181
+ size: [
182
+ "large",
183
+ "extra-large"
184
+ ],
185
+ className: "gridui-u-gap-gridui-32 gridui-u-type-supporting"
186
+ }
187
+ ],
128
188
  defaultVariants: {
129
189
  variant: "primary",
130
190
  size: "standard"
@@ -132,21 +192,68 @@ var buttonVariants = cva(buttonStyles(), {
132
192
  });
133
193
  var buttonClass = (variants = {}, className) => {
134
194
  const textVariant = variants.variant === "text" || variants.variant === "underlined";
135
- const boundaryLayout = variants.layout === "cell" || variants.layout === "rail";
136
195
  return cn(buttonVariants({
137
196
  variant: variants.variant,
138
197
  size: variants.size,
139
- layout: variants.layout
140
- }), textVariant && "px-0", !textVariant && !boundaryLayout && "gridui-hover-surface", className);
198
+ layout: variants.layout,
199
+ iconMotion: variants.iconMotion
200
+ }), textVariant && "gridui-u-px-0", className);
201
+ };
202
+
203
+ // src/shared/content.tsx
204
+ import { cn as cn2 } from "@gridui/style-utils";
205
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
206
+ var ButtonContent = (props) => {
207
+ const { children, startIcon, endIcon, layout, size, iconMotion } = props;
208
+ const label = /* @__PURE__ */ jsxs(Fragment, { children: [
209
+ startIcon !== void 0 && startIcon !== null && typeof startIcon !== "boolean" && /* @__PURE__ */ jsx(
210
+ "span",
211
+ {
212
+ className: "gridui-button-adornment gridui-u-inline-flex gridui-u-shrink-0 gridui-u-items-center gridui-u-pointer-events-none",
213
+ "aria-hidden": "true",
214
+ inert: true,
215
+ children: startIcon
216
+ }
217
+ ),
218
+ children
219
+ ] });
220
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
221
+ layout === "divided" ? /* @__PURE__ */ jsx(
222
+ "span",
223
+ {
224
+ className: buttonLabelStyles({ size }),
225
+ children: label
226
+ }
227
+ ) : label,
228
+ endIcon !== void 0 && endIcon !== null && typeof endIcon !== "boolean" && /* @__PURE__ */ jsx(
229
+ "span",
230
+ {
231
+ className: cn2(
232
+ "gridui-button-adornment gridui-u-inline-flex gridui-u-shrink-0 gridui-u-items-center gridui-u-pointer-events-none",
233
+ layout === "divided" && buttonEndRegionStyles({ size })
234
+ ),
235
+ "aria-hidden": "true",
236
+ inert: true,
237
+ children: iconMotion === "outward" ? /* @__PURE__ */ jsx(
238
+ "span",
239
+ {
240
+ className: "gridui-button-end-icon gridui-u-inline-flex",
241
+ children: endIcon
242
+ }
243
+ ) : endIcon
244
+ }
245
+ )
246
+ ] });
141
247
  };
142
248
 
143
249
  // src/button/button.tsx
144
- import { jsx, jsxs } from "react/jsx-runtime";
250
+ import { jsx as jsx2 } from "react/jsx-runtime";
145
251
  var Button = (props) => {
146
252
  const {
147
253
  variant,
148
254
  size,
149
255
  layout,
256
+ iconMotion,
150
257
  loading = false,
151
258
  disabled,
152
259
  type = "button",
@@ -159,13 +266,15 @@ var Button = (props) => {
159
266
  const variants = variant === "text" || variant === "underlined" ? {
160
267
  variant,
161
268
  size,
162
- layout: "standard"
269
+ layout: "standard",
270
+ iconMotion
163
271
  } : {
164
272
  variant,
165
273
  size,
166
- layout
274
+ layout,
275
+ iconMotion
167
276
  };
168
- return /* @__PURE__ */ jsxs(
277
+ return /* @__PURE__ */ jsx2(
169
278
  "button",
170
279
  {
171
280
  ...restProps,
@@ -173,52 +282,29 @@ var Button = (props) => {
173
282
  disabled: disabled || loading,
174
283
  "aria-busy": loading || restProps["aria-busy"],
175
284
  className: buttonClass(variants, className),
176
- children: [
177
- startIcon !== void 0 && startIcon !== null && typeof startIcon !== "boolean" && /* @__PURE__ */ jsx(
178
- "span",
179
- {
180
- className: "gridui-button-adornment inline-flex shrink-0 items-center pointer-events-none",
181
- "aria-hidden": "true",
182
- inert: true,
183
- children: startIcon
184
- }
185
- ),
186
- children,
187
- endIcon !== void 0 && endIcon !== null && typeof endIcon !== "boolean" && /* @__PURE__ */ jsx(
188
- "span",
189
- {
190
- className: "gridui-button-adornment inline-flex shrink-0 items-center pointer-events-none",
191
- "aria-hidden": "true",
192
- inert: true,
193
- children: endIcon
194
- }
195
- )
196
- ]
285
+ children: /* @__PURE__ */ jsx2(
286
+ ButtonContent,
287
+ {
288
+ layout: variants.layout,
289
+ size,
290
+ iconMotion,
291
+ startIcon,
292
+ endIcon,
293
+ children
294
+ }
295
+ )
197
296
  }
198
297
  );
199
298
  };
200
299
 
201
- // src/button/download.ts
202
- var downloadBlob = (blob, filename) => {
203
- const url = URL.createObjectURL(blob);
204
- const link = document.createElement("a");
205
- link.href = url;
206
- link.download = filename;
207
- document.body.appendChild(link);
208
- link.click();
209
- link.remove();
210
- window.setTimeout(() => {
211
- URL.revokeObjectURL(url);
212
- }, 3e4);
213
- };
214
-
215
300
  // src/button-link/button-link.tsx
216
- import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
301
+ import { jsx as jsx3 } from "react/jsx-runtime";
217
302
  var ButtonLink = (props) => {
218
303
  const {
219
304
  variant = "secondary",
220
305
  size,
221
306
  layout,
307
+ iconMotion,
222
308
  className,
223
309
  children,
224
310
  startIcon,
@@ -228,38 +314,30 @@ var ButtonLink = (props) => {
228
314
  const variants = variant === "text" || variant === "underlined" ? {
229
315
  variant,
230
316
  size,
231
- layout: "standard"
317
+ layout: "standard",
318
+ iconMotion
232
319
  } : {
233
320
  variant,
234
321
  size,
235
- layout
322
+ layout,
323
+ iconMotion
236
324
  };
237
- return /* @__PURE__ */ jsxs2(
325
+ return /* @__PURE__ */ jsx3(
238
326
  "a",
239
327
  {
240
328
  ...restProps,
241
329
  className: buttonClass(variants, className),
242
- children: [
243
- startIcon !== void 0 && startIcon !== null && typeof startIcon !== "boolean" && /* @__PURE__ */ jsx2(
244
- "span",
245
- {
246
- className: "gridui-button-adornment inline-flex shrink-0 items-center pointer-events-none",
247
- "aria-hidden": "true",
248
- inert: true,
249
- children: startIcon
250
- }
251
- ),
252
- children,
253
- endIcon !== void 0 && endIcon !== null && typeof endIcon !== "boolean" && /* @__PURE__ */ jsx2(
254
- "span",
255
- {
256
- className: "gridui-button-adornment inline-flex shrink-0 items-center pointer-events-none",
257
- "aria-hidden": "true",
258
- inert: true,
259
- children: endIcon
260
- }
261
- )
262
- ]
330
+ children: /* @__PURE__ */ jsx3(
331
+ ButtonContent,
332
+ {
333
+ layout: variants.layout,
334
+ size,
335
+ iconMotion,
336
+ startIcon,
337
+ endIcon,
338
+ children
339
+ }
340
+ )
263
341
  }
264
342
  );
265
343
  };
@@ -267,7 +345,6 @@ export {
267
345
  Button,
268
346
  ButtonLink,
269
347
  buttonClass,
270
- downloadBlob,
271
348
  useAsyncAction
272
349
  };
273
350
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/button/async-action.ts", "../src/shared/style.ts", "../src/button/button.tsx", "../src/button/download.ts", "../src/button-link/button-link.tsx"],
4
- "sourcesContent": ["/**\n * @author WMXPY\n * @package Button\n * @namespace Button\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 Shared\n * @description Style\n */\n\nimport { cn } from \"@gridui/style-utils\";\nimport { cva, type VariantProps } 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 gridui-interaction-boundary\",\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 gridui-interaction-boundary\",\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 const textVariant = variants.variant === \"text\" || variants.variant === \"underlined\";\n const boundaryLayout = variants.layout === \"cell\" || variants.layout === \"rail\";\n return cn(buttonVariants({\n variant: variants.variant,\n size: variants.size,\n layout: variants.layout,\n }), textVariant && \"px-0\", !textVariant && !boundaryLayout && \"gridui-hover-surface\", className);\n};\n", "/**\n * @author WMXPY\n * @package Button\n * @namespace Button\n * @description Button\n */\n\nimport { buttonClass, type ButtonVariants } from \"../shared/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", "/**\n * @author WMXPY\n * @package Button\n * @namespace Button\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", "/**\n * @author WMXPY\n * @package Button\n * @namespace ButtonLink\n * @description Button Link\n */\n\nimport { buttonClass, type ButtonVariants } from \"../shared/style\";\nimport type { ComponentPropsWithRef, FC, ReactNode } from \"react\";\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"],
5
- "mappings": "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",
6
- "names": ["jsx", "jsxs"]
3
+ "sources": ["../src/button/async-action.ts", "../src/shared/style.ts", "../src/shared/content.tsx", "../src/button/button.tsx", "../src/button-link/button-link.tsx"],
4
+ "sourcesContent": ["/**\n * @author WMXPY\n * @package Button\n * @namespace Button\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 Shared\n * @description Style\n */\n\nimport { cn } from \"@gridui/style-utils\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nexport const buttonStyles = cva(cn(\n \"gridui-button\",\n \"gridui-u-inline-flex gridui-u-w-fit gridui-u-max-w-full gridui-u-min-w-0 gridui-u-items-center gridui-u-justify-center gridui-u-gap-gridui-8 gridui-u-border gridui-u-border-solid gridui-u-border-transparent gridui-u-rounded-control gridui-u-type-ui gridui-u-text-center gridui-u-no-underline gridui-u-wrap-anywhere gridui-u-cursor-pointer gridui-u-transition-colors gridui-u-duration-(--gridui-motion-duration-quick) gridui-u-ease-(--gridui-motion-ease-out)\",\n \"gridui-u-[&_svg]:w-gridui-16 gridui-u-[&_svg]:h-gridui-16 gridui-u-[&_svg]:shrink-0 gridui-u-[&_svg]:pointer-events-none\",\n \"gridui-u-disabled:opacity-50 gridui-u-disabled:cursor-not-allowed\",\n \"gridui-u-aria-disabled:opacity-50 gridui-u-aria-disabled:cursor-not-allowed\",\n \"gridui-u-data-disabled:opacity-50 gridui-u-data-disabled:cursor-not-allowed\",\n \"gridui-u-motion-reduce:transition-none\",\n));\n\nexport const buttonStandardStyles = cva(cn(\n \"gridui-button-standard\",\n \"gridui-u-min-h-11 gridui-u-py-gridui-8 gridui-u-px-gridui-16\",\n));\n\nexport const buttonSmallStyles = cva(cn(\n \"gridui-button-small\",\n \"gridui-u-min-h-9 gridui-u-py-gridui-4 gridui-u-px-gridui-8\",\n));\n\nexport const buttonLargeStyles = cva(cn(\n \"gridui-button-large\",\n \"gridui-u-min-h-12 gridui-u-py-gridui-8 gridui-u-px-gridui-24 gridui-u-[&_svg]:w-5 gridui-u-[&_svg]:h-5\",\n));\n\nexport const buttonExtraLargeStyles = cva(cn(\n \"gridui-button-extra-large\",\n \"gridui-u-min-h-18 gridui-u-py-gridui-16 gridui-u-px-gridui-24 gridui-u-[&_svg]:w-5 gridui-u-[&_svg]:h-5\",\n));\n\nexport const buttonPrimaryStyles = cva(cn(\n \"gridui-button-primary\",\n \"gridui-u-text-accent-foreground gridui-u-bg-accent-background gridui-u-border-accent-background\",\n));\n\nexport const buttonSecondaryStyles = cva(cn(\n \"gridui-button-secondary\",\n \"gridui-u-text-foreground gridui-u-bg-transparent gridui-u-border-border\",\n));\n\nexport const buttonQuietStyles = cva(cn(\n \"gridui-button-quiet\",\n \"gridui-u-text-foreground gridui-u-bg-transparent\",\n));\n\nexport const buttonHighlightStyles = cva(cn(\n \"gridui-button-highlight\",\n \"gridui-u-text-foreground gridui-u-bg-brand-tint\",\n));\n\nexport const buttonTextStyles = cva(cn(\n \"gridui-button-text\",\n \"gridui-u-text-foreground gridui-u-bg-transparent gridui-u-border-0 gridui-u-rounded-none\",\n));\n\nexport const buttonUnderlinedStyles = cva(cn(\n \"gridui-button-underlined\",\n \"gridui-u-text-foreground gridui-u-bg-transparent gridui-u-border-0 gridui-u-border-b gridui-u-border-foreground gridui-u-rounded-none\",\n));\n\nexport const buttonEntryStyles = cva(cn(\n \"gridui-button-entry\",\n \"gridui-u-justify-between gridui-u-w-full gridui-u-py-gridui-16 gridui-u-px-gridui-24\",\n));\n\nexport const buttonCellStyles = cva(cn(\n \"gridui-button-cell gridui-interaction-boundary\",\n \"gridui-u-w-full gridui-u-h-full gridui-u-justify-start gridui-u-rounded-none gridui-u-border-0 gridui-u-py-gridui-16 gridui-u-px-gridui-24 gridui-u-text-left\",\n));\n\nexport const buttonRailStyles = cva(cn(\n \"gridui-button-rail gridui-interaction-boundary\",\n \"gridui-u-w-full gridui-u-min-w-gridui-24 gridui-u-flex-col gridui-u-py-gridui-8 gridui-u-px-0\",\n \"gridui-u-[&_>_span]:[writing-mode:vertical-rl] gridui-u-[&_>_span]:whitespace-nowrap\",\n));\n\nexport const buttonIconStyles = cva(cn(\n \"gridui-button-icon\",\n \"gridui-u-w-11 gridui-u-h-11 gridui-u-shrink-0 gridui-u-p-0\",\n \"gridui-u-[&.gridui-button-small]:w-9 gridui-u-[&.gridui-button-small]:h-9\",\n \"gridui-u-[&.gridui-button-large]:w-12 gridui-u-[&.gridui-button-large]:h-12\",\n \"gridui-u-[&.gridui-button-extra-large]:w-18 gridui-u-[&.gridui-button-extra-large]:h-18\",\n \"gridui-u-pointer-coarse:[&.gridui-button-small]:w-11 gridui-u-pointer-coarse:[&.gridui-button-small]:h-11\",\n));\n\nexport const buttonDividedStyles = cva(cn(\n \"gridui-button-divided\",\n \"gridui-u-w-full gridui-u-items-stretch gridui-u-justify-between gridui-u-gap-0 gridui-u-rounded-none gridui-u-p-0 gridui-u-text-start\",\n));\n\nexport const buttonLabelStyles = cva(cn(\n \"gridui-button-label\",\n \"gridui-u-inline-flex gridui-u-min-w-0 gridui-u-flex-1 gridui-u-items-center gridui-u-gap-gridui-8\",\n), {\n variants: {\n size: {\n small: \"gridui-u-py-gridui-4 gridui-u-px-gridui-8\",\n standard: \"gridui-u-py-gridui-8 gridui-u-px-gridui-16\",\n large: \"gridui-u-py-gridui-8 gridui-u-px-gridui-24\",\n \"extra-large\": \"gridui-u-py-gridui-16 gridui-u-px-gridui-24\",\n },\n },\n defaultVariants: { size: \"standard\" },\n});\n\nexport const buttonEndRegionStyles = cva(cn(\n \"gridui-button-end-region\",\n \"gridui-u-justify-center gridui-u-self-stretch gridui-u-border-s gridui-u-border-solid gridui-u-border-current/25\",\n), {\n variants: {\n size: {\n small: \"gridui-u-w-9\",\n standard: \"gridui-u-w-11\",\n large: \"gridui-u-w-12\",\n \"extra-large\": \"gridui-u-w-gridui-64\",\n },\n },\n defaultVariants: { size: \"standard\" },\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 large: buttonLargeStyles(),\n \"extra-large\": buttonExtraLargeStyles(),\n },\n layout: {\n standard: \"\",\n icon: buttonIconStyles(),\n entry: buttonEntryStyles(),\n cell: buttonCellStyles(),\n rail: buttonRailStyles(),\n divided: buttonDividedStyles(),\n },\n iconMotion: {\n none: \"\",\n outward: \"gridui-button-icon-motion-outward\",\n },\n },\n compoundVariants: [\n {\n variant: [\n \"text\",\n \"underlined\",\n ],\n size: [\n \"large\",\n \"extra-large\",\n ],\n className: \"gridui-u-gap-gridui-32 gridui-u-type-supporting\",\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 const textVariant = variants.variant === \"text\" || variants.variant === \"underlined\";\n return cn(buttonVariants({\n variant: variants.variant,\n size: variants.size,\n layout: variants.layout,\n iconMotion: variants.iconMotion,\n }), textVariant && \"gridui-u-px-0\", className);\n};\n", "/**\n * @author WMXPY\n * @package Button\n * @namespace Shared\n * @description Content\n */\n\nimport { buttonEndRegionStyles, buttonLabelStyles, type ButtonVariants } from \"./style\";\nimport { cn } from \"@gridui/style-utils\";\nimport type { FC, ReactNode } from \"react\";\n\nexport type ButtonContentProps = {\n readonly children?: ReactNode;\n readonly startIcon?: ReactNode;\n readonly endIcon?: ReactNode;\n readonly layout?: ButtonVariants[\"layout\"];\n readonly size?: ButtonVariants[\"size\"];\n readonly iconMotion?: ButtonVariants[\"iconMotion\"];\n};\n\nexport const ButtonContent: FC<ButtonContentProps> = (props: ButtonContentProps) => {\n const { children, startIcon, endIcon, layout, size, iconMotion } = props;\n const label = (<>\n {startIcon !== undefined && startIcon !== null && typeof startIcon !== \"boolean\" && (<span\n className=\"gridui-button-adornment gridui-u-inline-flex gridui-u-shrink-0 gridui-u-items-center gridui-u-pointer-events-none\"\n aria-hidden=\"true\"\n inert\n >\n {startIcon}\n </span>)}\n {children}\n </>);\n\n return (<>\n {layout === \"divided\" ? (<span\n className={buttonLabelStyles({ size })}\n >\n {label}\n </span>) : label}\n {endIcon !== undefined && endIcon !== null && typeof endIcon !== \"boolean\" && (<span\n className={cn(\n \"gridui-button-adornment gridui-u-inline-flex gridui-u-shrink-0 gridui-u-items-center gridui-u-pointer-events-none\",\n layout === \"divided\" && buttonEndRegionStyles({ size }),\n )}\n aria-hidden=\"true\"\n inert\n >\n {iconMotion === \"outward\" ? (<span\n className=\"gridui-button-end-icon gridui-u-inline-flex\"\n >\n {endIcon}\n </span>) : endIcon}\n </span>)}\n </>);\n};\n", "/**\n * @author WMXPY\n * @package Button\n * @namespace Button\n * @description Button\n */\n\nimport { ButtonContent } from \"../shared/content\";\nimport { buttonClass, type ButtonVariants } from \"../shared/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 iconMotion,\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 iconMotion,\n } : {\n variant,\n size,\n layout,\n iconMotion,\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 <ButtonContent\n layout={variants.layout}\n size={size}\n iconMotion={iconMotion}\n startIcon={startIcon}\n endIcon={endIcon}\n >\n {children}\n </ButtonContent>\n </button>);\n};\n", "/**\n * @author WMXPY\n * @package Button\n * @namespace ButtonLink\n * @description Button Link\n */\n\nimport { ButtonContent } from \"../shared/content\";\nimport { buttonClass, type ButtonVariants } from \"../shared/style\";\nimport type { ComponentPropsWithRef, FC, ReactNode } from \"react\";\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 iconMotion,\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 iconMotion,\n } : {\n variant,\n size,\n layout,\n iconMotion,\n };\n return (<a\n {...restProps}\n className={buttonClass(variants, className)}\n >\n <ButtonContent\n layout={variants.layout}\n size={size}\n iconMotion={iconMotion}\n startIcon={startIcon}\n endIcon={endIcon}\n >\n {children}\n </ButtonContent>\n </a>);\n};\n"],
5
+ "mappings": "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",
6
+ "names": ["cn", "jsx", "jsx"]
7
7
  }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @author WMXPY
3
+ * @package Button
4
+ * @namespace Shared
5
+ * @description Content
6
+ */
7
+ import { type ButtonVariants } from "./style";
8
+ import type { FC, ReactNode } from "react";
9
+ export type ButtonContentProps = {
10
+ readonly children?: ReactNode;
11
+ readonly startIcon?: ReactNode;
12
+ readonly endIcon?: ReactNode;
13
+ readonly layout?: ButtonVariants["layout"];
14
+ readonly size?: ButtonVariants["size"];
15
+ readonly iconMotion?: ButtonVariants["iconMotion"];
16
+ };
17
+ export declare const ButtonContent: FC<ButtonContentProps>;
@@ -8,6 +8,8 @@ import { type VariantProps } from "class-variance-authority";
8
8
  export declare const buttonStyles: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
9
9
  export declare const buttonStandardStyles: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
10
10
  export declare const buttonSmallStyles: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
11
+ export declare const buttonLargeStyles: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
12
+ export declare const buttonExtraLargeStyles: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
11
13
  export declare const buttonPrimaryStyles: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
12
14
  export declare const buttonSecondaryStyles: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
13
15
  export declare const buttonQuietStyles: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
@@ -18,10 +20,18 @@ export declare const buttonEntryStyles: (props?: import("class-variance-authorit
18
20
  export declare const buttonCellStyles: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
19
21
  export declare const buttonRailStyles: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
20
22
  export declare const buttonIconStyles: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
23
+ export declare const buttonDividedStyles: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
24
+ export declare const buttonLabelStyles: (props?: ({
25
+ size?: "small" | "standard" | "large" | "extra-large" | null | undefined;
26
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
27
+ export declare const buttonEndRegionStyles: (props?: ({
28
+ size?: "small" | "standard" | "large" | "extra-large" | null | undefined;
29
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
21
30
  export declare const buttonVariants: (props?: ({
22
31
  variant?: "primary" | "secondary" | "quiet" | "highlight" | "text" | "underlined" | null | undefined;
23
- size?: "small" | "standard" | null | undefined;
24
- layout?: "standard" | "icon" | "entry" | "cell" | "rail" | null | undefined;
32
+ size?: "small" | "standard" | "large" | "extra-large" | null | undefined;
33
+ layout?: "standard" | "icon" | "entry" | "cell" | "rail" | "divided" | null | undefined;
34
+ iconMotion?: "none" | "outward" | null | undefined;
25
35
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
26
36
  type ButtonStyleVariants = VariantProps<typeof buttonVariants>;
27
37
  export type ButtonVariants = Omit<ButtonStyleVariants, "variant" | "layout"> & ({
package/dist/styles.css CHANGED
@@ -9,219 +9,300 @@
9
9
  }
10
10
  }
11
11
  @layer utilities {
12
- .pointer-events-none {
12
+ .gridui-u-pointer-events-none {
13
13
  pointer-events: none;
14
14
  }
15
- .inline-flex {
15
+ .gridui-u-inline-flex {
16
16
  display: inline-flex;
17
17
  }
18
- .h-11 {
18
+ .gridui-u-h-11 {
19
19
  height: calc(var(--spacing) * 11);
20
20
  }
21
- .h-full {
21
+ .gridui-u-h-full {
22
22
  height: 100%;
23
23
  }
24
- .min-h-9 {
24
+ .gridui-u-min-h-9 {
25
25
  min-height: calc(var(--spacing) * 9);
26
26
  }
27
- .min-h-11 {
27
+ .gridui-u-min-h-11 {
28
28
  min-height: calc(var(--spacing) * 11);
29
29
  }
30
- .w-11 {
30
+ .gridui-u-min-h-12 {
31
+ min-height: calc(var(--spacing) * 12);
32
+ }
33
+ .gridui-u-min-h-18 {
34
+ min-height: calc(var(--spacing) * 18);
35
+ }
36
+ .gridui-u-w-9 {
37
+ width: calc(var(--spacing) * 9);
38
+ }
39
+ .gridui-u-w-11 {
31
40
  width: calc(var(--spacing) * 11);
32
41
  }
33
- .w-fit {
42
+ .gridui-u-w-12 {
43
+ width: calc(var(--spacing) * 12);
44
+ }
45
+ .gridui-u-w-fit {
34
46
  width: fit-content;
35
47
  }
36
- .w-full {
48
+ .gridui-u-w-full {
37
49
  width: 100%;
38
50
  }
39
- .max-w-full {
51
+ .gridui-u-w-gridui-64 {
52
+ width: var(--gridui-space-64);
53
+ }
54
+ .gridui-u-max-w-full {
40
55
  max-width: 100%;
41
56
  }
42
- .min-w-0 {
57
+ .gridui-u-min-w-0 {
43
58
  min-width: 0px;
44
59
  }
45
- .min-w-gridui-24 {
60
+ .gridui-u-min-w-gridui-24 {
46
61
  min-width: var(--gridui-space-24);
47
62
  }
48
- .shrink-0 {
63
+ .gridui-u-flex-1 {
64
+ flex: 1;
65
+ }
66
+ .gridui-u-shrink-0 {
49
67
  flex-shrink: 0;
50
68
  }
51
- .cursor-pointer {
69
+ .gridui-u-cursor-pointer {
52
70
  cursor: pointer;
53
71
  }
54
- .flex-col {
72
+ .gridui-u-flex-col {
55
73
  flex-direction: column;
56
74
  }
57
- .items-center {
75
+ .gridui-u-items-center {
58
76
  align-items: center;
59
77
  }
60
- .justify-between {
78
+ .gridui-u-items-stretch {
79
+ align-items: stretch;
80
+ }
81
+ .gridui-u-justify-between {
61
82
  justify-content: space-between;
62
83
  }
63
- .justify-center {
84
+ .gridui-u-justify-center {
64
85
  justify-content: center;
65
86
  }
66
- .justify-start {
87
+ .gridui-u-justify-start {
67
88
  justify-content: flex-start;
68
89
  }
69
- .gap-gridui-8 {
90
+ .gridui-u-gap-0 {
91
+ gap: 0px;
92
+ }
93
+ .gridui-u-gap-gridui-8 {
70
94
  gap: var(--gridui-space-8);
71
95
  }
72
- .rounded-control {
96
+ .gridui-u-gap-gridui-32 {
97
+ gap: var(--gridui-space-32);
98
+ }
99
+ .gridui-u-self-stretch {
100
+ align-self: stretch;
101
+ }
102
+ .gridui-u-rounded-control {
73
103
  border-radius: var(--gridui-control-radius);
74
104
  }
75
- .rounded-none {
105
+ .gridui-u-rounded-none {
76
106
  border-radius: 0;
77
107
  }
78
- .border {
108
+ .gridui-u-border {
79
109
  border-style: var(--tw-border-style);
80
110
  border-width: 1px;
81
111
  }
82
- .border-0 {
112
+ .gridui-u-border-0 {
83
113
  border-style: var(--tw-border-style);
84
114
  border-width: 0px;
85
115
  }
86
- .border-b {
116
+ .gridui-u-border-s {
117
+ border-inline-start-style: var(--tw-border-style);
118
+ border-inline-start-width: 1px;
119
+ }
120
+ .gridui-u-border-b {
87
121
  border-bottom-style: var(--tw-border-style);
88
122
  border-bottom-width: 1px;
89
123
  }
90
- .border-solid {
124
+ .gridui-u-border-solid {
91
125
  --tw-border-style: solid;
92
126
  border-style: solid;
93
127
  }
94
- .border-accent-background {
128
+ .gridui-u-border-accent-background {
95
129
  border-color: var(--gridui-accent-background);
96
130
  }
97
- .border-border {
131
+ .gridui-u-border-border {
98
132
  border-color: var(--gridui-border);
99
133
  }
100
- .border-foreground {
134
+ .gridui-u-border-current\/25 {
135
+ border-color: currentcolor;
136
+ @supports (color: color-mix(in lab, red, red)) {
137
+ border-color: color-mix(in oklab, currentcolor 25%, transparent);
138
+ }
139
+ }
140
+ .gridui-u-border-foreground {
101
141
  border-color: var(--gridui-foreground);
102
142
  }
103
- .border-transparent {
143
+ .gridui-u-border-transparent {
104
144
  border-color: transparent;
105
145
  }
106
- .bg-accent-background {
146
+ .gridui-u-bg-accent-background {
107
147
  background-color: var(--gridui-accent-background);
108
148
  }
109
- .bg-surface {
110
- background-color: var(--gridui-surface);
149
+ .gridui-u-bg-brand-tint {
150
+ background-color: var(--gridui-brand-tint);
111
151
  }
112
- .bg-transparent {
152
+ .gridui-u-bg-transparent {
113
153
  background-color: transparent;
114
154
  }
115
- .p-0 {
155
+ .gridui-u-p-0 {
116
156
  padding: 0px;
117
157
  }
118
- .px-0 {
158
+ .gridui-u-px-0 {
119
159
  padding-inline: 0px;
120
160
  }
121
- .px-gridui-8 {
161
+ .gridui-u-px-gridui-8 {
122
162
  padding-inline: var(--gridui-space-8);
123
163
  }
124
- .px-gridui-16 {
164
+ .gridui-u-px-gridui-16 {
125
165
  padding-inline: var(--gridui-space-16);
126
166
  }
127
- .px-gridui-24 {
167
+ .gridui-u-px-gridui-24 {
128
168
  padding-inline: var(--gridui-space-24);
129
169
  }
130
- .py-gridui-4 {
170
+ .gridui-u-py-gridui-4 {
131
171
  padding-block: var(--gridui-space-4);
132
172
  }
133
- .py-gridui-8 {
173
+ .gridui-u-py-gridui-8 {
134
174
  padding-block: var(--gridui-space-8);
135
175
  }
136
- .py-gridui-16 {
176
+ .gridui-u-py-gridui-16 {
137
177
  padding-block: var(--gridui-space-16);
138
178
  }
139
- .text-center {
179
+ .gridui-u-text-center {
140
180
  text-align: center;
141
181
  }
142
- .text-left {
182
+ .gridui-u-text-left {
143
183
  text-align: left;
144
184
  }
145
- .type-ui {
185
+ .gridui-u-text-start {
186
+ text-align: start;
187
+ }
188
+ .gridui-u-type-supporting {
189
+ font: var(--gridui-type-supporting);
190
+ letter-spacing: normal;
191
+ }
192
+ .gridui-u-type-ui {
146
193
  font: var(--gridui-type-ui);
147
194
  letter-spacing: normal;
148
195
  }
149
- .wrap-anywhere {
196
+ .gridui-u-wrap-anywhere {
150
197
  overflow-wrap: anywhere;
151
198
  }
152
- .text-accent-foreground {
199
+ .gridui-u-text-accent-foreground {
153
200
  color: var(--gridui-accent-foreground);
154
201
  }
155
- .text-foreground {
202
+ .gridui-u-text-foreground {
156
203
  color: var(--gridui-foreground);
157
204
  }
158
- .no-underline {
205
+ .gridui-u-no-underline {
159
206
  text-decoration-line: none;
160
207
  }
161
- .transition-colors {
208
+ .gridui-u-transition-colors {
162
209
  transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to;
163
210
  transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
164
211
  transition-duration: var(--tw-duration, var(--default-transition-duration));
165
212
  }
166
- .duration-\(--gridui-motion-duration-quick\) {
213
+ .gridui-u-duration-\(--gridui-motion-duration-quick\) {
167
214
  --tw-duration: var(--gridui-motion-duration-quick);
168
215
  transition-duration: var(--gridui-motion-duration-quick);
169
216
  }
170
- .ease-\(--gridui-motion-ease-out\) {
217
+ .gridui-u-ease-\(--gridui-motion-ease-out\) {
171
218
  --tw-ease: var(--gridui-motion-ease-out);
172
219
  transition-timing-function: var(--gridui-motion-ease-out);
173
220
  }
174
- .disabled\:cursor-not-allowed:disabled {
221
+ .gridui-u-disabled\:cursor-not-allowed:disabled {
222
+ cursor: not-allowed;
223
+ }
224
+ .gridui-u-disabled\:opacity-50:disabled {
225
+ opacity: 50%;
226
+ }
227
+ .gridui-u-aria-disabled\:cursor-not-allowed[aria-disabled="true"] {
228
+ cursor: not-allowed;
229
+ }
230
+ .gridui-u-aria-disabled\:opacity-50[aria-disabled="true"] {
231
+ opacity: 50%;
232
+ }
233
+ .gridui-u-data-disabled\:cursor-not-allowed[data-disabled] {
175
234
  cursor: not-allowed;
176
235
  }
177
- .disabled\:opacity-50:disabled {
236
+ .gridui-u-data-disabled\:opacity-50[data-disabled] {
178
237
  opacity: 50%;
179
238
  }
180
239
  @media (prefers-reduced-motion: reduce) {
181
- .motion-reduce\:transition-none {
240
+ .gridui-u-motion-reduce\:transition-none {
182
241
  transition-property: none;
183
242
  }
184
243
  }
185
- .\[\&_\>_span\]\:whitespace-nowrap > span {
244
+ .gridui-u-\[\&_\>_span\]\:whitespace-nowrap > span {
186
245
  white-space: nowrap;
187
246
  }
188
- .\[\&_\>_span\]\:\[writing-mode\:vertical-rl\] > span {
247
+ .gridui-u-\[\&_\>_span\]\:\[writing-mode\:vertical-rl\] > span {
189
248
  writing-mode: vertical-rl;
190
249
  }
191
- .\[\&_svg\]\:pointer-events-none svg {
250
+ .gridui-u-\[\&_svg\]\:pointer-events-none svg {
192
251
  pointer-events: none;
193
252
  }
194
- .\[\&_svg\]\:h-gridui-16 svg {
253
+ .gridui-u-\[\&_svg\]\:h-5 svg {
254
+ height: calc(var(--spacing) * 5);
255
+ }
256
+ .gridui-u-\[\&_svg\]\:h-gridui-16 svg {
195
257
  height: var(--gridui-space-16);
196
258
  }
197
- .\[\&_svg\]\:w-gridui-16 svg {
259
+ .gridui-u-\[\&_svg\]\:w-5 svg {
260
+ width: calc(var(--spacing) * 5);
261
+ }
262
+ .gridui-u-\[\&_svg\]\:w-gridui-16 svg {
198
263
  width: var(--gridui-space-16);
199
264
  }
200
- .\[\&_svg\]\:shrink-0 svg {
265
+ .gridui-u-\[\&_svg\]\:shrink-0 svg {
201
266
  flex-shrink: 0;
202
267
  }
203
- .\[\&\.gridui-button-small\]\:h-9.gridui-button-small {
268
+ .gridui-u-\[\&\.gridui-button-extra-large\]\:h-18.gridui-button-extra-large {
269
+ height: calc(var(--spacing) * 18);
270
+ }
271
+ .gridui-u-\[\&\.gridui-button-extra-large\]\:w-18.gridui-button-extra-large {
272
+ width: calc(var(--spacing) * 18);
273
+ }
274
+ .gridui-u-\[\&\.gridui-button-large\]\:h-12.gridui-button-large {
275
+ height: calc(var(--spacing) * 12);
276
+ }
277
+ .gridui-u-\[\&\.gridui-button-large\]\:w-12.gridui-button-large {
278
+ width: calc(var(--spacing) * 12);
279
+ }
280
+ .gridui-u-\[\&\.gridui-button-small\]\:h-9.gridui-button-small {
204
281
  height: calc(var(--spacing) * 9);
205
282
  }
206
- .\[\&\.gridui-button-small\]\:w-9.gridui-button-small {
283
+ .gridui-u-\[\&\.gridui-button-small\]\:w-9.gridui-button-small {
207
284
  width: calc(var(--spacing) * 9);
208
285
  }
209
286
  @media (pointer: coarse) {
210
- .pointer-coarse\:\[\&\.gridui-button-small\]\:h-11.gridui-button-small {
287
+ .gridui-u-pointer-coarse\:\[\&\.gridui-button-small\]\:h-11.gridui-button-small {
211
288
  height: calc(var(--spacing) * 11);
212
289
  }
213
- .pointer-coarse\:\[\&\.gridui-button-small\]\:w-11.gridui-button-small {
290
+ .gridui-u-pointer-coarse\:\[\&\.gridui-button-small\]\:w-11.gridui-button-small {
214
291
  width: calc(var(--spacing) * 11);
215
292
  }
216
293
  }
217
- .\[\&\:active\:not\(\:disabled\)\]\:opacity-\[0\.8\]:active:not(:disabled) {
218
- opacity: 0.8;
219
- }
220
- .\[\&\:hover\:not\(\:disabled\)\]\:border-foreground:hover:not(:disabled) {
221
- border-color: var(--gridui-foreground);
222
- }
223
- .\[\&\:hover\:not\(\:disabled\)\]\:bg-surface-hover:hover:not(:disabled) {
224
- background-color: var(--gridui-surface-hover);
294
+ }
295
+ @layer components {
296
+ @media (prefers-reduced-motion: no-preference) {
297
+ .gridui-button-icon-motion-outward:not(:disabled, [aria-disabled="true"], [data-disabled], [aria-readonly="true"], [data-readonly], [readonly]) .gridui-button-end-icon {
298
+ transition: transform var(--gridui-motion-duration-quick) var(--gridui-motion-ease-out);
299
+ }
300
+ .gridui-button-icon-motion-outward:not(:disabled, [aria-disabled="true"], [data-disabled], [aria-readonly="true"], [data-readonly], [readonly]):hover .gridui-button-end-icon {
301
+ transform: translate(var(--gridui-space-4), calc(-1 * var(--gridui-space-4)));
302
+ }
303
+ .gridui-button-icon-motion-outward:not(:disabled, [aria-disabled="true"], [data-disabled], [aria-readonly="true"], [data-readonly], [readonly]):dir(rtl):hover .gridui-button-end-icon {
304
+ transform: translate(calc(-1 * var(--gridui-space-4)), calc(-1 * var(--gridui-space-4)));
305
+ }
225
306
  }
226
307
  }
227
308
  @property --tw-border-style {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gridui/button",
3
- "version": "2.1.3",
3
+ "version": "3.0.0",
4
4
  "description": "GridUI React buttons and action helpers",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
@@ -22,8 +22,8 @@
22
22
  "access": "public"
23
23
  },
24
24
  "dependencies": {
25
- "@gridui/style-utils": "^2.1.3",
26
- "@gridui/theme": "^2.3.1",
25
+ "@gridui/style-utils": "^2.1.4",
26
+ "@gridui/theme": "^2.4.0",
27
27
  "class-variance-authority": "0.7.1"
28
28
  },
29
29
  "devDependencies": {
@@ -35,7 +35,7 @@
35
35
  "@types/react": "19.3.0",
36
36
  "@types/react-dom": "19.3.0",
37
37
  "jest": "30.5.2",
38
- "lucide-react": "1.64.0",
38
+ "lucide-react": "1.66.0",
39
39
  "react": "19.3.1",
40
40
  "react-dom": "19.3.1",
41
41
  "typescript": "6.0.3"
@@ -1,7 +0,0 @@
1
- /**
2
- * @author WMXPY
3
- * @package Button
4
- * @namespace Button
5
- * @description Download
6
- */
7
- export declare const downloadBlob: (blob: Blob, filename: string) => void;