doodleui-react 0.1.1 → 0.2.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 CHANGED
@@ -1,11 +1,18 @@
1
1
  "use client";
2
- import { createContext, forwardRef, useState, useId, useRef, useLayoutEffect, useContext, useCallback, useMemo } from 'react';
2
+ import { createContext, forwardRef, useState, useId, useRef, useLayoutEffect, useContext, Children, isValidElement, cloneElement, useEffect, useCallback, useMemo } from 'react';
3
3
  import rough from 'roughjs';
4
4
  import { jsxs, jsx } from 'react/jsx-runtime';
5
5
  import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
6
6
  import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
7
7
  import * as Dialog from '@radix-ui/react-dialog';
8
8
  import * as TooltipPrimitive from '@radix-ui/react-tooltip';
9
+ import * as SelectPrimitive from '@radix-ui/react-select';
10
+ import * as SwitchPrimitive from '@radix-ui/react-switch';
11
+ import * as TabsPrimitive from '@radix-ui/react-tabs';
12
+ import * as ToastPrimitive from '@radix-ui/react-toast';
13
+ import * as AccordionPrimitive from '@radix-ui/react-accordion';
14
+ import * as AvatarPrimitive from '@radix-ui/react-avatar';
15
+ import * as SliderPrimitive from '@radix-ui/react-slider';
9
16
 
10
17
  // src/types.ts
11
18
  function toRoughOptions(props) {
@@ -60,6 +67,13 @@ function cn(...parts) {
60
67
  const value = parts.filter(Boolean).join(" ");
61
68
  return value.length > 0 ? value : void 0;
62
69
  }
70
+ function deriveSeed(base, key) {
71
+ let hash = 0;
72
+ for (let i = 0; i < key.length; i += 1) {
73
+ hash = hash * 31 + key.charCodeAt(i) | 0;
74
+ }
75
+ return (base + (hash >>> 0)) % 2 ** 31;
76
+ }
63
77
  var SketchSeedContext = createContext(null);
64
78
  function SketchSeedProvider({
65
79
  children,
@@ -1253,7 +1267,1950 @@ function Tooltip({
1253
1267
  ) })
1254
1268
  ] });
1255
1269
  }
1270
+ var CHEVRON_PATH = "M 4 6 L 10 12 L 16 6";
1271
+ var UNDERLINE_INSET = 4;
1272
+ var SelectSketchContext = createContext(
1273
+ null
1274
+ );
1275
+ function useSelectSketch() {
1276
+ const ctx = useContext(SelectSketchContext);
1277
+ if (!ctx) {
1278
+ throw new Error("Select parts must be used inside <Select>.");
1279
+ }
1280
+ return ctx;
1281
+ }
1282
+ function Select({
1283
+ options,
1284
+ placeholder = "Select\u2026",
1285
+ className,
1286
+ style,
1287
+ roughness,
1288
+ seed,
1289
+ sketchColor,
1290
+ bowing,
1291
+ fillStyle,
1292
+ strokeWidth,
1293
+ value,
1294
+ defaultValue,
1295
+ onValueChange,
1296
+ "aria-label": ariaLabel,
1297
+ ...rest
1298
+ }) {
1299
+ const [uncontrolled, setUncontrolled] = useState(defaultValue);
1300
+ const selectedValue = value ?? uncontrolled;
1301
+ const selectedLabel = options.find((option) => option.value === selectedValue)?.label;
1302
+ const resolvedSeed = useResolvedSeed(seed);
1303
+ const ink = sketchColor ?? SKETCH_COLORS.ink;
1304
+ return /* @__PURE__ */ jsx(
1305
+ SelectSketchContext.Provider,
1306
+ {
1307
+ value: {
1308
+ roughness,
1309
+ seed: resolvedSeed,
1310
+ sketchColor,
1311
+ bowing,
1312
+ fillStyle,
1313
+ strokeWidth,
1314
+ resolvedSeed,
1315
+ ink,
1316
+ selectedValue,
1317
+ selectedLabel,
1318
+ placeholder
1319
+ },
1320
+ children: /* @__PURE__ */ jsxs(
1321
+ SelectPrimitive.Root,
1322
+ {
1323
+ value,
1324
+ defaultValue,
1325
+ onValueChange: (next) => {
1326
+ setUncontrolled(next);
1327
+ onValueChange?.(next);
1328
+ },
1329
+ ...rest,
1330
+ children: [
1331
+ /* @__PURE__ */ jsx(
1332
+ SelectTrigger,
1333
+ {
1334
+ className,
1335
+ style,
1336
+ placeholder,
1337
+ "aria-label": ariaLabel
1338
+ }
1339
+ ),
1340
+ /* @__PURE__ */ jsx(SelectContent, { children: options.map((option) => /* @__PURE__ */ jsx(
1341
+ SelectItem,
1342
+ {
1343
+ value: option.value,
1344
+ disabled: option.disabled,
1345
+ children: option.label
1346
+ },
1347
+ option.value
1348
+ )) })
1349
+ ]
1350
+ }
1351
+ )
1352
+ }
1353
+ );
1354
+ }
1355
+ var SelectTrigger = forwardRef(
1356
+ function SelectTrigger2({ className, style, placeholder, children, ...rest }, ref) {
1357
+ const sketch = useSelectSketch();
1358
+ const [openish, setOpenish] = useState(false);
1359
+ return /* @__PURE__ */ jsxs(
1360
+ SelectPrimitive.Trigger,
1361
+ {
1362
+ ref,
1363
+ className: cn(className),
1364
+ onPointerDown: () => setOpenish(true),
1365
+ onBlur: () => setOpenish(false),
1366
+ style: {
1367
+ position: "relative",
1368
+ display: "inline-flex",
1369
+ alignItems: "center",
1370
+ justifyContent: "space-between",
1371
+ gap: 12,
1372
+ minWidth: 180,
1373
+ minHeight: 38,
1374
+ padding: "8px 12px",
1375
+ border: "none",
1376
+ background: "transparent",
1377
+ cursor: "pointer",
1378
+ color: sketch.ink,
1379
+ fontFamily: doodleUiFontFamily,
1380
+ fontSize: 15,
1381
+ lineHeight: 1.2,
1382
+ outline: "none",
1383
+ textAlign: "left",
1384
+ ...style
1385
+ },
1386
+ ...rest,
1387
+ children: [
1388
+ /* @__PURE__ */ jsx(
1389
+ RoughSvg,
1390
+ {
1391
+ shape: "rectangle",
1392
+ roughness: sketch.roughness,
1393
+ seed: sketch.resolvedSeed,
1394
+ sketchColor: openish ? SKETCH_COLORS.accent : sketch.ink,
1395
+ bowing: sketch.bowing,
1396
+ fillStyle: sketch.fillStyle,
1397
+ strokeWidth: openish ? (sketch.strokeWidth ?? 1.75) + 0.35 : sketch.strokeWidth
1398
+ }
1399
+ ),
1400
+ /* @__PURE__ */ jsx(
1401
+ "span",
1402
+ {
1403
+ style: {
1404
+ position: "relative",
1405
+ zIndex: 1,
1406
+ flex: 1,
1407
+ overflow: "hidden",
1408
+ textOverflow: "ellipsis",
1409
+ whiteSpace: "nowrap"
1410
+ },
1411
+ children: children ?? sketch.selectedLabel ?? placeholder
1412
+ }
1413
+ ),
1414
+ /* @__PURE__ */ jsx(
1415
+ SelectPrimitive.Icon,
1416
+ {
1417
+ style: {
1418
+ position: "relative",
1419
+ zIndex: 1,
1420
+ width: 18,
1421
+ height: 18,
1422
+ flexShrink: 0
1423
+ },
1424
+ children: /* @__PURE__ */ jsx(
1425
+ RoughSvg,
1426
+ {
1427
+ shape: "path",
1428
+ path: CHEVRON_PATH,
1429
+ roughness: (sketch.roughness ?? 1.5) * 0.7,
1430
+ seed: sketch.resolvedSeed,
1431
+ sketchColor: sketch.ink,
1432
+ bowing: sketch.bowing,
1433
+ strokeWidth: (sketch.strokeWidth ?? 1.6) + 0.2,
1434
+ inset: 0
1435
+ }
1436
+ )
1437
+ }
1438
+ )
1439
+ ]
1440
+ }
1441
+ );
1442
+ }
1443
+ );
1444
+ var SelectContent = forwardRef(
1445
+ function SelectContent2({ className, style, children, ...rest }, ref) {
1446
+ const sketch = useSelectSketch();
1447
+ return /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsx(
1448
+ SelectPrimitive.Content,
1449
+ {
1450
+ ref,
1451
+ position: "popper",
1452
+ sideOffset: 6,
1453
+ className: cn(className),
1454
+ style: {
1455
+ zIndex: 80,
1456
+ outline: "none",
1457
+ minWidth: "var(--radix-select-trigger-width)",
1458
+ ...style
1459
+ },
1460
+ ...rest,
1461
+ children: /* @__PURE__ */ jsx(
1462
+ SketchBox,
1463
+ {
1464
+ roughness: sketch.roughness,
1465
+ seed: sketch.resolvedSeed,
1466
+ sketchColor: sketch.ink,
1467
+ bowing: sketch.bowing,
1468
+ fillStyle: sketch.fillStyle ?? "solid",
1469
+ fill: "#f7f6f2",
1470
+ strokeWidth: sketch.strokeWidth ?? 1.5,
1471
+ contentStyle: { padding: "6px 4px" },
1472
+ children: /* @__PURE__ */ jsx(SelectPrimitive.Viewport, { children })
1473
+ }
1474
+ )
1475
+ }
1476
+ ) });
1477
+ }
1478
+ );
1479
+ var SelectItem = forwardRef(
1480
+ function SelectItem2({ className, style, children, value, ...rest }, ref) {
1481
+ const sketch = useSelectSketch();
1482
+ const [highlighted, setHighlighted] = useState(false);
1483
+ const selected = sketch.selectedValue === value;
1484
+ const mark = highlighted || selected;
1485
+ return /* @__PURE__ */ jsxs(
1486
+ SelectPrimitive.Item,
1487
+ {
1488
+ ref,
1489
+ value,
1490
+ className: cn(className),
1491
+ onPointerMove: () => setHighlighted(true),
1492
+ onPointerLeave: () => setHighlighted(false),
1493
+ onFocus: () => setHighlighted(true),
1494
+ onBlur: () => setHighlighted(false),
1495
+ style: {
1496
+ position: "relative",
1497
+ display: "flex",
1498
+ alignItems: "center",
1499
+ padding: "7px 12px",
1500
+ fontFamily: doodleUiFontFamily,
1501
+ fontSize: 14,
1502
+ color: sketch.ink,
1503
+ outline: "none",
1504
+ cursor: "pointer",
1505
+ userSelect: "none",
1506
+ fontWeight: selected ? doodleUiFontWeight(650) : doodleUiFontWeight(400),
1507
+ ...style
1508
+ },
1509
+ ...rest,
1510
+ children: [
1511
+ mark ? /* @__PURE__ */ jsx(
1512
+ RoughSvg,
1513
+ {
1514
+ shape: "line",
1515
+ roughness: (sketch.roughness ?? 1.5) + 0.4,
1516
+ seed: sketch.resolvedSeed,
1517
+ sketchColor: selected ? SKETCH_COLORS.accent : sketch.ink,
1518
+ bowing: sketch.bowing ?? 1.6,
1519
+ strokeWidth: selected ? 1.8 : 1.3,
1520
+ inset: UNDERLINE_INSET,
1521
+ style: { opacity: selected ? 0.9 : 0.45 }
1522
+ }
1523
+ ) : null,
1524
+ /* @__PURE__ */ jsx(
1525
+ SelectPrimitive.ItemText,
1526
+ {
1527
+ style: { position: "relative", zIndex: 1 },
1528
+ children
1529
+ }
1530
+ )
1531
+ ]
1532
+ }
1533
+ );
1534
+ }
1535
+ );
1536
+ var SelectRoot = SelectPrimitive.Root;
1537
+ var SelectValue = SelectPrimitive.Value;
1538
+ var SelectGroup = SelectPrimitive.Group;
1539
+ var SelectLabel = SelectPrimitive.Label;
1540
+ var SelectSeparator = SelectPrimitive.Separator;
1541
+ var TRACK_W = 44;
1542
+ var TRACK_H = 24;
1543
+ var THUMB = 18;
1544
+ var THUMB_OFF = 3;
1545
+ var THUMB_ON = TRACK_W - THUMB - 3;
1546
+ var Switch = forwardRef(
1547
+ function Switch2({
1548
+ className,
1549
+ style,
1550
+ label,
1551
+ roughness,
1552
+ seed,
1553
+ sketchColor,
1554
+ bowing,
1555
+ fillStyle,
1556
+ strokeWidth,
1557
+ checked,
1558
+ defaultChecked,
1559
+ onCheckedChange,
1560
+ id,
1561
+ ...rest
1562
+ }, ref) {
1563
+ const [uncontrolled, setUncontrolled] = useState(defaultChecked === true);
1564
+ const isOn = checked ?? uncontrolled;
1565
+ const ink = sketchColor ?? SKETCH_COLORS.ink;
1566
+ const resolvedSeed = useResolvedSeed(seed);
1567
+ return /* @__PURE__ */ jsxs(
1568
+ "span",
1569
+ {
1570
+ className: cn(className),
1571
+ style: {
1572
+ display: "inline-flex",
1573
+ alignItems: "center",
1574
+ gap: 8,
1575
+ cursor: "pointer",
1576
+ userSelect: "none",
1577
+ ...style
1578
+ },
1579
+ children: [
1580
+ /* @__PURE__ */ jsxs(
1581
+ SwitchPrimitive.Root,
1582
+ {
1583
+ ref,
1584
+ id,
1585
+ checked,
1586
+ defaultChecked,
1587
+ onCheckedChange: (next) => {
1588
+ setUncontrolled(next);
1589
+ onCheckedChange?.(next);
1590
+ },
1591
+ style: {
1592
+ position: "relative",
1593
+ width: TRACK_W,
1594
+ height: TRACK_H,
1595
+ padding: 0,
1596
+ border: "none",
1597
+ background: "transparent",
1598
+ flexShrink: 0,
1599
+ cursor: "pointer",
1600
+ outline: "none"
1601
+ },
1602
+ ...rest,
1603
+ children: [
1604
+ /* @__PURE__ */ jsx(
1605
+ RoughSvg,
1606
+ {
1607
+ shape: "rectangle",
1608
+ roughness,
1609
+ seed: resolvedSeed,
1610
+ sketchColor: isOn ? SKETCH_COLORS.accent : ink,
1611
+ bowing: bowing ?? 1.4,
1612
+ fillStyle: fillStyle ?? (isOn ? "hachure" : void 0),
1613
+ fill: isOn ? SKETCH_COLORS.accentFill : void 0,
1614
+ strokeWidth: strokeWidth ?? 1.6,
1615
+ inset: 1.5
1616
+ }
1617
+ ),
1618
+ /* @__PURE__ */ jsx(
1619
+ SwitchPrimitive.Thumb,
1620
+ {
1621
+ style: {
1622
+ position: "absolute",
1623
+ top: (TRACK_H - THUMB) / 2,
1624
+ left: 0,
1625
+ width: THUMB,
1626
+ height: THUMB,
1627
+ display: "block",
1628
+ transform: `translateX(${isOn ? THUMB_ON : THUMB_OFF}px)`,
1629
+ transition: "transform 160ms ease",
1630
+ zIndex: 1
1631
+ },
1632
+ children: /* @__PURE__ */ jsx(
1633
+ RoughSvg,
1634
+ {
1635
+ shape: "ellipse",
1636
+ roughness: (roughness ?? 1.5) * 0.85,
1637
+ seed: deriveSeed(resolvedSeed, "thumb"),
1638
+ sketchColor: isOn ? SKETCH_COLORS.accent : ink,
1639
+ fill: "#f7f6f2",
1640
+ fillStyle: "solid",
1641
+ bowing,
1642
+ strokeWidth: (strokeWidth ?? 1.5) + 0.2,
1643
+ inset: 1
1644
+ }
1645
+ )
1646
+ }
1647
+ )
1648
+ ]
1649
+ }
1650
+ ),
1651
+ label ? /* @__PURE__ */ jsx(
1652
+ "label",
1653
+ {
1654
+ htmlFor: id,
1655
+ style: {
1656
+ fontSize: 15,
1657
+ cursor: "pointer",
1658
+ fontFamily: doodleUiFontFamily
1659
+ },
1660
+ children: label
1661
+ }
1662
+ ) : null
1663
+ ]
1664
+ }
1665
+ );
1666
+ }
1667
+ );
1668
+ var TabsSketchContext = createContext(null);
1669
+ function useTabsSketch() {
1670
+ const ctx = useContext(TabsSketchContext);
1671
+ if (!ctx) {
1672
+ throw new Error("Tab parts must be used inside <Tabs>.");
1673
+ }
1674
+ return ctx;
1675
+ }
1676
+ var Tabs = forwardRef(function Tabs2({
1677
+ className,
1678
+ style,
1679
+ children,
1680
+ value,
1681
+ defaultValue,
1682
+ onValueChange,
1683
+ roughness,
1684
+ seed,
1685
+ sketchColor,
1686
+ bowing,
1687
+ fillStyle,
1688
+ strokeWidth,
1689
+ ...rest
1690
+ }, ref) {
1691
+ const [uncontrolled, setUncontrolled] = useState(defaultValue);
1692
+ const current = value ?? uncontrolled;
1693
+ const resolvedSeed = useResolvedSeed(seed);
1694
+ const ink = sketchColor ?? SKETCH_COLORS.ink;
1695
+ return /* @__PURE__ */ jsx(
1696
+ TabsSketchContext.Provider,
1697
+ {
1698
+ value: {
1699
+ roughness,
1700
+ seed: resolvedSeed,
1701
+ sketchColor,
1702
+ bowing,
1703
+ fillStyle,
1704
+ strokeWidth,
1705
+ resolvedSeed,
1706
+ ink,
1707
+ current
1708
+ },
1709
+ children: /* @__PURE__ */ jsx(
1710
+ TabsPrimitive.Root,
1711
+ {
1712
+ ref,
1713
+ className: cn(className),
1714
+ style,
1715
+ value: current,
1716
+ defaultValue,
1717
+ onValueChange: (next) => {
1718
+ setUncontrolled(next);
1719
+ onValueChange?.(next);
1720
+ },
1721
+ ...rest,
1722
+ children
1723
+ }
1724
+ )
1725
+ }
1726
+ );
1727
+ });
1728
+ var TabList = forwardRef(
1729
+ function TabList2({ className, style, children, ...rest }, ref) {
1730
+ return /* @__PURE__ */ jsx(
1731
+ TabsPrimitive.List,
1732
+ {
1733
+ ref,
1734
+ className: cn(className),
1735
+ style: {
1736
+ display: "flex",
1737
+ flexWrap: "wrap",
1738
+ gap: 4,
1739
+ ...style
1740
+ },
1741
+ ...rest,
1742
+ children
1743
+ }
1744
+ );
1745
+ }
1746
+ );
1747
+ var Tab = forwardRef(function Tab2({ className, style, children, value, ...rest }, ref) {
1748
+ const sketch = useTabsSketch();
1749
+ const active = sketch.current === value;
1750
+ return /* @__PURE__ */ jsxs(
1751
+ TabsPrimitive.Trigger,
1752
+ {
1753
+ ref,
1754
+ value,
1755
+ className: cn(className),
1756
+ style: {
1757
+ position: "relative",
1758
+ border: "none",
1759
+ background: "transparent",
1760
+ cursor: "pointer",
1761
+ padding: "8px 14px 12px",
1762
+ fontFamily: doodleUiFontFamily,
1763
+ fontSize: 15,
1764
+ fontWeight: active ? doodleUiFontWeight(650) : doodleUiFontWeight(400),
1765
+ color: sketch.ink,
1766
+ outline: "none",
1767
+ ...style
1768
+ },
1769
+ ...rest,
1770
+ children: [
1771
+ /* @__PURE__ */ jsx("span", { style: { position: "relative", zIndex: 1 }, children }),
1772
+ active ? /* @__PURE__ */ jsx(
1773
+ "span",
1774
+ {
1775
+ style: {
1776
+ position: "absolute",
1777
+ left: 8,
1778
+ right: 8,
1779
+ bottom: 2,
1780
+ height: 10,
1781
+ pointerEvents: "none"
1782
+ },
1783
+ children: /* @__PURE__ */ jsx(
1784
+ RoughSvg,
1785
+ {
1786
+ shape: "line",
1787
+ roughness: (sketch.roughness ?? 1.5) + 0.35,
1788
+ seed: deriveSeed(sketch.resolvedSeed, value),
1789
+ sketchColor: SKETCH_COLORS.accent,
1790
+ bowing: sketch.bowing ?? 1.8,
1791
+ strokeWidth: (sketch.strokeWidth ?? 1.75) + 0.4,
1792
+ inset: 2
1793
+ }
1794
+ )
1795
+ }
1796
+ ) : null
1797
+ ]
1798
+ }
1799
+ );
1800
+ });
1801
+ var TabPanel = forwardRef(
1802
+ function TabPanel2({ className, style, children, ...rest }, ref) {
1803
+ const sketch = useTabsSketch();
1804
+ return /* @__PURE__ */ jsx(
1805
+ TabsPrimitive.Content,
1806
+ {
1807
+ ref,
1808
+ className: cn(className),
1809
+ style: {
1810
+ paddingTop: 14,
1811
+ fontFamily: doodleUiFontFamily,
1812
+ color: sketch.ink,
1813
+ fontSize: 15,
1814
+ lineHeight: 1.5,
1815
+ outline: "none",
1816
+ ...style
1817
+ },
1818
+ ...rest,
1819
+ children
1820
+ }
1821
+ );
1822
+ }
1823
+ );
1824
+ var TableSketchContext = createContext(null);
1825
+ function useTableSketch() {
1826
+ const ctx = useContext(TableSketchContext);
1827
+ if (!ctx) {
1828
+ throw new Error("Table parts must be used inside <Table>.");
1829
+ }
1830
+ return ctx;
1831
+ }
1832
+ var Table = forwardRef(function Table2({
1833
+ className,
1834
+ style,
1835
+ children,
1836
+ headerUnderline = true,
1837
+ roughness,
1838
+ seed,
1839
+ sketchColor,
1840
+ bowing,
1841
+ fillStyle,
1842
+ strokeWidth,
1843
+ ...rest
1844
+ }, ref) {
1845
+ const wrapperRef = useRef(null);
1846
+ const tableRef = useRef(null);
1847
+ const [lines, setLines] = useState([]);
1848
+ const resolvedSeed = useResolvedSeed(seed);
1849
+ const ink = sketchColor ?? SKETCH_COLORS.ink;
1850
+ useLayoutEffect(() => {
1851
+ const wrapper = wrapperRef.current;
1852
+ const table = tableRef.current;
1853
+ if (!wrapper || !table) return;
1854
+ const measure = () => {
1855
+ const rows = Array.from(table.querySelectorAll("tr"));
1856
+ const next = [];
1857
+ rows.forEach((row, index) => {
1858
+ const isLast = index === rows.length - 1;
1859
+ const isHeader = row.parentElement?.tagName === "THEAD";
1860
+ if (isLast && !isHeader) return;
1861
+ next.push({
1862
+ y: row.offsetTop + row.offsetHeight,
1863
+ width: table.offsetWidth,
1864
+ key: isHeader ? `header-${index}` : `row-${index}`,
1865
+ header: Boolean(isHeader)
1866
+ });
1867
+ });
1868
+ setLines(next);
1869
+ };
1870
+ measure();
1871
+ const observer = new ResizeObserver(measure);
1872
+ observer.observe(table);
1873
+ observer.observe(wrapper);
1874
+ return () => observer.disconnect();
1875
+ }, [children]);
1876
+ return /* @__PURE__ */ jsx(
1877
+ TableSketchContext.Provider,
1878
+ {
1879
+ value: {
1880
+ roughness,
1881
+ seed: resolvedSeed,
1882
+ sketchColor,
1883
+ bowing,
1884
+ fillStyle,
1885
+ strokeWidth,
1886
+ resolvedSeed,
1887
+ ink
1888
+ },
1889
+ children: /* @__PURE__ */ jsxs(
1890
+ "div",
1891
+ {
1892
+ ref: wrapperRef,
1893
+ className: cn(className),
1894
+ style: { position: "relative", width: "100%", ...style },
1895
+ children: [
1896
+ /* @__PURE__ */ jsx(
1897
+ "div",
1898
+ {
1899
+ "aria-hidden": "true",
1900
+ style: {
1901
+ position: "absolute",
1902
+ inset: 0,
1903
+ pointerEvents: "none",
1904
+ zIndex: 1,
1905
+ overflow: "visible"
1906
+ },
1907
+ children: lines.map((line) => {
1908
+ if (line.header && !headerUnderline) return null;
1909
+ return /* @__PURE__ */ jsx(
1910
+ "div",
1911
+ {
1912
+ style: {
1913
+ position: "absolute",
1914
+ left: 0,
1915
+ width: line.width,
1916
+ top: line.y - 6,
1917
+ height: 12
1918
+ },
1919
+ children: /* @__PURE__ */ jsx(
1920
+ RoughSvg,
1921
+ {
1922
+ shape: "line",
1923
+ roughness: line.header ? (roughness ?? 1.5) + 0.2 : roughness ?? 1.7,
1924
+ seed: deriveSeed(resolvedSeed, line.key),
1925
+ sketchColor: ink,
1926
+ bowing: bowing ?? (line.header ? 1.4 : 2),
1927
+ strokeWidth: line.header ? (strokeWidth ?? 1.75) + 0.35 : strokeWidth ?? 1.35,
1928
+ inset: 6
1929
+ }
1930
+ )
1931
+ },
1932
+ line.key
1933
+ );
1934
+ })
1935
+ }
1936
+ ),
1937
+ /* @__PURE__ */ jsx(
1938
+ "table",
1939
+ {
1940
+ ref: (node) => {
1941
+ tableRef.current = node;
1942
+ if (typeof ref === "function") ref(node);
1943
+ else if (ref) ref.current = node;
1944
+ },
1945
+ style: {
1946
+ width: "100%",
1947
+ borderCollapse: "collapse",
1948
+ position: "relative",
1949
+ zIndex: 0,
1950
+ fontFamily: doodleUiFontFamily,
1951
+ color: ink
1952
+ },
1953
+ ...rest,
1954
+ children
1955
+ }
1956
+ )
1957
+ ]
1958
+ }
1959
+ )
1960
+ }
1961
+ );
1962
+ });
1963
+ var TableHead = forwardRef(function TableHead2({ className, style, ...rest }, ref) {
1964
+ return /* @__PURE__ */ jsx(
1965
+ "thead",
1966
+ {
1967
+ ref,
1968
+ className: cn(className),
1969
+ style,
1970
+ ...rest
1971
+ }
1972
+ );
1973
+ });
1974
+ var TableBody = forwardRef(function TableBody2({ className, style, ...rest }, ref) {
1975
+ return /* @__PURE__ */ jsx(
1976
+ "tbody",
1977
+ {
1978
+ ref,
1979
+ className: cn(className),
1980
+ style,
1981
+ ...rest
1982
+ }
1983
+ );
1984
+ });
1985
+ var TableRow = forwardRef(function TableRow2({ className, style, ...rest }, ref) {
1986
+ return /* @__PURE__ */ jsx(
1987
+ "tr",
1988
+ {
1989
+ ref,
1990
+ className: cn(className),
1991
+ style,
1992
+ ...rest
1993
+ }
1994
+ );
1995
+ });
1996
+ var TableHeaderCell = forwardRef(function TableHeaderCell2({ className, style, children, ...rest }, ref) {
1997
+ useTableSketch();
1998
+ return /* @__PURE__ */ jsx(
1999
+ "th",
2000
+ {
2001
+ ref,
2002
+ className: cn(className),
2003
+ style: {
2004
+ textAlign: "left",
2005
+ fontWeight: doodleUiFontWeight(650),
2006
+ fontSize: 13,
2007
+ padding: "10px 12px",
2008
+ ...style
2009
+ },
2010
+ ...rest,
2011
+ children
2012
+ }
2013
+ );
2014
+ });
2015
+ var TableCell = forwardRef(
2016
+ function TableCell2({ className, style, children, ...rest }, ref) {
2017
+ useTableSketch();
2018
+ return /* @__PURE__ */ jsx(
2019
+ "td",
2020
+ {
2021
+ ref,
2022
+ className: cn(className),
2023
+ style: {
2024
+ fontSize: 14,
2025
+ padding: "10px 12px",
2026
+ ...style
2027
+ },
2028
+ ...rest,
2029
+ children
2030
+ }
2031
+ );
2032
+ }
2033
+ );
2034
+ var VARIANT_COLOR2 = {
2035
+ info: SKETCH_COLORS.info,
2036
+ warning: SKETCH_COLORS.warning,
2037
+ error: SKETCH_COLORS.error,
2038
+ success: SKETCH_COLORS.success
2039
+ };
2040
+ var VARIANT_FILL2 = {
2041
+ info: "#d2deec",
2042
+ warning: "#f3e2c0",
2043
+ error: "#f3d0cc",
2044
+ success: "#d3e8dc"
2045
+ };
2046
+ var POSITION_STYLE = {
2047
+ "top-left": { top: 16, left: 16 },
2048
+ "top-right": { top: 16, right: 16 },
2049
+ "bottom-left": { bottom: 16, left: 16 },
2050
+ "bottom-right": { bottom: 16, right: 16 }
2051
+ };
2052
+ var ToastPositionContext = createContext("bottom-right");
2053
+ function ToastProvider({
2054
+ children,
2055
+ position = "bottom-right",
2056
+ duration = 4e3,
2057
+ swipeDirection = "right",
2058
+ label
2059
+ }) {
2060
+ return /* @__PURE__ */ jsx(ToastPositionContext.Provider, { value: position, children: /* @__PURE__ */ jsxs(
2061
+ ToastPrimitive.Provider,
2062
+ {
2063
+ duration,
2064
+ swipeDirection,
2065
+ label,
2066
+ children: [
2067
+ children,
2068
+ /* @__PURE__ */ jsx(
2069
+ ToastPrimitive.Viewport,
2070
+ {
2071
+ style: {
2072
+ position: "fixed",
2073
+ zIndex: 90,
2074
+ display: "flex",
2075
+ flexDirection: "column",
2076
+ gap: 10,
2077
+ width: "min(360px, calc(100vw - 32px))",
2078
+ margin: 0,
2079
+ padding: 0,
2080
+ listStyle: "none",
2081
+ outline: "none",
2082
+ ...POSITION_STYLE[position]
2083
+ }
2084
+ }
2085
+ )
2086
+ ]
2087
+ }
2088
+ ) });
2089
+ }
2090
+ function Toast({
2091
+ open,
2092
+ defaultOpen,
2093
+ onOpenChange,
2094
+ title,
2095
+ children,
2096
+ variant = "info",
2097
+ duration,
2098
+ className,
2099
+ style,
2100
+ roughness,
2101
+ seed,
2102
+ sketchColor,
2103
+ bowing,
2104
+ fillStyle,
2105
+ strokeWidth
2106
+ }) {
2107
+ const position = useContext(ToastPositionContext);
2108
+ const fromTop = position.startsWith("top");
2109
+ const [entered, setEntered] = useState(false);
2110
+ const color = sketchColor ?? VARIANT_COLOR2[variant];
2111
+ const visible = open ?? true;
2112
+ useLayoutEffect(() => {
2113
+ if (!visible) {
2114
+ setEntered(false);
2115
+ return;
2116
+ }
2117
+ setEntered(false);
2118
+ const frame = requestAnimationFrame(() => {
2119
+ requestAnimationFrame(() => setEntered(true));
2120
+ });
2121
+ return () => cancelAnimationFrame(frame);
2122
+ }, [visible]);
2123
+ return /* @__PURE__ */ jsx(
2124
+ ToastPrimitive.Root,
2125
+ {
2126
+ open,
2127
+ defaultOpen,
2128
+ onOpenChange,
2129
+ duration,
2130
+ className: cn(className),
2131
+ style: {
2132
+ transform: entered ? "translateY(0)" : `translateY(${fromTop ? "-10px" : "10px"})`,
2133
+ opacity: entered ? 1 : 0,
2134
+ transition: "transform 200ms ease, opacity 200ms ease",
2135
+ outline: "none",
2136
+ ...style
2137
+ },
2138
+ children: /* @__PURE__ */ jsxs(
2139
+ SketchBox,
2140
+ {
2141
+ roughness,
2142
+ seed,
2143
+ sketchColor: color,
2144
+ bowing,
2145
+ fillStyle: fillStyle ?? "hachure",
2146
+ fill: VARIANT_FILL2[variant],
2147
+ strokeWidth: strokeWidth ?? 1.7,
2148
+ shadow: true,
2149
+ contentStyle: { padding: "12px 16px" },
2150
+ children: [
2151
+ title ? /* @__PURE__ */ jsx(
2152
+ ToastPrimitive.Title,
2153
+ {
2154
+ style: {
2155
+ margin: 0,
2156
+ fontWeight: doodleUiFontWeight(700),
2157
+ fontSize: 15,
2158
+ fontFamily: doodleUiFontFamily,
2159
+ color,
2160
+ marginBottom: children ? 4 : 0
2161
+ },
2162
+ children: title
2163
+ }
2164
+ ) : null,
2165
+ children ? /* @__PURE__ */ jsx(
2166
+ ToastPrimitive.Description,
2167
+ {
2168
+ style: {
2169
+ margin: 0,
2170
+ fontSize: 14,
2171
+ lineHeight: 1.5,
2172
+ fontFamily: doodleUiFontFamily,
2173
+ color: SKETCH_COLORS.ink
2174
+ },
2175
+ children
2176
+ }
2177
+ ) : null
2178
+ ]
2179
+ }
2180
+ )
2181
+ }
2182
+ );
2183
+ }
2184
+ var ToastRoot = ToastPrimitive.Root;
2185
+ var ToastTitle = ToastPrimitive.Title;
2186
+ var ToastDescription = ToastPrimitive.Description;
2187
+ var ToastClose = ToastPrimitive.Close;
2188
+ var ToastAction = ToastPrimitive.Action;
2189
+ var ToastViewport = ToastPrimitive.Viewport;
2190
+ var CHEVRON_PATH2 = "M 6 4 L 12 10 L 6 16";
2191
+ var AccordionSketchContext = createContext(null);
2192
+ function useAccordionSketch() {
2193
+ const ctx = useContext(AccordionSketchContext);
2194
+ if (!ctx) {
2195
+ throw new Error("Accordion parts must be used inside <Accordion>.");
2196
+ }
2197
+ return ctx;
2198
+ }
2199
+ var AccordionItemContext = createContext("");
2200
+ var Accordion = forwardRef(
2201
+ function Accordion2({
2202
+ className,
2203
+ style,
2204
+ children,
2205
+ type = "single",
2206
+ collapsible = true,
2207
+ value,
2208
+ defaultValue,
2209
+ onValueChange,
2210
+ disabled,
2211
+ roughness,
2212
+ seed,
2213
+ sketchColor,
2214
+ bowing,
2215
+ fillStyle,
2216
+ strokeWidth
2217
+ }, ref) {
2218
+ const resolvedSeed = useResolvedSeed(seed);
2219
+ const ink = sketchColor ?? SKETCH_COLORS.ink;
2220
+ const [uncontrolled, setUncontrolled] = useState(defaultValue ?? (type === "multiple" ? [] : void 0));
2221
+ const openValue = value ?? uncontrolled;
2222
+ const sketchValue = {
2223
+ roughness,
2224
+ seed: resolvedSeed,
2225
+ sketchColor,
2226
+ bowing,
2227
+ fillStyle,
2228
+ strokeWidth,
2229
+ resolvedSeed,
2230
+ ink,
2231
+ openValue
2232
+ };
2233
+ function handleChange(next) {
2234
+ setUncontrolled(next);
2235
+ onValueChange?.(next);
2236
+ }
2237
+ const root = type === "multiple" ? /* @__PURE__ */ jsx(
2238
+ AccordionPrimitive.Root,
2239
+ {
2240
+ ref,
2241
+ type: "multiple",
2242
+ disabled,
2243
+ className: cn(className),
2244
+ style,
2245
+ value: openValue,
2246
+ defaultValue,
2247
+ onValueChange: handleChange,
2248
+ children
2249
+ }
2250
+ ) : /* @__PURE__ */ jsx(
2251
+ AccordionPrimitive.Root,
2252
+ {
2253
+ ref,
2254
+ type: "single",
2255
+ collapsible,
2256
+ disabled,
2257
+ className: cn(className),
2258
+ style,
2259
+ value: openValue,
2260
+ defaultValue,
2261
+ onValueChange: handleChange,
2262
+ children
2263
+ }
2264
+ );
2265
+ return /* @__PURE__ */ jsx(AccordionSketchContext.Provider, { value: sketchValue, children: root });
2266
+ }
2267
+ );
2268
+ var AccordionItem = forwardRef(
2269
+ function AccordionItem2({ className, style, children, value, ...rest }, ref) {
2270
+ const sketch = useAccordionSketch();
2271
+ return /* @__PURE__ */ jsx(AccordionItemContext.Provider, { value, children: /* @__PURE__ */ jsxs(
2272
+ AccordionPrimitive.Item,
2273
+ {
2274
+ ref,
2275
+ value,
2276
+ className: cn(className),
2277
+ style: { position: "relative", ...style },
2278
+ ...rest,
2279
+ children: [
2280
+ /* @__PURE__ */ jsx(
2281
+ "div",
2282
+ {
2283
+ style: {
2284
+ position: "absolute",
2285
+ left: 0,
2286
+ right: 0,
2287
+ top: -6,
2288
+ height: 12,
2289
+ pointerEvents: "none"
2290
+ },
2291
+ children: /* @__PURE__ */ jsx(
2292
+ RoughSvg,
2293
+ {
2294
+ shape: "line",
2295
+ roughness: (sketch.roughness ?? 1.5) + 0.25,
2296
+ seed: deriveSeed(sketch.resolvedSeed, `div-${value}`),
2297
+ sketchColor: sketch.ink,
2298
+ bowing: sketch.bowing ?? 1.8,
2299
+ strokeWidth: sketch.strokeWidth ?? 1.4,
2300
+ inset: 2
2301
+ }
2302
+ )
2303
+ }
2304
+ ),
2305
+ children
2306
+ ]
2307
+ }
2308
+ ) });
2309
+ }
2310
+ );
2311
+ var AccordionTrigger = forwardRef(function AccordionTrigger2({ className, style, children, ...rest }, ref) {
2312
+ const sketch = useAccordionSketch();
2313
+ const itemValue = useContext(AccordionItemContext);
2314
+ const open = Array.isArray(sketch.openValue) ? sketch.openValue.includes(itemValue) : sketch.openValue === itemValue;
2315
+ return /* @__PURE__ */ jsx(AccordionPrimitive.Header, { asChild: true, children: /* @__PURE__ */ jsx("h3", { style: { margin: 0 }, children: /* @__PURE__ */ jsxs(
2316
+ AccordionPrimitive.Trigger,
2317
+ {
2318
+ ref,
2319
+ className: cn(className),
2320
+ style: {
2321
+ display: "flex",
2322
+ width: "100%",
2323
+ alignItems: "center",
2324
+ justifyContent: "space-between",
2325
+ gap: 12,
2326
+ padding: "12px 4px",
2327
+ border: "none",
2328
+ background: "transparent",
2329
+ cursor: "pointer",
2330
+ fontFamily: doodleUiFontFamily,
2331
+ fontSize: 15,
2332
+ fontWeight: doodleUiFontWeight(600),
2333
+ color: sketch.ink,
2334
+ textAlign: "left",
2335
+ outline: "none",
2336
+ ...style
2337
+ },
2338
+ ...rest,
2339
+ children: [
2340
+ /* @__PURE__ */ jsx("span", { children }),
2341
+ /* @__PURE__ */ jsx(
2342
+ "span",
2343
+ {
2344
+ style: {
2345
+ position: "relative",
2346
+ width: 18,
2347
+ height: 18,
2348
+ flexShrink: 0,
2349
+ transform: open ? "rotate(90deg)" : "rotate(0deg)",
2350
+ transition: "transform 180ms ease"
2351
+ },
2352
+ children: /* @__PURE__ */ jsx(
2353
+ RoughSvg,
2354
+ {
2355
+ shape: "path",
2356
+ path: CHEVRON_PATH2,
2357
+ roughness: (sketch.roughness ?? 1.5) * 0.7,
2358
+ seed: deriveSeed(sketch.resolvedSeed, `chevron-${itemValue}`),
2359
+ sketchColor: sketch.ink,
2360
+ bowing: sketch.bowing,
2361
+ strokeWidth: (sketch.strokeWidth ?? 1.6) + 0.2,
2362
+ inset: 0
2363
+ }
2364
+ )
2365
+ }
2366
+ )
2367
+ ]
2368
+ }
2369
+ ) }) });
2370
+ });
2371
+ var AccordionContent = forwardRef(function AccordionContent2({ className, style, children, ...rest }, ref) {
2372
+ const sketch = useAccordionSketch();
2373
+ return /* @__PURE__ */ jsx(
2374
+ AccordionPrimitive.Content,
2375
+ {
2376
+ ref,
2377
+ className: cn(className),
2378
+ style: {
2379
+ padding: "0 4px 14px",
2380
+ fontFamily: doodleUiFontFamily,
2381
+ fontSize: 14,
2382
+ lineHeight: 1.5,
2383
+ color: sketch.ink,
2384
+ ...style
2385
+ },
2386
+ ...rest,
2387
+ children
2388
+ }
2389
+ );
2390
+ });
2391
+ var STATUS_COLOR = {
2392
+ online: SKETCH_COLORS.success,
2393
+ offline: "#8a8680",
2394
+ busy: SKETCH_COLORS.accent
2395
+ };
2396
+ var Avatar = forwardRef(
2397
+ function Avatar2({
2398
+ className,
2399
+ style,
2400
+ src,
2401
+ alt,
2402
+ fallback,
2403
+ size = 40,
2404
+ shape = "circle",
2405
+ status,
2406
+ roughness,
2407
+ seed,
2408
+ sketchColor,
2409
+ bowing,
2410
+ fillStyle,
2411
+ strokeWidth,
2412
+ ...rest
2413
+ }, ref) {
2414
+ const ink = sketchColor ?? SKETCH_COLORS.ink;
2415
+ const resolvedSeed = useResolvedSeed(seed);
2416
+ const roughShape = shape === "circle" ? "ellipse" : "rectangle";
2417
+ const badge = 12;
2418
+ const rootStyle = {
2419
+ position: "relative",
2420
+ display: "inline-flex",
2421
+ width: size,
2422
+ height: size,
2423
+ flexShrink: 0,
2424
+ verticalAlign: "middle",
2425
+ ...style
2426
+ };
2427
+ return /* @__PURE__ */ jsxs(
2428
+ AvatarPrimitive.Root,
2429
+ {
2430
+ ref,
2431
+ className: cn(className),
2432
+ style: rootStyle,
2433
+ ...rest,
2434
+ children: [
2435
+ /* @__PURE__ */ jsx(
2436
+ RoughSvg,
2437
+ {
2438
+ shape: roughShape,
2439
+ roughness,
2440
+ seed: resolvedSeed,
2441
+ sketchColor: ink,
2442
+ bowing,
2443
+ fillStyle: fillStyle ?? "solid",
2444
+ fill: "#f7f6f2",
2445
+ strokeWidth: strokeWidth ?? 1.6,
2446
+ inset: 1.5
2447
+ }
2448
+ ),
2449
+ /* @__PURE__ */ jsxs(
2450
+ "span",
2451
+ {
2452
+ style: {
2453
+ position: "absolute",
2454
+ inset: 4,
2455
+ overflow: "hidden",
2456
+ borderRadius: shape === "circle" ? "50%" : 4,
2457
+ zIndex: 1,
2458
+ display: "flex",
2459
+ alignItems: "center",
2460
+ justifyContent: "center"
2461
+ },
2462
+ children: [
2463
+ src ? /* @__PURE__ */ jsx(
2464
+ AvatarPrimitive.Image,
2465
+ {
2466
+ src,
2467
+ alt,
2468
+ style: {
2469
+ width: "100%",
2470
+ height: "100%",
2471
+ objectFit: "cover"
2472
+ }
2473
+ }
2474
+ ) : null,
2475
+ /* @__PURE__ */ jsx(
2476
+ AvatarPrimitive.Fallback,
2477
+ {
2478
+ delayMs: src ? 400 : 0,
2479
+ style: {
2480
+ width: "100%",
2481
+ height: "100%",
2482
+ display: "flex",
2483
+ alignItems: "center",
2484
+ justifyContent: "center",
2485
+ fontFamily: doodleUiFontFamily,
2486
+ fontWeight: doodleUiFontWeight(650),
2487
+ fontSize: Math.max(12, size * 0.36),
2488
+ color: ink,
2489
+ background: SKETCH_COLORS.secondaryFill
2490
+ },
2491
+ children: fallback
2492
+ }
2493
+ )
2494
+ ]
2495
+ }
2496
+ ),
2497
+ status ? /* @__PURE__ */ jsx(
2498
+ "span",
2499
+ {
2500
+ style: {
2501
+ position: "absolute",
2502
+ width: badge,
2503
+ height: badge,
2504
+ right: -1,
2505
+ bottom: -1,
2506
+ zIndex: 2
2507
+ },
2508
+ children: /* @__PURE__ */ jsx(
2509
+ RoughSvg,
2510
+ {
2511
+ shape: "ellipse",
2512
+ roughness: (roughness ?? 1.5) * 0.8,
2513
+ seed: deriveSeed(resolvedSeed, "status"),
2514
+ sketchColor: STATUS_COLOR[status],
2515
+ fill: STATUS_COLOR[status],
2516
+ fillStyle: "solid",
2517
+ bowing,
2518
+ strokeWidth: 1,
2519
+ inset: 0.5
2520
+ }
2521
+ )
2522
+ }
2523
+ ) : null
2524
+ ]
2525
+ }
2526
+ );
2527
+ }
2528
+ );
2529
+ var Slider = forwardRef(function Slider2({
2530
+ className,
2531
+ style,
2532
+ roughness,
2533
+ seed,
2534
+ sketchColor,
2535
+ bowing,
2536
+ fillStyle,
2537
+ strokeWidth,
2538
+ thumbShape = "circle",
2539
+ ...rest
2540
+ }, ref) {
2541
+ const ink = sketchColor ?? SKETCH_COLORS.ink;
2542
+ const resolvedSeed = useResolvedSeed(seed);
2543
+ return /* @__PURE__ */ jsxs(
2544
+ SliderPrimitive.Root,
2545
+ {
2546
+ ref,
2547
+ className: cn(className),
2548
+ style: {
2549
+ position: "relative",
2550
+ display: "flex",
2551
+ alignItems: "center",
2552
+ width: "100%",
2553
+ height: 28,
2554
+ userSelect: "none",
2555
+ touchAction: "none",
2556
+ ...style
2557
+ },
2558
+ ...rest,
2559
+ children: [
2560
+ /* @__PURE__ */ jsxs(
2561
+ SliderPrimitive.Track,
2562
+ {
2563
+ style: {
2564
+ position: "relative",
2565
+ flex: 1,
2566
+ height: 16
2567
+ },
2568
+ children: [
2569
+ /* @__PURE__ */ jsx(
2570
+ RoughSvg,
2571
+ {
2572
+ shape: "line",
2573
+ roughness: roughness ?? 1.8,
2574
+ seed: resolvedSeed,
2575
+ sketchColor: ink,
2576
+ bowing: bowing ?? 2,
2577
+ strokeWidth: strokeWidth ?? 1.6,
2578
+ inset: 4
2579
+ }
2580
+ ),
2581
+ /* @__PURE__ */ jsx(
2582
+ SliderPrimitive.Range,
2583
+ {
2584
+ style: {
2585
+ position: "absolute",
2586
+ left: 0,
2587
+ height: "100%"
2588
+ },
2589
+ children: /* @__PURE__ */ jsx(
2590
+ RoughSvg,
2591
+ {
2592
+ shape: "line",
2593
+ roughness: (roughness ?? 1.5) + 0.4,
2594
+ seed: deriveSeed(resolvedSeed, "range"),
2595
+ sketchColor: SKETCH_COLORS.accent,
2596
+ bowing: bowing ?? 1.6,
2597
+ strokeWidth: (strokeWidth ?? 1.6) + 0.6,
2598
+ inset: 4
2599
+ }
2600
+ )
2601
+ }
2602
+ )
2603
+ ]
2604
+ }
2605
+ ),
2606
+ /* @__PURE__ */ jsx(
2607
+ SliderPrimitive.Thumb,
2608
+ {
2609
+ style: {
2610
+ display: "block",
2611
+ width: 20,
2612
+ height: 20,
2613
+ position: "relative",
2614
+ outline: "none",
2615
+ cursor: "grab"
2616
+ },
2617
+ children: /* @__PURE__ */ jsx(
2618
+ RoughSvg,
2619
+ {
2620
+ shape: thumbShape === "square" ? "rectangle" : "ellipse",
2621
+ roughness: (roughness ?? 1.5) * 0.85,
2622
+ seed: deriveSeed(resolvedSeed, "thumb"),
2623
+ sketchColor: SKETCH_COLORS.accent,
2624
+ fill: "#f7f6f2",
2625
+ fillStyle: fillStyle ?? "solid",
2626
+ bowing,
2627
+ strokeWidth: (strokeWidth ?? 1.5) + 0.3,
2628
+ inset: 1
2629
+ }
2630
+ )
2631
+ }
2632
+ )
2633
+ ]
2634
+ }
2635
+ );
2636
+ });
2637
+ var PREV_PATH = "M 12 4 L 6 10 L 12 16";
2638
+ var NEXT_PATH = "M 6 4 L 12 10 L 6 16";
2639
+ function pageItems(page, count) {
2640
+ if (count <= 7) {
2641
+ return Array.from({ length: count }, (_, i) => i + 1);
2642
+ }
2643
+ const items = [1];
2644
+ const start = Math.max(2, page - 1);
2645
+ const end = Math.min(count - 1, page + 1);
2646
+ if (start > 2) items.push("ellipsis");
2647
+ for (let n = start; n <= end; n += 1) items.push(n);
2648
+ if (end < count - 1) items.push("ellipsis");
2649
+ items.push(count);
2650
+ return items;
2651
+ }
2652
+ var Pagination = forwardRef(
2653
+ function Pagination2({
2654
+ className,
2655
+ style,
2656
+ page,
2657
+ count,
2658
+ onPageChange,
2659
+ roughness,
2660
+ seed,
2661
+ sketchColor,
2662
+ bowing,
2663
+ strokeWidth,
2664
+ ...rest
2665
+ }, ref) {
2666
+ const ink = sketchColor ?? SKETCH_COLORS.ink;
2667
+ const resolvedSeed = useResolvedSeed(seed);
2668
+ const items = pageItems(page, count);
2669
+ return /* @__PURE__ */ jsxs(
2670
+ "nav",
2671
+ {
2672
+ ref,
2673
+ className: cn(className),
2674
+ "aria-label": "Pagination",
2675
+ style: {
2676
+ display: "inline-flex",
2677
+ alignItems: "center",
2678
+ gap: 4,
2679
+ ...style
2680
+ },
2681
+ ...rest,
2682
+ children: [
2683
+ /* @__PURE__ */ jsx(
2684
+ PageButton,
2685
+ {
2686
+ "aria-label": "Previous page",
2687
+ disabled: page <= 1,
2688
+ onClick: () => onPageChange?.(Math.max(1, page - 1)),
2689
+ roughness,
2690
+ seed: deriveSeed(resolvedSeed, "prev"),
2691
+ ink,
2692
+ bowing,
2693
+ strokeWidth,
2694
+ children: /* @__PURE__ */ jsx("span", { style: { position: "relative", width: 16, height: 16, display: "block" }, children: /* @__PURE__ */ jsx(
2695
+ RoughSvg,
2696
+ {
2697
+ shape: "path",
2698
+ path: PREV_PATH,
2699
+ roughness: (roughness ?? 1.5) * 0.7,
2700
+ seed: deriveSeed(resolvedSeed, "prev-arrow"),
2701
+ sketchColor: ink,
2702
+ strokeWidth: (strokeWidth ?? 1.5) + 0.2,
2703
+ inset: 0
2704
+ }
2705
+ ) })
2706
+ }
2707
+ ),
2708
+ items.map(
2709
+ (item, index) => item === "ellipsis" ? /* @__PURE__ */ jsx(
2710
+ "span",
2711
+ {
2712
+ style: {
2713
+ width: 28,
2714
+ textAlign: "center",
2715
+ fontFamily: doodleUiFontFamily,
2716
+ color: ink
2717
+ },
2718
+ children: "\u2026"
2719
+ },
2720
+ `e-${index}`
2721
+ ) : /* @__PURE__ */ jsx(
2722
+ PageButton,
2723
+ {
2724
+ "aria-label": `Page ${item}`,
2725
+ "aria-current": item === page ? "page" : void 0,
2726
+ active: item === page,
2727
+ onClick: () => onPageChange?.(item),
2728
+ roughness,
2729
+ seed: deriveSeed(resolvedSeed, `page-${item}`),
2730
+ ink,
2731
+ bowing,
2732
+ strokeWidth,
2733
+ children: item
2734
+ },
2735
+ item
2736
+ )
2737
+ ),
2738
+ /* @__PURE__ */ jsx(
2739
+ PageButton,
2740
+ {
2741
+ "aria-label": "Next page",
2742
+ disabled: page >= count,
2743
+ onClick: () => onPageChange?.(Math.min(count, page + 1)),
2744
+ roughness,
2745
+ seed: deriveSeed(resolvedSeed, "next"),
2746
+ ink,
2747
+ bowing,
2748
+ strokeWidth,
2749
+ children: /* @__PURE__ */ jsx("span", { style: { position: "relative", width: 16, height: 16, display: "block" }, children: /* @__PURE__ */ jsx(
2750
+ RoughSvg,
2751
+ {
2752
+ shape: "path",
2753
+ path: NEXT_PATH,
2754
+ roughness: (roughness ?? 1.5) * 0.7,
2755
+ seed: deriveSeed(resolvedSeed, "next-arrow"),
2756
+ sketchColor: ink,
2757
+ strokeWidth: (strokeWidth ?? 1.5) + 0.2,
2758
+ inset: 0
2759
+ }
2760
+ ) })
2761
+ }
2762
+ )
2763
+ ]
2764
+ }
2765
+ );
2766
+ }
2767
+ );
2768
+ function PageButton({
2769
+ children,
2770
+ className,
2771
+ style,
2772
+ active,
2773
+ disabled,
2774
+ roughness,
2775
+ seed,
2776
+ ink,
2777
+ bowing,
2778
+ strokeWidth,
2779
+ ...rest
2780
+ }) {
2781
+ return /* @__PURE__ */ jsxs(
2782
+ "button",
2783
+ {
2784
+ type: "button",
2785
+ disabled,
2786
+ className: cn(className),
2787
+ style: {
2788
+ position: "relative",
2789
+ width: 36,
2790
+ height: 36,
2791
+ padding: 0,
2792
+ border: "none",
2793
+ background: "transparent",
2794
+ cursor: disabled ? "not-allowed" : "pointer",
2795
+ color: ink,
2796
+ fontFamily: doodleUiFontFamily,
2797
+ fontWeight: active ? doodleUiFontWeight(700) : doodleUiFontWeight(400),
2798
+ fontSize: 14,
2799
+ outline: "none",
2800
+ opacity: disabled ? 0.4 : 1,
2801
+ ...style
2802
+ },
2803
+ ...rest,
2804
+ children: [
2805
+ /* @__PURE__ */ jsx(
2806
+ RoughSvg,
2807
+ {
2808
+ shape: "ellipse",
2809
+ roughness,
2810
+ seed,
2811
+ sketchColor: active ? SKETCH_COLORS.accent : ink,
2812
+ bowing,
2813
+ fill: active ? SKETCH_COLORS.accentFill : void 0,
2814
+ fillStyle: active ? "hachure" : void 0,
2815
+ strokeWidth: active ? (strokeWidth ?? 1.6) + 0.3 : strokeWidth ?? 1.4,
2816
+ inset: 1.5
2817
+ }
2818
+ ),
2819
+ active ? /* @__PURE__ */ jsx(
2820
+ RoughSvg,
2821
+ {
2822
+ shape: "ellipse",
2823
+ roughness: (roughness ?? 1.5) + 0.45,
2824
+ seed,
2825
+ sketchColor: SKETCH_COLORS.accent,
2826
+ bowing: bowing ?? 1.6,
2827
+ strokeWidth: 1.1,
2828
+ inset: -1.5,
2829
+ style: { opacity: 0.7 }
2830
+ }
2831
+ ) : null,
2832
+ /* @__PURE__ */ jsx("span", { style: { position: "relative", zIndex: 1 }, children })
2833
+ ]
2834
+ }
2835
+ );
2836
+ }
2837
+ var SLASH_PATH = "M 10 3 L 6 15";
2838
+ var CHEVRON_PATH3 = "M 5 4 L 11 9 L 5 14";
2839
+ var BreadcrumbSketchContext = createContext(null);
2840
+ function useBreadcrumbSketch() {
2841
+ const ctx = useContext(BreadcrumbSketchContext);
2842
+ if (!ctx) {
2843
+ throw new Error("BreadcrumbItem must be used inside <Breadcrumb>.");
2844
+ }
2845
+ return ctx;
2846
+ }
2847
+ var Breadcrumb = forwardRef(
2848
+ function Breadcrumb2({
2849
+ className,
2850
+ style,
2851
+ children,
2852
+ separator = "slash",
2853
+ roughness,
2854
+ seed,
2855
+ sketchColor,
2856
+ bowing,
2857
+ strokeWidth,
2858
+ ...rest
2859
+ }, ref) {
2860
+ const ink = sketchColor ?? SKETCH_COLORS.ink;
2861
+ const resolvedSeed = useResolvedSeed(seed);
2862
+ const items = Children.toArray(children).filter(isValidElement);
2863
+ return /* @__PURE__ */ jsx(
2864
+ BreadcrumbSketchContext.Provider,
2865
+ {
2866
+ value: {
2867
+ roughness,
2868
+ seed: resolvedSeed,
2869
+ sketchColor,
2870
+ bowing,
2871
+ strokeWidth,
2872
+ resolvedSeed,
2873
+ ink,
2874
+ separator
2875
+ },
2876
+ children: /* @__PURE__ */ jsx(
2877
+ "nav",
2878
+ {
2879
+ ref,
2880
+ className: cn(className),
2881
+ "aria-label": "Breadcrumb",
2882
+ style,
2883
+ ...rest,
2884
+ children: /* @__PURE__ */ jsx(
2885
+ "ol",
2886
+ {
2887
+ style: {
2888
+ display: "flex",
2889
+ flexWrap: "wrap",
2890
+ alignItems: "center",
2891
+ gap: 4,
2892
+ listStyle: "none",
2893
+ margin: 0,
2894
+ padding: 0,
2895
+ fontFamily: doodleUiFontFamily,
2896
+ color: ink,
2897
+ fontSize: 14
2898
+ },
2899
+ children: items.map((child, index) => /* @__PURE__ */ jsxs(
2900
+ "li",
2901
+ {
2902
+ style: { display: "inline-flex", alignItems: "center", gap: 4 },
2903
+ children: [
2904
+ cloneElement(child, {
2905
+ index
2906
+ }),
2907
+ index < items.length - 1 ? /* @__PURE__ */ jsx(
2908
+ SeparatorMark,
2909
+ {
2910
+ index,
2911
+ separator,
2912
+ resolvedSeed,
2913
+ roughness,
2914
+ ink,
2915
+ bowing,
2916
+ strokeWidth
2917
+ }
2918
+ ) : null
2919
+ ]
2920
+ },
2921
+ index
2922
+ ))
2923
+ }
2924
+ )
2925
+ }
2926
+ )
2927
+ }
2928
+ );
2929
+ }
2930
+ );
2931
+ function SeparatorMark({
2932
+ index,
2933
+ separator,
2934
+ resolvedSeed,
2935
+ roughness,
2936
+ ink,
2937
+ bowing,
2938
+ strokeWidth
2939
+ }) {
2940
+ return /* @__PURE__ */ jsx(
2941
+ "span",
2942
+ {
2943
+ "aria-hidden": "true",
2944
+ style: { position: "relative", width: 16, height: 18, display: "inline-block" },
2945
+ children: /* @__PURE__ */ jsx(
2946
+ RoughSvg,
2947
+ {
2948
+ shape: "path",
2949
+ path: separator === "chevron" ? CHEVRON_PATH3 : SLASH_PATH,
2950
+ roughness: (roughness ?? 1.5) * 0.85,
2951
+ seed: deriveSeed(resolvedSeed, `sep-${index}`),
2952
+ sketchColor: ink,
2953
+ bowing: bowing ?? 1.6,
2954
+ strokeWidth: strokeWidth ?? 1.4,
2955
+ inset: 0
2956
+ }
2957
+ )
2958
+ }
2959
+ );
2960
+ }
2961
+ var BreadcrumbItem = forwardRef(
2962
+ function BreadcrumbItem2({ className, style, href, current, children, index: _index, ...rest }, ref) {
2963
+ const sketch = useBreadcrumbSketch();
2964
+ const contentStyle = {
2965
+ color: current ? sketch.ink : sketch.ink,
2966
+ opacity: current ? 1 : 0.75,
2967
+ textDecoration: "none",
2968
+ fontFamily: doodleUiFontFamily,
2969
+ ...style
2970
+ };
2971
+ if (href && !current) {
2972
+ return /* @__PURE__ */ jsx(
2973
+ "a",
2974
+ {
2975
+ href,
2976
+ className: cn(className),
2977
+ style: contentStyle,
2978
+ ...rest,
2979
+ children
2980
+ }
2981
+ );
2982
+ }
2983
+ return /* @__PURE__ */ jsx(
2984
+ "span",
2985
+ {
2986
+ ref,
2987
+ className: cn(className),
2988
+ "aria-current": current ? "page" : void 0,
2989
+ style: contentStyle,
2990
+ ...rest,
2991
+ children
2992
+ }
2993
+ );
2994
+ }
2995
+ );
2996
+ var Skeleton = forwardRef(
2997
+ function Skeleton2({
2998
+ className,
2999
+ style,
3000
+ variant = "rect",
3001
+ pulse = true,
3002
+ width,
3003
+ height,
3004
+ roughness,
3005
+ seed,
3006
+ sketchColor,
3007
+ bowing,
3008
+ fillStyle,
3009
+ strokeWidth,
3010
+ ...rest
3011
+ }, ref) {
3012
+ const base = useResolvedSeed(seed);
3013
+ const [tick, setTick] = useState(0);
3014
+ const ink = sketchColor ?? SKETCH_COLORS.ink;
3015
+ useEffect(() => {
3016
+ if (!pulse) return;
3017
+ const id = window.setInterval(() => {
3018
+ setTick((current) => current + 1);
3019
+ }, 900);
3020
+ return () => window.clearInterval(id);
3021
+ }, [pulse]);
3022
+ const resolved = pulse ? deriveSeed(base, `pulse-${tick}`) : base;
3023
+ const shape = variant === "circle" ? "ellipse" : "rectangle";
3024
+ const defaultHeight = variant === "text" ? 14 : variant === "circle" ? 40 : 80;
3025
+ const defaultWidth = variant === "circle" ? 40 : "100%";
3026
+ return /* @__PURE__ */ jsx(
3027
+ "div",
3028
+ {
3029
+ ref,
3030
+ "aria-hidden": "true",
3031
+ className: cn(className),
3032
+ style: {
3033
+ position: "relative",
3034
+ width: width ?? defaultWidth,
3035
+ height: height ?? defaultHeight,
3036
+ maxWidth: "100%",
3037
+ ...style
3038
+ },
3039
+ ...rest,
3040
+ children: /* @__PURE__ */ jsx(
3041
+ RoughSvg,
3042
+ {
3043
+ shape,
3044
+ roughness: (roughness ?? 1.5) + 0.4,
3045
+ seed: resolved,
3046
+ sketchColor: ink,
3047
+ fill: ink,
3048
+ fillStyle: fillStyle ?? "hachure",
3049
+ bowing: bowing ?? 1.6,
3050
+ strokeWidth: strokeWidth ?? 1.1,
3051
+ inset: 2,
3052
+ style: { opacity: 0.28 }
3053
+ }
3054
+ )
3055
+ }
3056
+ );
3057
+ }
3058
+ );
3059
+ function normalizeSteps(steps) {
3060
+ return steps.map(
3061
+ (step) => step !== null && typeof step === "object" && "label" in step ? step : { label: step }
3062
+ );
3063
+ }
3064
+ var Stepper = forwardRef(
3065
+ function Stepper2({
3066
+ className,
3067
+ style,
3068
+ steps,
3069
+ current = 0,
3070
+ orientation = "horizontal",
3071
+ roughness,
3072
+ seed,
3073
+ sketchColor,
3074
+ bowing,
3075
+ fillStyle,
3076
+ strokeWidth,
3077
+ ...rest
3078
+ }, ref) {
3079
+ const ink = sketchColor ?? SKETCH_COLORS.ink;
3080
+ const resolvedSeed = useResolvedSeed(seed);
3081
+ const items = normalizeSteps(steps);
3082
+ const horizontal = orientation === "horizontal";
3083
+ return /* @__PURE__ */ jsx(
3084
+ "div",
3085
+ {
3086
+ ref,
3087
+ role: "list",
3088
+ className: cn(className),
3089
+ style: {
3090
+ display: "flex",
3091
+ flexDirection: horizontal ? "row" : "column",
3092
+ alignItems: horizontal ? "flex-start" : "stretch",
3093
+ ...style
3094
+ },
3095
+ ...rest,
3096
+ children: items.map((step, index) => {
3097
+ const complete = index < current;
3098
+ const active = index === current;
3099
+ const markerColor = complete || active ? SKETCH_COLORS.accent : ink;
3100
+ return /* @__PURE__ */ jsxs(
3101
+ "div",
3102
+ {
3103
+ role: "listitem",
3104
+ "aria-current": active ? "step" : void 0,
3105
+ style: {
3106
+ display: "flex",
3107
+ flex: horizontal ? 1 : void 0,
3108
+ flexDirection: horizontal ? "column" : "row",
3109
+ alignItems: horizontal ? "center" : "flex-start",
3110
+ minWidth: 0
3111
+ },
3112
+ children: [
3113
+ /* @__PURE__ */ jsxs(
3114
+ "div",
3115
+ {
3116
+ style: {
3117
+ display: "flex",
3118
+ flexDirection: horizontal ? "row" : "column",
3119
+ alignItems: "center",
3120
+ width: horizontal ? "100%" : void 0
3121
+ },
3122
+ children: [
3123
+ /* @__PURE__ */ jsxs(
3124
+ "span",
3125
+ {
3126
+ style: {
3127
+ position: "relative",
3128
+ width: 28,
3129
+ height: 28,
3130
+ flexShrink: 0,
3131
+ display: "inline-flex",
3132
+ alignItems: "center",
3133
+ justifyContent: "center",
3134
+ fontFamily: doodleUiFontFamily,
3135
+ fontWeight: doodleUiFontWeight(700),
3136
+ fontSize: 13,
3137
+ color: markerColor
3138
+ },
3139
+ children: [
3140
+ /* @__PURE__ */ jsx(
3141
+ RoughSvg,
3142
+ {
3143
+ shape: "ellipse",
3144
+ roughness,
3145
+ seed: deriveSeed(resolvedSeed, `step-${index}`),
3146
+ sketchColor: markerColor,
3147
+ fill: complete ? SKETCH_COLORS.accentFill : active ? "#f7f6f2" : void 0,
3148
+ fillStyle: complete || active ? fillStyle ?? "hachure" : void 0,
3149
+ bowing,
3150
+ strokeWidth: active ? (strokeWidth ?? 1.6) + 0.4 : strokeWidth ?? 1.5,
3151
+ inset: 1.5
3152
+ }
3153
+ ),
3154
+ /* @__PURE__ */ jsx("span", { style: { position: "relative", zIndex: 1 }, children: complete ? "\u2713" : index + 1 })
3155
+ ]
3156
+ }
3157
+ ),
3158
+ index < items.length - 1 ? /* @__PURE__ */ jsx(
3159
+ "span",
3160
+ {
3161
+ style: {
3162
+ position: "relative",
3163
+ flex: 1,
3164
+ width: horizontal ? void 0 : 12,
3165
+ height: horizontal ? 12 : 28,
3166
+ minWidth: horizontal ? 16 : 12,
3167
+ alignSelf: "center"
3168
+ },
3169
+ children: /* @__PURE__ */ jsx(
3170
+ RoughSvg,
3171
+ {
3172
+ shape: horizontal ? "line" : "line-vertical",
3173
+ roughness: (roughness ?? 1.5) + 0.3,
3174
+ seed: deriveSeed(resolvedSeed, `connector-${index}`),
3175
+ sketchColor: complete ? SKETCH_COLORS.accent : ink,
3176
+ bowing: bowing ?? 2,
3177
+ strokeWidth: strokeWidth ?? 1.4,
3178
+ inset: 2
3179
+ }
3180
+ )
3181
+ }
3182
+ ) : null
3183
+ ]
3184
+ }
3185
+ ),
3186
+ /* @__PURE__ */ jsxs(
3187
+ "div",
3188
+ {
3189
+ style: {
3190
+ marginTop: horizontal ? 8 : 0,
3191
+ marginLeft: horizontal ? 0 : 10,
3192
+ paddingBottom: horizontal ? 0 : 8,
3193
+ textAlign: horizontal ? "center" : "left",
3194
+ fontFamily: doodleUiFontFamily,
3195
+ fontSize: 13,
3196
+ color: ink
3197
+ },
3198
+ children: [
3199
+ /* @__PURE__ */ jsx("div", { style: { fontWeight: doodleUiFontWeight(600) }, children: step.label }),
3200
+ step.description ? /* @__PURE__ */ jsx("div", { style: { opacity: 0.7, fontSize: 12, marginTop: 2 }, children: step.description }) : null
3201
+ ]
3202
+ }
3203
+ )
3204
+ ]
3205
+ },
3206
+ index
3207
+ );
3208
+ })
3209
+ }
3210
+ );
3211
+ }
3212
+ );
1256
3213
 
1257
- 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 };
3214
+ export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, Avatar, Badge, Breadcrumb, BreadcrumbItem, Button, Card, Checkbox, DEFAULT_BOWING, DEFAULT_INK, DEFAULT_ROUGHNESS, DEFAULT_STROKE_WIDTH, Divider, Input, Modal, ModalClose, ModalDescription, ModalRoot, ModalTitle, ModalTrigger, Pagination, Progress, Radio, RadioGroup, RoughSvg, SKETCH_COLORS, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectRoot, SelectSeparator, SelectTrigger, SelectValue, Skeleton, SketchBox, SketchSeedProvider, Slider, Stepper, Switch, Tab, TabList, TabPanel, Table, TableBody, TableCell, TableHead, TableHeaderCell, TableRow, Tabs, Textarea, Toast, ToastAction, ToastClose, ToastDescription, ToastProvider, ToastRoot, ToastTitle, ToastViewport, Tooltip, TooltipProvider, deriveSeed, toRoughOptions, useResolvedSeed, useSketchSeed };
1258
3215
  //# sourceMappingURL=index.js.map
1259
3216
  //# sourceMappingURL=index.js.map