@astra-kit/ui 1.0.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +14 -3
  3. package/THIRD_PARTY_NOTICES.md +1 -1
  4. package/dist/components/button-link.d.ts +15 -0
  5. package/dist/components/button-link.js +70 -0
  6. package/dist/components/button-recipe.d.ts +27 -0
  7. package/dist/components/button-recipe.js +44 -0
  8. package/dist/components/button.d.ts +3 -5
  9. package/dist/components/button.js +1 -25
  10. package/dist/components/empty-state.d.ts +20 -0
  11. package/dist/components/empty-state.js +357 -0
  12. package/dist/components/metric-card.d.ts +22 -0
  13. package/dist/components/metric-card.js +378 -0
  14. package/dist/components/radio-group.d.ts +5 -3
  15. package/dist/components/radio-group.js +88 -85
  16. package/dist/components/stepper.d.ts +39 -0
  17. package/dist/components/stepper.js +693 -0
  18. package/dist/components/timeline.d.ts +51 -0
  19. package/dist/components/timeline.js +1013 -0
  20. package/dist/components/usage-meter.d.ts +39 -0
  21. package/dist/components/usage-meter.js +1093 -0
  22. package/dist/constants/empty-state.d.ts +12 -0
  23. package/dist/constants/empty-state.js +12 -0
  24. package/dist/constants/metric-card.d.ts +12 -0
  25. package/dist/constants/metric-card.js +12 -0
  26. package/dist/constants/stepper.d.ts +52 -0
  27. package/dist/constants/stepper.js +23 -0
  28. package/dist/constants/timeline.d.ts +62 -0
  29. package/dist/constants/timeline.js +31 -0
  30. package/dist/constants/usage-meter.d.ts +100 -0
  31. package/dist/constants/usage-meter.js +38 -0
  32. package/dist/hooks/use-has-entered-view.d.ts +9 -0
  33. package/dist/hooks/use-has-entered-view.js +46 -0
  34. package/dist/index.d.ts +7 -0
  35. package/dist/index.js +8 -0
  36. package/dist/motion/arc-odometer.d.ts +53 -0
  37. package/dist/motion/arc-odometer.js +424 -0
  38. package/dist/motion/arc-text-swap.d.ts +22 -0
  39. package/dist/motion/arc-text-swap.js +142 -0
  40. package/dist/motion/arc-tokens.d.ts +1 -0
  41. package/dist/motion/arc-tokens.js +2 -1
  42. package/dist/styles.css +1 -1
  43. package/package.json +31 -1
@@ -0,0 +1,693 @@
1
+ "use client";
2
+ import { c as _c } from "react/compiler-runtime";
3
+ /**
4
+ * Arc's Stepper (https://uiarc.dev, MIT License, see THIRD_PARTY_NOTICES.md): shows where a person is in a multi-step
5
+ * flow and what is done. Driven by `current`; with `onStepSelect` people can go back to completed steps by click or
6
+ * keyboard. Connectors fill one after another when progress jumps several steps, the ring then grows around the new
7
+ * current marker, and numbers morph into drawn checks or alerts.
8
+ */
9
+ import { useEffect, useLayoutEffect, useRef, useState } from "react";
10
+ import { AnimatePresence, animate, motion, useMotionValue } from "motion/react";
11
+ import { STEPPER_ALERT_DOT_DELAY_S, STEPPER_DEFAULT_COMPLETE_LABEL, STEPPER_DEFAULT_LABEL, STEPPER_DEFAULT_MESSAGES, STEPPER_GLYPH_DRAW_DELAY_S, STEPPER_GLYPH_ENTER_SCALE, STEPPER_RING_DELAY_S, STEPPER_RING_ENTER_SCALE, STEPPER_TEXT_MORPH_WINDOW_MS } from "../constants/stepper.js";
12
+ import { usePrefersReducedMotion } from "../hooks/use-prefers-reduced-motion.js";
13
+ import { cn } from "../lib/utils.js";
14
+ import { ArcTextSwap } from "../motion/arc-text-swap.js";
15
+ import { ARC_BLUR, ARC_DURATION, ARC_EASE, ARC_SPRING_SMOOTH, ARC_SPRING_SNAPPY, ARC_STAGGER } from "../motion/arc-tokens.js";
16
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
17
+ const still = { duration: 0 };
18
+ const leave = {
19
+ duration: ARC_DURATION.fast,
20
+ ease: [...ARC_EASE.standard]
21
+ };
22
+ const glyphFrom = {
23
+ opacity: 0,
24
+ scale: STEPPER_GLYPH_ENTER_SCALE,
25
+ filter: `blur(${ARC_BLUR.subtle}px)`
26
+ };
27
+ const glyphRest = {
28
+ opacity: 1,
29
+ scale: 1,
30
+ filter: "blur(0px)"
31
+ };
32
+ /**
33
+ * Text that rises in when it changes. Its slot springs to the new height, so a message that wraps eases the steps below
34
+ * it down instead of pushing them; unrelated resizes (fonts, container width) follow exactly.
35
+ */
36
+ function SwapSlot(t0) {
37
+ const $ = _c(18);
38
+ const { text, className, reduceMotion } = t0;
39
+ const inner = useRef(null);
40
+ const armedUntil = useRef(0);
41
+ const height = useMotionValue("auto");
42
+ let t1;
43
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
44
+ t1 = () => {
45
+ armedUntil.current = performance.now() + STEPPER_TEXT_MORPH_WINDOW_MS;
46
+ };
47
+ $[0] = t1;
48
+ } else {
49
+ t1 = $[0];
50
+ }
51
+ let t2;
52
+ if ($[1] !== text) {
53
+ t2 = [text];
54
+ $[1] = text;
55
+ $[2] = t2;
56
+ } else {
57
+ t2 = $[2];
58
+ }
59
+ useLayoutEffect(t1, t2);
60
+ let t3;
61
+ let t4;
62
+ if ($[3] !== height || $[4] !== reduceMotion) {
63
+ t3 = () => {
64
+ const node = inner.current;
65
+ if (!node || typeof ResizeObserver === "undefined") {
66
+ return;
67
+ }
68
+ let hasMeasured = false;
69
+ const observer = new ResizeObserver(() => {
70
+ const next = node.offsetHeight;
71
+ if (!hasMeasured || reduceMotion || performance.now() > armedUntil.current) {
72
+ hasMeasured = true;
73
+ height.jump(next);
74
+ return;
75
+ }
76
+ animate(height, next, ARC_SPRING_SMOOTH);
77
+ });
78
+ observer.observe(node);
79
+ return () => observer.disconnect();
80
+ };
81
+ t4 = [height, reduceMotion];
82
+ $[3] = height;
83
+ $[4] = reduceMotion;
84
+ $[5] = t3;
85
+ $[6] = t4;
86
+ } else {
87
+ t3 = $[5];
88
+ t4 = $[6];
89
+ }
90
+ useEffect(t3, t4);
91
+ let t5;
92
+ if ($[7] !== height) {
93
+ t5 = { height };
94
+ $[7] = height;
95
+ $[8] = t5;
96
+ } else {
97
+ t5 = $[8];
98
+ }
99
+ let t6;
100
+ if ($[9] !== className) {
101
+ t6 = cn("break-words", className);
102
+ $[9] = className;
103
+ $[10] = t6;
104
+ } else {
105
+ t6 = $[10];
106
+ }
107
+ let t7;
108
+ if ($[11] !== reduceMotion || $[12] !== t6 || $[13] !== text) {
109
+ t7 = /* @__PURE__ */ _jsx("span", {
110
+ ref: inner,
111
+ className: "relative block",
112
+ children: /* @__PURE__ */ _jsx(ArcTextSwap, {
113
+ text,
114
+ reduceMotion,
115
+ lineClassName: t6
116
+ })
117
+ });
118
+ $[11] = reduceMotion;
119
+ $[12] = t6;
120
+ $[13] = text;
121
+ $[14] = t7;
122
+ } else {
123
+ t7 = $[14];
124
+ }
125
+ let t8;
126
+ if ($[15] !== t5 || $[16] !== t7) {
127
+ t8 = /* @__PURE__ */ _jsx(motion.span, {
128
+ className: "block",
129
+ style: t5,
130
+ children: t7
131
+ });
132
+ $[15] = t5;
133
+ $[16] = t7;
134
+ $[17] = t8;
135
+ } else {
136
+ t8 = $[17];
137
+ }
138
+ return t8;
139
+ }
140
+ /** The number, check and alert share one spot: the outgoing glyph shrinks away while the next pops in and draws. */
141
+ function Glyph(t0) {
142
+ const $ = _c(22);
143
+ const { kind, number, delay, reduceMotion } = t0;
144
+ let t1;
145
+ if ($[0] !== delay || $[1] !== reduceMotion) {
146
+ t1 = reduceMotion ? still : {
147
+ scale: {
148
+ ...ARC_SPRING_SNAPPY,
149
+ delay
150
+ },
151
+ opacity: {
152
+ duration: ARC_DURATION.fast,
153
+ delay
154
+ },
155
+ filter: {
156
+ duration: ARC_DURATION.fast,
157
+ delay
158
+ }
159
+ };
160
+ $[0] = delay;
161
+ $[1] = reduceMotion;
162
+ $[2] = t1;
163
+ } else {
164
+ t1 = $[2];
165
+ }
166
+ const pop = t1;
167
+ const t2 = reduceMotion ? still : leave;
168
+ let t3;
169
+ if ($[3] !== t2) {
170
+ t3 = {
171
+ ...glyphFrom,
172
+ transition: t2
173
+ };
174
+ $[3] = t2;
175
+ $[4] = t3;
176
+ } else {
177
+ t3 = $[4];
178
+ }
179
+ const exit = t3;
180
+ let t4;
181
+ if ($[5] !== delay || $[6] !== reduceMotion) {
182
+ t4 = reduceMotion ? still : {
183
+ duration: ARC_DURATION.standard,
184
+ ease: [...ARC_EASE.enter],
185
+ delay: delay + STEPPER_GLYPH_DRAW_DELAY_S
186
+ };
187
+ $[5] = delay;
188
+ $[6] = reduceMotion;
189
+ $[7] = t4;
190
+ } else {
191
+ t4 = $[7];
192
+ }
193
+ const draw = t4;
194
+ if (kind === "number") {
195
+ let t5;
196
+ if ($[8] !== exit || $[9] !== number || $[10] !== pop) {
197
+ t5 = /* @__PURE__ */ _jsx(motion.span, {
198
+ className: "col-start-1 row-start-1 grid place-items-center",
199
+ initial: glyphFrom,
200
+ animate: glyphRest,
201
+ exit,
202
+ transition: pop,
203
+ children: number
204
+ });
205
+ $[8] = exit;
206
+ $[9] = number;
207
+ $[10] = pop;
208
+ $[11] = t5;
209
+ } else {
210
+ t5 = $[11];
211
+ }
212
+ return t5;
213
+ }
214
+ let t5;
215
+ if ($[12] === Symbol.for("react.memo_cache_sentinel")) {
216
+ t5 = cn("col-start-1 row-start-1 grid place-items-center", "size-3.5");
217
+ $[12] = t5;
218
+ } else {
219
+ t5 = $[12];
220
+ }
221
+ let t6;
222
+ if ($[13] !== delay || $[14] !== draw || $[15] !== kind || $[16] !== reduceMotion) {
223
+ t6 = kind === "check" ? /* @__PURE__ */ _jsx(motion.path, {
224
+ d: "M5.5 12.5l4.25 4.25L18.5 8",
225
+ initial: { pathLength: 0 },
226
+ animate: { pathLength: 1 },
227
+ transition: draw
228
+ }) : /* @__PURE__ */ _jsxs(_Fragment, { children: [/* @__PURE__ */ _jsx(motion.path, {
229
+ d: "M12 6.75v6.5",
230
+ initial: { pathLength: 0 },
231
+ animate: { pathLength: 1 },
232
+ transition: draw
233
+ }), /* @__PURE__ */ _jsx(motion.circle, {
234
+ cx: 12,
235
+ cy: 17.4,
236
+ r: 1.4,
237
+ fill: "currentColor",
238
+ stroke: "none",
239
+ initial: { scale: 0 },
240
+ animate: { scale: 1 },
241
+ transition: reduceMotion ? still : {
242
+ ...ARC_SPRING_SNAPPY,
243
+ delay: delay + STEPPER_ALERT_DOT_DELAY_S
244
+ }
245
+ })] });
246
+ $[13] = delay;
247
+ $[14] = draw;
248
+ $[15] = kind;
249
+ $[16] = reduceMotion;
250
+ $[17] = t6;
251
+ } else {
252
+ t6 = $[17];
253
+ }
254
+ let t7;
255
+ if ($[18] !== exit || $[19] !== pop || $[20] !== t6) {
256
+ t7 = /* @__PURE__ */ _jsx(motion.svg, {
257
+ className: t5,
258
+ viewBox: "0 0 24 24",
259
+ fill: "none",
260
+ stroke: "currentColor",
261
+ strokeWidth: 2.5,
262
+ strokeLinecap: "round",
263
+ strokeLinejoin: "round",
264
+ initial: glyphFrom,
265
+ animate: glyphRest,
266
+ exit,
267
+ transition: pop,
268
+ children: t6
269
+ });
270
+ $[18] = exit;
271
+ $[19] = pop;
272
+ $[20] = t6;
273
+ $[21] = t7;
274
+ } else {
275
+ t7 = $[21];
276
+ }
277
+ return t7;
278
+ }
279
+ /** The ring grows out from behind the disc once progress arrives, so the eye lands on the new step after the connector fills. */
280
+ function Marker(t0) {
281
+ const $ = _c(14);
282
+ const { number, kind, isCurrent, glyphDelay, ringDelay, reduceMotion } = t0;
283
+ let t1;
284
+ if ($[0] !== isCurrent || $[1] !== reduceMotion || $[2] !== ringDelay) {
285
+ t1 = isCurrent ? /* @__PURE__ */ _jsx(motion.span, {
286
+ className: "absolute -inset-(--halo) rounded-(--radius-pill) bg-(--accent-subtle) transition-[background-color] duration-(--duration-standard) ease-(--ease-standard) group-data-[status=error]/step:bg-danger/16",
287
+ initial: {
288
+ opacity: 0,
289
+ scale: STEPPER_RING_ENTER_SCALE
290
+ },
291
+ animate: {
292
+ opacity: 1,
293
+ scale: 1
294
+ },
295
+ exit: {
296
+ opacity: 0,
297
+ scale: STEPPER_RING_ENTER_SCALE,
298
+ transition: reduceMotion ? still : leave
299
+ },
300
+ transition: reduceMotion ? still : {
301
+ scale: {
302
+ ...ARC_SPRING_SNAPPY,
303
+ delay: ringDelay
304
+ },
305
+ opacity: {
306
+ duration: ARC_DURATION.fast,
307
+ delay: ringDelay
308
+ }
309
+ }
310
+ }, "ring") : null;
311
+ $[0] = isCurrent;
312
+ $[1] = reduceMotion;
313
+ $[2] = ringDelay;
314
+ $[3] = t1;
315
+ } else {
316
+ t1 = $[3];
317
+ }
318
+ let t2;
319
+ if ($[4] !== t1) {
320
+ t2 = /* @__PURE__ */ _jsx(AnimatePresence, {
321
+ initial: false,
322
+ children: t1
323
+ });
324
+ $[4] = t1;
325
+ $[5] = t2;
326
+ } else {
327
+ t2 = $[5];
328
+ }
329
+ let t3;
330
+ if ($[6] !== glyphDelay || $[7] !== kind || $[8] !== number || $[9] !== reduceMotion) {
331
+ t3 = /* @__PURE__ */ _jsx("span", {
332
+ className: "relative grid size-full place-items-center rounded-(--radius-pill) bg-surface text-xs leading-none font-medium text-text-muted tabular-nums shadow-[inset_0_0_0_1px_var(--border-strong)] transition-[background-color,box-shadow,color,transform] duration-(--duration-standard) ease-(--ease-standard) group-data-[status=current]/step:text-foreground group-data-[status=current]/step:shadow-[inset_0_0_0_1.5px_var(--accent)] group-data-[status=complete]/step:bg-(--accent) group-data-[status=complete]/step:text-(--accent-foreground) group-data-[status=complete]/step:shadow-[inset_0_0_0_1px_var(--accent)] group-data-[status=error]/step:bg-[color-mix(in_oklab,var(--danger)_10%,var(--surface))] group-data-[status=error]/step:text-danger group-data-[status=error]/step:shadow-[inset_0_0_0_1.5px_var(--danger)] group-data-clickable/head:group-active/head:scale-92 group-data-clickable/head:group-data-[status=complete]/step:group-hover/head:bg-(--accent-strong) group-data-clickable/head:group-data-[status=complete]/step:group-hover/head:shadow-[inset_0_0_0_1px_var(--accent-strong)] group-data-clickable/head:group-data-[status=error]/step:group-hover/head:bg-[color-mix(in_oklab,var(--danger)_18%,var(--surface))] motion-reduce:transition-none motion-reduce:group-active/head:scale-100",
333
+ children: /* @__PURE__ */ _jsx(AnimatePresence, {
334
+ initial: false,
335
+ children: /* @__PURE__ */ _jsx(Glyph, {
336
+ kind,
337
+ number,
338
+ delay: glyphDelay,
339
+ reduceMotion
340
+ }, kind)
341
+ })
342
+ });
343
+ $[6] = glyphDelay;
344
+ $[7] = kind;
345
+ $[8] = number;
346
+ $[9] = reduceMotion;
347
+ $[10] = t3;
348
+ } else {
349
+ t3 = $[10];
350
+ }
351
+ let t4;
352
+ if ($[11] !== t2 || $[12] !== t3) {
353
+ t4 = /* @__PURE__ */ _jsxs("span", {
354
+ "data-slot": "stepper-marker",
355
+ "aria-hidden": "true",
356
+ className: "relative grid size-(--marker) flex-none place-items-center",
357
+ children: [t2, t3]
358
+ });
359
+ $[11] = t2;
360
+ $[12] = t3;
361
+ $[13] = t4;
362
+ } else {
363
+ t4 = $[13];
364
+ }
365
+ return t4;
366
+ }
367
+ /**
368
+ * A horizontal or vertical steps indicator driven by the current index, with optional navigation back to completed steps.
369
+ * @param props - Steps, current index, orientation, selection callback, copy and native attributes.
370
+ * @returns The stepper: a labelled `nav` when interactive, otherwise a `role="group"`.
371
+ */
372
+ function Stepper(t0) {
373
+ const $ = _c(52);
374
+ let className;
375
+ let current;
376
+ let messages;
377
+ let onStepSelect;
378
+ let props;
379
+ let steps;
380
+ let t1;
381
+ let t2;
382
+ let t3;
383
+ let t4;
384
+ let t5;
385
+ if ($[0] !== t0) {
386
+ ({steps, current, orientation: t1, onStepSelect, details: t2, compact: t3, label: t4, completeLabel: t5, messages, className, ...props} = t0);
387
+ $[0] = t0;
388
+ $[1] = className;
389
+ $[2] = current;
390
+ $[3] = messages;
391
+ $[4] = onStepSelect;
392
+ $[5] = props;
393
+ $[6] = steps;
394
+ $[7] = t1;
395
+ $[8] = t2;
396
+ $[9] = t3;
397
+ $[10] = t4;
398
+ $[11] = t5;
399
+ } else {
400
+ className = $[1];
401
+ current = $[2];
402
+ messages = $[3];
403
+ onStepSelect = $[4];
404
+ props = $[5];
405
+ steps = $[6];
406
+ t1 = $[7];
407
+ t2 = $[8];
408
+ t3 = $[9];
409
+ t4 = $[10];
410
+ t5 = $[11];
411
+ }
412
+ const orientation = t1 === undefined ? "horizontal" : t1;
413
+ const details = t2 === undefined ? "all" : t2;
414
+ const compact = t3 === undefined ? false : t3;
415
+ const label = t4 === undefined ? STEPPER_DEFAULT_LABEL : t4;
416
+ const completeLabel = t5 === undefined ? STEPPER_DEFAULT_COMPLETE_LABEL : t5;
417
+ const copy = {
418
+ ...STEPPER_DEFAULT_MESSAGES,
419
+ ...messages
420
+ };
421
+ const statusText = {
422
+ complete: copy.completed,
423
+ current: "",
424
+ upcoming: copy.notStarted,
425
+ error: copy.error
426
+ };
427
+ const reduceMotion = usePrefersReducedMotion();
428
+ const count = steps.length;
429
+ let t6;
430
+ if ($[12] !== current) {
431
+ t6 = Math.round(current);
432
+ $[12] = current;
433
+ $[13] = t6;
434
+ } else {
435
+ t6 = $[13];
436
+ }
437
+ const active = Math.min(Math.max(t6, 0), count);
438
+ let t7;
439
+ if ($[14] !== active) {
440
+ t7 = {
441
+ to: active,
442
+ from: active
443
+ };
444
+ $[14] = active;
445
+ $[15] = t7;
446
+ } else {
447
+ t7 = $[15];
448
+ }
449
+ const [travel, setTravel] = useState(t7);
450
+ if (travel.to !== active) {
451
+ setTravel({
452
+ to: active,
453
+ from: travel.to
454
+ });
455
+ }
456
+ const from = travel.from;
457
+ const stagger = ARC_STAGGER.line;
458
+ let t8;
459
+ if ($[16] !== active || $[17] !== from || $[18] !== reduceMotion) {
460
+ t8 = (index) => {
461
+ if (reduceMotion) {
462
+ return 0;
463
+ }
464
+ if (active > from) {
465
+ return index >= from && index < active ? (index - from) * stagger : 0;
466
+ }
467
+ return index >= active && index < from ? (from - 1 - index) * stagger : 0;
468
+ };
469
+ $[16] = active;
470
+ $[17] = from;
471
+ $[18] = reduceMotion;
472
+ $[19] = t8;
473
+ } else {
474
+ t8 = $[19];
475
+ }
476
+ const delayAt = t8;
477
+ const ringDelay = reduceMotion ? 0 : Math.max(0, Math.abs(active - from) - 1) * stagger + STEPPER_RING_DELAY_S;
478
+ const isInteractive = Boolean(onStepSelect);
479
+ const isVertical = orientation === "vertical";
480
+ const currentStep = active >= count ? undefined : steps[active];
481
+ let t9;
482
+ if ($[20] !== isVertical) {
483
+ t9 = function onKeyDown(event) {
484
+ const isRightToLeft = !isVertical && getComputedStyle(event.currentTarget).direction === "rtl";
485
+ const backKeys = ["ArrowUp", isRightToLeft ? "ArrowRight" : "ArrowLeft"];
486
+ const aheadKeys = ["ArrowDown", isRightToLeft ? "ArrowLeft" : "ArrowRight"];
487
+ if (![
488
+ ...backKeys,
489
+ ...aheadKeys,
490
+ "Home",
491
+ "End"
492
+ ].includes(event.key)) {
493
+ return;
494
+ }
495
+ const targets = Array.from(event.currentTarget.querySelectorAll("button[data-reachable]"));
496
+ const position = targets.indexOf(event.target);
497
+ if (position < 0) {
498
+ return;
499
+ }
500
+ event.preventDefault();
501
+ const next = event.key === "Home" ? 0 : event.key === "End" ? targets.length - 1 : backKeys.includes(event.key) ? Math.max(0, position - 1) : Math.min(targets.length - 1, position + 1);
502
+ targets[next]?.focus();
503
+ };
504
+ $[20] = isVertical;
505
+ $[21] = t9;
506
+ } else {
507
+ t9 = $[21];
508
+ }
509
+ const onKeyDown = t9;
510
+ const Root = isInteractive ? "nav" : "div";
511
+ const hiddenTextClassName = compact ? "sr-only" : isVertical ? "" : "@max-[30rem]/stepper:sr-only";
512
+ const t10 = "stepper";
513
+ const t11 = isInteractive ? undefined : "group";
514
+ const t12 = !isVertical && "@container/stepper w-full";
515
+ let t13;
516
+ if ($[22] !== className || $[23] !== t12) {
517
+ t13 = cn("min-w-0 font-sans tracking-(--tracking-body) text-foreground [--halo:4px] [--marker:1.75rem]", t12, className);
518
+ $[22] = className;
519
+ $[23] = t12;
520
+ $[24] = t13;
521
+ } else {
522
+ t13 = $[24];
523
+ }
524
+ let t14;
525
+ if ($[25] !== count || $[26] !== isVertical) {
526
+ t14 = isVertical ? undefined : { gridTemplateColumns: count > 1 ? `repeat(${count - 1}, minmax(0, 1fr)) auto` : "auto" };
527
+ $[25] = count;
528
+ $[26] = isVertical;
529
+ $[27] = t14;
530
+ } else {
531
+ t14 = $[27];
532
+ }
533
+ const t15 = isInteractive ? onKeyDown : undefined;
534
+ const t16 = steps.map((step, index_0) => {
535
+ const isCurrent = index_0 === active;
536
+ const status = step.error ? "error" : index_0 < active ? "complete" : isCurrent ? "current" : "upcoming";
537
+ const isClickable = isInteractive && index_0 < active;
538
+ const detail = step.error ?? (details === "all" || isCurrent ? step.description : undefined);
539
+ const kind = step.error ? "error" : index_0 < active ? "check" : "number";
540
+ const isLast = index_0 === count - 1;
541
+ const content = /* @__PURE__ */ _jsxs(_Fragment, { children: [/* @__PURE__ */ _jsx(Marker, {
542
+ number: index_0 + 1,
543
+ kind,
544
+ isCurrent,
545
+ glyphDelay: delayAt(index_0),
546
+ ringDelay,
547
+ reduceMotion
548
+ }), /* @__PURE__ */ _jsxs("span", {
549
+ "data-slot": "stepper-text",
550
+ className: cn("grid min-w-0", isVertical && "pt-1", hiddenTextClassName),
551
+ children: [
552
+ /* @__PURE__ */ _jsx("span", {
553
+ className: "block text-sm leading-5 font-medium break-words text-text-muted transition-colors duration-(--duration-standard) ease-(--ease-standard) group-data-[status=complete]/step:text-text-secondary group-data-[status=current]/step:text-foreground group-data-[status=error]/step:text-foreground group-data-clickable/head:group-hover/head:text-foreground motion-reduce:transition-none",
554
+ children: step.label
555
+ }),
556
+ statusText[status] ? /* @__PURE__ */ _jsx("span", {
557
+ className: "sr-only",
558
+ children: `, ${statusText[status]}`
559
+ }) : null,
560
+ /* @__PURE__ */ _jsx(SwapSlot, {
561
+ text: detail,
562
+ className: cn("pt-0.5 text-xs leading-(--leading-body) font-normal", step.error ? "text-danger" : "text-text-muted"),
563
+ reduceMotion
564
+ })
565
+ ]
566
+ })] });
567
+ const headClassName = cn("group/head m-0 grid cursor-default rounded-(--space-2) border-0 bg-transparent p-0 text-start [font:inherit] [letter-spacing:inherit] text-inherit [-webkit-tap-highlight-color:transparent] [--focus-outline-offset:4px] data-clickable:cursor-pointer", isVertical ? cn("w-full items-start gap-x-(--space-3)", compact ? "grid-cols-[var(--marker)] gap-x-0" : "grid-cols-[var(--marker)_minmax(0,1fr)]") : "w-fit max-w-full justify-items-start gap-y-(--space-3)");
568
+ return /* @__PURE__ */ _jsxs("li", {
569
+ "data-slot": "stepper-step",
570
+ "data-status": status,
571
+ className: cn("group/step relative min-w-0", !isLast && (isVertical ? compact ? "pb-(--space-6)" : "pb-(--space-5)" : "pe-(--space-4)")),
572
+ children: [!isLast ? /* @__PURE__ */ _jsx("span", {
573
+ "data-slot": "stepper-connector",
574
+ "aria-hidden": "true",
575
+ className: cn("pointer-events-none absolute overflow-hidden rounded-(--radius-pill) bg-border", isVertical ? "start-[calc(var(--marker)/2_-_1px)] top-[calc(var(--marker)+var(--halo)+2px)] bottom-[calc(var(--halo)+2px)] w-0.5" : "start-[calc(var(--marker)+var(--halo)+var(--space-1))] end-[calc(var(--halo)+var(--space-1))] top-[calc(var(--marker)/2_-_1px)] h-0.5"),
576
+ children: /* @__PURE__ */ _jsx(motion.span, {
577
+ className: cn("absolute inset-0 rounded-[inherit] bg-(--accent)", isVertical ? "origin-top" : "origin-left rtl:origin-right"),
578
+ initial: false,
579
+ animate: isVertical ? { scaleY: index_0 < active ? 1 : 0 } : { scaleX: index_0 < active ? 1 : 0 },
580
+ transition: reduceMotion ? still : {
581
+ ...ARC_SPRING_SMOOTH,
582
+ delay: delayAt(index_0)
583
+ }
584
+ }, orientation)
585
+ }) : null, isInteractive ? /* @__PURE__ */ _jsx("button", {
586
+ type: "button",
587
+ className: headClassName,
588
+ "data-clickable": isClickable || undefined,
589
+ "data-reachable": index_0 <= active || undefined,
590
+ "aria-current": isCurrent ? "step" : undefined,
591
+ "aria-disabled": isClickable ? undefined : true,
592
+ tabIndex: isClickable || isCurrent ? undefined : -1,
593
+ onClick: isClickable ? () => onStepSelect?.(index_0) : undefined,
594
+ children: content
595
+ }) : /* @__PURE__ */ _jsx("span", {
596
+ className: headClassName,
597
+ "aria-current": isCurrent ? "step" : undefined,
598
+ children: content
599
+ })]
600
+ }, step.id);
601
+ });
602
+ let t17;
603
+ if ($[28] !== t14 || $[29] !== t15 || $[30] !== t16) {
604
+ t17 = /* @__PURE__ */ _jsx("ol", {
605
+ className: "m-0 grid list-none p-0",
606
+ style: t14,
607
+ onKeyDown: t15,
608
+ children: t16
609
+ });
610
+ $[28] = t14;
611
+ $[29] = t15;
612
+ $[30] = t16;
613
+ $[31] = t17;
614
+ } else {
615
+ t17 = $[31];
616
+ }
617
+ let t18;
618
+ if ($[32] !== compact || $[33] !== completeLabel || $[34] !== currentStep?.description || $[35] !== currentStep?.error || $[36] !== currentStep?.label || $[37] !== isVertical || $[38] !== reduceMotion) {
619
+ t18 = isVertical ? null : /* @__PURE__ */ _jsxs("span", {
620
+ "data-slot": "stepper-caption",
621
+ "aria-hidden": "true",
622
+ className: cn("mt-(--space-3)", compact ? "grid" : "hidden @max-[30rem]/stepper:grid"),
623
+ children: [/* @__PURE__ */ _jsx(SwapSlot, {
624
+ text: currentStep?.label ?? completeLabel,
625
+ className: "text-sm leading-5 font-medium text-foreground",
626
+ reduceMotion
627
+ }), /* @__PURE__ */ _jsx(SwapSlot, {
628
+ text: currentStep?.error ?? currentStep?.description,
629
+ className: cn("pt-0.5 text-xs leading-(--leading-body) font-normal", currentStep?.error ? "text-danger" : "text-text-muted"),
630
+ reduceMotion
631
+ })]
632
+ });
633
+ $[32] = compact;
634
+ $[33] = completeLabel;
635
+ $[34] = currentStep?.description;
636
+ $[35] = currentStep?.error;
637
+ $[36] = currentStep?.label;
638
+ $[37] = isVertical;
639
+ $[38] = reduceMotion;
640
+ $[39] = t18;
641
+ } else {
642
+ t18 = $[39];
643
+ }
644
+ const t19 = "sr-only";
645
+ const t20 = "polite";
646
+ const t21 = currentStep ? copy.stepAnnouncement({
647
+ position: active + 1,
648
+ count,
649
+ label: currentStep.label
650
+ }) : completeLabel;
651
+ let t22;
652
+ if ($[40] !== t21) {
653
+ t22 = /* @__PURE__ */ _jsx("span", {
654
+ className: t19,
655
+ "aria-live": t20,
656
+ children: t21
657
+ });
658
+ $[40] = t21;
659
+ $[41] = t22;
660
+ } else {
661
+ t22 = $[41];
662
+ }
663
+ let t23;
664
+ if ($[42] !== Root || $[43] !== label || $[44] !== orientation || $[45] !== props || $[46] !== t11 || $[47] !== t13 || $[48] !== t17 || $[49] !== t18 || $[50] !== t22) {
665
+ t23 = /* @__PURE__ */ _jsxs(Root, {
666
+ "data-slot": t10,
667
+ "data-orientation": orientation,
668
+ "aria-label": label,
669
+ role: t11,
670
+ className: t13,
671
+ ...props,
672
+ children: [
673
+ t17,
674
+ t18,
675
+ t22
676
+ ]
677
+ });
678
+ $[42] = Root;
679
+ $[43] = label;
680
+ $[44] = orientation;
681
+ $[45] = props;
682
+ $[46] = t11;
683
+ $[47] = t13;
684
+ $[48] = t17;
685
+ $[49] = t18;
686
+ $[50] = t22;
687
+ $[51] = t23;
688
+ } else {
689
+ t23 = $[51];
690
+ }
691
+ return t23;
692
+ }
693
+ export { Stepper };