@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.
- package/LICENSE +625 -0
- package/README.md +15 -0
- package/dist/chunk-HCQJTSV3.js +39 -0
- package/dist/chunk-HCQJTSV3.js.map +1 -0
- package/dist/chunk-OU66JJZD.js +7 -0
- package/dist/chunk-OU66JJZD.js.map +1 -0
- package/dist/chunk-PZ5AY32C.js +10 -0
- package/dist/chunk-PZ5AY32C.js.map +1 -0
- package/dist/chunk-TXNSYK4G.js +23 -0
- package/dist/chunk-TXNSYK4G.js.map +1 -0
- package/dist/components/motion/index.d.ts +92 -0
- package/dist/components/motion/index.js +643 -0
- package/dist/components/motion/index.js.map +1 -0
- package/dist/hooks/index.d.ts +3 -0
- package/dist/hooks/index.js +8 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/index.d.ts +241 -0
- package/dist/index.js +1144 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/ease.d.ts +3 -0
- package/dist/lib/ease.js +8 -0
- package/dist/lib/ease.js.map +1 -0
- package/dist/lib/file-tree.d.ts +16 -0
- package/dist/lib/file-tree.js +46 -0
- package/dist/lib/file-tree.js.map +1 -0
- package/dist/lib/highlight.d.ts +14 -0
- package/dist/lib/highlight.js +35 -0
- package/dist/lib/highlight.js.map +1 -0
- package/dist/lib/markdown-plugins.d.ts +6 -0
- package/dist/lib/markdown-plugins.js +11041 -0
- package/dist/lib/markdown-plugins.js.map +1 -0
- package/dist/lib/prompt-diff.d.ts +21 -0
- package/dist/lib/prompt-diff.js +95 -0
- package/dist/lib/prompt-diff.js.map +1 -0
- package/dist/lib/selection.d.ts +11 -0
- package/dist/lib/selection.js +15 -0
- package/dist/lib/selection.js.map +1 -0
- package/dist/lib/theme.d.ts +14 -0
- package/dist/lib/theme.js +78 -0
- package/dist/lib/theme.js.map +1 -0
- package/dist/lib/utils.d.ts +15 -0
- package/dist/lib/utils.js +14 -0
- package/dist/lib/utils.js.map +1 -0
- 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
|