beez-ui 0.11.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.
- package/CHANGELOG.md +36 -1
- package/README.md +62 -15
- package/THIRD_PARTY_NOTICES.md +31 -0
- package/assets/fonts/ibmplexmono-LICENSE.txt +93 -93
- package/assets/fonts/{poppins-LICENSE.txt → inter-LICENSE.txt} +2 -2
- package/assets/fonts/inter-latin-variable.woff2 +0 -0
- package/dist/components/account-menu.js +2 -2
- package/dist/components/alert-dialog.d.ts +4 -2
- package/dist/components/alert-dialog.js +78 -66
- package/dist/components/animated-collapse.js +106 -36
- package/dist/components/button-interaction.d.ts +23 -0
- package/dist/components/button-interaction.js +22 -0
- package/dist/components/button-label.d.ts +8 -0
- package/dist/components/button-label.js +322 -0
- package/dist/components/button.d.ts +23 -10
- package/dist/components/button.js +111 -64
- package/dist/components/calendar.d.ts +2 -2
- package/dist/components/calendar.js +4 -4
- package/dist/components/carousel.d.ts +3 -3
- package/dist/components/carousel.js +3 -3
- package/dist/components/control-button.d.ts +16 -0
- package/dist/components/control-button.js +215 -0
- package/dist/components/data-table.js +7 -7
- package/dist/components/dialog.js +3 -2
- package/dist/components/dropdown-menu.js +1 -1
- package/dist/components/file-upload.js +5 -5
- package/dist/components/filter-presets-bar.js +6 -6
- package/dist/components/filter-query-bar.js +2 -2
- package/dist/components/input-group.d.ts +2 -2
- package/dist/components/input-group.js +2 -2
- package/dist/components/pagination.d.ts +2 -2
- package/dist/components/pagination.js +2 -2
- package/dist/components/reaction-button.js +2 -2
- package/dist/components/rich-link-editor.js +7 -7
- package/dist/components/rich-text-content.js +1 -1
- package/dist/components/sheet.js +2 -2
- package/dist/components/sidebar.js +3 -3
- package/dist/components/typing-animation.js +1 -1
- package/dist/constants/button.d.ts +16 -0
- package/dist/constants/button.js +16 -0
- package/dist/motion/arc-press.d.ts +6 -0
- package/dist/motion/arc-press.js +59 -0
- package/dist/motion/arc-tokens.d.ts +32 -0
- package/dist/motion/arc-tokens.js +42 -0
- package/dist/providers/beez-ui-provider.d.ts +1 -1
- package/dist/providers/beez-ui-provider.js +6 -1
- package/dist/styles.css +1 -1
- package/fonts.css +5 -5
- package/package.json +3 -2
- package/styles.css +4 -4
- package/theme.css +248 -87
- package/assets/fonts/poppins-latin-600.woff2 +0 -0
|
@@ -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
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
export
|
|
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 };
|
|
@@ -1,98 +1,145 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { c as _c } from "react/compiler-runtime";
|
|
3
|
-
import { Button as ButtonPrimitive } from "@base-ui/react/button";
|
|
4
3
|
import { cva } from "class-variance-authority";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
4
|
+
import { useIsPresent } from "motion/react";
|
|
5
|
+
import { usePrefersReducedMotion } from "../hooks/use-prefers-reduced-motion.js";
|
|
7
6
|
import { cn } from "../lib/utils.js";
|
|
7
|
+
import { useArcPress } from "../motion/arc-press.js";
|
|
8
|
+
import { useAttachedElement } from "../motion/use-attached-element.js";
|
|
9
|
+
import { ButtonLabel } from "./button-label.js";
|
|
10
|
+
import { LEAVING_ATTRIBUTES, LOADING_INERT_HANDLERS } from "./button-interaction.js";
|
|
8
11
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
9
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Arc's button recipe on its tokens. Press scale is driven by Motion alone, so `transform` never gets a CSS
|
|
14
|
+
* transition, and anchors of floating layers never scale because Radix measures them on pointerdown. Keyboard focus
|
|
15
|
+
* uses the foundation's shared outline; pointer focus draws no ring.
|
|
16
|
+
*/
|
|
17
|
+
const buttonVariants = cva("relative inline-flex shrink-0 cursor-pointer items-center justify-center gap-2 rounded-(--radius-control) border border-transparent px-4 font-sans text-sm leading-(--leading-body) font-medium whitespace-nowrap select-none [-webkit-tap-highlight-color:transparent] transition-[color,background-color,border-color,opacity,box-shadow] duration-(--duration-fast) ease-(--ease-standard) disabled:cursor-not-allowed disabled:opacity-[.52] aria-busy:cursor-progress motion-reduce:transition-none [&:is([aria-haspopup]:not([aria-haspopup=false]),[data-state],[role=combobox])]:transform-none! [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", {
|
|
10
18
|
variants: {
|
|
11
19
|
variant: {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
destructive: "bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40",
|
|
17
|
-
link: "text-primary underline-offset-4 hover:underline"
|
|
20
|
+
primary: "border-foreground bg-foreground text-background hover-fine:not-disabled:opacity-[.91] hover-fine:not-disabled:shadow-(--shadow-resting) active:not-disabled:opacity-[.84]",
|
|
21
|
+
secondary: "border-border bg-surface text-foreground hover-fine:not-disabled:bg-surface-muted hover-fine:not-disabled:shadow-(--shadow-resting) active:not-disabled:bg-surface-muted disabled:bg-surface-muted disabled:text-text-muted disabled:opacity-100",
|
|
22
|
+
ghost: "bg-transparent text-text-secondary hover-fine:not-disabled:bg-surface-muted hover-fine:not-disabled:text-foreground active:not-disabled:bg-surface-muted active:not-disabled:text-foreground disabled:text-text-muted disabled:opacity-100",
|
|
23
|
+
danger: "border-border bg-surface text-danger hover-fine:not-disabled:border-danger hover-fine:not-disabled:bg-surface-muted active:not-disabled:border-danger active:not-disabled:bg-surface-muted disabled:bg-surface-muted disabled:text-[color-mix(in_oklab,var(--danger)_55%,var(--surface-muted))] disabled:opacity-100"
|
|
18
24
|
},
|
|
19
25
|
size: {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
lg: "h-9 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-3 has-data-[icon=inline-start]:pl-3",
|
|
24
|
-
icon: "size-8",
|
|
25
|
-
"icon-xs": "size-6 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3",
|
|
26
|
-
"icon-sm": "size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg",
|
|
27
|
-
"icon-lg": "size-9"
|
|
26
|
+
sm: "min-h-(--control-height-sm) px-3",
|
|
27
|
+
md: "min-h-(--control-height-md)",
|
|
28
|
+
lg: "min-h-(--control-height-lg) px-5"
|
|
28
29
|
}
|
|
29
30
|
},
|
|
30
31
|
defaultVariants: {
|
|
31
|
-
variant: "
|
|
32
|
-
size: "
|
|
32
|
+
variant: "primary",
|
|
33
|
+
size: "md"
|
|
33
34
|
}
|
|
34
35
|
});
|
|
36
|
+
/**
|
|
37
|
+
* A single action on a page, form or dialog. Defaults to `type="button"`, so it only submits a form when asked to.
|
|
38
|
+
* @param props - Variant, size, loading state and native button attributes, including `ref`.
|
|
39
|
+
* @returns The native button.
|
|
40
|
+
*/
|
|
35
41
|
function Button(t0) {
|
|
36
|
-
const $ = _c(
|
|
42
|
+
const $ = _c(29);
|
|
43
|
+
let children;
|
|
37
44
|
let className;
|
|
38
45
|
let props;
|
|
46
|
+
let ref;
|
|
39
47
|
let t1;
|
|
40
48
|
let t2;
|
|
41
49
|
let t3;
|
|
50
|
+
let t4;
|
|
42
51
|
if ($[0] !== t0) {
|
|
43
|
-
({className, variant: t1, size: t2,
|
|
52
|
+
({className, variant: t1, size: t2, loading: t3, type: t4, children, ref, ...props} = t0);
|
|
44
53
|
$[0] = t0;
|
|
45
|
-
$[1] =
|
|
46
|
-
$[2] =
|
|
47
|
-
$[3] =
|
|
48
|
-
$[4] =
|
|
49
|
-
$[5] =
|
|
54
|
+
$[1] = children;
|
|
55
|
+
$[2] = className;
|
|
56
|
+
$[3] = props;
|
|
57
|
+
$[4] = ref;
|
|
58
|
+
$[5] = t1;
|
|
59
|
+
$[6] = t2;
|
|
60
|
+
$[7] = t3;
|
|
61
|
+
$[8] = t4;
|
|
50
62
|
} else {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
63
|
+
children = $[1];
|
|
64
|
+
className = $[2];
|
|
65
|
+
props = $[3];
|
|
66
|
+
ref = $[4];
|
|
67
|
+
t1 = $[5];
|
|
68
|
+
t2 = $[6];
|
|
69
|
+
t3 = $[7];
|
|
70
|
+
t4 = $[8];
|
|
56
71
|
}
|
|
57
|
-
const variant = t1 === undefined ? "
|
|
58
|
-
const size = t2 === undefined ? "
|
|
59
|
-
const
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
72
|
+
const variant = t1 === undefined ? "primary" : t1;
|
|
73
|
+
const size = t2 === undefined ? "md" : t2;
|
|
74
|
+
const loading = t3 === undefined ? false : t3;
|
|
75
|
+
const type = t4 === undefined ? "button" : t4;
|
|
76
|
+
const reduceMotion = usePrefersReducedMotion();
|
|
77
|
+
const isPresent = useIsPresent();
|
|
78
|
+
const [element, attach] = useAttachedElement(ref);
|
|
79
|
+
useArcPress(element, !reduceMotion);
|
|
80
|
+
let t5;
|
|
81
|
+
if ($[9] !== className || $[10] !== size || $[11] !== variant) {
|
|
82
|
+
t5 = cn(buttonVariants({
|
|
64
83
|
variant,
|
|
65
84
|
size,
|
|
66
85
|
className
|
|
67
86
|
}));
|
|
68
|
-
$[
|
|
69
|
-
$[
|
|
70
|
-
$[
|
|
71
|
-
$[
|
|
87
|
+
$[9] = className;
|
|
88
|
+
$[10] = size;
|
|
89
|
+
$[11] = variant;
|
|
90
|
+
$[12] = t5;
|
|
72
91
|
} else {
|
|
73
|
-
|
|
92
|
+
t5 = $[12];
|
|
74
93
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
94
|
+
const t6 = loading || undefined;
|
|
95
|
+
const t7 = loading || props["aria-disabled"] || undefined;
|
|
96
|
+
const t8 = loading ? LOADING_INERT_HANDLERS : undefined;
|
|
97
|
+
const t9 = isPresent ? undefined : LEAVING_ATTRIBUTES;
|
|
98
|
+
let t10;
|
|
99
|
+
if ($[13] !== children || $[14] !== loading || $[15] !== reduceMotion) {
|
|
100
|
+
t10 = /* @__PURE__ */ _jsx(ButtonLabel, {
|
|
101
|
+
loading,
|
|
102
|
+
reduceMotion,
|
|
103
|
+
children
|
|
104
|
+
});
|
|
105
|
+
$[13] = children;
|
|
106
|
+
$[14] = loading;
|
|
107
|
+
$[15] = reduceMotion;
|
|
108
|
+
$[16] = t10;
|
|
109
|
+
} else {
|
|
110
|
+
t10 = $[16];
|
|
111
|
+
}
|
|
112
|
+
let t11;
|
|
113
|
+
if ($[17] !== attach || $[18] !== props || $[19] !== size || $[20] !== t10 || $[21] !== t5 || $[22] !== t6 || $[23] !== t7 || $[24] !== t8 || $[25] !== t9 || $[26] !== type || $[27] !== variant) {
|
|
114
|
+
t11 = /* @__PURE__ */ _jsx("button", {
|
|
115
|
+
ref: attach,
|
|
116
|
+
type,
|
|
117
|
+
"data-slot": "button",
|
|
118
|
+
"data-variant": variant,
|
|
119
|
+
"data-size": size,
|
|
120
|
+
className: t5,
|
|
121
|
+
"aria-busy": t6,
|
|
122
|
+
...props,
|
|
123
|
+
"aria-disabled": t7,
|
|
124
|
+
...t8,
|
|
125
|
+
...t9,
|
|
126
|
+
children: t10
|
|
86
127
|
});
|
|
87
|
-
$[
|
|
88
|
-
$[
|
|
89
|
-
$[
|
|
90
|
-
$[
|
|
91
|
-
$[
|
|
92
|
-
$[
|
|
128
|
+
$[17] = attach;
|
|
129
|
+
$[18] = props;
|
|
130
|
+
$[19] = size;
|
|
131
|
+
$[20] = t10;
|
|
132
|
+
$[21] = t5;
|
|
133
|
+
$[22] = t6;
|
|
134
|
+
$[23] = t7;
|
|
135
|
+
$[24] = t8;
|
|
136
|
+
$[25] = t9;
|
|
137
|
+
$[26] = type;
|
|
138
|
+
$[27] = variant;
|
|
139
|
+
$[28] = t11;
|
|
93
140
|
} else {
|
|
94
|
-
|
|
141
|
+
t11 = $[28];
|
|
95
142
|
}
|
|
96
|
-
return
|
|
143
|
+
return t11;
|
|
97
144
|
}
|
|
98
|
-
export { Button
|
|
145
|
+
export { Button };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { DayPicker, type DayButton, type Locale } from "react-day-picker";
|
|
3
|
-
import {
|
|
3
|
+
import { ControlButton } from "./control-button.js";
|
|
4
4
|
declare function Calendar({ className, classNames, showOutsideDays, captionLayout, buttonVariant, locale, formatters, components, ...props }: React.ComponentProps<typeof DayPicker> & {
|
|
5
|
-
buttonVariant?: React.ComponentProps<typeof
|
|
5
|
+
buttonVariant?: React.ComponentProps<typeof ControlButton>["variant"];
|
|
6
6
|
}): React.JSX.Element;
|
|
7
7
|
declare function CalendarDayButton({ className, day, modifiers, locale, ...props }: React.ComponentProps<typeof DayButton> & {
|
|
8
8
|
locale?: Partial<Locale>;
|
|
@@ -7,7 +7,7 @@ import { animate, frame } from "motion/react";
|
|
|
7
7
|
import { usePrefersReducedMotion } from "../hooks/use-prefers-reduced-motion.js";
|
|
8
8
|
import { MOTION_EASE, MOTION_MONTH_DISTANCE, MOTION_TIMING } from "../motion/tokens.js";
|
|
9
9
|
import { cn } from "../lib/utils.js";
|
|
10
|
-
import {
|
|
10
|
+
import { ControlButton, controlButtonVariants } from "./control-button.js";
|
|
11
11
|
import { ChevronLeft, ChevronRight, ChevronDown } from "lucide-react";
|
|
12
12
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
13
13
|
function Calendar(t0) {
|
|
@@ -75,8 +75,8 @@ function Calendar(t0) {
|
|
|
75
75
|
const t9 = cn("relative flex flex-col gap-4 md:flex-row", defaultClassNames.months);
|
|
76
76
|
const t10 = cn("flex w-full flex-col gap-4", defaultClassNames.month);
|
|
77
77
|
const t11 = cn("absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1", defaultClassNames.nav);
|
|
78
|
-
const t12 = cn(
|
|
79
|
-
const t13 = cn(
|
|
78
|
+
const t12 = cn(controlButtonVariants({ variant: buttonVariant }), "size-(--cell-size) p-0 select-none aria-disabled:opacity-50", defaultClassNames.button_previous);
|
|
79
|
+
const t13 = cn(controlButtonVariants({ variant: buttonVariant }), "size-(--cell-size) p-0 select-none aria-disabled:opacity-50", defaultClassNames.button_next);
|
|
80
80
|
const t14 = cn("flex h-(--cell-size) w-full items-center justify-center px-(--cell-size)", defaultClassNames.month_caption);
|
|
81
81
|
const t15 = cn("flex h-(--cell-size) w-full items-center justify-center gap-1.5 text-sm font-medium", defaultClassNames.dropdowns);
|
|
82
82
|
const t16 = cn("relative rounded-(--cell-radius)", defaultClassNames.dropdown_root);
|
|
@@ -390,7 +390,7 @@ function CalendarDayButton(t0) {
|
|
|
390
390
|
t2 = $[8];
|
|
391
391
|
}
|
|
392
392
|
React.useEffect(t1, t2);
|
|
393
|
-
const T0 =
|
|
393
|
+
const T0 = ControlButton;
|
|
394
394
|
const t3 = "ghost";
|
|
395
395
|
const t4 = "icon";
|
|
396
396
|
let t5;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import useEmblaCarousel, { type UseEmblaCarouselType } from "embla-carousel-react";
|
|
3
|
-
import {
|
|
3
|
+
import { ControlButton } from "./control-button.js";
|
|
4
4
|
type CarouselApi = UseEmblaCarouselType[1];
|
|
5
5
|
type UseCarouselParameters = Parameters<typeof useEmblaCarousel>;
|
|
6
6
|
type CarouselOptions = UseCarouselParameters[0];
|
|
@@ -23,6 +23,6 @@ declare function useCarousel(): CarouselContextProps;
|
|
|
23
23
|
declare function Carousel({ orientation, opts, setApi, plugins, className, children, ...props }: React.ComponentProps<"div"> & CarouselProps): React.JSX.Element;
|
|
24
24
|
declare function CarouselContent({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
|
|
25
25
|
declare function CarouselItem({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
|
|
26
|
-
declare function CarouselPrevious({ className, variant, size, ...props }: React.ComponentProps<typeof
|
|
27
|
-
declare function CarouselNext({ className, variant, size, ...props }: React.ComponentProps<typeof
|
|
26
|
+
declare function CarouselPrevious({ className, variant, size, ...props }: React.ComponentProps<typeof ControlButton>): React.JSX.Element;
|
|
27
|
+
declare function CarouselNext({ className, variant, size, ...props }: React.ComponentProps<typeof ControlButton>): React.JSX.Element;
|
|
28
28
|
export { type CarouselApi, Carousel, CarouselContent, CarouselItem, CarouselPrevious, CarouselNext, useCarousel, };
|
|
@@ -4,7 +4,7 @@ import * as React from "react";
|
|
|
4
4
|
import useEmblaCarousel from "embla-carousel-react";
|
|
5
5
|
import { usePrefersReducedMotion } from "../hooks/use-prefers-reduced-motion.js";
|
|
6
6
|
import { cn } from "../lib/utils.js";
|
|
7
|
-
import {
|
|
7
|
+
import { ControlButton } from "./control-button.js";
|
|
8
8
|
import { ChevronLeftIcon, ChevronRightIcon } from "lucide-react";
|
|
9
9
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
10
10
|
/** Arrow keys that move to the previous and next slide along each axis. */
|
|
@@ -389,7 +389,7 @@ function CarouselPrevious(t0) {
|
|
|
389
389
|
}
|
|
390
390
|
let t8;
|
|
391
391
|
if ($[10] !== props || $[11] !== scrollPrev || $[12] !== size || $[13] !== t4 || $[14] !== t5 || $[15] !== variant) {
|
|
392
|
-
t8 = /* @__PURE__ */ _jsxs(
|
|
392
|
+
t8 = /* @__PURE__ */ _jsxs(ControlButton, {
|
|
393
393
|
"data-slot": "carousel-previous",
|
|
394
394
|
variant,
|
|
395
395
|
size,
|
|
@@ -460,7 +460,7 @@ function CarouselNext(t0) {
|
|
|
460
460
|
}
|
|
461
461
|
let t8;
|
|
462
462
|
if ($[10] !== props || $[11] !== scrollNext || $[12] !== size || $[13] !== t4 || $[14] !== t5 || $[15] !== variant) {
|
|
463
|
-
t8 = /* @__PURE__ */ _jsxs(
|
|
463
|
+
t8 = /* @__PURE__ */ _jsxs(ControlButton, {
|
|
464
464
|
"data-slot": "carousel-next",
|
|
465
465
|
variant,
|
|
466
466
|
size,
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Button as ButtonPrimitive } from "@base-ui/react/button";
|
|
2
|
+
import { type VariantProps } from "class-variance-authority";
|
|
3
|
+
/**
|
|
4
|
+
* Class recipe. Press scale is driven by Motion alone, so `transform` never gets a CSS transition,
|
|
5
|
+
* and anchors of floating layers never scale because Radix measures them on pointerdown.
|
|
6
|
+
*/
|
|
7
|
+
declare const controlButtonVariants: (props?: ({
|
|
8
|
+
variant?: "default" | "destructive" | "ghost" | "link" | "outline" | "secondary" | null | undefined;
|
|
9
|
+
size?: "default" | "icon" | "icon-lg" | "icon-sm" | "icon-xs" | "lg" | "sm" | "xs" | null | undefined;
|
|
10
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
11
|
+
declare function ControlButton({ className, variant, size, asChild, loading, children, ref, ...props }: ButtonPrimitive.Props & VariantProps<typeof controlButtonVariants> & {
|
|
12
|
+
asChild?: boolean;
|
|
13
|
+
/** Shows a spinner, sets `aria-busy` and swallows clicks while keeping keyboard focus. */
|
|
14
|
+
loading?: boolean;
|
|
15
|
+
}): import("react").JSX.Element;
|
|
16
|
+
export { ControlButton, controlButtonVariants };
|