doodleui-react 0.1.1 → 0.3.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/dist/index.cjs CHANGED
@@ -7,7 +7,15 @@ var jsxRuntime = require('react/jsx-runtime');
7
7
  var CheckboxPrimitive = require('@radix-ui/react-checkbox');
8
8
  var RadioGroupPrimitive = require('@radix-ui/react-radio-group');
9
9
  var Dialog = require('@radix-ui/react-dialog');
10
+ var framerMotion = require('framer-motion');
10
11
  var TooltipPrimitive = require('@radix-ui/react-tooltip');
12
+ var SelectPrimitive = require('@radix-ui/react-select');
13
+ var SwitchPrimitive = require('@radix-ui/react-switch');
14
+ var TabsPrimitive = require('@radix-ui/react-tabs');
15
+ var ToastPrimitive = require('@radix-ui/react-toast');
16
+ var AccordionPrimitive = require('@radix-ui/react-accordion');
17
+ var AvatarPrimitive = require('@radix-ui/react-avatar');
18
+ var SliderPrimitive = require('@radix-ui/react-slider');
11
19
 
12
20
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
13
21
 
@@ -34,6 +42,13 @@ var CheckboxPrimitive__namespace = /*#__PURE__*/_interopNamespace(CheckboxPrimit
34
42
  var RadioGroupPrimitive__namespace = /*#__PURE__*/_interopNamespace(RadioGroupPrimitive);
35
43
  var Dialog__namespace = /*#__PURE__*/_interopNamespace(Dialog);
36
44
  var TooltipPrimitive__namespace = /*#__PURE__*/_interopNamespace(TooltipPrimitive);
45
+ var SelectPrimitive__namespace = /*#__PURE__*/_interopNamespace(SelectPrimitive);
46
+ var SwitchPrimitive__namespace = /*#__PURE__*/_interopNamespace(SwitchPrimitive);
47
+ var TabsPrimitive__namespace = /*#__PURE__*/_interopNamespace(TabsPrimitive);
48
+ var ToastPrimitive__namespace = /*#__PURE__*/_interopNamespace(ToastPrimitive);
49
+ var AccordionPrimitive__namespace = /*#__PURE__*/_interopNamespace(AccordionPrimitive);
50
+ var AvatarPrimitive__namespace = /*#__PURE__*/_interopNamespace(AvatarPrimitive);
51
+ var SliderPrimitive__namespace = /*#__PURE__*/_interopNamespace(SliderPrimitive);
37
52
 
38
53
  // src/types.ts
39
54
  function toRoughOptions(props) {
@@ -69,6 +84,11 @@ var SKETCH_COLORS = {
69
84
  };
70
85
 
71
86
  // src/utils.ts
87
+ function assignRef(ref, value) {
88
+ if (!ref) return;
89
+ if (typeof ref === "function") ref(value);
90
+ else ref.current = value;
91
+ }
72
92
  function randomSeed() {
73
93
  return Math.floor(Math.random() * 2 ** 31);
74
94
  }
@@ -88,6 +108,13 @@ function cn(...parts) {
88
108
  const value = parts.filter(Boolean).join(" ");
89
109
  return value.length > 0 ? value : void 0;
90
110
  }
111
+ function deriveSeed(base, key) {
112
+ let hash = 0;
113
+ for (let i = 0; i < key.length; i += 1) {
114
+ hash = hash * 31 + key.charCodeAt(i) | 0;
115
+ }
116
+ return (base + (hash >>> 0)) % 2 ** 31;
117
+ }
91
118
  var SketchSeedContext = react.createContext(null);
92
119
  function SketchSeedProvider({
93
120
  children,
@@ -262,6 +289,177 @@ function RoughSvg({
262
289
  }
263
290
  );
264
291
  }
292
+ var DoodleUIContext = react.createContext(null);
293
+ function DoodleUIProvider({
294
+ children,
295
+ animate = true,
296
+ forceAnimate = false
297
+ }) {
298
+ const value = react.useMemo(
299
+ () => ({ animate, forceAnimate }),
300
+ [animate, forceAnimate]
301
+ );
302
+ return /* @__PURE__ */ jsxRuntime.jsx(DoodleUIContext.Provider, { value, children });
303
+ }
304
+ function useDoodleUI() {
305
+ return react.useContext(DoodleUIContext) ?? { animate: true, forceAnimate: false };
306
+ }
307
+
308
+ // src/animations/resolveAnimate.ts
309
+ function resolveAnimate({
310
+ animate,
311
+ providerAnimate = true,
312
+ forceAnimate = false,
313
+ prefersReducedMotion = false
314
+ }) {
315
+ if (prefersReducedMotion && !forceAnimate) return false;
316
+ if (animate !== void 0) return animate;
317
+ return providerAnimate;
318
+ }
319
+ function subscribe(onStoreChange) {
320
+ const media = window.matchMedia("(prefers-reduced-motion: reduce)");
321
+ media.addEventListener("change", onStoreChange);
322
+ return () => media.removeEventListener("change", onStoreChange);
323
+ }
324
+ function getSnapshot() {
325
+ return window.matchMedia("(prefers-reduced-motion: reduce)").matches;
326
+ }
327
+ function getServerSnapshot() {
328
+ return false;
329
+ }
330
+ function usePrefersReducedMotion() {
331
+ return react.useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
332
+ }
333
+
334
+ // src/animations/useAnimate.ts
335
+ function useAnimate(animate) {
336
+ const { animate: providerAnimate, forceAnimate } = useDoodleUI();
337
+ const prefersReducedMotion = usePrefersReducedMotion();
338
+ return resolveAnimate({
339
+ animate,
340
+ providerAnimate,
341
+ forceAnimate,
342
+ prefersReducedMotion
343
+ });
344
+ }
345
+ function useTweenNumber(target, enabled, duration = 400) {
346
+ const [value, setValue] = react.useState(target);
347
+ const valueRef = react.useRef(target);
348
+ valueRef.current = value;
349
+ react.useEffect(() => {
350
+ if (!enabled) {
351
+ valueRef.current = target;
352
+ setValue(target);
353
+ return;
354
+ }
355
+ const from = valueRef.current;
356
+ if (from === target) return;
357
+ const start = performance.now();
358
+ let frame = 0;
359
+ const tick = (now) => {
360
+ const t = Math.min(1, (now - start) / duration);
361
+ const eased = 1 - (1 - t) ** 3;
362
+ const next = from + (target - from) * eased;
363
+ valueRef.current = next;
364
+ setValue(next);
365
+ if (t < 1) frame = requestAnimationFrame(tick);
366
+ };
367
+ frame = requestAnimationFrame(tick);
368
+ return () => cancelAnimationFrame(frame);
369
+ }, [target, enabled, duration]);
370
+ return enabled ? value : target;
371
+ }
372
+ var DRAW_IN_DURATION_MS = 400;
373
+ var DRAW_IN_ALERT_MS = 200;
374
+ var DRAW_IN_TOOLTIP_MS = 180;
375
+ var DRAW_IN_MARK_MS = 240;
376
+ var TABLE_STAGGER_MS = 40;
377
+ var DRAW_IN_EASING = "ease-out";
378
+ var running = /* @__PURE__ */ new WeakMap();
379
+ function collectStrokePaths(root) {
380
+ const groups = root.querySelectorAll("g");
381
+ if (groups.length > 0) {
382
+ const paths = [];
383
+ groups.forEach((group) => {
384
+ const children = group.querySelectorAll(":scope > path");
385
+ if (children.length === 0) return;
386
+ paths.push(children[children.length - 1]);
387
+ });
388
+ return paths;
389
+ }
390
+ return Array.from(root.querySelectorAll("path"));
391
+ }
392
+ function getStrokePaths(target) {
393
+ if (target instanceof SVGPathElement) return [target];
394
+ if (target instanceof SVGSVGElement) return collectStrokePaths(target);
395
+ const svgs = target.querySelectorAll("svg");
396
+ if (svgs.length > 0) {
397
+ return Array.from(svgs).flatMap((svg) => collectStrokePaths(svg));
398
+ }
399
+ return collectStrokePaths(target);
400
+ }
401
+ function clearDash(path) {
402
+ path.style.strokeDasharray = "";
403
+ path.style.strokeDashoffset = "";
404
+ }
405
+ function cancelDrawIn(target) {
406
+ if (!target) return;
407
+ const animations = running.get(target);
408
+ animations?.forEach((animation) => animation.cancel());
409
+ running.delete(target);
410
+ getStrokePaths(target).forEach(clearDash);
411
+ }
412
+ function drawIn(target, duration = DRAW_IN_DURATION_MS, delay = 0) {
413
+ cancelDrawIn(target);
414
+ const paths = getStrokePaths(target);
415
+ const animations = [];
416
+ for (const path of paths) {
417
+ let length = 0;
418
+ try {
419
+ length = path.getTotalLength();
420
+ } catch {
421
+ continue;
422
+ }
423
+ if (length <= 0) continue;
424
+ path.style.strokeDasharray = `${length}`;
425
+ path.style.strokeDashoffset = `${length}`;
426
+ const animation = path.animate(
427
+ [{ strokeDashoffset: String(length) }, { strokeDashoffset: "0" }],
428
+ { duration, delay, easing: DRAW_IN_EASING, fill: "forwards" }
429
+ );
430
+ animation.finished.then(() => {
431
+ clearDash(path);
432
+ }).catch(() => {
433
+ });
434
+ animations.push(animation);
435
+ }
436
+ running.set(target, animations);
437
+ }
438
+ function useDrawIn(pathRef, duration = DRAW_IN_DURATION_MS, enabled = true, replayKey, delay = 0) {
439
+ react.useLayoutEffect(() => {
440
+ const target = pathRef.current;
441
+ if (!target) return;
442
+ if (!enabled) {
443
+ cancelDrawIn(target);
444
+ return;
445
+ }
446
+ const apply = () => drawIn(target, duration, delay);
447
+ if (getStrokePaths(target).length > 0) {
448
+ apply();
449
+ return () => cancelDrawIn(target);
450
+ }
451
+ const observer = new MutationObserver(() => {
452
+ if (getStrokePaths(target).length === 0) return;
453
+ observer.disconnect();
454
+ apply();
455
+ });
456
+ observer.observe(target, { childList: true, subtree: true });
457
+ return () => {
458
+ observer.disconnect();
459
+ cancelDrawIn(target);
460
+ };
461
+ }, [pathRef, duration, enabled, replayKey, delay]);
462
+ }
265
463
  var SketchBox = react.forwardRef(
266
464
  function SketchBox2({
267
465
  children,
@@ -280,12 +478,21 @@ var SketchBox = react.forwardRef(
280
478
  strokeWidth,
281
479
  inset,
282
480
  path,
481
+ animate,
482
+ drawInDuration = DRAW_IN_DURATION_MS,
483
+ drawInKey,
283
484
  ...rest
284
485
  }, ref) {
486
+ const rootRef = react.useRef(null);
487
+ const shouldAnimate = useAnimate(animate);
488
+ useDrawIn(rootRef, drawInDuration, shouldAnimate, drawInKey);
285
489
  return /* @__PURE__ */ jsxRuntime.jsxs(
286
490
  "div",
287
491
  {
288
- ref,
492
+ ref: (node) => {
493
+ rootRef.current = node;
494
+ assignRef(ref, node);
495
+ },
289
496
  className: cn(className),
290
497
  style: { position: "relative", ...style },
291
498
  ...rest,
@@ -343,6 +550,10 @@ var SIZE_STYLES = {
343
550
  md: { fontSize: 15, padding: "8px 16px", minHeight: 38 },
344
551
  lg: { fontSize: 17, padding: "11px 22px", minHeight: 46 }
345
552
  };
553
+ function assignRef2(ref, value) {
554
+ if (typeof ref === "function") ref(value);
555
+ else if (ref) ref.current = value;
556
+ }
346
557
  var Button = react.forwardRef(
347
558
  function Button2({
348
559
  children,
@@ -357,18 +568,28 @@ var Button = react.forwardRef(
357
568
  fillStyle,
358
569
  strokeWidth,
359
570
  disabled,
571
+ animate,
360
572
  onMouseEnter,
361
573
  onMouseLeave,
362
574
  ...rest
363
575
  }, ref) {
576
+ const rootRef = react.useRef(null);
364
577
  const [hovered, setHovered] = react.useState(false);
578
+ const shouldAnimate = useAnimate(animate);
579
+ const resolvedSeed = useResolvedSeed(seed);
580
+ const hoverSeed = deriveSeed(resolvedSeed, "hover");
581
+ const sketchSeed = shouldAnimate && hovered && !disabled ? hoverSeed : resolvedSeed;
365
582
  const ink = sketchColor ?? SKETCH_COLORS.ink;
366
583
  const fill = variant === "primary" ? SKETCH_COLORS.accentFill : variant === "secondary" ? SKETCH_COLORS.secondaryFill : void 0;
367
584
  const stroke = variant === "ghost" && !hovered ? "transparent" : variant === "primary" ? sketchColor ?? SKETCH_COLORS.accent : ink;
585
+ useDrawIn(rootRef, DRAW_IN_DURATION_MS, shouldAnimate, sketchSeed);
368
586
  return /* @__PURE__ */ jsxRuntime.jsxs(
369
587
  "button",
370
588
  {
371
- ref,
589
+ ref: (node) => {
590
+ rootRef.current = node;
591
+ assignRef2(ref, node);
592
+ },
372
593
  type: "button",
373
594
  className: cn(className),
374
595
  disabled,
@@ -404,12 +625,12 @@ var Button = react.forwardRef(
404
625
  {
405
626
  shape: "rectangle",
406
627
  roughness,
407
- seed,
628
+ seed: sketchSeed,
408
629
  sketchColor: stroke,
409
630
  bowing,
410
631
  fillStyle: fillStyle ?? "hachure",
411
632
  fill,
412
- strokeWidth: hovered ? (strokeWidth ?? 1.75) + 0.4 : strokeWidth
633
+ strokeWidth: !shouldAnimate && hovered ? (strokeWidth ?? 1.75) + 0.4 : strokeWidth
413
634
  }
414
635
  ),
415
636
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: { position: "relative", zIndex: 1 }, children })
@@ -431,11 +652,18 @@ var Input = react.forwardRef(function Input2({
431
652
  id,
432
653
  onFocus,
433
654
  onBlur,
655
+ animate,
434
656
  ...rest
435
657
  }, ref) {
436
658
  const [focused, setFocused] = react.useState(false);
659
+ const fieldRef = react.useRef(null);
660
+ const shouldAnimate = useAnimate(animate);
661
+ const resolvedSeed = useResolvedSeed(seed);
662
+ const focusSeed = deriveSeed(resolvedSeed, "focus");
663
+ const sketchSeed = shouldAnimate && focused ? focusSeed : resolvedSeed;
437
664
  const ink = sketchColor ?? SKETCH_COLORS.ink;
438
665
  const inputId = id;
666
+ useDrawIn(fieldRef, DRAW_IN_DURATION_MS, shouldAnimate, sketchSeed);
439
667
  return /* @__PURE__ */ jsxRuntime.jsxs(
440
668
  "label",
441
669
  {
@@ -459,17 +687,17 @@ var Input = react.forwardRef(function Input2({
459
687
  children: label
460
688
  }
461
689
  ) : null,
462
- /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { position: "relative", display: "block" }, children: [
690
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { ref: fieldRef, style: { position: "relative", display: "block" }, children: [
463
691
  /* @__PURE__ */ jsxRuntime.jsx(
464
692
  RoughSvg,
465
693
  {
466
694
  shape: "rectangle",
467
695
  roughness,
468
- seed,
696
+ seed: sketchSeed,
469
697
  sketchColor: focused ? SKETCH_COLORS.accent : ink,
470
698
  bowing,
471
699
  fillStyle,
472
- strokeWidth: focused ? (strokeWidth ?? 1.75) + 0.35 : strokeWidth
700
+ strokeWidth: focused && !shouldAnimate ? (strokeWidth ?? 1.75) + 0.35 : focused ? (strokeWidth ?? 1.75) + 0.2 : strokeWidth
473
701
  }
474
702
  ),
475
703
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -523,10 +751,17 @@ var Textarea = react.forwardRef(
523
751
  rows = 4,
524
752
  onFocus,
525
753
  onBlur,
754
+ animate,
526
755
  ...rest
527
756
  }, ref) {
528
757
  const [focused, setFocused] = react.useState(false);
758
+ const fieldRef = react.useRef(null);
759
+ const shouldAnimate = useAnimate(animate);
760
+ const resolvedSeed = useResolvedSeed(seed);
761
+ const focusSeed = deriveSeed(resolvedSeed, "focus");
762
+ const sketchSeed = shouldAnimate && focused ? focusSeed : resolvedSeed;
529
763
  const ink = sketchColor ?? SKETCH_COLORS.ink;
764
+ useDrawIn(fieldRef, DRAW_IN_DURATION_MS, shouldAnimate, sketchSeed);
530
765
  return /* @__PURE__ */ jsxRuntime.jsxs(
531
766
  "label",
532
767
  {
@@ -550,17 +785,17 @@ var Textarea = react.forwardRef(
550
785
  children: label
551
786
  }
552
787
  ) : null,
553
- /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { position: "relative", display: "block" }, children: [
788
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { ref: fieldRef, style: { position: "relative", display: "block" }, children: [
554
789
  /* @__PURE__ */ jsxRuntime.jsx(
555
790
  RoughSvg,
556
791
  {
557
792
  shape: "rectangle",
558
793
  roughness,
559
- seed,
794
+ seed: sketchSeed,
560
795
  sketchColor: focused ? SKETCH_COLORS.accent : ink,
561
796
  bowing,
562
797
  fillStyle,
563
- strokeWidth: focused ? (strokeWidth ?? 1.75) + 0.35 : strokeWidth
798
+ strokeWidth: focused && !shouldAnimate ? (strokeWidth ?? 1.75) + 0.35 : focused ? (strokeWidth ?? 1.75) + 0.2 : strokeWidth
564
799
  }
565
800
  ),
566
801
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -605,6 +840,36 @@ var Textarea = react.forwardRef(
605
840
  );
606
841
  var BOX = 20;
607
842
  var CHECK_PATH = "M 4.5 10.5 L 8.5 14.5 L 15.5 5.5";
843
+ function CheckMark({
844
+ roughness,
845
+ seed,
846
+ bowing,
847
+ strokeWidth,
848
+ shouldAnimate
849
+ }) {
850
+ const ref = react.useRef(null);
851
+ useDrawIn(ref, DRAW_IN_MARK_MS, shouldAnimate);
852
+ return /* @__PURE__ */ jsxRuntime.jsx(
853
+ "span",
854
+ {
855
+ ref,
856
+ style: { position: "absolute", inset: 0, pointerEvents: "none" },
857
+ children: /* @__PURE__ */ jsxRuntime.jsx(
858
+ RoughSvg,
859
+ {
860
+ shape: "path",
861
+ path: CHECK_PATH,
862
+ roughness: (roughness ?? 1.5) * 0.7,
863
+ seed,
864
+ sketchColor: SKETCH_COLORS.accent,
865
+ bowing,
866
+ strokeWidth: (strokeWidth ?? 1.6) + 0.4,
867
+ inset: 0
868
+ }
869
+ )
870
+ }
871
+ );
872
+ }
608
873
  var Checkbox = react.forwardRef(
609
874
  function Checkbox2({
610
875
  className,
@@ -620,11 +885,15 @@ var Checkbox = react.forwardRef(
620
885
  defaultChecked,
621
886
  onCheckedChange,
622
887
  id,
888
+ animate,
623
889
  ...rest
624
890
  }, ref) {
625
891
  const ink = sketchColor ?? SKETCH_COLORS.ink;
626
892
  const generatedId = react.useId();
627
893
  const inputId = id ?? generatedId;
894
+ const boxRef = react.useRef(null);
895
+ const shouldAnimate = useAnimate(animate);
896
+ useDrawIn(boxRef, DRAW_IN_DURATION_MS, shouldAnimate);
628
897
  return /* @__PURE__ */ jsxRuntime.jsxs(
629
898
  "span",
630
899
  {
@@ -659,16 +928,23 @@ var Checkbox = react.forwardRef(
659
928
  ...rest,
660
929
  children: [
661
930
  /* @__PURE__ */ jsxRuntime.jsx(
662
- RoughSvg,
931
+ "span",
663
932
  {
664
- shape: "rectangle",
665
- roughness,
666
- seed,
667
- sketchColor: ink,
668
- bowing,
669
- fillStyle,
670
- strokeWidth: strokeWidth ?? 1.6,
671
- inset: 1.5
933
+ ref: boxRef,
934
+ style: { position: "absolute", inset: 0, pointerEvents: "none" },
935
+ children: /* @__PURE__ */ jsxRuntime.jsx(
936
+ RoughSvg,
937
+ {
938
+ shape: "rectangle",
939
+ roughness,
940
+ seed,
941
+ sketchColor: ink,
942
+ bowing,
943
+ fillStyle,
944
+ strokeWidth: strokeWidth ?? 1.6,
945
+ inset: 1.5
946
+ }
947
+ )
672
948
  }
673
949
  ),
674
950
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -680,16 +956,13 @@ var Checkbox = react.forwardRef(
680
956
  display: "block"
681
957
  },
682
958
  children: /* @__PURE__ */ jsxRuntime.jsx(
683
- RoughSvg,
959
+ CheckMark,
684
960
  {
685
- shape: "path",
686
- path: CHECK_PATH,
687
- roughness: (roughness ?? 1.5) * 0.7,
961
+ roughness,
688
962
  seed,
689
- sketchColor: SKETCH_COLORS.accent,
690
963
  bowing,
691
- strokeWidth: (strokeWidth ?? 1.6) + 0.4,
692
- inset: 0
964
+ strokeWidth,
965
+ shouldAnimate
693
966
  }
694
967
  )
695
968
  }
@@ -730,6 +1003,53 @@ var RadioGroup = react.forwardRef(
730
1003
  }
731
1004
  );
732
1005
  var SIZE = 20;
1006
+ function RadioDot({
1007
+ roughness,
1008
+ seed,
1009
+ bowing,
1010
+ shouldAnimate
1011
+ }) {
1012
+ const ref = react.useRef(null);
1013
+ useDrawIn(ref, DRAW_IN_MARK_MS, shouldAnimate);
1014
+ react.useLayoutEffect(() => {
1015
+ const node = ref.current;
1016
+ if (!node || !shouldAnimate) return;
1017
+ const animation = node.animate(
1018
+ [
1019
+ { transform: "scale(0.35)", opacity: 0 },
1020
+ { transform: "scale(1)", opacity: 1 }
1021
+ ],
1022
+ { duration: 180, easing: "ease-out", fill: "forwards" }
1023
+ );
1024
+ return () => animation.cancel();
1025
+ }, [shouldAnimate]);
1026
+ return /* @__PURE__ */ jsxRuntime.jsx(
1027
+ "span",
1028
+ {
1029
+ ref,
1030
+ style: {
1031
+ position: "absolute",
1032
+ inset: 0,
1033
+ pointerEvents: "none",
1034
+ display: "block"
1035
+ },
1036
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1037
+ RoughSvg,
1038
+ {
1039
+ shape: "ellipse",
1040
+ roughness: (roughness ?? 1.5) + 0.2,
1041
+ seed,
1042
+ sketchColor: SKETCH_COLORS.accent,
1043
+ fill: SKETCH_COLORS.accent,
1044
+ fillStyle: "solid",
1045
+ bowing,
1046
+ strokeWidth: 1,
1047
+ inset: 6
1048
+ }
1049
+ )
1050
+ }
1051
+ );
1052
+ }
733
1053
  var Radio = react.forwardRef(function Radio2({
734
1054
  className,
735
1055
  style,
@@ -741,11 +1061,15 @@ var Radio = react.forwardRef(function Radio2({
741
1061
  fillStyle,
742
1062
  strokeWidth,
743
1063
  id,
1064
+ animate,
744
1065
  ...rest
745
1066
  }, ref) {
746
1067
  const ink = sketchColor ?? SKETCH_COLORS.ink;
747
1068
  const generatedId = react.useId();
748
1069
  const inputId = id ?? generatedId;
1070
+ const ringRef = react.useRef(null);
1071
+ const shouldAnimate = useAnimate(animate);
1072
+ useDrawIn(ringRef, DRAW_IN_DURATION_MS, shouldAnimate);
749
1073
  return /* @__PURE__ */ jsxRuntime.jsxs(
750
1074
  "span",
751
1075
  {
@@ -778,16 +1102,23 @@ var Radio = react.forwardRef(function Radio2({
778
1102
  ...rest,
779
1103
  children: [
780
1104
  /* @__PURE__ */ jsxRuntime.jsx(
781
- RoughSvg,
1105
+ "span",
782
1106
  {
783
- shape: "ellipse",
784
- roughness,
785
- seed,
786
- sketchColor: ink,
787
- bowing,
788
- fillStyle,
789
- strokeWidth: strokeWidth ?? 1.6,
790
- inset: 1.5
1107
+ ref: ringRef,
1108
+ style: { position: "absolute", inset: 0, pointerEvents: "none" },
1109
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1110
+ RoughSvg,
1111
+ {
1112
+ shape: "ellipse",
1113
+ roughness,
1114
+ seed,
1115
+ sketchColor: ink,
1116
+ bowing,
1117
+ fillStyle,
1118
+ strokeWidth: strokeWidth ?? 1.6,
1119
+ inset: 1.5
1120
+ }
1121
+ )
791
1122
  }
792
1123
  ),
793
1124
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -799,17 +1130,12 @@ var Radio = react.forwardRef(function Radio2({
799
1130
  display: "block"
800
1131
  },
801
1132
  children: /* @__PURE__ */ jsxRuntime.jsx(
802
- RoughSvg,
1133
+ RadioDot,
803
1134
  {
804
- shape: "ellipse",
805
- roughness: (roughness ?? 1.5) + 0.2,
1135
+ roughness,
806
1136
  seed,
807
- sketchColor: SKETCH_COLORS.accent,
808
- fill: SKETCH_COLORS.accent,
809
- fillStyle: "solid",
810
1137
  bowing,
811
- strokeWidth: 1,
812
- inset: 6
1138
+ shouldAnimate
813
1139
  }
814
1140
  )
815
1141
  }
@@ -843,6 +1169,7 @@ var Card = react.forwardRef(function Card2({
843
1169
  bowing,
844
1170
  fillStyle,
845
1171
  strokeWidth,
1172
+ animate,
846
1173
  ...rest
847
1174
  }, ref) {
848
1175
  const boxProps = {
@@ -853,7 +1180,8 @@ var Card = react.forwardRef(function Card2({
853
1180
  sketchColor: sketchColor ?? SKETCH_COLORS.ink,
854
1181
  bowing,
855
1182
  fillStyle,
856
- strokeWidth
1183
+ strokeWidth,
1184
+ animate
857
1185
  };
858
1186
  return /* @__PURE__ */ jsxRuntime.jsxs(
859
1187
  SketchBox,
@@ -893,6 +1221,7 @@ var Badge = react.forwardRef(function Badge2({
893
1221
  bowing,
894
1222
  fillStyle,
895
1223
  strokeWidth,
1224
+ animate,
896
1225
  ...rest
897
1226
  }, ref) {
898
1227
  const ink = variant === "accent" ? sketchColor ?? SKETCH_COLORS.accent : sketchColor ?? SKETCH_COLORS.ink;
@@ -920,6 +1249,7 @@ var Badge = react.forwardRef(function Badge2({
920
1249
  sketchColor: ink,
921
1250
  bowing,
922
1251
  strokeWidth: strokeWidth ?? 1.4,
1252
+ animate,
923
1253
  ...rest,
924
1254
  children: /* @__PURE__ */ jsxRuntime.jsx("span", { ref, children })
925
1255
  }
@@ -950,6 +1280,7 @@ var Alert = react.forwardRef(function Alert2({
950
1280
  fillStyle,
951
1281
  strokeWidth,
952
1282
  role = "status",
1283
+ animate,
953
1284
  ...rest
954
1285
  }, ref) {
955
1286
  const color = sketchColor ?? VARIANT_COLOR[variant];
@@ -968,6 +1299,8 @@ var Alert = react.forwardRef(function Alert2({
968
1299
  fillStyle: fillStyle ?? "hachure",
969
1300
  fill: VARIANT_FILL[variant],
970
1301
  strokeWidth,
1302
+ animate,
1303
+ drawInDuration: DRAW_IN_ALERT_MS,
971
1304
  ...rest,
972
1305
  children: [
973
1306
  title ? /* @__PURE__ */ jsxRuntime.jsx(
@@ -1000,15 +1333,27 @@ function Modal({
1000
1333
  sketchColor,
1001
1334
  bowing,
1002
1335
  fillStyle,
1003
- strokeWidth
1336
+ strokeWidth,
1337
+ animate
1004
1338
  }) {
1005
1339
  const ink = sketchColor ?? SKETCH_COLORS.ink;
1006
- return /* @__PURE__ */ jsxRuntime.jsxs(Dialog__namespace.Root, { open, defaultOpen, onOpenChange, children: [
1340
+ const [uncontrolled, setUncontrolled] = react.useState(defaultOpen === true);
1341
+ const isOpen = open ?? uncontrolled;
1342
+ const shouldAnimate = useAnimate(animate);
1343
+ function handleOpenChange(next) {
1344
+ setUncontrolled(next);
1345
+ onOpenChange?.(next);
1346
+ }
1347
+ return /* @__PURE__ */ jsxRuntime.jsxs(Dialog__namespace.Root, { open: isOpen, onOpenChange: handleOpenChange, children: [
1007
1348
  trigger ? /* @__PURE__ */ jsxRuntime.jsx(Dialog__namespace.Trigger, { asChild: true, children: trigger }) : null,
1008
- /* @__PURE__ */ jsxRuntime.jsxs(Dialog__namespace.Portal, { children: [
1009
- /* @__PURE__ */ jsxRuntime.jsx(
1010
- Dialog__namespace.Overlay,
1349
+ /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: isOpen ? /* @__PURE__ */ jsxRuntime.jsxs(Dialog__namespace.Portal, { forceMount: true, children: [
1350
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog__namespace.Overlay, { asChild: true, forceMount: true, children: /* @__PURE__ */ jsxRuntime.jsx(
1351
+ framerMotion.motion.div,
1011
1352
  {
1353
+ initial: shouldAnimate ? { opacity: 0 } : false,
1354
+ animate: { opacity: 1 },
1355
+ exit: shouldAnimate ? { opacity: 0 } : void 0,
1356
+ transition: shouldAnimate ? { duration: 0.2, ease: "easeOut" } : { duration: 0 },
1012
1357
  style: {
1013
1358
  position: "fixed",
1014
1359
  inset: 0,
@@ -1016,92 +1361,121 @@ function Modal({
1016
1361
  zIndex: 70
1017
1362
  }
1018
1363
  }
1019
- ),
1364
+ ) }),
1020
1365
  /* @__PURE__ */ jsxRuntime.jsx(
1021
- Dialog__namespace.Content,
1366
+ "div",
1022
1367
  {
1023
- className: cn(className),
1024
1368
  style: {
1025
1369
  position: "fixed",
1026
- left: "50%",
1027
- top: "50%",
1028
- transform: "translate(-50%, -50%)",
1370
+ inset: 0,
1029
1371
  zIndex: 80,
1030
- width: "min(480px, calc(100vw - 32px))",
1031
- outline: "none"
1372
+ display: "flex",
1373
+ alignItems: "center",
1374
+ justifyContent: "center",
1375
+ pointerEvents: "none",
1376
+ padding: 16
1032
1377
  },
1033
- children: /* @__PURE__ */ jsxRuntime.jsxs(
1034
- SketchBox,
1378
+ children: /* @__PURE__ */ jsxRuntime.jsx(Dialog__namespace.Content, { asChild: true, forceMount: true, children: /* @__PURE__ */ jsxRuntime.jsx(
1379
+ framerMotion.motion.div,
1035
1380
  {
1036
- roughness,
1037
- seed,
1038
- sketchColor: ink,
1039
- bowing,
1040
- fillStyle: fillStyle ?? "solid",
1041
- fill: "#f7f6f2",
1042
- strokeWidth: strokeWidth ?? 2,
1043
- shadow: true,
1044
- contentStyle: { padding: "20px 22px 18px" },
1045
- children: [
1046
- /* @__PURE__ */ jsxRuntime.jsxs(
1047
- "div",
1048
- {
1049
- style: {
1050
- display: "flex",
1051
- alignItems: "flex-start",
1052
- justifyContent: "space-between",
1053
- gap: 12,
1054
- marginBottom: title ? 10 : 0
1055
- },
1056
- children: [
1057
- title ? /* @__PURE__ */ jsxRuntime.jsx(
1058
- Dialog__namespace.Title,
1059
- {
1060
- style: {
1061
- margin: 0,
1062
- fontSize: 18,
1063
- fontWeight: doodleUiFontWeight(700),
1064
- fontFamily: doodleUiFontFamily,
1065
- color: ink
1066
- },
1067
- children: title
1068
- }
1069
- ) : /* @__PURE__ */ jsxRuntime.jsx(Dialog__namespace.Title, { style: { position: "absolute", width: 1, height: 1, overflow: "hidden", clip: "rect(0 0 0 0)" }, children: "Dialog" }),
1070
- /* @__PURE__ */ jsxRuntime.jsx(Dialog__namespace.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
1071
- Button,
1072
- {
1073
- variant: "ghost",
1074
- size: "sm",
1075
- roughness,
1076
- seed,
1077
- sketchColor: ink,
1078
- "aria-label": "Close",
1079
- children: "Close"
1080
- }
1081
- ) })
1082
- ]
1083
- }
1084
- ),
1085
- description ? /* @__PURE__ */ jsxRuntime.jsx(
1086
- Dialog__namespace.Description,
1087
- {
1088
- style: {
1089
- margin: "0 0 14px",
1090
- fontSize: 14,
1091
- lineHeight: 1.5,
1092
- color: ink,
1093
- opacity: 0.8
1094
- },
1095
- children: description
1096
- }
1097
- ) : null,
1098
- /* @__PURE__ */ jsxRuntime.jsx("div", { children })
1099
- ]
1381
+ className: cn(className),
1382
+ initial: shouldAnimate ? { opacity: 0, scale: 0.96, y: 10 } : false,
1383
+ animate: { opacity: 1, scale: 1, y: 0 },
1384
+ exit: shouldAnimate ? { opacity: 0, scale: 0.96, y: 8 } : void 0,
1385
+ transition: shouldAnimate ? { duration: 0.22, ease: "easeOut" } : { duration: 0 },
1386
+ style: {
1387
+ width: "min(480px, calc(100vw - 32px))",
1388
+ outline: "none",
1389
+ pointerEvents: "auto"
1390
+ },
1391
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
1392
+ SketchBox,
1393
+ {
1394
+ roughness,
1395
+ seed,
1396
+ sketchColor: ink,
1397
+ bowing,
1398
+ fillStyle: fillStyle ?? "solid",
1399
+ fill: "#f7f6f2",
1400
+ strokeWidth: strokeWidth ?? 2,
1401
+ shadow: true,
1402
+ animate,
1403
+ contentStyle: { padding: "20px 22px 18px" },
1404
+ children: [
1405
+ /* @__PURE__ */ jsxRuntime.jsxs(
1406
+ "div",
1407
+ {
1408
+ style: {
1409
+ display: "flex",
1410
+ alignItems: "flex-start",
1411
+ justifyContent: "space-between",
1412
+ gap: 12,
1413
+ marginBottom: title ? 10 : 0
1414
+ },
1415
+ children: [
1416
+ title ? /* @__PURE__ */ jsxRuntime.jsx(
1417
+ Dialog__namespace.Title,
1418
+ {
1419
+ style: {
1420
+ margin: 0,
1421
+ fontSize: 18,
1422
+ fontWeight: doodleUiFontWeight(700),
1423
+ fontFamily: doodleUiFontFamily,
1424
+ color: ink
1425
+ },
1426
+ children: title
1427
+ }
1428
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
1429
+ Dialog__namespace.Title,
1430
+ {
1431
+ style: {
1432
+ position: "absolute",
1433
+ width: 1,
1434
+ height: 1,
1435
+ overflow: "hidden",
1436
+ clip: "rect(0 0 0 0)"
1437
+ },
1438
+ children: "Dialog"
1439
+ }
1440
+ ),
1441
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog__namespace.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
1442
+ Button,
1443
+ {
1444
+ variant: "ghost",
1445
+ size: "sm",
1446
+ roughness,
1447
+ seed,
1448
+ sketchColor: ink,
1449
+ animate,
1450
+ "aria-label": "Close",
1451
+ children: "Close"
1452
+ }
1453
+ ) })
1454
+ ]
1455
+ }
1456
+ ),
1457
+ description ? /* @__PURE__ */ jsxRuntime.jsx(
1458
+ Dialog__namespace.Description,
1459
+ {
1460
+ style: {
1461
+ margin: "0 0 14px",
1462
+ fontSize: 14,
1463
+ lineHeight: 1.5,
1464
+ color: ink,
1465
+ opacity: 0.8
1466
+ },
1467
+ children: description
1468
+ }
1469
+ ) : null,
1470
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children })
1471
+ ]
1472
+ }
1473
+ )
1100
1474
  }
1101
- )
1475
+ ) })
1102
1476
  }
1103
1477
  )
1104
- ] })
1478
+ ] }) : null })
1105
1479
  ] });
1106
1480
  }
1107
1481
  var ModalRoot = Dialog__namespace.Root;
@@ -1119,13 +1493,20 @@ var Divider = react.forwardRef(
1119
1493
  sketchColor,
1120
1494
  bowing,
1121
1495
  strokeWidth,
1496
+ animate,
1122
1497
  ...rest
1123
1498
  }, ref) {
1499
+ const rootRef = react.useRef(null);
1500
+ const shouldAnimate = useAnimate(animate);
1124
1501
  const horizontal = orientation === "horizontal";
1502
+ useDrawIn(rootRef, DRAW_IN_DURATION_MS, shouldAnimate);
1125
1503
  return /* @__PURE__ */ jsxRuntime.jsx(
1126
1504
  "div",
1127
1505
  {
1128
- ref,
1506
+ ref: (node) => {
1507
+ rootRef.current = node;
1508
+ assignRef(ref, node);
1509
+ },
1129
1510
  role: "separator",
1130
1511
  "aria-orientation": orientation,
1131
1512
  className: cn(className),
@@ -1165,15 +1546,27 @@ var Progress = react.forwardRef(
1165
1546
  bowing,
1166
1547
  fillStyle,
1167
1548
  strokeWidth,
1549
+ animate,
1168
1550
  ...rest
1169
1551
  }, ref) {
1552
+ const rootRef = react.useRef(null);
1553
+ const trackRef = react.useRef(null);
1170
1554
  const ink = sketchColor ?? SKETCH_COLORS.accent;
1171
1555
  const clamped = Math.min(max, Math.max(0, value));
1172
1556
  const percent = max === 0 ? 0 : clamped / max * 100;
1557
+ const shouldAnimate = useAnimate(animate);
1558
+ const displayed = useTweenNumber(percent, shouldAnimate, 420);
1559
+ const resolvedSeed = useResolvedSeed(seed);
1560
+ const fillSeed = shouldAnimate ? deriveSeed(resolvedSeed, `fill-${Math.round(displayed / 6)}`) : resolvedSeed;
1561
+ const fillRoughness = (roughness ?? 1.5) + 0.4 + displayed / 100 * 0.7;
1562
+ useDrawIn(trackRef, DRAW_IN_DURATION_MS, shouldAnimate);
1173
1563
  return /* @__PURE__ */ jsxRuntime.jsxs(
1174
1564
  "div",
1175
1565
  {
1176
- ref,
1566
+ ref: (node) => {
1567
+ rootRef.current = node;
1568
+ assignRef(ref, node);
1569
+ },
1177
1570
  role: "progressbar",
1178
1571
  "aria-valuemin": 0,
1179
1572
  "aria-valuemax": max,
@@ -1188,18 +1581,25 @@ var Progress = react.forwardRef(
1188
1581
  ...rest,
1189
1582
  children: [
1190
1583
  /* @__PURE__ */ jsxRuntime.jsx(
1191
- RoughSvg,
1584
+ "span",
1192
1585
  {
1193
- shape: "rectangle",
1194
- roughness,
1195
- seed,
1196
- sketchColor: SKETCH_COLORS.ink,
1197
- bowing,
1198
- strokeWidth: strokeWidth ?? 1.5,
1199
- inset: 2
1586
+ ref: trackRef,
1587
+ style: { position: "absolute", inset: 0, pointerEvents: "none" },
1588
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1589
+ RoughSvg,
1590
+ {
1591
+ shape: "rectangle",
1592
+ roughness,
1593
+ seed: resolvedSeed,
1594
+ sketchColor: SKETCH_COLORS.ink,
1595
+ bowing,
1596
+ strokeWidth: strokeWidth ?? 1.5,
1597
+ inset: 2
1598
+ }
1599
+ )
1200
1600
  }
1201
1601
  ),
1202
- percent > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
1602
+ displayed > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
1203
1603
  "div",
1204
1604
  {
1205
1605
  style: {
@@ -1207,16 +1607,16 @@ var Progress = react.forwardRef(
1207
1607
  left: 5,
1208
1608
  top: 4,
1209
1609
  bottom: 4,
1210
- width: `calc(${percent}% - 10px)`,
1211
- minWidth: percent > 0 ? 8 : 0,
1610
+ width: `calc(${displayed}% - 10px)`,
1611
+ minWidth: displayed > 0 ? 8 : 0,
1212
1612
  overflow: "hidden"
1213
1613
  },
1214
1614
  children: /* @__PURE__ */ jsxRuntime.jsx(
1215
1615
  RoughSvg,
1216
1616
  {
1217
1617
  shape: "rectangle",
1218
- roughness: (roughness ?? 1.5) + 0.55,
1219
- seed,
1618
+ roughness: fillRoughness,
1619
+ seed: fillSeed,
1220
1620
  sketchColor: ink,
1221
1621
  fill: ink,
1222
1622
  fillStyle: fillStyle ?? "hachure",
@@ -1244,7 +1644,8 @@ function Tooltip({
1244
1644
  sketchColor,
1245
1645
  bowing,
1246
1646
  fillStyle,
1247
- strokeWidth
1647
+ strokeWidth,
1648
+ animate
1248
1649
  }) {
1249
1650
  const ink = sketchColor ?? SKETCH_COLORS.ink;
1250
1651
  return /* @__PURE__ */ jsxRuntime.jsxs(TooltipPrimitive__namespace.Root, { delayDuration, children: [
@@ -1266,6 +1667,8 @@ function Tooltip({
1266
1667
  fillStyle: fillStyle ?? "solid",
1267
1668
  fill: "#f7f6f2",
1268
1669
  strokeWidth: strokeWidth ?? 1.4,
1670
+ animate,
1671
+ drawInDuration: DRAW_IN_TOOLTIP_MS,
1269
1672
  contentStyle: {
1270
1673
  padding: "6px 10px",
1271
1674
  fontSize: 13,
@@ -1281,9 +1684,2064 @@ function Tooltip({
1281
1684
  ) })
1282
1685
  ] });
1283
1686
  }
1687
+ var CHEVRON_PATH = "M 4 6 L 10 12 L 16 6";
1688
+ var UNDERLINE_INSET = 4;
1689
+ var SelectSketchContext = react.createContext(
1690
+ null
1691
+ );
1692
+ function useSelectSketch() {
1693
+ const ctx = react.useContext(SelectSketchContext);
1694
+ if (!ctx) {
1695
+ throw new Error("Select parts must be used inside <Select>.");
1696
+ }
1697
+ return ctx;
1698
+ }
1699
+ function Select({
1700
+ options,
1701
+ placeholder = "Select\u2026",
1702
+ className,
1703
+ style,
1704
+ roughness,
1705
+ seed,
1706
+ sketchColor,
1707
+ bowing,
1708
+ fillStyle,
1709
+ strokeWidth,
1710
+ value,
1711
+ defaultValue,
1712
+ onValueChange,
1713
+ animate,
1714
+ "aria-label": ariaLabel,
1715
+ ...rest
1716
+ }) {
1717
+ const [uncontrolled, setUncontrolled] = react.useState(defaultValue);
1718
+ const selectedValue = value ?? uncontrolled;
1719
+ const selectedLabel = options.find((option) => option.value === selectedValue)?.label;
1720
+ const resolvedSeed = useResolvedSeed(seed);
1721
+ const ink = sketchColor ?? SKETCH_COLORS.ink;
1722
+ return /* @__PURE__ */ jsxRuntime.jsx(
1723
+ SelectSketchContext.Provider,
1724
+ {
1725
+ value: {
1726
+ roughness,
1727
+ seed: resolvedSeed,
1728
+ sketchColor,
1729
+ bowing,
1730
+ fillStyle,
1731
+ strokeWidth,
1732
+ resolvedSeed,
1733
+ ink,
1734
+ selectedValue,
1735
+ selectedLabel,
1736
+ placeholder,
1737
+ animate
1738
+ },
1739
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
1740
+ SelectPrimitive__namespace.Root,
1741
+ {
1742
+ value,
1743
+ defaultValue,
1744
+ onValueChange: (next) => {
1745
+ setUncontrolled(next);
1746
+ onValueChange?.(next);
1747
+ },
1748
+ ...rest,
1749
+ children: [
1750
+ /* @__PURE__ */ jsxRuntime.jsx(
1751
+ SelectTrigger,
1752
+ {
1753
+ className,
1754
+ style,
1755
+ placeholder,
1756
+ "aria-label": ariaLabel
1757
+ }
1758
+ ),
1759
+ /* @__PURE__ */ jsxRuntime.jsx(SelectContent, { children: options.map((option) => /* @__PURE__ */ jsxRuntime.jsx(
1760
+ SelectItem,
1761
+ {
1762
+ value: option.value,
1763
+ disabled: option.disabled,
1764
+ children: option.label
1765
+ },
1766
+ option.value
1767
+ )) })
1768
+ ]
1769
+ }
1770
+ )
1771
+ }
1772
+ );
1773
+ }
1774
+ var SelectTrigger = react.forwardRef(
1775
+ function SelectTrigger2({ className, style, placeholder, children, ...rest }, ref) {
1776
+ const sketch = useSelectSketch();
1777
+ const [openish, setOpenish] = react.useState(false);
1778
+ const rootRef = react.useRef(null);
1779
+ const shouldAnimate = useAnimate(sketch.animate);
1780
+ useDrawIn(rootRef, DRAW_IN_DURATION_MS, shouldAnimate);
1781
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1782
+ SelectPrimitive__namespace.Trigger,
1783
+ {
1784
+ ref: (node) => {
1785
+ rootRef.current = node;
1786
+ assignRef(ref, node);
1787
+ },
1788
+ className: cn(className),
1789
+ onPointerDown: () => setOpenish(true),
1790
+ onBlur: () => setOpenish(false),
1791
+ style: {
1792
+ position: "relative",
1793
+ display: "inline-flex",
1794
+ alignItems: "center",
1795
+ justifyContent: "space-between",
1796
+ gap: 12,
1797
+ minWidth: 180,
1798
+ minHeight: 38,
1799
+ padding: "8px 12px",
1800
+ border: "none",
1801
+ background: "transparent",
1802
+ cursor: "pointer",
1803
+ color: sketch.ink,
1804
+ fontFamily: doodleUiFontFamily,
1805
+ fontSize: 15,
1806
+ lineHeight: 1.2,
1807
+ outline: "none",
1808
+ textAlign: "left",
1809
+ ...style
1810
+ },
1811
+ ...rest,
1812
+ children: [
1813
+ /* @__PURE__ */ jsxRuntime.jsx(
1814
+ RoughSvg,
1815
+ {
1816
+ shape: "rectangle",
1817
+ roughness: sketch.roughness,
1818
+ seed: sketch.resolvedSeed,
1819
+ sketchColor: openish ? SKETCH_COLORS.accent : sketch.ink,
1820
+ bowing: sketch.bowing,
1821
+ fillStyle: sketch.fillStyle,
1822
+ strokeWidth: openish ? (sketch.strokeWidth ?? 1.75) + 0.35 : sketch.strokeWidth
1823
+ }
1824
+ ),
1825
+ /* @__PURE__ */ jsxRuntime.jsx(
1826
+ "span",
1827
+ {
1828
+ style: {
1829
+ position: "relative",
1830
+ zIndex: 1,
1831
+ flex: 1,
1832
+ overflow: "hidden",
1833
+ textOverflow: "ellipsis",
1834
+ whiteSpace: "nowrap"
1835
+ },
1836
+ children: children ?? sketch.selectedLabel ?? placeholder
1837
+ }
1838
+ ),
1839
+ /* @__PURE__ */ jsxRuntime.jsx(
1840
+ SelectPrimitive__namespace.Icon,
1841
+ {
1842
+ style: {
1843
+ position: "relative",
1844
+ zIndex: 1,
1845
+ width: 18,
1846
+ height: 18,
1847
+ flexShrink: 0
1848
+ },
1849
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1850
+ RoughSvg,
1851
+ {
1852
+ shape: "path",
1853
+ path: CHEVRON_PATH,
1854
+ roughness: (sketch.roughness ?? 1.5) * 0.7,
1855
+ seed: sketch.resolvedSeed,
1856
+ sketchColor: sketch.ink,
1857
+ bowing: sketch.bowing,
1858
+ strokeWidth: (sketch.strokeWidth ?? 1.6) + 0.2,
1859
+ inset: 0
1860
+ }
1861
+ )
1862
+ }
1863
+ )
1864
+ ]
1865
+ }
1866
+ );
1867
+ }
1868
+ );
1869
+ var SelectContent = react.forwardRef(
1870
+ function SelectContent2({ className, style, children, ...rest }, ref) {
1871
+ const sketch = useSelectSketch();
1872
+ return /* @__PURE__ */ jsxRuntime.jsx(SelectPrimitive__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
1873
+ SelectPrimitive__namespace.Content,
1874
+ {
1875
+ ref,
1876
+ position: "popper",
1877
+ sideOffset: 6,
1878
+ className: cn(className),
1879
+ style: {
1880
+ zIndex: 80,
1881
+ outline: "none",
1882
+ minWidth: "var(--radix-select-trigger-width)",
1883
+ ...style
1884
+ },
1885
+ ...rest,
1886
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1887
+ SketchBox,
1888
+ {
1889
+ roughness: sketch.roughness,
1890
+ seed: sketch.resolvedSeed,
1891
+ sketchColor: sketch.ink,
1892
+ bowing: sketch.bowing,
1893
+ fillStyle: sketch.fillStyle ?? "solid",
1894
+ fill: "#f7f6f2",
1895
+ strokeWidth: sketch.strokeWidth ?? 1.5,
1896
+ animate: sketch.animate,
1897
+ contentStyle: { padding: "6px 4px" },
1898
+ children: /* @__PURE__ */ jsxRuntime.jsx(SelectPrimitive__namespace.Viewport, { children })
1899
+ }
1900
+ )
1901
+ }
1902
+ ) });
1903
+ }
1904
+ );
1905
+ var SelectItem = react.forwardRef(
1906
+ function SelectItem2({ className, style, children, value, ...rest }, ref) {
1907
+ const sketch = useSelectSketch();
1908
+ const [highlighted, setHighlighted] = react.useState(false);
1909
+ const selected = sketch.selectedValue === value;
1910
+ const mark = highlighted || selected;
1911
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1912
+ SelectPrimitive__namespace.Item,
1913
+ {
1914
+ ref,
1915
+ value,
1916
+ className: cn(className),
1917
+ onPointerMove: () => setHighlighted(true),
1918
+ onPointerLeave: () => setHighlighted(false),
1919
+ onFocus: () => setHighlighted(true),
1920
+ onBlur: () => setHighlighted(false),
1921
+ style: {
1922
+ position: "relative",
1923
+ display: "flex",
1924
+ alignItems: "center",
1925
+ padding: "7px 12px",
1926
+ fontFamily: doodleUiFontFamily,
1927
+ fontSize: 14,
1928
+ color: sketch.ink,
1929
+ outline: "none",
1930
+ cursor: "pointer",
1931
+ userSelect: "none",
1932
+ fontWeight: selected ? doodleUiFontWeight(650) : doodleUiFontWeight(400),
1933
+ ...style
1934
+ },
1935
+ ...rest,
1936
+ children: [
1937
+ mark ? /* @__PURE__ */ jsxRuntime.jsx(
1938
+ RoughSvg,
1939
+ {
1940
+ shape: "line",
1941
+ roughness: (sketch.roughness ?? 1.5) + 0.4,
1942
+ seed: sketch.resolvedSeed,
1943
+ sketchColor: selected ? SKETCH_COLORS.accent : sketch.ink,
1944
+ bowing: sketch.bowing ?? 1.6,
1945
+ strokeWidth: selected ? 1.8 : 1.3,
1946
+ inset: UNDERLINE_INSET,
1947
+ style: { opacity: selected ? 0.9 : 0.45 }
1948
+ }
1949
+ ) : null,
1950
+ /* @__PURE__ */ jsxRuntime.jsx(
1951
+ SelectPrimitive__namespace.ItemText,
1952
+ {
1953
+ style: { position: "relative", zIndex: 1 },
1954
+ children
1955
+ }
1956
+ )
1957
+ ]
1958
+ }
1959
+ );
1960
+ }
1961
+ );
1962
+ var SelectRoot = SelectPrimitive__namespace.Root;
1963
+ var SelectValue = SelectPrimitive__namespace.Value;
1964
+ var SelectGroup = SelectPrimitive__namespace.Group;
1965
+ var SelectLabel = SelectPrimitive__namespace.Label;
1966
+ var SelectSeparator = SelectPrimitive__namespace.Separator;
1967
+ var TRACK_W = 44;
1968
+ var TRACK_H = 24;
1969
+ var THUMB = 18;
1970
+ var THUMB_OFF = 3;
1971
+ var THUMB_ON = TRACK_W - THUMB - 3;
1972
+ var Switch = react.forwardRef(
1973
+ function Switch2({
1974
+ className,
1975
+ style,
1976
+ label,
1977
+ roughness,
1978
+ seed,
1979
+ sketchColor,
1980
+ bowing,
1981
+ fillStyle,
1982
+ strokeWidth,
1983
+ checked,
1984
+ defaultChecked,
1985
+ onCheckedChange,
1986
+ id,
1987
+ animate,
1988
+ ...rest
1989
+ }, ref) {
1990
+ const [uncontrolled, setUncontrolled] = react.useState(defaultChecked === true);
1991
+ const isOn = checked ?? uncontrolled;
1992
+ const ink = sketchColor ?? SKETCH_COLORS.ink;
1993
+ const resolvedSeed = useResolvedSeed(seed);
1994
+ const shouldAnimate = useAnimate(animate);
1995
+ const trackRef = react.useRef(null);
1996
+ const trackSeed = shouldAnimate ? deriveSeed(resolvedSeed, isOn ? "on" : "off") : resolvedSeed;
1997
+ useDrawIn(trackRef, DRAW_IN_DURATION_MS, shouldAnimate, trackSeed);
1998
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1999
+ "span",
2000
+ {
2001
+ className: cn(className),
2002
+ style: {
2003
+ display: "inline-flex",
2004
+ alignItems: "center",
2005
+ gap: 8,
2006
+ cursor: "pointer",
2007
+ userSelect: "none",
2008
+ ...style
2009
+ },
2010
+ children: [
2011
+ /* @__PURE__ */ jsxRuntime.jsxs(
2012
+ SwitchPrimitive__namespace.Root,
2013
+ {
2014
+ ref,
2015
+ id,
2016
+ checked,
2017
+ defaultChecked,
2018
+ onCheckedChange: (next) => {
2019
+ setUncontrolled(next);
2020
+ onCheckedChange?.(next);
2021
+ },
2022
+ style: {
2023
+ position: "relative",
2024
+ width: TRACK_W,
2025
+ height: TRACK_H,
2026
+ padding: 0,
2027
+ border: "none",
2028
+ background: "transparent",
2029
+ flexShrink: 0,
2030
+ cursor: "pointer",
2031
+ outline: "none"
2032
+ },
2033
+ ...rest,
2034
+ children: [
2035
+ /* @__PURE__ */ jsxRuntime.jsx(
2036
+ "span",
2037
+ {
2038
+ ref: trackRef,
2039
+ style: { position: "absolute", inset: 0, pointerEvents: "none" },
2040
+ children: /* @__PURE__ */ jsxRuntime.jsx(
2041
+ RoughSvg,
2042
+ {
2043
+ shape: "rectangle",
2044
+ roughness,
2045
+ seed: trackSeed,
2046
+ sketchColor: isOn ? SKETCH_COLORS.accent : ink,
2047
+ bowing: bowing ?? 1.4,
2048
+ fillStyle: fillStyle ?? (isOn ? "hachure" : void 0),
2049
+ fill: isOn ? SKETCH_COLORS.accentFill : void 0,
2050
+ strokeWidth: strokeWidth ?? 1.6,
2051
+ inset: 1.5
2052
+ }
2053
+ )
2054
+ }
2055
+ ),
2056
+ /* @__PURE__ */ jsxRuntime.jsx(SwitchPrimitive__namespace.Thumb, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
2057
+ framerMotion.motion.span,
2058
+ {
2059
+ initial: false,
2060
+ animate: { x: isOn ? THUMB_ON : THUMB_OFF },
2061
+ transition: shouldAnimate ? { type: "spring", stiffness: 420, damping: 30 } : { duration: 0 },
2062
+ style: {
2063
+ position: "absolute",
2064
+ top: (TRACK_H - THUMB) / 2,
2065
+ left: 0,
2066
+ width: THUMB,
2067
+ height: THUMB,
2068
+ display: "block",
2069
+ zIndex: 1
2070
+ },
2071
+ children: /* @__PURE__ */ jsxRuntime.jsx(
2072
+ RoughSvg,
2073
+ {
2074
+ shape: "ellipse",
2075
+ roughness: (roughness ?? 1.5) * 0.85,
2076
+ seed: deriveSeed(resolvedSeed, "thumb"),
2077
+ sketchColor: isOn ? SKETCH_COLORS.accent : ink,
2078
+ fill: "#f7f6f2",
2079
+ fillStyle: "solid",
2080
+ bowing,
2081
+ strokeWidth: (strokeWidth ?? 1.5) + 0.2,
2082
+ inset: 1
2083
+ }
2084
+ )
2085
+ }
2086
+ ) })
2087
+ ]
2088
+ }
2089
+ ),
2090
+ label ? /* @__PURE__ */ jsxRuntime.jsx(
2091
+ "label",
2092
+ {
2093
+ htmlFor: id,
2094
+ style: {
2095
+ fontSize: 15,
2096
+ cursor: "pointer",
2097
+ fontFamily: doodleUiFontFamily
2098
+ },
2099
+ children: label
2100
+ }
2101
+ ) : null
2102
+ ]
2103
+ }
2104
+ );
2105
+ }
2106
+ );
2107
+ var TabsSketchContext = react.createContext(null);
2108
+ function useTabsSketch() {
2109
+ const ctx = react.useContext(TabsSketchContext);
2110
+ if (!ctx) {
2111
+ throw new Error("Tab parts must be used inside <Tabs>.");
2112
+ }
2113
+ return ctx;
2114
+ }
2115
+ var Tabs = react.forwardRef(function Tabs2({
2116
+ className,
2117
+ style,
2118
+ children,
2119
+ value,
2120
+ defaultValue,
2121
+ onValueChange,
2122
+ roughness,
2123
+ seed,
2124
+ sketchColor,
2125
+ bowing,
2126
+ fillStyle,
2127
+ strokeWidth,
2128
+ animate,
2129
+ ...rest
2130
+ }, ref) {
2131
+ const [uncontrolled, setUncontrolled] = react.useState(defaultValue);
2132
+ const current = value ?? uncontrolled;
2133
+ const resolvedSeed = useResolvedSeed(seed);
2134
+ const ink = sketchColor ?? SKETCH_COLORS.ink;
2135
+ const shouldAnimate = useAnimate(animate);
2136
+ return /* @__PURE__ */ jsxRuntime.jsx(
2137
+ TabsSketchContext.Provider,
2138
+ {
2139
+ value: {
2140
+ roughness,
2141
+ seed: resolvedSeed,
2142
+ sketchColor,
2143
+ bowing,
2144
+ fillStyle,
2145
+ strokeWidth,
2146
+ resolvedSeed,
2147
+ ink,
2148
+ current,
2149
+ shouldAnimate
2150
+ },
2151
+ children: /* @__PURE__ */ jsxRuntime.jsx(
2152
+ TabsPrimitive__namespace.Root,
2153
+ {
2154
+ ref,
2155
+ className: cn(className),
2156
+ style,
2157
+ value: current,
2158
+ defaultValue,
2159
+ onValueChange: (next) => {
2160
+ setUncontrolled(next);
2161
+ onValueChange?.(next);
2162
+ },
2163
+ ...rest,
2164
+ children
2165
+ }
2166
+ )
2167
+ }
2168
+ );
2169
+ });
2170
+ function TabUnderline({
2171
+ box,
2172
+ seed,
2173
+ sketch
2174
+ }) {
2175
+ const ref = react.useRef(null);
2176
+ useDrawIn(ref, DRAW_IN_MARK_MS, sketch.shouldAnimate, seed);
2177
+ return /* @__PURE__ */ jsxRuntime.jsx(
2178
+ "span",
2179
+ {
2180
+ ref,
2181
+ "aria-hidden": "true",
2182
+ style: {
2183
+ position: "absolute",
2184
+ left: box.left,
2185
+ top: box.top,
2186
+ width: box.width,
2187
+ height: 10,
2188
+ pointerEvents: "none",
2189
+ transition: sketch.shouldAnimate ? "left 220ms ease, width 220ms ease, top 220ms ease" : void 0
2190
+ },
2191
+ children: /* @__PURE__ */ jsxRuntime.jsx(
2192
+ RoughSvg,
2193
+ {
2194
+ shape: "line",
2195
+ roughness: (sketch.roughness ?? 1.5) + 0.35,
2196
+ seed,
2197
+ sketchColor: SKETCH_COLORS.accent,
2198
+ bowing: sketch.bowing ?? 1.8,
2199
+ strokeWidth: (sketch.strokeWidth ?? 1.75) + 0.4,
2200
+ inset: 2
2201
+ }
2202
+ )
2203
+ }
2204
+ );
2205
+ }
2206
+ var TabList = react.forwardRef(
2207
+ function TabList2({ className, style, children, ...rest }, ref) {
2208
+ const sketch = useTabsSketch();
2209
+ const listRef = react.useRef(null);
2210
+ const [underline, setUnderline] = react.useState(null);
2211
+ react.useLayoutEffect(() => {
2212
+ const list = listRef.current;
2213
+ if (!list) return;
2214
+ const measure = () => {
2215
+ const active = list.querySelector('[data-state="active"]');
2216
+ if (!active) {
2217
+ setUnderline(null);
2218
+ return;
2219
+ }
2220
+ setUnderline({
2221
+ left: active.offsetLeft + 8,
2222
+ top: active.offsetTop + active.offsetHeight - 10,
2223
+ width: Math.max(12, active.offsetWidth - 16)
2224
+ });
2225
+ };
2226
+ measure();
2227
+ const observer = new ResizeObserver(measure);
2228
+ observer.observe(list);
2229
+ return () => observer.disconnect();
2230
+ }, [sketch.current, children]);
2231
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2232
+ TabsPrimitive__namespace.List,
2233
+ {
2234
+ ref: (node) => {
2235
+ listRef.current = node;
2236
+ assignRef(ref, node);
2237
+ },
2238
+ className: cn(className),
2239
+ style: {
2240
+ display: "flex",
2241
+ flexWrap: "wrap",
2242
+ gap: 4,
2243
+ position: "relative",
2244
+ ...style
2245
+ },
2246
+ ...rest,
2247
+ children: [
2248
+ children,
2249
+ underline && sketch.current ? /* @__PURE__ */ jsxRuntime.jsx(
2250
+ TabUnderline,
2251
+ {
2252
+ box: underline,
2253
+ seed: deriveSeed(sketch.resolvedSeed, sketch.current),
2254
+ sketch
2255
+ }
2256
+ ) : null
2257
+ ]
2258
+ }
2259
+ );
2260
+ }
2261
+ );
2262
+ var Tab = react.forwardRef(function Tab2({ className, style, children, value, ...rest }, ref) {
2263
+ const sketch = useTabsSketch();
2264
+ const active = sketch.current === value;
2265
+ return /* @__PURE__ */ jsxRuntime.jsx(
2266
+ TabsPrimitive__namespace.Trigger,
2267
+ {
2268
+ ref,
2269
+ value,
2270
+ className: cn(className),
2271
+ style: {
2272
+ position: "relative",
2273
+ border: "none",
2274
+ background: "transparent",
2275
+ cursor: "pointer",
2276
+ padding: "8px 14px 12px",
2277
+ fontFamily: doodleUiFontFamily,
2278
+ fontSize: 15,
2279
+ fontWeight: active ? doodleUiFontWeight(650) : doodleUiFontWeight(400),
2280
+ color: sketch.ink,
2281
+ outline: "none",
2282
+ ...style
2283
+ },
2284
+ ...rest,
2285
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { style: { position: "relative", zIndex: 1 }, children })
2286
+ }
2287
+ );
2288
+ });
2289
+ var TabPanel = react.forwardRef(
2290
+ function TabPanel2({ className, style, children, ...rest }, ref) {
2291
+ const sketch = useTabsSketch();
2292
+ return /* @__PURE__ */ jsxRuntime.jsx(
2293
+ TabsPrimitive__namespace.Content,
2294
+ {
2295
+ ref,
2296
+ className: cn(className),
2297
+ style: {
2298
+ paddingTop: 14,
2299
+ fontFamily: doodleUiFontFamily,
2300
+ color: sketch.ink,
2301
+ fontSize: 15,
2302
+ lineHeight: 1.5,
2303
+ outline: "none",
2304
+ ...style
2305
+ },
2306
+ ...rest,
2307
+ children
2308
+ }
2309
+ );
2310
+ }
2311
+ );
2312
+ var TableSketchContext = react.createContext(null);
2313
+ function useTableSketch() {
2314
+ const ctx = react.useContext(TableSketchContext);
2315
+ if (!ctx) {
2316
+ throw new Error("Table parts must be used inside <Table>.");
2317
+ }
2318
+ return ctx;
2319
+ }
2320
+ function TableRule({
2321
+ line,
2322
+ headerUnderline,
2323
+ roughness,
2324
+ resolvedSeed,
2325
+ ink,
2326
+ bowing,
2327
+ strokeWidth,
2328
+ shouldAnimate
2329
+ }) {
2330
+ const ref = react.useRef(null);
2331
+ const delay = shouldAnimate ? Math.min(line.index, 6) * TABLE_STAGGER_MS : 0;
2332
+ useDrawIn(ref, DRAW_IN_DURATION_MS, shouldAnimate, void 0, delay);
2333
+ if (line.header && !headerUnderline) return null;
2334
+ return /* @__PURE__ */ jsxRuntime.jsx(
2335
+ "div",
2336
+ {
2337
+ ref,
2338
+ style: {
2339
+ position: "absolute",
2340
+ left: 0,
2341
+ width: line.width,
2342
+ top: line.y - 6,
2343
+ height: 12
2344
+ },
2345
+ children: /* @__PURE__ */ jsxRuntime.jsx(
2346
+ RoughSvg,
2347
+ {
2348
+ shape: "line",
2349
+ roughness: line.header ? (roughness ?? 1.5) + 0.2 : roughness ?? 1.7,
2350
+ seed: deriveSeed(resolvedSeed, line.key),
2351
+ sketchColor: ink,
2352
+ bowing: bowing ?? (line.header ? 1.4 : 2),
2353
+ strokeWidth: line.header ? (strokeWidth ?? 1.75) + 0.35 : strokeWidth ?? 1.35,
2354
+ inset: 6
2355
+ }
2356
+ )
2357
+ }
2358
+ );
2359
+ }
2360
+ var Table = react.forwardRef(function Table2({
2361
+ className,
2362
+ style,
2363
+ children,
2364
+ headerUnderline = true,
2365
+ roughness,
2366
+ seed,
2367
+ sketchColor,
2368
+ bowing,
2369
+ fillStyle,
2370
+ strokeWidth,
2371
+ animate,
2372
+ ...rest
2373
+ }, ref) {
2374
+ const wrapperRef = react.useRef(null);
2375
+ const tableRef = react.useRef(null);
2376
+ const [lines, setLines] = react.useState([]);
2377
+ const resolvedSeed = useResolvedSeed(seed);
2378
+ const ink = sketchColor ?? SKETCH_COLORS.ink;
2379
+ const shouldAnimate = useAnimate(animate);
2380
+ react.useLayoutEffect(() => {
2381
+ const wrapper = wrapperRef.current;
2382
+ const table = tableRef.current;
2383
+ if (!wrapper || !table) return;
2384
+ const measure = () => {
2385
+ const rows = Array.from(table.querySelectorAll("tr"));
2386
+ const next = [];
2387
+ rows.forEach((row, index) => {
2388
+ const isLast = index === rows.length - 1;
2389
+ const isHeader = row.parentElement?.tagName === "THEAD";
2390
+ if (isLast && !isHeader) return;
2391
+ next.push({
2392
+ y: row.offsetTop + row.offsetHeight,
2393
+ width: table.offsetWidth,
2394
+ key: isHeader ? `header-${index}` : `row-${index}`,
2395
+ header: Boolean(isHeader),
2396
+ index
2397
+ });
2398
+ });
2399
+ setLines(next);
2400
+ };
2401
+ measure();
2402
+ const observer = new ResizeObserver(measure);
2403
+ observer.observe(table);
2404
+ observer.observe(wrapper);
2405
+ return () => observer.disconnect();
2406
+ }, [children]);
2407
+ return /* @__PURE__ */ jsxRuntime.jsx(
2408
+ TableSketchContext.Provider,
2409
+ {
2410
+ value: {
2411
+ roughness,
2412
+ seed: resolvedSeed,
2413
+ sketchColor,
2414
+ bowing,
2415
+ fillStyle,
2416
+ strokeWidth,
2417
+ resolvedSeed,
2418
+ ink,
2419
+ shouldAnimate
2420
+ },
2421
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
2422
+ "div",
2423
+ {
2424
+ ref: wrapperRef,
2425
+ className: cn(className),
2426
+ style: { position: "relative", width: "100%", ...style },
2427
+ children: [
2428
+ /* @__PURE__ */ jsxRuntime.jsx(
2429
+ "div",
2430
+ {
2431
+ "aria-hidden": "true",
2432
+ style: {
2433
+ position: "absolute",
2434
+ inset: 0,
2435
+ pointerEvents: "none",
2436
+ zIndex: 1,
2437
+ overflow: "visible"
2438
+ },
2439
+ children: lines.map((line) => /* @__PURE__ */ jsxRuntime.jsx(
2440
+ TableRule,
2441
+ {
2442
+ line,
2443
+ headerUnderline,
2444
+ roughness,
2445
+ resolvedSeed,
2446
+ ink,
2447
+ bowing,
2448
+ strokeWidth,
2449
+ shouldAnimate
2450
+ },
2451
+ line.key
2452
+ ))
2453
+ }
2454
+ ),
2455
+ /* @__PURE__ */ jsxRuntime.jsx(
2456
+ "table",
2457
+ {
2458
+ ref: (node) => {
2459
+ tableRef.current = node;
2460
+ assignRef(ref, node);
2461
+ },
2462
+ style: {
2463
+ width: "100%",
2464
+ borderCollapse: "collapse",
2465
+ position: "relative",
2466
+ zIndex: 0,
2467
+ fontFamily: doodleUiFontFamily,
2468
+ color: ink
2469
+ },
2470
+ ...rest,
2471
+ children
2472
+ }
2473
+ )
2474
+ ]
2475
+ }
2476
+ )
2477
+ }
2478
+ );
2479
+ });
2480
+ var TableHead = react.forwardRef(function TableHead2({ className, style, ...rest }, ref) {
2481
+ return /* @__PURE__ */ jsxRuntime.jsx(
2482
+ "thead",
2483
+ {
2484
+ ref,
2485
+ className: cn(className),
2486
+ style,
2487
+ ...rest
2488
+ }
2489
+ );
2490
+ });
2491
+ var TableBody = react.forwardRef(function TableBody2({ className, style, ...rest }, ref) {
2492
+ return /* @__PURE__ */ jsxRuntime.jsx(
2493
+ "tbody",
2494
+ {
2495
+ ref,
2496
+ className: cn(className),
2497
+ style,
2498
+ ...rest
2499
+ }
2500
+ );
2501
+ });
2502
+ var TableRow = react.forwardRef(function TableRow2({ className, style, ...rest }, ref) {
2503
+ return /* @__PURE__ */ jsxRuntime.jsx(
2504
+ "tr",
2505
+ {
2506
+ ref,
2507
+ className: cn(className),
2508
+ style,
2509
+ ...rest
2510
+ }
2511
+ );
2512
+ });
2513
+ var TableHeaderCell = react.forwardRef(function TableHeaderCell2({ className, style, children, ...rest }, ref) {
2514
+ useTableSketch();
2515
+ return /* @__PURE__ */ jsxRuntime.jsx(
2516
+ "th",
2517
+ {
2518
+ ref,
2519
+ className: cn(className),
2520
+ style: {
2521
+ textAlign: "left",
2522
+ fontWeight: doodleUiFontWeight(650),
2523
+ fontSize: 13,
2524
+ padding: "10px 12px",
2525
+ ...style
2526
+ },
2527
+ ...rest,
2528
+ children
2529
+ }
2530
+ );
2531
+ });
2532
+ var TableCell = react.forwardRef(
2533
+ function TableCell2({ className, style, children, ...rest }, ref) {
2534
+ useTableSketch();
2535
+ return /* @__PURE__ */ jsxRuntime.jsx(
2536
+ "td",
2537
+ {
2538
+ ref,
2539
+ className: cn(className),
2540
+ style: {
2541
+ fontSize: 14,
2542
+ padding: "10px 12px",
2543
+ ...style
2544
+ },
2545
+ ...rest,
2546
+ children
2547
+ }
2548
+ );
2549
+ }
2550
+ );
2551
+ var VARIANT_COLOR2 = {
2552
+ info: SKETCH_COLORS.info,
2553
+ warning: SKETCH_COLORS.warning,
2554
+ error: SKETCH_COLORS.error,
2555
+ success: SKETCH_COLORS.success
2556
+ };
2557
+ var VARIANT_FILL2 = {
2558
+ info: "#d2deec",
2559
+ warning: "#f3e2c0",
2560
+ error: "#f3d0cc",
2561
+ success: "#d3e8dc"
2562
+ };
2563
+ var POSITION_STYLE = {
2564
+ "top-left": { top: 16, left: 16 },
2565
+ "top-right": { top: 16, right: 16 },
2566
+ "bottom-left": { bottom: 16, left: 16 },
2567
+ "bottom-right": { bottom: 16, right: 16 }
2568
+ };
2569
+ var ToastPositionContext = react.createContext("bottom-right");
2570
+ function ToastProvider({
2571
+ children,
2572
+ position = "bottom-right",
2573
+ duration = 4e3,
2574
+ swipeDirection = "right",
2575
+ label
2576
+ }) {
2577
+ return /* @__PURE__ */ jsxRuntime.jsx(ToastPositionContext.Provider, { value: position, children: /* @__PURE__ */ jsxRuntime.jsxs(
2578
+ ToastPrimitive__namespace.Provider,
2579
+ {
2580
+ duration,
2581
+ swipeDirection,
2582
+ label,
2583
+ children: [
2584
+ children,
2585
+ /* @__PURE__ */ jsxRuntime.jsx(
2586
+ ToastPrimitive__namespace.Viewport,
2587
+ {
2588
+ style: {
2589
+ position: "fixed",
2590
+ zIndex: 90,
2591
+ display: "flex",
2592
+ flexDirection: "column",
2593
+ gap: 10,
2594
+ width: "min(360px, calc(100vw - 32px))",
2595
+ margin: 0,
2596
+ padding: 0,
2597
+ listStyle: "none",
2598
+ outline: "none",
2599
+ ...POSITION_STYLE[position]
2600
+ }
2601
+ }
2602
+ )
2603
+ ]
2604
+ }
2605
+ ) });
2606
+ }
2607
+ function Toast({
2608
+ open,
2609
+ defaultOpen,
2610
+ onOpenChange,
2611
+ title,
2612
+ children,
2613
+ variant = "info",
2614
+ duration,
2615
+ className,
2616
+ style,
2617
+ roughness,
2618
+ seed,
2619
+ sketchColor,
2620
+ bowing,
2621
+ fillStyle,
2622
+ strokeWidth,
2623
+ animate
2624
+ }) {
2625
+ const position = react.useContext(ToastPositionContext);
2626
+ const fromTop = position.startsWith("top");
2627
+ const [uncontrolled, setUncontrolled] = react.useState(defaultOpen ?? false);
2628
+ const isOpen = open ?? uncontrolled;
2629
+ const shouldAnimate = useAnimate(animate);
2630
+ const color = sketchColor ?? VARIANT_COLOR2[variant];
2631
+ const offset = fromTop ? -14 : 14;
2632
+ function handleOpenChange(next) {
2633
+ setUncontrolled(next);
2634
+ onOpenChange?.(next);
2635
+ }
2636
+ return /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: isOpen ? /* @__PURE__ */ jsxRuntime.jsx(
2637
+ ToastPrimitive__namespace.Root,
2638
+ {
2639
+ open: isOpen,
2640
+ onOpenChange: handleOpenChange,
2641
+ duration,
2642
+ forceMount: true,
2643
+ asChild: true,
2644
+ children: /* @__PURE__ */ jsxRuntime.jsx(
2645
+ framerMotion.motion.li,
2646
+ {
2647
+ className: cn(className),
2648
+ initial: shouldAnimate ? { y: offset, opacity: 0, rotate: -1.4 } : false,
2649
+ animate: shouldAnimate ? { y: 0, opacity: 1, rotate: [-1.2, 0.9, -0.35, 0] } : { y: 0, opacity: 1, rotate: 0 },
2650
+ exit: shouldAnimate ? { y: offset, opacity: 0, rotate: 1.2 } : { opacity: 0 },
2651
+ transition: shouldAnimate ? { duration: 0.38, ease: "easeOut" } : { duration: 0 },
2652
+ style: {
2653
+ listStyle: "none",
2654
+ outline: "none",
2655
+ ...style
2656
+ },
2657
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
2658
+ SketchBox,
2659
+ {
2660
+ roughness,
2661
+ seed,
2662
+ sketchColor: color,
2663
+ bowing,
2664
+ fillStyle: fillStyle ?? "hachure",
2665
+ fill: VARIANT_FILL2[variant],
2666
+ strokeWidth: strokeWidth ?? 1.7,
2667
+ shadow: true,
2668
+ animate,
2669
+ contentStyle: { padding: "12px 16px" },
2670
+ children: [
2671
+ title ? /* @__PURE__ */ jsxRuntime.jsx(
2672
+ ToastPrimitive__namespace.Title,
2673
+ {
2674
+ style: {
2675
+ margin: 0,
2676
+ fontWeight: doodleUiFontWeight(700),
2677
+ fontSize: 15,
2678
+ fontFamily: doodleUiFontFamily,
2679
+ color,
2680
+ marginBottom: children ? 4 : 0
2681
+ },
2682
+ children: title
2683
+ }
2684
+ ) : null,
2685
+ children ? /* @__PURE__ */ jsxRuntime.jsx(
2686
+ ToastPrimitive__namespace.Description,
2687
+ {
2688
+ style: {
2689
+ margin: 0,
2690
+ fontSize: 14,
2691
+ lineHeight: 1.5,
2692
+ fontFamily: doodleUiFontFamily,
2693
+ color: SKETCH_COLORS.ink
2694
+ },
2695
+ children
2696
+ }
2697
+ ) : null
2698
+ ]
2699
+ }
2700
+ )
2701
+ }
2702
+ )
2703
+ }
2704
+ ) : null });
2705
+ }
2706
+ var ToastRoot = ToastPrimitive__namespace.Root;
2707
+ var ToastTitle = ToastPrimitive__namespace.Title;
2708
+ var ToastDescription = ToastPrimitive__namespace.Description;
2709
+ var ToastClose = ToastPrimitive__namespace.Close;
2710
+ var ToastAction = ToastPrimitive__namespace.Action;
2711
+ var ToastViewport = ToastPrimitive__namespace.Viewport;
2712
+ var CHEVRON_PATH2 = "M 6 4 L 12 10 L 6 16";
2713
+ var AccordionSketchContext = react.createContext(null);
2714
+ function useAccordionSketch() {
2715
+ const ctx = react.useContext(AccordionSketchContext);
2716
+ if (!ctx) {
2717
+ throw new Error("Accordion parts must be used inside <Accordion>.");
2718
+ }
2719
+ return ctx;
2720
+ }
2721
+ var AccordionItemContext = react.createContext("");
2722
+ var Accordion = react.forwardRef(
2723
+ function Accordion2({
2724
+ className,
2725
+ style,
2726
+ children,
2727
+ type = "single",
2728
+ collapsible = true,
2729
+ value,
2730
+ defaultValue,
2731
+ onValueChange,
2732
+ disabled,
2733
+ roughness,
2734
+ seed,
2735
+ sketchColor,
2736
+ bowing,
2737
+ fillStyle,
2738
+ strokeWidth
2739
+ }, ref) {
2740
+ const resolvedSeed = useResolvedSeed(seed);
2741
+ const ink = sketchColor ?? SKETCH_COLORS.ink;
2742
+ const [uncontrolled, setUncontrolled] = react.useState(defaultValue ?? (type === "multiple" ? [] : void 0));
2743
+ const openValue = value ?? uncontrolled;
2744
+ const sketchValue = {
2745
+ roughness,
2746
+ seed: resolvedSeed,
2747
+ sketchColor,
2748
+ bowing,
2749
+ fillStyle,
2750
+ strokeWidth,
2751
+ resolvedSeed,
2752
+ ink,
2753
+ openValue
2754
+ };
2755
+ function handleChange(next) {
2756
+ setUncontrolled(next);
2757
+ onValueChange?.(next);
2758
+ }
2759
+ const root = type === "multiple" ? /* @__PURE__ */ jsxRuntime.jsx(
2760
+ AccordionPrimitive__namespace.Root,
2761
+ {
2762
+ ref,
2763
+ type: "multiple",
2764
+ disabled,
2765
+ className: cn(className),
2766
+ style,
2767
+ value: openValue,
2768
+ defaultValue,
2769
+ onValueChange: handleChange,
2770
+ children
2771
+ }
2772
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
2773
+ AccordionPrimitive__namespace.Root,
2774
+ {
2775
+ ref,
2776
+ type: "single",
2777
+ collapsible,
2778
+ disabled,
2779
+ className: cn(className),
2780
+ style,
2781
+ value: openValue,
2782
+ defaultValue,
2783
+ onValueChange: handleChange,
2784
+ children
2785
+ }
2786
+ );
2787
+ return /* @__PURE__ */ jsxRuntime.jsx(AccordionSketchContext.Provider, { value: sketchValue, children: root });
2788
+ }
2789
+ );
2790
+ var AccordionItem = react.forwardRef(
2791
+ function AccordionItem2({ className, style, children, value, ...rest }, ref) {
2792
+ const sketch = useAccordionSketch();
2793
+ return /* @__PURE__ */ jsxRuntime.jsx(AccordionItemContext.Provider, { value, children: /* @__PURE__ */ jsxRuntime.jsxs(
2794
+ AccordionPrimitive__namespace.Item,
2795
+ {
2796
+ ref,
2797
+ value,
2798
+ className: cn(className),
2799
+ style: { position: "relative", ...style },
2800
+ ...rest,
2801
+ children: [
2802
+ /* @__PURE__ */ jsxRuntime.jsx(
2803
+ "div",
2804
+ {
2805
+ style: {
2806
+ position: "absolute",
2807
+ left: 0,
2808
+ right: 0,
2809
+ top: -6,
2810
+ height: 12,
2811
+ pointerEvents: "none"
2812
+ },
2813
+ children: /* @__PURE__ */ jsxRuntime.jsx(
2814
+ RoughSvg,
2815
+ {
2816
+ shape: "line",
2817
+ roughness: (sketch.roughness ?? 1.5) + 0.25,
2818
+ seed: deriveSeed(sketch.resolvedSeed, `div-${value}`),
2819
+ sketchColor: sketch.ink,
2820
+ bowing: sketch.bowing ?? 1.8,
2821
+ strokeWidth: sketch.strokeWidth ?? 1.4,
2822
+ inset: 2
2823
+ }
2824
+ )
2825
+ }
2826
+ ),
2827
+ children
2828
+ ]
2829
+ }
2830
+ ) });
2831
+ }
2832
+ );
2833
+ var AccordionTrigger = react.forwardRef(function AccordionTrigger2({ className, style, children, ...rest }, ref) {
2834
+ const sketch = useAccordionSketch();
2835
+ const itemValue = react.useContext(AccordionItemContext);
2836
+ const open = Array.isArray(sketch.openValue) ? sketch.openValue.includes(itemValue) : sketch.openValue === itemValue;
2837
+ return /* @__PURE__ */ jsxRuntime.jsx(AccordionPrimitive__namespace.Header, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("h3", { style: { margin: 0 }, children: /* @__PURE__ */ jsxRuntime.jsxs(
2838
+ AccordionPrimitive__namespace.Trigger,
2839
+ {
2840
+ ref,
2841
+ className: cn(className),
2842
+ style: {
2843
+ display: "flex",
2844
+ width: "100%",
2845
+ alignItems: "center",
2846
+ justifyContent: "space-between",
2847
+ gap: 12,
2848
+ padding: "12px 4px",
2849
+ border: "none",
2850
+ background: "transparent",
2851
+ cursor: "pointer",
2852
+ fontFamily: doodleUiFontFamily,
2853
+ fontSize: 15,
2854
+ fontWeight: doodleUiFontWeight(600),
2855
+ color: sketch.ink,
2856
+ textAlign: "left",
2857
+ outline: "none",
2858
+ ...style
2859
+ },
2860
+ ...rest,
2861
+ children: [
2862
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children }),
2863
+ /* @__PURE__ */ jsxRuntime.jsx(
2864
+ "span",
2865
+ {
2866
+ style: {
2867
+ position: "relative",
2868
+ width: 18,
2869
+ height: 18,
2870
+ flexShrink: 0,
2871
+ transform: open ? "rotate(90deg)" : "rotate(0deg)",
2872
+ transition: "transform 180ms ease"
2873
+ },
2874
+ children: /* @__PURE__ */ jsxRuntime.jsx(
2875
+ RoughSvg,
2876
+ {
2877
+ shape: "path",
2878
+ path: CHEVRON_PATH2,
2879
+ roughness: (sketch.roughness ?? 1.5) * 0.7,
2880
+ seed: deriveSeed(sketch.resolvedSeed, `chevron-${itemValue}`),
2881
+ sketchColor: sketch.ink,
2882
+ bowing: sketch.bowing,
2883
+ strokeWidth: (sketch.strokeWidth ?? 1.6) + 0.2,
2884
+ inset: 0
2885
+ }
2886
+ )
2887
+ }
2888
+ )
2889
+ ]
2890
+ }
2891
+ ) }) });
2892
+ });
2893
+ var AccordionContent = react.forwardRef(function AccordionContent2({ className, style, children, ...rest }, ref) {
2894
+ const sketch = useAccordionSketch();
2895
+ return /* @__PURE__ */ jsxRuntime.jsx(
2896
+ AccordionPrimitive__namespace.Content,
2897
+ {
2898
+ ref,
2899
+ className: cn(className),
2900
+ style: {
2901
+ padding: "0 4px 14px",
2902
+ fontFamily: doodleUiFontFamily,
2903
+ fontSize: 14,
2904
+ lineHeight: 1.5,
2905
+ color: sketch.ink,
2906
+ ...style
2907
+ },
2908
+ ...rest,
2909
+ children
2910
+ }
2911
+ );
2912
+ });
2913
+ var STATUS_COLOR = {
2914
+ online: SKETCH_COLORS.success,
2915
+ offline: "#8a8680",
2916
+ busy: SKETCH_COLORS.accent
2917
+ };
2918
+ var Avatar = react.forwardRef(
2919
+ function Avatar2({
2920
+ className,
2921
+ style,
2922
+ src,
2923
+ alt,
2924
+ fallback,
2925
+ size = 40,
2926
+ shape = "circle",
2927
+ status,
2928
+ roughness,
2929
+ seed,
2930
+ sketchColor,
2931
+ bowing,
2932
+ fillStyle,
2933
+ strokeWidth,
2934
+ ...rest
2935
+ }, ref) {
2936
+ const ink = sketchColor ?? SKETCH_COLORS.ink;
2937
+ const resolvedSeed = useResolvedSeed(seed);
2938
+ const roughShape = shape === "circle" ? "ellipse" : "rectangle";
2939
+ const badge = 12;
2940
+ const rootStyle = {
2941
+ position: "relative",
2942
+ display: "inline-flex",
2943
+ width: size,
2944
+ height: size,
2945
+ flexShrink: 0,
2946
+ verticalAlign: "middle",
2947
+ ...style
2948
+ };
2949
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2950
+ AvatarPrimitive__namespace.Root,
2951
+ {
2952
+ ref,
2953
+ className: cn(className),
2954
+ style: rootStyle,
2955
+ ...rest,
2956
+ children: [
2957
+ /* @__PURE__ */ jsxRuntime.jsx(
2958
+ RoughSvg,
2959
+ {
2960
+ shape: roughShape,
2961
+ roughness,
2962
+ seed: resolvedSeed,
2963
+ sketchColor: ink,
2964
+ bowing,
2965
+ fillStyle: fillStyle ?? "solid",
2966
+ fill: "#f7f6f2",
2967
+ strokeWidth: strokeWidth ?? 1.6,
2968
+ inset: 1.5
2969
+ }
2970
+ ),
2971
+ /* @__PURE__ */ jsxRuntime.jsxs(
2972
+ "span",
2973
+ {
2974
+ style: {
2975
+ position: "absolute",
2976
+ inset: 4,
2977
+ overflow: "hidden",
2978
+ borderRadius: shape === "circle" ? "50%" : 4,
2979
+ zIndex: 1,
2980
+ display: "flex",
2981
+ alignItems: "center",
2982
+ justifyContent: "center"
2983
+ },
2984
+ children: [
2985
+ src ? /* @__PURE__ */ jsxRuntime.jsx(
2986
+ AvatarPrimitive__namespace.Image,
2987
+ {
2988
+ src,
2989
+ alt,
2990
+ style: {
2991
+ width: "100%",
2992
+ height: "100%",
2993
+ objectFit: "cover"
2994
+ }
2995
+ }
2996
+ ) : null,
2997
+ /* @__PURE__ */ jsxRuntime.jsx(
2998
+ AvatarPrimitive__namespace.Fallback,
2999
+ {
3000
+ delayMs: src ? 400 : 0,
3001
+ style: {
3002
+ width: "100%",
3003
+ height: "100%",
3004
+ display: "flex",
3005
+ alignItems: "center",
3006
+ justifyContent: "center",
3007
+ fontFamily: doodleUiFontFamily,
3008
+ fontWeight: doodleUiFontWeight(650),
3009
+ fontSize: Math.max(12, size * 0.36),
3010
+ color: ink,
3011
+ background: SKETCH_COLORS.secondaryFill
3012
+ },
3013
+ children: fallback
3014
+ }
3015
+ )
3016
+ ]
3017
+ }
3018
+ ),
3019
+ status ? /* @__PURE__ */ jsxRuntime.jsx(
3020
+ "span",
3021
+ {
3022
+ style: {
3023
+ position: "absolute",
3024
+ width: badge,
3025
+ height: badge,
3026
+ right: -1,
3027
+ bottom: -1,
3028
+ zIndex: 2
3029
+ },
3030
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3031
+ RoughSvg,
3032
+ {
3033
+ shape: "ellipse",
3034
+ roughness: (roughness ?? 1.5) * 0.8,
3035
+ seed: deriveSeed(resolvedSeed, "status"),
3036
+ sketchColor: STATUS_COLOR[status],
3037
+ fill: STATUS_COLOR[status],
3038
+ fillStyle: "solid",
3039
+ bowing,
3040
+ strokeWidth: 1,
3041
+ inset: 0.5
3042
+ }
3043
+ )
3044
+ }
3045
+ ) : null
3046
+ ]
3047
+ }
3048
+ );
3049
+ }
3050
+ );
3051
+ var Slider = react.forwardRef(function Slider2({
3052
+ className,
3053
+ style,
3054
+ roughness,
3055
+ seed,
3056
+ sketchColor,
3057
+ bowing,
3058
+ fillStyle,
3059
+ strokeWidth,
3060
+ thumbShape = "circle",
3061
+ ...rest
3062
+ }, ref) {
3063
+ const ink = sketchColor ?? SKETCH_COLORS.ink;
3064
+ const resolvedSeed = useResolvedSeed(seed);
3065
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3066
+ SliderPrimitive__namespace.Root,
3067
+ {
3068
+ ref,
3069
+ className: cn(className),
3070
+ style: {
3071
+ position: "relative",
3072
+ display: "flex",
3073
+ alignItems: "center",
3074
+ width: "100%",
3075
+ height: 28,
3076
+ userSelect: "none",
3077
+ touchAction: "none",
3078
+ ...style
3079
+ },
3080
+ ...rest,
3081
+ children: [
3082
+ /* @__PURE__ */ jsxRuntime.jsxs(
3083
+ SliderPrimitive__namespace.Track,
3084
+ {
3085
+ style: {
3086
+ position: "relative",
3087
+ flex: 1,
3088
+ height: 16
3089
+ },
3090
+ children: [
3091
+ /* @__PURE__ */ jsxRuntime.jsx(
3092
+ RoughSvg,
3093
+ {
3094
+ shape: "line",
3095
+ roughness: roughness ?? 1.8,
3096
+ seed: resolvedSeed,
3097
+ sketchColor: ink,
3098
+ bowing: bowing ?? 2,
3099
+ strokeWidth: strokeWidth ?? 1.6,
3100
+ inset: 4
3101
+ }
3102
+ ),
3103
+ /* @__PURE__ */ jsxRuntime.jsx(
3104
+ SliderPrimitive__namespace.Range,
3105
+ {
3106
+ style: {
3107
+ position: "absolute",
3108
+ left: 0,
3109
+ height: "100%"
3110
+ },
3111
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3112
+ RoughSvg,
3113
+ {
3114
+ shape: "line",
3115
+ roughness: (roughness ?? 1.5) + 0.4,
3116
+ seed: deriveSeed(resolvedSeed, "range"),
3117
+ sketchColor: SKETCH_COLORS.accent,
3118
+ bowing: bowing ?? 1.6,
3119
+ strokeWidth: (strokeWidth ?? 1.6) + 0.6,
3120
+ inset: 4
3121
+ }
3122
+ )
3123
+ }
3124
+ )
3125
+ ]
3126
+ }
3127
+ ),
3128
+ /* @__PURE__ */ jsxRuntime.jsx(
3129
+ SliderPrimitive__namespace.Thumb,
3130
+ {
3131
+ style: {
3132
+ display: "block",
3133
+ width: 20,
3134
+ height: 20,
3135
+ position: "relative",
3136
+ outline: "none",
3137
+ cursor: "grab"
3138
+ },
3139
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3140
+ RoughSvg,
3141
+ {
3142
+ shape: thumbShape === "square" ? "rectangle" : "ellipse",
3143
+ roughness: (roughness ?? 1.5) * 0.85,
3144
+ seed: deriveSeed(resolvedSeed, "thumb"),
3145
+ sketchColor: SKETCH_COLORS.accent,
3146
+ fill: "#f7f6f2",
3147
+ fillStyle: fillStyle ?? "solid",
3148
+ bowing,
3149
+ strokeWidth: (strokeWidth ?? 1.5) + 0.3,
3150
+ inset: 1
3151
+ }
3152
+ )
3153
+ }
3154
+ )
3155
+ ]
3156
+ }
3157
+ );
3158
+ });
3159
+ var PREV_PATH = "M 12 4 L 6 10 L 12 16";
3160
+ var NEXT_PATH = "M 6 4 L 12 10 L 6 16";
3161
+ function pageItems(page, count) {
3162
+ if (count <= 7) {
3163
+ return Array.from({ length: count }, (_, i) => i + 1);
3164
+ }
3165
+ const items = [1];
3166
+ const start = Math.max(2, page - 1);
3167
+ const end = Math.min(count - 1, page + 1);
3168
+ if (start > 2) items.push("ellipsis");
3169
+ for (let n = start; n <= end; n += 1) items.push(n);
3170
+ if (end < count - 1) items.push("ellipsis");
3171
+ items.push(count);
3172
+ return items;
3173
+ }
3174
+ var Pagination = react.forwardRef(
3175
+ function Pagination2({
3176
+ className,
3177
+ style,
3178
+ page,
3179
+ count,
3180
+ onPageChange,
3181
+ roughness,
3182
+ seed,
3183
+ sketchColor,
3184
+ bowing,
3185
+ strokeWidth,
3186
+ ...rest
3187
+ }, ref) {
3188
+ const ink = sketchColor ?? SKETCH_COLORS.ink;
3189
+ const resolvedSeed = useResolvedSeed(seed);
3190
+ const items = pageItems(page, count);
3191
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3192
+ "nav",
3193
+ {
3194
+ ref,
3195
+ className: cn(className),
3196
+ "aria-label": "Pagination",
3197
+ style: {
3198
+ display: "inline-flex",
3199
+ alignItems: "center",
3200
+ gap: 4,
3201
+ ...style
3202
+ },
3203
+ ...rest,
3204
+ children: [
3205
+ /* @__PURE__ */ jsxRuntime.jsx(
3206
+ PageButton,
3207
+ {
3208
+ "aria-label": "Previous page",
3209
+ disabled: page <= 1,
3210
+ onClick: () => onPageChange?.(Math.max(1, page - 1)),
3211
+ roughness,
3212
+ seed: deriveSeed(resolvedSeed, "prev"),
3213
+ ink,
3214
+ bowing,
3215
+ strokeWidth,
3216
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { style: { position: "relative", width: 16, height: 16, display: "block" }, children: /* @__PURE__ */ jsxRuntime.jsx(
3217
+ RoughSvg,
3218
+ {
3219
+ shape: "path",
3220
+ path: PREV_PATH,
3221
+ roughness: (roughness ?? 1.5) * 0.7,
3222
+ seed: deriveSeed(resolvedSeed, "prev-arrow"),
3223
+ sketchColor: ink,
3224
+ strokeWidth: (strokeWidth ?? 1.5) + 0.2,
3225
+ inset: 0
3226
+ }
3227
+ ) })
3228
+ }
3229
+ ),
3230
+ items.map(
3231
+ (item, index) => item === "ellipsis" ? /* @__PURE__ */ jsxRuntime.jsx(
3232
+ "span",
3233
+ {
3234
+ style: {
3235
+ width: 28,
3236
+ textAlign: "center",
3237
+ fontFamily: doodleUiFontFamily,
3238
+ color: ink
3239
+ },
3240
+ children: "\u2026"
3241
+ },
3242
+ `e-${index}`
3243
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
3244
+ PageButton,
3245
+ {
3246
+ "aria-label": `Page ${item}`,
3247
+ "aria-current": item === page ? "page" : void 0,
3248
+ active: item === page,
3249
+ onClick: () => onPageChange?.(item),
3250
+ roughness,
3251
+ seed: deriveSeed(resolvedSeed, `page-${item}`),
3252
+ ink,
3253
+ bowing,
3254
+ strokeWidth,
3255
+ children: item
3256
+ },
3257
+ item
3258
+ )
3259
+ ),
3260
+ /* @__PURE__ */ jsxRuntime.jsx(
3261
+ PageButton,
3262
+ {
3263
+ "aria-label": "Next page",
3264
+ disabled: page >= count,
3265
+ onClick: () => onPageChange?.(Math.min(count, page + 1)),
3266
+ roughness,
3267
+ seed: deriveSeed(resolvedSeed, "next"),
3268
+ ink,
3269
+ bowing,
3270
+ strokeWidth,
3271
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { style: { position: "relative", width: 16, height: 16, display: "block" }, children: /* @__PURE__ */ jsxRuntime.jsx(
3272
+ RoughSvg,
3273
+ {
3274
+ shape: "path",
3275
+ path: NEXT_PATH,
3276
+ roughness: (roughness ?? 1.5) * 0.7,
3277
+ seed: deriveSeed(resolvedSeed, "next-arrow"),
3278
+ sketchColor: ink,
3279
+ strokeWidth: (strokeWidth ?? 1.5) + 0.2,
3280
+ inset: 0
3281
+ }
3282
+ ) })
3283
+ }
3284
+ )
3285
+ ]
3286
+ }
3287
+ );
3288
+ }
3289
+ );
3290
+ function PageButton({
3291
+ children,
3292
+ className,
3293
+ style,
3294
+ active,
3295
+ disabled,
3296
+ roughness,
3297
+ seed,
3298
+ ink,
3299
+ bowing,
3300
+ strokeWidth,
3301
+ ...rest
3302
+ }) {
3303
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3304
+ "button",
3305
+ {
3306
+ type: "button",
3307
+ disabled,
3308
+ className: cn(className),
3309
+ style: {
3310
+ position: "relative",
3311
+ width: 36,
3312
+ height: 36,
3313
+ padding: 0,
3314
+ border: "none",
3315
+ background: "transparent",
3316
+ cursor: disabled ? "not-allowed" : "pointer",
3317
+ color: ink,
3318
+ fontFamily: doodleUiFontFamily,
3319
+ fontWeight: active ? doodleUiFontWeight(700) : doodleUiFontWeight(400),
3320
+ fontSize: 14,
3321
+ outline: "none",
3322
+ opacity: disabled ? 0.4 : 1,
3323
+ ...style
3324
+ },
3325
+ ...rest,
3326
+ children: [
3327
+ /* @__PURE__ */ jsxRuntime.jsx(
3328
+ RoughSvg,
3329
+ {
3330
+ shape: "ellipse",
3331
+ roughness,
3332
+ seed,
3333
+ sketchColor: active ? SKETCH_COLORS.accent : ink,
3334
+ bowing,
3335
+ fill: active ? SKETCH_COLORS.accentFill : void 0,
3336
+ fillStyle: active ? "hachure" : void 0,
3337
+ strokeWidth: active ? (strokeWidth ?? 1.6) + 0.3 : strokeWidth ?? 1.4,
3338
+ inset: 1.5
3339
+ }
3340
+ ),
3341
+ active ? /* @__PURE__ */ jsxRuntime.jsx(
3342
+ RoughSvg,
3343
+ {
3344
+ shape: "ellipse",
3345
+ roughness: (roughness ?? 1.5) + 0.45,
3346
+ seed,
3347
+ sketchColor: SKETCH_COLORS.accent,
3348
+ bowing: bowing ?? 1.6,
3349
+ strokeWidth: 1.1,
3350
+ inset: -1.5,
3351
+ style: { opacity: 0.7 }
3352
+ }
3353
+ ) : null,
3354
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { position: "relative", zIndex: 1 }, children })
3355
+ ]
3356
+ }
3357
+ );
3358
+ }
3359
+ var SLASH_PATH = "M 10 3 L 6 15";
3360
+ var CHEVRON_PATH3 = "M 5 4 L 11 9 L 5 14";
3361
+ var BreadcrumbSketchContext = react.createContext(null);
3362
+ function useBreadcrumbSketch() {
3363
+ const ctx = react.useContext(BreadcrumbSketchContext);
3364
+ if (!ctx) {
3365
+ throw new Error("BreadcrumbItem must be used inside <Breadcrumb>.");
3366
+ }
3367
+ return ctx;
3368
+ }
3369
+ var Breadcrumb = react.forwardRef(
3370
+ function Breadcrumb2({
3371
+ className,
3372
+ style,
3373
+ children,
3374
+ separator = "slash",
3375
+ roughness,
3376
+ seed,
3377
+ sketchColor,
3378
+ bowing,
3379
+ strokeWidth,
3380
+ ...rest
3381
+ }, ref) {
3382
+ const ink = sketchColor ?? SKETCH_COLORS.ink;
3383
+ const resolvedSeed = useResolvedSeed(seed);
3384
+ const items = react.Children.toArray(children).filter(react.isValidElement);
3385
+ return /* @__PURE__ */ jsxRuntime.jsx(
3386
+ BreadcrumbSketchContext.Provider,
3387
+ {
3388
+ value: {
3389
+ roughness,
3390
+ seed: resolvedSeed,
3391
+ sketchColor,
3392
+ bowing,
3393
+ strokeWidth,
3394
+ resolvedSeed,
3395
+ ink,
3396
+ separator
3397
+ },
3398
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3399
+ "nav",
3400
+ {
3401
+ ref,
3402
+ className: cn(className),
3403
+ "aria-label": "Breadcrumb",
3404
+ style,
3405
+ ...rest,
3406
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3407
+ "ol",
3408
+ {
3409
+ style: {
3410
+ display: "flex",
3411
+ flexWrap: "wrap",
3412
+ alignItems: "center",
3413
+ gap: 4,
3414
+ listStyle: "none",
3415
+ margin: 0,
3416
+ padding: 0,
3417
+ fontFamily: doodleUiFontFamily,
3418
+ color: ink,
3419
+ fontSize: 14
3420
+ },
3421
+ children: items.map((child, index) => /* @__PURE__ */ jsxRuntime.jsxs(
3422
+ "li",
3423
+ {
3424
+ style: { display: "inline-flex", alignItems: "center", gap: 4 },
3425
+ children: [
3426
+ react.cloneElement(child, {
3427
+ index
3428
+ }),
3429
+ index < items.length - 1 ? /* @__PURE__ */ jsxRuntime.jsx(
3430
+ SeparatorMark,
3431
+ {
3432
+ index,
3433
+ separator,
3434
+ resolvedSeed,
3435
+ roughness,
3436
+ ink,
3437
+ bowing,
3438
+ strokeWidth
3439
+ }
3440
+ ) : null
3441
+ ]
3442
+ },
3443
+ index
3444
+ ))
3445
+ }
3446
+ )
3447
+ }
3448
+ )
3449
+ }
3450
+ );
3451
+ }
3452
+ );
3453
+ function SeparatorMark({
3454
+ index,
3455
+ separator,
3456
+ resolvedSeed,
3457
+ roughness,
3458
+ ink,
3459
+ bowing,
3460
+ strokeWidth
3461
+ }) {
3462
+ return /* @__PURE__ */ jsxRuntime.jsx(
3463
+ "span",
3464
+ {
3465
+ "aria-hidden": "true",
3466
+ style: { position: "relative", width: 16, height: 18, display: "inline-block" },
3467
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3468
+ RoughSvg,
3469
+ {
3470
+ shape: "path",
3471
+ path: separator === "chevron" ? CHEVRON_PATH3 : SLASH_PATH,
3472
+ roughness: (roughness ?? 1.5) * 0.85,
3473
+ seed: deriveSeed(resolvedSeed, `sep-${index}`),
3474
+ sketchColor: ink,
3475
+ bowing: bowing ?? 1.6,
3476
+ strokeWidth: strokeWidth ?? 1.4,
3477
+ inset: 0
3478
+ }
3479
+ )
3480
+ }
3481
+ );
3482
+ }
3483
+ var BreadcrumbItem = react.forwardRef(
3484
+ function BreadcrumbItem2({ className, style, href, current, children, index: _index, ...rest }, ref) {
3485
+ const sketch = useBreadcrumbSketch();
3486
+ const contentStyle = {
3487
+ color: current ? sketch.ink : sketch.ink,
3488
+ opacity: current ? 1 : 0.75,
3489
+ textDecoration: "none",
3490
+ fontFamily: doodleUiFontFamily,
3491
+ ...style
3492
+ };
3493
+ if (href && !current) {
3494
+ return /* @__PURE__ */ jsxRuntime.jsx(
3495
+ "a",
3496
+ {
3497
+ href,
3498
+ className: cn(className),
3499
+ style: contentStyle,
3500
+ ...rest,
3501
+ children
3502
+ }
3503
+ );
3504
+ }
3505
+ return /* @__PURE__ */ jsxRuntime.jsx(
3506
+ "span",
3507
+ {
3508
+ ref,
3509
+ className: cn(className),
3510
+ "aria-current": current ? "page" : void 0,
3511
+ style: contentStyle,
3512
+ ...rest,
3513
+ children
3514
+ }
3515
+ );
3516
+ }
3517
+ );
3518
+ var Skeleton = react.forwardRef(
3519
+ function Skeleton2({
3520
+ className,
3521
+ style,
3522
+ variant = "rect",
3523
+ pulse = true,
3524
+ width,
3525
+ height,
3526
+ roughness,
3527
+ seed,
3528
+ sketchColor,
3529
+ bowing,
3530
+ fillStyle,
3531
+ strokeWidth,
3532
+ ...rest
3533
+ }, ref) {
3534
+ const base = useResolvedSeed(seed);
3535
+ const [tick, setTick] = react.useState(0);
3536
+ const ink = sketchColor ?? SKETCH_COLORS.ink;
3537
+ react.useEffect(() => {
3538
+ if (!pulse) return;
3539
+ const id = window.setInterval(() => {
3540
+ setTick((current) => current + 1);
3541
+ }, 900);
3542
+ return () => window.clearInterval(id);
3543
+ }, [pulse]);
3544
+ const resolved = pulse ? deriveSeed(base, `pulse-${tick}`) : base;
3545
+ const shape = variant === "circle" ? "ellipse" : "rectangle";
3546
+ const defaultHeight = variant === "text" ? 14 : variant === "circle" ? 40 : 80;
3547
+ const defaultWidth = variant === "circle" ? 40 : "100%";
3548
+ return /* @__PURE__ */ jsxRuntime.jsx(
3549
+ "div",
3550
+ {
3551
+ ref,
3552
+ "aria-hidden": "true",
3553
+ className: cn(className),
3554
+ style: {
3555
+ position: "relative",
3556
+ width: width ?? defaultWidth,
3557
+ height: height ?? defaultHeight,
3558
+ maxWidth: "100%",
3559
+ ...style
3560
+ },
3561
+ ...rest,
3562
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3563
+ RoughSvg,
3564
+ {
3565
+ shape,
3566
+ roughness: (roughness ?? 1.5) + 0.4,
3567
+ seed: resolved,
3568
+ sketchColor: ink,
3569
+ fill: ink,
3570
+ fillStyle: fillStyle ?? "hachure",
3571
+ bowing: bowing ?? 1.6,
3572
+ strokeWidth: strokeWidth ?? 1.1,
3573
+ inset: 2,
3574
+ style: { opacity: 0.28 }
3575
+ }
3576
+ )
3577
+ }
3578
+ );
3579
+ }
3580
+ );
3581
+ function normalizeSteps(steps) {
3582
+ return steps.map(
3583
+ (step) => step !== null && typeof step === "object" && "label" in step ? step : { label: step }
3584
+ );
3585
+ }
3586
+ var Stepper = react.forwardRef(
3587
+ function Stepper2({
3588
+ className,
3589
+ style,
3590
+ steps,
3591
+ current = 0,
3592
+ orientation = "horizontal",
3593
+ roughness,
3594
+ seed,
3595
+ sketchColor,
3596
+ bowing,
3597
+ fillStyle,
3598
+ strokeWidth,
3599
+ ...rest
3600
+ }, ref) {
3601
+ const ink = sketchColor ?? SKETCH_COLORS.ink;
3602
+ const resolvedSeed = useResolvedSeed(seed);
3603
+ const items = normalizeSteps(steps);
3604
+ const horizontal = orientation === "horizontal";
3605
+ return /* @__PURE__ */ jsxRuntime.jsx(
3606
+ "div",
3607
+ {
3608
+ ref,
3609
+ role: "list",
3610
+ className: cn(className),
3611
+ style: {
3612
+ display: "flex",
3613
+ flexDirection: horizontal ? "row" : "column",
3614
+ alignItems: horizontal ? "flex-start" : "stretch",
3615
+ ...style
3616
+ },
3617
+ ...rest,
3618
+ children: items.map((step, index) => {
3619
+ const complete = index < current;
3620
+ const active = index === current;
3621
+ const markerColor = complete || active ? SKETCH_COLORS.accent : ink;
3622
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3623
+ "div",
3624
+ {
3625
+ role: "listitem",
3626
+ "aria-current": active ? "step" : void 0,
3627
+ style: {
3628
+ display: "flex",
3629
+ flex: horizontal ? 1 : void 0,
3630
+ flexDirection: horizontal ? "column" : "row",
3631
+ alignItems: horizontal ? "center" : "flex-start",
3632
+ minWidth: 0
3633
+ },
3634
+ children: [
3635
+ /* @__PURE__ */ jsxRuntime.jsxs(
3636
+ "div",
3637
+ {
3638
+ style: {
3639
+ display: "flex",
3640
+ flexDirection: horizontal ? "row" : "column",
3641
+ alignItems: "center",
3642
+ width: horizontal ? "100%" : void 0
3643
+ },
3644
+ children: [
3645
+ /* @__PURE__ */ jsxRuntime.jsxs(
3646
+ "span",
3647
+ {
3648
+ style: {
3649
+ position: "relative",
3650
+ width: 28,
3651
+ height: 28,
3652
+ flexShrink: 0,
3653
+ display: "inline-flex",
3654
+ alignItems: "center",
3655
+ justifyContent: "center",
3656
+ fontFamily: doodleUiFontFamily,
3657
+ fontWeight: doodleUiFontWeight(700),
3658
+ fontSize: 13,
3659
+ color: markerColor
3660
+ },
3661
+ children: [
3662
+ /* @__PURE__ */ jsxRuntime.jsx(
3663
+ RoughSvg,
3664
+ {
3665
+ shape: "ellipse",
3666
+ roughness,
3667
+ seed: deriveSeed(resolvedSeed, `step-${index}`),
3668
+ sketchColor: markerColor,
3669
+ fill: complete ? SKETCH_COLORS.accentFill : active ? "#f7f6f2" : void 0,
3670
+ fillStyle: complete || active ? fillStyle ?? "hachure" : void 0,
3671
+ bowing,
3672
+ strokeWidth: active ? (strokeWidth ?? 1.6) + 0.4 : strokeWidth ?? 1.5,
3673
+ inset: 1.5
3674
+ }
3675
+ ),
3676
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { position: "relative", zIndex: 1 }, children: complete ? "\u2713" : index + 1 })
3677
+ ]
3678
+ }
3679
+ ),
3680
+ index < items.length - 1 ? /* @__PURE__ */ jsxRuntime.jsx(
3681
+ "span",
3682
+ {
3683
+ style: {
3684
+ position: "relative",
3685
+ flex: 1,
3686
+ width: horizontal ? void 0 : 12,
3687
+ height: horizontal ? 12 : 28,
3688
+ minWidth: horizontal ? 16 : 12,
3689
+ alignSelf: "center"
3690
+ },
3691
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3692
+ RoughSvg,
3693
+ {
3694
+ shape: horizontal ? "line" : "line-vertical",
3695
+ roughness: (roughness ?? 1.5) + 0.3,
3696
+ seed: deriveSeed(resolvedSeed, `connector-${index}`),
3697
+ sketchColor: complete ? SKETCH_COLORS.accent : ink,
3698
+ bowing: bowing ?? 2,
3699
+ strokeWidth: strokeWidth ?? 1.4,
3700
+ inset: 2
3701
+ }
3702
+ )
3703
+ }
3704
+ ) : null
3705
+ ]
3706
+ }
3707
+ ),
3708
+ /* @__PURE__ */ jsxRuntime.jsxs(
3709
+ "div",
3710
+ {
3711
+ style: {
3712
+ marginTop: horizontal ? 8 : 0,
3713
+ marginLeft: horizontal ? 0 : 10,
3714
+ paddingBottom: horizontal ? 0 : 8,
3715
+ textAlign: horizontal ? "center" : "left",
3716
+ fontFamily: doodleUiFontFamily,
3717
+ fontSize: 13,
3718
+ color: ink
3719
+ },
3720
+ children: [
3721
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontWeight: doodleUiFontWeight(600) }, children: step.label }),
3722
+ step.description ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { opacity: 0.7, fontSize: 12, marginTop: 2 }, children: step.description }) : null
3723
+ ]
3724
+ }
3725
+ )
3726
+ ]
3727
+ },
3728
+ index
3729
+ );
3730
+ })
3731
+ }
3732
+ );
3733
+ }
3734
+ );
1284
3735
 
3736
+ exports.Accordion = Accordion;
3737
+ exports.AccordionContent = AccordionContent;
3738
+ exports.AccordionItem = AccordionItem;
3739
+ exports.AccordionTrigger = AccordionTrigger;
1285
3740
  exports.Alert = Alert;
3741
+ exports.Avatar = Avatar;
1286
3742
  exports.Badge = Badge;
3743
+ exports.Breadcrumb = Breadcrumb;
3744
+ exports.BreadcrumbItem = BreadcrumbItem;
1287
3745
  exports.Button = Button;
1288
3746
  exports.Card = Card;
1289
3747
  exports.Checkbox = Checkbox;
@@ -1291,7 +3749,12 @@ exports.DEFAULT_BOWING = DEFAULT_BOWING;
1291
3749
  exports.DEFAULT_INK = DEFAULT_INK;
1292
3750
  exports.DEFAULT_ROUGHNESS = DEFAULT_ROUGHNESS;
1293
3751
  exports.DEFAULT_STROKE_WIDTH = DEFAULT_STROKE_WIDTH;
3752
+ exports.DRAW_IN_ALERT_MS = DRAW_IN_ALERT_MS;
3753
+ exports.DRAW_IN_DURATION_MS = DRAW_IN_DURATION_MS;
3754
+ exports.DRAW_IN_MARK_MS = DRAW_IN_MARK_MS;
3755
+ exports.DRAW_IN_TOOLTIP_MS = DRAW_IN_TOOLTIP_MS;
1294
3756
  exports.Divider = Divider;
3757
+ exports.DoodleUIProvider = DoodleUIProvider;
1295
3758
  exports.Input = Input;
1296
3759
  exports.Modal = Modal;
1297
3760
  exports.ModalClose = ModalClose;
@@ -1299,17 +3762,54 @@ exports.ModalDescription = ModalDescription;
1299
3762
  exports.ModalRoot = ModalRoot;
1300
3763
  exports.ModalTitle = ModalTitle;
1301
3764
  exports.ModalTrigger = ModalTrigger;
3765
+ exports.Pagination = Pagination;
1302
3766
  exports.Progress = Progress;
1303
3767
  exports.Radio = Radio;
1304
3768
  exports.RadioGroup = RadioGroup;
1305
3769
  exports.RoughSvg = RoughSvg;
1306
3770
  exports.SKETCH_COLORS = SKETCH_COLORS;
3771
+ exports.Select = Select;
3772
+ exports.SelectContent = SelectContent;
3773
+ exports.SelectGroup = SelectGroup;
3774
+ exports.SelectItem = SelectItem;
3775
+ exports.SelectLabel = SelectLabel;
3776
+ exports.SelectRoot = SelectRoot;
3777
+ exports.SelectSeparator = SelectSeparator;
3778
+ exports.SelectTrigger = SelectTrigger;
3779
+ exports.SelectValue = SelectValue;
3780
+ exports.Skeleton = Skeleton;
1307
3781
  exports.SketchBox = SketchBox;
1308
3782
  exports.SketchSeedProvider = SketchSeedProvider;
3783
+ exports.Slider = Slider;
3784
+ exports.Stepper = Stepper;
3785
+ exports.Switch = Switch;
3786
+ exports.TABLE_STAGGER_MS = TABLE_STAGGER_MS;
3787
+ exports.Tab = Tab;
3788
+ exports.TabList = TabList;
3789
+ exports.TabPanel = TabPanel;
3790
+ exports.Table = Table;
3791
+ exports.TableBody = TableBody;
3792
+ exports.TableCell = TableCell;
3793
+ exports.TableHead = TableHead;
3794
+ exports.TableHeaderCell = TableHeaderCell;
3795
+ exports.TableRow = TableRow;
3796
+ exports.Tabs = Tabs;
1309
3797
  exports.Textarea = Textarea;
3798
+ exports.Toast = Toast;
3799
+ exports.ToastAction = ToastAction;
3800
+ exports.ToastClose = ToastClose;
3801
+ exports.ToastDescription = ToastDescription;
3802
+ exports.ToastProvider = ToastProvider;
3803
+ exports.ToastRoot = ToastRoot;
3804
+ exports.ToastTitle = ToastTitle;
3805
+ exports.ToastViewport = ToastViewport;
1310
3806
  exports.Tooltip = Tooltip;
1311
3807
  exports.TooltipProvider = TooltipProvider;
3808
+ exports.deriveSeed = deriveSeed;
1312
3809
  exports.toRoughOptions = toRoughOptions;
3810
+ exports.useAnimate = useAnimate;
3811
+ exports.useDoodleUI = useDoodleUI;
3812
+ exports.useDrawIn = useDrawIn;
1313
3813
  exports.useResolvedSeed = useResolvedSeed;
1314
3814
  exports.useSketchSeed = useSketchSeed;
1315
3815
  //# sourceMappingURL=index.cjs.map