doodleui-react 0.2.0 → 0.4.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,6 +7,7 @@ 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');
11
12
  var SelectPrimitive = require('@radix-ui/react-select');
12
13
  var SwitchPrimitive = require('@radix-ui/react-switch');
@@ -15,6 +16,12 @@ var ToastPrimitive = require('@radix-ui/react-toast');
15
16
  var AccordionPrimitive = require('@radix-ui/react-accordion');
16
17
  var AvatarPrimitive = require('@radix-ui/react-avatar');
17
18
  var SliderPrimitive = require('@radix-ui/react-slider');
19
+ var LabelPrimitive = require('@radix-ui/react-label');
20
+ var CollapsiblePrimitive = require('@radix-ui/react-collapsible');
21
+ var PopoverPrimitive = require('@radix-ui/react-popover');
22
+ var DropdownMenuPrimitive = require('@radix-ui/react-dropdown-menu');
23
+ var AlertDialogPrimitive = require('@radix-ui/react-alert-dialog');
24
+ var cmdk = require('cmdk');
18
25
 
19
26
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
20
27
 
@@ -48,6 +55,11 @@ var ToastPrimitive__namespace = /*#__PURE__*/_interopNamespace(ToastPrimitive);
48
55
  var AccordionPrimitive__namespace = /*#__PURE__*/_interopNamespace(AccordionPrimitive);
49
56
  var AvatarPrimitive__namespace = /*#__PURE__*/_interopNamespace(AvatarPrimitive);
50
57
  var SliderPrimitive__namespace = /*#__PURE__*/_interopNamespace(SliderPrimitive);
58
+ var LabelPrimitive__namespace = /*#__PURE__*/_interopNamespace(LabelPrimitive);
59
+ var CollapsiblePrimitive__namespace = /*#__PURE__*/_interopNamespace(CollapsiblePrimitive);
60
+ var PopoverPrimitive__namespace = /*#__PURE__*/_interopNamespace(PopoverPrimitive);
61
+ var DropdownMenuPrimitive__namespace = /*#__PURE__*/_interopNamespace(DropdownMenuPrimitive);
62
+ var AlertDialogPrimitive__namespace = /*#__PURE__*/_interopNamespace(AlertDialogPrimitive);
51
63
 
52
64
  // src/types.ts
53
65
  function toRoughOptions(props) {
@@ -83,6 +95,11 @@ var SKETCH_COLORS = {
83
95
  };
84
96
 
85
97
  // src/utils.ts
98
+ function assignRef(ref, value) {
99
+ if (!ref) return;
100
+ if (typeof ref === "function") ref(value);
101
+ else ref.current = value;
102
+ }
86
103
  function randomSeed() {
87
104
  return Math.floor(Math.random() * 2 ** 31);
88
105
  }
@@ -283,6 +300,177 @@ function RoughSvg({
283
300
  }
284
301
  );
285
302
  }
303
+ var DoodleUIContext = react.createContext(null);
304
+ function DoodleUIProvider({
305
+ children,
306
+ animate = true,
307
+ forceAnimate = false
308
+ }) {
309
+ const value = react.useMemo(
310
+ () => ({ animate, forceAnimate }),
311
+ [animate, forceAnimate]
312
+ );
313
+ return /* @__PURE__ */ jsxRuntime.jsx(DoodleUIContext.Provider, { value, children });
314
+ }
315
+ function useDoodleUI() {
316
+ return react.useContext(DoodleUIContext) ?? { animate: true, forceAnimate: false };
317
+ }
318
+
319
+ // src/animations/resolveAnimate.ts
320
+ function resolveAnimate({
321
+ animate,
322
+ providerAnimate = true,
323
+ forceAnimate = false,
324
+ prefersReducedMotion = false
325
+ }) {
326
+ if (prefersReducedMotion && !forceAnimate) return false;
327
+ if (animate !== void 0) return animate;
328
+ return providerAnimate;
329
+ }
330
+ function subscribe(onStoreChange) {
331
+ const media = window.matchMedia("(prefers-reduced-motion: reduce)");
332
+ media.addEventListener("change", onStoreChange);
333
+ return () => media.removeEventListener("change", onStoreChange);
334
+ }
335
+ function getSnapshot() {
336
+ return window.matchMedia("(prefers-reduced-motion: reduce)").matches;
337
+ }
338
+ function getServerSnapshot() {
339
+ return false;
340
+ }
341
+ function usePrefersReducedMotion() {
342
+ return react.useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
343
+ }
344
+
345
+ // src/animations/useAnimate.ts
346
+ function useAnimate(animate) {
347
+ const { animate: providerAnimate, forceAnimate } = useDoodleUI();
348
+ const prefersReducedMotion = usePrefersReducedMotion();
349
+ return resolveAnimate({
350
+ animate,
351
+ providerAnimate,
352
+ forceAnimate,
353
+ prefersReducedMotion
354
+ });
355
+ }
356
+ function useTweenNumber(target, enabled, duration = 400) {
357
+ const [value, setValue] = react.useState(target);
358
+ const valueRef = react.useRef(target);
359
+ valueRef.current = value;
360
+ react.useEffect(() => {
361
+ if (!enabled) {
362
+ valueRef.current = target;
363
+ setValue(target);
364
+ return;
365
+ }
366
+ const from = valueRef.current;
367
+ if (from === target) return;
368
+ const start = performance.now();
369
+ let frame = 0;
370
+ const tick = (now) => {
371
+ const t = Math.min(1, (now - start) / duration);
372
+ const eased = 1 - (1 - t) ** 3;
373
+ const next = from + (target - from) * eased;
374
+ valueRef.current = next;
375
+ setValue(next);
376
+ if (t < 1) frame = requestAnimationFrame(tick);
377
+ };
378
+ frame = requestAnimationFrame(tick);
379
+ return () => cancelAnimationFrame(frame);
380
+ }, [target, enabled, duration]);
381
+ return enabled ? value : target;
382
+ }
383
+ var DRAW_IN_DURATION_MS = 400;
384
+ var DRAW_IN_ALERT_MS = 200;
385
+ var DRAW_IN_TOOLTIP_MS = 180;
386
+ var DRAW_IN_MARK_MS = 240;
387
+ var TABLE_STAGGER_MS = 40;
388
+ var DRAW_IN_EASING = "ease-out";
389
+ var running = /* @__PURE__ */ new WeakMap();
390
+ function collectStrokePaths(root) {
391
+ const groups = root.querySelectorAll("g");
392
+ if (groups.length > 0) {
393
+ const paths = [];
394
+ groups.forEach((group) => {
395
+ const children = group.querySelectorAll(":scope > path");
396
+ if (children.length === 0) return;
397
+ paths.push(children[children.length - 1]);
398
+ });
399
+ return paths;
400
+ }
401
+ return Array.from(root.querySelectorAll("path"));
402
+ }
403
+ function getStrokePaths(target) {
404
+ if (target instanceof SVGPathElement) return [target];
405
+ if (target instanceof SVGSVGElement) return collectStrokePaths(target);
406
+ const svgs = target.querySelectorAll("svg");
407
+ if (svgs.length > 0) {
408
+ return Array.from(svgs).flatMap((svg) => collectStrokePaths(svg));
409
+ }
410
+ return collectStrokePaths(target);
411
+ }
412
+ function clearDash(path) {
413
+ path.style.strokeDasharray = "";
414
+ path.style.strokeDashoffset = "";
415
+ }
416
+ function cancelDrawIn(target) {
417
+ if (!target) return;
418
+ const animations = running.get(target);
419
+ animations?.forEach((animation) => animation.cancel());
420
+ running.delete(target);
421
+ getStrokePaths(target).forEach(clearDash);
422
+ }
423
+ function drawIn(target, duration = DRAW_IN_DURATION_MS, delay = 0) {
424
+ cancelDrawIn(target);
425
+ const paths = getStrokePaths(target);
426
+ const animations = [];
427
+ for (const path of paths) {
428
+ let length = 0;
429
+ try {
430
+ length = path.getTotalLength();
431
+ } catch {
432
+ continue;
433
+ }
434
+ if (length <= 0) continue;
435
+ path.style.strokeDasharray = `${length}`;
436
+ path.style.strokeDashoffset = `${length}`;
437
+ const animation = path.animate(
438
+ [{ strokeDashoffset: String(length) }, { strokeDashoffset: "0" }],
439
+ { duration, delay, easing: DRAW_IN_EASING, fill: "forwards" }
440
+ );
441
+ animation.finished.then(() => {
442
+ clearDash(path);
443
+ }).catch(() => {
444
+ });
445
+ animations.push(animation);
446
+ }
447
+ running.set(target, animations);
448
+ }
449
+ function useDrawIn(pathRef, duration = DRAW_IN_DURATION_MS, enabled = true, replayKey, delay = 0) {
450
+ react.useLayoutEffect(() => {
451
+ const target = pathRef.current;
452
+ if (!target) return;
453
+ if (!enabled) {
454
+ cancelDrawIn(target);
455
+ return;
456
+ }
457
+ const apply = () => drawIn(target, duration, delay);
458
+ if (getStrokePaths(target).length > 0) {
459
+ apply();
460
+ return () => cancelDrawIn(target);
461
+ }
462
+ const observer = new MutationObserver(() => {
463
+ if (getStrokePaths(target).length === 0) return;
464
+ observer.disconnect();
465
+ apply();
466
+ });
467
+ observer.observe(target, { childList: true, subtree: true });
468
+ return () => {
469
+ observer.disconnect();
470
+ cancelDrawIn(target);
471
+ };
472
+ }, [pathRef, duration, enabled, replayKey, delay]);
473
+ }
286
474
  var SketchBox = react.forwardRef(
287
475
  function SketchBox2({
288
476
  children,
@@ -301,12 +489,21 @@ var SketchBox = react.forwardRef(
301
489
  strokeWidth,
302
490
  inset,
303
491
  path,
492
+ animate,
493
+ drawInDuration = DRAW_IN_DURATION_MS,
494
+ drawInKey,
304
495
  ...rest
305
496
  }, ref) {
497
+ const rootRef = react.useRef(null);
498
+ const shouldAnimate = useAnimate(animate);
499
+ useDrawIn(rootRef, drawInDuration, shouldAnimate, drawInKey);
306
500
  return /* @__PURE__ */ jsxRuntime.jsxs(
307
501
  "div",
308
502
  {
309
- ref,
503
+ ref: (node) => {
504
+ rootRef.current = node;
505
+ assignRef(ref, node);
506
+ },
310
507
  className: cn(className),
311
508
  style: { position: "relative", ...style },
312
509
  ...rest,
@@ -364,6 +561,10 @@ var SIZE_STYLES = {
364
561
  md: { fontSize: 15, padding: "8px 16px", minHeight: 38 },
365
562
  lg: { fontSize: 17, padding: "11px 22px", minHeight: 46 }
366
563
  };
564
+ function assignRef2(ref, value) {
565
+ if (typeof ref === "function") ref(value);
566
+ else if (ref) ref.current = value;
567
+ }
367
568
  var Button = react.forwardRef(
368
569
  function Button2({
369
570
  children,
@@ -378,18 +579,28 @@ var Button = react.forwardRef(
378
579
  fillStyle,
379
580
  strokeWidth,
380
581
  disabled,
582
+ animate,
381
583
  onMouseEnter,
382
584
  onMouseLeave,
383
585
  ...rest
384
586
  }, ref) {
587
+ const rootRef = react.useRef(null);
385
588
  const [hovered, setHovered] = react.useState(false);
589
+ const shouldAnimate = useAnimate(animate);
590
+ const resolvedSeed = useResolvedSeed(seed);
591
+ const hoverSeed = deriveSeed(resolvedSeed, "hover");
592
+ const sketchSeed = shouldAnimate && hovered && !disabled ? hoverSeed : resolvedSeed;
386
593
  const ink = sketchColor ?? SKETCH_COLORS.ink;
387
594
  const fill = variant === "primary" ? SKETCH_COLORS.accentFill : variant === "secondary" ? SKETCH_COLORS.secondaryFill : void 0;
388
595
  const stroke = variant === "ghost" && !hovered ? "transparent" : variant === "primary" ? sketchColor ?? SKETCH_COLORS.accent : ink;
596
+ useDrawIn(rootRef, DRAW_IN_DURATION_MS, shouldAnimate, sketchSeed);
389
597
  return /* @__PURE__ */ jsxRuntime.jsxs(
390
598
  "button",
391
599
  {
392
- ref,
600
+ ref: (node) => {
601
+ rootRef.current = node;
602
+ assignRef2(ref, node);
603
+ },
393
604
  type: "button",
394
605
  className: cn(className),
395
606
  disabled,
@@ -425,12 +636,12 @@ var Button = react.forwardRef(
425
636
  {
426
637
  shape: "rectangle",
427
638
  roughness,
428
- seed,
639
+ seed: sketchSeed,
429
640
  sketchColor: stroke,
430
641
  bowing,
431
642
  fillStyle: fillStyle ?? "hachure",
432
643
  fill,
433
- strokeWidth: hovered ? (strokeWidth ?? 1.75) + 0.4 : strokeWidth
644
+ strokeWidth: !shouldAnimate && hovered ? (strokeWidth ?? 1.75) + 0.4 : strokeWidth
434
645
  }
435
646
  ),
436
647
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: { position: "relative", zIndex: 1 }, children })
@@ -452,11 +663,18 @@ var Input = react.forwardRef(function Input2({
452
663
  id,
453
664
  onFocus,
454
665
  onBlur,
666
+ animate,
455
667
  ...rest
456
668
  }, ref) {
457
669
  const [focused, setFocused] = react.useState(false);
670
+ const fieldRef = react.useRef(null);
671
+ const shouldAnimate = useAnimate(animate);
672
+ const resolvedSeed = useResolvedSeed(seed);
673
+ const focusSeed = deriveSeed(resolvedSeed, "focus");
674
+ const sketchSeed = shouldAnimate && focused ? focusSeed : resolvedSeed;
458
675
  const ink = sketchColor ?? SKETCH_COLORS.ink;
459
676
  const inputId = id;
677
+ useDrawIn(fieldRef, DRAW_IN_DURATION_MS, shouldAnimate, sketchSeed);
460
678
  return /* @__PURE__ */ jsxRuntime.jsxs(
461
679
  "label",
462
680
  {
@@ -480,17 +698,17 @@ var Input = react.forwardRef(function Input2({
480
698
  children: label
481
699
  }
482
700
  ) : null,
483
- /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { position: "relative", display: "block" }, children: [
701
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { ref: fieldRef, style: { position: "relative", display: "block" }, children: [
484
702
  /* @__PURE__ */ jsxRuntime.jsx(
485
703
  RoughSvg,
486
704
  {
487
705
  shape: "rectangle",
488
706
  roughness,
489
- seed,
707
+ seed: sketchSeed,
490
708
  sketchColor: focused ? SKETCH_COLORS.accent : ink,
491
709
  bowing,
492
710
  fillStyle,
493
- strokeWidth: focused ? (strokeWidth ?? 1.75) + 0.35 : strokeWidth
711
+ strokeWidth: focused && !shouldAnimate ? (strokeWidth ?? 1.75) + 0.35 : focused ? (strokeWidth ?? 1.75) + 0.2 : strokeWidth
494
712
  }
495
713
  ),
496
714
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -544,10 +762,17 @@ var Textarea = react.forwardRef(
544
762
  rows = 4,
545
763
  onFocus,
546
764
  onBlur,
765
+ animate,
547
766
  ...rest
548
767
  }, ref) {
549
768
  const [focused, setFocused] = react.useState(false);
769
+ const fieldRef = react.useRef(null);
770
+ const shouldAnimate = useAnimate(animate);
771
+ const resolvedSeed = useResolvedSeed(seed);
772
+ const focusSeed = deriveSeed(resolvedSeed, "focus");
773
+ const sketchSeed = shouldAnimate && focused ? focusSeed : resolvedSeed;
550
774
  const ink = sketchColor ?? SKETCH_COLORS.ink;
775
+ useDrawIn(fieldRef, DRAW_IN_DURATION_MS, shouldAnimate, sketchSeed);
551
776
  return /* @__PURE__ */ jsxRuntime.jsxs(
552
777
  "label",
553
778
  {
@@ -571,17 +796,17 @@ var Textarea = react.forwardRef(
571
796
  children: label
572
797
  }
573
798
  ) : null,
574
- /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { position: "relative", display: "block" }, children: [
799
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { ref: fieldRef, style: { position: "relative", display: "block" }, children: [
575
800
  /* @__PURE__ */ jsxRuntime.jsx(
576
801
  RoughSvg,
577
802
  {
578
803
  shape: "rectangle",
579
804
  roughness,
580
- seed,
805
+ seed: sketchSeed,
581
806
  sketchColor: focused ? SKETCH_COLORS.accent : ink,
582
807
  bowing,
583
808
  fillStyle,
584
- strokeWidth: focused ? (strokeWidth ?? 1.75) + 0.35 : strokeWidth
809
+ strokeWidth: focused && !shouldAnimate ? (strokeWidth ?? 1.75) + 0.35 : focused ? (strokeWidth ?? 1.75) + 0.2 : strokeWidth
585
810
  }
586
811
  ),
587
812
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -626,6 +851,36 @@ var Textarea = react.forwardRef(
626
851
  );
627
852
  var BOX = 20;
628
853
  var CHECK_PATH = "M 4.5 10.5 L 8.5 14.5 L 15.5 5.5";
854
+ function CheckMark({
855
+ roughness,
856
+ seed,
857
+ bowing,
858
+ strokeWidth,
859
+ shouldAnimate
860
+ }) {
861
+ const ref = react.useRef(null);
862
+ useDrawIn(ref, DRAW_IN_MARK_MS, shouldAnimate);
863
+ return /* @__PURE__ */ jsxRuntime.jsx(
864
+ "span",
865
+ {
866
+ ref,
867
+ style: { position: "absolute", inset: 0, pointerEvents: "none" },
868
+ children: /* @__PURE__ */ jsxRuntime.jsx(
869
+ RoughSvg,
870
+ {
871
+ shape: "path",
872
+ path: CHECK_PATH,
873
+ roughness: (roughness ?? 1.5) * 0.7,
874
+ seed,
875
+ sketchColor: SKETCH_COLORS.accent,
876
+ bowing,
877
+ strokeWidth: (strokeWidth ?? 1.6) + 0.4,
878
+ inset: 0
879
+ }
880
+ )
881
+ }
882
+ );
883
+ }
629
884
  var Checkbox = react.forwardRef(
630
885
  function Checkbox2({
631
886
  className,
@@ -641,11 +896,15 @@ var Checkbox = react.forwardRef(
641
896
  defaultChecked,
642
897
  onCheckedChange,
643
898
  id,
899
+ animate,
644
900
  ...rest
645
901
  }, ref) {
646
902
  const ink = sketchColor ?? SKETCH_COLORS.ink;
647
903
  const generatedId = react.useId();
648
904
  const inputId = id ?? generatedId;
905
+ const boxRef = react.useRef(null);
906
+ const shouldAnimate = useAnimate(animate);
907
+ useDrawIn(boxRef, DRAW_IN_DURATION_MS, shouldAnimate);
649
908
  return /* @__PURE__ */ jsxRuntime.jsxs(
650
909
  "span",
651
910
  {
@@ -680,16 +939,23 @@ var Checkbox = react.forwardRef(
680
939
  ...rest,
681
940
  children: [
682
941
  /* @__PURE__ */ jsxRuntime.jsx(
683
- RoughSvg,
942
+ "span",
684
943
  {
685
- shape: "rectangle",
686
- roughness,
687
- seed,
688
- sketchColor: ink,
689
- bowing,
690
- fillStyle,
691
- strokeWidth: strokeWidth ?? 1.6,
692
- inset: 1.5
944
+ ref: boxRef,
945
+ style: { position: "absolute", inset: 0, pointerEvents: "none" },
946
+ children: /* @__PURE__ */ jsxRuntime.jsx(
947
+ RoughSvg,
948
+ {
949
+ shape: "rectangle",
950
+ roughness,
951
+ seed,
952
+ sketchColor: ink,
953
+ bowing,
954
+ fillStyle,
955
+ strokeWidth: strokeWidth ?? 1.6,
956
+ inset: 1.5
957
+ }
958
+ )
693
959
  }
694
960
  ),
695
961
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -701,16 +967,13 @@ var Checkbox = react.forwardRef(
701
967
  display: "block"
702
968
  },
703
969
  children: /* @__PURE__ */ jsxRuntime.jsx(
704
- RoughSvg,
970
+ CheckMark,
705
971
  {
706
- shape: "path",
707
- path: CHECK_PATH,
708
- roughness: (roughness ?? 1.5) * 0.7,
972
+ roughness,
709
973
  seed,
710
- sketchColor: SKETCH_COLORS.accent,
711
974
  bowing,
712
- strokeWidth: (strokeWidth ?? 1.6) + 0.4,
713
- inset: 0
975
+ strokeWidth,
976
+ shouldAnimate
714
977
  }
715
978
  )
716
979
  }
@@ -751,6 +1014,53 @@ var RadioGroup = react.forwardRef(
751
1014
  }
752
1015
  );
753
1016
  var SIZE = 20;
1017
+ function RadioDot({
1018
+ roughness,
1019
+ seed,
1020
+ bowing,
1021
+ shouldAnimate
1022
+ }) {
1023
+ const ref = react.useRef(null);
1024
+ useDrawIn(ref, DRAW_IN_MARK_MS, shouldAnimate);
1025
+ react.useLayoutEffect(() => {
1026
+ const node = ref.current;
1027
+ if (!node || !shouldAnimate) return;
1028
+ const animation = node.animate(
1029
+ [
1030
+ { transform: "scale(0.35)", opacity: 0 },
1031
+ { transform: "scale(1)", opacity: 1 }
1032
+ ],
1033
+ { duration: 180, easing: "ease-out", fill: "forwards" }
1034
+ );
1035
+ return () => animation.cancel();
1036
+ }, [shouldAnimate]);
1037
+ return /* @__PURE__ */ jsxRuntime.jsx(
1038
+ "span",
1039
+ {
1040
+ ref,
1041
+ style: {
1042
+ position: "absolute",
1043
+ inset: 0,
1044
+ pointerEvents: "none",
1045
+ display: "block"
1046
+ },
1047
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1048
+ RoughSvg,
1049
+ {
1050
+ shape: "ellipse",
1051
+ roughness: (roughness ?? 1.5) + 0.2,
1052
+ seed,
1053
+ sketchColor: SKETCH_COLORS.accent,
1054
+ fill: SKETCH_COLORS.accent,
1055
+ fillStyle: "solid",
1056
+ bowing,
1057
+ strokeWidth: 1,
1058
+ inset: 6
1059
+ }
1060
+ )
1061
+ }
1062
+ );
1063
+ }
754
1064
  var Radio = react.forwardRef(function Radio2({
755
1065
  className,
756
1066
  style,
@@ -762,11 +1072,15 @@ var Radio = react.forwardRef(function Radio2({
762
1072
  fillStyle,
763
1073
  strokeWidth,
764
1074
  id,
1075
+ animate,
765
1076
  ...rest
766
1077
  }, ref) {
767
1078
  const ink = sketchColor ?? SKETCH_COLORS.ink;
768
1079
  const generatedId = react.useId();
769
1080
  const inputId = id ?? generatedId;
1081
+ const ringRef = react.useRef(null);
1082
+ const shouldAnimate = useAnimate(animate);
1083
+ useDrawIn(ringRef, DRAW_IN_DURATION_MS, shouldAnimate);
770
1084
  return /* @__PURE__ */ jsxRuntime.jsxs(
771
1085
  "span",
772
1086
  {
@@ -799,16 +1113,23 @@ var Radio = react.forwardRef(function Radio2({
799
1113
  ...rest,
800
1114
  children: [
801
1115
  /* @__PURE__ */ jsxRuntime.jsx(
802
- RoughSvg,
1116
+ "span",
803
1117
  {
804
- shape: "ellipse",
805
- roughness,
806
- seed,
807
- sketchColor: ink,
808
- bowing,
809
- fillStyle,
810
- strokeWidth: strokeWidth ?? 1.6,
811
- inset: 1.5
1118
+ ref: ringRef,
1119
+ style: { position: "absolute", inset: 0, pointerEvents: "none" },
1120
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1121
+ RoughSvg,
1122
+ {
1123
+ shape: "ellipse",
1124
+ roughness,
1125
+ seed,
1126
+ sketchColor: ink,
1127
+ bowing,
1128
+ fillStyle,
1129
+ strokeWidth: strokeWidth ?? 1.6,
1130
+ inset: 1.5
1131
+ }
1132
+ )
812
1133
  }
813
1134
  ),
814
1135
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -820,17 +1141,12 @@ var Radio = react.forwardRef(function Radio2({
820
1141
  display: "block"
821
1142
  },
822
1143
  children: /* @__PURE__ */ jsxRuntime.jsx(
823
- RoughSvg,
1144
+ RadioDot,
824
1145
  {
825
- shape: "ellipse",
826
- roughness: (roughness ?? 1.5) + 0.2,
1146
+ roughness,
827
1147
  seed,
828
- sketchColor: SKETCH_COLORS.accent,
829
- fill: SKETCH_COLORS.accent,
830
- fillStyle: "solid",
831
1148
  bowing,
832
- strokeWidth: 1,
833
- inset: 6
1149
+ shouldAnimate
834
1150
  }
835
1151
  )
836
1152
  }
@@ -864,6 +1180,7 @@ var Card = react.forwardRef(function Card2({
864
1180
  bowing,
865
1181
  fillStyle,
866
1182
  strokeWidth,
1183
+ animate,
867
1184
  ...rest
868
1185
  }, ref) {
869
1186
  const boxProps = {
@@ -874,7 +1191,8 @@ var Card = react.forwardRef(function Card2({
874
1191
  sketchColor: sketchColor ?? SKETCH_COLORS.ink,
875
1192
  bowing,
876
1193
  fillStyle,
877
- strokeWidth
1194
+ strokeWidth,
1195
+ animate
878
1196
  };
879
1197
  return /* @__PURE__ */ jsxRuntime.jsxs(
880
1198
  SketchBox,
@@ -914,6 +1232,7 @@ var Badge = react.forwardRef(function Badge2({
914
1232
  bowing,
915
1233
  fillStyle,
916
1234
  strokeWidth,
1235
+ animate,
917
1236
  ...rest
918
1237
  }, ref) {
919
1238
  const ink = variant === "accent" ? sketchColor ?? SKETCH_COLORS.accent : sketchColor ?? SKETCH_COLORS.ink;
@@ -941,6 +1260,7 @@ var Badge = react.forwardRef(function Badge2({
941
1260
  sketchColor: ink,
942
1261
  bowing,
943
1262
  strokeWidth: strokeWidth ?? 1.4,
1263
+ animate,
944
1264
  ...rest,
945
1265
  children: /* @__PURE__ */ jsxRuntime.jsx("span", { ref, children })
946
1266
  }
@@ -971,6 +1291,7 @@ var Alert = react.forwardRef(function Alert2({
971
1291
  fillStyle,
972
1292
  strokeWidth,
973
1293
  role = "status",
1294
+ animate,
974
1295
  ...rest
975
1296
  }, ref) {
976
1297
  const color = sketchColor ?? VARIANT_COLOR[variant];
@@ -989,6 +1310,8 @@ var Alert = react.forwardRef(function Alert2({
989
1310
  fillStyle: fillStyle ?? "hachure",
990
1311
  fill: VARIANT_FILL[variant],
991
1312
  strokeWidth,
1313
+ animate,
1314
+ drawInDuration: DRAW_IN_ALERT_MS,
992
1315
  ...rest,
993
1316
  children: [
994
1317
  title ? /* @__PURE__ */ jsxRuntime.jsx(
@@ -1021,15 +1344,27 @@ function Modal({
1021
1344
  sketchColor,
1022
1345
  bowing,
1023
1346
  fillStyle,
1024
- strokeWidth
1347
+ strokeWidth,
1348
+ animate
1025
1349
  }) {
1026
1350
  const ink = sketchColor ?? SKETCH_COLORS.ink;
1027
- return /* @__PURE__ */ jsxRuntime.jsxs(Dialog__namespace.Root, { open, defaultOpen, onOpenChange, children: [
1351
+ const [uncontrolled, setUncontrolled] = react.useState(defaultOpen === true);
1352
+ const isOpen = open ?? uncontrolled;
1353
+ const shouldAnimate = useAnimate(animate);
1354
+ function handleOpenChange(next) {
1355
+ setUncontrolled(next);
1356
+ onOpenChange?.(next);
1357
+ }
1358
+ return /* @__PURE__ */ jsxRuntime.jsxs(Dialog__namespace.Root, { open: isOpen, onOpenChange: handleOpenChange, children: [
1028
1359
  trigger ? /* @__PURE__ */ jsxRuntime.jsx(Dialog__namespace.Trigger, { asChild: true, children: trigger }) : null,
1029
- /* @__PURE__ */ jsxRuntime.jsxs(Dialog__namespace.Portal, { children: [
1030
- /* @__PURE__ */ jsxRuntime.jsx(
1031
- Dialog__namespace.Overlay,
1360
+ /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: isOpen ? /* @__PURE__ */ jsxRuntime.jsxs(Dialog__namespace.Portal, { forceMount: true, children: [
1361
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog__namespace.Overlay, { asChild: true, forceMount: true, children: /* @__PURE__ */ jsxRuntime.jsx(
1362
+ framerMotion.motion.div,
1032
1363
  {
1364
+ initial: shouldAnimate ? { opacity: 0 } : false,
1365
+ animate: { opacity: 1 },
1366
+ exit: shouldAnimate ? { opacity: 0 } : void 0,
1367
+ transition: shouldAnimate ? { duration: 0.2, ease: "easeOut" } : { duration: 0 },
1033
1368
  style: {
1034
1369
  position: "fixed",
1035
1370
  inset: 0,
@@ -1037,92 +1372,121 @@ function Modal({
1037
1372
  zIndex: 70
1038
1373
  }
1039
1374
  }
1040
- ),
1375
+ ) }),
1041
1376
  /* @__PURE__ */ jsxRuntime.jsx(
1042
- Dialog__namespace.Content,
1377
+ "div",
1043
1378
  {
1044
- className: cn(className),
1045
1379
  style: {
1046
1380
  position: "fixed",
1047
- left: "50%",
1048
- top: "50%",
1049
- transform: "translate(-50%, -50%)",
1381
+ inset: 0,
1050
1382
  zIndex: 80,
1051
- width: "min(480px, calc(100vw - 32px))",
1052
- outline: "none"
1383
+ display: "flex",
1384
+ alignItems: "center",
1385
+ justifyContent: "center",
1386
+ pointerEvents: "none",
1387
+ padding: 16
1053
1388
  },
1054
- children: /* @__PURE__ */ jsxRuntime.jsxs(
1055
- SketchBox,
1389
+ children: /* @__PURE__ */ jsxRuntime.jsx(Dialog__namespace.Content, { asChild: true, forceMount: true, children: /* @__PURE__ */ jsxRuntime.jsx(
1390
+ framerMotion.motion.div,
1056
1391
  {
1057
- roughness,
1058
- seed,
1059
- sketchColor: ink,
1060
- bowing,
1061
- fillStyle: fillStyle ?? "solid",
1062
- fill: "#f7f6f2",
1063
- strokeWidth: strokeWidth ?? 2,
1064
- shadow: true,
1065
- contentStyle: { padding: "20px 22px 18px" },
1066
- children: [
1067
- /* @__PURE__ */ jsxRuntime.jsxs(
1068
- "div",
1069
- {
1070
- style: {
1071
- display: "flex",
1072
- alignItems: "flex-start",
1073
- justifyContent: "space-between",
1074
- gap: 12,
1075
- marginBottom: title ? 10 : 0
1076
- },
1077
- children: [
1078
- title ? /* @__PURE__ */ jsxRuntime.jsx(
1079
- Dialog__namespace.Title,
1080
- {
1081
- style: {
1082
- margin: 0,
1083
- fontSize: 18,
1084
- fontWeight: doodleUiFontWeight(700),
1085
- fontFamily: doodleUiFontFamily,
1086
- color: ink
1087
- },
1088
- children: title
1089
- }
1090
- ) : /* @__PURE__ */ jsxRuntime.jsx(Dialog__namespace.Title, { style: { position: "absolute", width: 1, height: 1, overflow: "hidden", clip: "rect(0 0 0 0)" }, children: "Dialog" }),
1091
- /* @__PURE__ */ jsxRuntime.jsx(Dialog__namespace.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
1092
- Button,
1093
- {
1094
- variant: "ghost",
1095
- size: "sm",
1096
- roughness,
1097
- seed,
1098
- sketchColor: ink,
1099
- "aria-label": "Close",
1100
- children: "Close"
1101
- }
1102
- ) })
1103
- ]
1104
- }
1105
- ),
1106
- description ? /* @__PURE__ */ jsxRuntime.jsx(
1107
- Dialog__namespace.Description,
1108
- {
1109
- style: {
1110
- margin: "0 0 14px",
1111
- fontSize: 14,
1112
- lineHeight: 1.5,
1113
- color: ink,
1114
- opacity: 0.8
1115
- },
1116
- children: description
1117
- }
1118
- ) : null,
1119
- /* @__PURE__ */ jsxRuntime.jsx("div", { children })
1120
- ]
1392
+ className: cn(className),
1393
+ initial: shouldAnimate ? { opacity: 0, scale: 0.96, y: 10 } : false,
1394
+ animate: { opacity: 1, scale: 1, y: 0 },
1395
+ exit: shouldAnimate ? { opacity: 0, scale: 0.96, y: 8 } : void 0,
1396
+ transition: shouldAnimate ? { duration: 0.22, ease: "easeOut" } : { duration: 0 },
1397
+ style: {
1398
+ width: "min(480px, calc(100vw - 32px))",
1399
+ outline: "none",
1400
+ pointerEvents: "auto"
1401
+ },
1402
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
1403
+ SketchBox,
1404
+ {
1405
+ roughness,
1406
+ seed,
1407
+ sketchColor: ink,
1408
+ bowing,
1409
+ fillStyle: fillStyle ?? "solid",
1410
+ fill: "#f7f6f2",
1411
+ strokeWidth: strokeWidth ?? 2,
1412
+ shadow: true,
1413
+ animate,
1414
+ contentStyle: { padding: "20px 22px 18px" },
1415
+ children: [
1416
+ /* @__PURE__ */ jsxRuntime.jsxs(
1417
+ "div",
1418
+ {
1419
+ style: {
1420
+ display: "flex",
1421
+ alignItems: "flex-start",
1422
+ justifyContent: "space-between",
1423
+ gap: 12,
1424
+ marginBottom: title ? 10 : 0
1425
+ },
1426
+ children: [
1427
+ title ? /* @__PURE__ */ jsxRuntime.jsx(
1428
+ Dialog__namespace.Title,
1429
+ {
1430
+ style: {
1431
+ margin: 0,
1432
+ fontSize: 18,
1433
+ fontWeight: doodleUiFontWeight(700),
1434
+ fontFamily: doodleUiFontFamily,
1435
+ color: ink
1436
+ },
1437
+ children: title
1438
+ }
1439
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
1440
+ Dialog__namespace.Title,
1441
+ {
1442
+ style: {
1443
+ position: "absolute",
1444
+ width: 1,
1445
+ height: 1,
1446
+ overflow: "hidden",
1447
+ clip: "rect(0 0 0 0)"
1448
+ },
1449
+ children: "Dialog"
1450
+ }
1451
+ ),
1452
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog__namespace.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
1453
+ Button,
1454
+ {
1455
+ variant: "ghost",
1456
+ size: "sm",
1457
+ roughness,
1458
+ seed,
1459
+ sketchColor: ink,
1460
+ animate,
1461
+ "aria-label": "Close",
1462
+ children: "Close"
1463
+ }
1464
+ ) })
1465
+ ]
1466
+ }
1467
+ ),
1468
+ description ? /* @__PURE__ */ jsxRuntime.jsx(
1469
+ Dialog__namespace.Description,
1470
+ {
1471
+ style: {
1472
+ margin: "0 0 14px",
1473
+ fontSize: 14,
1474
+ lineHeight: 1.5,
1475
+ color: ink,
1476
+ opacity: 0.8
1477
+ },
1478
+ children: description
1479
+ }
1480
+ ) : null,
1481
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children })
1482
+ ]
1483
+ }
1484
+ )
1121
1485
  }
1122
- )
1486
+ ) })
1123
1487
  }
1124
1488
  )
1125
- ] })
1489
+ ] }) : null })
1126
1490
  ] });
1127
1491
  }
1128
1492
  var ModalRoot = Dialog__namespace.Root;
@@ -1140,13 +1504,20 @@ var Divider = react.forwardRef(
1140
1504
  sketchColor,
1141
1505
  bowing,
1142
1506
  strokeWidth,
1507
+ animate,
1143
1508
  ...rest
1144
1509
  }, ref) {
1510
+ const rootRef = react.useRef(null);
1511
+ const shouldAnimate = useAnimate(animate);
1145
1512
  const horizontal = orientation === "horizontal";
1513
+ useDrawIn(rootRef, DRAW_IN_DURATION_MS, shouldAnimate);
1146
1514
  return /* @__PURE__ */ jsxRuntime.jsx(
1147
1515
  "div",
1148
1516
  {
1149
- ref,
1517
+ ref: (node) => {
1518
+ rootRef.current = node;
1519
+ assignRef(ref, node);
1520
+ },
1150
1521
  role: "separator",
1151
1522
  "aria-orientation": orientation,
1152
1523
  className: cn(className),
@@ -1186,15 +1557,27 @@ var Progress = react.forwardRef(
1186
1557
  bowing,
1187
1558
  fillStyle,
1188
1559
  strokeWidth,
1560
+ animate,
1189
1561
  ...rest
1190
1562
  }, ref) {
1563
+ const rootRef = react.useRef(null);
1564
+ const trackRef = react.useRef(null);
1191
1565
  const ink = sketchColor ?? SKETCH_COLORS.accent;
1192
1566
  const clamped = Math.min(max, Math.max(0, value));
1193
1567
  const percent = max === 0 ? 0 : clamped / max * 100;
1568
+ const shouldAnimate = useAnimate(animate);
1569
+ const displayed = useTweenNumber(percent, shouldAnimate, 420);
1570
+ const resolvedSeed = useResolvedSeed(seed);
1571
+ const fillSeed = shouldAnimate ? deriveSeed(resolvedSeed, `fill-${Math.round(displayed / 6)}`) : resolvedSeed;
1572
+ const fillRoughness = (roughness ?? 1.5) + 0.4 + displayed / 100 * 0.7;
1573
+ useDrawIn(trackRef, DRAW_IN_DURATION_MS, shouldAnimate);
1194
1574
  return /* @__PURE__ */ jsxRuntime.jsxs(
1195
1575
  "div",
1196
1576
  {
1197
- ref,
1577
+ ref: (node) => {
1578
+ rootRef.current = node;
1579
+ assignRef(ref, node);
1580
+ },
1198
1581
  role: "progressbar",
1199
1582
  "aria-valuemin": 0,
1200
1583
  "aria-valuemax": max,
@@ -1209,18 +1592,25 @@ var Progress = react.forwardRef(
1209
1592
  ...rest,
1210
1593
  children: [
1211
1594
  /* @__PURE__ */ jsxRuntime.jsx(
1212
- RoughSvg,
1595
+ "span",
1213
1596
  {
1214
- shape: "rectangle",
1215
- roughness,
1216
- seed,
1217
- sketchColor: SKETCH_COLORS.ink,
1218
- bowing,
1219
- strokeWidth: strokeWidth ?? 1.5,
1220
- inset: 2
1597
+ ref: trackRef,
1598
+ style: { position: "absolute", inset: 0, pointerEvents: "none" },
1599
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1600
+ RoughSvg,
1601
+ {
1602
+ shape: "rectangle",
1603
+ roughness,
1604
+ seed: resolvedSeed,
1605
+ sketchColor: SKETCH_COLORS.ink,
1606
+ bowing,
1607
+ strokeWidth: strokeWidth ?? 1.5,
1608
+ inset: 2
1609
+ }
1610
+ )
1221
1611
  }
1222
1612
  ),
1223
- percent > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
1613
+ displayed > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
1224
1614
  "div",
1225
1615
  {
1226
1616
  style: {
@@ -1228,16 +1618,16 @@ var Progress = react.forwardRef(
1228
1618
  left: 5,
1229
1619
  top: 4,
1230
1620
  bottom: 4,
1231
- width: `calc(${percent}% - 10px)`,
1232
- minWidth: percent > 0 ? 8 : 0,
1621
+ width: `calc(${displayed}% - 10px)`,
1622
+ minWidth: displayed > 0 ? 8 : 0,
1233
1623
  overflow: "hidden"
1234
1624
  },
1235
1625
  children: /* @__PURE__ */ jsxRuntime.jsx(
1236
1626
  RoughSvg,
1237
1627
  {
1238
1628
  shape: "rectangle",
1239
- roughness: (roughness ?? 1.5) + 0.55,
1240
- seed,
1629
+ roughness: fillRoughness,
1630
+ seed: fillSeed,
1241
1631
  sketchColor: ink,
1242
1632
  fill: ink,
1243
1633
  fillStyle: fillStyle ?? "hachure",
@@ -1265,7 +1655,8 @@ function Tooltip({
1265
1655
  sketchColor,
1266
1656
  bowing,
1267
1657
  fillStyle,
1268
- strokeWidth
1658
+ strokeWidth,
1659
+ animate
1269
1660
  }) {
1270
1661
  const ink = sketchColor ?? SKETCH_COLORS.ink;
1271
1662
  return /* @__PURE__ */ jsxRuntime.jsxs(TooltipPrimitive__namespace.Root, { delayDuration, children: [
@@ -1287,6 +1678,8 @@ function Tooltip({
1287
1678
  fillStyle: fillStyle ?? "solid",
1288
1679
  fill: "#f7f6f2",
1289
1680
  strokeWidth: strokeWidth ?? 1.4,
1681
+ animate,
1682
+ drawInDuration: DRAW_IN_TOOLTIP_MS,
1290
1683
  contentStyle: {
1291
1684
  padding: "6px 10px",
1292
1685
  fontSize: 13,
@@ -1328,6 +1721,7 @@ function Select({
1328
1721
  value,
1329
1722
  defaultValue,
1330
1723
  onValueChange,
1724
+ animate,
1331
1725
  "aria-label": ariaLabel,
1332
1726
  ...rest
1333
1727
  }) {
@@ -1350,7 +1744,8 @@ function Select({
1350
1744
  ink,
1351
1745
  selectedValue,
1352
1746
  selectedLabel,
1353
- placeholder
1747
+ placeholder,
1748
+ animate
1354
1749
  },
1355
1750
  children: /* @__PURE__ */ jsxRuntime.jsxs(
1356
1751
  SelectPrimitive__namespace.Root,
@@ -1391,10 +1786,16 @@ var SelectTrigger = react.forwardRef(
1391
1786
  function SelectTrigger2({ className, style, placeholder, children, ...rest }, ref) {
1392
1787
  const sketch = useSelectSketch();
1393
1788
  const [openish, setOpenish] = react.useState(false);
1789
+ const rootRef = react.useRef(null);
1790
+ const shouldAnimate = useAnimate(sketch.animate);
1791
+ useDrawIn(rootRef, DRAW_IN_DURATION_MS, shouldAnimate);
1394
1792
  return /* @__PURE__ */ jsxRuntime.jsxs(
1395
1793
  SelectPrimitive__namespace.Trigger,
1396
1794
  {
1397
- ref,
1795
+ ref: (node) => {
1796
+ rootRef.current = node;
1797
+ assignRef(ref, node);
1798
+ },
1398
1799
  className: cn(className),
1399
1800
  onPointerDown: () => setOpenish(true),
1400
1801
  onBlur: () => setOpenish(false),
@@ -1503,6 +1904,7 @@ var SelectContent = react.forwardRef(
1503
1904
  fillStyle: sketch.fillStyle ?? "solid",
1504
1905
  fill: "#f7f6f2",
1505
1906
  strokeWidth: sketch.strokeWidth ?? 1.5,
1907
+ animate: sketch.animate,
1506
1908
  contentStyle: { padding: "6px 4px" },
1507
1909
  children: /* @__PURE__ */ jsxRuntime.jsx(SelectPrimitive__namespace.Viewport, { children })
1508
1910
  }
@@ -1593,12 +1995,17 @@ var Switch = react.forwardRef(
1593
1995
  defaultChecked,
1594
1996
  onCheckedChange,
1595
1997
  id,
1998
+ animate,
1596
1999
  ...rest
1597
2000
  }, ref) {
1598
2001
  const [uncontrolled, setUncontrolled] = react.useState(defaultChecked === true);
1599
2002
  const isOn = checked ?? uncontrolled;
1600
2003
  const ink = sketchColor ?? SKETCH_COLORS.ink;
1601
2004
  const resolvedSeed = useResolvedSeed(seed);
2005
+ const shouldAnimate = useAnimate(animate);
2006
+ const trackRef = react.useRef(null);
2007
+ const trackSeed = shouldAnimate ? deriveSeed(resolvedSeed, isOn ? "on" : "off") : resolvedSeed;
2008
+ useDrawIn(trackRef, DRAW_IN_DURATION_MS, shouldAnimate, trackSeed);
1602
2009
  return /* @__PURE__ */ jsxRuntime.jsxs(
1603
2010
  "span",
1604
2011
  {
@@ -1637,22 +2044,32 @@ var Switch = react.forwardRef(
1637
2044
  ...rest,
1638
2045
  children: [
1639
2046
  /* @__PURE__ */ jsxRuntime.jsx(
1640
- RoughSvg,
2047
+ "span",
1641
2048
  {
1642
- shape: "rectangle",
1643
- roughness,
1644
- seed: resolvedSeed,
1645
- sketchColor: isOn ? SKETCH_COLORS.accent : ink,
1646
- bowing: bowing ?? 1.4,
1647
- fillStyle: fillStyle ?? (isOn ? "hachure" : void 0),
1648
- fill: isOn ? SKETCH_COLORS.accentFill : void 0,
1649
- strokeWidth: strokeWidth ?? 1.6,
1650
- inset: 1.5
2049
+ ref: trackRef,
2050
+ style: { position: "absolute", inset: 0, pointerEvents: "none" },
2051
+ children: /* @__PURE__ */ jsxRuntime.jsx(
2052
+ RoughSvg,
2053
+ {
2054
+ shape: "rectangle",
2055
+ roughness,
2056
+ seed: trackSeed,
2057
+ sketchColor: isOn ? SKETCH_COLORS.accent : ink,
2058
+ bowing: bowing ?? 1.4,
2059
+ fillStyle: fillStyle ?? (isOn ? "hachure" : void 0),
2060
+ fill: isOn ? SKETCH_COLORS.accentFill : void 0,
2061
+ strokeWidth: strokeWidth ?? 1.6,
2062
+ inset: 1.5
2063
+ }
2064
+ )
1651
2065
  }
1652
2066
  ),
1653
- /* @__PURE__ */ jsxRuntime.jsx(
1654
- SwitchPrimitive__namespace.Thumb,
2067
+ /* @__PURE__ */ jsxRuntime.jsx(SwitchPrimitive__namespace.Thumb, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
2068
+ framerMotion.motion.span,
1655
2069
  {
2070
+ initial: false,
2071
+ animate: { x: isOn ? THUMB_ON : THUMB_OFF },
2072
+ transition: shouldAnimate ? { type: "spring", stiffness: 420, damping: 30 } : { duration: 0 },
1656
2073
  style: {
1657
2074
  position: "absolute",
1658
2075
  top: (TRACK_H - THUMB) / 2,
@@ -1660,8 +2077,6 @@ var Switch = react.forwardRef(
1660
2077
  width: THUMB,
1661
2078
  height: THUMB,
1662
2079
  display: "block",
1663
- transform: `translateX(${isOn ? THUMB_ON : THUMB_OFF}px)`,
1664
- transition: "transform 160ms ease",
1665
2080
  zIndex: 1
1666
2081
  },
1667
2082
  children: /* @__PURE__ */ jsxRuntime.jsx(
@@ -1679,7 +2094,7 @@ var Switch = react.forwardRef(
1679
2094
  }
1680
2095
  )
1681
2096
  }
1682
- )
2097
+ ) })
1683
2098
  ]
1684
2099
  }
1685
2100
  ),
@@ -1721,12 +2136,14 @@ var Tabs = react.forwardRef(function Tabs2({
1721
2136
  bowing,
1722
2137
  fillStyle,
1723
2138
  strokeWidth,
2139
+ animate,
1724
2140
  ...rest
1725
2141
  }, ref) {
1726
2142
  const [uncontrolled, setUncontrolled] = react.useState(defaultValue);
1727
2143
  const current = value ?? uncontrolled;
1728
2144
  const resolvedSeed = useResolvedSeed(seed);
1729
2145
  const ink = sketchColor ?? SKETCH_COLORS.ink;
2146
+ const shouldAnimate = useAnimate(animate);
1730
2147
  return /* @__PURE__ */ jsxRuntime.jsx(
1731
2148
  TabsSketchContext.Provider,
1732
2149
  {
@@ -1739,7 +2156,8 @@ var Tabs = react.forwardRef(function Tabs2({
1739
2156
  strokeWidth,
1740
2157
  resolvedSeed,
1741
2158
  ink,
1742
- current
2159
+ current,
2160
+ shouldAnimate
1743
2161
  },
1744
2162
  children: /* @__PURE__ */ jsxRuntime.jsx(
1745
2163
  TabsPrimitive__namespace.Root,
@@ -1760,29 +2178,102 @@ var Tabs = react.forwardRef(function Tabs2({
1760
2178
  }
1761
2179
  );
1762
2180
  });
2181
+ function TabUnderline({
2182
+ box,
2183
+ seed,
2184
+ sketch
2185
+ }) {
2186
+ const ref = react.useRef(null);
2187
+ useDrawIn(ref, DRAW_IN_MARK_MS, sketch.shouldAnimate, seed);
2188
+ return /* @__PURE__ */ jsxRuntime.jsx(
2189
+ "span",
2190
+ {
2191
+ ref,
2192
+ "aria-hidden": "true",
2193
+ style: {
2194
+ position: "absolute",
2195
+ left: box.left,
2196
+ top: box.top,
2197
+ width: box.width,
2198
+ height: 10,
2199
+ pointerEvents: "none",
2200
+ transition: sketch.shouldAnimate ? "left 220ms ease, width 220ms ease, top 220ms ease" : void 0
2201
+ },
2202
+ children: /* @__PURE__ */ jsxRuntime.jsx(
2203
+ RoughSvg,
2204
+ {
2205
+ shape: "line",
2206
+ roughness: (sketch.roughness ?? 1.5) + 0.35,
2207
+ seed,
2208
+ sketchColor: SKETCH_COLORS.accent,
2209
+ bowing: sketch.bowing ?? 1.8,
2210
+ strokeWidth: (sketch.strokeWidth ?? 1.75) + 0.4,
2211
+ inset: 2
2212
+ }
2213
+ )
2214
+ }
2215
+ );
2216
+ }
1763
2217
  var TabList = react.forwardRef(
1764
2218
  function TabList2({ className, style, children, ...rest }, ref) {
1765
- return /* @__PURE__ */ jsxRuntime.jsx(
2219
+ const sketch = useTabsSketch();
2220
+ const listRef = react.useRef(null);
2221
+ const [underline, setUnderline] = react.useState(null);
2222
+ react.useLayoutEffect(() => {
2223
+ const list = listRef.current;
2224
+ if (!list) return;
2225
+ const measure = () => {
2226
+ const active = list.querySelector('[data-state="active"]');
2227
+ if (!active) {
2228
+ setUnderline(null);
2229
+ return;
2230
+ }
2231
+ setUnderline({
2232
+ left: active.offsetLeft + 8,
2233
+ top: active.offsetTop + active.offsetHeight - 10,
2234
+ width: Math.max(12, active.offsetWidth - 16)
2235
+ });
2236
+ };
2237
+ measure();
2238
+ const observer = new ResizeObserver(measure);
2239
+ observer.observe(list);
2240
+ return () => observer.disconnect();
2241
+ }, [sketch.current, children]);
2242
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1766
2243
  TabsPrimitive__namespace.List,
1767
2244
  {
1768
- ref,
2245
+ ref: (node) => {
2246
+ listRef.current = node;
2247
+ assignRef(ref, node);
2248
+ },
1769
2249
  className: cn(className),
1770
2250
  style: {
1771
2251
  display: "flex",
1772
2252
  flexWrap: "wrap",
1773
2253
  gap: 4,
2254
+ position: "relative",
1774
2255
  ...style
1775
2256
  },
1776
2257
  ...rest,
1777
- children
1778
- }
1779
- );
2258
+ children: [
2259
+ children,
2260
+ underline && sketch.current ? /* @__PURE__ */ jsxRuntime.jsx(
2261
+ TabUnderline,
2262
+ {
2263
+ box: underline,
2264
+ seed: deriveSeed(sketch.resolvedSeed, sketch.current),
2265
+ sketch
2266
+ }
2267
+ ) : null
2268
+ ]
2269
+ }
2270
+ );
1780
2271
  }
1781
2272
  );
1782
2273
  var Tab = react.forwardRef(function Tab2({ className, style, children, value, ...rest }, ref) {
1783
2274
  const sketch = useTabsSketch();
1784
2275
  const active = sketch.current === value;
1785
- return /* @__PURE__ */ jsxRuntime.jsxs(
2276
+ return /* @__PURE__ */ jsxRuntime.jsx(
1786
2277
  TabsPrimitive__namespace.Trigger,
1787
2278
  {
1788
2279
  ref,
@@ -1802,34 +2293,7 @@ var Tab = react.forwardRef(function Tab2({ className, style, children, value, ..
1802
2293
  ...style
1803
2294
  },
1804
2295
  ...rest,
1805
- children: [
1806
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { position: "relative", zIndex: 1 }, children }),
1807
- active ? /* @__PURE__ */ jsxRuntime.jsx(
1808
- "span",
1809
- {
1810
- style: {
1811
- position: "absolute",
1812
- left: 8,
1813
- right: 8,
1814
- bottom: 2,
1815
- height: 10,
1816
- pointerEvents: "none"
1817
- },
1818
- children: /* @__PURE__ */ jsxRuntime.jsx(
1819
- RoughSvg,
1820
- {
1821
- shape: "line",
1822
- roughness: (sketch.roughness ?? 1.5) + 0.35,
1823
- seed: deriveSeed(sketch.resolvedSeed, value),
1824
- sketchColor: SKETCH_COLORS.accent,
1825
- bowing: sketch.bowing ?? 1.8,
1826
- strokeWidth: (sketch.strokeWidth ?? 1.75) + 0.4,
1827
- inset: 2
1828
- }
1829
- )
1830
- }
1831
- ) : null
1832
- ]
2296
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { style: { position: "relative", zIndex: 1 }, children })
1833
2297
  }
1834
2298
  );
1835
2299
  });
@@ -1864,6 +2328,46 @@ function useTableSketch() {
1864
2328
  }
1865
2329
  return ctx;
1866
2330
  }
2331
+ function TableRule({
2332
+ line,
2333
+ headerUnderline,
2334
+ roughness,
2335
+ resolvedSeed,
2336
+ ink,
2337
+ bowing,
2338
+ strokeWidth,
2339
+ shouldAnimate
2340
+ }) {
2341
+ const ref = react.useRef(null);
2342
+ const delay = shouldAnimate ? Math.min(line.index, 6) * TABLE_STAGGER_MS : 0;
2343
+ useDrawIn(ref, DRAW_IN_DURATION_MS, shouldAnimate, void 0, delay);
2344
+ if (line.header && !headerUnderline) return null;
2345
+ return /* @__PURE__ */ jsxRuntime.jsx(
2346
+ "div",
2347
+ {
2348
+ ref,
2349
+ style: {
2350
+ position: "absolute",
2351
+ left: 0,
2352
+ width: line.width,
2353
+ top: line.y - 6,
2354
+ height: 12
2355
+ },
2356
+ children: /* @__PURE__ */ jsxRuntime.jsx(
2357
+ RoughSvg,
2358
+ {
2359
+ shape: "line",
2360
+ roughness: line.header ? (roughness ?? 1.5) + 0.2 : roughness ?? 1.7,
2361
+ seed: deriveSeed(resolvedSeed, line.key),
2362
+ sketchColor: ink,
2363
+ bowing: bowing ?? (line.header ? 1.4 : 2),
2364
+ strokeWidth: line.header ? (strokeWidth ?? 1.75) + 0.35 : strokeWidth ?? 1.35,
2365
+ inset: 6
2366
+ }
2367
+ )
2368
+ }
2369
+ );
2370
+ }
1867
2371
  var Table = react.forwardRef(function Table2({
1868
2372
  className,
1869
2373
  style,
@@ -1875,6 +2379,7 @@ var Table = react.forwardRef(function Table2({
1875
2379
  bowing,
1876
2380
  fillStyle,
1877
2381
  strokeWidth,
2382
+ animate,
1878
2383
  ...rest
1879
2384
  }, ref) {
1880
2385
  const wrapperRef = react.useRef(null);
@@ -1882,6 +2387,7 @@ var Table = react.forwardRef(function Table2({
1882
2387
  const [lines, setLines] = react.useState([]);
1883
2388
  const resolvedSeed = useResolvedSeed(seed);
1884
2389
  const ink = sketchColor ?? SKETCH_COLORS.ink;
2390
+ const shouldAnimate = useAnimate(animate);
1885
2391
  react.useLayoutEffect(() => {
1886
2392
  const wrapper = wrapperRef.current;
1887
2393
  const table = tableRef.current;
@@ -1897,7 +2403,8 @@ var Table = react.forwardRef(function Table2({
1897
2403
  y: row.offsetTop + row.offsetHeight,
1898
2404
  width: table.offsetWidth,
1899
2405
  key: isHeader ? `header-${index}` : `row-${index}`,
1900
- header: Boolean(isHeader)
2406
+ header: Boolean(isHeader),
2407
+ index
1901
2408
  });
1902
2409
  });
1903
2410
  setLines(next);
@@ -1919,7 +2426,8 @@ var Table = react.forwardRef(function Table2({
1919
2426
  fillStyle,
1920
2427
  strokeWidth,
1921
2428
  resolvedSeed,
1922
- ink
2429
+ ink,
2430
+ shouldAnimate
1923
2431
  },
1924
2432
  children: /* @__PURE__ */ jsxRuntime.jsxs(
1925
2433
  "div",
@@ -1939,34 +2447,20 @@ var Table = react.forwardRef(function Table2({
1939
2447
  zIndex: 1,
1940
2448
  overflow: "visible"
1941
2449
  },
1942
- children: lines.map((line) => {
1943
- if (line.header && !headerUnderline) return null;
1944
- return /* @__PURE__ */ jsxRuntime.jsx(
1945
- "div",
1946
- {
1947
- style: {
1948
- position: "absolute",
1949
- left: 0,
1950
- width: line.width,
1951
- top: line.y - 6,
1952
- height: 12
1953
- },
1954
- children: /* @__PURE__ */ jsxRuntime.jsx(
1955
- RoughSvg,
1956
- {
1957
- shape: "line",
1958
- roughness: line.header ? (roughness ?? 1.5) + 0.2 : roughness ?? 1.7,
1959
- seed: deriveSeed(resolvedSeed, line.key),
1960
- sketchColor: ink,
1961
- bowing: bowing ?? (line.header ? 1.4 : 2),
1962
- strokeWidth: line.header ? (strokeWidth ?? 1.75) + 0.35 : strokeWidth ?? 1.35,
1963
- inset: 6
1964
- }
1965
- )
1966
- },
1967
- line.key
1968
- );
1969
- })
2450
+ children: lines.map((line) => /* @__PURE__ */ jsxRuntime.jsx(
2451
+ TableRule,
2452
+ {
2453
+ line,
2454
+ headerUnderline,
2455
+ roughness,
2456
+ resolvedSeed,
2457
+ ink,
2458
+ bowing,
2459
+ strokeWidth,
2460
+ shouldAnimate
2461
+ },
2462
+ line.key
2463
+ ))
1970
2464
  }
1971
2465
  ),
1972
2466
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -1974,8 +2468,7 @@ var Table = react.forwardRef(function Table2({
1974
2468
  {
1975
2469
  ref: (node) => {
1976
2470
  tableRef.current = node;
1977
- if (typeof ref === "function") ref(node);
1978
- else if (ref) ref.current = node;
2471
+ assignRef(ref, node);
1979
2472
  },
1980
2473
  style: {
1981
2474
  width: "100%",
@@ -2137,84 +2630,89 @@ function Toast({
2137
2630
  sketchColor,
2138
2631
  bowing,
2139
2632
  fillStyle,
2140
- strokeWidth
2633
+ strokeWidth,
2634
+ animate
2141
2635
  }) {
2142
2636
  const position = react.useContext(ToastPositionContext);
2143
2637
  const fromTop = position.startsWith("top");
2144
- const [entered, setEntered] = react.useState(false);
2638
+ const [uncontrolled, setUncontrolled] = react.useState(defaultOpen ?? false);
2639
+ const isOpen = open ?? uncontrolled;
2640
+ const shouldAnimate = useAnimate(animate);
2145
2641
  const color = sketchColor ?? VARIANT_COLOR2[variant];
2146
- const visible = open ?? true;
2147
- react.useLayoutEffect(() => {
2148
- if (!visible) {
2149
- setEntered(false);
2150
- return;
2151
- }
2152
- setEntered(false);
2153
- const frame = requestAnimationFrame(() => {
2154
- requestAnimationFrame(() => setEntered(true));
2155
- });
2156
- return () => cancelAnimationFrame(frame);
2157
- }, [visible]);
2158
- return /* @__PURE__ */ jsxRuntime.jsx(
2642
+ const offset = fromTop ? -14 : 14;
2643
+ function handleOpenChange(next) {
2644
+ setUncontrolled(next);
2645
+ onOpenChange?.(next);
2646
+ }
2647
+ return /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: isOpen ? /* @__PURE__ */ jsxRuntime.jsx(
2159
2648
  ToastPrimitive__namespace.Root,
2160
2649
  {
2161
- open,
2162
- defaultOpen,
2163
- onOpenChange,
2650
+ open: isOpen,
2651
+ onOpenChange: handleOpenChange,
2164
2652
  duration,
2165
- className: cn(className),
2166
- style: {
2167
- transform: entered ? "translateY(0)" : `translateY(${fromTop ? "-10px" : "10px"})`,
2168
- opacity: entered ? 1 : 0,
2169
- transition: "transform 200ms ease, opacity 200ms ease",
2170
- outline: "none",
2171
- ...style
2172
- },
2173
- children: /* @__PURE__ */ jsxRuntime.jsxs(
2174
- SketchBox,
2653
+ forceMount: true,
2654
+ asChild: true,
2655
+ children: /* @__PURE__ */ jsxRuntime.jsx(
2656
+ framerMotion.motion.li,
2175
2657
  {
2176
- roughness,
2177
- seed,
2178
- sketchColor: color,
2179
- bowing,
2180
- fillStyle: fillStyle ?? "hachure",
2181
- fill: VARIANT_FILL2[variant],
2182
- strokeWidth: strokeWidth ?? 1.7,
2183
- shadow: true,
2184
- contentStyle: { padding: "12px 16px" },
2185
- children: [
2186
- title ? /* @__PURE__ */ jsxRuntime.jsx(
2187
- ToastPrimitive__namespace.Title,
2188
- {
2189
- style: {
2190
- margin: 0,
2191
- fontWeight: doodleUiFontWeight(700),
2192
- fontSize: 15,
2193
- fontFamily: doodleUiFontFamily,
2194
- color,
2195
- marginBottom: children ? 4 : 0
2196
- },
2197
- children: title
2198
- }
2199
- ) : null,
2200
- children ? /* @__PURE__ */ jsxRuntime.jsx(
2201
- ToastPrimitive__namespace.Description,
2202
- {
2203
- style: {
2204
- margin: 0,
2205
- fontSize: 14,
2206
- lineHeight: 1.5,
2207
- fontFamily: doodleUiFontFamily,
2208
- color: SKETCH_COLORS.ink
2209
- },
2210
- children
2211
- }
2212
- ) : null
2213
- ]
2658
+ className: cn(className),
2659
+ initial: shouldAnimate ? { y: offset, opacity: 0, rotate: -1.4 } : false,
2660
+ animate: shouldAnimate ? { y: 0, opacity: 1, rotate: [-1.2, 0.9, -0.35, 0] } : { y: 0, opacity: 1, rotate: 0 },
2661
+ exit: shouldAnimate ? { y: offset, opacity: 0, rotate: 1.2 } : { opacity: 0 },
2662
+ transition: shouldAnimate ? { duration: 0.38, ease: "easeOut" } : { duration: 0 },
2663
+ style: {
2664
+ listStyle: "none",
2665
+ outline: "none",
2666
+ ...style
2667
+ },
2668
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
2669
+ SketchBox,
2670
+ {
2671
+ roughness,
2672
+ seed,
2673
+ sketchColor: color,
2674
+ bowing,
2675
+ fillStyle: fillStyle ?? "hachure",
2676
+ fill: VARIANT_FILL2[variant],
2677
+ strokeWidth: strokeWidth ?? 1.7,
2678
+ shadow: true,
2679
+ animate,
2680
+ contentStyle: { padding: "12px 16px" },
2681
+ children: [
2682
+ title ? /* @__PURE__ */ jsxRuntime.jsx(
2683
+ ToastPrimitive__namespace.Title,
2684
+ {
2685
+ style: {
2686
+ margin: 0,
2687
+ fontWeight: doodleUiFontWeight(700),
2688
+ fontSize: 15,
2689
+ fontFamily: doodleUiFontFamily,
2690
+ color,
2691
+ marginBottom: children ? 4 : 0
2692
+ },
2693
+ children: title
2694
+ }
2695
+ ) : null,
2696
+ children ? /* @__PURE__ */ jsxRuntime.jsx(
2697
+ ToastPrimitive__namespace.Description,
2698
+ {
2699
+ style: {
2700
+ margin: 0,
2701
+ fontSize: 14,
2702
+ lineHeight: 1.5,
2703
+ fontFamily: doodleUiFontFamily,
2704
+ color: SKETCH_COLORS.ink
2705
+ },
2706
+ children
2707
+ }
2708
+ ) : null
2709
+ ]
2710
+ }
2711
+ )
2214
2712
  }
2215
2713
  )
2216
2714
  }
2217
- );
2715
+ ) : null });
2218
2716
  }
2219
2717
  var ToastRoot = ToastPrimitive__namespace.Root;
2220
2718
  var ToastTitle = ToastPrimitive__namespace.Title;
@@ -3245,12 +3743,1495 @@ var Stepper = react.forwardRef(
3245
3743
  );
3246
3744
  }
3247
3745
  );
3746
+ var Label2 = react.forwardRef(function Label3({
3747
+ className,
3748
+ style,
3749
+ children,
3750
+ required,
3751
+ roughness,
3752
+ seed,
3753
+ sketchColor,
3754
+ bowing,
3755
+ strokeWidth,
3756
+ animate,
3757
+ ...rest
3758
+ }, ref) {
3759
+ const ink = sketchColor ?? SKETCH_COLORS.ink;
3760
+ const resolvedSeed = useResolvedSeed(seed);
3761
+ const shouldAnimate = useAnimate(animate);
3762
+ const markRef = react.useRef(null);
3763
+ useDrawIn(markRef, DRAW_IN_MARK_MS, shouldAnimate);
3764
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3765
+ LabelPrimitive__namespace.Root,
3766
+ {
3767
+ ref,
3768
+ className: cn(className),
3769
+ style: {
3770
+ display: "inline-flex",
3771
+ alignItems: "center",
3772
+ gap: 4,
3773
+ fontFamily: doodleUiFontFamily,
3774
+ fontSize: 13,
3775
+ fontWeight: doodleUiFontWeight(600),
3776
+ color: ink,
3777
+ cursor: "default",
3778
+ ...style
3779
+ },
3780
+ ...rest,
3781
+ children: [
3782
+ children,
3783
+ required ? /* @__PURE__ */ jsxRuntime.jsx(
3784
+ "span",
3785
+ {
3786
+ ref: markRef,
3787
+ "aria-hidden": "true",
3788
+ style: { position: "relative", width: 10, height: 10, flexShrink: 0 },
3789
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3790
+ RoughSvg,
3791
+ {
3792
+ shape: "ellipse",
3793
+ roughness: (roughness ?? 1.5) * 0.9,
3794
+ seed: resolvedSeed,
3795
+ sketchColor: SKETCH_COLORS.accent,
3796
+ bowing,
3797
+ fillStyle: "solid",
3798
+ fill: SKETCH_COLORS.accent,
3799
+ strokeWidth: strokeWidth ?? 1.2,
3800
+ inset: 1
3801
+ }
3802
+ )
3803
+ }
3804
+ ) : null
3805
+ ]
3806
+ }
3807
+ );
3808
+ });
3809
+ var CHEVRON_PATH4 = "M 6 4 L 12 10 L 6 16";
3810
+ var CollapsibleSketchContext = react.createContext(null);
3811
+ function useCollapsibleSketch() {
3812
+ const ctx = react.useContext(CollapsibleSketchContext);
3813
+ if (!ctx) {
3814
+ throw new Error(
3815
+ "Collapsible parts must be used inside <Collapsible>."
3816
+ );
3817
+ }
3818
+ return ctx;
3819
+ }
3820
+ var Collapsible = react.forwardRef(
3821
+ function Collapsible2({
3822
+ className,
3823
+ style,
3824
+ children,
3825
+ open,
3826
+ defaultOpen,
3827
+ onOpenChange,
3828
+ disabled,
3829
+ roughness,
3830
+ seed,
3831
+ sketchColor,
3832
+ bowing,
3833
+ fillStyle,
3834
+ strokeWidth,
3835
+ ...rest
3836
+ }, ref) {
3837
+ const resolvedSeed = useResolvedSeed(seed);
3838
+ const ink = sketchColor ?? SKETCH_COLORS.ink;
3839
+ const [uncontrolled, setUncontrolled] = react.useState(defaultOpen ?? false);
3840
+ const isOpen = open ?? uncontrolled;
3841
+ return /* @__PURE__ */ jsxRuntime.jsx(
3842
+ CollapsibleSketchContext.Provider,
3843
+ {
3844
+ value: {
3845
+ roughness,
3846
+ seed: resolvedSeed,
3847
+ sketchColor,
3848
+ bowing,
3849
+ fillStyle,
3850
+ strokeWidth,
3851
+ resolvedSeed,
3852
+ ink,
3853
+ open: isOpen
3854
+ },
3855
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3856
+ CollapsiblePrimitive__namespace.Root,
3857
+ {
3858
+ ref,
3859
+ open: isOpen,
3860
+ disabled,
3861
+ className: cn(className),
3862
+ style,
3863
+ onOpenChange: (next) => {
3864
+ setUncontrolled(next);
3865
+ onOpenChange?.(next);
3866
+ },
3867
+ ...rest,
3868
+ children
3869
+ }
3870
+ )
3871
+ }
3872
+ );
3873
+ }
3874
+ );
3875
+ var CollapsibleTrigger = react.forwardRef(function CollapsibleTrigger2({ className, style, children, ...rest }, ref) {
3876
+ const sketch = useCollapsibleSketch();
3877
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3878
+ CollapsiblePrimitive__namespace.Trigger,
3879
+ {
3880
+ ref,
3881
+ className: cn(className),
3882
+ style: {
3883
+ display: "flex",
3884
+ width: "100%",
3885
+ alignItems: "center",
3886
+ justifyContent: "space-between",
3887
+ gap: 12,
3888
+ padding: "10px 4px",
3889
+ border: "none",
3890
+ background: "transparent",
3891
+ cursor: "pointer",
3892
+ fontFamily: doodleUiFontFamily,
3893
+ fontSize: 15,
3894
+ fontWeight: doodleUiFontWeight(600),
3895
+ color: sketch.ink,
3896
+ textAlign: "left",
3897
+ outline: "none",
3898
+ ...style
3899
+ },
3900
+ ...rest,
3901
+ children: [
3902
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children }),
3903
+ /* @__PURE__ */ jsxRuntime.jsx(
3904
+ "span",
3905
+ {
3906
+ style: {
3907
+ position: "relative",
3908
+ width: 18,
3909
+ height: 18,
3910
+ flexShrink: 0,
3911
+ transform: sketch.open ? "rotate(90deg)" : "rotate(0deg)",
3912
+ transition: "transform 180ms ease"
3913
+ },
3914
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3915
+ RoughSvg,
3916
+ {
3917
+ shape: "path",
3918
+ path: CHEVRON_PATH4,
3919
+ roughness: (sketch.roughness ?? 1.5) * 0.7,
3920
+ seed: sketch.resolvedSeed,
3921
+ sketchColor: sketch.ink,
3922
+ bowing: sketch.bowing,
3923
+ strokeWidth: (sketch.strokeWidth ?? 1.6) + 0.2,
3924
+ inset: 0
3925
+ }
3926
+ )
3927
+ }
3928
+ )
3929
+ ]
3930
+ }
3931
+ );
3932
+ });
3933
+ var CollapsibleContent = react.forwardRef(function CollapsibleContent2({ className, style, children, ...rest }, ref) {
3934
+ const sketch = useCollapsibleSketch();
3935
+ return /* @__PURE__ */ jsxRuntime.jsx(
3936
+ CollapsiblePrimitive__namespace.Content,
3937
+ {
3938
+ ref,
3939
+ className: cn(className),
3940
+ style: {
3941
+ padding: "0 4px 12px",
3942
+ fontFamily: doodleUiFontFamily,
3943
+ fontSize: 14,
3944
+ lineHeight: 1.5,
3945
+ color: sketch.ink,
3946
+ ...style
3947
+ },
3948
+ ...rest,
3949
+ children
3950
+ }
3951
+ );
3952
+ });
3953
+ var PopoverSketchContext = react.createContext(
3954
+ null
3955
+ );
3956
+ function usePopoverSketch() {
3957
+ const ctx = react.useContext(PopoverSketchContext);
3958
+ if (!ctx) {
3959
+ throw new Error("Popover parts must be used inside <Popover>.");
3960
+ }
3961
+ return ctx;
3962
+ }
3963
+ function Popover({
3964
+ children,
3965
+ roughness,
3966
+ seed,
3967
+ sketchColor,
3968
+ bowing,
3969
+ fillStyle,
3970
+ strokeWidth,
3971
+ animate,
3972
+ ...rest
3973
+ }) {
3974
+ const resolvedSeed = useResolvedSeed(seed);
3975
+ const ink = sketchColor ?? SKETCH_COLORS.ink;
3976
+ return /* @__PURE__ */ jsxRuntime.jsx(
3977
+ PopoverSketchContext.Provider,
3978
+ {
3979
+ value: {
3980
+ roughness,
3981
+ seed: resolvedSeed,
3982
+ sketchColor,
3983
+ bowing,
3984
+ fillStyle,
3985
+ strokeWidth,
3986
+ resolvedSeed,
3987
+ ink,
3988
+ animate
3989
+ },
3990
+ children: /* @__PURE__ */ jsxRuntime.jsx(PopoverPrimitive__namespace.Root, { ...rest, children })
3991
+ }
3992
+ );
3993
+ }
3994
+ var PopoverTrigger = PopoverPrimitive__namespace.Trigger;
3995
+ var PopoverAnchor = PopoverPrimitive__namespace.Anchor;
3996
+ var PopoverClose = PopoverPrimitive__namespace.Close;
3997
+ var PopoverContent = react.forwardRef(
3998
+ function PopoverContent2({ className, style, children, sideOffset = 8, ...rest }, ref) {
3999
+ const sketch = usePopoverSketch();
4000
+ return /* @__PURE__ */ jsxRuntime.jsx(PopoverPrimitive__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
4001
+ PopoverPrimitive__namespace.Content,
4002
+ {
4003
+ ref,
4004
+ sideOffset,
4005
+ className: cn(className),
4006
+ style: { zIndex: 80, outline: "none", ...style },
4007
+ ...rest,
4008
+ children: /* @__PURE__ */ jsxRuntime.jsx(
4009
+ SketchBox,
4010
+ {
4011
+ roughness: sketch.roughness,
4012
+ seed: sketch.resolvedSeed,
4013
+ sketchColor: sketch.ink,
4014
+ bowing: sketch.bowing,
4015
+ fillStyle: sketch.fillStyle ?? "solid",
4016
+ fill: "#f7f6f2",
4017
+ strokeWidth: sketch.strokeWidth ?? 1.5,
4018
+ shadow: true,
4019
+ animate: sketch.animate,
4020
+ contentStyle: { padding: "14px 16px", minWidth: 200 },
4021
+ children
4022
+ }
4023
+ )
4024
+ }
4025
+ ) });
4026
+ }
4027
+ );
4028
+ var PopoverArrow = react.forwardRef(
4029
+ function PopoverArrow2(props, ref) {
4030
+ const sketch = usePopoverSketch();
4031
+ return /* @__PURE__ */ jsxRuntime.jsx(PopoverPrimitive__namespace.Arrow, { ref, fill: sketch.ink, ...props });
4032
+ }
4033
+ );
4034
+ var DropdownMenuSketchContext = react.createContext(null);
4035
+ function useDropdownMenuSketch() {
4036
+ const ctx = react.useContext(DropdownMenuSketchContext);
4037
+ if (!ctx) {
4038
+ throw new Error(
4039
+ "DropdownMenu parts must be used inside <DropdownMenu>."
4040
+ );
4041
+ }
4042
+ return ctx;
4043
+ }
4044
+ function DropdownMenu({
4045
+ children,
4046
+ roughness,
4047
+ seed,
4048
+ sketchColor,
4049
+ bowing,
4050
+ fillStyle,
4051
+ strokeWidth,
4052
+ animate,
4053
+ ...rest
4054
+ }) {
4055
+ const resolvedSeed = useResolvedSeed(seed);
4056
+ const ink = sketchColor ?? SKETCH_COLORS.ink;
4057
+ return /* @__PURE__ */ jsxRuntime.jsx(
4058
+ DropdownMenuSketchContext.Provider,
4059
+ {
4060
+ value: {
4061
+ roughness,
4062
+ seed: resolvedSeed,
4063
+ sketchColor,
4064
+ bowing,
4065
+ fillStyle,
4066
+ strokeWidth,
4067
+ resolvedSeed,
4068
+ ink,
4069
+ animate
4070
+ },
4071
+ children: /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuPrimitive__namespace.Root, { ...rest, children })
4072
+ }
4073
+ );
4074
+ }
4075
+ var DropdownMenuTrigger = DropdownMenuPrimitive__namespace.Trigger;
4076
+ var DropdownMenuGroup = DropdownMenuPrimitive__namespace.Group;
4077
+ var DropdownMenuRadioGroup = DropdownMenuPrimitive__namespace.RadioGroup;
4078
+ var DropdownMenuSub = DropdownMenuPrimitive__namespace.Sub;
4079
+ var DropdownMenuContent = react.forwardRef(function DropdownMenuContent2({ className, style, children, sideOffset = 6, align = "start", ...rest }, ref) {
4080
+ const sketch = useDropdownMenuSketch();
4081
+ return /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuPrimitive__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
4082
+ DropdownMenuPrimitive__namespace.Content,
4083
+ {
4084
+ ref,
4085
+ sideOffset,
4086
+ align,
4087
+ className: cn(className),
4088
+ style: { zIndex: 80, outline: "none", minWidth: 180, ...style },
4089
+ ...rest,
4090
+ children: /* @__PURE__ */ jsxRuntime.jsx(
4091
+ SketchBox,
4092
+ {
4093
+ roughness: sketch.roughness,
4094
+ seed: sketch.resolvedSeed,
4095
+ sketchColor: sketch.ink,
4096
+ bowing: sketch.bowing,
4097
+ fillStyle: sketch.fillStyle ?? "solid",
4098
+ fill: "#f7f6f2",
4099
+ strokeWidth: sketch.strokeWidth ?? 1.5,
4100
+ shadow: true,
4101
+ animate: sketch.animate,
4102
+ contentStyle: { padding: "6px 4px" },
4103
+ children
4104
+ }
4105
+ )
4106
+ }
4107
+ ) });
4108
+ });
4109
+ function useMark(highlighted) {
4110
+ const sketch = useDropdownMenuSketch();
4111
+ return { sketch, mark: highlighted };
4112
+ }
4113
+ var DropdownMenuItem = react.forwardRef(function DropdownMenuItem2({ className, style, children, inset, ...rest }, ref) {
4114
+ const [highlighted, setHighlighted] = react.useState(false);
4115
+ const { sketch, mark } = useMark(highlighted);
4116
+ return /* @__PURE__ */ jsxRuntime.jsxs(
4117
+ DropdownMenuPrimitive__namespace.Item,
4118
+ {
4119
+ ref,
4120
+ className: cn(className),
4121
+ onPointerMove: () => setHighlighted(true),
4122
+ onPointerLeave: () => setHighlighted(false),
4123
+ onFocus: () => setHighlighted(true),
4124
+ onBlur: () => setHighlighted(false),
4125
+ style: {
4126
+ position: "relative",
4127
+ display: "flex",
4128
+ alignItems: "center",
4129
+ gap: 8,
4130
+ padding: inset ? "7px 12px 7px 26px" : "7px 12px",
4131
+ fontFamily: doodleUiFontFamily,
4132
+ fontSize: 14,
4133
+ color: sketch.ink,
4134
+ outline: "none",
4135
+ cursor: "pointer",
4136
+ userSelect: "none",
4137
+ ...style
4138
+ },
4139
+ ...rest,
4140
+ children: [
4141
+ mark ? /* @__PURE__ */ jsxRuntime.jsx(
4142
+ RoughSvg,
4143
+ {
4144
+ shape: "line",
4145
+ roughness: (sketch.roughness ?? 1.5) + 0.4,
4146
+ seed: sketch.resolvedSeed,
4147
+ sketchColor: sketch.ink,
4148
+ bowing: sketch.bowing ?? 1.6,
4149
+ strokeWidth: 1.3,
4150
+ inset: 4,
4151
+ style: { opacity: 0.4 }
4152
+ }
4153
+ ) : null,
4154
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { position: "relative", zIndex: 1 }, children })
4155
+ ]
4156
+ }
4157
+ );
4158
+ });
4159
+ var CHECK_PATH2 = "M 2 6 L 5 9 L 10 3";
4160
+ var DropdownMenuCheckboxItem = react.forwardRef(function DropdownMenuCheckboxItem2({ className, style, children, checked, ...rest }, ref) {
4161
+ const [highlighted, setHighlighted] = react.useState(false);
4162
+ const { sketch, mark } = useMark(highlighted);
4163
+ return /* @__PURE__ */ jsxRuntime.jsxs(
4164
+ DropdownMenuPrimitive__namespace.CheckboxItem,
4165
+ {
4166
+ ref,
4167
+ checked,
4168
+ className: cn(className),
4169
+ onPointerMove: () => setHighlighted(true),
4170
+ onPointerLeave: () => setHighlighted(false),
4171
+ style: {
4172
+ position: "relative",
4173
+ display: "flex",
4174
+ alignItems: "center",
4175
+ gap: 8,
4176
+ padding: "7px 12px 7px 26px",
4177
+ fontFamily: doodleUiFontFamily,
4178
+ fontSize: 14,
4179
+ color: sketch.ink,
4180
+ outline: "none",
4181
+ cursor: "pointer",
4182
+ userSelect: "none",
4183
+ ...style
4184
+ },
4185
+ ...rest,
4186
+ children: [
4187
+ mark ? /* @__PURE__ */ jsxRuntime.jsx(
4188
+ RoughSvg,
4189
+ {
4190
+ shape: "line",
4191
+ roughness: (sketch.roughness ?? 1.5) + 0.4,
4192
+ seed: sketch.resolvedSeed,
4193
+ sketchColor: sketch.ink,
4194
+ bowing: sketch.bowing ?? 1.6,
4195
+ strokeWidth: 1.3,
4196
+ inset: 4,
4197
+ style: { opacity: 0.4 }
4198
+ }
4199
+ ) : null,
4200
+ /* @__PURE__ */ jsxRuntime.jsx(
4201
+ "span",
4202
+ {
4203
+ style: {
4204
+ position: "relative",
4205
+ width: 12,
4206
+ height: 12,
4207
+ flexShrink: 0,
4208
+ marginLeft: -18
4209
+ },
4210
+ children: /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuPrimitive__namespace.ItemIndicator, { children: /* @__PURE__ */ jsxRuntime.jsx(
4211
+ RoughSvg,
4212
+ {
4213
+ shape: "path",
4214
+ path: CHECK_PATH2,
4215
+ roughness: (sketch.roughness ?? 1.5) * 0.7,
4216
+ seed: deriveSeed(sketch.resolvedSeed, "checkbox-mark"),
4217
+ sketchColor: SKETCH_COLORS.accent,
4218
+ bowing: sketch.bowing,
4219
+ strokeWidth: 1.6,
4220
+ inset: 0
4221
+ }
4222
+ ) })
4223
+ }
4224
+ ),
4225
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { position: "relative", zIndex: 1 }, children })
4226
+ ]
4227
+ }
4228
+ );
4229
+ });
4230
+ var DropdownMenuRadioItem = react.forwardRef(function DropdownMenuRadioItem2({ className, style, children, ...rest }, ref) {
4231
+ const [highlighted, setHighlighted] = react.useState(false);
4232
+ const { sketch, mark } = useMark(highlighted);
4233
+ return /* @__PURE__ */ jsxRuntime.jsxs(
4234
+ DropdownMenuPrimitive__namespace.RadioItem,
4235
+ {
4236
+ ref,
4237
+ className: cn(className),
4238
+ onPointerMove: () => setHighlighted(true),
4239
+ onPointerLeave: () => setHighlighted(false),
4240
+ style: {
4241
+ position: "relative",
4242
+ display: "flex",
4243
+ alignItems: "center",
4244
+ gap: 8,
4245
+ padding: "7px 12px 7px 26px",
4246
+ fontFamily: doodleUiFontFamily,
4247
+ fontSize: 14,
4248
+ color: sketch.ink,
4249
+ outline: "none",
4250
+ cursor: "pointer",
4251
+ userSelect: "none",
4252
+ ...style
4253
+ },
4254
+ ...rest,
4255
+ children: [
4256
+ mark ? /* @__PURE__ */ jsxRuntime.jsx(
4257
+ RoughSvg,
4258
+ {
4259
+ shape: "line",
4260
+ roughness: (sketch.roughness ?? 1.5) + 0.4,
4261
+ seed: sketch.resolvedSeed,
4262
+ sketchColor: sketch.ink,
4263
+ bowing: sketch.bowing ?? 1.6,
4264
+ strokeWidth: 1.3,
4265
+ inset: 4,
4266
+ style: { opacity: 0.4 }
4267
+ }
4268
+ ) : null,
4269
+ /* @__PURE__ */ jsxRuntime.jsx(
4270
+ "span",
4271
+ {
4272
+ style: {
4273
+ position: "relative",
4274
+ width: 8,
4275
+ height: 8,
4276
+ flexShrink: 0,
4277
+ marginLeft: -18
4278
+ },
4279
+ children: /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuPrimitive__namespace.ItemIndicator, { children: /* @__PURE__ */ jsxRuntime.jsx(
4280
+ RoughSvg,
4281
+ {
4282
+ shape: "ellipse",
4283
+ roughness: (sketch.roughness ?? 1.5) * 0.8,
4284
+ seed: deriveSeed(sketch.resolvedSeed, "radio-mark"),
4285
+ sketchColor: SKETCH_COLORS.accent,
4286
+ bowing: sketch.bowing,
4287
+ fillStyle: "solid",
4288
+ fill: SKETCH_COLORS.accent,
4289
+ strokeWidth: 1.2,
4290
+ inset: 0
4291
+ }
4292
+ ) })
4293
+ }
4294
+ ),
4295
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { position: "relative", zIndex: 1 }, children })
4296
+ ]
4297
+ }
4298
+ );
4299
+ });
4300
+ var DropdownMenuLabel = react.forwardRef(function DropdownMenuLabel2({ className, style, children, ...rest }, ref) {
4301
+ const sketch = useDropdownMenuSketch();
4302
+ return /* @__PURE__ */ jsxRuntime.jsx(
4303
+ DropdownMenuPrimitive__namespace.Label,
4304
+ {
4305
+ ref,
4306
+ className: cn(className),
4307
+ style: {
4308
+ padding: "6px 12px",
4309
+ fontFamily: doodleUiFontFamily,
4310
+ fontSize: 12,
4311
+ fontWeight: 700,
4312
+ color: sketch.ink,
4313
+ opacity: 0.6,
4314
+ textTransform: "uppercase",
4315
+ letterSpacing: 0.4,
4316
+ ...style
4317
+ },
4318
+ ...rest,
4319
+ children
4320
+ }
4321
+ );
4322
+ });
4323
+ var DropdownMenuSeparator = react.forwardRef(function DropdownMenuSeparator2({ className, style, ...rest }, ref) {
4324
+ const sketch = useDropdownMenuSketch();
4325
+ return /* @__PURE__ */ jsxRuntime.jsx(
4326
+ DropdownMenuPrimitive__namespace.Separator,
4327
+ {
4328
+ ref,
4329
+ className: cn(className),
4330
+ style: { position: "relative", height: 10, margin: "2px 0", ...style },
4331
+ ...rest,
4332
+ children: /* @__PURE__ */ jsxRuntime.jsx(
4333
+ RoughSvg,
4334
+ {
4335
+ shape: "line",
4336
+ roughness: (sketch.roughness ?? 1.5) + 0.2,
4337
+ seed: deriveSeed(sketch.resolvedSeed, "separator"),
4338
+ sketchColor: sketch.ink,
4339
+ bowing: sketch.bowing ?? 1.8,
4340
+ strokeWidth: 1.2,
4341
+ inset: 6,
4342
+ style: { opacity: 0.5 }
4343
+ }
4344
+ )
4345
+ }
4346
+ );
4347
+ });
4348
+ var DialogSketchContext = react.createContext(
4349
+ null
4350
+ );
4351
+ function useDialogSketch() {
4352
+ const ctx = react.useContext(DialogSketchContext);
4353
+ if (!ctx) {
4354
+ throw new Error("Dialog parts must be used inside <Dialog>.");
4355
+ }
4356
+ return ctx;
4357
+ }
4358
+ function Dialog2({
4359
+ children,
4360
+ open,
4361
+ defaultOpen,
4362
+ onOpenChange,
4363
+ roughness,
4364
+ seed,
4365
+ sketchColor,
4366
+ bowing,
4367
+ fillStyle,
4368
+ strokeWidth,
4369
+ animate,
4370
+ ...rest
4371
+ }) {
4372
+ const resolvedSeed = useResolvedSeed(seed);
4373
+ const ink = sketchColor ?? SKETCH_COLORS.ink;
4374
+ const [uncontrolled, setUncontrolled] = react.useState(defaultOpen === true);
4375
+ const isOpen = open ?? uncontrolled;
4376
+ return /* @__PURE__ */ jsxRuntime.jsx(
4377
+ DialogSketchContext.Provider,
4378
+ {
4379
+ value: {
4380
+ roughness,
4381
+ seed: resolvedSeed,
4382
+ sketchColor,
4383
+ bowing,
4384
+ fillStyle,
4385
+ strokeWidth,
4386
+ resolvedSeed,
4387
+ ink,
4388
+ animate,
4389
+ open: isOpen
4390
+ },
4391
+ children: /* @__PURE__ */ jsxRuntime.jsx(
4392
+ Dialog__namespace.Root,
4393
+ {
4394
+ open: isOpen,
4395
+ onOpenChange: (next) => {
4396
+ setUncontrolled(next);
4397
+ onOpenChange?.(next);
4398
+ },
4399
+ ...rest,
4400
+ children
4401
+ }
4402
+ )
4403
+ }
4404
+ );
4405
+ }
4406
+ var DialogTrigger = Dialog__namespace.Trigger;
4407
+ var DialogPortal = Dialog__namespace.Portal;
4408
+ var DialogClose = Dialog__namespace.Close;
4409
+ var DialogOverlay = react.forwardRef(
4410
+ function DialogOverlay2({ style, ...rest }, ref) {
4411
+ const sketch = useDialogSketch();
4412
+ const shouldAnimate = useAnimate(sketch.animate);
4413
+ return /* @__PURE__ */ jsxRuntime.jsx(Dialog__namespace.Overlay, { ref, asChild: true, forceMount: true, ...rest, children: /* @__PURE__ */ jsxRuntime.jsx(
4414
+ framerMotion.motion.div,
4415
+ {
4416
+ initial: shouldAnimate ? { opacity: 0 } : false,
4417
+ animate: { opacity: 1 },
4418
+ exit: shouldAnimate ? { opacity: 0 } : void 0,
4419
+ transition: shouldAnimate ? { duration: 0.2, ease: "easeOut" } : { duration: 0 },
4420
+ style: {
4421
+ position: "fixed",
4422
+ inset: 0,
4423
+ background: "rgba(31, 29, 26, 0.38)",
4424
+ zIndex: 70,
4425
+ ...style
4426
+ }
4427
+ }
4428
+ ) });
4429
+ }
4430
+ );
4431
+ var DialogContent = react.forwardRef(
4432
+ function DialogContent2({ className, style, contentStyle, children, ...rest }, ref) {
4433
+ const sketch = useDialogSketch();
4434
+ const shouldAnimate = useAnimate(sketch.animate);
4435
+ return /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: sketch.open ? /* @__PURE__ */ jsxRuntime.jsxs(Dialog__namespace.Portal, { forceMount: true, children: [
4436
+ /* @__PURE__ */ jsxRuntime.jsx(DialogOverlay, {}),
4437
+ /* @__PURE__ */ jsxRuntime.jsx(
4438
+ "div",
4439
+ {
4440
+ style: {
4441
+ position: "fixed",
4442
+ inset: 0,
4443
+ zIndex: 80,
4444
+ display: "flex",
4445
+ alignItems: "center",
4446
+ justifyContent: "center",
4447
+ pointerEvents: "none",
4448
+ padding: 16
4449
+ },
4450
+ children: /* @__PURE__ */ jsxRuntime.jsx(Dialog__namespace.Content, { ref, asChild: true, forceMount: true, ...rest, children: /* @__PURE__ */ jsxRuntime.jsx(
4451
+ framerMotion.motion.div,
4452
+ {
4453
+ className: cn(className),
4454
+ initial: shouldAnimate ? { opacity: 0, scale: 0.96, y: 10 } : false,
4455
+ animate: { opacity: 1, scale: 1, y: 0 },
4456
+ exit: shouldAnimate ? { opacity: 0, scale: 0.96, y: 8 } : void 0,
4457
+ transition: shouldAnimate ? { duration: 0.22, ease: "easeOut" } : { duration: 0 },
4458
+ style: {
4459
+ width: "min(420px, calc(100vw - 32px))",
4460
+ outline: "none",
4461
+ pointerEvents: "auto",
4462
+ ...style
4463
+ },
4464
+ children: /* @__PURE__ */ jsxRuntime.jsx(
4465
+ SketchBox,
4466
+ {
4467
+ roughness: sketch.roughness,
4468
+ seed: sketch.resolvedSeed,
4469
+ sketchColor: sketch.ink,
4470
+ bowing: sketch.bowing,
4471
+ fillStyle: sketch.fillStyle ?? "solid",
4472
+ fill: "#f7f6f2",
4473
+ strokeWidth: sketch.strokeWidth ?? 2,
4474
+ animate: sketch.animate,
4475
+ contentStyle: { padding: 20, ...contentStyle },
4476
+ children
4477
+ }
4478
+ )
4479
+ }
4480
+ ) })
4481
+ }
4482
+ )
4483
+ ] }) : null });
4484
+ }
4485
+ );
4486
+ function DialogHeader({ children, className, style }) {
4487
+ return /* @__PURE__ */ jsxRuntime.jsx(
4488
+ "div",
4489
+ {
4490
+ className: cn(className),
4491
+ style: {
4492
+ display: "flex",
4493
+ flexDirection: "column",
4494
+ gap: 6,
4495
+ marginBottom: 12,
4496
+ ...style
4497
+ },
4498
+ children
4499
+ }
4500
+ );
4501
+ }
4502
+ function DialogFooter({ children, className, style }) {
4503
+ return /* @__PURE__ */ jsxRuntime.jsx(
4504
+ "div",
4505
+ {
4506
+ className: cn(className),
4507
+ style: {
4508
+ display: "flex",
4509
+ justifyContent: "flex-end",
4510
+ gap: 8,
4511
+ marginTop: 16,
4512
+ ...style
4513
+ },
4514
+ children
4515
+ }
4516
+ );
4517
+ }
4518
+ var DialogTitle = react.forwardRef(
4519
+ function DialogTitle2({ style, ...rest }, ref) {
4520
+ const sketch = useDialogSketch();
4521
+ return /* @__PURE__ */ jsxRuntime.jsx(
4522
+ Dialog__namespace.Title,
4523
+ {
4524
+ ref,
4525
+ style: {
4526
+ margin: 0,
4527
+ fontSize: 18,
4528
+ fontWeight: doodleUiFontWeight(700),
4529
+ fontFamily: doodleUiFontFamily,
4530
+ color: sketch.ink,
4531
+ ...style
4532
+ },
4533
+ ...rest
4534
+ }
4535
+ );
4536
+ }
4537
+ );
4538
+ var DialogDescription = react.forwardRef(function DialogDescription2({ style, ...rest }, ref) {
4539
+ const sketch = useDialogSketch();
4540
+ return /* @__PURE__ */ jsxRuntime.jsx(
4541
+ Dialog__namespace.Description,
4542
+ {
4543
+ ref,
4544
+ style: {
4545
+ margin: 0,
4546
+ fontSize: 14,
4547
+ lineHeight: 1.5,
4548
+ fontFamily: doodleUiFontFamily,
4549
+ color: sketch.ink,
4550
+ opacity: 0.8,
4551
+ ...style
4552
+ },
4553
+ ...rest
4554
+ }
4555
+ );
4556
+ });
4557
+ var AlertDialogSketchContext = react.createContext(null);
4558
+ function useAlertDialogSketch() {
4559
+ const ctx = react.useContext(AlertDialogSketchContext);
4560
+ if (!ctx) {
4561
+ throw new Error(
4562
+ "AlertDialog parts must be used inside <AlertDialog>."
4563
+ );
4564
+ }
4565
+ return ctx;
4566
+ }
4567
+ function AlertDialog({
4568
+ children,
4569
+ open,
4570
+ defaultOpen,
4571
+ onOpenChange,
4572
+ roughness,
4573
+ seed,
4574
+ sketchColor,
4575
+ bowing,
4576
+ fillStyle,
4577
+ strokeWidth,
4578
+ animate,
4579
+ ...rest
4580
+ }) {
4581
+ const resolvedSeed = useResolvedSeed(seed);
4582
+ const ink = sketchColor ?? SKETCH_COLORS.ink;
4583
+ const [uncontrolled, setUncontrolled] = react.useState(defaultOpen === true);
4584
+ const isOpen = open ?? uncontrolled;
4585
+ return /* @__PURE__ */ jsxRuntime.jsx(
4586
+ AlertDialogSketchContext.Provider,
4587
+ {
4588
+ value: {
4589
+ roughness,
4590
+ seed: resolvedSeed,
4591
+ sketchColor,
4592
+ bowing,
4593
+ fillStyle,
4594
+ strokeWidth,
4595
+ resolvedSeed,
4596
+ ink,
4597
+ animate,
4598
+ open: isOpen
4599
+ },
4600
+ children: /* @__PURE__ */ jsxRuntime.jsx(
4601
+ AlertDialogPrimitive__namespace.Root,
4602
+ {
4603
+ open: isOpen,
4604
+ onOpenChange: (next) => {
4605
+ setUncontrolled(next);
4606
+ onOpenChange?.(next);
4607
+ },
4608
+ ...rest,
4609
+ children
4610
+ }
4611
+ )
4612
+ }
4613
+ );
4614
+ }
4615
+ var AlertDialogTrigger = AlertDialogPrimitive__namespace.Trigger;
4616
+ var AlertDialogPortal = AlertDialogPrimitive__namespace.Portal;
4617
+ var AlertDialogOverlay = react.forwardRef(function AlertDialogOverlay2({ style, ...rest }, ref) {
4618
+ const sketch = useAlertDialogSketch();
4619
+ const shouldAnimate = useAnimate(sketch.animate);
4620
+ return /* @__PURE__ */ jsxRuntime.jsx(AlertDialogPrimitive__namespace.Overlay, { ref, asChild: true, forceMount: true, ...rest, children: /* @__PURE__ */ jsxRuntime.jsx(
4621
+ framerMotion.motion.div,
4622
+ {
4623
+ initial: shouldAnimate ? { opacity: 0 } : false,
4624
+ animate: { opacity: 1 },
4625
+ exit: shouldAnimate ? { opacity: 0 } : void 0,
4626
+ transition: shouldAnimate ? { duration: 0.2, ease: "easeOut" } : { duration: 0 },
4627
+ style: {
4628
+ position: "fixed",
4629
+ inset: 0,
4630
+ background: "rgba(31, 29, 26, 0.38)",
4631
+ zIndex: 70,
4632
+ ...style
4633
+ }
4634
+ }
4635
+ ) });
4636
+ });
4637
+ var AlertDialogContent = react.forwardRef(function AlertDialogContent2({ className, style, contentStyle, children, ...rest }, ref) {
4638
+ const sketch = useAlertDialogSketch();
4639
+ const shouldAnimate = useAnimate(sketch.animate);
4640
+ return /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: sketch.open ? /* @__PURE__ */ jsxRuntime.jsxs(AlertDialogPrimitive__namespace.Portal, { forceMount: true, children: [
4641
+ /* @__PURE__ */ jsxRuntime.jsx(AlertDialogOverlay, {}),
4642
+ /* @__PURE__ */ jsxRuntime.jsx(
4643
+ "div",
4644
+ {
4645
+ style: {
4646
+ position: "fixed",
4647
+ inset: 0,
4648
+ zIndex: 80,
4649
+ display: "flex",
4650
+ alignItems: "center",
4651
+ justifyContent: "center",
4652
+ pointerEvents: "none",
4653
+ padding: 16
4654
+ },
4655
+ children: /* @__PURE__ */ jsxRuntime.jsx(AlertDialogPrimitive__namespace.Content, { ref, asChild: true, forceMount: true, ...rest, children: /* @__PURE__ */ jsxRuntime.jsx(
4656
+ framerMotion.motion.div,
4657
+ {
4658
+ className: cn(className),
4659
+ initial: shouldAnimate ? { opacity: 0, scale: 0.96, y: 10 } : false,
4660
+ animate: { opacity: 1, scale: 1, y: 0 },
4661
+ exit: shouldAnimate ? { opacity: 0, scale: 0.96, y: 8 } : void 0,
4662
+ transition: shouldAnimate ? { duration: 0.22, ease: "easeOut" } : { duration: 0 },
4663
+ style: {
4664
+ width: "min(420px, calc(100vw - 32px))",
4665
+ outline: "none",
4666
+ pointerEvents: "auto",
4667
+ ...style
4668
+ },
4669
+ children: /* @__PURE__ */ jsxRuntime.jsx(
4670
+ SketchBox,
4671
+ {
4672
+ roughness: sketch.roughness,
4673
+ seed: sketch.resolvedSeed,
4674
+ sketchColor: sketch.ink,
4675
+ bowing: sketch.bowing,
4676
+ fillStyle: sketch.fillStyle ?? "solid",
4677
+ fill: "#f7f6f2",
4678
+ strokeWidth: sketch.strokeWidth ?? 2,
4679
+ animate: sketch.animate,
4680
+ contentStyle: { padding: 20, ...contentStyle },
4681
+ children
4682
+ }
4683
+ )
4684
+ }
4685
+ ) })
4686
+ }
4687
+ )
4688
+ ] }) : null });
4689
+ });
4690
+ function AlertDialogHeader({
4691
+ children,
4692
+ className,
4693
+ style
4694
+ }) {
4695
+ return /* @__PURE__ */ jsxRuntime.jsx(
4696
+ "div",
4697
+ {
4698
+ className: cn(className),
4699
+ style: {
4700
+ display: "flex",
4701
+ flexDirection: "column",
4702
+ gap: 6,
4703
+ marginBottom: 12,
4704
+ ...style
4705
+ },
4706
+ children
4707
+ }
4708
+ );
4709
+ }
4710
+ function AlertDialogFooter({
4711
+ children,
4712
+ className,
4713
+ style
4714
+ }) {
4715
+ return /* @__PURE__ */ jsxRuntime.jsx(
4716
+ "div",
4717
+ {
4718
+ className: cn(className),
4719
+ style: {
4720
+ display: "flex",
4721
+ justifyContent: "flex-end",
4722
+ gap: 8,
4723
+ marginTop: 16,
4724
+ ...style
4725
+ },
4726
+ children
4727
+ }
4728
+ );
4729
+ }
4730
+ var AlertDialogTitle = react.forwardRef(function AlertDialogTitle2({ style, ...rest }, ref) {
4731
+ const sketch = useAlertDialogSketch();
4732
+ return /* @__PURE__ */ jsxRuntime.jsx(
4733
+ AlertDialogPrimitive__namespace.Title,
4734
+ {
4735
+ ref,
4736
+ style: {
4737
+ margin: 0,
4738
+ fontSize: 18,
4739
+ fontWeight: doodleUiFontWeight(700),
4740
+ fontFamily: doodleUiFontFamily,
4741
+ color: sketch.ink,
4742
+ ...style
4743
+ },
4744
+ ...rest
4745
+ }
4746
+ );
4747
+ });
4748
+ var AlertDialogDescription = react.forwardRef(function AlertDialogDescription2({ style, ...rest }, ref) {
4749
+ const sketch = useAlertDialogSketch();
4750
+ return /* @__PURE__ */ jsxRuntime.jsx(
4751
+ AlertDialogPrimitive__namespace.Description,
4752
+ {
4753
+ ref,
4754
+ style: {
4755
+ margin: 0,
4756
+ fontSize: 14,
4757
+ lineHeight: 1.5,
4758
+ fontFamily: doodleUiFontFamily,
4759
+ color: sketch.ink,
4760
+ opacity: 0.8,
4761
+ ...style
4762
+ },
4763
+ ...rest
4764
+ }
4765
+ );
4766
+ });
4767
+ var AlertDialogAction = react.forwardRef(function AlertDialogAction2({ children, ...rest }, ref) {
4768
+ const sketch = useAlertDialogSketch();
4769
+ return /* @__PURE__ */ jsxRuntime.jsx(AlertDialogPrimitive__namespace.Action, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
4770
+ Button,
4771
+ {
4772
+ ref,
4773
+ variant: "primary",
4774
+ sketchColor: sketch.sketchColor,
4775
+ roughness: sketch.roughness,
4776
+ seed: sketch.resolvedSeed,
4777
+ bowing: sketch.bowing,
4778
+ animate: sketch.animate,
4779
+ ...rest,
4780
+ children
4781
+ }
4782
+ ) });
4783
+ });
4784
+ var AlertDialogCancel = react.forwardRef(function AlertDialogCancel2({ children, ...rest }, ref) {
4785
+ const sketch = useAlertDialogSketch();
4786
+ return /* @__PURE__ */ jsxRuntime.jsx(AlertDialogPrimitive__namespace.Cancel, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
4787
+ Button,
4788
+ {
4789
+ ref,
4790
+ variant: "outline",
4791
+ sketchColor: sketch.sketchColor,
4792
+ roughness: sketch.roughness,
4793
+ seed: sketch.resolvedSeed,
4794
+ bowing: sketch.bowing,
4795
+ animate: sketch.animate,
4796
+ ...rest,
4797
+ children
4798
+ }
4799
+ ) });
4800
+ });
4801
+ var CommandSketchContext = react.createContext(
4802
+ null
4803
+ );
4804
+ function useCommandSketch() {
4805
+ const ctx = react.useContext(CommandSketchContext);
4806
+ if (!ctx) {
4807
+ throw new Error("Command parts must be used inside <Command>.");
4808
+ }
4809
+ return ctx;
4810
+ }
4811
+ var Command = react.forwardRef(
4812
+ function Command2({
4813
+ className,
4814
+ style,
4815
+ children,
4816
+ roughness,
4817
+ seed,
4818
+ sketchColor,
4819
+ bowing,
4820
+ fillStyle,
4821
+ strokeWidth,
4822
+ animate,
4823
+ ...rest
4824
+ }, ref) {
4825
+ const resolvedSeed = useResolvedSeed(seed);
4826
+ const ink = sketchColor ?? SKETCH_COLORS.ink;
4827
+ return /* @__PURE__ */ jsxRuntime.jsx(
4828
+ CommandSketchContext.Provider,
4829
+ {
4830
+ value: {
4831
+ roughness,
4832
+ seed: resolvedSeed,
4833
+ sketchColor,
4834
+ bowing,
4835
+ fillStyle,
4836
+ strokeWidth,
4837
+ resolvedSeed,
4838
+ ink,
4839
+ animate
4840
+ },
4841
+ children: /* @__PURE__ */ jsxRuntime.jsx(
4842
+ SketchBox,
4843
+ {
4844
+ className: cn(className),
4845
+ style,
4846
+ roughness,
4847
+ seed: resolvedSeed,
4848
+ sketchColor: ink,
4849
+ bowing,
4850
+ fillStyle: fillStyle ?? "solid",
4851
+ fill: "#f7f6f2",
4852
+ strokeWidth: strokeWidth ?? 1.5,
4853
+ animate,
4854
+ contentStyle: { padding: 0, display: "flex", flexDirection: "column" },
4855
+ children: /* @__PURE__ */ jsxRuntime.jsx(cmdk.Command, { ref, ...rest, children })
4856
+ }
4857
+ )
4858
+ }
4859
+ );
4860
+ }
4861
+ );
4862
+ var CommandInput = react.forwardRef(
4863
+ function CommandInput2({ className, style, ...rest }, ref) {
4864
+ const sketch = useCommandSketch();
4865
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { position: "relative", padding: "10px 12px 12px" }, children: [
4866
+ /* @__PURE__ */ jsxRuntime.jsx(
4867
+ cmdk.CommandInput,
4868
+ {
4869
+ ref,
4870
+ className: cn(className),
4871
+ style: {
4872
+ width: "100%",
4873
+ boxSizing: "border-box",
4874
+ border: "none",
4875
+ outline: "none",
4876
+ background: "transparent",
4877
+ color: sketch.ink,
4878
+ fontFamily: doodleUiFontFamily,
4879
+ fontSize: 15,
4880
+ padding: "2px 2px 8px",
4881
+ ...style
4882
+ },
4883
+ ...rest
4884
+ }
4885
+ ),
4886
+ /* @__PURE__ */ jsxRuntime.jsx(
4887
+ RoughSvg,
4888
+ {
4889
+ shape: "line",
4890
+ roughness: (sketch.roughness ?? 1.5) + 0.2,
4891
+ seed: deriveSeed(sketch.resolvedSeed, "command-divider"),
4892
+ sketchColor: sketch.ink,
4893
+ bowing: sketch.bowing ?? 1.6,
4894
+ strokeWidth: 1.2,
4895
+ inset: 4,
4896
+ style: { position: "absolute", bottom: 0, left: 0, right: 0, height: 8, opacity: 0.4 }
4897
+ }
4898
+ )
4899
+ ] });
4900
+ }
4901
+ );
4902
+ var CommandList = react.forwardRef(
4903
+ function CommandList2({ className, style, ...rest }, ref) {
4904
+ return /* @__PURE__ */ jsxRuntime.jsx(
4905
+ cmdk.CommandList,
4906
+ {
4907
+ ref,
4908
+ className: cn(className),
4909
+ style: {
4910
+ maxHeight: 280,
4911
+ overflowY: "auto",
4912
+ padding: "4px 4px 8px",
4913
+ ...style
4914
+ },
4915
+ ...rest
4916
+ }
4917
+ );
4918
+ }
4919
+ );
4920
+ var CommandEmpty = react.forwardRef(
4921
+ function CommandEmpty2({ className, style, ...rest }, ref) {
4922
+ const sketch = useCommandSketch();
4923
+ return /* @__PURE__ */ jsxRuntime.jsx(
4924
+ cmdk.CommandEmpty,
4925
+ {
4926
+ ref,
4927
+ className: cn(className),
4928
+ style: {
4929
+ padding: "16px 12px",
4930
+ textAlign: "center",
4931
+ fontFamily: doodleUiFontFamily,
4932
+ fontSize: 14,
4933
+ color: sketch.ink,
4934
+ opacity: 0.6,
4935
+ ...style
4936
+ },
4937
+ ...rest
4938
+ }
4939
+ );
4940
+ }
4941
+ );
4942
+ var CommandGroup = react.forwardRef(
4943
+ function CommandGroup2({ className, style, ...rest }, ref) {
4944
+ const sketch = useCommandSketch();
4945
+ return /* @__PURE__ */ jsxRuntime.jsx(
4946
+ cmdk.CommandGroup,
4947
+ {
4948
+ ref,
4949
+ className: cn(className),
4950
+ style: { padding: "4px 2px", color: sketch.ink, ...style },
4951
+ ...rest
4952
+ }
4953
+ );
4954
+ }
4955
+ );
4956
+ var CommandItem = react.forwardRef(
4957
+ function CommandItem2({ className, style, children, onMouseEnter, onMouseLeave, ...rest }, ref) {
4958
+ const sketch = useCommandSketch();
4959
+ const [highlighted, setHighlighted] = react.useState(false);
4960
+ return /* @__PURE__ */ jsxRuntime.jsxs(
4961
+ cmdk.CommandItem,
4962
+ {
4963
+ ref,
4964
+ className: cn(className),
4965
+ onMouseEnter: (event) => {
4966
+ setHighlighted(true);
4967
+ onMouseEnter?.(event);
4968
+ },
4969
+ onMouseLeave: (event) => {
4970
+ setHighlighted(false);
4971
+ onMouseLeave?.(event);
4972
+ },
4973
+ style: {
4974
+ position: "relative",
4975
+ display: "flex",
4976
+ alignItems: "center",
4977
+ gap: 8,
4978
+ padding: "7px 10px",
4979
+ borderRadius: 4,
4980
+ fontFamily: doodleUiFontFamily,
4981
+ fontSize: 14,
4982
+ color: sketch.ink,
4983
+ cursor: "pointer",
4984
+ userSelect: "none",
4985
+ outline: "none",
4986
+ ...style
4987
+ },
4988
+ ...rest,
4989
+ children: [
4990
+ highlighted ? /* @__PURE__ */ jsxRuntime.jsx(
4991
+ RoughSvg,
4992
+ {
4993
+ shape: "line",
4994
+ roughness: (sketch.roughness ?? 1.5) + 0.4,
4995
+ seed: sketch.resolvedSeed,
4996
+ sketchColor: sketch.ink,
4997
+ bowing: sketch.bowing ?? 1.6,
4998
+ strokeWidth: 1.3,
4999
+ inset: 3,
5000
+ style: { opacity: 0.4 }
5001
+ }
5002
+ ) : null,
5003
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { position: "relative", zIndex: 1, flex: 1 }, children })
5004
+ ]
5005
+ }
5006
+ );
5007
+ }
5008
+ );
5009
+ var CommandSeparator = react.forwardRef(function CommandSeparator2({ className, style, ...rest }, ref) {
5010
+ const sketch = useCommandSketch();
5011
+ return /* @__PURE__ */ jsxRuntime.jsx(
5012
+ cmdk.CommandSeparator,
5013
+ {
5014
+ ref,
5015
+ className: cn(className),
5016
+ style: { position: "relative", height: 10, margin: "2px 4px", ...style },
5017
+ ...rest,
5018
+ children: /* @__PURE__ */ jsxRuntime.jsx(
5019
+ RoughSvg,
5020
+ {
5021
+ shape: "line",
5022
+ roughness: (sketch.roughness ?? 1.5) + 0.2,
5023
+ seed: deriveSeed(sketch.resolvedSeed, "command-separator"),
5024
+ sketchColor: sketch.ink,
5025
+ bowing: sketch.bowing ?? 1.8,
5026
+ strokeWidth: 1.2,
5027
+ inset: 4,
5028
+ style: { opacity: 0.4 }
5029
+ }
5030
+ )
5031
+ }
5032
+ );
5033
+ });
5034
+ function CommandShortcut({
5035
+ children,
5036
+ className,
5037
+ style
5038
+ }) {
5039
+ const sketch = useCommandSketch();
5040
+ return /* @__PURE__ */ jsxRuntime.jsx(
5041
+ "span",
5042
+ {
5043
+ className: cn(className),
5044
+ style: {
5045
+ marginLeft: "auto",
5046
+ fontFamily: doodleUiFontFamily,
5047
+ fontSize: 12,
5048
+ color: sketch.ink,
5049
+ opacity: 0.5,
5050
+ letterSpacing: 0.4,
5051
+ ...style
5052
+ },
5053
+ children
5054
+ }
5055
+ );
5056
+ }
5057
+ var CHEVRON_PATH5 = "M 4 6 L 10 12 L 16 6";
5058
+ function Combobox({
5059
+ options,
5060
+ placeholder = "Select\u2026",
5061
+ searchPlaceholder = "Search\u2026",
5062
+ emptyMessage = "No results.",
5063
+ value,
5064
+ defaultValue,
5065
+ onValueChange,
5066
+ disabled,
5067
+ className,
5068
+ style,
5069
+ roughness,
5070
+ seed,
5071
+ sketchColor,
5072
+ bowing,
5073
+ fillStyle,
5074
+ strokeWidth,
5075
+ animate,
5076
+ "aria-label": ariaLabel
5077
+ }) {
5078
+ const [open, setOpen] = react.useState(false);
5079
+ const [uncontrolled, setUncontrolled] = react.useState(defaultValue);
5080
+ const selectedValue = value ?? uncontrolled;
5081
+ const selectedOption = options.find(
5082
+ (option) => option.value === selectedValue
5083
+ );
5084
+ const ink = sketchColor ?? SKETCH_COLORS.ink;
5085
+ const resolvedSeed = useResolvedSeed(seed);
5086
+ const shouldAnimate = useAnimate(animate);
5087
+ const triggerRef = react.useRef(null);
5088
+ useDrawIn(triggerRef, DRAW_IN_DURATION_MS, shouldAnimate);
5089
+ function handleSelect(nextValue) {
5090
+ setUncontrolled(nextValue);
5091
+ onValueChange?.(nextValue);
5092
+ setOpen(false);
5093
+ }
5094
+ return /* @__PURE__ */ jsxRuntime.jsxs(PopoverPrimitive__namespace.Root, { open, onOpenChange: setOpen, children: [
5095
+ /* @__PURE__ */ jsxRuntime.jsx(PopoverPrimitive__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
5096
+ "button",
5097
+ {
5098
+ ref: (node) => assignRef(triggerRef, node),
5099
+ type: "button",
5100
+ role: "combobox",
5101
+ "aria-expanded": open,
5102
+ "aria-label": ariaLabel,
5103
+ disabled,
5104
+ className: cn(className),
5105
+ style: {
5106
+ position: "relative",
5107
+ display: "inline-flex",
5108
+ alignItems: "center",
5109
+ justifyContent: "space-between",
5110
+ gap: 12,
5111
+ width: "100%",
5112
+ minWidth: 200,
5113
+ minHeight: 38,
5114
+ padding: "8px 12px",
5115
+ border: "none",
5116
+ background: "transparent",
5117
+ cursor: disabled ? "not-allowed" : "pointer",
5118
+ opacity: disabled ? 0.5 : 1,
5119
+ color: ink,
5120
+ fontFamily: doodleUiFontFamily,
5121
+ fontSize: 15,
5122
+ lineHeight: 1.2,
5123
+ outline: "none",
5124
+ textAlign: "left",
5125
+ ...style
5126
+ },
5127
+ children: [
5128
+ /* @__PURE__ */ jsxRuntime.jsx(
5129
+ RoughSvg,
5130
+ {
5131
+ shape: "rectangle",
5132
+ roughness,
5133
+ seed: resolvedSeed,
5134
+ sketchColor: open ? SKETCH_COLORS.accent : ink,
5135
+ bowing,
5136
+ fillStyle,
5137
+ strokeWidth: open ? (strokeWidth ?? 1.75) + 0.35 : strokeWidth
5138
+ }
5139
+ ),
5140
+ /* @__PURE__ */ jsxRuntime.jsx(
5141
+ "span",
5142
+ {
5143
+ style: {
5144
+ position: "relative",
5145
+ zIndex: 1,
5146
+ flex: 1,
5147
+ overflow: "hidden",
5148
+ textOverflow: "ellipsis",
5149
+ whiteSpace: "nowrap"
5150
+ },
5151
+ children: selectedOption?.label ?? placeholder
5152
+ }
5153
+ ),
5154
+ /* @__PURE__ */ jsxRuntime.jsx(
5155
+ "span",
5156
+ {
5157
+ style: { position: "relative", zIndex: 1, width: 18, height: 18, flexShrink: 0 },
5158
+ children: /* @__PURE__ */ jsxRuntime.jsx(
5159
+ RoughSvg,
5160
+ {
5161
+ shape: "path",
5162
+ path: CHEVRON_PATH5,
5163
+ roughness: roughness ? roughness * 0.7 : 1.05,
5164
+ seed: resolvedSeed,
5165
+ sketchColor: ink,
5166
+ bowing,
5167
+ strokeWidth: (strokeWidth ?? 1.6) + 0.2,
5168
+ inset: 0
5169
+ }
5170
+ )
5171
+ }
5172
+ )
5173
+ ]
5174
+ }
5175
+ ) }),
5176
+ /* @__PURE__ */ jsxRuntime.jsx(PopoverPrimitive__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
5177
+ PopoverPrimitive__namespace.Content,
5178
+ {
5179
+ align: "start",
5180
+ sideOffset: 8,
5181
+ style: {
5182
+ zIndex: 80,
5183
+ outline: "none",
5184
+ width: "var(--radix-popover-trigger-width)"
5185
+ },
5186
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
5187
+ Command,
5188
+ {
5189
+ roughness,
5190
+ seed: resolvedSeed,
5191
+ sketchColor: ink,
5192
+ bowing,
5193
+ fillStyle,
5194
+ strokeWidth,
5195
+ animate,
5196
+ children: [
5197
+ /* @__PURE__ */ jsxRuntime.jsx(CommandInput, { placeholder: searchPlaceholder }),
5198
+ /* @__PURE__ */ jsxRuntime.jsxs(CommandList, { children: [
5199
+ /* @__PURE__ */ jsxRuntime.jsx(CommandEmpty, { children: emptyMessage }),
5200
+ /* @__PURE__ */ jsxRuntime.jsx(CommandGroup, { children: options.map((option) => /* @__PURE__ */ jsxRuntime.jsx(
5201
+ CommandItem,
5202
+ {
5203
+ value: option.value,
5204
+ disabled: option.disabled,
5205
+ onSelect: handleSelect,
5206
+ children: option.label
5207
+ },
5208
+ option.value
5209
+ )) })
5210
+ ] })
5211
+ ]
5212
+ }
5213
+ )
5214
+ }
5215
+ ) })
5216
+ ] });
5217
+ }
3248
5218
 
3249
5219
  exports.Accordion = Accordion;
3250
5220
  exports.AccordionContent = AccordionContent;
3251
5221
  exports.AccordionItem = AccordionItem;
3252
5222
  exports.AccordionTrigger = AccordionTrigger;
3253
5223
  exports.Alert = Alert;
5224
+ exports.AlertDialog = AlertDialog;
5225
+ exports.AlertDialogAction = AlertDialogAction;
5226
+ exports.AlertDialogCancel = AlertDialogCancel;
5227
+ exports.AlertDialogContent = AlertDialogContent;
5228
+ exports.AlertDialogDescription = AlertDialogDescription;
5229
+ exports.AlertDialogFooter = AlertDialogFooter;
5230
+ exports.AlertDialogHeader = AlertDialogHeader;
5231
+ exports.AlertDialogOverlay = AlertDialogOverlay;
5232
+ exports.AlertDialogPortal = AlertDialogPortal;
5233
+ exports.AlertDialogTitle = AlertDialogTitle;
5234
+ exports.AlertDialogTrigger = AlertDialogTrigger;
3254
5235
  exports.Avatar = Avatar;
3255
5236
  exports.Badge = Badge;
3256
5237
  exports.Breadcrumb = Breadcrumb;
@@ -3258,12 +5239,51 @@ exports.BreadcrumbItem = BreadcrumbItem;
3258
5239
  exports.Button = Button;
3259
5240
  exports.Card = Card;
3260
5241
  exports.Checkbox = Checkbox;
5242
+ exports.Collapsible = Collapsible;
5243
+ exports.CollapsibleContent = CollapsibleContent;
5244
+ exports.CollapsibleTrigger = CollapsibleTrigger;
5245
+ exports.Combobox = Combobox;
5246
+ exports.Command = Command;
5247
+ exports.CommandEmpty = CommandEmpty;
5248
+ exports.CommandGroup = CommandGroup;
5249
+ exports.CommandInput = CommandInput;
5250
+ exports.CommandItem = CommandItem;
5251
+ exports.CommandList = CommandList;
5252
+ exports.CommandSeparator = CommandSeparator;
5253
+ exports.CommandShortcut = CommandShortcut;
3261
5254
  exports.DEFAULT_BOWING = DEFAULT_BOWING;
3262
5255
  exports.DEFAULT_INK = DEFAULT_INK;
3263
5256
  exports.DEFAULT_ROUGHNESS = DEFAULT_ROUGHNESS;
3264
5257
  exports.DEFAULT_STROKE_WIDTH = DEFAULT_STROKE_WIDTH;
5258
+ exports.DRAW_IN_ALERT_MS = DRAW_IN_ALERT_MS;
5259
+ exports.DRAW_IN_DURATION_MS = DRAW_IN_DURATION_MS;
5260
+ exports.DRAW_IN_MARK_MS = DRAW_IN_MARK_MS;
5261
+ exports.DRAW_IN_TOOLTIP_MS = DRAW_IN_TOOLTIP_MS;
5262
+ exports.Dialog = Dialog2;
5263
+ exports.DialogClose = DialogClose;
5264
+ exports.DialogContent = DialogContent;
5265
+ exports.DialogDescription = DialogDescription;
5266
+ exports.DialogFooter = DialogFooter;
5267
+ exports.DialogHeader = DialogHeader;
5268
+ exports.DialogOverlay = DialogOverlay;
5269
+ exports.DialogPortal = DialogPortal;
5270
+ exports.DialogTitle = DialogTitle;
5271
+ exports.DialogTrigger = DialogTrigger;
3265
5272
  exports.Divider = Divider;
5273
+ exports.DoodleUIProvider = DoodleUIProvider;
5274
+ exports.DropdownMenu = DropdownMenu;
5275
+ exports.DropdownMenuCheckboxItem = DropdownMenuCheckboxItem;
5276
+ exports.DropdownMenuContent = DropdownMenuContent;
5277
+ exports.DropdownMenuGroup = DropdownMenuGroup;
5278
+ exports.DropdownMenuItem = DropdownMenuItem;
5279
+ exports.DropdownMenuLabel = DropdownMenuLabel;
5280
+ exports.DropdownMenuRadioGroup = DropdownMenuRadioGroup;
5281
+ exports.DropdownMenuRadioItem = DropdownMenuRadioItem;
5282
+ exports.DropdownMenuSeparator = DropdownMenuSeparator;
5283
+ exports.DropdownMenuSub = DropdownMenuSub;
5284
+ exports.DropdownMenuTrigger = DropdownMenuTrigger;
3266
5285
  exports.Input = Input;
5286
+ exports.Label = Label2;
3267
5287
  exports.Modal = Modal;
3268
5288
  exports.ModalClose = ModalClose;
3269
5289
  exports.ModalDescription = ModalDescription;
@@ -3271,6 +5291,12 @@ exports.ModalRoot = ModalRoot;
3271
5291
  exports.ModalTitle = ModalTitle;
3272
5292
  exports.ModalTrigger = ModalTrigger;
3273
5293
  exports.Pagination = Pagination;
5294
+ exports.Popover = Popover;
5295
+ exports.PopoverAnchor = PopoverAnchor;
5296
+ exports.PopoverArrow = PopoverArrow;
5297
+ exports.PopoverClose = PopoverClose;
5298
+ exports.PopoverContent = PopoverContent;
5299
+ exports.PopoverTrigger = PopoverTrigger;
3274
5300
  exports.Progress = Progress;
3275
5301
  exports.Radio = Radio;
3276
5302
  exports.RadioGroup = RadioGroup;
@@ -3291,6 +5317,7 @@ exports.SketchSeedProvider = SketchSeedProvider;
3291
5317
  exports.Slider = Slider;
3292
5318
  exports.Stepper = Stepper;
3293
5319
  exports.Switch = Switch;
5320
+ exports.TABLE_STAGGER_MS = TABLE_STAGGER_MS;
3294
5321
  exports.Tab = Tab;
3295
5322
  exports.TabList = TabList;
3296
5323
  exports.TabPanel = TabPanel;
@@ -3314,6 +5341,9 @@ exports.Tooltip = Tooltip;
3314
5341
  exports.TooltipProvider = TooltipProvider;
3315
5342
  exports.deriveSeed = deriveSeed;
3316
5343
  exports.toRoughOptions = toRoughOptions;
5344
+ exports.useAnimate = useAnimate;
5345
+ exports.useDoodleUI = useDoodleUI;
5346
+ exports.useDrawIn = useDrawIn;
3317
5347
  exports.useResolvedSeed = useResolvedSeed;
3318
5348
  exports.useSketchSeed = useSketchSeed;
3319
5349
  //# sourceMappingURL=index.cjs.map