@particle-academy/react-fancy 1.5.0 → 1.6.1
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 +9 -0
- package/dist/index.cjs +550 -179
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +62 -13
- package/dist/index.d.ts +62 -13
- package/dist/index.js +550 -179
- 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.cjs
CHANGED
|
@@ -1323,13 +1323,6 @@ var avatarSize = {
|
|
|
1323
1323
|
lg: "w-6 h-6",
|
|
1324
1324
|
xl: "w-7 h-7"
|
|
1325
1325
|
};
|
|
1326
|
-
var alertIconSize = {
|
|
1327
|
-
xs: "w-2 h-2",
|
|
1328
|
-
sm: "w-2.5 h-2.5",
|
|
1329
|
-
md: "w-3 h-3",
|
|
1330
|
-
lg: "w-4 h-4",
|
|
1331
|
-
xl: "w-4 h-4"
|
|
1332
|
-
};
|
|
1333
1326
|
var badgeSize = {
|
|
1334
1327
|
xs: "text-[10px] px-1 min-w-[14px] h-3.5",
|
|
1335
1328
|
sm: "text-[10px] px-1.5 min-w-[16px] h-4",
|
|
@@ -1441,7 +1434,7 @@ var Action = react.forwardRef(
|
|
|
1441
1434
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1442
1435
|
"span",
|
|
1443
1436
|
{
|
|
1444
|
-
className: cn("flex-shrink-0", iconColorCls),
|
|
1437
|
+
className: cn("inline-flex items-center flex-shrink-0", iconColorCls),
|
|
1445
1438
|
children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: iconSlug, size: iconSizeMap[size] })
|
|
1446
1439
|
},
|
|
1447
1440
|
`icon-${trailing ? "t" : "l"}`
|
|
@@ -1495,17 +1488,8 @@ var Action = react.forwardRef(
|
|
|
1495
1488
|
className: "relative inline-flex flex-shrink-0",
|
|
1496
1489
|
"data-action-alert": true,
|
|
1497
1490
|
children: [
|
|
1498
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className:
|
|
1499
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1500
|
-
"span",
|
|
1501
|
-
{
|
|
1502
|
-
className: cn(
|
|
1503
|
-
alertIconSize[size],
|
|
1504
|
-
"absolute inset-0 text-red-400 dark:text-red-300 animate-ping opacity-75"
|
|
1505
|
-
),
|
|
1506
|
-
children: alertIconEl
|
|
1507
|
-
}
|
|
1508
|
-
)
|
|
1491
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-500 dark:text-red-400 animate-pulse", children: alertIconEl }),
|
|
1492
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute inset-0 flex items-center justify-center text-red-400 dark:text-red-300 animate-ping opacity-75", children: alertIconEl })
|
|
1509
1493
|
]
|
|
1510
1494
|
},
|
|
1511
1495
|
"alert-icon"
|
|
@@ -1645,7 +1629,7 @@ function dirtyRingClasses(dirty) {
|
|
|
1645
1629
|
function errorClasses(error) {
|
|
1646
1630
|
return error ? "border-red-500 focus:ring-red-500" : "";
|
|
1647
1631
|
}
|
|
1648
|
-
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-
|
|
1632
|
+
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";
|
|
1649
1633
|
function resolveOption(option) {
|
|
1650
1634
|
if (typeof option === "string") {
|
|
1651
1635
|
return { value: option, label: option };
|
|
@@ -1662,13 +1646,13 @@ function Field({
|
|
|
1662
1646
|
children,
|
|
1663
1647
|
className
|
|
1664
1648
|
}) {
|
|
1665
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-react-fancy-field": "", className: cn("flex flex-col gap-
|
|
1649
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-react-fancy-field": "", className: cn("flex flex-col gap-2", className), children: [
|
|
1666
1650
|
label && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1667
1651
|
"label",
|
|
1668
1652
|
{
|
|
1669
1653
|
htmlFor,
|
|
1670
1654
|
className: cn(
|
|
1671
|
-
"font-medium text-zinc-700 dark:text-zinc-
|
|
1655
|
+
"font-medium text-zinc-700 dark:text-zinc-100",
|
|
1672
1656
|
labelSizeClasses[size]
|
|
1673
1657
|
),
|
|
1674
1658
|
children: [
|
|
@@ -1696,7 +1680,7 @@ var insidePaddingRight = {
|
|
|
1696
1680
|
lg: "pr-10",
|
|
1697
1681
|
xl: "pr-11"
|
|
1698
1682
|
};
|
|
1699
|
-
var affixOutsideClasses = "inline-flex items-center border border-zinc-300 bg-zinc-50 px-3 text-sm text-zinc-500 dark:border-zinc-
|
|
1683
|
+
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";
|
|
1700
1684
|
function InputWrapper({
|
|
1701
1685
|
children,
|
|
1702
1686
|
prefix,
|
|
@@ -2116,7 +2100,7 @@ var Checkbox = react.forwardRef(
|
|
|
2116
2100
|
onChange: (e) => setChecked(e.target.checked),
|
|
2117
2101
|
className: cn(
|
|
2118
2102
|
sizeClasses6,
|
|
2119
|
-
"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-
|
|
2103
|
+
"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]",
|
|
2120
2104
|
dirtyRingClasses(dirty),
|
|
2121
2105
|
error && "border-red-500"
|
|
2122
2106
|
)
|
|
@@ -2128,7 +2112,7 @@ var Checkbox = react.forwardRef(
|
|
|
2128
2112
|
{
|
|
2129
2113
|
htmlFor: checkboxId,
|
|
2130
2114
|
className: cn(
|
|
2131
|
-
"cursor-pointer text-sm text-zinc-700 dark:text-zinc-
|
|
2115
|
+
"cursor-pointer text-sm text-zinc-700 dark:text-zinc-100",
|
|
2132
2116
|
disabled && "cursor-not-allowed opacity-50"
|
|
2133
2117
|
),
|
|
2134
2118
|
children: [
|
|
@@ -2203,7 +2187,7 @@ function CheckboxGroup({
|
|
|
2203
2187
|
onChange: () => handleToggle(resolved.value),
|
|
2204
2188
|
className: cn(
|
|
2205
2189
|
sizeClasses6,
|
|
2206
|
-
"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-
|
|
2190
|
+
"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]",
|
|
2207
2191
|
dirtyRingClasses(dirty),
|
|
2208
2192
|
error && "border-red-500"
|
|
2209
2193
|
)
|
|
@@ -2215,7 +2199,7 @@ function CheckboxGroup({
|
|
|
2215
2199
|
{
|
|
2216
2200
|
htmlFor: optionId,
|
|
2217
2201
|
className: cn(
|
|
2218
|
-
"cursor-pointer text-sm text-zinc-700 dark:text-zinc-
|
|
2202
|
+
"cursor-pointer text-sm text-zinc-700 dark:text-zinc-100",
|
|
2219
2203
|
(disabled || resolved.disabled) && "cursor-not-allowed opacity-50"
|
|
2220
2204
|
),
|
|
2221
2205
|
children: resolved.label
|
|
@@ -2300,7 +2284,7 @@ function RadioGroup({
|
|
|
2300
2284
|
onChange: () => setValue(resolved.value),
|
|
2301
2285
|
className: cn(
|
|
2302
2286
|
sizeClasses6,
|
|
2303
|
-
"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-
|
|
2287
|
+
"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]",
|
|
2304
2288
|
dirtyRingClasses(dirty),
|
|
2305
2289
|
error && "border-red-500"
|
|
2306
2290
|
)
|
|
@@ -2312,7 +2296,7 @@ function RadioGroup({
|
|
|
2312
2296
|
{
|
|
2313
2297
|
htmlFor: optionId,
|
|
2314
2298
|
className: cn(
|
|
2315
|
-
"cursor-pointer text-sm text-zinc-700 dark:text-zinc-
|
|
2299
|
+
"cursor-pointer text-sm text-zinc-700 dark:text-zinc-100",
|
|
2316
2300
|
(disabled || resolved.disabled) && "cursor-not-allowed opacity-50"
|
|
2317
2301
|
),
|
|
2318
2302
|
children: resolved.label
|
|
@@ -2419,7 +2403,7 @@ var Switch = react.forwardRef(
|
|
|
2419
2403
|
className: cn(
|
|
2420
2404
|
"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",
|
|
2421
2405
|
trackSizes,
|
|
2422
|
-
checked ? trackColorMap[color] : "bg-zinc-200 dark:bg-zinc-
|
|
2406
|
+
checked ? trackColorMap[color] : "bg-zinc-200 dark:bg-zinc-600",
|
|
2423
2407
|
dirtyRingClasses(dirty),
|
|
2424
2408
|
error && "ring-2 ring-red-500/50"
|
|
2425
2409
|
),
|
|
@@ -2442,7 +2426,7 @@ var Switch = react.forwardRef(
|
|
|
2442
2426
|
{
|
|
2443
2427
|
htmlFor: switchId,
|
|
2444
2428
|
className: cn(
|
|
2445
|
-
"cursor-pointer text-sm text-zinc-700 dark:text-zinc-
|
|
2429
|
+
"cursor-pointer text-sm text-zinc-700 dark:text-zinc-100",
|
|
2446
2430
|
disabled && "cursor-not-allowed opacity-50"
|
|
2447
2431
|
),
|
|
2448
2432
|
children: [
|
|
@@ -2744,7 +2728,7 @@ function MultiSwitch({
|
|
|
2744
2728
|
role: "radiogroup",
|
|
2745
2729
|
id,
|
|
2746
2730
|
className: cn(
|
|
2747
|
-
"relative inline-flex rounded-lg border border-zinc-300 bg-zinc-100 dark:border-zinc-
|
|
2731
|
+
"relative inline-flex rounded-lg border border-zinc-300 bg-zinc-100 dark:border-zinc-700 dark:bg-zinc-800",
|
|
2748
2732
|
dirty && "ring-2 ring-amber-400/50",
|
|
2749
2733
|
error && "ring-2 ring-red-500/50",
|
|
2750
2734
|
disabled && "opacity-50 cursor-not-allowed",
|
|
@@ -3438,7 +3422,7 @@ function EmojiSelect({
|
|
|
3438
3422
|
"button",
|
|
3439
3423
|
{
|
|
3440
3424
|
type: "button",
|
|
3441
|
-
className: "flex items-center gap-2 rounded-lg border border-zinc-300 px-3 py-2 text-sm dark:border-zinc-
|
|
3425
|
+
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]",
|
|
3442
3426
|
onClick: () => setOpen(!open),
|
|
3443
3427
|
children: selected ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xl", children: selected }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-zinc-400", children: "Pick emoji" })
|
|
3444
3428
|
}
|
|
@@ -3451,7 +3435,7 @@ function EmojiSelect({
|
|
|
3451
3435
|
value: query,
|
|
3452
3436
|
onChange: (e) => setQuery(e.target.value),
|
|
3453
3437
|
placeholder,
|
|
3454
|
-
className: "mb-2 w-full rounded-md border border-zinc-200 px-2 py-1 text-sm dark:border-zinc-
|
|
3438
|
+
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",
|
|
3455
3439
|
autoFocus: true
|
|
3456
3440
|
}
|
|
3457
3441
|
),
|
|
@@ -4511,42 +4495,66 @@ var Callout = react.forwardRef(
|
|
|
4511
4495
|
);
|
|
4512
4496
|
Callout.displayName = "Callout";
|
|
4513
4497
|
var TimelineContext = react.createContext({
|
|
4514
|
-
|
|
4515
|
-
index: 0
|
|
4498
|
+
variant: "stacked",
|
|
4499
|
+
index: 0,
|
|
4500
|
+
total: 0,
|
|
4501
|
+
animated: true
|
|
4516
4502
|
});
|
|
4517
4503
|
function useTimeline() {
|
|
4518
4504
|
return react.useContext(TimelineContext);
|
|
4519
4505
|
}
|
|
4520
4506
|
var dotColorClasses2 = {
|
|
4521
|
-
|
|
4522
|
-
|
|
4523
|
-
amber: "bg-amber-500
|
|
4524
|
-
|
|
4525
|
-
|
|
4526
|
-
|
|
4527
|
-
|
|
4528
|
-
|
|
4529
|
-
|
|
4530
|
-
|
|
4531
|
-
|
|
4532
|
-
|
|
4507
|
+
red: "bg-red-500",
|
|
4508
|
+
orange: "bg-orange-500",
|
|
4509
|
+
amber: "bg-amber-500",
|
|
4510
|
+
yellow: "bg-yellow-500",
|
|
4511
|
+
lime: "bg-lime-500",
|
|
4512
|
+
green: "bg-green-500",
|
|
4513
|
+
emerald: "bg-emerald-500",
|
|
4514
|
+
teal: "bg-teal-500",
|
|
4515
|
+
cyan: "bg-cyan-500",
|
|
4516
|
+
sky: "bg-sky-500",
|
|
4517
|
+
blue: "bg-blue-500",
|
|
4518
|
+
indigo: "bg-indigo-500",
|
|
4519
|
+
violet: "bg-violet-500",
|
|
4520
|
+
purple: "bg-purple-500",
|
|
4521
|
+
fuchsia: "bg-fuchsia-500",
|
|
4522
|
+
pink: "bg-pink-500",
|
|
4523
|
+
rose: "bg-rose-500",
|
|
4524
|
+
zinc: "bg-zinc-300 dark:bg-zinc-600"
|
|
4533
4525
|
};
|
|
4534
4526
|
var ringColorClasses = {
|
|
4535
|
-
|
|
4536
|
-
|
|
4537
|
-
amber: "ring-amber-500/30
|
|
4538
|
-
|
|
4527
|
+
red: "ring-red-500/30",
|
|
4528
|
+
orange: "ring-orange-500/30",
|
|
4529
|
+
amber: "ring-amber-500/30",
|
|
4530
|
+
yellow: "ring-yellow-500/30",
|
|
4531
|
+
lime: "ring-lime-500/30",
|
|
4532
|
+
green: "ring-green-500/30",
|
|
4533
|
+
emerald: "ring-emerald-500/30",
|
|
4534
|
+
teal: "ring-teal-500/30",
|
|
4535
|
+
cyan: "ring-cyan-500/30",
|
|
4536
|
+
sky: "ring-sky-500/30",
|
|
4537
|
+
blue: "ring-blue-500/30",
|
|
4538
|
+
indigo: "ring-indigo-500/30",
|
|
4539
|
+
violet: "ring-violet-500/30",
|
|
4540
|
+
purple: "ring-purple-500/30",
|
|
4541
|
+
fuchsia: "ring-fuchsia-500/30",
|
|
4542
|
+
pink: "ring-pink-500/30",
|
|
4543
|
+
rose: "ring-rose-500/30",
|
|
4539
4544
|
zinc: "ring-zinc-400/30 dark:ring-zinc-500/30"
|
|
4540
4545
|
};
|
|
4541
|
-
function Dot({ icon, color, active }) {
|
|
4546
|
+
function Dot({ icon, emoji, color, active }) {
|
|
4542
4547
|
const c = color ?? "zinc";
|
|
4548
|
+
if (emoji) {
|
|
4549
|
+
return /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsx("span", { className: "text-sm", children: emoji }) });
|
|
4550
|
+
}
|
|
4543
4551
|
if (icon) {
|
|
4544
4552
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4545
4553
|
"span",
|
|
4546
4554
|
{
|
|
4547
4555
|
className: cn(
|
|
4548
|
-
"flex h-
|
|
4549
|
-
|
|
4556
|
+
"flex h-8 w-8 shrink-0 items-center justify-center rounded-full text-white",
|
|
4557
|
+
dotColorClasses2[c],
|
|
4550
4558
|
active && "ring-4",
|
|
4551
4559
|
active && ringColorClasses[c]
|
|
4552
4560
|
),
|
|
@@ -4558,7 +4566,7 @@ function Dot({ icon, color, active }) {
|
|
|
4558
4566
|
"span",
|
|
4559
4567
|
{
|
|
4560
4568
|
className: cn(
|
|
4561
|
-
"h-3 w-3 rounded-full",
|
|
4569
|
+
"h-3 w-3 shrink-0 rounded-full",
|
|
4562
4570
|
dotColorClasses2[c],
|
|
4563
4571
|
active && "ring-4",
|
|
4564
4572
|
active && ringColorClasses[c]
|
|
@@ -4566,32 +4574,83 @@ function Dot({ icon, color, active }) {
|
|
|
4566
4574
|
}
|
|
4567
4575
|
);
|
|
4568
4576
|
}
|
|
4577
|
+
function useIntersectionReveal(animated) {
|
|
4578
|
+
const ref = react.useRef(null);
|
|
4579
|
+
const [visible, setVisible] = react.useState(!animated);
|
|
4580
|
+
react.useEffect(() => {
|
|
4581
|
+
if (!animated || !ref.current) return;
|
|
4582
|
+
const el = ref.current;
|
|
4583
|
+
const observer = new IntersectionObserver(
|
|
4584
|
+
([entry]) => {
|
|
4585
|
+
if (entry.isIntersecting) {
|
|
4586
|
+
setVisible(true);
|
|
4587
|
+
observer.disconnect();
|
|
4588
|
+
}
|
|
4589
|
+
},
|
|
4590
|
+
{ threshold: 0.2 }
|
|
4591
|
+
);
|
|
4592
|
+
observer.observe(el);
|
|
4593
|
+
return () => observer.disconnect();
|
|
4594
|
+
}, [animated]);
|
|
4595
|
+
return { ref, visible };
|
|
4596
|
+
}
|
|
4569
4597
|
var TimelineItem = react.forwardRef(
|
|
4570
|
-
({
|
|
4571
|
-
|
|
4572
|
-
|
|
4573
|
-
|
|
4574
|
-
|
|
4575
|
-
|
|
4576
|
-
|
|
4577
|
-
const { orientation, index } = useTimeline();
|
|
4578
|
-
if (orientation === "horizontal") {
|
|
4579
|
-
const isTop = index % 2 === 0;
|
|
4598
|
+
({ children, icon, emoji, date, color = "zinc", active = false, className }, _ref) => {
|
|
4599
|
+
const { variant, index, total, animated } = useTimeline();
|
|
4600
|
+
const { ref, visible } = useIntersectionReveal(animated);
|
|
4601
|
+
const isLast = index === total - 1;
|
|
4602
|
+
const isLargeDot = !!icon || !!emoji;
|
|
4603
|
+
const isEven = index % 2 === 0;
|
|
4604
|
+
if (variant === "horizontal") {
|
|
4580
4605
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4581
4606
|
"div",
|
|
4582
4607
|
{
|
|
4583
4608
|
ref,
|
|
4584
4609
|
"data-react-fancy-timeline-item": "",
|
|
4585
|
-
className: cn(
|
|
4586
|
-
|
|
4610
|
+
className: cn(
|
|
4611
|
+
"flex flex-col items-center",
|
|
4612
|
+
!isLast && "min-w-40",
|
|
4613
|
+
animated && "transition duration-500 ease-out",
|
|
4614
|
+
animated && (visible ? "translate-y-0 opacity-100" : "translate-y-4 opacity-0"),
|
|
4615
|
+
className
|
|
4616
|
+
),
|
|
4587
4617
|
children: [
|
|
4588
|
-
/* @__PURE__ */ jsxRuntime.
|
|
4589
|
-
|
|
4590
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4591
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "
|
|
4592
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-px flex-1 bg-zinc-200 dark:bg-zinc-700" })
|
|
4618
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-8 w-full items-center", children: [
|
|
4619
|
+
index > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-px flex-1 bg-zinc-200 dark:bg-zinc-700" }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1" }),
|
|
4620
|
+
/* @__PURE__ */ jsxRuntime.jsx(Dot, { icon, emoji, color, active }),
|
|
4621
|
+
!isLast ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-px flex-1 bg-zinc-200 dark:bg-zinc-700" }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1" })
|
|
4593
4622
|
] }),
|
|
4594
|
-
/* @__PURE__ */ jsxRuntime.
|
|
4623
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 max-w-40 px-2 text-center", children: [
|
|
4624
|
+
date && /* @__PURE__ */ jsxRuntime.jsx("time", { className: "text-xs font-medium uppercase tracking-wide text-zinc-500 dark:text-zinc-400", children: date }),
|
|
4625
|
+
children
|
|
4626
|
+
] })
|
|
4627
|
+
]
|
|
4628
|
+
}
|
|
4629
|
+
);
|
|
4630
|
+
}
|
|
4631
|
+
if (variant === "alternating") {
|
|
4632
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4633
|
+
"div",
|
|
4634
|
+
{
|
|
4635
|
+
ref,
|
|
4636
|
+
"data-react-fancy-timeline-item": "",
|
|
4637
|
+
className: cn(
|
|
4638
|
+
"relative flex gap-x-4 md:grid md:grid-cols-[1fr_1.5rem_1fr] md:gap-x-6",
|
|
4639
|
+
animated && "transition duration-500 ease-out",
|
|
4640
|
+
animated && (visible ? "translate-y-0 opacity-100" : "translate-y-4 opacity-0"),
|
|
4641
|
+
className
|
|
4642
|
+
),
|
|
4643
|
+
children: [
|
|
4644
|
+
/* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsx("div", { className: "mt-1.5", children: /* @__PURE__ */ jsxRuntime.jsx(Dot, { icon, emoji, color, active }) }) : /* @__PURE__ */ jsxRuntime.jsx(Dot, { icon, emoji, color, active }) }),
|
|
4645
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn(
|
|
4646
|
+
"min-w-0 flex-1",
|
|
4647
|
+
!isLast && "pb-8",
|
|
4648
|
+
isLargeDot && "pt-1",
|
|
4649
|
+
isEven ? "md:col-start-1 md:row-start-1 md:text-right" : "md:col-start-3"
|
|
4650
|
+
), children: [
|
|
4651
|
+
date && /* @__PURE__ */ jsxRuntime.jsx("time", { className: "text-xs font-medium uppercase tracking-wide text-zinc-500 dark:text-zinc-400", children: date }),
|
|
4652
|
+
children
|
|
4653
|
+
] })
|
|
4595
4654
|
]
|
|
4596
4655
|
}
|
|
4597
4656
|
);
|
|
@@ -4601,11 +4660,18 @@ var TimelineItem = react.forwardRef(
|
|
|
4601
4660
|
{
|
|
4602
4661
|
ref,
|
|
4603
4662
|
"data-react-fancy-timeline-item": "",
|
|
4604
|
-
className: cn(
|
|
4663
|
+
className: cn(
|
|
4664
|
+
"relative flex gap-x-4",
|
|
4665
|
+
animated && "transition duration-500 ease-out",
|
|
4666
|
+
animated && (visible ? "translate-y-0 opacity-100" : "translate-y-4 opacity-0"),
|
|
4667
|
+
className
|
|
4668
|
+
),
|
|
4605
4669
|
children: [
|
|
4606
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "
|
|
4607
|
-
/* @__PURE__ */ jsxRuntime.
|
|
4608
|
-
|
|
4670
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative z-10 flex w-8 shrink-0 justify-center", children: !isLargeDot ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1.5", children: /* @__PURE__ */ jsxRuntime.jsx(Dot, { icon, emoji, color, active }) }) : /* @__PURE__ */ jsxRuntime.jsx(Dot, { icon, emoji, color, active }) }),
|
|
4671
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("min-w-0 flex-1", !isLast && "pb-8", isLargeDot && "pt-1"), children: [
|
|
4672
|
+
date && /* @__PURE__ */ jsxRuntime.jsx("time", { className: "text-xs font-medium uppercase tracking-wide text-zinc-500 dark:text-zinc-400", children: date }),
|
|
4673
|
+
children
|
|
4674
|
+
] })
|
|
4609
4675
|
]
|
|
4610
4676
|
}
|
|
4611
4677
|
);
|
|
@@ -4613,8 +4679,8 @@ var TimelineItem = react.forwardRef(
|
|
|
4613
4679
|
);
|
|
4614
4680
|
TimelineItem.displayName = "TimelineItem";
|
|
4615
4681
|
var TimelineBlock = react.forwardRef(
|
|
4616
|
-
({ heading, children, icon, color = "zinc", active = false, className }, ref) => {
|
|
4617
|
-
return /* @__PURE__ */ jsxRuntime.jsx(TimelineItem, { icon, color, active, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4682
|
+
({ heading, children, icon, emoji, color = "zinc", active = false, className }, ref) => {
|
|
4683
|
+
return /* @__PURE__ */ jsxRuntime.jsx(TimelineItem, { icon, emoji, color, active, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4618
4684
|
"div",
|
|
4619
4685
|
{
|
|
4620
4686
|
ref,
|
|
@@ -4634,21 +4700,58 @@ var TimelineBlock = react.forwardRef(
|
|
|
4634
4700
|
);
|
|
4635
4701
|
TimelineBlock.displayName = "TimelineBlock";
|
|
4636
4702
|
var TimelineRoot = react.forwardRef(
|
|
4637
|
-
({
|
|
4638
|
-
|
|
4639
|
-
|
|
4640
|
-
|
|
4641
|
-
|
|
4642
|
-
|
|
4643
|
-
|
|
4644
|
-
|
|
4645
|
-
|
|
4646
|
-
|
|
4647
|
-
|
|
4648
|
-
|
|
4649
|
-
|
|
4650
|
-
|
|
4651
|
-
|
|
4703
|
+
({
|
|
4704
|
+
children,
|
|
4705
|
+
variant: variantProp,
|
|
4706
|
+
orientation,
|
|
4707
|
+
events,
|
|
4708
|
+
heading,
|
|
4709
|
+
description,
|
|
4710
|
+
animated = true,
|
|
4711
|
+
className
|
|
4712
|
+
}, ref) => {
|
|
4713
|
+
const scrollRef = react.useRef(null);
|
|
4714
|
+
let variant = variantProp ?? "stacked";
|
|
4715
|
+
if (!variantProp && orientation) {
|
|
4716
|
+
variant = orientation === "horizontal" ? "horizontal" : "stacked";
|
|
4717
|
+
}
|
|
4718
|
+
const isHorizontal = variant === "horizontal";
|
|
4719
|
+
const isAlternating = variant === "alternating";
|
|
4720
|
+
const items = events ? events.map((e, i) => /* @__PURE__ */ jsxRuntime.jsxs(TimelineItem, { date: e.date, emoji: e.emoji, icon: e.icon, color: e.color, children: [
|
|
4721
|
+
e.title && /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "font-semibold text-zinc-900 dark:text-white", children: e.title }),
|
|
4722
|
+
e.description && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 text-sm leading-relaxed text-zinc-600 dark:text-zinc-400", children: e.description })
|
|
4723
|
+
] }, i)) : react.Children.toArray(children);
|
|
4724
|
+
const handleWheel = react.useCallback((e) => {
|
|
4725
|
+
if (!scrollRef.current) return;
|
|
4726
|
+
e.preventDefault();
|
|
4727
|
+
scrollRef.current.scrollLeft += e.deltaY;
|
|
4728
|
+
}, []);
|
|
4729
|
+
const content = items.map((child, i) => /* @__PURE__ */ jsxRuntime.jsx(TimelineContext.Provider, { value: { variant, index: i, total: items.length, animated }, children: child }, i));
|
|
4730
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, "data-react-fancy-timeline": "", "data-variant": variant, className, children: [
|
|
4731
|
+
(heading || description) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-8", children: [
|
|
4732
|
+
heading && /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-xl font-semibold text-zinc-900 dark:text-white", children: heading }),
|
|
4733
|
+
description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-sm text-zinc-500 dark:text-zinc-400", children: description })
|
|
4734
|
+
] }),
|
|
4735
|
+
isHorizontal ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
4736
|
+
"div",
|
|
4737
|
+
{
|
|
4738
|
+
ref: scrollRef,
|
|
4739
|
+
className: "overflow-x-auto pb-4 -mb-4",
|
|
4740
|
+
style: { scrollbarWidth: "thin", scrollbarColor: "rgb(161 161 170) transparent" },
|
|
4741
|
+
onWheel: handleWheel,
|
|
4742
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex min-w-max items-start", children: content })
|
|
4743
|
+
}
|
|
4744
|
+
) : (
|
|
4745
|
+
/* Vertical variants: continuous background line behind all events */
|
|
4746
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
4747
|
+
items.length > 1 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(
|
|
4748
|
+
"absolute top-0 bottom-0 w-px bg-zinc-200 dark:bg-zinc-700",
|
|
4749
|
+
isAlternating ? "left-4 md:left-1/2 md:-translate-x-px" : "left-4"
|
|
4750
|
+
) }),
|
|
4751
|
+
content
|
|
4752
|
+
] })
|
|
4753
|
+
)
|
|
4754
|
+
] });
|
|
4652
4755
|
}
|
|
4653
4756
|
);
|
|
4654
4757
|
TimelineRoot.displayName = "Timeline";
|
|
@@ -4769,7 +4872,7 @@ var Tooltip = react.forwardRef(
|
|
|
4769
4872
|
"data-react-fancy-tooltip": "",
|
|
4770
4873
|
role: "tooltip",
|
|
4771
4874
|
className: cn(
|
|
4772
|
-
"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-
|
|
4875
|
+
"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",
|
|
4773
4876
|
className
|
|
4774
4877
|
),
|
|
4775
4878
|
style: { left: position.x, top: position.y },
|
|
@@ -4779,7 +4882,7 @@ var Tooltip = react.forwardRef(
|
|
|
4779
4882
|
"div",
|
|
4780
4883
|
{
|
|
4781
4884
|
className: cn(
|
|
4782
|
-
"absolute h-2 w-2 rotate-45 bg-zinc-900 dark:bg-zinc-
|
|
4885
|
+
"absolute h-2 w-2 rotate-45 bg-zinc-900 dark:bg-zinc-700",
|
|
4783
4886
|
position.placement.startsWith("top") && "bottom-[-4px] left-1/2 -translate-x-1/2",
|
|
4784
4887
|
position.placement.startsWith("bottom") && "top-[-4px] left-1/2 -translate-x-1/2",
|
|
4785
4888
|
position.placement.startsWith("left") && "right-[-4px] top-1/2 -translate-y-1/2",
|
|
@@ -6271,7 +6374,7 @@ var Autocomplete = react.forwardRef(
|
|
|
6271
6374
|
role: "combobox",
|
|
6272
6375
|
"aria-expanded": open,
|
|
6273
6376
|
"aria-autocomplete": "list",
|
|
6274
|
-
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-
|
|
6377
|
+
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"
|
|
6275
6378
|
}
|
|
6276
6379
|
),
|
|
6277
6380
|
open && /* @__PURE__ */ jsxRuntime.jsx(Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -6365,7 +6468,7 @@ var Pillbox = react.forwardRef(
|
|
|
6365
6468
|
"data-react-fancy-pillbox": "",
|
|
6366
6469
|
ref,
|
|
6367
6470
|
className: cn(
|
|
6368
|
-
"flex flex-wrap items-center gap-1.5 rounded-lg border border-zinc-200 bg-white px-3 py-2 transition-
|
|
6471
|
+
"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",
|
|
6369
6472
|
disabled && "cursor-not-allowed opacity-50",
|
|
6370
6473
|
className
|
|
6371
6474
|
),
|
|
@@ -6496,7 +6599,7 @@ var OtpInput = react.forwardRef(
|
|
|
6496
6599
|
onFocus: (e) => e.target.select(),
|
|
6497
6600
|
disabled,
|
|
6498
6601
|
autoFocus: autoFocus && i === 0,
|
|
6499
|
-
className: "h-12 w-10 rounded-lg border border-zinc-200 bg-white text-center text-lg font-medium outline-none transition-
|
|
6602
|
+
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",
|
|
6500
6603
|
"aria-label": `Digit ${i + 1}`
|
|
6501
6604
|
},
|
|
6502
6605
|
i
|
|
@@ -6545,7 +6648,7 @@ function FileUploadDropzone({
|
|
|
6545
6648
|
onClick: () => !disabled && inputRef.current?.click(),
|
|
6546
6649
|
className: cn(
|
|
6547
6650
|
"flex cursor-pointer flex-col items-center justify-center rounded-xl border-2 border-dashed p-8 text-center transition-colors",
|
|
6548
|
-
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-
|
|
6651
|
+
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",
|
|
6549
6652
|
disabled && "cursor-not-allowed opacity-50",
|
|
6550
6653
|
className
|
|
6551
6654
|
),
|
|
@@ -7905,6 +8008,7 @@ function usePanZoom({
|
|
|
7905
8008
|
if (!container) return;
|
|
7906
8009
|
function handleWheel(e) {
|
|
7907
8010
|
if (!zoomableRef.current) return;
|
|
8011
|
+
if (!e.ctrlKey && !e.metaKey) return;
|
|
7908
8012
|
e.preventDefault();
|
|
7909
8013
|
const rect = container.getBoundingClientRect();
|
|
7910
8014
|
const mouseX = e.clientX - rect.left;
|
|
@@ -9097,9 +9201,11 @@ function useCanvas() {
|
|
|
9097
9201
|
if (!ctx) throw new Error("useCanvas must be used within a Canvas component");
|
|
9098
9202
|
return ctx;
|
|
9099
9203
|
}
|
|
9100
|
-
function CanvasNode({ children, id, x, y, className, style }) {
|
|
9101
|
-
const { registerNode, unregisterNode } = useCanvas();
|
|
9204
|
+
function CanvasNode({ children, id, x, y, draggable, onPositionChange, className, style }) {
|
|
9205
|
+
const { registerNode, unregisterNode, viewport } = useCanvas();
|
|
9102
9206
|
const nodeRef = react.useRef(null);
|
|
9207
|
+
const isDragging = react.useRef(false);
|
|
9208
|
+
const dragStart = react.useRef({ mouseX: 0, mouseY: 0, nodeX: 0, nodeY: 0 });
|
|
9103
9209
|
react.useEffect(() => {
|
|
9104
9210
|
const el = nodeRef.current;
|
|
9105
9211
|
if (!el) return;
|
|
@@ -9114,14 +9220,39 @@ function CanvasNode({ children, id, x, y, className, style }) {
|
|
|
9114
9220
|
unregisterNode(id);
|
|
9115
9221
|
};
|
|
9116
9222
|
}, [id, x, y, registerNode, unregisterNode]);
|
|
9223
|
+
const handlePointerDown = react.useCallback(
|
|
9224
|
+
(e) => {
|
|
9225
|
+
if (!draggable || e.button !== 0) return;
|
|
9226
|
+
e.stopPropagation();
|
|
9227
|
+
isDragging.current = true;
|
|
9228
|
+
dragStart.current = { mouseX: e.clientX, mouseY: e.clientY, nodeX: x, nodeY: y };
|
|
9229
|
+
e.target.setPointerCapture(e.pointerId);
|
|
9230
|
+
},
|
|
9231
|
+
[draggable, x, y]
|
|
9232
|
+
);
|
|
9233
|
+
const handlePointerMove = react.useCallback(
|
|
9234
|
+
(e) => {
|
|
9235
|
+
if (!isDragging.current) return;
|
|
9236
|
+
const dx = (e.clientX - dragStart.current.mouseX) / viewport.zoom;
|
|
9237
|
+
const dy = (e.clientY - dragStart.current.mouseY) / viewport.zoom;
|
|
9238
|
+
onPositionChange?.(dragStart.current.nodeX + dx, dragStart.current.nodeY + dy);
|
|
9239
|
+
},
|
|
9240
|
+
[viewport.zoom, onPositionChange]
|
|
9241
|
+
);
|
|
9242
|
+
const handlePointerUp = react.useCallback(() => {
|
|
9243
|
+
isDragging.current = false;
|
|
9244
|
+
}, []);
|
|
9117
9245
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
9118
9246
|
"div",
|
|
9119
9247
|
{
|
|
9120
9248
|
ref: nodeRef,
|
|
9121
9249
|
"data-react-fancy-canvas-node": "",
|
|
9122
9250
|
"data-node-id": id,
|
|
9123
|
-
className: cn("absolute", className),
|
|
9251
|
+
className: cn("absolute", draggable && "cursor-grab active:cursor-grabbing", className),
|
|
9124
9252
|
style: { left: x, top: y, ...style },
|
|
9253
|
+
onPointerDown: handlePointerDown,
|
|
9254
|
+
onPointerMove: handlePointerMove,
|
|
9255
|
+
onPointerUp: handlePointerUp,
|
|
9125
9256
|
children
|
|
9126
9257
|
}
|
|
9127
9258
|
);
|
|
@@ -9158,10 +9289,18 @@ function getAnchorPoint(rect, anchor, otherRect) {
|
|
|
9158
9289
|
}
|
|
9159
9290
|
}
|
|
9160
9291
|
function bezierPath(from, to) {
|
|
9161
|
-
const dx = Math.abs(to.x - from.x)
|
|
9162
|
-
const
|
|
9163
|
-
|
|
9164
|
-
|
|
9292
|
+
const dx = Math.abs(to.x - from.x);
|
|
9293
|
+
const dy = Math.abs(to.y - from.y);
|
|
9294
|
+
if (dx > dy) {
|
|
9295
|
+
const offset2 = dx * 0.5;
|
|
9296
|
+
const cp1x = from.x + (to.x > from.x ? offset2 : -offset2);
|
|
9297
|
+
const cp2x = to.x + (to.x > from.x ? -offset2 : offset2);
|
|
9298
|
+
return `M${from.x},${from.y} C${cp1x},${from.y} ${cp2x},${to.y} ${to.x},${to.y}`;
|
|
9299
|
+
}
|
|
9300
|
+
const offset = Math.max(dy * 0.5, 30);
|
|
9301
|
+
const cp1y = from.y + (to.y > from.y ? offset : -offset);
|
|
9302
|
+
const cp2y = to.y + (to.y > from.y ? -offset : offset);
|
|
9303
|
+
return `M${from.x},${from.y} C${from.x},${cp1y} ${to.x},${cp2y} ${to.x},${to.y}`;
|
|
9165
9304
|
}
|
|
9166
9305
|
function stepPath(from, to) {
|
|
9167
9306
|
const midX = (from.x + to.x) / 2;
|
|
@@ -9346,6 +9485,7 @@ function CanvasRoot({
|
|
|
9346
9485
|
pannable = true,
|
|
9347
9486
|
zoomable = true,
|
|
9348
9487
|
showGrid = false,
|
|
9488
|
+
fitOnMount = false,
|
|
9349
9489
|
className,
|
|
9350
9490
|
style
|
|
9351
9491
|
}) {
|
|
@@ -9365,15 +9505,41 @@ function CanvasRoot({
|
|
|
9365
9505
|
() => ({ viewport, setViewport, registerNode, unregisterNode, nodeRects, registryVersion, containerRef }),
|
|
9366
9506
|
[viewport, setViewport, registerNode, unregisterNode, nodeRects, registryVersion]
|
|
9367
9507
|
);
|
|
9508
|
+
const hasFitted = react.useRef(false);
|
|
9509
|
+
react.useEffect(() => {
|
|
9510
|
+
if (!fitOnMount || hasFitted.current || nodeRects.size === 0) return;
|
|
9511
|
+
const container = containerRef.current;
|
|
9512
|
+
if (!container || container.clientWidth === 0) return;
|
|
9513
|
+
hasFitted.current = true;
|
|
9514
|
+
requestAnimationFrame(() => {
|
|
9515
|
+
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
|
9516
|
+
nodeRects.forEach((r) => {
|
|
9517
|
+
minX = Math.min(minX, r.x);
|
|
9518
|
+
minY = Math.min(minY, r.y);
|
|
9519
|
+
maxX = Math.max(maxX, r.x + r.width);
|
|
9520
|
+
maxY = Math.max(maxY, r.y + r.height);
|
|
9521
|
+
});
|
|
9522
|
+
const padding = 40;
|
|
9523
|
+
const contentW = maxX - minX + padding * 2;
|
|
9524
|
+
const contentH = maxY - minY + padding * 2;
|
|
9525
|
+
const cw = container.clientWidth;
|
|
9526
|
+
const ch = container.clientHeight;
|
|
9527
|
+
const zoom = Math.min(cw / contentW, ch / contentH, 1.5);
|
|
9528
|
+
const panX = (cw - contentW * zoom) / 2 - minX * zoom + padding * zoom;
|
|
9529
|
+
const panY = (ch - contentH * zoom) / 2 - minY * zoom + padding * zoom;
|
|
9530
|
+
setViewport({ panX, panY, zoom });
|
|
9531
|
+
});
|
|
9532
|
+
}, [fitOnMount, nodeRects, registryVersion, setViewport]);
|
|
9368
9533
|
const edges = [];
|
|
9369
9534
|
const others = [];
|
|
9370
9535
|
const overlays = [];
|
|
9371
9536
|
react.Children.forEach(children, (child) => {
|
|
9372
9537
|
const el = child;
|
|
9373
9538
|
if (!el || !el.type) return;
|
|
9374
|
-
|
|
9539
|
+
const elType = el.type;
|
|
9540
|
+
if (elType === CanvasEdge || elType?._isCanvasEdge) {
|
|
9375
9541
|
edges.push(el);
|
|
9376
|
-
} else if (
|
|
9542
|
+
} else if (elType === CanvasMinimap || elType === CanvasControls) {
|
|
9377
9543
|
overlays.push(el);
|
|
9378
9544
|
} else {
|
|
9379
9545
|
others.push(el);
|
|
@@ -9420,15 +9586,16 @@ function CanvasRoot({
|
|
|
9420
9586
|
},
|
|
9421
9587
|
children: [
|
|
9422
9588
|
/* @__PURE__ */ jsxRuntime.jsxs("defs", { children: [
|
|
9423
|
-
/* @__PURE__ */ jsxRuntime.jsx("marker", { id: "canvas-arrow", viewBox: "0 0 10 10", refX: "10", refY: "5", markerWidth: "8", markerHeight: "8", orient: "auto
|
|
9424
|
-
/* @__PURE__ */ jsxRuntime.jsx("marker", { id: "canvas-circle", viewBox: "0 0 10 10", refX: "5", refY: "5", markerWidth: "8", markerHeight: "8", orient: "auto
|
|
9425
|
-
/* @__PURE__ */ jsxRuntime.jsx("marker", { id: "canvas-
|
|
9426
|
-
/* @__PURE__ */ jsxRuntime.
|
|
9427
|
-
|
|
9428
|
-
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "
|
|
9429
|
-
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "
|
|
9430
|
-
|
|
9431
|
-
|
|
9589
|
+
/* @__PURE__ */ jsxRuntime.jsx("marker", { id: "canvas-arrow", viewBox: "0 0 10 10", refX: "10", refY: "5", markerWidth: "8", markerHeight: "8", orient: "auto", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M0,0 L10,5 L0,10 Z", fill: "#71717a" }) }),
|
|
9590
|
+
/* @__PURE__ */ jsxRuntime.jsx("marker", { id: "canvas-circle", viewBox: "0 0 10 10", refX: "5", refY: "5", markerWidth: "8", markerHeight: "8", orient: "auto", children: /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "5", cy: "5", r: "3.5", fill: "#71717a" }) }),
|
|
9591
|
+
/* @__PURE__ */ jsxRuntime.jsx("marker", { id: "canvas-diamond", viewBox: "0 0 12 12", refX: "6", refY: "6", markerWidth: "10", markerHeight: "10", orient: "auto", children: /* @__PURE__ */ jsxRuntime.jsx("polygon", { points: "6,0 12,6 6,12 0,6", fill: "none", stroke: "#71717a", strokeWidth: "1.5" }) }),
|
|
9592
|
+
/* @__PURE__ */ jsxRuntime.jsx("marker", { id: "canvas-one", viewBox: "0 0 2 16", refX: "1", refY: "8", markerWidth: "2", markerHeight: "14", orient: "auto", children: /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "1", y1: "0", x2: "1", y2: "16", stroke: "#71717a", strokeWidth: "2" }) }),
|
|
9593
|
+
/* @__PURE__ */ jsxRuntime.jsxs("marker", { id: "canvas-crow-foot", viewBox: "0 0 16 16", refX: "16", refY: "8", markerWidth: "14", markerHeight: "14", orient: "auto", children: [
|
|
9594
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "16", y1: "8", x2: "0", y2: "0", stroke: "#71717a", strokeWidth: "2", strokeLinecap: "round" }),
|
|
9595
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "16", y1: "8", x2: "0", y2: "8", stroke: "#71717a", strokeWidth: "2", strokeLinecap: "round" }),
|
|
9596
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "16", y1: "8", x2: "0", y2: "16", stroke: "#71717a", strokeWidth: "2", strokeLinecap: "round" }),
|
|
9597
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "16", y1: "0", x2: "16", y2: "16", stroke: "#71717a", strokeWidth: "2", strokeLinecap: "round" })
|
|
9598
|
+
] })
|
|
9432
9599
|
] }),
|
|
9433
9600
|
edges
|
|
9434
9601
|
]
|
|
@@ -9486,13 +9653,16 @@ function DiagramField({
|
|
|
9486
9653
|
DiagramField.displayName = "DiagramField";
|
|
9487
9654
|
function DiagramEntity({
|
|
9488
9655
|
children,
|
|
9489
|
-
id,
|
|
9656
|
+
id: idProp,
|
|
9490
9657
|
name,
|
|
9491
9658
|
x = 0,
|
|
9492
9659
|
y = 0,
|
|
9493
9660
|
color = "bg-blue-600 dark:bg-blue-500",
|
|
9661
|
+
draggable,
|
|
9662
|
+
onPositionChange,
|
|
9494
9663
|
className
|
|
9495
9664
|
}) {
|
|
9665
|
+
const id = idProp ?? name;
|
|
9496
9666
|
const fields = [];
|
|
9497
9667
|
const other = [];
|
|
9498
9668
|
react.Children.forEach(children, (child) => {
|
|
@@ -9504,7 +9674,7 @@ function DiagramEntity({
|
|
|
9504
9674
|
other.push(el);
|
|
9505
9675
|
}
|
|
9506
9676
|
});
|
|
9507
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Canvas.Node, { id, x, y, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
9677
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Canvas.Node, { id, x, y, draggable, onPositionChange, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
9508
9678
|
"div",
|
|
9509
9679
|
{
|
|
9510
9680
|
"data-react-fancy-diagram-entity": "",
|
|
@@ -9531,37 +9701,193 @@ function DiagramEntity({
|
|
|
9531
9701
|
) });
|
|
9532
9702
|
}
|
|
9533
9703
|
DiagramEntity.displayName = "DiagramEntity";
|
|
9534
|
-
|
|
9535
|
-
|
|
9536
|
-
|
|
9537
|
-
|
|
9538
|
-
|
|
9539
|
-
|
|
9540
|
-
case "
|
|
9541
|
-
|
|
9704
|
+
var HEADER_HEIGHT = 36;
|
|
9705
|
+
var FIELD_HEIGHT = 28;
|
|
9706
|
+
var SYMBOL_SIZE = 12;
|
|
9707
|
+
function oneSymbol(pt, direction) {
|
|
9708
|
+
const s = SYMBOL_SIZE * 0.6;
|
|
9709
|
+
switch (direction) {
|
|
9710
|
+
case "left":
|
|
9711
|
+
case "right":
|
|
9712
|
+
return `M${pt.x},${pt.y - s} L${pt.x},${pt.y + s}`;
|
|
9713
|
+
case "up":
|
|
9714
|
+
case "down":
|
|
9715
|
+
return `M${pt.x - s},${pt.y} L${pt.x + s},${pt.y}`;
|
|
9542
9716
|
}
|
|
9543
9717
|
}
|
|
9718
|
+
function crowFootSymbol(pt, direction) {
|
|
9719
|
+
const s = SYMBOL_SIZE;
|
|
9720
|
+
const spread = s * 0.8;
|
|
9721
|
+
let tip;
|
|
9722
|
+
switch (direction) {
|
|
9723
|
+
case "right":
|
|
9724
|
+
tip = { x: pt.x - s, y: pt.y };
|
|
9725
|
+
return [
|
|
9726
|
+
`M${pt.x},${pt.y - spread} L${tip.x},${tip.y}`,
|
|
9727
|
+
`M${pt.x},${pt.y} L${tip.x},${tip.y}`,
|
|
9728
|
+
`M${pt.x},${pt.y + spread} L${tip.x},${tip.y}`,
|
|
9729
|
+
// bar at entity edge
|
|
9730
|
+
`M${pt.x},${pt.y - spread} L${pt.x},${pt.y + spread}`
|
|
9731
|
+
].join(" ");
|
|
9732
|
+
case "left":
|
|
9733
|
+
tip = { x: pt.x + s, y: pt.y };
|
|
9734
|
+
return [
|
|
9735
|
+
`M${pt.x},${pt.y - spread} L${tip.x},${tip.y}`,
|
|
9736
|
+
`M${pt.x},${pt.y} L${tip.x},${tip.y}`,
|
|
9737
|
+
`M${pt.x},${pt.y + spread} L${tip.x},${tip.y}`,
|
|
9738
|
+
`M${pt.x},${pt.y - spread} L${pt.x},${pt.y + spread}`
|
|
9739
|
+
].join(" ");
|
|
9740
|
+
case "down":
|
|
9741
|
+
tip = { x: pt.x, y: pt.y - s };
|
|
9742
|
+
return [
|
|
9743
|
+
`M${pt.x - spread},${pt.y} L${tip.x},${tip.y}`,
|
|
9744
|
+
`M${pt.x},${pt.y} L${tip.x},${tip.y}`,
|
|
9745
|
+
`M${pt.x + spread},${pt.y} L${tip.x},${tip.y}`,
|
|
9746
|
+
`M${pt.x - spread},${pt.y} L${pt.x + spread},${pt.y}`
|
|
9747
|
+
].join(" ");
|
|
9748
|
+
case "up":
|
|
9749
|
+
tip = { x: pt.x, y: pt.y + s };
|
|
9750
|
+
return [
|
|
9751
|
+
`M${pt.x - spread},${pt.y} L${tip.x},${tip.y}`,
|
|
9752
|
+
`M${pt.x},${pt.y} L${tip.x},${tip.y}`,
|
|
9753
|
+
`M${pt.x + spread},${pt.y} L${tip.x},${tip.y}`,
|
|
9754
|
+
`M${pt.x - spread},${pt.y} L${pt.x + spread},${pt.y}`
|
|
9755
|
+
].join(" ");
|
|
9756
|
+
}
|
|
9757
|
+
}
|
|
9758
|
+
function getSymbolPath(type, end, pt, direction) {
|
|
9759
|
+
const side = end === "start" ? type.split("-to-")[0] : type.split("-to-")[1];
|
|
9760
|
+
if (side === "one") return oneSymbol(pt, direction);
|
|
9761
|
+
if (side === "many") return crowFootSymbol(pt, direction);
|
|
9762
|
+
return null;
|
|
9763
|
+
}
|
|
9544
9764
|
function DiagramRelation({
|
|
9545
9765
|
from,
|
|
9546
9766
|
to,
|
|
9767
|
+
fromField: fromFieldProp,
|
|
9768
|
+
toField: toFieldProp,
|
|
9547
9769
|
type,
|
|
9548
|
-
label
|
|
9549
|
-
className
|
|
9770
|
+
label
|
|
9550
9771
|
}) {
|
|
9551
|
-
const
|
|
9552
|
-
|
|
9553
|
-
|
|
9554
|
-
|
|
9555
|
-
|
|
9556
|
-
|
|
9557
|
-
|
|
9558
|
-
|
|
9559
|
-
|
|
9560
|
-
|
|
9561
|
-
|
|
9772
|
+
const { nodeRects, registryVersion } = useCanvas();
|
|
9773
|
+
const { schema } = useDiagram();
|
|
9774
|
+
const result = react.useMemo(() => {
|
|
9775
|
+
const fromRect = nodeRects.get(from);
|
|
9776
|
+
const toRect = nodeRects.get(to);
|
|
9777
|
+
if (!fromRect || !toRect) return null;
|
|
9778
|
+
const fromEntity = schema.entities.find((e) => (e.id ?? e.name) === from);
|
|
9779
|
+
const toEntity = schema.entities.find((e) => (e.id ?? e.name) === to);
|
|
9780
|
+
let fromFieldIdx = -1;
|
|
9781
|
+
let toFieldIdx = -1;
|
|
9782
|
+
if (fromFieldProp && fromEntity?.fields) {
|
|
9783
|
+
fromFieldIdx = fromEntity.fields.findIndex((f) => f.name === fromFieldProp);
|
|
9784
|
+
} else if (fromEntity?.fields) {
|
|
9785
|
+
fromFieldIdx = fromEntity.fields.findIndex((f) => f.primary);
|
|
9562
9786
|
}
|
|
9563
|
-
|
|
9787
|
+
if (toFieldProp && toEntity?.fields) {
|
|
9788
|
+
toFieldIdx = toEntity.fields.findIndex((f) => f.name === toFieldProp);
|
|
9789
|
+
} else if (toEntity?.fields) {
|
|
9790
|
+
const fromName = (fromEntity?.name ?? from).toLowerCase();
|
|
9791
|
+
toFieldIdx = toEntity.fields.findIndex(
|
|
9792
|
+
(f) => f.foreign && (f.name === `${fromName}_id` || f.name === `${fromName}Id`)
|
|
9793
|
+
);
|
|
9794
|
+
if (toFieldIdx === -1) {
|
|
9795
|
+
toFieldIdx = toEntity.fields.findIndex((f) => f.foreign);
|
|
9796
|
+
}
|
|
9797
|
+
}
|
|
9798
|
+
const fromFieldY = fromFieldIdx >= 0 ? HEADER_HEIGHT + fromFieldIdx * FIELD_HEIGHT + FIELD_HEIGHT / 2 : fromRect.height / 2;
|
|
9799
|
+
const toFieldY = toFieldIdx >= 0 ? HEADER_HEIGHT + toFieldIdx * FIELD_HEIGHT + FIELD_HEIGHT / 2 : toRect.height / 2;
|
|
9800
|
+
const fromCx = fromRect.x + fromRect.width / 2;
|
|
9801
|
+
const toCx = toRect.x + toRect.width / 2;
|
|
9802
|
+
const fromCy = fromRect.y + fromRect.height / 2;
|
|
9803
|
+
const toCy = toRect.y + toRect.height / 2;
|
|
9804
|
+
const dx = Math.abs(fromCx - toCx);
|
|
9805
|
+
const dy = Math.abs(fromCy - toCy);
|
|
9806
|
+
let fromPt, toPt;
|
|
9807
|
+
let fromDir;
|
|
9808
|
+
let toDir;
|
|
9809
|
+
if (dx > dy * 0.5) {
|
|
9810
|
+
if (fromCx < toCx) {
|
|
9811
|
+
fromPt = { x: fromRect.x + fromRect.width, y: fromRect.y + fromFieldY };
|
|
9812
|
+
toPt = { x: toRect.x, y: toRect.y + toFieldY };
|
|
9813
|
+
fromDir = "right";
|
|
9814
|
+
toDir = "left";
|
|
9815
|
+
} else {
|
|
9816
|
+
fromPt = { x: fromRect.x, y: fromRect.y + fromFieldY };
|
|
9817
|
+
toPt = { x: toRect.x + toRect.width, y: toRect.y + toFieldY };
|
|
9818
|
+
fromDir = "left";
|
|
9819
|
+
toDir = "right";
|
|
9820
|
+
}
|
|
9821
|
+
} else {
|
|
9822
|
+
if (fromCy < toCy) {
|
|
9823
|
+
fromPt = { x: fromRect.x + fromRect.width / 2, y: fromRect.y + fromRect.height };
|
|
9824
|
+
toPt = { x: toRect.x + toRect.width / 2, y: toRect.y };
|
|
9825
|
+
fromDir = "down";
|
|
9826
|
+
toDir = "up";
|
|
9827
|
+
} else {
|
|
9828
|
+
fromPt = { x: fromRect.x + fromRect.width / 2, y: fromRect.y };
|
|
9829
|
+
toPt = { x: toRect.x + toRect.width / 2, y: toRect.y + toRect.height };
|
|
9830
|
+
fromDir = "up";
|
|
9831
|
+
toDir = "down";
|
|
9832
|
+
}
|
|
9833
|
+
}
|
|
9834
|
+
const offsetFrom = { ...fromPt };
|
|
9835
|
+
const offsetTo = { ...toPt };
|
|
9836
|
+
switch (fromDir) {
|
|
9837
|
+
case "right":
|
|
9838
|
+
offsetFrom.x += SYMBOL_SIZE;
|
|
9839
|
+
break;
|
|
9840
|
+
case "left":
|
|
9841
|
+
offsetFrom.x -= SYMBOL_SIZE;
|
|
9842
|
+
break;
|
|
9843
|
+
case "down":
|
|
9844
|
+
offsetFrom.y += SYMBOL_SIZE;
|
|
9845
|
+
break;
|
|
9846
|
+
case "up":
|
|
9847
|
+
offsetFrom.y -= SYMBOL_SIZE;
|
|
9848
|
+
break;
|
|
9849
|
+
}
|
|
9850
|
+
switch (toDir) {
|
|
9851
|
+
case "right":
|
|
9852
|
+
offsetTo.x += SYMBOL_SIZE;
|
|
9853
|
+
break;
|
|
9854
|
+
case "left":
|
|
9855
|
+
offsetTo.x -= SYMBOL_SIZE;
|
|
9856
|
+
break;
|
|
9857
|
+
case "down":
|
|
9858
|
+
offsetTo.y += SYMBOL_SIZE;
|
|
9859
|
+
break;
|
|
9860
|
+
case "up":
|
|
9861
|
+
offsetTo.y -= SYMBOL_SIZE;
|
|
9862
|
+
break;
|
|
9863
|
+
}
|
|
9864
|
+
const adx = Math.abs(offsetTo.x - offsetFrom.x);
|
|
9865
|
+
const ady = Math.abs(offsetTo.y - offsetFrom.y);
|
|
9866
|
+
let linePath;
|
|
9867
|
+
if (adx > ady) {
|
|
9868
|
+
const off = adx * 0.4;
|
|
9869
|
+
const cp1x = offsetFrom.x + (offsetTo.x > offsetFrom.x ? off : -off);
|
|
9870
|
+
const cp2x = offsetTo.x + (offsetTo.x > offsetFrom.x ? -off : off);
|
|
9871
|
+
linePath = `M${offsetFrom.x},${offsetFrom.y} C${cp1x},${offsetFrom.y} ${cp2x},${offsetTo.y} ${offsetTo.x},${offsetTo.y}`;
|
|
9872
|
+
} else {
|
|
9873
|
+
const off = Math.max(ady * 0.4, 20);
|
|
9874
|
+
const cp1y = offsetFrom.y + (offsetTo.y > offsetFrom.y ? off : -off);
|
|
9875
|
+
const cp2y = offsetTo.y + (offsetTo.y > offsetFrom.y ? -off : off);
|
|
9876
|
+
linePath = `M${offsetFrom.x},${offsetFrom.y} C${offsetFrom.x},${cp1y} ${offsetTo.x},${cp2y} ${offsetTo.x},${offsetTo.y}`;
|
|
9877
|
+
}
|
|
9878
|
+
const startSymbol = getSymbolPath(type, "start", fromPt, fromDir);
|
|
9879
|
+
const endSymbol = getSymbolPath(type, "end", toPt, toDir);
|
|
9880
|
+
return { linePath, startSymbol, endSymbol, midX: (offsetFrom.x + offsetTo.x) / 2, midY: (offsetFrom.y + offsetTo.y) / 2 };
|
|
9881
|
+
}, [from, to, fromFieldProp, toFieldProp, type, schema, nodeRects, registryVersion]);
|
|
9882
|
+
if (!result) return null;
|
|
9883
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("g", { "data-react-fancy-diagram-relation": "", children: [
|
|
9884
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: result.linePath, fill: "none", stroke: "#71717a", strokeWidth: 2 }),
|
|
9885
|
+
result.startSymbol && /* @__PURE__ */ jsxRuntime.jsx("path", { d: result.startSymbol, fill: "none", stroke: "#71717a", strokeWidth: 2 }),
|
|
9886
|
+
result.endSymbol && /* @__PURE__ */ jsxRuntime.jsx("path", { d: result.endSymbol, fill: "none", stroke: "#71717a", strokeWidth: 2 }),
|
|
9887
|
+
label && /* @__PURE__ */ jsxRuntime.jsx("foreignObject", { x: result.midX - 40, y: result.midY - 12, width: 80, height: 24, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center text-xs text-zinc-500", children: label }) })
|
|
9888
|
+
] });
|
|
9564
9889
|
}
|
|
9890
|
+
DiagramRelation._isCanvasEdge = true;
|
|
9565
9891
|
DiagramRelation.displayName = "DiagramRelation";
|
|
9566
9892
|
var FORMAT_LABELS = {
|
|
9567
9893
|
erd: "ERD",
|
|
@@ -9672,12 +9998,12 @@ DiagramToolbar.displayName = "DiagramToolbar";
|
|
|
9672
9998
|
|
|
9673
9999
|
// src/components/Diagram/diagram.layout.ts
|
|
9674
10000
|
var ENTITY_WIDTH = 220;
|
|
9675
|
-
var
|
|
9676
|
-
var
|
|
10001
|
+
var HEADER_HEIGHT2 = 40;
|
|
10002
|
+
var FIELD_HEIGHT2 = 28;
|
|
9677
10003
|
var HORIZONTAL_GAP = 80;
|
|
9678
10004
|
var VERTICAL_GAP = 60;
|
|
9679
10005
|
function getEntityHeight(fieldCount) {
|
|
9680
|
-
return
|
|
10006
|
+
return HEADER_HEIGHT2 + Math.max(fieldCount, 1) * FIELD_HEIGHT2;
|
|
9681
10007
|
}
|
|
9682
10008
|
function computeDiagramLayout(schema) {
|
|
9683
10009
|
const positions = /* @__PURE__ */ new Map();
|
|
@@ -9780,58 +10106,103 @@ function DiagramRoot({
|
|
|
9780
10106
|
}) {
|
|
9781
10107
|
const downloadableRef = react.useRef(downloadable);
|
|
9782
10108
|
const importableRef = react.useRef(importable);
|
|
9783
|
-
const
|
|
10109
|
+
const normalizedSchema = react.useMemo(() => {
|
|
9784
10110
|
if (!schema) return { entities: [], relations: [] };
|
|
9785
|
-
const
|
|
9786
|
-
|
|
9787
|
-
|
|
9788
|
-
|
|
9789
|
-
|
|
9790
|
-
|
|
9791
|
-
|
|
10111
|
+
const entities = schema.entities.map((e) => ({
|
|
10112
|
+
...e,
|
|
10113
|
+
id: e.id ?? e.name
|
|
10114
|
+
}));
|
|
10115
|
+
const relations = schema.relations.map((r, i) => ({
|
|
10116
|
+
...r,
|
|
10117
|
+
id: r.id ?? `rel-${i}`
|
|
10118
|
+
}));
|
|
10119
|
+
return { entities, relations };
|
|
9792
10120
|
}, [schema]);
|
|
10121
|
+
const initialPositions = react.useMemo(() => {
|
|
10122
|
+
if (normalizedSchema.entities.length === 0) return /* @__PURE__ */ new Map();
|
|
10123
|
+
const layout = computeDiagramLayout(normalizedSchema);
|
|
10124
|
+
const positions = /* @__PURE__ */ new Map();
|
|
10125
|
+
for (const entity of normalizedSchema.entities) {
|
|
10126
|
+
if (entity.x !== void 0 && entity.y !== void 0) {
|
|
10127
|
+
positions.set(entity.id, { x: entity.x, y: entity.y });
|
|
10128
|
+
} else {
|
|
10129
|
+
const pos = layout.get(entity.id);
|
|
10130
|
+
positions.set(entity.id, pos ?? { x: 0, y: 0 });
|
|
10131
|
+
}
|
|
10132
|
+
}
|
|
10133
|
+
return positions;
|
|
10134
|
+
}, [normalizedSchema]);
|
|
10135
|
+
const computedDefaultViewport = react.useMemo(() => {
|
|
10136
|
+
if (defaultViewport) return defaultViewport;
|
|
10137
|
+
if (initialPositions.size === 0) return { panX: 0, panY: 0, zoom: 1 };
|
|
10138
|
+
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
|
10139
|
+
initialPositions.forEach((pos) => {
|
|
10140
|
+
minX = Math.min(minX, pos.x);
|
|
10141
|
+
minY = Math.min(minY, pos.y);
|
|
10142
|
+
maxX = Math.max(maxX, pos.x + 220);
|
|
10143
|
+
maxY = Math.max(maxY, pos.y + 200);
|
|
10144
|
+
});
|
|
10145
|
+
const padding = 40;
|
|
10146
|
+
const panX = -minX + padding;
|
|
10147
|
+
const panY = -minY + padding;
|
|
10148
|
+
return { panX, panY, zoom: 1 };
|
|
10149
|
+
}, [defaultViewport, initialPositions]);
|
|
10150
|
+
const [entityPositions, setEntityPositions] = react.useState(initialPositions);
|
|
10151
|
+
const handleEntityMove = react.useCallback((entityId, x, y) => {
|
|
10152
|
+
setEntityPositions((prev) => {
|
|
10153
|
+
const next = new Map(prev);
|
|
10154
|
+
next.set(entityId, { x, y });
|
|
10155
|
+
return next;
|
|
10156
|
+
});
|
|
10157
|
+
}, []);
|
|
9793
10158
|
const ctx = react.useMemo(
|
|
9794
10159
|
() => ({
|
|
9795
10160
|
diagramType: type,
|
|
9796
|
-
schema:
|
|
10161
|
+
schema: normalizedSchema,
|
|
9797
10162
|
downloadableRef,
|
|
9798
10163
|
importableRef,
|
|
9799
10164
|
exportFormats,
|
|
9800
10165
|
onImport
|
|
9801
10166
|
}),
|
|
9802
|
-
[type,
|
|
10167
|
+
[type, normalizedSchema, exportFormats, onImport]
|
|
9803
10168
|
);
|
|
9804
10169
|
return /* @__PURE__ */ jsxRuntime.jsx(DiagramContext.Provider, { value: ctx, children: /* @__PURE__ */ jsxRuntime.jsx("div", { "data-react-fancy-diagram": "", className: "relative h-full w-full", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
9805
10170
|
Canvas,
|
|
9806
10171
|
{
|
|
9807
10172
|
viewport,
|
|
9808
|
-
defaultViewport,
|
|
10173
|
+
defaultViewport: computedDefaultViewport,
|
|
9809
10174
|
onViewportChange,
|
|
9810
10175
|
showGrid: true,
|
|
10176
|
+
fitOnMount: true,
|
|
9811
10177
|
className: cn("h-full w-full", className),
|
|
9812
10178
|
children: [
|
|
9813
|
-
|
|
9814
|
-
|
|
9815
|
-
|
|
9816
|
-
|
|
9817
|
-
|
|
9818
|
-
|
|
9819
|
-
|
|
9820
|
-
|
|
9821
|
-
|
|
9822
|
-
|
|
9823
|
-
|
|
9824
|
-
|
|
9825
|
-
|
|
9826
|
-
|
|
9827
|
-
|
|
9828
|
-
|
|
9829
|
-
|
|
9830
|
-
|
|
9831
|
-
|
|
9832
|
-
|
|
9833
|
-
|
|
9834
|
-
|
|
10179
|
+
normalizedSchema.entities.map((entity) => {
|
|
10180
|
+
const pos = entityPositions.get(entity.id) ?? { x: 0, y: 0 };
|
|
10181
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
10182
|
+
DiagramEntity,
|
|
10183
|
+
{
|
|
10184
|
+
id: entity.id,
|
|
10185
|
+
name: entity.name,
|
|
10186
|
+
x: pos.x,
|
|
10187
|
+
y: pos.y,
|
|
10188
|
+
draggable: true,
|
|
10189
|
+
onPositionChange: (nx, ny) => handleEntityMove(entity.id, nx, ny),
|
|
10190
|
+
children: entity.fields?.map((field) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
10191
|
+
DiagramField,
|
|
10192
|
+
{
|
|
10193
|
+
name: field.name,
|
|
10194
|
+
type: field.type,
|
|
10195
|
+
primary: field.primary,
|
|
10196
|
+
foreign: field.foreign,
|
|
10197
|
+
nullable: field.nullable
|
|
10198
|
+
},
|
|
10199
|
+
field.name
|
|
10200
|
+
))
|
|
10201
|
+
},
|
|
10202
|
+
entity.id
|
|
10203
|
+
);
|
|
10204
|
+
}),
|
|
10205
|
+
normalizedSchema.relations.map((rel) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
9835
10206
|
DiagramRelation,
|
|
9836
10207
|
{
|
|
9837
10208
|
from: rel.from,
|