doodleui-react 0.1.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.js ADDED
@@ -0,0 +1,1174 @@
1
+ "use client";
2
+ import { createContext, forwardRef, useState, useId, useRef, useLayoutEffect, useContext, useCallback, useMemo } from 'react';
3
+ import rough from 'roughjs';
4
+ import { jsxs, jsx } from 'react/jsx-runtime';
5
+ import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
6
+ import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
7
+ import * as Dialog from '@radix-ui/react-dialog';
8
+ import * as TooltipPrimitive from '@radix-ui/react-tooltip';
9
+
10
+ // src/types.ts
11
+ function toRoughOptions(props) {
12
+ const stroke = props.stroke ?? props.sketchColor ?? DEFAULT_INK;
13
+ const options = {
14
+ roughness: props.roughness ?? DEFAULT_ROUGHNESS,
15
+ bowing: props.bowing ?? DEFAULT_BOWING,
16
+ stroke,
17
+ strokeWidth: props.strokeWidth ?? DEFAULT_STROKE_WIDTH,
18
+ seed: props.seed
19
+ };
20
+ if (props.fill) {
21
+ options.fill = props.fill;
22
+ options.fillStyle = props.fillStyle ?? "hachure";
23
+ }
24
+ return options;
25
+ }
26
+ var DEFAULT_ROUGHNESS = 1.5;
27
+ var DEFAULT_BOWING = 1;
28
+ var DEFAULT_STROKE_WIDTH = 1.75;
29
+ var DEFAULT_INK = "#1f1d1a";
30
+ var DEFAULT_INSET = 3;
31
+ var SKETCH_COLORS = {
32
+ ink: DEFAULT_INK,
33
+ accent: "#e24b3b",
34
+ accentFill: "#f4c4bc",
35
+ secondaryFill: "#d7e3d4",
36
+ paper: "#eef0ea",
37
+ info: "#1d4e89",
38
+ warning: "#c47b17",
39
+ error: "#c0392b",
40
+ success: "#2d6a4f"
41
+ };
42
+
43
+ // src/utils.ts
44
+ function randomSeed() {
45
+ return Math.floor(Math.random() * 2 ** 31);
46
+ }
47
+ function cn(...parts) {
48
+ const value = parts.filter(Boolean).join(" ");
49
+ return value.length > 0 ? value : void 0;
50
+ }
51
+ var SketchSeedContext = createContext(null);
52
+ function SketchSeedProvider({
53
+ children,
54
+ initialSeed
55
+ }) {
56
+ const [seed, setSeed] = useState(() => initialSeed ?? randomSeed());
57
+ const shuffle = useCallback(() => {
58
+ setSeed(randomSeed());
59
+ }, []);
60
+ const value = useMemo(
61
+ () => ({ seed, shuffle, setSeed }),
62
+ [seed, shuffle]
63
+ );
64
+ return /* @__PURE__ */ jsx(SketchSeedContext.Provider, { value, children });
65
+ }
66
+ function useSketchSeed() {
67
+ const ctx = useContext(SketchSeedContext);
68
+ if (!ctx) {
69
+ throw new Error(
70
+ "useSketchSeed() must be used inside <SketchSeedProvider>. Wrap your tree so Shuffle can redraw every sketch."
71
+ );
72
+ }
73
+ return ctx;
74
+ }
75
+ function useOptionalSketchSeed() {
76
+ return useContext(SketchSeedContext);
77
+ }
78
+
79
+ // src/hooks/useResolvedSeed.ts
80
+ function useResolvedSeed(seed) {
81
+ const ctx = useOptionalSketchSeed();
82
+ const [fallback] = useState(randomSeed);
83
+ if (seed != null) return seed;
84
+ if (ctx) return ctx.seed;
85
+ return fallback;
86
+ }
87
+ function useElementSize(ref) {
88
+ const [size, setSize] = useState({ width: 0, height: 0 });
89
+ useLayoutEffect(() => {
90
+ const el = ref.current;
91
+ if (!el) return;
92
+ const update = () => {
93
+ setSize({ width: el.offsetWidth, height: el.offsetHeight });
94
+ };
95
+ update();
96
+ const observer = new ResizeObserver(update);
97
+ observer.observe(el);
98
+ return () => observer.disconnect();
99
+ }, [ref]);
100
+ return size;
101
+ }
102
+ function RoughSvg({
103
+ shape = "rectangle",
104
+ width: widthProp,
105
+ height: heightProp,
106
+ roughness,
107
+ seed: seedProp,
108
+ sketchColor,
109
+ bowing,
110
+ fillStyle,
111
+ strokeWidth,
112
+ fill,
113
+ inset = DEFAULT_INSET,
114
+ path,
115
+ className,
116
+ style
117
+ }) {
118
+ const containerRef = useRef(null);
119
+ const svgRef = useRef(null);
120
+ const measured = useElementSize(containerRef);
121
+ const seed = useResolvedSeed(seedProp);
122
+ const width = widthProp ?? measured.width;
123
+ const height = heightProp ?? measured.height;
124
+ useLayoutEffect(() => {
125
+ const svg = svgRef.current;
126
+ if (!svg || width < 2 || height < 2) return;
127
+ while (svg.firstChild) svg.removeChild(svg.firstChild);
128
+ const rc = rough.svg(svg);
129
+ const options = toRoughOptions({
130
+ roughness,
131
+ seed,
132
+ sketchColor,
133
+ bowing,
134
+ fillStyle,
135
+ strokeWidth,
136
+ fill
137
+ });
138
+ const x = inset;
139
+ const y = inset;
140
+ const w = Math.max(1, width - inset * 2);
141
+ const h = Math.max(1, height - inset * 2);
142
+ let node;
143
+ switch (shape) {
144
+ case "ellipse":
145
+ node = rc.ellipse(width / 2, height / 2, w, h, options);
146
+ break;
147
+ case "line":
148
+ node = rc.line(inset, height / 2, width - inset, height / 2, options);
149
+ break;
150
+ case "line-vertical":
151
+ node = rc.line(width / 2, inset, width / 2, height - inset, options);
152
+ break;
153
+ case "path":
154
+ if (!path) return;
155
+ node = rc.path(path, options);
156
+ break;
157
+ default:
158
+ node = rc.rectangle(x, y, w, h, options);
159
+ }
160
+ svg.appendChild(node);
161
+ }, [
162
+ width,
163
+ height,
164
+ shape,
165
+ roughness,
166
+ seed,
167
+ sketchColor,
168
+ bowing,
169
+ fillStyle,
170
+ strokeWidth,
171
+ fill,
172
+ inset,
173
+ path
174
+ ]);
175
+ const overlayStyle = {
176
+ position: "absolute",
177
+ inset: 0,
178
+ width: "100%",
179
+ height: "100%",
180
+ pointerEvents: "none",
181
+ overflow: "visible",
182
+ zIndex: 0,
183
+ ...style
184
+ };
185
+ return /* @__PURE__ */ jsx(
186
+ "div",
187
+ {
188
+ ref: containerRef,
189
+ "aria-hidden": "true",
190
+ className,
191
+ style: overlayStyle,
192
+ children: /* @__PURE__ */ jsx(
193
+ "svg",
194
+ {
195
+ ref: svgRef,
196
+ width: "100%",
197
+ height: "100%",
198
+ overflow: "visible",
199
+ style: { display: "block" }
200
+ }
201
+ )
202
+ }
203
+ );
204
+ }
205
+ var SketchBox = forwardRef(
206
+ function SketchBox2({
207
+ children,
208
+ className,
209
+ style,
210
+ contentClassName,
211
+ contentStyle,
212
+ shape = "rectangle",
213
+ fill,
214
+ fillStyle,
215
+ shadow = false,
216
+ roughness,
217
+ seed,
218
+ sketchColor,
219
+ bowing,
220
+ strokeWidth,
221
+ inset,
222
+ path,
223
+ ...rest
224
+ }, ref) {
225
+ return /* @__PURE__ */ jsxs(
226
+ "div",
227
+ {
228
+ ref,
229
+ className: cn(className),
230
+ style: { position: "relative", ...style },
231
+ ...rest,
232
+ children: [
233
+ shadow ? /* @__PURE__ */ jsx(
234
+ RoughSvg,
235
+ {
236
+ shape,
237
+ roughness: (roughness ?? 1.5) + 0.35,
238
+ seed,
239
+ sketchColor,
240
+ bowing,
241
+ fillStyle: "hachure",
242
+ fill: sketchColor ?? "#1f1d1a",
243
+ strokeWidth: 1,
244
+ inset,
245
+ style: { transform: "translate(5px, 6px)", opacity: 0.16 }
246
+ }
247
+ ) : null,
248
+ /* @__PURE__ */ jsx(
249
+ RoughSvg,
250
+ {
251
+ shape,
252
+ roughness,
253
+ seed,
254
+ sketchColor,
255
+ bowing,
256
+ fillStyle: fill ? fillStyle : shadow ? "solid" : fillStyle,
257
+ fill: fill ?? (shadow ? "#f7f6f2" : void 0),
258
+ strokeWidth,
259
+ inset,
260
+ path
261
+ }
262
+ ),
263
+ /* @__PURE__ */ jsx(
264
+ "div",
265
+ {
266
+ className: contentClassName,
267
+ style: { position: "relative", zIndex: 1, ...contentStyle },
268
+ children
269
+ }
270
+ )
271
+ ]
272
+ }
273
+ );
274
+ }
275
+ );
276
+ var SIZE_STYLES = {
277
+ sm: { fontSize: 13, padding: "4px 12px", minHeight: 30 },
278
+ md: { fontSize: 15, padding: "8px 16px", minHeight: 38 },
279
+ lg: { fontSize: 17, padding: "11px 22px", minHeight: 46 }
280
+ };
281
+ var Button = forwardRef(
282
+ function Button2({
283
+ children,
284
+ className,
285
+ style,
286
+ variant = "primary",
287
+ size = "md",
288
+ roughness,
289
+ seed,
290
+ sketchColor,
291
+ bowing,
292
+ fillStyle,
293
+ strokeWidth,
294
+ disabled,
295
+ onMouseEnter,
296
+ onMouseLeave,
297
+ ...rest
298
+ }, ref) {
299
+ const [hovered, setHovered] = useState(false);
300
+ const ink = sketchColor ?? SKETCH_COLORS.ink;
301
+ const fill = variant === "primary" ? SKETCH_COLORS.accentFill : variant === "secondary" ? SKETCH_COLORS.secondaryFill : void 0;
302
+ const stroke = variant === "ghost" && !hovered ? "transparent" : variant === "primary" ? sketchColor ?? SKETCH_COLORS.accent : ink;
303
+ return /* @__PURE__ */ jsxs(
304
+ "button",
305
+ {
306
+ ref,
307
+ type: "button",
308
+ className: cn(className),
309
+ disabled,
310
+ onMouseEnter: (event) => {
311
+ setHovered(true);
312
+ onMouseEnter?.(event);
313
+ },
314
+ onMouseLeave: (event) => {
315
+ setHovered(false);
316
+ onMouseLeave?.(event);
317
+ },
318
+ style: {
319
+ position: "relative",
320
+ display: "inline-flex",
321
+ alignItems: "center",
322
+ justifyContent: "center",
323
+ gap: 8,
324
+ border: "none",
325
+ background: "transparent",
326
+ cursor: disabled ? "not-allowed" : "pointer",
327
+ color: ink,
328
+ fontFamily: "inherit",
329
+ fontWeight: 600,
330
+ lineHeight: 1.2,
331
+ opacity: disabled ? 0.45 : 1,
332
+ ...SIZE_STYLES[size],
333
+ ...style
334
+ },
335
+ ...rest,
336
+ children: [
337
+ /* @__PURE__ */ jsx(
338
+ RoughSvg,
339
+ {
340
+ shape: "rectangle",
341
+ roughness,
342
+ seed,
343
+ sketchColor: stroke,
344
+ bowing,
345
+ fillStyle: fillStyle ?? "hachure",
346
+ fill,
347
+ strokeWidth: hovered ? (strokeWidth ?? 1.75) + 0.4 : strokeWidth
348
+ }
349
+ ),
350
+ /* @__PURE__ */ jsx("span", { style: { position: "relative", zIndex: 1 }, children })
351
+ ]
352
+ }
353
+ );
354
+ }
355
+ );
356
+ var Input = forwardRef(function Input2({
357
+ className,
358
+ style,
359
+ label,
360
+ roughness,
361
+ seed,
362
+ sketchColor,
363
+ bowing,
364
+ fillStyle,
365
+ strokeWidth,
366
+ id,
367
+ onFocus,
368
+ onBlur,
369
+ ...rest
370
+ }, ref) {
371
+ const [focused, setFocused] = useState(false);
372
+ const ink = sketchColor ?? SKETCH_COLORS.ink;
373
+ const inputId = id;
374
+ return /* @__PURE__ */ jsxs(
375
+ "label",
376
+ {
377
+ htmlFor: inputId,
378
+ style: {
379
+ display: "flex",
380
+ flexDirection: "column",
381
+ gap: 6,
382
+ width: "100%"
383
+ },
384
+ children: [
385
+ label ? /* @__PURE__ */ jsx("span", { style: { fontSize: 13, fontWeight: 600, color: ink }, children: label }) : null,
386
+ /* @__PURE__ */ jsxs("span", { style: { position: "relative", display: "block" }, children: [
387
+ /* @__PURE__ */ jsx(
388
+ RoughSvg,
389
+ {
390
+ shape: "rectangle",
391
+ roughness,
392
+ seed,
393
+ sketchColor: focused ? SKETCH_COLORS.accent : ink,
394
+ bowing,
395
+ fillStyle,
396
+ strokeWidth: focused ? (strokeWidth ?? 1.75) + 0.35 : strokeWidth
397
+ }
398
+ ),
399
+ /* @__PURE__ */ jsx(
400
+ "input",
401
+ {
402
+ ref,
403
+ id: inputId,
404
+ className: cn(className),
405
+ onFocus: (event) => {
406
+ setFocused(true);
407
+ onFocus?.(event);
408
+ },
409
+ onBlur: (event) => {
410
+ setFocused(false);
411
+ onBlur?.(event);
412
+ },
413
+ style: {
414
+ position: "relative",
415
+ zIndex: 1,
416
+ width: "100%",
417
+ boxSizing: "border-box",
418
+ border: "none",
419
+ outline: "none",
420
+ background: "transparent",
421
+ color: ink,
422
+ fontFamily: "inherit",
423
+ fontSize: 15,
424
+ padding: "8px 12px",
425
+ ...style
426
+ },
427
+ ...rest
428
+ }
429
+ )
430
+ ] })
431
+ ]
432
+ }
433
+ );
434
+ });
435
+ var Textarea = forwardRef(
436
+ function Textarea2({
437
+ className,
438
+ style,
439
+ label,
440
+ roughness,
441
+ seed,
442
+ sketchColor,
443
+ bowing,
444
+ fillStyle,
445
+ strokeWidth,
446
+ id,
447
+ rows = 4,
448
+ onFocus,
449
+ onBlur,
450
+ ...rest
451
+ }, ref) {
452
+ const [focused, setFocused] = useState(false);
453
+ const ink = sketchColor ?? SKETCH_COLORS.ink;
454
+ return /* @__PURE__ */ jsxs(
455
+ "label",
456
+ {
457
+ htmlFor: id,
458
+ style: {
459
+ display: "flex",
460
+ flexDirection: "column",
461
+ gap: 6,
462
+ width: "100%"
463
+ },
464
+ children: [
465
+ label ? /* @__PURE__ */ jsx("span", { style: { fontSize: 13, fontWeight: 600, color: ink }, children: label }) : null,
466
+ /* @__PURE__ */ jsxs("span", { style: { position: "relative", display: "block" }, children: [
467
+ /* @__PURE__ */ jsx(
468
+ RoughSvg,
469
+ {
470
+ shape: "rectangle",
471
+ roughness,
472
+ seed,
473
+ sketchColor: focused ? SKETCH_COLORS.accent : ink,
474
+ bowing,
475
+ fillStyle,
476
+ strokeWidth: focused ? (strokeWidth ?? 1.75) + 0.35 : strokeWidth
477
+ }
478
+ ),
479
+ /* @__PURE__ */ jsx(
480
+ "textarea",
481
+ {
482
+ ref,
483
+ id,
484
+ rows,
485
+ className: cn(className),
486
+ onFocus: (event) => {
487
+ setFocused(true);
488
+ onFocus?.(event);
489
+ },
490
+ onBlur: (event) => {
491
+ setFocused(false);
492
+ onBlur?.(event);
493
+ },
494
+ style: {
495
+ position: "relative",
496
+ zIndex: 1,
497
+ width: "100%",
498
+ boxSizing: "border-box",
499
+ border: "none",
500
+ outline: "none",
501
+ background: "transparent",
502
+ color: ink,
503
+ fontFamily: "inherit",
504
+ fontSize: 15,
505
+ lineHeight: 1.5,
506
+ padding: "10px 12px",
507
+ resize: "vertical",
508
+ ...style
509
+ },
510
+ ...rest
511
+ }
512
+ )
513
+ ] })
514
+ ]
515
+ }
516
+ );
517
+ }
518
+ );
519
+ var BOX = 20;
520
+ var CHECK_PATH = "M 4.5 10.5 L 8.5 14.5 L 15.5 5.5";
521
+ var Checkbox = forwardRef(
522
+ function Checkbox2({
523
+ className,
524
+ style,
525
+ label,
526
+ roughness,
527
+ seed,
528
+ sketchColor,
529
+ bowing,
530
+ fillStyle,
531
+ strokeWidth,
532
+ checked,
533
+ defaultChecked,
534
+ onCheckedChange,
535
+ id,
536
+ ...rest
537
+ }, ref) {
538
+ const ink = sketchColor ?? SKETCH_COLORS.ink;
539
+ const generatedId = useId();
540
+ const inputId = id ?? generatedId;
541
+ return /* @__PURE__ */ jsxs(
542
+ "span",
543
+ {
544
+ className: cn(className),
545
+ style: {
546
+ display: "inline-flex",
547
+ alignItems: "center",
548
+ gap: 8,
549
+ cursor: "pointer",
550
+ userSelect: "none",
551
+ ...style
552
+ },
553
+ children: [
554
+ /* @__PURE__ */ jsxs(
555
+ CheckboxPrimitive.Root,
556
+ {
557
+ ref,
558
+ id: inputId,
559
+ checked,
560
+ defaultChecked,
561
+ onCheckedChange,
562
+ style: {
563
+ position: "relative",
564
+ width: BOX,
565
+ height: BOX,
566
+ padding: 0,
567
+ border: "none",
568
+ background: "transparent",
569
+ flexShrink: 0,
570
+ cursor: "pointer"
571
+ },
572
+ ...rest,
573
+ children: [
574
+ /* @__PURE__ */ jsx(
575
+ RoughSvg,
576
+ {
577
+ shape: "rectangle",
578
+ roughness,
579
+ seed,
580
+ sketchColor: ink,
581
+ bowing,
582
+ fillStyle,
583
+ strokeWidth: strokeWidth ?? 1.6,
584
+ inset: 1.5
585
+ }
586
+ ),
587
+ /* @__PURE__ */ jsx(
588
+ CheckboxPrimitive.Indicator,
589
+ {
590
+ style: {
591
+ position: "absolute",
592
+ inset: 0,
593
+ display: "block"
594
+ },
595
+ children: /* @__PURE__ */ jsx(
596
+ RoughSvg,
597
+ {
598
+ shape: "path",
599
+ path: CHECK_PATH,
600
+ roughness: (roughness ?? 1.5) * 0.7,
601
+ seed,
602
+ sketchColor: SKETCH_COLORS.accent,
603
+ bowing,
604
+ strokeWidth: (strokeWidth ?? 1.6) + 0.4,
605
+ inset: 0
606
+ }
607
+ )
608
+ }
609
+ )
610
+ ]
611
+ }
612
+ ),
613
+ label ? /* @__PURE__ */ jsx("label", { htmlFor: inputId, style: { fontSize: 15, cursor: "pointer" }, children: label }) : null
614
+ ]
615
+ }
616
+ );
617
+ }
618
+ );
619
+ var RadioGroup = forwardRef(
620
+ function RadioGroup2({ className, style, children, ...rest }, ref) {
621
+ return /* @__PURE__ */ jsx(
622
+ RadioGroupPrimitive.Root,
623
+ {
624
+ ref,
625
+ className: cn(className),
626
+ style: {
627
+ display: "flex",
628
+ flexDirection: "column",
629
+ gap: 10,
630
+ ...style
631
+ },
632
+ ...rest,
633
+ children
634
+ }
635
+ );
636
+ }
637
+ );
638
+ var SIZE = 20;
639
+ var Radio = forwardRef(function Radio2({
640
+ className,
641
+ style,
642
+ label,
643
+ roughness,
644
+ seed,
645
+ sketchColor,
646
+ bowing,
647
+ fillStyle,
648
+ strokeWidth,
649
+ id,
650
+ ...rest
651
+ }, ref) {
652
+ const ink = sketchColor ?? SKETCH_COLORS.ink;
653
+ const generatedId = useId();
654
+ const inputId = id ?? generatedId;
655
+ return /* @__PURE__ */ jsxs(
656
+ "span",
657
+ {
658
+ className: cn(className),
659
+ style: {
660
+ display: "inline-flex",
661
+ alignItems: "center",
662
+ gap: 8,
663
+ cursor: "pointer",
664
+ userSelect: "none",
665
+ ...style
666
+ },
667
+ children: [
668
+ /* @__PURE__ */ jsxs(
669
+ RadioGroupPrimitive.Item,
670
+ {
671
+ ref,
672
+ id: inputId,
673
+ style: {
674
+ position: "relative",
675
+ width: SIZE,
676
+ height: SIZE,
677
+ padding: 0,
678
+ border: "none",
679
+ background: "transparent",
680
+ flexShrink: 0,
681
+ cursor: "pointer",
682
+ borderRadius: "50%"
683
+ },
684
+ ...rest,
685
+ children: [
686
+ /* @__PURE__ */ jsx(
687
+ RoughSvg,
688
+ {
689
+ shape: "ellipse",
690
+ roughness,
691
+ seed,
692
+ sketchColor: ink,
693
+ bowing,
694
+ fillStyle,
695
+ strokeWidth: strokeWidth ?? 1.6,
696
+ inset: 1.5
697
+ }
698
+ ),
699
+ /* @__PURE__ */ jsx(
700
+ RadioGroupPrimitive.Indicator,
701
+ {
702
+ style: {
703
+ position: "absolute",
704
+ inset: 0,
705
+ display: "block"
706
+ },
707
+ children: /* @__PURE__ */ jsx(
708
+ RoughSvg,
709
+ {
710
+ shape: "ellipse",
711
+ roughness: (roughness ?? 1.5) + 0.2,
712
+ seed,
713
+ sketchColor: SKETCH_COLORS.accent,
714
+ fill: SKETCH_COLORS.accent,
715
+ fillStyle: "solid",
716
+ bowing,
717
+ strokeWidth: 1,
718
+ inset: 6
719
+ }
720
+ )
721
+ }
722
+ )
723
+ ]
724
+ }
725
+ ),
726
+ label ? /* @__PURE__ */ jsx("label", { htmlFor: inputId, style: { fontSize: 15, cursor: "pointer" }, children: label }) : null
727
+ ]
728
+ }
729
+ );
730
+ });
731
+ var Card = forwardRef(function Card2({
732
+ children,
733
+ className,
734
+ style,
735
+ shadow = true,
736
+ fill,
737
+ title,
738
+ footer,
739
+ roughness,
740
+ seed,
741
+ sketchColor,
742
+ bowing,
743
+ fillStyle,
744
+ strokeWidth,
745
+ ...rest
746
+ }, ref) {
747
+ const boxProps = {
748
+ shadow,
749
+ fill,
750
+ roughness,
751
+ seed,
752
+ sketchColor: sketchColor ?? SKETCH_COLORS.ink,
753
+ bowing,
754
+ fillStyle,
755
+ strokeWidth
756
+ };
757
+ return /* @__PURE__ */ jsxs(
758
+ SketchBox,
759
+ {
760
+ ref,
761
+ className: cn(className),
762
+ style,
763
+ contentStyle: { padding: "16px 18px" },
764
+ ...boxProps,
765
+ ...rest,
766
+ children: [
767
+ title ? /* @__PURE__ */ jsx(
768
+ "div",
769
+ {
770
+ style: {
771
+ fontWeight: 700,
772
+ fontSize: 16,
773
+ marginBottom: 10
774
+ },
775
+ children: title
776
+ }
777
+ ) : null,
778
+ children,
779
+ footer ? /* @__PURE__ */ jsx("div", { style: { marginTop: 14, fontSize: 13, opacity: 0.8 }, children: footer }) : null
780
+ ]
781
+ }
782
+ );
783
+ });
784
+ var Badge = forwardRef(function Badge2({
785
+ children,
786
+ className,
787
+ style,
788
+ variant = "default",
789
+ roughness,
790
+ seed,
791
+ sketchColor,
792
+ bowing,
793
+ fillStyle,
794
+ strokeWidth,
795
+ ...rest
796
+ }, ref) {
797
+ const ink = variant === "accent" ? sketchColor ?? SKETCH_COLORS.accent : sketchColor ?? SKETCH_COLORS.ink;
798
+ const fill = variant === "accent" ? SKETCH_COLORS.accentFill : variant === "outline" ? void 0 : SKETCH_COLORS.secondaryFill;
799
+ return /* @__PURE__ */ jsx(
800
+ SketchBox,
801
+ {
802
+ className: cn(className),
803
+ style: {
804
+ display: "inline-flex",
805
+ verticalAlign: "middle",
806
+ ...style
807
+ },
808
+ contentStyle: {
809
+ padding: "2px 10px",
810
+ fontSize: 12,
811
+ fontWeight: 650,
812
+ lineHeight: 1.4,
813
+ letterSpacing: "0.01em"
814
+ },
815
+ fill,
816
+ fillStyle: fillStyle ?? "hachure",
817
+ roughness,
818
+ seed,
819
+ sketchColor: ink,
820
+ bowing,
821
+ strokeWidth: strokeWidth ?? 1.4,
822
+ ...rest,
823
+ children: /* @__PURE__ */ jsx("span", { ref, children })
824
+ }
825
+ );
826
+ });
827
+ var VARIANT_COLOR = {
828
+ info: SKETCH_COLORS.info,
829
+ warning: SKETCH_COLORS.warning,
830
+ error: SKETCH_COLORS.error,
831
+ success: SKETCH_COLORS.success
832
+ };
833
+ var VARIANT_FILL = {
834
+ info: "#d2deec",
835
+ warning: "#f3e2c0",
836
+ error: "#f3d0cc",
837
+ success: "#d3e8dc"
838
+ };
839
+ var Alert = forwardRef(function Alert2({
840
+ children,
841
+ className,
842
+ style,
843
+ variant = "info",
844
+ title,
845
+ roughness,
846
+ seed,
847
+ sketchColor,
848
+ bowing,
849
+ fillStyle,
850
+ strokeWidth,
851
+ role = "status",
852
+ ...rest
853
+ }, ref) {
854
+ const color = sketchColor ?? VARIANT_COLOR[variant];
855
+ return /* @__PURE__ */ jsxs(
856
+ SketchBox,
857
+ {
858
+ ref,
859
+ role,
860
+ className: cn(className),
861
+ style: { color, ...style },
862
+ contentStyle: { padding: "12px 16px" },
863
+ roughness,
864
+ seed,
865
+ sketchColor: color,
866
+ bowing,
867
+ fillStyle: fillStyle ?? "hachure",
868
+ fill: VARIANT_FILL[variant],
869
+ strokeWidth,
870
+ ...rest,
871
+ children: [
872
+ title ? /* @__PURE__ */ jsx("div", { style: { fontWeight: 700, marginBottom: 4, fontSize: 15 }, children: title }) : null,
873
+ /* @__PURE__ */ jsx("div", { style: { fontSize: 14, lineHeight: 1.5, color: SKETCH_COLORS.ink }, children })
874
+ ]
875
+ }
876
+ );
877
+ });
878
+ function Modal({
879
+ open,
880
+ defaultOpen,
881
+ onOpenChange,
882
+ trigger,
883
+ title,
884
+ description,
885
+ children,
886
+ className,
887
+ roughness,
888
+ seed,
889
+ sketchColor,
890
+ bowing,
891
+ fillStyle,
892
+ strokeWidth
893
+ }) {
894
+ const ink = sketchColor ?? SKETCH_COLORS.ink;
895
+ return /* @__PURE__ */ jsxs(Dialog.Root, { open, defaultOpen, onOpenChange, children: [
896
+ trigger ? /* @__PURE__ */ jsx(Dialog.Trigger, { asChild: true, children: trigger }) : null,
897
+ /* @__PURE__ */ jsxs(Dialog.Portal, { children: [
898
+ /* @__PURE__ */ jsx(
899
+ Dialog.Overlay,
900
+ {
901
+ style: {
902
+ position: "fixed",
903
+ inset: 0,
904
+ background: "rgba(31, 29, 26, 0.38)",
905
+ zIndex: 70
906
+ }
907
+ }
908
+ ),
909
+ /* @__PURE__ */ jsx(
910
+ Dialog.Content,
911
+ {
912
+ className: cn(className),
913
+ style: {
914
+ position: "fixed",
915
+ left: "50%",
916
+ top: "50%",
917
+ transform: "translate(-50%, -50%)",
918
+ zIndex: 80,
919
+ width: "min(480px, calc(100vw - 32px))",
920
+ outline: "none"
921
+ },
922
+ children: /* @__PURE__ */ jsxs(
923
+ SketchBox,
924
+ {
925
+ roughness,
926
+ seed,
927
+ sketchColor: ink,
928
+ bowing,
929
+ fillStyle: fillStyle ?? "solid",
930
+ fill: "#f7f6f2",
931
+ strokeWidth: strokeWidth ?? 2,
932
+ shadow: true,
933
+ contentStyle: { padding: "20px 22px 18px" },
934
+ children: [
935
+ /* @__PURE__ */ jsxs(
936
+ "div",
937
+ {
938
+ style: {
939
+ display: "flex",
940
+ alignItems: "flex-start",
941
+ justifyContent: "space-between",
942
+ gap: 12,
943
+ marginBottom: title ? 10 : 0
944
+ },
945
+ children: [
946
+ title ? /* @__PURE__ */ jsx(
947
+ Dialog.Title,
948
+ {
949
+ style: {
950
+ margin: 0,
951
+ fontSize: 18,
952
+ fontWeight: 700,
953
+ color: ink
954
+ },
955
+ children: title
956
+ }
957
+ ) : /* @__PURE__ */ jsx(Dialog.Title, { style: { position: "absolute", width: 1, height: 1, overflow: "hidden", clip: "rect(0 0 0 0)" }, children: "Dialog" }),
958
+ /* @__PURE__ */ jsx(Dialog.Close, { asChild: true, children: /* @__PURE__ */ jsx(
959
+ Button,
960
+ {
961
+ variant: "ghost",
962
+ size: "sm",
963
+ roughness,
964
+ seed,
965
+ sketchColor: ink,
966
+ "aria-label": "Close",
967
+ children: "Close"
968
+ }
969
+ ) })
970
+ ]
971
+ }
972
+ ),
973
+ description ? /* @__PURE__ */ jsx(
974
+ Dialog.Description,
975
+ {
976
+ style: {
977
+ margin: "0 0 14px",
978
+ fontSize: 14,
979
+ lineHeight: 1.5,
980
+ color: ink,
981
+ opacity: 0.8
982
+ },
983
+ children: description
984
+ }
985
+ ) : null,
986
+ /* @__PURE__ */ jsx("div", { children })
987
+ ]
988
+ }
989
+ )
990
+ }
991
+ )
992
+ ] })
993
+ ] });
994
+ }
995
+ var ModalRoot = Dialog.Root;
996
+ var ModalTrigger = Dialog.Trigger;
997
+ var ModalClose = Dialog.Close;
998
+ var ModalTitle = Dialog.Title;
999
+ var ModalDescription = Dialog.Description;
1000
+ var Divider = forwardRef(
1001
+ function Divider2({
1002
+ className,
1003
+ style,
1004
+ orientation = "horizontal",
1005
+ roughness,
1006
+ seed,
1007
+ sketchColor,
1008
+ bowing,
1009
+ strokeWidth,
1010
+ ...rest
1011
+ }, ref) {
1012
+ const horizontal = orientation === "horizontal";
1013
+ return /* @__PURE__ */ jsx(
1014
+ "div",
1015
+ {
1016
+ ref,
1017
+ role: "separator",
1018
+ "aria-orientation": orientation,
1019
+ className: cn(className),
1020
+ style: {
1021
+ position: "relative",
1022
+ width: horizontal ? "100%" : 12,
1023
+ height: horizontal ? 12 : "100%",
1024
+ minHeight: horizontal ? 12 : 48,
1025
+ ...style
1026
+ },
1027
+ ...rest,
1028
+ children: /* @__PURE__ */ jsx(
1029
+ RoughSvg,
1030
+ {
1031
+ shape: horizontal ? "line" : "line-vertical",
1032
+ roughness: roughness ?? 1.8,
1033
+ seed,
1034
+ sketchColor: sketchColor ?? SKETCH_COLORS.ink,
1035
+ bowing: bowing ?? 2,
1036
+ strokeWidth: strokeWidth ?? 1.5,
1037
+ inset: 4
1038
+ }
1039
+ )
1040
+ }
1041
+ );
1042
+ }
1043
+ );
1044
+ var Progress = forwardRef(
1045
+ function Progress2({
1046
+ className,
1047
+ style,
1048
+ value = 0,
1049
+ max = 100,
1050
+ roughness,
1051
+ seed,
1052
+ sketchColor,
1053
+ bowing,
1054
+ fillStyle,
1055
+ strokeWidth,
1056
+ ...rest
1057
+ }, ref) {
1058
+ const ink = sketchColor ?? SKETCH_COLORS.accent;
1059
+ const clamped = Math.min(max, Math.max(0, value));
1060
+ const percent = max === 0 ? 0 : clamped / max * 100;
1061
+ return /* @__PURE__ */ jsxs(
1062
+ "div",
1063
+ {
1064
+ ref,
1065
+ role: "progressbar",
1066
+ "aria-valuemin": 0,
1067
+ "aria-valuemax": max,
1068
+ "aria-valuenow": clamped,
1069
+ className: cn(className),
1070
+ style: {
1071
+ position: "relative",
1072
+ width: "100%",
1073
+ height: 18,
1074
+ ...style
1075
+ },
1076
+ ...rest,
1077
+ children: [
1078
+ /* @__PURE__ */ jsx(
1079
+ RoughSvg,
1080
+ {
1081
+ shape: "rectangle",
1082
+ roughness,
1083
+ seed,
1084
+ sketchColor: SKETCH_COLORS.ink,
1085
+ bowing,
1086
+ strokeWidth: strokeWidth ?? 1.5,
1087
+ inset: 2
1088
+ }
1089
+ ),
1090
+ percent > 0 ? /* @__PURE__ */ jsx(
1091
+ "div",
1092
+ {
1093
+ style: {
1094
+ position: "absolute",
1095
+ left: 5,
1096
+ top: 4,
1097
+ bottom: 4,
1098
+ width: `calc(${percent}% - 10px)`,
1099
+ minWidth: percent > 0 ? 8 : 0,
1100
+ overflow: "hidden"
1101
+ },
1102
+ children: /* @__PURE__ */ jsx(
1103
+ RoughSvg,
1104
+ {
1105
+ shape: "rectangle",
1106
+ roughness: (roughness ?? 1.5) + 0.55,
1107
+ seed,
1108
+ sketchColor: ink,
1109
+ fill: ink,
1110
+ fillStyle: fillStyle ?? "hachure",
1111
+ bowing,
1112
+ strokeWidth: 1.1,
1113
+ inset: 1
1114
+ }
1115
+ )
1116
+ }
1117
+ ) : null
1118
+ ]
1119
+ }
1120
+ );
1121
+ }
1122
+ );
1123
+ var TooltipProvider = TooltipPrimitive.Provider;
1124
+ function Tooltip({
1125
+ content,
1126
+ children,
1127
+ side = "top",
1128
+ delayDuration = 200,
1129
+ className,
1130
+ roughness,
1131
+ seed,
1132
+ sketchColor,
1133
+ bowing,
1134
+ fillStyle,
1135
+ strokeWidth
1136
+ }) {
1137
+ const ink = sketchColor ?? SKETCH_COLORS.ink;
1138
+ return /* @__PURE__ */ jsxs(TooltipPrimitive.Root, { delayDuration, children: [
1139
+ /* @__PURE__ */ jsx(TooltipPrimitive.Trigger, { asChild: true, children }),
1140
+ /* @__PURE__ */ jsx(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsx(
1141
+ TooltipPrimitive.Content,
1142
+ {
1143
+ side,
1144
+ sideOffset: 8,
1145
+ className: cn(className),
1146
+ style: { zIndex: 60, outline: "none" },
1147
+ children: /* @__PURE__ */ jsx(
1148
+ SketchBox,
1149
+ {
1150
+ roughness: roughness ?? 1.3,
1151
+ seed,
1152
+ sketchColor: ink,
1153
+ bowing,
1154
+ fillStyle: fillStyle ?? "solid",
1155
+ fill: "#f7f6f2",
1156
+ strokeWidth: strokeWidth ?? 1.4,
1157
+ contentStyle: {
1158
+ padding: "6px 10px",
1159
+ fontSize: 13,
1160
+ lineHeight: 1.35,
1161
+ color: ink,
1162
+ maxWidth: 240
1163
+ },
1164
+ children: content
1165
+ }
1166
+ )
1167
+ }
1168
+ ) })
1169
+ ] });
1170
+ }
1171
+
1172
+ export { Alert, Badge, Button, Card, Checkbox, DEFAULT_BOWING, DEFAULT_INK, DEFAULT_ROUGHNESS, DEFAULT_STROKE_WIDTH, Divider, Input, Modal, ModalClose, ModalDescription, ModalRoot, ModalTitle, ModalTrigger, Progress, Radio, RadioGroup, RoughSvg, SKETCH_COLORS, SketchBox, SketchSeedProvider, Textarea, Tooltip, TooltipProvider, toRoughOptions, useResolvedSeed, useSketchSeed };
1173
+ //# sourceMappingURL=index.js.map
1174
+ //# sourceMappingURL=index.js.map