beez-ui 0.10.0 → 2.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.
Files changed (58) hide show
  1. package/CHANGELOG.md +40 -1
  2. package/README.md +63 -16
  3. package/THIRD_PARTY_NOTICES.md +31 -0
  4. package/assets/fonts/ibmplexmono-LICENSE.txt +93 -93
  5. package/assets/fonts/{poppins-LICENSE.txt → inter-LICENSE.txt} +2 -2
  6. package/assets/fonts/inter-latin-variable.woff2 +0 -0
  7. package/dist/components/account-menu.d.ts +5 -2
  8. package/dist/components/account-menu.js +150 -145
  9. package/dist/components/alert-dialog.d.ts +4 -2
  10. package/dist/components/alert-dialog.js +78 -66
  11. package/dist/components/animated-collapse.js +106 -36
  12. package/dist/components/button-interaction.d.ts +23 -0
  13. package/dist/components/button-interaction.js +22 -0
  14. package/dist/components/button-label.d.ts +8 -0
  15. package/dist/components/button-label.js +322 -0
  16. package/dist/components/button.d.ts +23 -10
  17. package/dist/components/button.js +111 -64
  18. package/dist/components/calendar.d.ts +2 -2
  19. package/dist/components/calendar.js +4 -4
  20. package/dist/components/carousel.d.ts +3 -3
  21. package/dist/components/carousel.js +3 -3
  22. package/dist/components/control-button.d.ts +16 -0
  23. package/dist/components/control-button.js +215 -0
  24. package/dist/components/data-table.js +7 -7
  25. package/dist/components/dialog.js +3 -2
  26. package/dist/components/dropdown-menu.js +1 -1
  27. package/dist/components/file-upload.js +5 -5
  28. package/dist/components/filter-presets-bar.js +6 -6
  29. package/dist/components/filter-query-bar.js +2 -2
  30. package/dist/components/input-group.d.ts +2 -2
  31. package/dist/components/input-group.js +2 -2
  32. package/dist/components/pagination.d.ts +2 -2
  33. package/dist/components/pagination.js +2 -2
  34. package/dist/components/reaction-button.js +2 -2
  35. package/dist/components/rich-link-editor.js +7 -7
  36. package/dist/components/rich-text-content.js +1 -1
  37. package/dist/components/sheet.js +2 -2
  38. package/dist/components/sidebar-panel-context.d.ts +17 -0
  39. package/dist/components/sidebar-panel-context.js +14 -0
  40. package/dist/components/sidebar.d.ts +40 -3
  41. package/dist/components/sidebar.js +259 -103
  42. package/dist/components/typing-animation.js +1 -1
  43. package/dist/constants/button.d.ts +16 -0
  44. package/dist/constants/button.js +16 -0
  45. package/dist/hooks/use-sidebar-persistence.d.ts +1 -1
  46. package/dist/hooks/use-sidebar-persistence.js +2 -2
  47. package/dist/motion/arc-press.d.ts +6 -0
  48. package/dist/motion/arc-press.js +59 -0
  49. package/dist/motion/arc-tokens.d.ts +32 -0
  50. package/dist/motion/arc-tokens.js +42 -0
  51. package/dist/providers/beez-ui-provider.d.ts +1 -1
  52. package/dist/providers/beez-ui-provider.js +6 -1
  53. package/dist/styles.css +1 -1
  54. package/fonts.css +5 -5
  55. package/package.json +3 -2
  56. package/styles.css +4 -4
  57. package/theme.css +248 -87
  58. package/assets/fonts/poppins-latin-600.woff2 +0 -0
@@ -2,7 +2,7 @@
2
2
  import { c as _c } from "react/compiler-runtime";
3
3
  /** Expands and collapses a region by animating its height, then releases overflow. */
4
4
  import { useState } from "react";
5
- import { AnimatePresence, motion } from "motion/react";
5
+ import { AnimatePresence, motion, useIsPresent } from "motion/react";
6
6
  import { usePrefersReducedMotion } from "../hooks/use-prefers-reduced-motion.js";
7
7
  import { cn } from "../lib/utils.js";
8
8
  import { MOTION_EASE, MOTION_EASE_IN_OUT, MOTION_TIMING } from "../motion/tokens.js";
@@ -26,6 +26,94 @@ const REDUCED_MOTION_COLLAPSE_TRANSITION = {
26
26
  }
27
27
  };
28
28
  /**
29
+ * The animated region. While it collapses out it turns inert and hidden from assistive
30
+ * technology, so stale controls cannot be clicked, focused or announced during the fade.
31
+ * @param props - Content, optional wrapper attributes and whether it mounts with an entrance.
32
+ * @returns The animated region.
33
+ */
34
+ function AnimatedCollapseRegion(t0) {
35
+ const $ = _c(15);
36
+ const { children, className, id, isEntering } = t0;
37
+ const [isSettled, setIsSettled] = useState(!isEntering);
38
+ const isPresent = useIsPresent();
39
+ const shouldReduceMotion = usePrefersReducedMotion();
40
+ const t1 = isPresent ? undefined : true;
41
+ const t2 = !isPresent || undefined;
42
+ const t3 = isSettled ? "overflow-visible" : "overflow-hidden";
43
+ let t4;
44
+ if ($[0] !== className || $[1] !== t3) {
45
+ t4 = cn(t3, className);
46
+ $[0] = className;
47
+ $[1] = t3;
48
+ $[2] = t4;
49
+ } else {
50
+ t4 = $[2];
51
+ }
52
+ let t5;
53
+ let t6;
54
+ let t7;
55
+ if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
56
+ t5 = {
57
+ height: 0,
58
+ opacity: 0
59
+ };
60
+ t6 = {
61
+ height: "auto",
62
+ opacity: 1
63
+ };
64
+ t7 = {
65
+ height: 0,
66
+ opacity: 0
67
+ };
68
+ $[3] = t5;
69
+ $[4] = t6;
70
+ $[5] = t7;
71
+ } else {
72
+ t5 = $[3];
73
+ t6 = $[4];
74
+ t7 = $[5];
75
+ }
76
+ const t8 = shouldReduceMotion ? REDUCED_MOTION_COLLAPSE_TRANSITION : COLLAPSE_TRANSITION;
77
+ let t10;
78
+ let t9;
79
+ if ($[6] === Symbol.for("react.memo_cache_sentinel")) {
80
+ t9 = () => setIsSettled(false);
81
+ t10 = () => setIsSettled(true);
82
+ $[6] = t10;
83
+ $[7] = t9;
84
+ } else {
85
+ t10 = $[6];
86
+ t9 = $[7];
87
+ }
88
+ let t11;
89
+ if ($[8] !== children || $[9] !== id || $[10] !== t1 || $[11] !== t2 || $[12] !== t4 || $[13] !== t8) {
90
+ t11 = /* @__PURE__ */ _jsx(motion.div, {
91
+ "data-slot": "animated-collapse",
92
+ id,
93
+ "aria-hidden": t1,
94
+ inert: t2,
95
+ className: t4,
96
+ initial: t5,
97
+ animate: t6,
98
+ exit: t7,
99
+ transition: t8,
100
+ onAnimationStart: t9,
101
+ onAnimationComplete: t10,
102
+ children
103
+ });
104
+ $[8] = children;
105
+ $[9] = id;
106
+ $[10] = t1;
107
+ $[11] = t2;
108
+ $[12] = t4;
109
+ $[13] = t8;
110
+ $[14] = t11;
111
+ } else {
112
+ t11 = $[14];
113
+ }
114
+ return t11;
115
+ }
116
+ /**
29
117
  * Renders `children` only while `isOpen`, animating height and opacity.
30
118
  * Keep padding inside `children`: the animated wrapper collapses to zero height.
31
119
  * Overflow is clipped only while animating, so focus rings and popovers are not cut once settled.
@@ -33,55 +121,37 @@ const REDUCED_MOTION_COLLAPSE_TRANSITION = {
33
121
  * @returns The animated region, or nothing when closed.
34
122
  */
35
123
  export function AnimatedCollapse(t0) {
36
- const $ = _c(10);
124
+ const $ = _c(9);
37
125
  const { isOpen, children, className, id, animateOnMount: t1 } = t0;
38
126
  const animateOnMount = t1 === undefined ? false : t1;
39
- const [isSettled, setIsSettled] = useState(!animateOnMount);
40
- const shouldReduceMotion = usePrefersReducedMotion();
41
127
  let t2;
42
- if ($[0] !== children || $[1] !== className || $[2] !== id || $[3] !== isOpen || $[4] !== isSettled || $[5] !== shouldReduceMotion) {
43
- t2 = isOpen ? /* @__PURE__ */ _jsx(motion.div, {
44
- "data-slot": "animated-collapse",
128
+ if ($[0] !== animateOnMount || $[1] !== children || $[2] !== className || $[3] !== id || $[4] !== isOpen) {
129
+ t2 = isOpen ? /* @__PURE__ */ _jsx(AnimatedCollapseRegion, {
130
+ className,
45
131
  id,
46
- className: cn(isSettled ? "overflow-visible" : "overflow-hidden", className),
47
- initial: {
48
- height: 0,
49
- opacity: 0
50
- },
51
- animate: {
52
- height: "auto",
53
- opacity: 1
54
- },
55
- exit: {
56
- height: 0,
57
- opacity: 0
58
- },
59
- transition: shouldReduceMotion ? REDUCED_MOTION_COLLAPSE_TRANSITION : COLLAPSE_TRANSITION,
60
- onAnimationStart: () => setIsSettled(false),
61
- onAnimationComplete: () => setIsSettled(true),
132
+ isEntering: animateOnMount,
62
133
  children
63
134
  }, "animated-collapse") : null;
64
- $[0] = children;
65
- $[1] = className;
66
- $[2] = id;
67
- $[3] = isOpen;
68
- $[4] = isSettled;
69
- $[5] = shouldReduceMotion;
70
- $[6] = t2;
135
+ $[0] = animateOnMount;
136
+ $[1] = children;
137
+ $[2] = className;
138
+ $[3] = id;
139
+ $[4] = isOpen;
140
+ $[5] = t2;
71
141
  } else {
72
- t2 = $[6];
142
+ t2 = $[5];
73
143
  }
74
144
  let t3;
75
- if ($[7] !== animateOnMount || $[8] !== t2) {
145
+ if ($[6] !== animateOnMount || $[7] !== t2) {
76
146
  t3 = /* @__PURE__ */ _jsx(AnimatePresence, {
77
147
  initial: animateOnMount,
78
148
  children: t2
79
149
  });
80
- $[7] = animateOnMount;
81
- $[8] = t2;
82
- $[9] = t3;
150
+ $[6] = animateOnMount;
151
+ $[7] = t2;
152
+ $[8] = t3;
83
153
  } else {
84
- t3 = $[9];
154
+ t3 = $[8];
85
155
  }
86
156
  return t3;
87
157
  }
@@ -0,0 +1,23 @@
1
+ /** Interaction states shared by `Button` and the internal `ControlButton`. */
2
+ import type { MouseEvent } from "react";
3
+ /** Swallows activation while loading, keeping the button focusable instead of disabling it. */
4
+ declare function preventActivation(event: MouseEvent<HTMLElement>): void;
5
+ /**
6
+ * While loading, these handlers are dropped: Radix triggers open their layer from pointer and key handlers they
7
+ * inject through `asChild`, so swallowing only the click would leave a busy trigger able to open it. Keyboard focus
8
+ * stays, since nothing here touches focusability.
9
+ */
10
+ export declare const LOADING_INERT_HANDLERS: {
11
+ readonly onClick: typeof preventActivation;
12
+ readonly onPointerDown: undefined;
13
+ readonly onKeyDown: undefined;
14
+ };
15
+ /**
16
+ * Applied while a parent `AnimatePresence` removes the button, so a stale control can be neither clicked, focused
17
+ * nor announced during the exit animation.
18
+ */
19
+ export declare const LEAVING_ATTRIBUTES: {
20
+ readonly inert: true;
21
+ readonly "aria-hidden": true;
22
+ };
23
+ export {};
@@ -0,0 +1,22 @@
1
+ /** Swallows activation while loading, keeping the button focusable instead of disabling it. */
2
+ function preventActivation(event) {
3
+ event.preventDefault();
4
+ }
5
+ /**
6
+ * While loading, these handlers are dropped: Radix triggers open their layer from pointer and key handlers they
7
+ * inject through `asChild`, so swallowing only the click would leave a busy trigger able to open it. Keyboard focus
8
+ * stays, since nothing here touches focusability.
9
+ */
10
+ export const LOADING_INERT_HANDLERS = {
11
+ onClick: preventActivation,
12
+ onPointerDown: undefined,
13
+ onKeyDown: undefined
14
+ };
15
+ /**
16
+ * Applied while a parent `AnimatePresence` removes the button, so a stale control can be neither clicked, focused
17
+ * nor announced during the exit animation.
18
+ */
19
+ export const LEAVING_ATTRIBUTES = {
20
+ inert: true,
21
+ "aria-hidden": true
22
+ };
@@ -0,0 +1,8 @@
1
+ import type { ReactNode } from "react";
2
+ export type ButtonLabelProps = {
3
+ children: ReactNode;
4
+ loading: boolean;
5
+ reduceMotion: boolean;
6
+ };
7
+ /** Button content: a spinner while loading and a label whose width springs when it changes. */
8
+ export declare function ButtonLabel({ children, loading, reduceMotion }: ButtonLabelProps): import("react").JSX.Element;
@@ -0,0 +1,322 @@
1
+ "use client";
2
+ import { c as _c } from "react/compiler-runtime";
3
+ /**
4
+ * Label morph and loading spinner adapted from Arc (https://uiarc.dev), Copyright (c) 2026 Elia Kuratli,
5
+ * MIT License. The full license text ships in THIRD_PARTY_NOTICES.md. Internal to Button.
6
+ */
7
+ import { isValidElement, useEffect, useLayoutEffect, useRef } from "react";
8
+ import { AnimatePresence, animate, motion, useIsPresent, useMotionValue } from "motion/react";
9
+ import { BUTTON_MORPH_WINDOW_MS } from "../constants/button.js";
10
+ import { cn } from "../lib/utils.js";
11
+ import { ARC_BLUR, ARC_DURATION, ARC_EASE, ARC_SPRING_MORPH, ARC_SPRING_SNAPPY } from "../motion/arc-tokens.js";
12
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
13
+ const restState = {
14
+ opacity: 1,
15
+ y: 0,
16
+ scale: 1,
17
+ filter: "blur(0px)"
18
+ };
19
+ /** Outgoing labels and icons leave faster than they enter. */
20
+ const exitTransition = {
21
+ duration: ARC_DURATION.fast,
22
+ ease: [...ARC_EASE.standard]
23
+ };
24
+ /** Text rises out of a soft blur; the outgoing label lifts away a little faster. */
25
+ const textEnter = {
26
+ opacity: 0,
27
+ y: 4,
28
+ filter: `blur(${ARC_BLUR.soft}px)`
29
+ };
30
+ const textExit = {
31
+ opacity: 0,
32
+ y: -3,
33
+ filter: `blur(${ARC_BLUR.soft}px)`,
34
+ transition: exitTransition
35
+ };
36
+ const iconEnter = {
37
+ opacity: 0,
38
+ scale: .6,
39
+ filter: `blur(${ARC_BLUR.subtle}px)`
40
+ };
41
+ const iconExit = {
42
+ ...iconEnter,
43
+ transition: exitTransition
44
+ };
45
+ const reducedTransition = { duration: ARC_DURATION.instant };
46
+ const reducedEnter = {
47
+ ...restState,
48
+ opacity: 0
49
+ };
50
+ const reducedExit = {
51
+ opacity: 0,
52
+ transition: reducedTransition
53
+ };
54
+ /** Scale rides the spring; opacity and blur tween so blur never overshoots below zero. */
55
+ const iconTransition = {
56
+ ...ARC_SPRING_SNAPPY,
57
+ opacity: {
58
+ duration: ARC_DURATION.fast,
59
+ ease: [...ARC_EASE.enter]
60
+ },
61
+ filter: {
62
+ duration: ARC_DURATION.fast,
63
+ ease: [...ARC_EASE.enter]
64
+ }
65
+ };
66
+ const textTransition = {
67
+ duration: ARC_DURATION.standard,
68
+ ease: [...ARC_EASE.enter]
69
+ };
70
+ /** Matches markup tags inside a label key so icon-only labels can be detected. */
71
+ const LABEL_KEY_TAG_PATTERN = /<[^>]*>/g;
72
+ /** Detects visible text left in a label key. */
73
+ const VISIBLE_TEXT_PATTERN = /\S/;
74
+ /** Builds a key from text and element names, so a new label crossfades while prop-only updates stay in place. */
75
+ function getLabelKey(node) {
76
+ if (node == null || typeof node === "boolean") return "";
77
+ if (typeof node === "string" || typeof node === "number" || typeof node === "bigint") return String(node);
78
+ if (Array.isArray(node)) return node.map(getLabelKey).join("");
79
+ if (!isValidElement(node)) return "";
80
+ const elementType = node.type;
81
+ const elementName = typeof elementType === "string" ? elementType : elementType?.displayName ?? elementType?.name ?? "";
82
+ return `<${elementName}>${getLabelKey(node.props.children)}`;
83
+ }
84
+ /**
85
+ * Springs the label slot to the natural width of an incoming label, so a new label never snaps the
86
+ * button's size. Other resizes jump straight to the new width.
87
+ */
88
+ function useMorphWidth(contentRef, labelKey, reduceMotion) {
89
+ const $ = _c(8);
90
+ const width = useMotionValue("auto");
91
+ const lastLabelKey = useRef(labelKey);
92
+ const morphDeadline = useRef(0);
93
+ let t0;
94
+ let t1;
95
+ if ($[0] !== labelKey) {
96
+ t0 = () => {
97
+ if (lastLabelKey.current === labelKey) {
98
+ return;
99
+ }
100
+ lastLabelKey.current = labelKey;
101
+ morphDeadline.current = performance.now() + BUTTON_MORPH_WINDOW_MS;
102
+ };
103
+ t1 = [labelKey];
104
+ $[0] = labelKey;
105
+ $[1] = t0;
106
+ $[2] = t1;
107
+ } else {
108
+ t0 = $[1];
109
+ t1 = $[2];
110
+ }
111
+ useLayoutEffect(t0, t1);
112
+ let t2;
113
+ let t3;
114
+ if ($[3] !== contentRef || $[4] !== reduceMotion || $[5] !== width) {
115
+ t2 = () => {
116
+ const content = contentRef.current;
117
+ const slot = content?.parentElement;
118
+ if (!content || !slot || typeof ResizeObserver === "undefined") {
119
+ return;
120
+ }
121
+ let hasMeasured = false;
122
+ const observer = new ResizeObserver((t4) => {
123
+ const [entry] = t4;
124
+ if (!entry) {
125
+ return;
126
+ }
127
+ const nextWidth = entry.contentRect.width;
128
+ const shouldJump = !nextWidth || !hasMeasured || reduceMotion || performance.now() > morphDeadline.current;
129
+ if (shouldJump) {
130
+ hasMeasured = nextWidth > 0;
131
+ width.jump(nextWidth || "auto");
132
+ delete slot.dataset.morphing;
133
+ return;
134
+ }
135
+ slot.dataset.morphing = "";
136
+ animate(width, nextWidth, {
137
+ ...ARC_SPRING_MORPH,
138
+ onComplete: () => {
139
+ delete slot.dataset.morphing;
140
+ }
141
+ });
142
+ });
143
+ observer.observe(content);
144
+ return () => observer.disconnect();
145
+ };
146
+ t3 = [
147
+ contentRef,
148
+ reduceMotion,
149
+ width
150
+ ];
151
+ $[3] = contentRef;
152
+ $[4] = reduceMotion;
153
+ $[5] = width;
154
+ $[6] = t2;
155
+ $[7] = t3;
156
+ } else {
157
+ t2 = $[6];
158
+ t3 = $[7];
159
+ }
160
+ useEffect(t2, t3);
161
+ return width;
162
+ }
163
+ /** One generation of the label; the outgoing one is hidden from assistive tech while it leaves. */
164
+ function LabelPhase(t0) {
165
+ const $ = _c(7);
166
+ const { children, isIcon, reduceMotion, ref } = t0;
167
+ const isPresent = useIsPresent();
168
+ const t1 = isPresent ? undefined : true;
169
+ const t2 = reduceMotion ? reducedEnter : isIcon ? iconEnter : textEnter;
170
+ const t3 = reduceMotion ? reducedExit : isIcon ? iconExit : textExit;
171
+ const t4 = reduceMotion ? reducedTransition : isIcon ? iconTransition : textTransition;
172
+ let t5;
173
+ if ($[0] !== children || $[1] !== ref || $[2] !== t1 || $[3] !== t2 || $[4] !== t3 || $[5] !== t4) {
174
+ t5 = /* @__PURE__ */ _jsx(motion.span, {
175
+ ref,
176
+ className: "inline-flex items-center justify-center gap-[inherit] whitespace-nowrap",
177
+ "aria-hidden": t1,
178
+ initial: t2,
179
+ animate: restState,
180
+ exit: t3,
181
+ transition: t4,
182
+ children
183
+ });
184
+ $[0] = children;
185
+ $[1] = ref;
186
+ $[2] = t1;
187
+ $[3] = t2;
188
+ $[4] = t3;
189
+ $[5] = t4;
190
+ $[6] = t5;
191
+ } else {
192
+ t5 = $[6];
193
+ }
194
+ return t5;
195
+ }
196
+ /** Button content: a spinner while loading and a label whose width springs when it changes. */
197
+ export function ButtonLabel(t0) {
198
+ const $ = _c(25);
199
+ const { children, loading, reduceMotion } = t0;
200
+ const contentRef = useRef(null);
201
+ let t1;
202
+ if ($[0] !== children) {
203
+ t1 = getLabelKey(children);
204
+ $[0] = children;
205
+ $[1] = t1;
206
+ } else {
207
+ t1 = $[1];
208
+ }
209
+ const labelKey = t1;
210
+ const width = useMorphWidth(contentRef, labelKey, reduceMotion);
211
+ let t2;
212
+ if ($[2] !== loading || $[3] !== reduceMotion) {
213
+ t2 = loading ? /* @__PURE__ */ _jsx(motion.span, {
214
+ className: "absolute top-1/2 left-1/2 -m-2 grid size-4",
215
+ "aria-hidden": "true",
216
+ initial: reduceMotion ? { opacity: 0 } : {
217
+ opacity: 0,
218
+ scale: .6
219
+ },
220
+ animate: {
221
+ opacity: 1,
222
+ scale: 1
223
+ },
224
+ exit: reduceMotion ? reducedExit : {
225
+ ...iconExit,
226
+ scale: .8
227
+ },
228
+ transition: reduceMotion ? reducedTransition : iconTransition,
229
+ children: /* @__PURE__ */ _jsx("span", { className: "animate-spin rounded-full border-[1.5px] border-current border-r-transparent motion-reduce:animate-none" })
230
+ }, "loader") : null;
231
+ $[2] = loading;
232
+ $[3] = reduceMotion;
233
+ $[4] = t2;
234
+ } else {
235
+ t2 = $[4];
236
+ }
237
+ let t3;
238
+ if ($[5] !== t2) {
239
+ t3 = /* @__PURE__ */ _jsx(AnimatePresence, {
240
+ initial: false,
241
+ children: t2
242
+ });
243
+ $[5] = t2;
244
+ $[6] = t3;
245
+ } else {
246
+ t3 = $[6];
247
+ }
248
+ const t4 = loading && "opacity-0";
249
+ let t5;
250
+ if ($[7] !== t4) {
251
+ t5 = cn("inline-flex min-w-0 items-center justify-center gap-[inherit] transition-opacity duration-150 data-morphing:[clip-path:inset(-50%_calc(var(--spacing)*-3))]", t4);
252
+ $[7] = t4;
253
+ $[8] = t5;
254
+ } else {
255
+ t5 = $[8];
256
+ }
257
+ let t6;
258
+ if ($[9] !== width) {
259
+ t6 = { width };
260
+ $[9] = width;
261
+ $[10] = t6;
262
+ } else {
263
+ t6 = $[10];
264
+ }
265
+ let t7;
266
+ if ($[11] !== labelKey) {
267
+ t7 = VISIBLE_TEXT_PATTERN.test(labelKey.replace(LABEL_KEY_TAG_PATTERN, ""));
268
+ $[11] = labelKey;
269
+ $[12] = t7;
270
+ } else {
271
+ t7 = $[12];
272
+ }
273
+ const t8 = !t7;
274
+ let t9;
275
+ if ($[13] !== children || $[14] !== labelKey || $[15] !== reduceMotion || $[16] !== t8) {
276
+ t9 = /* @__PURE__ */ _jsx("span", {
277
+ ref: contentRef,
278
+ className: "inline-flex flex-none items-center gap-[inherit]",
279
+ children: /* @__PURE__ */ _jsx(AnimatePresence, {
280
+ mode: "popLayout",
281
+ initial: false,
282
+ children: /* @__PURE__ */ _jsx(LabelPhase, {
283
+ isIcon: t8,
284
+ reduceMotion,
285
+ children
286
+ }, labelKey)
287
+ })
288
+ });
289
+ $[13] = children;
290
+ $[14] = labelKey;
291
+ $[15] = reduceMotion;
292
+ $[16] = t8;
293
+ $[17] = t9;
294
+ } else {
295
+ t9 = $[17];
296
+ }
297
+ let t10;
298
+ if ($[18] !== t5 || $[19] !== t6 || $[20] !== t9) {
299
+ t10 = /* @__PURE__ */ _jsx(motion.span, {
300
+ "data-slot": "button-label",
301
+ className: t5,
302
+ style: t6,
303
+ children: t9
304
+ });
305
+ $[18] = t5;
306
+ $[19] = t6;
307
+ $[20] = t9;
308
+ $[21] = t10;
309
+ } else {
310
+ t10 = $[21];
311
+ }
312
+ let t11;
313
+ if ($[22] !== t10 || $[23] !== t3) {
314
+ t11 = /* @__PURE__ */ _jsxs(_Fragment, { children: [t3, t10] });
315
+ $[22] = t10;
316
+ $[23] = t3;
317
+ $[24] = t11;
318
+ } else {
319
+ t11 = $[24];
320
+ }
321
+ return t11;
322
+ }
@@ -1,10 +1,23 @@
1
- import { Button as ButtonPrimitive } from "@base-ui/react/button";
2
- import { type VariantProps } from "class-variance-authority";
3
- declare const buttonVariants: (props?: ({
4
- variant?: "default" | "destructive" | "ghost" | "link" | "outline" | "secondary" | null | undefined;
5
- size?: "default" | "icon" | "icon-lg" | "icon-sm" | "icon-xs" | "lg" | "sm" | "xs" | null | undefined;
6
- } & import("class-variance-authority/types").ClassProp) | undefined) => string;
7
- declare function Button({ className, variant, size, asChild, ...props }: ButtonPrimitive.Props & VariantProps<typeof buttonVariants> & {
8
- asChild?: boolean;
9
- }): import("react").JSX.Element;
10
- export { Button, buttonVariants };
1
+ /**
2
+ * Arc's Button (https://uiarc.dev, MIT License, see THIRD_PARTY_NOTICES.md): its variants, sizes, tokens and motion,
3
+ * with width-aware press feedback, a label that springs to its new width and a loading spinner. It renders a native
4
+ * button; style links as links instead. Composite components that need icon sizes use the internal `ControlButton`.
5
+ */
6
+ import type { ComponentProps } from "react";
7
+ /** Visual weight, as in Arc: one primary action per surface. */
8
+ export type ButtonVariant = "primary" | "secondary" | "ghost" | "danger";
9
+ /** Height and padding, from Arc's control heights. */
10
+ export type ButtonSize = "sm" | "md" | "lg";
11
+ export type ButtonProps = ComponentProps<"button"> & {
12
+ variant?: ButtonVariant;
13
+ size?: ButtonSize;
14
+ /** Shows a spinner, sets `aria-busy` and swallows clicks while keeping keyboard focus. */
15
+ loading?: boolean;
16
+ };
17
+ /**
18
+ * A single action on a page, form or dialog. Defaults to `type="button"`, so it only submits a form when asked to.
19
+ * @param props - Variant, size, loading state and native button attributes, including `ref`.
20
+ * @returns The native button.
21
+ */
22
+ declare function Button({ className, variant, size, loading, type, children, ref, ...props }: ButtonProps): import("react").JSX.Element;
23
+ export { Button };