@codraoss/ui 0.9.4

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 (44) hide show
  1. package/LICENSE +625 -0
  2. package/README.md +15 -0
  3. package/dist/chunk-HCQJTSV3.js +39 -0
  4. package/dist/chunk-HCQJTSV3.js.map +1 -0
  5. package/dist/chunk-OU66JJZD.js +7 -0
  6. package/dist/chunk-OU66JJZD.js.map +1 -0
  7. package/dist/chunk-PZ5AY32C.js +10 -0
  8. package/dist/chunk-PZ5AY32C.js.map +1 -0
  9. package/dist/chunk-TXNSYK4G.js +23 -0
  10. package/dist/chunk-TXNSYK4G.js.map +1 -0
  11. package/dist/components/motion/index.d.ts +92 -0
  12. package/dist/components/motion/index.js +643 -0
  13. package/dist/components/motion/index.js.map +1 -0
  14. package/dist/hooks/index.d.ts +3 -0
  15. package/dist/hooks/index.js +8 -0
  16. package/dist/hooks/index.js.map +1 -0
  17. package/dist/index.d.ts +241 -0
  18. package/dist/index.js +1144 -0
  19. package/dist/index.js.map +1 -0
  20. package/dist/lib/ease.d.ts +3 -0
  21. package/dist/lib/ease.js +8 -0
  22. package/dist/lib/ease.js.map +1 -0
  23. package/dist/lib/file-tree.d.ts +16 -0
  24. package/dist/lib/file-tree.js +46 -0
  25. package/dist/lib/file-tree.js.map +1 -0
  26. package/dist/lib/highlight.d.ts +14 -0
  27. package/dist/lib/highlight.js +35 -0
  28. package/dist/lib/highlight.js.map +1 -0
  29. package/dist/lib/markdown-plugins.d.ts +6 -0
  30. package/dist/lib/markdown-plugins.js +11041 -0
  31. package/dist/lib/markdown-plugins.js.map +1 -0
  32. package/dist/lib/prompt-diff.d.ts +21 -0
  33. package/dist/lib/prompt-diff.js +95 -0
  34. package/dist/lib/prompt-diff.js.map +1 -0
  35. package/dist/lib/selection.d.ts +11 -0
  36. package/dist/lib/selection.js +15 -0
  37. package/dist/lib/selection.js.map +1 -0
  38. package/dist/lib/theme.d.ts +14 -0
  39. package/dist/lib/theme.js +78 -0
  40. package/dist/lib/theme.js.map +1 -0
  41. package/dist/lib/utils.d.ts +15 -0
  42. package/dist/lib/utils.js +14 -0
  43. package/dist/lib/utils.js.map +1 -0
  44. package/package.json +150 -0
@@ -0,0 +1,643 @@
1
+ import {
2
+ cn
3
+ } from "../../chunk-HCQJTSV3.js";
4
+ import {
5
+ useIsDarkMode
6
+ } from "../../chunk-TXNSYK4G.js";
7
+ import "../../chunk-PZ5AY32C.js";
8
+
9
+ // src/components/motion/shared-layout-bg.tsx
10
+ import {
11
+ AnimatePresence,
12
+ domMax,
13
+ LazyMotion,
14
+ m,
15
+ useReducedMotion
16
+ } from "motion/react";
17
+ import {
18
+ Children,
19
+ cloneElement,
20
+ isValidElement,
21
+ useId,
22
+ useState
23
+ } from "react";
24
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
25
+ var SPRING_LAYOUT = {
26
+ type: "spring",
27
+ stiffness: 400,
28
+ damping: 40,
29
+ mass: 0.6
30
+ };
31
+ var variants = {
32
+ initial: { opacity: 0, filter: "blur(6px)" },
33
+ animate: { opacity: 1, filter: "blur(0px)" },
34
+ exit: (isActive) => !isActive ? { opacity: 0, filter: "blur(6px)" } : {}
35
+ };
36
+ var reducedVariants = {
37
+ initial: { opacity: 0 },
38
+ animate: { opacity: 1 },
39
+ exit: (isActive) => !isActive ? { opacity: 0 } : {}
40
+ };
41
+ function SharedLayoutBg({
42
+ children,
43
+ className,
44
+ pillClassName,
45
+ inset = 0
46
+ }) {
47
+ const [activeId, setActiveId] = useState(null);
48
+ const uid = useId();
49
+ const reduce = useReducedMotion();
50
+ const rows = [];
51
+ for (const child of Children.toArray(children)) {
52
+ if (!isValidElement(child)) continue;
53
+ const el = child;
54
+ const childKey = el.key ? String(el.key) : `item-${rows.length}`;
55
+ rows.push(
56
+ cloneElement(
57
+ el,
58
+ {
59
+ key: childKey,
60
+ className: cn("relative z-10", el.props.className),
61
+ onMouseEnter: (e) => {
62
+ el.props.onMouseEnter?.(e);
63
+ setActiveId(childKey);
64
+ }
65
+ },
66
+ /* @__PURE__ */ jsxs(Fragment, { children: [
67
+ /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-0 z-0", children: /* @__PURE__ */ jsx(AnimatePresence, { custom: activeId !== null, children: activeId !== null ? /* @__PURE__ */ jsx(
68
+ m.div,
69
+ {
70
+ variants: reduce ? reducedVariants : variants,
71
+ initial: "initial",
72
+ animate: "animate",
73
+ exit: "exit",
74
+ custom: activeId !== null,
75
+ className: "absolute inset-0",
76
+ style: { left: -inset, right: -inset, top: 0, bottom: 0 },
77
+ children: activeId === childKey ? /* @__PURE__ */ jsx(
78
+ m.div,
79
+ {
80
+ layoutId: `shared-bg-${uid}`,
81
+ transition: reduce ? { duration: 0 } : SPRING_LAYOUT,
82
+ className: cn(
83
+ "pointer-events-none h-full w-full rounded-lg",
84
+ pillClassName
85
+ )
86
+ }
87
+ ) : null
88
+ }
89
+ ) : null }) }),
90
+ el
91
+ ] })
92
+ )
93
+ );
94
+ }
95
+ return /* @__PURE__ */ jsx(LazyMotion, { features: domMax, children: /* @__PURE__ */ jsx(
96
+ m.div,
97
+ {
98
+ layoutRoot: true,
99
+ onMouseLeave: () => setActiveId(null),
100
+ className: cn("flex w-full flex-col", className),
101
+ children: rows
102
+ }
103
+ ) });
104
+ }
105
+
106
+ // src/components/motion/smooth-scroll.tsx
107
+ import { ReactLenis, useLenis } from "lenis/react";
108
+ import { useMotionValue, useReducedMotion as useReducedMotion2 } from "motion/react";
109
+ import {
110
+ createContext,
111
+ useCallback,
112
+ useEffect,
113
+ useMemo,
114
+ useRef
115
+ } from "react";
116
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
117
+ var EASE_SCROLL = (t) => Math.min(1, 1.001 - 2 ** (-10 * t));
118
+ var SmoothScrollContext = createContext(null);
119
+ function readMetrics(target) {
120
+ if (target instanceof Window) {
121
+ const max = Math.max(
122
+ 0,
123
+ document.documentElement.scrollHeight - window.innerHeight
124
+ );
125
+ return { y: window.scrollY, max };
126
+ }
127
+ return {
128
+ y: target.scrollTop,
129
+ max: Math.max(0, target.scrollHeight - target.clientHeight)
130
+ };
131
+ }
132
+ function resolveTop(target, source, offset = 0) {
133
+ if (typeof target === "number") return target + offset;
134
+ if (source instanceof Window) {
135
+ const el2 = typeof target === "string" ? document.querySelector(target) : target;
136
+ if (!el2) return window.scrollY;
137
+ return el2.getBoundingClientRect().top + window.scrollY + offset;
138
+ }
139
+ const el = typeof target === "string" ? source.querySelector(target) : target;
140
+ if (!(el instanceof HTMLElement)) return source.scrollTop;
141
+ return el.offsetTop + offset;
142
+ }
143
+ function LenisBridge({
144
+ scrollY,
145
+ progress,
146
+ velocity,
147
+ lenisRef
148
+ }) {
149
+ const lenis = useLenis((instance) => {
150
+ scrollY.set(instance.scroll);
151
+ progress.set(instance.progress);
152
+ velocity.set(instance.velocity);
153
+ });
154
+ useEffect(() => {
155
+ lenisRef.current = lenis ?? null;
156
+ return () => {
157
+ lenisRef.current = null;
158
+ };
159
+ }, [lenis, lenisRef]);
160
+ return null;
161
+ }
162
+ function useNativeScrollSync(enabled, getTarget, scrollY, progress, velocity) {
163
+ useEffect(() => {
164
+ if (!enabled) return;
165
+ const target = getTarget();
166
+ if (!target) return;
167
+ let lastY = readMetrics(target).y;
168
+ let lastT = performance.now();
169
+ const onScroll = () => {
170
+ const { y, max } = readMetrics(target);
171
+ const now = performance.now();
172
+ const dt = now - lastT || 16;
173
+ scrollY.set(y);
174
+ progress.set(max > 0 ? y / max : 0);
175
+ velocity.set((y - lastY) / dt * 16);
176
+ lastY = y;
177
+ lastT = now;
178
+ };
179
+ onScroll();
180
+ target.addEventListener("scroll", onScroll, { passive: true });
181
+ return () => target.removeEventListener("scroll", onScroll);
182
+ }, [enabled, getTarget, scrollY, progress, velocity]);
183
+ }
184
+ function SmoothScroll({
185
+ children,
186
+ root = true,
187
+ lerp = 0.1,
188
+ duration = 1.2,
189
+ orientation = "vertical",
190
+ wheelMultiplier = 1,
191
+ touch = false,
192
+ className
193
+ }) {
194
+ const reduce = useReducedMotion2();
195
+ const scrollY = useMotionValue(0);
196
+ const progress = useMotionValue(0);
197
+ const velocity = useMotionValue(0);
198
+ const lenisRef = useRef(null);
199
+ const containerRef = useRef(null);
200
+ const nativeSource = useCallback(
201
+ () => root ? window : containerRef.current,
202
+ [root]
203
+ );
204
+ const scrollTo = useCallback(
205
+ (target, options) => {
206
+ const lenis = lenisRef.current;
207
+ if (lenis && !reduce) {
208
+ lenis.scrollTo(target, {
209
+ offset: options?.offset,
210
+ duration: options?.duration,
211
+ immediate: options?.immediate
212
+ });
213
+ return;
214
+ }
215
+ const source = nativeSource();
216
+ const behavior = reduce || options?.immediate ? "auto" : "smooth";
217
+ const top = resolveTop(target, source ?? window, options?.offset);
218
+ (source ?? window).scrollTo({ top, behavior });
219
+ },
220
+ [reduce, nativeSource]
221
+ );
222
+ useNativeScrollSync(!!reduce, nativeSource, scrollY, progress, velocity);
223
+ const api = useMemo(
224
+ () => ({ lenis: lenisRef.current, scrollY, progress, velocity, scrollTo }),
225
+ [scrollY, progress, velocity, scrollTo]
226
+ );
227
+ if (reduce) {
228
+ return /* @__PURE__ */ jsx2(SmoothScrollContext.Provider, { value: api, children: /* @__PURE__ */ jsx2("div", { ref: containerRef, className, children }) });
229
+ }
230
+ return /* @__PURE__ */ jsx2(SmoothScrollContext.Provider, { value: api, children: /* @__PURE__ */ jsxs2(
231
+ ReactLenis,
232
+ {
233
+ root,
234
+ className,
235
+ options: {
236
+ lerp,
237
+ duration,
238
+ orientation,
239
+ wheelMultiplier,
240
+ smoothWheel: true,
241
+ syncTouch: touch,
242
+ easing: EASE_SCROLL,
243
+ // Without this, Lenis preventDefault()s every wheel event, blocking nested scrollable
244
+ // elements (log panes, drawers, option lists). Escape hatch: `data-lenis-prevent`.
245
+ allowNestedScroll: true
246
+ },
247
+ children: [
248
+ /* @__PURE__ */ jsx2(
249
+ LenisBridge,
250
+ {
251
+ scrollY,
252
+ progress,
253
+ velocity,
254
+ lenisRef
255
+ }
256
+ ),
257
+ children
258
+ ]
259
+ }
260
+ ) });
261
+ }
262
+
263
+ // src/components/motion/stepped-slider.tsx
264
+ import {
265
+ domAnimation,
266
+ LazyMotion as LazyMotion2,
267
+ m as m2,
268
+ useMotionTemplate,
269
+ useMotionValue as useMotionValue2,
270
+ useReducedMotion as useReducedMotion3,
271
+ useSpring,
272
+ useTransform
273
+ } from "motion/react";
274
+ import {
275
+ useCallback as useCallback2,
276
+ useEffect as useEffect2,
277
+ useMemo as useMemo2,
278
+ useRef as useRef2,
279
+ useState as useState2
280
+ } from "react";
281
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
282
+ var SPRING_GLIDE = { stiffness: 700, damping: 50, mass: 0.5 };
283
+ var SPRING_BOUNCY = { type: "spring", stiffness: 500, damping: 14, mass: 0.7 };
284
+ function seedFromId(id) {
285
+ if (!id) return 0;
286
+ let hash = 0;
287
+ for (let i = 0; i < id.length; i += 1) {
288
+ hash = hash * 31 + id.charCodeAt(i) >>> 0;
289
+ }
290
+ return hash % 997 / 997;
291
+ }
292
+ var clamp = (v, lo, hi) => Math.min(hi, Math.max(lo, v));
293
+ function SteppedSlider({
294
+ id,
295
+ value,
296
+ defaultValue = 0,
297
+ onValueChange,
298
+ min = 0,
299
+ max = 100,
300
+ step = 1,
301
+ steps = [],
302
+ formatValue,
303
+ disabled = false,
304
+ className,
305
+ "aria-label": ariaLabel,
306
+ "aria-labelledby": ariaLabelledBy
307
+ }) {
308
+ const reduce = useReducedMotion3();
309
+ const isDark = useIsDarkMode();
310
+ const seed = useMemo2(() => seedFromId(id), [id]);
311
+ const trackRef = useRef2(null);
312
+ const [internal, setInternal] = useState2(defaultValue);
313
+ const [active, setActive] = useState2(false);
314
+ const [dragValue, setDragValue] = useState2(null);
315
+ const dragValueRef = useRef2(null);
316
+ const controlled = value !== void 0;
317
+ const committedValue = clamp(controlled ? value : internal, min, max);
318
+ const current = active && dragValue !== null ? clamp(dragValue, min, max) : committedValue;
319
+ const percent = (current - min) / (max - min) * 100;
320
+ const isMaxed = current === max;
321
+ const hue = 185 + (seed - 0.5) * 16;
322
+ const glowColor = isDark ? `oklch(68% 0.14 ${hue})` : `oklch(52% 0.13 ${hue})`;
323
+ const fillGradient = isDark ? `linear-gradient(90deg, oklch(28% 0.08 ${hue}), oklch(62% 0.12 ${hue}))` : `linear-gradient(90deg, oklch(93% 0.03 ${hue}), oklch(56% 0.13 ${hue}))`;
324
+ const dotDriftDuration = 1.4 + seed * 0.5;
325
+ const glowDuration = 1.6 + seed * 0.6;
326
+ const target = useMotionValue2(percent);
327
+ useEffect2(() => {
328
+ target.set(percent);
329
+ }, [percent, target]);
330
+ const smooth = useSpring(target, SPRING_GLIDE);
331
+ const pos = reduce ? target : smooth;
332
+ const left = useMotionTemplate`${pos}%`;
333
+ const thumbX = useTransform(pos, (p) => `${-p}%`);
334
+ const snapValue = useCallback2(
335
+ (next) => clamp(Math.round((next - min) / step) * step + min, min, max),
336
+ [min, max, step]
337
+ );
338
+ const commit = useCallback2(
339
+ (next) => {
340
+ const snapped = snapValue(next);
341
+ if (!controlled) setInternal(snapped);
342
+ onValueChange?.(snapped);
343
+ },
344
+ [controlled, onValueChange, snapValue]
345
+ );
346
+ const valueFromX = useCallback2(
347
+ (clientX) => {
348
+ const rect = trackRef.current?.getBoundingClientRect();
349
+ if (!rect) return committedValue;
350
+ const ratio = clamp((clientX - rect.left) / rect.width, 0, 1);
351
+ return min + ratio * (max - min);
352
+ },
353
+ [committedValue, min, max]
354
+ );
355
+ const trackDragValue = useCallback2((next) => {
356
+ dragValueRef.current = next;
357
+ setDragValue(next);
358
+ }, []);
359
+ const onPointerDown = useCallback2(
360
+ (event) => {
361
+ if (disabled) return;
362
+ event.currentTarget.setPointerCapture(event.pointerId);
363
+ setActive(true);
364
+ trackDragValue(snapValue(valueFromX(event.clientX)));
365
+ },
366
+ [disabled, valueFromX, snapValue, trackDragValue]
367
+ );
368
+ const onPointerMove = useCallback2(
369
+ (event) => {
370
+ if (!active || disabled) return;
371
+ trackDragValue(snapValue(valueFromX(event.clientX)));
372
+ },
373
+ [active, disabled, valueFromX, snapValue, trackDragValue]
374
+ );
375
+ const endDrag = useCallback2(
376
+ (event) => {
377
+ event.currentTarget.releasePointerCapture?.(event.pointerId);
378
+ setActive(false);
379
+ const pending = dragValueRef.current;
380
+ trackDragValue(null);
381
+ if (pending !== null) commit(pending);
382
+ },
383
+ [commit, trackDragValue]
384
+ );
385
+ const onKeyDown = useCallback2(
386
+ (event) => {
387
+ if (disabled) return;
388
+ const map = {
389
+ ArrowRight: committedValue + step,
390
+ ArrowUp: committedValue + step,
391
+ ArrowLeft: committedValue - step,
392
+ ArrowDown: committedValue - step,
393
+ Home: min,
394
+ End: max
395
+ };
396
+ if (event.key in map) {
397
+ event.preventDefault();
398
+ commit(map[event.key]);
399
+ }
400
+ },
401
+ [disabled, committedValue, step, min, max, commit]
402
+ );
403
+ const valueLabel = formatValue ? formatValue(current) : String(current);
404
+ return /* @__PURE__ */ jsx3(LazyMotion2, { features: domAnimation, children: /* @__PURE__ */ jsxs3("div", { className: cn("w-full", className), children: [
405
+ /* @__PURE__ */ jsx3("div", { className: "mb-1.5 flex justify-end", children: /* @__PURE__ */ jsx3("span", { className: "text-xs font-medium text-foreground tabular-nums", children: valueLabel }) }),
406
+ /* @__PURE__ */ jsxs3(
407
+ "div",
408
+ {
409
+ ref: trackRef,
410
+ onPointerDown,
411
+ onPointerMove,
412
+ onPointerUp: endDrag,
413
+ onPointerCancel: endDrag,
414
+ className: cn(
415
+ "relative flex h-10 w-full touch-none select-none items-center overflow-hidden rounded-lg bg-muted",
416
+ disabled ? "pointer-events-none opacity-50" : "cursor-grab active:cursor-grabbing"
417
+ ),
418
+ children: [
419
+ /* @__PURE__ */ jsx3(m2.div, { className: "absolute inset-y-0 left-0 overflow-hidden", style: { width: left }, children: isMaxed ? /* @__PURE__ */ jsx3(
420
+ "div",
421
+ {
422
+ className: "absolute inset-0",
423
+ style: { backgroundImage: fillGradient },
424
+ children: /* @__PURE__ */ jsx3(
425
+ m2.div,
426
+ {
427
+ className: "absolute inset-0",
428
+ style: {
429
+ backgroundImage: "radial-gradient(circle, rgba(255,255,255,0.85) 1.3px, transparent 1.3px)",
430
+ backgroundSize: "10px 10px"
431
+ },
432
+ animate: reduce ? void 0 : { backgroundPositionX: ["0px", "10px"] },
433
+ transition: { duration: dotDriftDuration, repeat: Infinity, ease: "linear" }
434
+ }
435
+ )
436
+ }
437
+ ) : /* @__PURE__ */ jsx3("div", { className: "absolute inset-0 bg-foreground/15" }) }),
438
+ /* @__PURE__ */ jsx3("div", { className: "pointer-events-none absolute inset-x-2 inset-y-0", children: steps.map((tick) => {
439
+ const tp = (tick.value - min) / (max - min) * 100;
440
+ return /* @__PURE__ */ jsx3(
441
+ "span",
442
+ {
443
+ className: cn(
444
+ "absolute top-1/2 -translate-x-1/2 -translate-y-1/2 rounded-full",
445
+ isMaxed ? "size-1.5 bg-white shadow-[0_0_0_1.5px_rgba(0,0,0,0.35)]" : "size-1 bg-foreground/25"
446
+ ),
447
+ style: { left: `${tp}%` }
448
+ },
449
+ tick.value
450
+ );
451
+ }) }),
452
+ isMaxed && !reduce && /* @__PURE__ */ jsx3(
453
+ m2.div,
454
+ {
455
+ "aria-hidden": true,
456
+ className: "pointer-events-none absolute top-1/2 h-5 w-1.5 rounded-sm",
457
+ style: { left, x: thumbX, y: "-50%", boxShadow: `0 0 9px 3px ${glowColor}` },
458
+ animate: { opacity: [0.25, 0.9, 0.25], scale: [1, 1.15, 1] },
459
+ transition: { duration: glowDuration, repeat: Infinity, ease: "easeInOut", delay: seed * 0.5 }
460
+ }
461
+ ),
462
+ /* @__PURE__ */ jsx3(
463
+ m2.div,
464
+ {
465
+ id,
466
+ role: "slider",
467
+ tabIndex: disabled ? -1 : 0,
468
+ "aria-label": ariaLabel,
469
+ "aria-labelledby": ariaLabelledBy,
470
+ "aria-valuemin": min,
471
+ "aria-valuemax": max,
472
+ "aria-valuenow": Math.round(current),
473
+ "aria-valuetext": valueLabel,
474
+ "aria-disabled": disabled || void 0,
475
+ onKeyDown,
476
+ animate: reduce ? void 0 : { scaleY: active ? 1.35 : 1 },
477
+ transition: SPRING_BOUNCY,
478
+ className: cn(
479
+ "absolute top-1/2 h-5 w-1.5 rounded-sm bg-foreground shadow-sm outline-none ring-foreground/30 focus-visible:ring-4",
480
+ // Background-colored ring keeps the thumb legible against the accent fill at any position.
481
+ isMaxed && "ring-2 ring-background"
482
+ ),
483
+ style: { left, x: thumbX, y: "-50%" }
484
+ }
485
+ )
486
+ ]
487
+ }
488
+ ),
489
+ steps.length > 0 && /* @__PURE__ */ jsx3("div", { className: "relative mt-1.5 h-4", children: /* @__PURE__ */ jsx3("div", { className: "absolute inset-x-2 inset-y-0", children: steps.map((tick, index) => {
490
+ const isFirst = index === 0;
491
+ const isLast = index === steps.length - 1;
492
+ const tp = (tick.value - min) / (max - min) * 100;
493
+ return /* @__PURE__ */ jsx3(
494
+ "span",
495
+ {
496
+ className: cn(
497
+ "absolute text-[10px] font-medium text-muted-foreground",
498
+ isFirst && "left-0",
499
+ isLast && "right-0",
500
+ !isFirst && !isLast && "-translate-x-1/2"
501
+ ),
502
+ style: !isFirst && !isLast ? { left: `${tp}%` } : void 0,
503
+ children: tick.label
504
+ },
505
+ tick.value
506
+ );
507
+ }) }) })
508
+ ] }) });
509
+ }
510
+
511
+ // src/components/motion/tabs.tsx
512
+ import { LazyMotion as LazyMotion3, m as m3, domMax as domMax2, MotionConfig, useReducedMotion as useReducedMotion4 } from "motion/react";
513
+ import {
514
+ createContext as createContext2,
515
+ useCallback as useCallback3,
516
+ useContext,
517
+ useId as useId2,
518
+ useMemo as useMemo3,
519
+ useState as useState3
520
+ } from "react";
521
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
522
+ var TabsCtx = createContext2(null);
523
+ function useTabs() {
524
+ const ctx = useContext(TabsCtx);
525
+ if (!ctx) throw new Error("Tabs.* must be used inside <Tabs>");
526
+ return ctx;
527
+ }
528
+ var transition = {
529
+ type: "spring",
530
+ stiffness: 170,
531
+ damping: 24,
532
+ mass: 1.2
533
+ };
534
+ function Tabs({
535
+ defaultValue,
536
+ value,
537
+ onValueChange,
538
+ variant = "pill",
539
+ children,
540
+ className
541
+ }) {
542
+ const [internal, setInternal] = useState3(defaultValue ?? "");
543
+ const layoutId = useId2();
544
+ const reduce = useReducedMotion4();
545
+ const controlled = value !== void 0;
546
+ const current = controlled ? value : internal;
547
+ const setValue = useCallback3(
548
+ (v) => {
549
+ if (!controlled) setInternal(v);
550
+ onValueChange?.(v);
551
+ },
552
+ [controlled, onValueChange]
553
+ );
554
+ const ctx = useMemo3(
555
+ () => ({ value: current, setValue, layoutId, variant }),
556
+ [current, setValue, layoutId, variant]
557
+ );
558
+ return /* @__PURE__ */ jsx4(MotionConfig, { transition: reduce ? { duration: 0 } : transition, children: /* @__PURE__ */ jsx4(TabsCtx.Provider, { value: ctx, children: /* @__PURE__ */ jsx4(LazyMotion3, { features: domMax2, children: /* @__PURE__ */ jsx4(m3.div, { layoutRoot: true, className, children }) }) }) });
559
+ }
560
+ var listClasses = {
561
+ pill: "inline-flex items-center gap-1 rounded-full bg-card p-1",
562
+ underline: "inline-flex items-center gap-1 border-b border-border",
563
+ segment: "inline-flex items-center gap-0 rounded-md border border-ui-line bg-ui-fill/40 p-0.5"
564
+ };
565
+ function TabsList({ children, className }) {
566
+ const { variant } = useTabs();
567
+ return /* @__PURE__ */ jsx4("div", { role: "tablist", className: cn(listClasses[variant], className), children });
568
+ }
569
+ function TabsTrigger({
570
+ value,
571
+ children,
572
+ className,
573
+ indicatorClassName
574
+ }) {
575
+ const { value: current, setValue, layoutId, variant } = useTabs();
576
+ const active = current === value;
577
+ if (variant === "underline") {
578
+ return /* @__PURE__ */ jsxs4(
579
+ "button",
580
+ {
581
+ type: "button",
582
+ role: "tab",
583
+ "aria-selected": active,
584
+ onClick: () => setValue(value),
585
+ className: cn(
586
+ "relative isolate px-3 pb-2.5 pt-1 -mb-px text-sm font-medium transition-colors min-h-[44px] inline-flex items-center",
587
+ active ? "text-foreground" : "text-muted-foreground hover:text-foreground",
588
+ className
589
+ ),
590
+ children: [
591
+ children,
592
+ active ? /* @__PURE__ */ jsx4(
593
+ m3.span,
594
+ {
595
+ layoutId,
596
+ className: cn("absolute -bottom-px left-0 right-0 h-px bg-primary", indicatorClassName)
597
+ }
598
+ ) : null
599
+ ]
600
+ }
601
+ );
602
+ }
603
+ const isSegment = variant === "segment";
604
+ const radius = variant === "pill" ? "rounded-full" : "rounded-[5px]";
605
+ const indicatorBg = isSegment ? "bg-ui-base shadow-sm ring-1 ring-ui-line" : "bg-primary";
606
+ const activeText = isSegment ? "text-ui-strong" : "text-primary-foreground";
607
+ const inactiveText = isSegment ? "text-ui-subtle hover:text-ui-default" : "text-muted-foreground hover:text-foreground";
608
+ return /* @__PURE__ */ jsxs4("div", { className: "relative", children: [
609
+ active ? /* @__PURE__ */ jsx4(
610
+ m3.span,
611
+ {
612
+ layoutId,
613
+ style: { borderRadius: variant === "pill" ? 9999 : 5 },
614
+ className: cn("absolute inset-0", indicatorBg, radius, indicatorClassName)
615
+ }
616
+ ) : null,
617
+ /* @__PURE__ */ jsx4(
618
+ "button",
619
+ {
620
+ type: "button",
621
+ role: "tab",
622
+ "aria-selected": active,
623
+ onClick: () => setValue(value),
624
+ className: cn(
625
+ "relative z-10 inline-flex items-center justify-center whitespace-nowrap bg-transparent px-3.5 py-1.5 text-sm font-medium capitalize transition-colors outline-none",
626
+ active ? activeText : inactiveText,
627
+ radius,
628
+ className
629
+ ),
630
+ children
631
+ }
632
+ )
633
+ ] });
634
+ }
635
+ export {
636
+ SharedLayoutBg,
637
+ SmoothScroll,
638
+ SteppedSlider,
639
+ Tabs,
640
+ TabsList,
641
+ TabsTrigger
642
+ };
643
+ //# sourceMappingURL=index.js.map