@particle-academy/react-fancy 1.5.1 → 1.7.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/README.md +14 -2
- package/dist/index.cjs +1062 -392
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +98 -16
- package/dist/index.d.ts +98 -16
- package/dist/index.js +1064 -394
- package/dist/index.js.map +1 -1
- package/dist/styles.css +57 -0
- package/dist/styles.css.map +1 -1
- package/package.json +10 -9
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { forwardRef, useId, useRef, useEffect,
|
|
1
|
+
import { forwardRef, useId, useRef, useEffect, useState, useCallback, createContext, Children, isValidElement, useMemo, cloneElement, useLayoutEffect, useContext, Fragment as Fragment$1 } from 'react';
|
|
2
2
|
import { clsx } from 'clsx';
|
|
3
3
|
import { twMerge } from 'tailwind-merge';
|
|
4
4
|
import * as LucideIcons from 'lucide-react';
|
|
@@ -1013,13 +1013,6 @@ var avatarSize = {
|
|
|
1013
1013
|
lg: "w-6 h-6",
|
|
1014
1014
|
xl: "w-7 h-7"
|
|
1015
1015
|
};
|
|
1016
|
-
var alertIconSize = {
|
|
1017
|
-
xs: "w-2 h-2",
|
|
1018
|
-
sm: "w-2.5 h-2.5",
|
|
1019
|
-
md: "w-3 h-3",
|
|
1020
|
-
lg: "w-4 h-4",
|
|
1021
|
-
xl: "w-4 h-4"
|
|
1022
|
-
};
|
|
1023
1016
|
var badgeSize = {
|
|
1024
1017
|
xs: "text-[10px] px-1 min-w-[14px] h-3.5",
|
|
1025
1018
|
sm: "text-[10px] px-1.5 min-w-[16px] h-4",
|
|
@@ -1131,7 +1124,7 @@ var Action = forwardRef(
|
|
|
1131
1124
|
return /* @__PURE__ */ jsx(
|
|
1132
1125
|
"span",
|
|
1133
1126
|
{
|
|
1134
|
-
className: cn("flex-shrink-0", iconColorCls),
|
|
1127
|
+
className: cn("inline-flex items-center flex-shrink-0", iconColorCls),
|
|
1135
1128
|
children: /* @__PURE__ */ jsx(Icon, { name: iconSlug, size: iconSizeMap[size] })
|
|
1136
1129
|
},
|
|
1137
1130
|
`icon-${trailing ? "t" : "l"}`
|
|
@@ -1185,17 +1178,8 @@ var Action = forwardRef(
|
|
|
1185
1178
|
className: "relative inline-flex flex-shrink-0",
|
|
1186
1179
|
"data-action-alert": true,
|
|
1187
1180
|
children: [
|
|
1188
|
-
/* @__PURE__ */ jsx("span", { className:
|
|
1189
|
-
/* @__PURE__ */ jsx(
|
|
1190
|
-
"span",
|
|
1191
|
-
{
|
|
1192
|
-
className: cn(
|
|
1193
|
-
alertIconSize[size],
|
|
1194
|
-
"absolute inset-0 text-red-400 dark:text-red-300 animate-ping opacity-75"
|
|
1195
|
-
),
|
|
1196
|
-
children: alertIconEl
|
|
1197
|
-
}
|
|
1198
|
-
)
|
|
1181
|
+
/* @__PURE__ */ jsx("span", { className: "text-red-500 dark:text-red-400 animate-pulse", children: alertIconEl }),
|
|
1182
|
+
/* @__PURE__ */ jsx("span", { className: "absolute inset-0 flex items-center justify-center text-red-400 dark:text-red-300 animate-ping opacity-75", children: alertIconEl })
|
|
1199
1183
|
]
|
|
1200
1184
|
},
|
|
1201
1185
|
"alert-icon"
|
|
@@ -1335,7 +1319,7 @@ function dirtyRingClasses(dirty) {
|
|
|
1335
1319
|
function errorClasses(error) {
|
|
1336
1320
|
return error ? "border-red-500 focus:ring-red-500" : "";
|
|
1337
1321
|
}
|
|
1338
|
-
var inputBaseClasses = "border border-zinc-300 bg-white text-zinc-900 placeholder:text-zinc-400 focus:outline-none focus:ring-2 focus:ring-blue-500/40 focus:border-blue-500 disabled:opacity-50 disabled:cursor-not-allowed dark:border-zinc-
|
|
1322
|
+
var inputBaseClasses = "border border-zinc-300 bg-white text-zinc-900 placeholder:text-zinc-400 transition-[border-color,box-shadow] duration-150 focus:outline-none focus:ring-2 focus:ring-blue-500/40 focus:border-blue-500 disabled:opacity-50 disabled:cursor-not-allowed dark:border-zinc-700 dark:bg-[#1e1e24] dark:text-zinc-100 dark:placeholder:text-zinc-500 dark:focus:border-blue-400 dark:focus:ring-blue-400/20";
|
|
1339
1323
|
function resolveOption(option) {
|
|
1340
1324
|
if (typeof option === "string") {
|
|
1341
1325
|
return { value: option, label: option };
|
|
@@ -1352,13 +1336,13 @@ function Field({
|
|
|
1352
1336
|
children,
|
|
1353
1337
|
className
|
|
1354
1338
|
}) {
|
|
1355
|
-
return /* @__PURE__ */ jsxs("div", { "data-react-fancy-field": "", className: cn("flex flex-col gap-
|
|
1339
|
+
return /* @__PURE__ */ jsxs("div", { "data-react-fancy-field": "", className: cn("flex flex-col gap-2", className), children: [
|
|
1356
1340
|
label && /* @__PURE__ */ jsxs(
|
|
1357
1341
|
"label",
|
|
1358
1342
|
{
|
|
1359
1343
|
htmlFor,
|
|
1360
1344
|
className: cn(
|
|
1361
|
-
"font-medium text-zinc-700 dark:text-zinc-
|
|
1345
|
+
"font-medium text-zinc-700 dark:text-zinc-100",
|
|
1362
1346
|
labelSizeClasses[size]
|
|
1363
1347
|
),
|
|
1364
1348
|
children: [
|
|
@@ -1386,7 +1370,7 @@ var insidePaddingRight = {
|
|
|
1386
1370
|
lg: "pr-10",
|
|
1387
1371
|
xl: "pr-11"
|
|
1388
1372
|
};
|
|
1389
|
-
var affixOutsideClasses = "inline-flex items-center border border-zinc-300 bg-zinc-50 px-3 text-sm text-zinc-500 dark:border-zinc-
|
|
1373
|
+
var affixOutsideClasses = "inline-flex items-center border border-zinc-300 bg-zinc-50 px-3 text-sm text-zinc-500 dark:border-zinc-700 dark:bg-zinc-800 dark:text-zinc-400";
|
|
1390
1374
|
function InputWrapper({
|
|
1391
1375
|
children,
|
|
1392
1376
|
prefix,
|
|
@@ -1630,10 +1614,157 @@ var Textarea = forwardRef(
|
|
|
1630
1614
|
}
|
|
1631
1615
|
);
|
|
1632
1616
|
Textarea.displayName = "Textarea";
|
|
1617
|
+
function Portal({ children, container }) {
|
|
1618
|
+
if (typeof document === "undefined") return null;
|
|
1619
|
+
const target = container ?? document.body;
|
|
1620
|
+
return createPortal(
|
|
1621
|
+
/* @__PURE__ */ jsx(PortalDarkWrapper, { children }),
|
|
1622
|
+
target
|
|
1623
|
+
);
|
|
1624
|
+
}
|
|
1625
|
+
function PortalDarkWrapper({ children }) {
|
|
1626
|
+
const ref = useRef(null);
|
|
1627
|
+
useEffect(() => {
|
|
1628
|
+
const root = document.documentElement;
|
|
1629
|
+
const wrapper = ref.current;
|
|
1630
|
+
if (!wrapper) return;
|
|
1631
|
+
const sync = () => {
|
|
1632
|
+
const isDark = root.classList.contains("dark") || root.getAttribute("data-theme") === "dark";
|
|
1633
|
+
wrapper.classList.toggle("dark", isDark);
|
|
1634
|
+
};
|
|
1635
|
+
sync();
|
|
1636
|
+
const observer = new MutationObserver(sync);
|
|
1637
|
+
observer.observe(root, {
|
|
1638
|
+
attributes: true,
|
|
1639
|
+
attributeFilter: ["class", "data-theme"]
|
|
1640
|
+
});
|
|
1641
|
+
return () => observer.disconnect();
|
|
1642
|
+
}, []);
|
|
1643
|
+
return /* @__PURE__ */ jsx("div", { ref, "data-react-fancy-portal": "", style: { display: "contents" }, children });
|
|
1644
|
+
}
|
|
1645
|
+
function getPosition(anchor, floating, placement, offset) {
|
|
1646
|
+
let x = 0;
|
|
1647
|
+
let y = 0;
|
|
1648
|
+
const base = placement.split("-")[0];
|
|
1649
|
+
const align = placement.split("-")[1];
|
|
1650
|
+
switch (base) {
|
|
1651
|
+
case "top":
|
|
1652
|
+
x = anchor.left + anchor.width / 2 - floating.width / 2;
|
|
1653
|
+
y = anchor.top - floating.height - offset;
|
|
1654
|
+
break;
|
|
1655
|
+
case "bottom":
|
|
1656
|
+
x = anchor.left + anchor.width / 2 - floating.width / 2;
|
|
1657
|
+
y = anchor.bottom + offset;
|
|
1658
|
+
break;
|
|
1659
|
+
case "left":
|
|
1660
|
+
x = anchor.left - floating.width - offset;
|
|
1661
|
+
y = anchor.top + anchor.height / 2 - floating.height / 2;
|
|
1662
|
+
break;
|
|
1663
|
+
case "right":
|
|
1664
|
+
x = anchor.right + offset;
|
|
1665
|
+
y = anchor.top + anchor.height / 2 - floating.height / 2;
|
|
1666
|
+
break;
|
|
1667
|
+
}
|
|
1668
|
+
if (base === "top" || base === "bottom") {
|
|
1669
|
+
if (align === "start") x = anchor.left;
|
|
1670
|
+
else if (align === "end") x = anchor.right - floating.width;
|
|
1671
|
+
}
|
|
1672
|
+
if (base === "left" || base === "right") {
|
|
1673
|
+
if (align === "start") y = anchor.top;
|
|
1674
|
+
else if (align === "end") y = anchor.bottom - floating.height;
|
|
1675
|
+
}
|
|
1676
|
+
let finalPlacement = placement;
|
|
1677
|
+
const vw = window.innerWidth;
|
|
1678
|
+
const vh = window.innerHeight;
|
|
1679
|
+
if (base === "bottom" && y + floating.height > vh) {
|
|
1680
|
+
y = anchor.top - floating.height - offset;
|
|
1681
|
+
finalPlacement = placement.replace("bottom", "top");
|
|
1682
|
+
} else if (base === "top" && y < 0) {
|
|
1683
|
+
y = anchor.bottom + offset;
|
|
1684
|
+
finalPlacement = placement.replace("top", "bottom");
|
|
1685
|
+
}
|
|
1686
|
+
x = Math.max(4, Math.min(x, vw - floating.width - 4));
|
|
1687
|
+
y = Math.max(4, Math.min(y, vh - floating.height - 4));
|
|
1688
|
+
return { x, y, placement: finalPlacement };
|
|
1689
|
+
}
|
|
1690
|
+
function useFloatingPosition(anchorRef, floatingRef, options = {}) {
|
|
1691
|
+
const { placement = "bottom", offset = 8, enabled = true } = options;
|
|
1692
|
+
const [position, setPosition] = useState({
|
|
1693
|
+
x: -9999,
|
|
1694
|
+
y: -9999,
|
|
1695
|
+
placement
|
|
1696
|
+
});
|
|
1697
|
+
const update = useCallback(() => {
|
|
1698
|
+
const anchor = anchorRef.current;
|
|
1699
|
+
const floating = floatingRef.current;
|
|
1700
|
+
if (!anchor || !floating) return;
|
|
1701
|
+
const anchorRect = anchor.getBoundingClientRect();
|
|
1702
|
+
const floatingRect = floating.getBoundingClientRect();
|
|
1703
|
+
setPosition(getPosition(anchorRect, floatingRect, placement, offset));
|
|
1704
|
+
}, [anchorRef, floatingRef, placement, offset]);
|
|
1705
|
+
useLayoutEffect(() => {
|
|
1706
|
+
if (!enabled) return;
|
|
1707
|
+
update();
|
|
1708
|
+
const raf = requestAnimationFrame(() => {
|
|
1709
|
+
update();
|
|
1710
|
+
});
|
|
1711
|
+
return () => cancelAnimationFrame(raf);
|
|
1712
|
+
}, [update, enabled]);
|
|
1713
|
+
useEffect(() => {
|
|
1714
|
+
if (!enabled) return;
|
|
1715
|
+
window.addEventListener("scroll", update, true);
|
|
1716
|
+
window.addEventListener("resize", update);
|
|
1717
|
+
return () => {
|
|
1718
|
+
window.removeEventListener("scroll", update, true);
|
|
1719
|
+
window.removeEventListener("resize", update);
|
|
1720
|
+
};
|
|
1721
|
+
}, [update, enabled]);
|
|
1722
|
+
return position;
|
|
1723
|
+
}
|
|
1724
|
+
function useOutsideClick(ref, handler, enabled = true, ignoreRef) {
|
|
1725
|
+
useEffect(() => {
|
|
1726
|
+
if (!enabled) return;
|
|
1727
|
+
const listener = (event) => {
|
|
1728
|
+
const el = ref.current;
|
|
1729
|
+
if (!el || el.contains(event.target)) return;
|
|
1730
|
+
if (ignoreRef?.current?.contains(event.target)) return;
|
|
1731
|
+
handler(event);
|
|
1732
|
+
};
|
|
1733
|
+
document.addEventListener("mousedown", listener);
|
|
1734
|
+
document.addEventListener("touchstart", listener);
|
|
1735
|
+
return () => {
|
|
1736
|
+
document.removeEventListener("mousedown", listener);
|
|
1737
|
+
document.removeEventListener("touchstart", listener);
|
|
1738
|
+
};
|
|
1739
|
+
}, [ref, handler, enabled, ignoreRef]);
|
|
1740
|
+
}
|
|
1741
|
+
function useEscapeKey(handler, enabled = true) {
|
|
1742
|
+
useEffect(() => {
|
|
1743
|
+
if (!enabled) return;
|
|
1744
|
+
const listener = (event) => {
|
|
1745
|
+
if (event.key === "Escape") {
|
|
1746
|
+
handler();
|
|
1747
|
+
}
|
|
1748
|
+
};
|
|
1749
|
+
document.addEventListener("keydown", listener);
|
|
1750
|
+
return () => document.removeEventListener("keydown", listener);
|
|
1751
|
+
}, [handler, enabled]);
|
|
1752
|
+
}
|
|
1633
1753
|
function isOptionGroup(item) {
|
|
1634
1754
|
return typeof item === "object" && "options" in item;
|
|
1635
1755
|
}
|
|
1636
|
-
function
|
|
1756
|
+
function flattenOptions(list) {
|
|
1757
|
+
const flat = [];
|
|
1758
|
+
for (const item of list) {
|
|
1759
|
+
if (isOptionGroup(item)) {
|
|
1760
|
+
flat.push(...item.options);
|
|
1761
|
+
} else {
|
|
1762
|
+
flat.push(item);
|
|
1763
|
+
}
|
|
1764
|
+
}
|
|
1765
|
+
return flat;
|
|
1766
|
+
}
|
|
1767
|
+
function renderNativeOption(option, index) {
|
|
1637
1768
|
const resolved = resolveOption(option);
|
|
1638
1769
|
return /* @__PURE__ */ jsx(
|
|
1639
1770
|
"option",
|
|
@@ -1645,7 +1776,7 @@ function renderOption(option, index) {
|
|
|
1645
1776
|
`${resolved.value}-${index}`
|
|
1646
1777
|
);
|
|
1647
1778
|
}
|
|
1648
|
-
var
|
|
1779
|
+
var NativeSelect = forwardRef(
|
|
1649
1780
|
({
|
|
1650
1781
|
size = "md",
|
|
1651
1782
|
dirty,
|
|
@@ -1703,8 +1834,8 @@ var Select = forwardRef(
|
|
|
1703
1834
|
placeholder && /* @__PURE__ */ jsx("option", { value: "", disabled: true, children: placeholder }),
|
|
1704
1835
|
list.map(
|
|
1705
1836
|
(item, index) => isOptionGroup(item) ? /* @__PURE__ */ jsx("optgroup", { label: item.label, children: item.options.map(
|
|
1706
|
-
(opt, optIndex) =>
|
|
1707
|
-
) }, `group-${index}`) :
|
|
1837
|
+
(opt, optIndex) => renderNativeOption(opt, optIndex)
|
|
1838
|
+
) }, `group-${index}`) : renderNativeOption(item, index)
|
|
1708
1839
|
)
|
|
1709
1840
|
]
|
|
1710
1841
|
}
|
|
@@ -1728,6 +1859,270 @@ var Select = forwardRef(
|
|
|
1728
1859
|
return select;
|
|
1729
1860
|
}
|
|
1730
1861
|
);
|
|
1862
|
+
NativeSelect.displayName = "NativeSelect";
|
|
1863
|
+
var ListboxSelect = forwardRef(
|
|
1864
|
+
({
|
|
1865
|
+
size = "md",
|
|
1866
|
+
dirty,
|
|
1867
|
+
error,
|
|
1868
|
+
label,
|
|
1869
|
+
description,
|
|
1870
|
+
required,
|
|
1871
|
+
disabled,
|
|
1872
|
+
className,
|
|
1873
|
+
id,
|
|
1874
|
+
list,
|
|
1875
|
+
placeholder = "Select...",
|
|
1876
|
+
multiple = false,
|
|
1877
|
+
values: controlledValues,
|
|
1878
|
+
defaultValues,
|
|
1879
|
+
onValueChange,
|
|
1880
|
+
onValuesChange,
|
|
1881
|
+
searchable = false,
|
|
1882
|
+
selectedSuffix = "selected",
|
|
1883
|
+
indicator = "check",
|
|
1884
|
+
value: controlledSingleValue,
|
|
1885
|
+
defaultValue: defaultSingleValue
|
|
1886
|
+
}, _ref) => {
|
|
1887
|
+
const autoId = useId();
|
|
1888
|
+
const selectId = id ?? autoId;
|
|
1889
|
+
const [open, setOpen] = useState(false);
|
|
1890
|
+
const [search2, setSearch] = useState("");
|
|
1891
|
+
const [activeIndex, setActiveIndex] = useState(-1);
|
|
1892
|
+
const [singleValue, setSingleValue] = useState(
|
|
1893
|
+
controlledSingleValue ?? defaultSingleValue ?? ""
|
|
1894
|
+
);
|
|
1895
|
+
const currentSingle = controlledSingleValue ?? singleValue;
|
|
1896
|
+
const [multiValues, setMultiValues] = useState(
|
|
1897
|
+
controlledValues ?? defaultValues ?? []
|
|
1898
|
+
);
|
|
1899
|
+
const currentMulti = controlledValues ?? multiValues;
|
|
1900
|
+
useEffect(() => {
|
|
1901
|
+
if (controlledValues) setMultiValues(controlledValues);
|
|
1902
|
+
}, [controlledValues]);
|
|
1903
|
+
useEffect(() => {
|
|
1904
|
+
if (controlledSingleValue !== void 0) setSingleValue(controlledSingleValue);
|
|
1905
|
+
}, [controlledSingleValue]);
|
|
1906
|
+
const anchorRef = useRef(null);
|
|
1907
|
+
const listRef = useRef(null);
|
|
1908
|
+
const wrapperRef = useRef(null);
|
|
1909
|
+
const searchRef = useRef(null);
|
|
1910
|
+
const position = useFloatingPosition(anchorRef, listRef, {
|
|
1911
|
+
placement: "bottom-start",
|
|
1912
|
+
offset: 4,
|
|
1913
|
+
enabled: open
|
|
1914
|
+
});
|
|
1915
|
+
const close = useCallback(() => {
|
|
1916
|
+
setOpen(false);
|
|
1917
|
+
setSearch("");
|
|
1918
|
+
setActiveIndex(-1);
|
|
1919
|
+
}, []);
|
|
1920
|
+
useOutsideClick(wrapperRef, close, open);
|
|
1921
|
+
useEscapeKey(close, open);
|
|
1922
|
+
useEffect(() => {
|
|
1923
|
+
if (open && searchable) {
|
|
1924
|
+
requestAnimationFrame(() => searchRef.current?.focus());
|
|
1925
|
+
}
|
|
1926
|
+
}, [open, searchable]);
|
|
1927
|
+
const allOptions = flattenOptions(list);
|
|
1928
|
+
const resolvedOptions = allOptions.map(resolveOption);
|
|
1929
|
+
const filtered = search2 ? resolvedOptions.filter(
|
|
1930
|
+
(o) => o.label.toLowerCase().includes(search2.toLowerCase())
|
|
1931
|
+
) : resolvedOptions;
|
|
1932
|
+
const isSelected = (value) => {
|
|
1933
|
+
if (multiple) return currentMulti.includes(value);
|
|
1934
|
+
return currentSingle === value;
|
|
1935
|
+
};
|
|
1936
|
+
const toggleOption = useCallback(
|
|
1937
|
+
(value) => {
|
|
1938
|
+
if (multiple) {
|
|
1939
|
+
const next = currentMulti.includes(value) ? currentMulti.filter((v) => v !== value) : [...currentMulti, value];
|
|
1940
|
+
setMultiValues(next);
|
|
1941
|
+
onValuesChange?.(next);
|
|
1942
|
+
} else {
|
|
1943
|
+
setSingleValue(value);
|
|
1944
|
+
onValueChange?.(value);
|
|
1945
|
+
close();
|
|
1946
|
+
}
|
|
1947
|
+
},
|
|
1948
|
+
[multiple, currentMulti, onValuesChange, onValueChange, close]
|
|
1949
|
+
);
|
|
1950
|
+
const getDisplayText = () => {
|
|
1951
|
+
if (multiple) {
|
|
1952
|
+
if (currentMulti.length === 0) return placeholder;
|
|
1953
|
+
if (currentMulti.length === 1) {
|
|
1954
|
+
const opt2 = resolvedOptions.find((o) => o.value === currentMulti[0]);
|
|
1955
|
+
return opt2?.label ?? currentMulti[0];
|
|
1956
|
+
}
|
|
1957
|
+
return `${currentMulti.length} ${selectedSuffix}`;
|
|
1958
|
+
}
|
|
1959
|
+
if (!currentSingle) return placeholder;
|
|
1960
|
+
const opt = resolvedOptions.find((o) => o.value === currentSingle);
|
|
1961
|
+
return opt?.label ?? currentSingle;
|
|
1962
|
+
};
|
|
1963
|
+
const hasValue = multiple ? currentMulti.length > 0 : !!currentSingle;
|
|
1964
|
+
const handleKeyDown = (e) => {
|
|
1965
|
+
if (!open) {
|
|
1966
|
+
if (e.key === "ArrowDown" || e.key === "Enter" || e.key === " ") {
|
|
1967
|
+
e.preventDefault();
|
|
1968
|
+
setOpen(true);
|
|
1969
|
+
}
|
|
1970
|
+
return;
|
|
1971
|
+
}
|
|
1972
|
+
if (e.key === "ArrowDown") {
|
|
1973
|
+
e.preventDefault();
|
|
1974
|
+
setActiveIndex((i) => Math.min(i + 1, filtered.length - 1));
|
|
1975
|
+
} else if (e.key === "ArrowUp") {
|
|
1976
|
+
e.preventDefault();
|
|
1977
|
+
setActiveIndex((i) => Math.max(i - 1, 0));
|
|
1978
|
+
} else if (e.key === "Enter" && activeIndex >= 0) {
|
|
1979
|
+
e.preventDefault();
|
|
1980
|
+
const item = filtered[activeIndex];
|
|
1981
|
+
if (item && !item.disabled) toggleOption(item.value);
|
|
1982
|
+
}
|
|
1983
|
+
};
|
|
1984
|
+
const trigger = /* @__PURE__ */ jsxs(
|
|
1985
|
+
"button",
|
|
1986
|
+
{
|
|
1987
|
+
ref: anchorRef,
|
|
1988
|
+
type: "button",
|
|
1989
|
+
id: selectId,
|
|
1990
|
+
disabled,
|
|
1991
|
+
onClick: () => setOpen((o) => !o),
|
|
1992
|
+
onKeyDown: handleKeyDown,
|
|
1993
|
+
role: "combobox",
|
|
1994
|
+
"aria-expanded": open,
|
|
1995
|
+
"aria-haspopup": "listbox",
|
|
1996
|
+
"data-react-fancy-select": "",
|
|
1997
|
+
"data-variant": "listbox",
|
|
1998
|
+
className: cn(
|
|
1999
|
+
inputBaseClasses,
|
|
2000
|
+
inputSizeClasses[size],
|
|
2001
|
+
dirtyClasses(dirty),
|
|
2002
|
+
errorClasses(error),
|
|
2003
|
+
"flex w-full cursor-pointer items-center justify-between gap-2 text-left",
|
|
2004
|
+
!hasValue && "text-zinc-400 dark:text-zinc-500",
|
|
2005
|
+
className
|
|
2006
|
+
),
|
|
2007
|
+
children: [
|
|
2008
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: getDisplayText() }),
|
|
2009
|
+
/* @__PURE__ */ jsx(
|
|
2010
|
+
"svg",
|
|
2011
|
+
{
|
|
2012
|
+
className: cn("h-4 w-4 shrink-0 text-zinc-400 transition-transform", open && "rotate-180"),
|
|
2013
|
+
viewBox: "0 0 20 20",
|
|
2014
|
+
fill: "currentColor",
|
|
2015
|
+
children: /* @__PURE__ */ jsx(
|
|
2016
|
+
"path",
|
|
2017
|
+
{
|
|
2018
|
+
fillRule: "evenodd",
|
|
2019
|
+
d: "M5.23 7.21a.75.75 0 011.06.02L10 11.168l3.71-3.938a.75.75 0 111.08 1.04l-4.25 4.5a.75.75 0 01-1.08 0l-4.25-4.5a.75.75 0 01.02-1.06z",
|
|
2020
|
+
clipRule: "evenodd"
|
|
2021
|
+
}
|
|
2022
|
+
)
|
|
2023
|
+
}
|
|
2024
|
+
)
|
|
2025
|
+
]
|
|
2026
|
+
}
|
|
2027
|
+
);
|
|
2028
|
+
const dropdown = open && /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsxs(
|
|
2029
|
+
"div",
|
|
2030
|
+
{
|
|
2031
|
+
ref: listRef,
|
|
2032
|
+
role: "listbox",
|
|
2033
|
+
"aria-multiselectable": multiple || void 0,
|
|
2034
|
+
className: "fixed z-50 max-h-60 min-w-[8rem] overflow-y-auto rounded-xl border border-zinc-200 bg-white p-1 shadow-lg dark:border-zinc-700 dark:bg-zinc-900 dark:shadow-zinc-950/50 fancy-scale-in",
|
|
2035
|
+
style: {
|
|
2036
|
+
left: position.x,
|
|
2037
|
+
top: position.y,
|
|
2038
|
+
width: anchorRef.current?.offsetWidth
|
|
2039
|
+
},
|
|
2040
|
+
children: [
|
|
2041
|
+
searchable && /* @__PURE__ */ jsx("div", { className: "px-2 pb-1", children: /* @__PURE__ */ jsx(
|
|
2042
|
+
"input",
|
|
2043
|
+
{
|
|
2044
|
+
ref: searchRef,
|
|
2045
|
+
type: "text",
|
|
2046
|
+
value: search2,
|
|
2047
|
+
onChange: (e) => {
|
|
2048
|
+
setSearch(e.target.value);
|
|
2049
|
+
setActiveIndex(-1);
|
|
2050
|
+
},
|
|
2051
|
+
onKeyDown: handleKeyDown,
|
|
2052
|
+
placeholder: "Search...",
|
|
2053
|
+
className: "w-full rounded-md border-0 bg-zinc-100 px-2.5 py-1.5 text-sm text-zinc-900 placeholder:text-zinc-400 outline-none dark:bg-zinc-800 dark:text-zinc-100 dark:placeholder:text-zinc-500"
|
|
2054
|
+
}
|
|
2055
|
+
) }),
|
|
2056
|
+
filtered.length === 0 ? /* @__PURE__ */ jsx("div", { className: "px-3 py-2 text-sm text-zinc-400", children: "No results found" }) : filtered.map((option, i) => {
|
|
2057
|
+
const selected = isSelected(option.value);
|
|
2058
|
+
return /* @__PURE__ */ jsxs(
|
|
2059
|
+
"button",
|
|
2060
|
+
{
|
|
2061
|
+
type: "button",
|
|
2062
|
+
role: "option",
|
|
2063
|
+
"aria-selected": selected,
|
|
2064
|
+
disabled: option.disabled,
|
|
2065
|
+
onClick: () => toggleOption(option.value),
|
|
2066
|
+
className: cn(
|
|
2067
|
+
"flex w-full items-center gap-2 rounded-lg px-3 py-2 text-left text-sm transition-colors",
|
|
2068
|
+
i === activeIndex ? "bg-zinc-100 dark:bg-zinc-800" : "hover:bg-zinc-50 dark:hover:bg-zinc-800/50",
|
|
2069
|
+
selected ? "text-zinc-900 dark:text-zinc-100" : "text-zinc-700 dark:text-zinc-300",
|
|
2070
|
+
option.disabled && "cursor-not-allowed opacity-50"
|
|
2071
|
+
),
|
|
2072
|
+
children: [
|
|
2073
|
+
indicator === "checkbox" ? /* @__PURE__ */ jsx(
|
|
2074
|
+
"span",
|
|
2075
|
+
{
|
|
2076
|
+
className: cn(
|
|
2077
|
+
"flex h-4 w-4 shrink-0 items-center justify-center rounded border transition-colors",
|
|
2078
|
+
selected ? "border-blue-500 bg-blue-500 text-white dark:border-blue-400 dark:bg-blue-400" : "border-zinc-300 dark:border-zinc-600"
|
|
2079
|
+
),
|
|
2080
|
+
children: selected && /* @__PURE__ */ jsx("svg", { className: "h-3 w-3", viewBox: "0 0 12 12", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("polyline", { points: "2.5 6 5 8.5 9.5 3.5" }) })
|
|
2081
|
+
}
|
|
2082
|
+
) : /* @__PURE__ */ jsx("span", { className: "flex h-4 w-4 shrink-0 items-center justify-center", children: selected && /* @__PURE__ */ jsx("svg", { className: "h-4 w-4 text-blue-500 dark:text-blue-400", viewBox: "0 0 20 20", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { fillRule: "evenodd", d: "M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z", clipRule: "evenodd" }) }) }),
|
|
2083
|
+
/* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1", children: [
|
|
2084
|
+
/* @__PURE__ */ jsx("span", { className: "block truncate", children: option.label }),
|
|
2085
|
+
option.description && /* @__PURE__ */ jsx("span", { className: "block truncate text-xs text-zinc-400 dark:text-zinc-500", children: option.description })
|
|
2086
|
+
] })
|
|
2087
|
+
]
|
|
2088
|
+
},
|
|
2089
|
+
option.value
|
|
2090
|
+
);
|
|
2091
|
+
})
|
|
2092
|
+
]
|
|
2093
|
+
}
|
|
2094
|
+
) });
|
|
2095
|
+
const content = /* @__PURE__ */ jsxs("div", { ref: wrapperRef, className: "relative", children: [
|
|
2096
|
+
trigger,
|
|
2097
|
+
dropdown
|
|
2098
|
+
] });
|
|
2099
|
+
if (label || error || description) {
|
|
2100
|
+
return /* @__PURE__ */ jsx(
|
|
2101
|
+
Field,
|
|
2102
|
+
{
|
|
2103
|
+
label,
|
|
2104
|
+
description,
|
|
2105
|
+
error,
|
|
2106
|
+
required,
|
|
2107
|
+
htmlFor: selectId,
|
|
2108
|
+
size,
|
|
2109
|
+
children: content
|
|
2110
|
+
}
|
|
2111
|
+
);
|
|
2112
|
+
}
|
|
2113
|
+
return content;
|
|
2114
|
+
}
|
|
2115
|
+
);
|
|
2116
|
+
ListboxSelect.displayName = "ListboxSelect";
|
|
2117
|
+
var Select = forwardRef(
|
|
2118
|
+
(props, ref) => {
|
|
2119
|
+
const variant = props.variant ?? (props.multiple ? "listbox" : "native");
|
|
2120
|
+
if (variant === "listbox") {
|
|
2121
|
+
return /* @__PURE__ */ jsx(ListboxSelect, { ...props, ref });
|
|
2122
|
+
}
|
|
2123
|
+
return /* @__PURE__ */ jsx(NativeSelect, { ...props, ref });
|
|
2124
|
+
}
|
|
2125
|
+
);
|
|
1731
2126
|
Select.displayName = "Select";
|
|
1732
2127
|
function useControllableState(controlledValue, defaultValue, onChange) {
|
|
1733
2128
|
const [uncontrolledValue, setUncontrolledValue] = useState(defaultValue);
|
|
@@ -1806,7 +2201,7 @@ var Checkbox = forwardRef(
|
|
|
1806
2201
|
onChange: (e) => setChecked(e.target.checked),
|
|
1807
2202
|
className: cn(
|
|
1808
2203
|
sizeClasses6,
|
|
1809
|
-
"cursor-pointer rounded border border-zinc-300 bg-white text-blue-600 focus:ring-2 focus:ring-blue-500/40 focus:ring-offset-0 disabled:cursor-not-allowed disabled:opacity-50 dark:border-zinc-
|
|
2204
|
+
"cursor-pointer rounded border border-zinc-300 bg-white text-blue-600 transition-[border-color,box-shadow] duration-150 focus:ring-2 focus:ring-blue-500/40 focus:ring-offset-0 disabled:cursor-not-allowed disabled:opacity-50 dark:border-zinc-700 dark:bg-[#1e1e24]",
|
|
1810
2205
|
dirtyRingClasses(dirty),
|
|
1811
2206
|
error && "border-red-500"
|
|
1812
2207
|
)
|
|
@@ -1818,7 +2213,7 @@ var Checkbox = forwardRef(
|
|
|
1818
2213
|
{
|
|
1819
2214
|
htmlFor: checkboxId,
|
|
1820
2215
|
className: cn(
|
|
1821
|
-
"cursor-pointer text-sm text-zinc-700 dark:text-zinc-
|
|
2216
|
+
"cursor-pointer text-sm text-zinc-700 dark:text-zinc-100",
|
|
1822
2217
|
disabled && "cursor-not-allowed opacity-50"
|
|
1823
2218
|
),
|
|
1824
2219
|
children: [
|
|
@@ -1893,7 +2288,7 @@ function CheckboxGroup({
|
|
|
1893
2288
|
onChange: () => handleToggle(resolved.value),
|
|
1894
2289
|
className: cn(
|
|
1895
2290
|
sizeClasses6,
|
|
1896
|
-
"cursor-pointer rounded border border-zinc-300 bg-white text-blue-600 focus:ring-2 focus:ring-blue-500/40 focus:ring-offset-0 disabled:cursor-not-allowed disabled:opacity-50 dark:border-zinc-
|
|
2291
|
+
"cursor-pointer rounded border border-zinc-300 bg-white text-blue-600 transition-[border-color,box-shadow] duration-150 focus:ring-2 focus:ring-blue-500/40 focus:ring-offset-0 disabled:cursor-not-allowed disabled:opacity-50 dark:border-zinc-700 dark:bg-[#1e1e24]",
|
|
1897
2292
|
dirtyRingClasses(dirty),
|
|
1898
2293
|
error && "border-red-500"
|
|
1899
2294
|
)
|
|
@@ -1905,7 +2300,7 @@ function CheckboxGroup({
|
|
|
1905
2300
|
{
|
|
1906
2301
|
htmlFor: optionId,
|
|
1907
2302
|
className: cn(
|
|
1908
|
-
"cursor-pointer text-sm text-zinc-700 dark:text-zinc-
|
|
2303
|
+
"cursor-pointer text-sm text-zinc-700 dark:text-zinc-100",
|
|
1909
2304
|
(disabled || resolved.disabled) && "cursor-not-allowed opacity-50"
|
|
1910
2305
|
),
|
|
1911
2306
|
children: resolved.label
|
|
@@ -1990,7 +2385,7 @@ function RadioGroup({
|
|
|
1990
2385
|
onChange: () => setValue(resolved.value),
|
|
1991
2386
|
className: cn(
|
|
1992
2387
|
sizeClasses6,
|
|
1993
|
-
"cursor-pointer border border-zinc-300 bg-white text-blue-600 focus:ring-2 focus:ring-blue-500/40 focus:ring-offset-0 disabled:cursor-not-allowed disabled:opacity-50 dark:border-zinc-
|
|
2388
|
+
"cursor-pointer border border-zinc-300 bg-white text-blue-600 transition-[border-color,box-shadow] duration-150 focus:ring-2 focus:ring-blue-500/40 focus:ring-offset-0 disabled:cursor-not-allowed disabled:opacity-50 dark:border-zinc-700 dark:bg-[#1e1e24]",
|
|
1994
2389
|
dirtyRingClasses(dirty),
|
|
1995
2390
|
error && "border-red-500"
|
|
1996
2391
|
)
|
|
@@ -2002,7 +2397,7 @@ function RadioGroup({
|
|
|
2002
2397
|
{
|
|
2003
2398
|
htmlFor: optionId,
|
|
2004
2399
|
className: cn(
|
|
2005
|
-
"cursor-pointer text-sm text-zinc-700 dark:text-zinc-
|
|
2400
|
+
"cursor-pointer text-sm text-zinc-700 dark:text-zinc-100",
|
|
2006
2401
|
(disabled || resolved.disabled) && "cursor-not-allowed opacity-50"
|
|
2007
2402
|
),
|
|
2008
2403
|
children: resolved.label
|
|
@@ -2109,7 +2504,7 @@ var Switch = forwardRef(
|
|
|
2109
2504
|
className: cn(
|
|
2110
2505
|
"relative inline-flex shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500/40 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
|
2111
2506
|
trackSizes,
|
|
2112
|
-
checked ? trackColorMap[color] : "bg-zinc-200 dark:bg-zinc-
|
|
2507
|
+
checked ? trackColorMap[color] : "bg-zinc-200 dark:bg-zinc-600",
|
|
2113
2508
|
dirtyRingClasses(dirty),
|
|
2114
2509
|
error && "ring-2 ring-red-500/50"
|
|
2115
2510
|
),
|
|
@@ -2132,7 +2527,7 @@ var Switch = forwardRef(
|
|
|
2132
2527
|
{
|
|
2133
2528
|
htmlFor: switchId,
|
|
2134
2529
|
className: cn(
|
|
2135
|
-
"cursor-pointer text-sm text-zinc-700 dark:text-zinc-
|
|
2530
|
+
"cursor-pointer text-sm text-zinc-700 dark:text-zinc-100",
|
|
2136
2531
|
disabled && "cursor-not-allowed opacity-50"
|
|
2137
2532
|
),
|
|
2138
2533
|
children: [
|
|
@@ -2434,7 +2829,7 @@ function MultiSwitch({
|
|
|
2434
2829
|
role: "radiogroup",
|
|
2435
2830
|
id,
|
|
2436
2831
|
className: cn(
|
|
2437
|
-
"relative inline-flex rounded-lg border border-zinc-300 bg-zinc-100 dark:border-zinc-
|
|
2832
|
+
"relative inline-flex rounded-lg border border-zinc-300 bg-zinc-100 dark:border-zinc-700 dark:bg-zinc-800",
|
|
2438
2833
|
dirty && "ring-2 ring-amber-400/50",
|
|
2439
2834
|
error && "ring-2 ring-red-500/50",
|
|
2440
2835
|
disabled && "opacity-50 cursor-not-allowed",
|
|
@@ -3128,7 +3523,7 @@ function EmojiSelect({
|
|
|
3128
3523
|
"button",
|
|
3129
3524
|
{
|
|
3130
3525
|
type: "button",
|
|
3131
|
-
className: "flex items-center gap-2 rounded-lg border border-zinc-300 px-3 py-2 text-sm dark:border-zinc-
|
|
3526
|
+
className: "flex items-center gap-2 rounded-lg border border-zinc-300 px-3 py-2 text-sm transition-[border-color,box-shadow] duration-150 dark:border-zinc-700 dark:bg-[#1e1e24]",
|
|
3132
3527
|
onClick: () => setOpen(!open),
|
|
3133
3528
|
children: selected ? /* @__PURE__ */ jsx("span", { className: "text-xl", children: selected }) : /* @__PURE__ */ jsx("span", { className: "text-zinc-400", children: "Pick emoji" })
|
|
3134
3529
|
}
|
|
@@ -3141,7 +3536,7 @@ function EmojiSelect({
|
|
|
3141
3536
|
value: query,
|
|
3142
3537
|
onChange: (e) => setQuery(e.target.value),
|
|
3143
3538
|
placeholder,
|
|
3144
|
-
className: "mb-2 w-full rounded-md border border-zinc-200 px-2 py-1 text-sm dark:border-zinc-
|
|
3539
|
+
className: "mb-2 w-full rounded-md border border-zinc-200 px-2 py-1 text-sm transition-[border-color,box-shadow] duration-150 dark:border-zinc-700 dark:bg-[#1e1e24] dark:text-zinc-100",
|
|
3145
3540
|
autoFocus: true
|
|
3146
3541
|
}
|
|
3147
3542
|
),
|
|
@@ -3396,34 +3791,6 @@ var Table = Object.assign(TableRoot, {
|
|
|
3396
3791
|
Tray: TableTray,
|
|
3397
3792
|
RowTray: TableRowTray
|
|
3398
3793
|
});
|
|
3399
|
-
function Portal({ children, container }) {
|
|
3400
|
-
if (typeof document === "undefined") return null;
|
|
3401
|
-
const target = container ?? document.body;
|
|
3402
|
-
return createPortal(
|
|
3403
|
-
/* @__PURE__ */ jsx(PortalDarkWrapper, { children }),
|
|
3404
|
-
target
|
|
3405
|
-
);
|
|
3406
|
-
}
|
|
3407
|
-
function PortalDarkWrapper({ children }) {
|
|
3408
|
-
const ref = useRef(null);
|
|
3409
|
-
useEffect(() => {
|
|
3410
|
-
const root = document.documentElement;
|
|
3411
|
-
const wrapper = ref.current;
|
|
3412
|
-
if (!wrapper) return;
|
|
3413
|
-
const sync = () => {
|
|
3414
|
-
const isDark = root.classList.contains("dark") || root.getAttribute("data-theme") === "dark";
|
|
3415
|
-
wrapper.classList.toggle("dark", isDark);
|
|
3416
|
-
};
|
|
3417
|
-
sync();
|
|
3418
|
-
const observer = new MutationObserver(sync);
|
|
3419
|
-
observer.observe(root, {
|
|
3420
|
-
attributes: true,
|
|
3421
|
-
attributeFilter: ["class", "data-theme"]
|
|
3422
|
-
});
|
|
3423
|
-
return () => observer.disconnect();
|
|
3424
|
-
}, []);
|
|
3425
|
-
return /* @__PURE__ */ jsx("div", { ref, "data-react-fancy-portal": "", style: { display: "contents" }, children });
|
|
3426
|
-
}
|
|
3427
3794
|
var sizeClasses3 = {
|
|
3428
3795
|
xs: "text-xs",
|
|
3429
3796
|
sm: "text-sm",
|
|
@@ -4201,42 +4568,66 @@ var Callout = forwardRef(
|
|
|
4201
4568
|
);
|
|
4202
4569
|
Callout.displayName = "Callout";
|
|
4203
4570
|
var TimelineContext = createContext({
|
|
4204
|
-
|
|
4205
|
-
index: 0
|
|
4571
|
+
variant: "stacked",
|
|
4572
|
+
index: 0,
|
|
4573
|
+
total: 0,
|
|
4574
|
+
animated: true
|
|
4206
4575
|
});
|
|
4207
4576
|
function useTimeline() {
|
|
4208
4577
|
return useContext(TimelineContext);
|
|
4209
4578
|
}
|
|
4210
4579
|
var dotColorClasses2 = {
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
amber: "bg-amber-500
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
|
|
4217
|
-
|
|
4218
|
-
|
|
4219
|
-
|
|
4220
|
-
|
|
4221
|
-
|
|
4222
|
-
|
|
4580
|
+
red: "bg-red-500",
|
|
4581
|
+
orange: "bg-orange-500",
|
|
4582
|
+
amber: "bg-amber-500",
|
|
4583
|
+
yellow: "bg-yellow-500",
|
|
4584
|
+
lime: "bg-lime-500",
|
|
4585
|
+
green: "bg-green-500",
|
|
4586
|
+
emerald: "bg-emerald-500",
|
|
4587
|
+
teal: "bg-teal-500",
|
|
4588
|
+
cyan: "bg-cyan-500",
|
|
4589
|
+
sky: "bg-sky-500",
|
|
4590
|
+
blue: "bg-blue-500",
|
|
4591
|
+
indigo: "bg-indigo-500",
|
|
4592
|
+
violet: "bg-violet-500",
|
|
4593
|
+
purple: "bg-purple-500",
|
|
4594
|
+
fuchsia: "bg-fuchsia-500",
|
|
4595
|
+
pink: "bg-pink-500",
|
|
4596
|
+
rose: "bg-rose-500",
|
|
4597
|
+
zinc: "bg-zinc-300 dark:bg-zinc-600"
|
|
4223
4598
|
};
|
|
4224
4599
|
var ringColorClasses = {
|
|
4225
|
-
|
|
4226
|
-
|
|
4227
|
-
amber: "ring-amber-500/30
|
|
4228
|
-
|
|
4600
|
+
red: "ring-red-500/30",
|
|
4601
|
+
orange: "ring-orange-500/30",
|
|
4602
|
+
amber: "ring-amber-500/30",
|
|
4603
|
+
yellow: "ring-yellow-500/30",
|
|
4604
|
+
lime: "ring-lime-500/30",
|
|
4605
|
+
green: "ring-green-500/30",
|
|
4606
|
+
emerald: "ring-emerald-500/30",
|
|
4607
|
+
teal: "ring-teal-500/30",
|
|
4608
|
+
cyan: "ring-cyan-500/30",
|
|
4609
|
+
sky: "ring-sky-500/30",
|
|
4610
|
+
blue: "ring-blue-500/30",
|
|
4611
|
+
indigo: "ring-indigo-500/30",
|
|
4612
|
+
violet: "ring-violet-500/30",
|
|
4613
|
+
purple: "ring-purple-500/30",
|
|
4614
|
+
fuchsia: "ring-fuchsia-500/30",
|
|
4615
|
+
pink: "ring-pink-500/30",
|
|
4616
|
+
rose: "ring-rose-500/30",
|
|
4229
4617
|
zinc: "ring-zinc-400/30 dark:ring-zinc-500/30"
|
|
4230
4618
|
};
|
|
4231
|
-
function Dot({ icon, color, active }) {
|
|
4619
|
+
function Dot({ icon, emoji, color, active }) {
|
|
4232
4620
|
const c = color ?? "zinc";
|
|
4621
|
+
if (emoji) {
|
|
4622
|
+
return /* @__PURE__ */ jsx("span", { className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-full border border-zinc-200 bg-zinc-100 dark:border-zinc-700 dark:bg-zinc-800", children: /* @__PURE__ */ jsx("span", { className: "text-sm", children: emoji }) });
|
|
4623
|
+
}
|
|
4233
4624
|
if (icon) {
|
|
4234
4625
|
return /* @__PURE__ */ jsx(
|
|
4235
4626
|
"span",
|
|
4236
4627
|
{
|
|
4237
4628
|
className: cn(
|
|
4238
|
-
"flex h-
|
|
4239
|
-
|
|
4629
|
+
"flex h-8 w-8 shrink-0 items-center justify-center rounded-full text-white",
|
|
4630
|
+
dotColorClasses2[c],
|
|
4240
4631
|
active && "ring-4",
|
|
4241
4632
|
active && ringColorClasses[c]
|
|
4242
4633
|
),
|
|
@@ -4248,7 +4639,7 @@ function Dot({ icon, color, active }) {
|
|
|
4248
4639
|
"span",
|
|
4249
4640
|
{
|
|
4250
4641
|
className: cn(
|
|
4251
|
-
"h-3 w-3 rounded-full",
|
|
4642
|
+
"h-3 w-3 shrink-0 rounded-full",
|
|
4252
4643
|
dotColorClasses2[c],
|
|
4253
4644
|
active && "ring-4",
|
|
4254
4645
|
active && ringColorClasses[c]
|
|
@@ -4256,32 +4647,83 @@ function Dot({ icon, color, active }) {
|
|
|
4256
4647
|
}
|
|
4257
4648
|
);
|
|
4258
4649
|
}
|
|
4650
|
+
function useIntersectionReveal(animated) {
|
|
4651
|
+
const ref = useRef(null);
|
|
4652
|
+
const [visible, setVisible] = useState(!animated);
|
|
4653
|
+
useEffect(() => {
|
|
4654
|
+
if (!animated || !ref.current) return;
|
|
4655
|
+
const el = ref.current;
|
|
4656
|
+
const observer = new IntersectionObserver(
|
|
4657
|
+
([entry]) => {
|
|
4658
|
+
if (entry.isIntersecting) {
|
|
4659
|
+
setVisible(true);
|
|
4660
|
+
observer.disconnect();
|
|
4661
|
+
}
|
|
4662
|
+
},
|
|
4663
|
+
{ threshold: 0.2 }
|
|
4664
|
+
);
|
|
4665
|
+
observer.observe(el);
|
|
4666
|
+
return () => observer.disconnect();
|
|
4667
|
+
}, [animated]);
|
|
4668
|
+
return { ref, visible };
|
|
4669
|
+
}
|
|
4259
4670
|
var TimelineItem = forwardRef(
|
|
4260
|
-
({
|
|
4261
|
-
|
|
4262
|
-
|
|
4263
|
-
|
|
4264
|
-
|
|
4265
|
-
|
|
4266
|
-
|
|
4267
|
-
const { orientation, index } = useTimeline();
|
|
4268
|
-
if (orientation === "horizontal") {
|
|
4269
|
-
const isTop = index % 2 === 0;
|
|
4671
|
+
({ children, icon, emoji, date, color = "zinc", active = false, className }, _ref) => {
|
|
4672
|
+
const { variant, index, total, animated } = useTimeline();
|
|
4673
|
+
const { ref, visible } = useIntersectionReveal(animated);
|
|
4674
|
+
const isLast = index === total - 1;
|
|
4675
|
+
const isLargeDot = !!icon || !!emoji;
|
|
4676
|
+
const isEven = index % 2 === 0;
|
|
4677
|
+
if (variant === "horizontal") {
|
|
4270
4678
|
return /* @__PURE__ */ jsxs(
|
|
4271
4679
|
"div",
|
|
4272
4680
|
{
|
|
4273
4681
|
ref,
|
|
4274
4682
|
"data-react-fancy-timeline-item": "",
|
|
4275
|
-
className: cn(
|
|
4276
|
-
|
|
4683
|
+
className: cn(
|
|
4684
|
+
"flex flex-col items-center",
|
|
4685
|
+
!isLast && "min-w-40",
|
|
4686
|
+
animated && "transition duration-500 ease-out",
|
|
4687
|
+
animated && (visible ? "translate-y-0 opacity-100" : "translate-y-4 opacity-0"),
|
|
4688
|
+
className
|
|
4689
|
+
),
|
|
4277
4690
|
children: [
|
|
4278
|
-
/* @__PURE__ */
|
|
4279
|
-
|
|
4280
|
-
/* @__PURE__ */ jsx(
|
|
4281
|
-
/* @__PURE__ */ jsx("div", { className: "
|
|
4282
|
-
/* @__PURE__ */ jsx("div", { className: "h-px flex-1 bg-zinc-200 dark:bg-zinc-700" })
|
|
4691
|
+
/* @__PURE__ */ jsxs("div", { className: "flex h-8 w-full items-center", children: [
|
|
4692
|
+
index > 0 ? /* @__PURE__ */ jsx("div", { className: "h-px flex-1 bg-zinc-200 dark:bg-zinc-700" }) : /* @__PURE__ */ jsx("div", { className: "flex-1" }),
|
|
4693
|
+
/* @__PURE__ */ jsx(Dot, { icon, emoji, color, active }),
|
|
4694
|
+
!isLast ? /* @__PURE__ */ jsx("div", { className: "h-px flex-1 bg-zinc-200 dark:bg-zinc-700" }) : /* @__PURE__ */ jsx("div", { className: "flex-1" })
|
|
4283
4695
|
] }),
|
|
4284
|
-
/* @__PURE__ */
|
|
4696
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-3 max-w-40 px-2 text-center", children: [
|
|
4697
|
+
date && /* @__PURE__ */ jsx("time", { className: "text-xs font-medium uppercase tracking-wide text-zinc-500 dark:text-zinc-400", children: date }),
|
|
4698
|
+
children
|
|
4699
|
+
] })
|
|
4700
|
+
]
|
|
4701
|
+
}
|
|
4702
|
+
);
|
|
4703
|
+
}
|
|
4704
|
+
if (variant === "alternating") {
|
|
4705
|
+
return /* @__PURE__ */ jsxs(
|
|
4706
|
+
"div",
|
|
4707
|
+
{
|
|
4708
|
+
ref,
|
|
4709
|
+
"data-react-fancy-timeline-item": "",
|
|
4710
|
+
className: cn(
|
|
4711
|
+
"relative flex gap-x-4 md:grid md:grid-cols-[1fr_1.5rem_1fr] md:gap-x-6",
|
|
4712
|
+
animated && "transition duration-500 ease-out",
|
|
4713
|
+
animated && (visible ? "translate-y-0 opacity-100" : "translate-y-4 opacity-0"),
|
|
4714
|
+
className
|
|
4715
|
+
),
|
|
4716
|
+
children: [
|
|
4717
|
+
/* @__PURE__ */ jsx("div", { className: "relative z-10 flex w-8 shrink-0 justify-center md:col-start-2 md:row-start-1 md:w-auto md:justify-center", children: !isLargeDot ? /* @__PURE__ */ jsx("div", { className: "mt-1.5", children: /* @__PURE__ */ jsx(Dot, { icon, emoji, color, active }) }) : /* @__PURE__ */ jsx(Dot, { icon, emoji, color, active }) }),
|
|
4718
|
+
/* @__PURE__ */ jsxs("div", { className: cn(
|
|
4719
|
+
"min-w-0 flex-1",
|
|
4720
|
+
!isLast && "pb-8",
|
|
4721
|
+
isLargeDot && "pt-1",
|
|
4722
|
+
isEven ? "md:col-start-1 md:row-start-1 md:text-right" : "md:col-start-3"
|
|
4723
|
+
), children: [
|
|
4724
|
+
date && /* @__PURE__ */ jsx("time", { className: "text-xs font-medium uppercase tracking-wide text-zinc-500 dark:text-zinc-400", children: date }),
|
|
4725
|
+
children
|
|
4726
|
+
] })
|
|
4285
4727
|
]
|
|
4286
4728
|
}
|
|
4287
4729
|
);
|
|
@@ -4291,11 +4733,18 @@ var TimelineItem = forwardRef(
|
|
|
4291
4733
|
{
|
|
4292
4734
|
ref,
|
|
4293
4735
|
"data-react-fancy-timeline-item": "",
|
|
4294
|
-
className: cn(
|
|
4736
|
+
className: cn(
|
|
4737
|
+
"relative flex gap-x-4",
|
|
4738
|
+
animated && "transition duration-500 ease-out",
|
|
4739
|
+
animated && (visible ? "translate-y-0 opacity-100" : "translate-y-4 opacity-0"),
|
|
4740
|
+
className
|
|
4741
|
+
),
|
|
4295
4742
|
children: [
|
|
4296
|
-
/* @__PURE__ */ jsx("div", { className: "
|
|
4297
|
-
/* @__PURE__ */
|
|
4298
|
-
|
|
4743
|
+
/* @__PURE__ */ jsx("div", { className: "relative z-10 flex w-8 shrink-0 justify-center", children: !isLargeDot ? /* @__PURE__ */ jsx("div", { className: "mt-1.5", children: /* @__PURE__ */ jsx(Dot, { icon, emoji, color, active }) }) : /* @__PURE__ */ jsx(Dot, { icon, emoji, color, active }) }),
|
|
4744
|
+
/* @__PURE__ */ jsxs("div", { className: cn("min-w-0 flex-1", !isLast && "pb-8", isLargeDot && "pt-1"), children: [
|
|
4745
|
+
date && /* @__PURE__ */ jsx("time", { className: "text-xs font-medium uppercase tracking-wide text-zinc-500 dark:text-zinc-400", children: date }),
|
|
4746
|
+
children
|
|
4747
|
+
] })
|
|
4299
4748
|
]
|
|
4300
4749
|
}
|
|
4301
4750
|
);
|
|
@@ -4303,8 +4752,8 @@ var TimelineItem = forwardRef(
|
|
|
4303
4752
|
);
|
|
4304
4753
|
TimelineItem.displayName = "TimelineItem";
|
|
4305
4754
|
var TimelineBlock = forwardRef(
|
|
4306
|
-
({ heading, children, icon, color = "zinc", active = false, className }, ref) => {
|
|
4307
|
-
return /* @__PURE__ */ jsx(TimelineItem, { icon, color, active, children: /* @__PURE__ */ jsxs(
|
|
4755
|
+
({ heading, children, icon, emoji, color = "zinc", active = false, className }, ref) => {
|
|
4756
|
+
return /* @__PURE__ */ jsx(TimelineItem, { icon, emoji, color, active, children: /* @__PURE__ */ jsxs(
|
|
4308
4757
|
"div",
|
|
4309
4758
|
{
|
|
4310
4759
|
ref,
|
|
@@ -4313,118 +4762,76 @@ var TimelineBlock = forwardRef(
|
|
|
4313
4762
|
"rounded-lg border border-zinc-200 bg-white p-4 dark:border-zinc-700 dark:bg-zinc-900",
|
|
4314
4763
|
active && "ring-2 ring-blue-500/20 dark:ring-blue-400/20",
|
|
4315
4764
|
className
|
|
4316
|
-
),
|
|
4317
|
-
children: [
|
|
4318
|
-
heading && /* @__PURE__ */ jsx("div", { className: "mb-2 text-sm font-semibold text-zinc-900 dark:text-zinc-100", children: heading }),
|
|
4319
|
-
/* @__PURE__ */ jsx("div", { className: "text-sm text-zinc-600 dark:text-zinc-400", children })
|
|
4320
|
-
]
|
|
4321
|
-
}
|
|
4322
|
-
) });
|
|
4323
|
-
}
|
|
4324
|
-
);
|
|
4325
|
-
TimelineBlock.displayName = "TimelineBlock";
|
|
4326
|
-
var TimelineRoot = forwardRef(
|
|
4327
|
-
({ children, orientation = "vertical", className }, ref) => {
|
|
4328
|
-
const items = Children.toArray(children);
|
|
4329
|
-
return /* @__PURE__ */ jsx(
|
|
4330
|
-
"div",
|
|
4331
|
-
{
|
|
4332
|
-
ref,
|
|
4333
|
-
"data-react-fancy-timeline": "",
|
|
4334
|
-
"data-orientation": orientation,
|
|
4335
|
-
className: cn(
|
|
4336
|
-
orientation === "vertical" ? "flex flex-col" : "flex flex-row items-center overflow-x-auto",
|
|
4337
|
-
className
|
|
4338
|
-
),
|
|
4339
|
-
children: items.map((child, i) => /* @__PURE__ */ jsx(TimelineContext.Provider, { value: { orientation, index: i }, children: child }, i))
|
|
4340
|
-
}
|
|
4341
|
-
);
|
|
4342
|
-
}
|
|
4343
|
-
);
|
|
4344
|
-
TimelineRoot.displayName = "Timeline";
|
|
4345
|
-
var Timeline = Object.assign(TimelineRoot, {
|
|
4346
|
-
Item: TimelineItem,
|
|
4347
|
-
Block: TimelineBlock
|
|
4348
|
-
});
|
|
4349
|
-
function getPosition(anchor, floating, placement, offset) {
|
|
4350
|
-
let x = 0;
|
|
4351
|
-
let y = 0;
|
|
4352
|
-
const base = placement.split("-")[0];
|
|
4353
|
-
const align = placement.split("-")[1];
|
|
4354
|
-
switch (base) {
|
|
4355
|
-
case "top":
|
|
4356
|
-
x = anchor.left + anchor.width / 2 - floating.width / 2;
|
|
4357
|
-
y = anchor.top - floating.height - offset;
|
|
4358
|
-
break;
|
|
4359
|
-
case "bottom":
|
|
4360
|
-
x = anchor.left + anchor.width / 2 - floating.width / 2;
|
|
4361
|
-
y = anchor.bottom + offset;
|
|
4362
|
-
break;
|
|
4363
|
-
case "left":
|
|
4364
|
-
x = anchor.left - floating.width - offset;
|
|
4365
|
-
y = anchor.top + anchor.height / 2 - floating.height / 2;
|
|
4366
|
-
break;
|
|
4367
|
-
case "right":
|
|
4368
|
-
x = anchor.right + offset;
|
|
4369
|
-
y = anchor.top + anchor.height / 2 - floating.height / 2;
|
|
4370
|
-
break;
|
|
4371
|
-
}
|
|
4372
|
-
if (base === "top" || base === "bottom") {
|
|
4373
|
-
if (align === "start") x = anchor.left;
|
|
4374
|
-
else if (align === "end") x = anchor.right - floating.width;
|
|
4375
|
-
}
|
|
4376
|
-
if (base === "left" || base === "right") {
|
|
4377
|
-
if (align === "start") y = anchor.top;
|
|
4378
|
-
else if (align === "end") y = anchor.bottom - floating.height;
|
|
4379
|
-
}
|
|
4380
|
-
let finalPlacement = placement;
|
|
4381
|
-
const vw = window.innerWidth;
|
|
4382
|
-
const vh = window.innerHeight;
|
|
4383
|
-
if (base === "bottom" && y + floating.height > vh) {
|
|
4384
|
-
y = anchor.top - floating.height - offset;
|
|
4385
|
-
finalPlacement = placement.replace("bottom", "top");
|
|
4386
|
-
} else if (base === "top" && y < 0) {
|
|
4387
|
-
y = anchor.bottom + offset;
|
|
4388
|
-
finalPlacement = placement.replace("top", "bottom");
|
|
4765
|
+
),
|
|
4766
|
+
children: [
|
|
4767
|
+
heading && /* @__PURE__ */ jsx("div", { className: "mb-2 text-sm font-semibold text-zinc-900 dark:text-zinc-100", children: heading }),
|
|
4768
|
+
/* @__PURE__ */ jsx("div", { className: "text-sm text-zinc-600 dark:text-zinc-400", children })
|
|
4769
|
+
]
|
|
4770
|
+
}
|
|
4771
|
+
) });
|
|
4389
4772
|
}
|
|
4390
|
-
|
|
4391
|
-
|
|
4392
|
-
|
|
4393
|
-
|
|
4394
|
-
|
|
4395
|
-
|
|
4396
|
-
|
|
4397
|
-
|
|
4398
|
-
|
|
4399
|
-
|
|
4400
|
-
|
|
4401
|
-
|
|
4402
|
-
|
|
4403
|
-
const
|
|
4404
|
-
|
|
4405
|
-
|
|
4406
|
-
|
|
4407
|
-
|
|
4408
|
-
|
|
4409
|
-
|
|
4410
|
-
|
|
4411
|
-
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
|
|
4415
|
-
|
|
4416
|
-
|
|
4417
|
-
|
|
4418
|
-
|
|
4419
|
-
|
|
4420
|
-
|
|
4421
|
-
|
|
4422
|
-
|
|
4423
|
-
|
|
4424
|
-
|
|
4425
|
-
|
|
4426
|
-
|
|
4427
|
-
|
|
4773
|
+
);
|
|
4774
|
+
TimelineBlock.displayName = "TimelineBlock";
|
|
4775
|
+
var TimelineRoot = forwardRef(
|
|
4776
|
+
({
|
|
4777
|
+
children,
|
|
4778
|
+
variant: variantProp,
|
|
4779
|
+
orientation,
|
|
4780
|
+
events,
|
|
4781
|
+
heading,
|
|
4782
|
+
description,
|
|
4783
|
+
animated = true,
|
|
4784
|
+
className
|
|
4785
|
+
}, ref) => {
|
|
4786
|
+
const scrollRef = useRef(null);
|
|
4787
|
+
let variant = variantProp ?? "stacked";
|
|
4788
|
+
if (!variantProp && orientation) {
|
|
4789
|
+
variant = orientation === "horizontal" ? "horizontal" : "stacked";
|
|
4790
|
+
}
|
|
4791
|
+
const isHorizontal = variant === "horizontal";
|
|
4792
|
+
const isAlternating = variant === "alternating";
|
|
4793
|
+
const items = events ? events.map((e, i) => /* @__PURE__ */ jsxs(TimelineItem, { date: e.date, emoji: e.emoji, icon: e.icon, color: e.color, children: [
|
|
4794
|
+
e.title && /* @__PURE__ */ jsx("h3", { className: "font-semibold text-zinc-900 dark:text-white", children: e.title }),
|
|
4795
|
+
e.description && /* @__PURE__ */ jsx("div", { className: "mt-1 text-sm leading-relaxed text-zinc-600 dark:text-zinc-400", children: e.description })
|
|
4796
|
+
] }, i)) : Children.toArray(children);
|
|
4797
|
+
const handleWheel = useCallback((e) => {
|
|
4798
|
+
if (!scrollRef.current) return;
|
|
4799
|
+
e.preventDefault();
|
|
4800
|
+
scrollRef.current.scrollLeft += e.deltaY;
|
|
4801
|
+
}, []);
|
|
4802
|
+
const content = items.map((child, i) => /* @__PURE__ */ jsx(TimelineContext.Provider, { value: { variant, index: i, total: items.length, animated }, children: child }, i));
|
|
4803
|
+
return /* @__PURE__ */ jsxs("div", { ref, "data-react-fancy-timeline": "", "data-variant": variant, className, children: [
|
|
4804
|
+
(heading || description) && /* @__PURE__ */ jsxs("div", { className: "mb-8", children: [
|
|
4805
|
+
heading && /* @__PURE__ */ jsx("h2", { className: "text-xl font-semibold text-zinc-900 dark:text-white", children: heading }),
|
|
4806
|
+
description && /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-zinc-500 dark:text-zinc-400", children: description })
|
|
4807
|
+
] }),
|
|
4808
|
+
isHorizontal ? /* @__PURE__ */ jsx(
|
|
4809
|
+
"div",
|
|
4810
|
+
{
|
|
4811
|
+
ref: scrollRef,
|
|
4812
|
+
className: "overflow-x-auto pb-4 -mb-4",
|
|
4813
|
+
style: { scrollbarWidth: "thin", scrollbarColor: "rgb(161 161 170) transparent" },
|
|
4814
|
+
onWheel: handleWheel,
|
|
4815
|
+
children: /* @__PURE__ */ jsx("div", { className: "flex min-w-max items-start", children: content })
|
|
4816
|
+
}
|
|
4817
|
+
) : (
|
|
4818
|
+
/* Vertical variants: continuous background line behind all events */
|
|
4819
|
+
/* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
4820
|
+
items.length > 1 && /* @__PURE__ */ jsx("div", { className: cn(
|
|
4821
|
+
"absolute top-0 bottom-0 w-px bg-zinc-200 dark:bg-zinc-700",
|
|
4822
|
+
isAlternating ? "left-4 md:left-1/2 md:-translate-x-px" : "left-4"
|
|
4823
|
+
) }),
|
|
4824
|
+
content
|
|
4825
|
+
] })
|
|
4826
|
+
)
|
|
4827
|
+
] });
|
|
4828
|
+
}
|
|
4829
|
+
);
|
|
4830
|
+
TimelineRoot.displayName = "Timeline";
|
|
4831
|
+
var Timeline = Object.assign(TimelineRoot, {
|
|
4832
|
+
Item: TimelineItem,
|
|
4833
|
+
Block: TimelineBlock
|
|
4834
|
+
});
|
|
4428
4835
|
var Tooltip = forwardRef(
|
|
4429
4836
|
function Tooltip2({ children, content, placement = "top", delay = 200, offset = 8, className }, _ref) {
|
|
4430
4837
|
const [open, setOpen] = useState(false);
|
|
@@ -4459,7 +4866,7 @@ var Tooltip = forwardRef(
|
|
|
4459
4866
|
"data-react-fancy-tooltip": "",
|
|
4460
4867
|
role: "tooltip",
|
|
4461
4868
|
className: cn(
|
|
4462
|
-
"fancy-fade-in pointer-events-none fixed z-50 max-w-xs rounded-lg bg-zinc-900 px-3 py-1.5 text-sm text-white shadow-lg dark:bg-zinc-
|
|
4869
|
+
"fancy-fade-in pointer-events-none fixed z-50 max-w-xs rounded-lg bg-zinc-900 px-3 py-1.5 text-sm text-white shadow-lg dark:bg-zinc-700 dark:text-zinc-100",
|
|
4463
4870
|
className
|
|
4464
4871
|
),
|
|
4465
4872
|
style: { left: position.x, top: position.y },
|
|
@@ -4469,7 +4876,7 @@ var Tooltip = forwardRef(
|
|
|
4469
4876
|
"div",
|
|
4470
4877
|
{
|
|
4471
4878
|
className: cn(
|
|
4472
|
-
"absolute h-2 w-2 rotate-45 bg-zinc-900 dark:bg-zinc-
|
|
4879
|
+
"absolute h-2 w-2 rotate-45 bg-zinc-900 dark:bg-zinc-700",
|
|
4473
4880
|
position.placement.startsWith("top") && "bottom-[-4px] left-1/2 -translate-x-1/2",
|
|
4474
4881
|
position.placement.startsWith("bottom") && "top-[-4px] left-1/2 -translate-x-1/2",
|
|
4475
4882
|
position.placement.startsWith("left") && "right-[-4px] top-1/2 -translate-y-1/2",
|
|
@@ -4492,78 +4899,26 @@ function usePopover() {
|
|
|
4492
4899
|
}
|
|
4493
4900
|
return ctx;
|
|
4494
4901
|
}
|
|
4495
|
-
function PopoverTrigger({ children }) {
|
|
4496
|
-
const { setOpen, open, anchorRef } = usePopover();
|
|
4497
|
-
return
|
|
4498
|
-
|
|
4499
|
-
|
|
4500
|
-
|
|
4501
|
-
|
|
4502
|
-
|
|
4503
|
-
|
|
4504
|
-
|
|
4505
|
-
|
|
4506
|
-
|
|
4507
|
-
|
|
4508
|
-
|
|
4509
|
-
const el = ref.current;
|
|
4510
|
-
if (!el || el.contains(event.target)) return;
|
|
4511
|
-
if (ignoreRef?.current?.contains(event.target)) return;
|
|
4512
|
-
handler(event);
|
|
4513
|
-
};
|
|
4514
|
-
document.addEventListener("mousedown", listener);
|
|
4515
|
-
document.addEventListener("touchstart", listener);
|
|
4516
|
-
return () => {
|
|
4517
|
-
document.removeEventListener("mousedown", listener);
|
|
4518
|
-
document.removeEventListener("touchstart", listener);
|
|
4519
|
-
};
|
|
4520
|
-
}, [ref, handler, enabled, ignoreRef]);
|
|
4521
|
-
}
|
|
4522
|
-
function useEscapeKey(handler, enabled = true) {
|
|
4523
|
-
useEffect(() => {
|
|
4524
|
-
if (!enabled) return;
|
|
4525
|
-
const listener = (event) => {
|
|
4526
|
-
if (event.key === "Escape") {
|
|
4527
|
-
handler();
|
|
4528
|
-
}
|
|
4529
|
-
};
|
|
4530
|
-
document.addEventListener("keydown", listener);
|
|
4531
|
-
return () => document.removeEventListener("keydown", listener);
|
|
4532
|
-
}, [handler, enabled]);
|
|
4533
|
-
}
|
|
4534
|
-
function useAnimation({
|
|
4535
|
-
open,
|
|
4536
|
-
enterClass,
|
|
4537
|
-
exitClass
|
|
4538
|
-
}) {
|
|
4539
|
-
const [mounted, setMounted] = useState(open);
|
|
4540
|
-
const [animClass, setAnimClass] = useState(open ? enterClass : "");
|
|
4541
|
-
const ref = useRef(null);
|
|
4542
|
-
useEffect(() => {
|
|
4543
|
-
if (open) {
|
|
4544
|
-
setMounted(true);
|
|
4545
|
-
setAnimClass(enterClass);
|
|
4546
|
-
} else if (mounted) {
|
|
4547
|
-
setAnimClass(exitClass);
|
|
4548
|
-
}
|
|
4549
|
-
}, [open, enterClass, exitClass, mounted]);
|
|
4550
|
-
const handleAnimationEnd = useCallback(() => {
|
|
4551
|
-
if (!open) {
|
|
4552
|
-
setMounted(false);
|
|
4553
|
-
setAnimClass("");
|
|
4902
|
+
function PopoverTrigger({ children, className }) {
|
|
4903
|
+
const { setOpen, open, anchorRef, hover, onHoverEnter, onHoverLeave } = usePopover();
|
|
4904
|
+
return /* @__PURE__ */ jsx(
|
|
4905
|
+
"span",
|
|
4906
|
+
{
|
|
4907
|
+
ref: anchorRef,
|
|
4908
|
+
"data-react-fancy-popover-trigger": "",
|
|
4909
|
+
className: cn("inline-flex", className),
|
|
4910
|
+
onClick: hover ? void 0 : () => setOpen(!open),
|
|
4911
|
+
onMouseEnter: hover ? onHoverEnter : void 0,
|
|
4912
|
+
onMouseLeave: hover ? onHoverLeave : void 0,
|
|
4913
|
+
"aria-expanded": open,
|
|
4914
|
+
"aria-haspopup": true,
|
|
4915
|
+
children
|
|
4554
4916
|
}
|
|
4555
|
-
|
|
4556
|
-
useEffect(() => {
|
|
4557
|
-
const el = ref.current;
|
|
4558
|
-
if (!el) return;
|
|
4559
|
-
el.addEventListener("animationend", handleAnimationEnd);
|
|
4560
|
-
return () => el.removeEventListener("animationend", handleAnimationEnd);
|
|
4561
|
-
}, [handleAnimationEnd, mounted]);
|
|
4562
|
-
return { mounted, className: animClass, ref };
|
|
4917
|
+
);
|
|
4563
4918
|
}
|
|
4919
|
+
PopoverTrigger.displayName = "PopoverTrigger";
|
|
4564
4920
|
function PopoverContent({ children, className }) {
|
|
4565
|
-
const { open, setOpen, anchorRef, placement, offset } = usePopover();
|
|
4566
|
-
const floatingRef = useRef(null);
|
|
4921
|
+
const { open, setOpen, anchorRef, floatingRef, placement, offset, hover, onHoverEnter, onHoverLeave } = usePopover();
|
|
4567
4922
|
const outsideRef = useRef(null);
|
|
4568
4923
|
const position = useFloatingPosition(anchorRef, floatingRef, {
|
|
4569
4924
|
placement,
|
|
@@ -4571,29 +4926,26 @@ function PopoverContent({ children, className }) {
|
|
|
4571
4926
|
enabled: open
|
|
4572
4927
|
});
|
|
4573
4928
|
const close = useCallback(() => setOpen(false), [setOpen]);
|
|
4574
|
-
useOutsideClick(outsideRef, close, open, anchorRef);
|
|
4929
|
+
useOutsideClick(outsideRef, close, open && !hover, anchorRef);
|
|
4575
4930
|
useEscapeKey(close, open);
|
|
4576
|
-
const
|
|
4577
|
-
|
|
4578
|
-
enterClass: "fancy-scale-in",
|
|
4579
|
-
exitClass: "fancy-fade-out"
|
|
4580
|
-
});
|
|
4581
|
-
if (!mounted) return null;
|
|
4931
|
+
const positioned = position.x !== -9999 && position.y !== -9999;
|
|
4932
|
+
if (!open) return null;
|
|
4582
4933
|
return /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(
|
|
4583
4934
|
"div",
|
|
4584
4935
|
{
|
|
4585
4936
|
ref: (node) => {
|
|
4586
4937
|
outsideRef.current = node;
|
|
4587
4938
|
floatingRef.current = node;
|
|
4588
|
-
animRef.current = node;
|
|
4589
4939
|
},
|
|
4590
4940
|
"data-react-fancy-popover": "",
|
|
4591
4941
|
className: cn(
|
|
4592
4942
|
"fixed z-50 rounded-xl border border-zinc-200 bg-white p-4 text-zinc-700 shadow-lg dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-200 dark:shadow-zinc-950/50",
|
|
4593
|
-
|
|
4943
|
+
positioned ? "fancy-scale-in" : "invisible",
|
|
4594
4944
|
className
|
|
4595
4945
|
),
|
|
4596
4946
|
style: { left: position.x, top: position.y },
|
|
4947
|
+
onMouseEnter: hover ? onHoverEnter : void 0,
|
|
4948
|
+
onMouseLeave: hover ? onHoverLeave : void 0,
|
|
4597
4949
|
children
|
|
4598
4950
|
}
|
|
4599
4951
|
) });
|
|
@@ -4605,17 +4957,37 @@ function PopoverRoot({
|
|
|
4605
4957
|
defaultOpen = false,
|
|
4606
4958
|
onOpenChange,
|
|
4607
4959
|
placement = "bottom",
|
|
4608
|
-
offset = 8
|
|
4960
|
+
offset = 8,
|
|
4961
|
+
hover = false,
|
|
4962
|
+
hoverDelay = 200,
|
|
4963
|
+
hoverCloseDelay = 300
|
|
4609
4964
|
}) {
|
|
4610
|
-
const [
|
|
4611
|
-
|
|
4612
|
-
|
|
4613
|
-
onOpenChange
|
|
4614
|
-
);
|
|
4965
|
+
const [internalOpen, setInternalOpen] = useState(defaultOpen);
|
|
4966
|
+
const isControlled = controlledOpen !== void 0;
|
|
4967
|
+
const open = isControlled ? controlledOpen : internalOpen;
|
|
4615
4968
|
const anchorRef = useRef(null);
|
|
4969
|
+
const floatingRef = useRef(null);
|
|
4970
|
+
const hoverTimeoutRef = useRef(void 0);
|
|
4971
|
+
const setOpen = useCallback(
|
|
4972
|
+
(next) => {
|
|
4973
|
+
if (!isControlled) setInternalOpen(next);
|
|
4974
|
+
onOpenChange?.(next);
|
|
4975
|
+
},
|
|
4976
|
+
[isControlled, onOpenChange]
|
|
4977
|
+
);
|
|
4978
|
+
const onHoverEnter = useCallback(() => {
|
|
4979
|
+
if (!hover) return;
|
|
4980
|
+
clearTimeout(hoverTimeoutRef.current);
|
|
4981
|
+
hoverTimeoutRef.current = setTimeout(() => setOpen(true), hoverDelay);
|
|
4982
|
+
}, [hover, hoverDelay, setOpen]);
|
|
4983
|
+
const onHoverLeave = useCallback(() => {
|
|
4984
|
+
if (!hover) return;
|
|
4985
|
+
clearTimeout(hoverTimeoutRef.current);
|
|
4986
|
+
hoverTimeoutRef.current = setTimeout(() => setOpen(false), hoverCloseDelay);
|
|
4987
|
+
}, [hover, hoverCloseDelay, setOpen]);
|
|
4616
4988
|
const ctx = useMemo(
|
|
4617
|
-
() => ({ open, setOpen, anchorRef, placement, offset }),
|
|
4618
|
-
[open, setOpen,
|
|
4989
|
+
() => ({ open, setOpen, anchorRef, floatingRef, placement, offset, hover, onHoverEnter, onHoverLeave }),
|
|
4990
|
+
[open, setOpen, placement, offset, hover, onHoverEnter, onHoverLeave]
|
|
4619
4991
|
);
|
|
4620
4992
|
return /* @__PURE__ */ jsx(PopoverContext.Provider, { value: ctx, children });
|
|
4621
4993
|
}
|
|
@@ -4643,6 +5015,36 @@ function DropdownTrigger({ children }) {
|
|
|
4643
5015
|
});
|
|
4644
5016
|
}
|
|
4645
5017
|
DropdownTrigger.displayName = "DropdownTrigger";
|
|
5018
|
+
function useAnimation({
|
|
5019
|
+
open,
|
|
5020
|
+
enterClass,
|
|
5021
|
+
exitClass
|
|
5022
|
+
}) {
|
|
5023
|
+
const [mounted, setMounted] = useState(open);
|
|
5024
|
+
const [animClass, setAnimClass] = useState(open ? enterClass : "");
|
|
5025
|
+
const ref = useRef(null);
|
|
5026
|
+
useEffect(() => {
|
|
5027
|
+
if (open) {
|
|
5028
|
+
setMounted(true);
|
|
5029
|
+
setAnimClass(enterClass);
|
|
5030
|
+
} else if (mounted) {
|
|
5031
|
+
setAnimClass(exitClass);
|
|
5032
|
+
}
|
|
5033
|
+
}, [open, enterClass, exitClass, mounted]);
|
|
5034
|
+
const handleAnimationEnd = useCallback(() => {
|
|
5035
|
+
if (!open) {
|
|
5036
|
+
setMounted(false);
|
|
5037
|
+
setAnimClass("");
|
|
5038
|
+
}
|
|
5039
|
+
}, [open]);
|
|
5040
|
+
useEffect(() => {
|
|
5041
|
+
const el = ref.current;
|
|
5042
|
+
if (!el) return;
|
|
5043
|
+
el.addEventListener("animationend", handleAnimationEnd);
|
|
5044
|
+
return () => el.removeEventListener("animationend", handleAnimationEnd);
|
|
5045
|
+
}, [handleAnimationEnd, mounted]);
|
|
5046
|
+
return { mounted, className: animClass, ref };
|
|
5047
|
+
}
|
|
4646
5048
|
function DropdownItems({ children, className }) {
|
|
4647
5049
|
const { open, setOpen, anchorRef, activeIndex, setActiveIndex, placement, offset } = useDropdown();
|
|
4648
5050
|
const floatingRef = useRef(null);
|
|
@@ -5961,7 +6363,7 @@ var Autocomplete = forwardRef(
|
|
|
5961
6363
|
role: "combobox",
|
|
5962
6364
|
"aria-expanded": open,
|
|
5963
6365
|
"aria-autocomplete": "list",
|
|
5964
|
-
className: "w-full rounded-lg border border-zinc-200 bg-white px-3 py-2 text-sm text-zinc-900 placeholder:text-zinc-400 outline-none transition-
|
|
6366
|
+
className: "w-full rounded-lg border border-zinc-200 bg-white px-3 py-2 text-sm text-zinc-900 placeholder:text-zinc-400 outline-none transition-[border-color,box-shadow] duration-150 focus:border-blue-500 focus:ring-2 focus:ring-blue-500/40 dark:border-zinc-700 dark:bg-[#1e1e24] dark:text-zinc-100 dark:placeholder:text-zinc-500 dark:focus:border-blue-400 dark:focus:ring-blue-400/20"
|
|
5965
6367
|
}
|
|
5966
6368
|
),
|
|
5967
6369
|
open && /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(
|
|
@@ -6055,7 +6457,7 @@ var Pillbox = forwardRef(
|
|
|
6055
6457
|
"data-react-fancy-pillbox": "",
|
|
6056
6458
|
ref,
|
|
6057
6459
|
className: cn(
|
|
6058
|
-
"flex flex-wrap items-center gap-1.5 rounded-lg border border-zinc-200 bg-white px-3 py-2 transition-
|
|
6460
|
+
"flex flex-wrap items-center gap-1.5 rounded-lg border border-zinc-200 bg-white px-3 py-2 transition-[border-color,box-shadow] duration-150 focus-within:border-blue-500 focus-within:ring-2 focus-within:ring-blue-500/40 dark:border-zinc-700 dark:bg-[#1e1e24] dark:text-zinc-100 dark:focus-within:border-blue-400 dark:focus-within:ring-blue-400/20",
|
|
6059
6461
|
disabled && "cursor-not-allowed opacity-50",
|
|
6060
6462
|
className
|
|
6061
6463
|
),
|
|
@@ -6186,7 +6588,7 @@ var OtpInput = forwardRef(
|
|
|
6186
6588
|
onFocus: (e) => e.target.select(),
|
|
6187
6589
|
disabled,
|
|
6188
6590
|
autoFocus: autoFocus && i === 0,
|
|
6189
|
-
className: "h-12 w-10 rounded-lg border border-zinc-200 bg-white text-center text-lg font-medium outline-none transition-
|
|
6591
|
+
className: "h-12 w-10 rounded-lg border border-zinc-200 bg-white text-center text-lg font-medium text-zinc-900 outline-none transition-[border-color,box-shadow] duration-150 focus:border-blue-500 focus:ring-2 focus:ring-blue-500/40 dark:border-zinc-700 dark:bg-[#1e1e24] dark:text-zinc-100 dark:focus:border-blue-400 dark:focus:ring-blue-400/20",
|
|
6190
6592
|
"aria-label": `Digit ${i + 1}`
|
|
6191
6593
|
},
|
|
6192
6594
|
i
|
|
@@ -6235,7 +6637,7 @@ function FileUploadDropzone({
|
|
|
6235
6637
|
onClick: () => !disabled && inputRef.current?.click(),
|
|
6236
6638
|
className: cn(
|
|
6237
6639
|
"flex cursor-pointer flex-col items-center justify-center rounded-xl border-2 border-dashed p-8 text-center transition-colors",
|
|
6238
|
-
dragOver ? "border-blue-400 bg-blue-50 dark:border-blue-500 dark:bg-blue-950" : "border-zinc-300 hover:border-zinc-400 dark:border-zinc-
|
|
6640
|
+
dragOver ? "border-blue-400 bg-blue-50 dark:border-blue-500 dark:bg-blue-950" : "border-zinc-300 hover:border-zinc-400 dark:border-zinc-700 dark:hover:border-zinc-500",
|
|
6239
6641
|
disabled && "cursor-not-allowed opacity-50",
|
|
6240
6642
|
className
|
|
6241
6643
|
),
|
|
@@ -7595,6 +7997,7 @@ function usePanZoom({
|
|
|
7595
7997
|
if (!container) return;
|
|
7596
7998
|
function handleWheel(e) {
|
|
7597
7999
|
if (!zoomableRef.current) return;
|
|
8000
|
+
if (!e.ctrlKey && !e.metaKey) return;
|
|
7598
8001
|
e.preventDefault();
|
|
7599
8002
|
const rect = container.getBoundingClientRect();
|
|
7600
8003
|
const mouseX = e.clientX - rect.left;
|
|
@@ -8787,9 +9190,11 @@ function useCanvas() {
|
|
|
8787
9190
|
if (!ctx) throw new Error("useCanvas must be used within a Canvas component");
|
|
8788
9191
|
return ctx;
|
|
8789
9192
|
}
|
|
8790
|
-
function CanvasNode({ children, id, x, y, className, style }) {
|
|
8791
|
-
const { registerNode, unregisterNode } = useCanvas();
|
|
9193
|
+
function CanvasNode({ children, id, x, y, draggable, onPositionChange, className, style }) {
|
|
9194
|
+
const { registerNode, unregisterNode, viewport } = useCanvas();
|
|
8792
9195
|
const nodeRef = useRef(null);
|
|
9196
|
+
const isDragging = useRef(false);
|
|
9197
|
+
const dragStart = useRef({ mouseX: 0, mouseY: 0, nodeX: 0, nodeY: 0 });
|
|
8793
9198
|
useEffect(() => {
|
|
8794
9199
|
const el = nodeRef.current;
|
|
8795
9200
|
if (!el) return;
|
|
@@ -8804,14 +9209,39 @@ function CanvasNode({ children, id, x, y, className, style }) {
|
|
|
8804
9209
|
unregisterNode(id);
|
|
8805
9210
|
};
|
|
8806
9211
|
}, [id, x, y, registerNode, unregisterNode]);
|
|
9212
|
+
const handlePointerDown = useCallback(
|
|
9213
|
+
(e) => {
|
|
9214
|
+
if (!draggable || e.button !== 0) return;
|
|
9215
|
+
e.stopPropagation();
|
|
9216
|
+
isDragging.current = true;
|
|
9217
|
+
dragStart.current = { mouseX: e.clientX, mouseY: e.clientY, nodeX: x, nodeY: y };
|
|
9218
|
+
e.target.setPointerCapture(e.pointerId);
|
|
9219
|
+
},
|
|
9220
|
+
[draggable, x, y]
|
|
9221
|
+
);
|
|
9222
|
+
const handlePointerMove = useCallback(
|
|
9223
|
+
(e) => {
|
|
9224
|
+
if (!isDragging.current) return;
|
|
9225
|
+
const dx = (e.clientX - dragStart.current.mouseX) / viewport.zoom;
|
|
9226
|
+
const dy = (e.clientY - dragStart.current.mouseY) / viewport.zoom;
|
|
9227
|
+
onPositionChange?.(dragStart.current.nodeX + dx, dragStart.current.nodeY + dy);
|
|
9228
|
+
},
|
|
9229
|
+
[viewport.zoom, onPositionChange]
|
|
9230
|
+
);
|
|
9231
|
+
const handlePointerUp = useCallback(() => {
|
|
9232
|
+
isDragging.current = false;
|
|
9233
|
+
}, []);
|
|
8807
9234
|
return /* @__PURE__ */ jsx(
|
|
8808
9235
|
"div",
|
|
8809
9236
|
{
|
|
8810
9237
|
ref: nodeRef,
|
|
8811
9238
|
"data-react-fancy-canvas-node": "",
|
|
8812
9239
|
"data-node-id": id,
|
|
8813
|
-
className: cn("absolute", className),
|
|
9240
|
+
className: cn("absolute", draggable && "cursor-grab active:cursor-grabbing", className),
|
|
8814
9241
|
style: { left: x, top: y, ...style },
|
|
9242
|
+
onPointerDown: handlePointerDown,
|
|
9243
|
+
onPointerMove: handlePointerMove,
|
|
9244
|
+
onPointerUp: handlePointerUp,
|
|
8815
9245
|
children
|
|
8816
9246
|
}
|
|
8817
9247
|
);
|
|
@@ -8848,10 +9278,18 @@ function getAnchorPoint(rect, anchor, otherRect) {
|
|
|
8848
9278
|
}
|
|
8849
9279
|
}
|
|
8850
9280
|
function bezierPath(from, to) {
|
|
8851
|
-
const dx = Math.abs(to.x - from.x)
|
|
8852
|
-
const
|
|
8853
|
-
|
|
8854
|
-
|
|
9281
|
+
const dx = Math.abs(to.x - from.x);
|
|
9282
|
+
const dy = Math.abs(to.y - from.y);
|
|
9283
|
+
if (dx > dy) {
|
|
9284
|
+
const offset2 = dx * 0.5;
|
|
9285
|
+
const cp1x = from.x + (to.x > from.x ? offset2 : -offset2);
|
|
9286
|
+
const cp2x = to.x + (to.x > from.x ? -offset2 : offset2);
|
|
9287
|
+
return `M${from.x},${from.y} C${cp1x},${from.y} ${cp2x},${to.y} ${to.x},${to.y}`;
|
|
9288
|
+
}
|
|
9289
|
+
const offset = Math.max(dy * 0.5, 30);
|
|
9290
|
+
const cp1y = from.y + (to.y > from.y ? offset : -offset);
|
|
9291
|
+
const cp2y = to.y + (to.y > from.y ? -offset : offset);
|
|
9292
|
+
return `M${from.x},${from.y} C${from.x},${cp1y} ${to.x},${cp2y} ${to.x},${to.y}`;
|
|
8855
9293
|
}
|
|
8856
9294
|
function stepPath(from, to) {
|
|
8857
9295
|
const midX = (from.x + to.x) / 2;
|
|
@@ -9036,6 +9474,7 @@ function CanvasRoot({
|
|
|
9036
9474
|
pannable = true,
|
|
9037
9475
|
zoomable = true,
|
|
9038
9476
|
showGrid = false,
|
|
9477
|
+
fitOnMount = false,
|
|
9039
9478
|
className,
|
|
9040
9479
|
style
|
|
9041
9480
|
}) {
|
|
@@ -9055,15 +9494,41 @@ function CanvasRoot({
|
|
|
9055
9494
|
() => ({ viewport, setViewport, registerNode, unregisterNode, nodeRects, registryVersion, containerRef }),
|
|
9056
9495
|
[viewport, setViewport, registerNode, unregisterNode, nodeRects, registryVersion]
|
|
9057
9496
|
);
|
|
9497
|
+
const hasFitted = useRef(false);
|
|
9498
|
+
useEffect(() => {
|
|
9499
|
+
if (!fitOnMount || hasFitted.current || nodeRects.size === 0) return;
|
|
9500
|
+
const container = containerRef.current;
|
|
9501
|
+
if (!container || container.clientWidth === 0) return;
|
|
9502
|
+
hasFitted.current = true;
|
|
9503
|
+
requestAnimationFrame(() => {
|
|
9504
|
+
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
|
9505
|
+
nodeRects.forEach((r) => {
|
|
9506
|
+
minX = Math.min(minX, r.x);
|
|
9507
|
+
minY = Math.min(minY, r.y);
|
|
9508
|
+
maxX = Math.max(maxX, r.x + r.width);
|
|
9509
|
+
maxY = Math.max(maxY, r.y + r.height);
|
|
9510
|
+
});
|
|
9511
|
+
const padding = 40;
|
|
9512
|
+
const contentW = maxX - minX + padding * 2;
|
|
9513
|
+
const contentH = maxY - minY + padding * 2;
|
|
9514
|
+
const cw = container.clientWidth;
|
|
9515
|
+
const ch = container.clientHeight;
|
|
9516
|
+
const zoom = Math.min(cw / contentW, ch / contentH, 1.5);
|
|
9517
|
+
const panX = (cw - contentW * zoom) / 2 - minX * zoom + padding * zoom;
|
|
9518
|
+
const panY = (ch - contentH * zoom) / 2 - minY * zoom + padding * zoom;
|
|
9519
|
+
setViewport({ panX, panY, zoom });
|
|
9520
|
+
});
|
|
9521
|
+
}, [fitOnMount, nodeRects, registryVersion, setViewport]);
|
|
9058
9522
|
const edges = [];
|
|
9059
9523
|
const others = [];
|
|
9060
9524
|
const overlays = [];
|
|
9061
9525
|
Children.forEach(children, (child) => {
|
|
9062
9526
|
const el = child;
|
|
9063
9527
|
if (!el || !el.type) return;
|
|
9064
|
-
|
|
9528
|
+
const elType = el.type;
|
|
9529
|
+
if (elType === CanvasEdge || elType?._isCanvasEdge) {
|
|
9065
9530
|
edges.push(el);
|
|
9066
|
-
} else if (
|
|
9531
|
+
} else if (elType === CanvasMinimap || elType === CanvasControls) {
|
|
9067
9532
|
overlays.push(el);
|
|
9068
9533
|
} else {
|
|
9069
9534
|
others.push(el);
|
|
@@ -9110,15 +9575,16 @@ function CanvasRoot({
|
|
|
9110
9575
|
},
|
|
9111
9576
|
children: [
|
|
9112
9577
|
/* @__PURE__ */ jsxs("defs", { children: [
|
|
9113
|
-
/* @__PURE__ */ jsx("marker", { id: "canvas-arrow", viewBox: "0 0 10 10", refX: "10", refY: "5", markerWidth: "8", markerHeight: "8", orient: "auto
|
|
9114
|
-
/* @__PURE__ */ jsx("marker", { id: "canvas-circle", viewBox: "0 0 10 10", refX: "5", refY: "5", markerWidth: "8", markerHeight: "8", orient: "auto
|
|
9115
|
-
/* @__PURE__ */ jsx("marker", { id: "canvas-
|
|
9116
|
-
/* @__PURE__ */
|
|
9117
|
-
|
|
9118
|
-
/* @__PURE__ */ jsx("line", { x1: "
|
|
9119
|
-
/* @__PURE__ */ jsx("line", { x1: "
|
|
9120
|
-
|
|
9121
|
-
|
|
9578
|
+
/* @__PURE__ */ jsx("marker", { id: "canvas-arrow", viewBox: "0 0 10 10", refX: "10", refY: "5", markerWidth: "8", markerHeight: "8", orient: "auto", children: /* @__PURE__ */ jsx("path", { d: "M0,0 L10,5 L0,10 Z", fill: "#71717a" }) }),
|
|
9579
|
+
/* @__PURE__ */ jsx("marker", { id: "canvas-circle", viewBox: "0 0 10 10", refX: "5", refY: "5", markerWidth: "8", markerHeight: "8", orient: "auto", children: /* @__PURE__ */ jsx("circle", { cx: "5", cy: "5", r: "3.5", fill: "#71717a" }) }),
|
|
9580
|
+
/* @__PURE__ */ jsx("marker", { id: "canvas-diamond", viewBox: "0 0 12 12", refX: "6", refY: "6", markerWidth: "10", markerHeight: "10", orient: "auto", children: /* @__PURE__ */ jsx("polygon", { points: "6,0 12,6 6,12 0,6", fill: "none", stroke: "#71717a", strokeWidth: "1.5" }) }),
|
|
9581
|
+
/* @__PURE__ */ jsx("marker", { id: "canvas-one", viewBox: "0 0 2 16", refX: "1", refY: "8", markerWidth: "2", markerHeight: "14", orient: "auto", children: /* @__PURE__ */ jsx("line", { x1: "1", y1: "0", x2: "1", y2: "16", stroke: "#71717a", strokeWidth: "2" }) }),
|
|
9582
|
+
/* @__PURE__ */ jsxs("marker", { id: "canvas-crow-foot", viewBox: "0 0 16 16", refX: "16", refY: "8", markerWidth: "14", markerHeight: "14", orient: "auto", children: [
|
|
9583
|
+
/* @__PURE__ */ jsx("line", { x1: "16", y1: "8", x2: "0", y2: "0", stroke: "#71717a", strokeWidth: "2", strokeLinecap: "round" }),
|
|
9584
|
+
/* @__PURE__ */ jsx("line", { x1: "16", y1: "8", x2: "0", y2: "8", stroke: "#71717a", strokeWidth: "2", strokeLinecap: "round" }),
|
|
9585
|
+
/* @__PURE__ */ jsx("line", { x1: "16", y1: "8", x2: "0", y2: "16", stroke: "#71717a", strokeWidth: "2", strokeLinecap: "round" }),
|
|
9586
|
+
/* @__PURE__ */ jsx("line", { x1: "16", y1: "0", x2: "16", y2: "16", stroke: "#71717a", strokeWidth: "2", strokeLinecap: "round" })
|
|
9587
|
+
] })
|
|
9122
9588
|
] }),
|
|
9123
9589
|
edges
|
|
9124
9590
|
]
|
|
@@ -9176,13 +9642,16 @@ function DiagramField({
|
|
|
9176
9642
|
DiagramField.displayName = "DiagramField";
|
|
9177
9643
|
function DiagramEntity({
|
|
9178
9644
|
children,
|
|
9179
|
-
id,
|
|
9645
|
+
id: idProp,
|
|
9180
9646
|
name,
|
|
9181
9647
|
x = 0,
|
|
9182
9648
|
y = 0,
|
|
9183
9649
|
color = "bg-blue-600 dark:bg-blue-500",
|
|
9650
|
+
draggable,
|
|
9651
|
+
onPositionChange,
|
|
9184
9652
|
className
|
|
9185
9653
|
}) {
|
|
9654
|
+
const id = idProp ?? name;
|
|
9186
9655
|
const fields = [];
|
|
9187
9656
|
const other = [];
|
|
9188
9657
|
Children.forEach(children, (child) => {
|
|
@@ -9194,7 +9663,7 @@ function DiagramEntity({
|
|
|
9194
9663
|
other.push(el);
|
|
9195
9664
|
}
|
|
9196
9665
|
});
|
|
9197
|
-
return /* @__PURE__ */ jsx(Canvas.Node, { id, x, y, children: /* @__PURE__ */ jsxs(
|
|
9666
|
+
return /* @__PURE__ */ jsx(Canvas.Node, { id, x, y, draggable, onPositionChange, children: /* @__PURE__ */ jsxs(
|
|
9198
9667
|
"div",
|
|
9199
9668
|
{
|
|
9200
9669
|
"data-react-fancy-diagram-entity": "",
|
|
@@ -9221,37 +9690,193 @@ function DiagramEntity({
|
|
|
9221
9690
|
) });
|
|
9222
9691
|
}
|
|
9223
9692
|
DiagramEntity.displayName = "DiagramEntity";
|
|
9224
|
-
|
|
9225
|
-
|
|
9226
|
-
|
|
9227
|
-
|
|
9228
|
-
|
|
9229
|
-
|
|
9230
|
-
case "
|
|
9231
|
-
|
|
9693
|
+
var HEADER_HEIGHT = 36;
|
|
9694
|
+
var FIELD_HEIGHT = 28;
|
|
9695
|
+
var SYMBOL_SIZE = 12;
|
|
9696
|
+
function oneSymbol(pt, direction) {
|
|
9697
|
+
const s = SYMBOL_SIZE * 0.6;
|
|
9698
|
+
switch (direction) {
|
|
9699
|
+
case "left":
|
|
9700
|
+
case "right":
|
|
9701
|
+
return `M${pt.x},${pt.y - s} L${pt.x},${pt.y + s}`;
|
|
9702
|
+
case "up":
|
|
9703
|
+
case "down":
|
|
9704
|
+
return `M${pt.x - s},${pt.y} L${pt.x + s},${pt.y}`;
|
|
9705
|
+
}
|
|
9706
|
+
}
|
|
9707
|
+
function crowFootSymbol(pt, direction) {
|
|
9708
|
+
const s = SYMBOL_SIZE;
|
|
9709
|
+
const spread = s * 0.8;
|
|
9710
|
+
let tip;
|
|
9711
|
+
switch (direction) {
|
|
9712
|
+
case "right":
|
|
9713
|
+
tip = { x: pt.x - s, y: pt.y };
|
|
9714
|
+
return [
|
|
9715
|
+
`M${pt.x},${pt.y - spread} L${tip.x},${tip.y}`,
|
|
9716
|
+
`M${pt.x},${pt.y} L${tip.x},${tip.y}`,
|
|
9717
|
+
`M${pt.x},${pt.y + spread} L${tip.x},${tip.y}`,
|
|
9718
|
+
// bar at entity edge
|
|
9719
|
+
`M${pt.x},${pt.y - spread} L${pt.x},${pt.y + spread}`
|
|
9720
|
+
].join(" ");
|
|
9721
|
+
case "left":
|
|
9722
|
+
tip = { x: pt.x + s, y: pt.y };
|
|
9723
|
+
return [
|
|
9724
|
+
`M${pt.x},${pt.y - spread} L${tip.x},${tip.y}`,
|
|
9725
|
+
`M${pt.x},${pt.y} L${tip.x},${tip.y}`,
|
|
9726
|
+
`M${pt.x},${pt.y + spread} L${tip.x},${tip.y}`,
|
|
9727
|
+
`M${pt.x},${pt.y - spread} L${pt.x},${pt.y + spread}`
|
|
9728
|
+
].join(" ");
|
|
9729
|
+
case "down":
|
|
9730
|
+
tip = { x: pt.x, y: pt.y - s };
|
|
9731
|
+
return [
|
|
9732
|
+
`M${pt.x - spread},${pt.y} L${tip.x},${tip.y}`,
|
|
9733
|
+
`M${pt.x},${pt.y} L${tip.x},${tip.y}`,
|
|
9734
|
+
`M${pt.x + spread},${pt.y} L${tip.x},${tip.y}`,
|
|
9735
|
+
`M${pt.x - spread},${pt.y} L${pt.x + spread},${pt.y}`
|
|
9736
|
+
].join(" ");
|
|
9737
|
+
case "up":
|
|
9738
|
+
tip = { x: pt.x, y: pt.y + s };
|
|
9739
|
+
return [
|
|
9740
|
+
`M${pt.x - spread},${pt.y} L${tip.x},${tip.y}`,
|
|
9741
|
+
`M${pt.x},${pt.y} L${tip.x},${tip.y}`,
|
|
9742
|
+
`M${pt.x + spread},${pt.y} L${tip.x},${tip.y}`,
|
|
9743
|
+
`M${pt.x - spread},${pt.y} L${pt.x + spread},${pt.y}`
|
|
9744
|
+
].join(" ");
|
|
9232
9745
|
}
|
|
9233
9746
|
}
|
|
9747
|
+
function getSymbolPath(type, end, pt, direction) {
|
|
9748
|
+
const side = end === "start" ? type.split("-to-")[0] : type.split("-to-")[1];
|
|
9749
|
+
if (side === "one") return oneSymbol(pt, direction);
|
|
9750
|
+
if (side === "many") return crowFootSymbol(pt, direction);
|
|
9751
|
+
return null;
|
|
9752
|
+
}
|
|
9234
9753
|
function DiagramRelation({
|
|
9235
9754
|
from,
|
|
9236
9755
|
to,
|
|
9756
|
+
fromField: fromFieldProp,
|
|
9757
|
+
toField: toFieldProp,
|
|
9237
9758
|
type,
|
|
9238
|
-
label
|
|
9239
|
-
className
|
|
9759
|
+
label
|
|
9240
9760
|
}) {
|
|
9241
|
-
const
|
|
9242
|
-
|
|
9243
|
-
|
|
9244
|
-
|
|
9245
|
-
|
|
9246
|
-
|
|
9247
|
-
|
|
9248
|
-
|
|
9249
|
-
|
|
9250
|
-
|
|
9251
|
-
|
|
9761
|
+
const { nodeRects, registryVersion } = useCanvas();
|
|
9762
|
+
const { schema } = useDiagram();
|
|
9763
|
+
const result = useMemo(() => {
|
|
9764
|
+
const fromRect = nodeRects.get(from);
|
|
9765
|
+
const toRect = nodeRects.get(to);
|
|
9766
|
+
if (!fromRect || !toRect) return null;
|
|
9767
|
+
const fromEntity = schema.entities.find((e) => (e.id ?? e.name) === from);
|
|
9768
|
+
const toEntity = schema.entities.find((e) => (e.id ?? e.name) === to);
|
|
9769
|
+
let fromFieldIdx = -1;
|
|
9770
|
+
let toFieldIdx = -1;
|
|
9771
|
+
if (fromFieldProp && fromEntity?.fields) {
|
|
9772
|
+
fromFieldIdx = fromEntity.fields.findIndex((f) => f.name === fromFieldProp);
|
|
9773
|
+
} else if (fromEntity?.fields) {
|
|
9774
|
+
fromFieldIdx = fromEntity.fields.findIndex((f) => f.primary);
|
|
9252
9775
|
}
|
|
9253
|
-
|
|
9776
|
+
if (toFieldProp && toEntity?.fields) {
|
|
9777
|
+
toFieldIdx = toEntity.fields.findIndex((f) => f.name === toFieldProp);
|
|
9778
|
+
} else if (toEntity?.fields) {
|
|
9779
|
+
const fromName = (fromEntity?.name ?? from).toLowerCase();
|
|
9780
|
+
toFieldIdx = toEntity.fields.findIndex(
|
|
9781
|
+
(f) => f.foreign && (f.name === `${fromName}_id` || f.name === `${fromName}Id`)
|
|
9782
|
+
);
|
|
9783
|
+
if (toFieldIdx === -1) {
|
|
9784
|
+
toFieldIdx = toEntity.fields.findIndex((f) => f.foreign);
|
|
9785
|
+
}
|
|
9786
|
+
}
|
|
9787
|
+
const fromFieldY = fromFieldIdx >= 0 ? HEADER_HEIGHT + fromFieldIdx * FIELD_HEIGHT + FIELD_HEIGHT / 2 : fromRect.height / 2;
|
|
9788
|
+
const toFieldY = toFieldIdx >= 0 ? HEADER_HEIGHT + toFieldIdx * FIELD_HEIGHT + FIELD_HEIGHT / 2 : toRect.height / 2;
|
|
9789
|
+
const fromCx = fromRect.x + fromRect.width / 2;
|
|
9790
|
+
const toCx = toRect.x + toRect.width / 2;
|
|
9791
|
+
const fromCy = fromRect.y + fromRect.height / 2;
|
|
9792
|
+
const toCy = toRect.y + toRect.height / 2;
|
|
9793
|
+
const dx = Math.abs(fromCx - toCx);
|
|
9794
|
+
const dy = Math.abs(fromCy - toCy);
|
|
9795
|
+
let fromPt, toPt;
|
|
9796
|
+
let fromDir;
|
|
9797
|
+
let toDir;
|
|
9798
|
+
if (dx > dy * 0.5) {
|
|
9799
|
+
if (fromCx < toCx) {
|
|
9800
|
+
fromPt = { x: fromRect.x + fromRect.width, y: fromRect.y + fromFieldY };
|
|
9801
|
+
toPt = { x: toRect.x, y: toRect.y + toFieldY };
|
|
9802
|
+
fromDir = "right";
|
|
9803
|
+
toDir = "left";
|
|
9804
|
+
} else {
|
|
9805
|
+
fromPt = { x: fromRect.x, y: fromRect.y + fromFieldY };
|
|
9806
|
+
toPt = { x: toRect.x + toRect.width, y: toRect.y + toFieldY };
|
|
9807
|
+
fromDir = "left";
|
|
9808
|
+
toDir = "right";
|
|
9809
|
+
}
|
|
9810
|
+
} else {
|
|
9811
|
+
if (fromCy < toCy) {
|
|
9812
|
+
fromPt = { x: fromRect.x + fromRect.width / 2, y: fromRect.y + fromRect.height };
|
|
9813
|
+
toPt = { x: toRect.x + toRect.width / 2, y: toRect.y };
|
|
9814
|
+
fromDir = "down";
|
|
9815
|
+
toDir = "up";
|
|
9816
|
+
} else {
|
|
9817
|
+
fromPt = { x: fromRect.x + fromRect.width / 2, y: fromRect.y };
|
|
9818
|
+
toPt = { x: toRect.x + toRect.width / 2, y: toRect.y + toRect.height };
|
|
9819
|
+
fromDir = "up";
|
|
9820
|
+
toDir = "down";
|
|
9821
|
+
}
|
|
9822
|
+
}
|
|
9823
|
+
const offsetFrom = { ...fromPt };
|
|
9824
|
+
const offsetTo = { ...toPt };
|
|
9825
|
+
switch (fromDir) {
|
|
9826
|
+
case "right":
|
|
9827
|
+
offsetFrom.x += SYMBOL_SIZE;
|
|
9828
|
+
break;
|
|
9829
|
+
case "left":
|
|
9830
|
+
offsetFrom.x -= SYMBOL_SIZE;
|
|
9831
|
+
break;
|
|
9832
|
+
case "down":
|
|
9833
|
+
offsetFrom.y += SYMBOL_SIZE;
|
|
9834
|
+
break;
|
|
9835
|
+
case "up":
|
|
9836
|
+
offsetFrom.y -= SYMBOL_SIZE;
|
|
9837
|
+
break;
|
|
9838
|
+
}
|
|
9839
|
+
switch (toDir) {
|
|
9840
|
+
case "right":
|
|
9841
|
+
offsetTo.x += SYMBOL_SIZE;
|
|
9842
|
+
break;
|
|
9843
|
+
case "left":
|
|
9844
|
+
offsetTo.x -= SYMBOL_SIZE;
|
|
9845
|
+
break;
|
|
9846
|
+
case "down":
|
|
9847
|
+
offsetTo.y += SYMBOL_SIZE;
|
|
9848
|
+
break;
|
|
9849
|
+
case "up":
|
|
9850
|
+
offsetTo.y -= SYMBOL_SIZE;
|
|
9851
|
+
break;
|
|
9852
|
+
}
|
|
9853
|
+
const adx = Math.abs(offsetTo.x - offsetFrom.x);
|
|
9854
|
+
const ady = Math.abs(offsetTo.y - offsetFrom.y);
|
|
9855
|
+
let linePath;
|
|
9856
|
+
if (adx > ady) {
|
|
9857
|
+
const off = adx * 0.4;
|
|
9858
|
+
const cp1x = offsetFrom.x + (offsetTo.x > offsetFrom.x ? off : -off);
|
|
9859
|
+
const cp2x = offsetTo.x + (offsetTo.x > offsetFrom.x ? -off : off);
|
|
9860
|
+
linePath = `M${offsetFrom.x},${offsetFrom.y} C${cp1x},${offsetFrom.y} ${cp2x},${offsetTo.y} ${offsetTo.x},${offsetTo.y}`;
|
|
9861
|
+
} else {
|
|
9862
|
+
const off = Math.max(ady * 0.4, 20);
|
|
9863
|
+
const cp1y = offsetFrom.y + (offsetTo.y > offsetFrom.y ? off : -off);
|
|
9864
|
+
const cp2y = offsetTo.y + (offsetTo.y > offsetFrom.y ? -off : off);
|
|
9865
|
+
linePath = `M${offsetFrom.x},${offsetFrom.y} C${offsetFrom.x},${cp1y} ${offsetTo.x},${cp2y} ${offsetTo.x},${offsetTo.y}`;
|
|
9866
|
+
}
|
|
9867
|
+
const startSymbol = getSymbolPath(type, "start", fromPt, fromDir);
|
|
9868
|
+
const endSymbol = getSymbolPath(type, "end", toPt, toDir);
|
|
9869
|
+
return { linePath, startSymbol, endSymbol, midX: (offsetFrom.x + offsetTo.x) / 2, midY: (offsetFrom.y + offsetTo.y) / 2 };
|
|
9870
|
+
}, [from, to, fromFieldProp, toFieldProp, type, schema, nodeRects, registryVersion]);
|
|
9871
|
+
if (!result) return null;
|
|
9872
|
+
return /* @__PURE__ */ jsxs("g", { "data-react-fancy-diagram-relation": "", children: [
|
|
9873
|
+
/* @__PURE__ */ jsx("path", { d: result.linePath, fill: "none", stroke: "#71717a", strokeWidth: 2 }),
|
|
9874
|
+
result.startSymbol && /* @__PURE__ */ jsx("path", { d: result.startSymbol, fill: "none", stroke: "#71717a", strokeWidth: 2 }),
|
|
9875
|
+
result.endSymbol && /* @__PURE__ */ jsx("path", { d: result.endSymbol, fill: "none", stroke: "#71717a", strokeWidth: 2 }),
|
|
9876
|
+
label && /* @__PURE__ */ jsx("foreignObject", { x: result.midX - 40, y: result.midY - 12, width: 80, height: 24, children: /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center text-xs text-zinc-500", children: label }) })
|
|
9877
|
+
] });
|
|
9254
9878
|
}
|
|
9879
|
+
DiagramRelation._isCanvasEdge = true;
|
|
9255
9880
|
DiagramRelation.displayName = "DiagramRelation";
|
|
9256
9881
|
var FORMAT_LABELS = {
|
|
9257
9882
|
erd: "ERD",
|
|
@@ -9362,12 +9987,12 @@ DiagramToolbar.displayName = "DiagramToolbar";
|
|
|
9362
9987
|
|
|
9363
9988
|
// src/components/Diagram/diagram.layout.ts
|
|
9364
9989
|
var ENTITY_WIDTH = 220;
|
|
9365
|
-
var
|
|
9366
|
-
var
|
|
9990
|
+
var HEADER_HEIGHT2 = 40;
|
|
9991
|
+
var FIELD_HEIGHT2 = 28;
|
|
9367
9992
|
var HORIZONTAL_GAP = 80;
|
|
9368
9993
|
var VERTICAL_GAP = 60;
|
|
9369
9994
|
function getEntityHeight(fieldCount) {
|
|
9370
|
-
return
|
|
9995
|
+
return HEADER_HEIGHT2 + Math.max(fieldCount, 1) * FIELD_HEIGHT2;
|
|
9371
9996
|
}
|
|
9372
9997
|
function computeDiagramLayout(schema) {
|
|
9373
9998
|
const positions = /* @__PURE__ */ new Map();
|
|
@@ -9470,58 +10095,103 @@ function DiagramRoot({
|
|
|
9470
10095
|
}) {
|
|
9471
10096
|
const downloadableRef = useRef(downloadable);
|
|
9472
10097
|
const importableRef = useRef(importable);
|
|
9473
|
-
const
|
|
10098
|
+
const normalizedSchema = useMemo(() => {
|
|
9474
10099
|
if (!schema) return { entities: [], relations: [] };
|
|
9475
|
-
const
|
|
9476
|
-
|
|
9477
|
-
|
|
9478
|
-
|
|
9479
|
-
|
|
9480
|
-
|
|
9481
|
-
|
|
10100
|
+
const entities = schema.entities.map((e) => ({
|
|
10101
|
+
...e,
|
|
10102
|
+
id: e.id ?? e.name
|
|
10103
|
+
}));
|
|
10104
|
+
const relations = schema.relations.map((r, i) => ({
|
|
10105
|
+
...r,
|
|
10106
|
+
id: r.id ?? `rel-${i}`
|
|
10107
|
+
}));
|
|
10108
|
+
return { entities, relations };
|
|
9482
10109
|
}, [schema]);
|
|
10110
|
+
const initialPositions = useMemo(() => {
|
|
10111
|
+
if (normalizedSchema.entities.length === 0) return /* @__PURE__ */ new Map();
|
|
10112
|
+
const layout = computeDiagramLayout(normalizedSchema);
|
|
10113
|
+
const positions = /* @__PURE__ */ new Map();
|
|
10114
|
+
for (const entity of normalizedSchema.entities) {
|
|
10115
|
+
if (entity.x !== void 0 && entity.y !== void 0) {
|
|
10116
|
+
positions.set(entity.id, { x: entity.x, y: entity.y });
|
|
10117
|
+
} else {
|
|
10118
|
+
const pos = layout.get(entity.id);
|
|
10119
|
+
positions.set(entity.id, pos ?? { x: 0, y: 0 });
|
|
10120
|
+
}
|
|
10121
|
+
}
|
|
10122
|
+
return positions;
|
|
10123
|
+
}, [normalizedSchema]);
|
|
10124
|
+
const computedDefaultViewport = useMemo(() => {
|
|
10125
|
+
if (defaultViewport) return defaultViewport;
|
|
10126
|
+
if (initialPositions.size === 0) return { panX: 0, panY: 0, zoom: 1 };
|
|
10127
|
+
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
|
10128
|
+
initialPositions.forEach((pos) => {
|
|
10129
|
+
minX = Math.min(minX, pos.x);
|
|
10130
|
+
minY = Math.min(minY, pos.y);
|
|
10131
|
+
maxX = Math.max(maxX, pos.x + 220);
|
|
10132
|
+
maxY = Math.max(maxY, pos.y + 200);
|
|
10133
|
+
});
|
|
10134
|
+
const padding = 40;
|
|
10135
|
+
const panX = -minX + padding;
|
|
10136
|
+
const panY = -minY + padding;
|
|
10137
|
+
return { panX, panY, zoom: 1 };
|
|
10138
|
+
}, [defaultViewport, initialPositions]);
|
|
10139
|
+
const [entityPositions, setEntityPositions] = useState(initialPositions);
|
|
10140
|
+
const handleEntityMove = useCallback((entityId, x, y) => {
|
|
10141
|
+
setEntityPositions((prev) => {
|
|
10142
|
+
const next = new Map(prev);
|
|
10143
|
+
next.set(entityId, { x, y });
|
|
10144
|
+
return next;
|
|
10145
|
+
});
|
|
10146
|
+
}, []);
|
|
9483
10147
|
const ctx = useMemo(
|
|
9484
10148
|
() => ({
|
|
9485
10149
|
diagramType: type,
|
|
9486
|
-
schema:
|
|
10150
|
+
schema: normalizedSchema,
|
|
9487
10151
|
downloadableRef,
|
|
9488
10152
|
importableRef,
|
|
9489
10153
|
exportFormats,
|
|
9490
10154
|
onImport
|
|
9491
10155
|
}),
|
|
9492
|
-
[type,
|
|
10156
|
+
[type, normalizedSchema, exportFormats, onImport]
|
|
9493
10157
|
);
|
|
9494
10158
|
return /* @__PURE__ */ jsx(DiagramContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx("div", { "data-react-fancy-diagram": "", className: "relative h-full w-full", children: /* @__PURE__ */ jsxs(
|
|
9495
10159
|
Canvas,
|
|
9496
10160
|
{
|
|
9497
10161
|
viewport,
|
|
9498
|
-
defaultViewport,
|
|
10162
|
+
defaultViewport: computedDefaultViewport,
|
|
9499
10163
|
onViewportChange,
|
|
9500
10164
|
showGrid: true,
|
|
10165
|
+
fitOnMount: true,
|
|
9501
10166
|
className: cn("h-full w-full", className),
|
|
9502
10167
|
children: [
|
|
9503
|
-
|
|
9504
|
-
|
|
9505
|
-
|
|
9506
|
-
|
|
9507
|
-
|
|
9508
|
-
|
|
9509
|
-
|
|
9510
|
-
|
|
9511
|
-
|
|
9512
|
-
|
|
9513
|
-
|
|
9514
|
-
|
|
9515
|
-
|
|
9516
|
-
|
|
9517
|
-
|
|
9518
|
-
|
|
9519
|
-
|
|
9520
|
-
|
|
9521
|
-
|
|
9522
|
-
|
|
9523
|
-
|
|
9524
|
-
|
|
10168
|
+
normalizedSchema.entities.map((entity) => {
|
|
10169
|
+
const pos = entityPositions.get(entity.id) ?? { x: 0, y: 0 };
|
|
10170
|
+
return /* @__PURE__ */ jsx(
|
|
10171
|
+
DiagramEntity,
|
|
10172
|
+
{
|
|
10173
|
+
id: entity.id,
|
|
10174
|
+
name: entity.name,
|
|
10175
|
+
x: pos.x,
|
|
10176
|
+
y: pos.y,
|
|
10177
|
+
draggable: true,
|
|
10178
|
+
onPositionChange: (nx, ny) => handleEntityMove(entity.id, nx, ny),
|
|
10179
|
+
children: entity.fields?.map((field) => /* @__PURE__ */ jsx(
|
|
10180
|
+
DiagramField,
|
|
10181
|
+
{
|
|
10182
|
+
name: field.name,
|
|
10183
|
+
type: field.type,
|
|
10184
|
+
primary: field.primary,
|
|
10185
|
+
foreign: field.foreign,
|
|
10186
|
+
nullable: field.nullable
|
|
10187
|
+
},
|
|
10188
|
+
field.name
|
|
10189
|
+
))
|
|
10190
|
+
},
|
|
10191
|
+
entity.id
|
|
10192
|
+
);
|
|
10193
|
+
}),
|
|
10194
|
+
normalizedSchema.relations.map((rel) => /* @__PURE__ */ jsx(
|
|
9525
10195
|
DiagramRelation,
|
|
9526
10196
|
{
|
|
9527
10197
|
from: rel.from,
|