@heyramzi/ui 2.11.1 → 2.11.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/helpers.js +38 -38
- package/dist/agents/page-state.js +49 -50
- package/dist/agents/vendor/color.js +146 -127
- package/dist/agents/vendor/draw.js +617 -508
- package/dist/agents/vendor/engine.js +698 -599
- package/dist/agents/vendor/mesh.js +653 -683
- package/dist/agents/vendor/plastic.js +3913 -3112
- package/dist/agents/vendor/presets.js +163 -164
- package/dist/agents/vendor/shapes.js +21 -20
- package/dist/agents/vendor/ticker.js +41 -42
- package/dist/agents/vendor/types.js +1 -0
- package/dist/agents/vendor/wear.js +1421 -1448
- package/dist/ai/confirmation/confirmation-context.svelte.js +6 -6
- package/dist/ai/confirmation/index.js +3 -1
- package/dist/ai/index.js +33 -0
- package/dist/ai/prompt-input/index.js +3 -1
- package/dist/ai/reasoning/index.js +3 -1
- package/dist/ai/reasoning/reasoning-context.svelte.js +6 -6
- package/dist/ai/suggestion/index.js +3 -1
- package/dist/ai/typing-dots/index.js +3 -1
- package/dist/animations/text-swap.js +24 -24
- package/dist/brand/index.js +54 -48
- package/dist/canvas/card/resize.js +5 -3
- package/dist/canvas/edges/edge-path.js +255 -242
- package/dist/canvas/editor/context-menu.js +39 -36
- package/dist/canvas/editor/dispatch.svelte.js +154 -151
- package/dist/canvas/editor/editor-context.js +7 -2
- package/dist/canvas/editor/editor-mode.js +1 -0
- package/dist/canvas/editor/frame.js +73 -76
- package/dist/canvas/editor/hand-context.js +5 -2
- package/dist/canvas/editor/history-core.js +163 -191
- package/dist/canvas/editor/keymap.js +95 -169
- package/dist/canvas/editor/layout-actions.js +143 -144
- package/dist/canvas/editor/lock.js +52 -51
- package/dist/canvas/editor/rebase.js +217 -240
- package/dist/canvas/editor/style.js +132 -137
- package/dist/canvas/editor/text-field-context.js +7 -2
- package/dist/canvas/editor/z-order.js +65 -70
- package/dist/canvas/headless/alignment.js +22 -16
- package/dist/canvas/headless/break-apart-find.js +286 -279
- package/dist/canvas/headless/break-apart-pieces.js +62 -58
- package/dist/canvas/headless/break-apart-plan.js +299 -325
- package/dist/canvas/headless/break-apart-style.js +75 -70
- package/dist/canvas/headless/break-apart.js +188 -181
- package/dist/canvas/headless/canvas-cleanup.js +78 -58
- package/dist/canvas/headless/edge-anchors.js +115 -116
- package/dist/canvas/headless/edge-memo.js +24 -22
- package/dist/canvas/headless/edge-serialization.js +17 -27
- package/dist/canvas/headless/figure-geometry.js +232 -264
- package/dist/canvas/headless/fit-viewport.js +84 -67
- package/dist/canvas/headless/grid.js +88 -86
- package/dist/canvas/headless/icon-node.js +44 -36
- package/dist/canvas/headless/index.js +1 -0
- package/dist/canvas/headless/linkify.js +17 -19
- package/dist/canvas/headless/pen-marks.js +101 -95
- package/dist/canvas/headless/sketch.js +231 -209
- package/dist/canvas/headless/snap-guides.js +99 -83
- package/dist/canvas/headless/svg-figure.js +133 -117
- package/dist/canvas/headless/table-layout.js +146 -107
- package/dist/canvas/index.js +2 -0
- package/dist/canvas/lod/lod-mode.svelte.js +20 -18
- package/dist/canvas/lod/render-all.svelte.js +36 -39
- package/dist/canvas/ops/arrange.js +78 -71
- package/dist/canvas/ops/ops.js +260 -255
- package/dist/canvas/pen/colors.js +37 -35
- package/dist/canvas/pen/eraser.js +28 -27
- package/dist/canvas/pen/geometry.js +120 -130
- package/dist/canvas/pen/index.js +1 -0
- package/dist/canvas/pen/ops.js +11 -11
- package/dist/canvas/pen/pen-session.js +150 -159
- package/dist/canvas/pen/plugin.js +107 -104
- package/dist/canvas/pen/shapes.js +73 -68
- package/dist/canvas/pen/stroke-path.js +32 -30
- package/dist/canvas/pen/types.js +21 -21
- package/dist/canvas/pen/ui.js +10 -8
- package/dist/canvas/plugin.js +46 -46
- package/dist/canvas/screen/glyphs.js +12 -11
- package/dist/canvas/screen/labels.js +22 -22
- package/dist/canvas/screen/parts.js +98 -111
- package/dist/canvas/screen/plugin.js +47 -56
- package/dist/canvas/screen/types.js +30 -35
- package/dist/canvas/screen/ui.js +7 -7
- package/dist/canvas/test-utils.js +14 -14
- package/dist/canvas/types.js +1 -0
- package/dist/canvas/ui/forward-wheel.js +24 -25
- package/dist/canvas/ui/icons.js +64 -131
- package/dist/canvas/ui/place-panel.js +58 -49
- package/dist/canvas/ui/shortcut-tip.js +14 -12
- package/dist/canvas/ui/tools.js +300 -385
- package/dist/charts/dashboard/chart.js +4 -0
- package/dist/charts/dashboard/data-table.js +11 -0
- package/dist/charts/dashboard/windows.js +8 -3
- package/dist/charts/edge-fade.js +10 -5
- package/dist/charts/hover-band.js +16 -11
- package/dist/charts/index.js +0 -1
- package/dist/charts/motion.js +11 -7
- package/dist/charts/primitives/chart-utils.js +12 -12
- package/dist/components/copy/clipboard.js +32 -32
- package/dist/components/copy/copied.svelte.js +31 -23
- package/dist/components/data-table/data-table.js +39 -39
- package/dist/components/docs/index.js +4 -0
- package/dist/components/docs/scroll-spy.svelte.js +73 -68
- package/dist/components/list-page/filter-section.js +4 -1
- package/dist/components/list-page/index.js +2 -0
- package/dist/components/list-page/list-table.js +7 -2
- package/dist/components/list-page/queue-rail.js +14 -0
- package/dist/components/list-page/section-host.js +4 -2
- package/dist/components/list-page/step.js +4 -3
- package/dist/components/list-page/types.js +1 -0
- package/dist/components/picker/trigger.js +48 -30
- package/dist/components/picker/types.js +1 -0
- package/dist/components/segmented/collapse.js +38 -27
- package/dist/components/segmented/index.js +8 -0
- package/dist/components/segmented/segmented.js +67 -42
- package/dist/components/star-rating-input/index.js +3 -1
- package/dist/components/table-view/types.js +1 -0
- package/dist/components/tags-input/tags.js +81 -69
- package/dist/components/theme/index.js +4 -0
- package/dist/components/toolbar/index.js +4 -0
- package/dist/components/toolbar/toolbar-trigger.js +14 -1
- package/dist/editor/anchors.js +17 -13
- package/dist/editor/block-id.js +52 -51
- package/dist/editor/block-ops.js +108 -80
- package/dist/editor/doc-blocks.js +155 -166
- package/dist/editor/extensions.js +139 -180
- package/dist/editor/index.js +4 -0
- package/dist/editor/markdown-test-helpers.js +4 -2
- package/dist/editor/markdown.js +420 -408
- package/dist/editor/serializer.js +204 -200
- package/dist/editor/slash-items.js +89 -101
- package/dist/editor/youtube-url.js +25 -20
- package/dist/effects/animated-beam/path-calculator.svelte.js +43 -38
- package/dist/effects/animated-beam/types.js +1 -0
- package/dist/effects/border-beam/css.js +92 -78
- package/dist/effects/border-beam/presets.js +1705 -1720
- package/dist/effects/border-beam/register-properties.js +43 -33
- package/dist/effects/border-beam/types.js +1 -0
- package/dist/effects/image-comparison/compare.js +3 -2
- package/dist/effects/image-reveal/types.js +1 -0
- package/dist/effects/magnetic/magnetic.js +58 -52
- package/dist/effects/reveal/observe.js +50 -40
- package/dist/effects/reveal/types.js +1 -0
- package/dist/effects/shader-gradient/color.js +36 -29
- package/dist/effects/shader-gradient/renderer.js +384 -295
- package/dist/effects/shader-gradient/shaders.js +31 -0
- package/dist/effects/shader-gradient/types.js +1 -0
- package/dist/icons/apple-symbol-exports.js +99 -124
- package/dist/icons/sf-symbols.js +357 -461
- package/dist/icons/trades.js +43 -28
- package/dist/inbox/index.js +1 -0
- package/dist/inbox/logic.js +126 -122
- package/dist/inbox/types.js +43 -43
- package/dist/lib/arrive.js +19 -12
- package/dist/lib/icon-types.js +1 -0
- package/dist/lib/initials.js +16 -10
- package/dist/lib/layout.js +5 -0
- package/dist/lib/panel.js +13 -0
- package/dist/lib/result.js +22 -22
- package/dist/lib/sliding-pill.js +59 -44
- package/dist/lib/theme-transition.js +43 -43
- package/dist/lib/tone.js +31 -24
- package/dist/lib/utils.js +3 -1
- package/dist/onboarding/define-tours.js +24 -23
- package/dist/onboarding/onboarding.svelte.js +16 -12
- package/dist/onboarding/pick.js +10 -6
- package/dist/onboarding/stores.js +40 -41
- package/dist/onboarding/wait.js +24 -23
- package/dist/panel/side-panel-types.js +1 -0
- package/dist/record/demo-data.js +459 -486
- package/dist/record/fields.js +129 -131
- package/dist/record/format.js +70 -82
- package/dist/record/gutter.js +1 -0
- package/dist/record/kinds.js +95 -105
- package/dist/record/logic.js +238 -219
- package/dist/record/types.js +49 -48
- package/dist/shadcn/accordion/index.js +3 -1
- package/dist/shadcn/alert/index.js +3 -1
- package/dist/shadcn/alert-dialog/index.js +3 -1
- package/dist/shadcn/attachment/index.js +3 -1
- package/dist/shadcn/avatar/index.js +3 -1
- package/dist/shadcn/breadcrumb/index.js +3 -1
- package/dist/shadcn/bubble/index.js +3 -1
- package/dist/shadcn/button/index.js +3 -1
- package/dist/shadcn/calendar/index.js +3 -1
- package/dist/shadcn/card/index.js +3 -1
- package/dist/shadcn/checkbox/index.js +3 -1
- package/dist/shadcn/code-block/index.js +3 -1
- package/dist/shadcn/collapsible/index.js +3 -1
- package/dist/shadcn/command/index.js +4 -1
- package/dist/shadcn/context-menu/index.js +3 -1
- package/dist/shadcn/dialog/index.js +3 -1
- package/dist/shadcn/dropdown-menu/menu-item.js +40 -20
- package/dist/shadcn/empty/index.js +3 -1
- package/dist/shadcn/field/index.js +3 -1
- package/dist/shadcn/hooks/highlighter.js +77 -75
- package/dist/shadcn/hooks/is-mobile.svelte.js +3 -3
- package/dist/shadcn/hooks/use-highlighted-code.svelte.js +62 -62
- package/dist/shadcn/input/index.js +3 -1
- package/dist/shadcn/kbd/index.js +3 -1
- package/dist/shadcn/label/index.js +3 -1
- package/dist/shadcn/marker/index.js +3 -1
- package/dist/shadcn/message/index.js +3 -1
- package/dist/shadcn/message-scroller/index.js +3 -1
- package/dist/shadcn/popover/index.js +3 -1
- package/dist/shadcn/progress/index.js +3 -1
- package/dist/shadcn/progress/tone.js +8 -7
- package/dist/shadcn/radio-group/index.js +3 -1
- package/dist/shadcn/scroll-area/index.js +3 -1
- package/dist/shadcn/select/index.js +3 -1
- package/dist/shadcn/separator/index.js +3 -1
- package/dist/shadcn/sheet/index.js +3 -1
- package/dist/shadcn/sidebar/context.svelte.js +42 -28
- package/dist/shadcn/sidebar/index.js +3 -1
- package/dist/shadcn/skeleton/index.js +3 -1
- package/dist/shadcn/slider/index.js +3 -1
- package/dist/shadcn/switch/index.js +3 -1
- package/dist/shadcn/table/index.js +3 -1
- package/dist/shadcn/tabs/index.js +3 -1
- package/dist/shadcn/textarea/index.js +3 -1
- package/dist/shadcn/toggle/index.js +3 -1
- package/dist/shadcn/toggle-group/index.js +3 -1
- package/dist/shadcn/tooltip/context.js +7 -2
- package/dist/shadcn/tooltip/index.js +3 -1
- package/dist/shadcn/trace/index.js +3 -1
- package/dist/slides/bridges.js +65 -59
- package/dist/slides/deck-controller.svelte.js +210 -207
- package/dist/slides/export/capture.js +66 -71
- package/dist/slides/export/ffmpeg.js +76 -72
- package/dist/slides/export/index.js +3 -0
- package/dist/slides/export/launch.js +9 -6
- package/dist/slides/export/pdf.js +60 -54
- package/dist/slides/export/types.js +1 -0
- package/dist/slides/labels.js +24 -24
- package/dist/slides/layout.js +39 -41
- package/dist/slides/model.js +9 -7
- package/dist/slides/navigation.js +78 -73
- package/dist/slides/types.js +2 -2
- package/dist/status/define-statuses.js +18 -14
- package/dist/status/status-types.js +1 -0
- package/dist/test-setup.js +24 -20
- package/dist/thread/logic.js +73 -77
- package/dist/thread/types.js +21 -21
- package/dist/work/board-order.js +94 -90
- package/dist/work/dates.js +16 -9
- package/dist/work/detail/detail-types.js +18 -18
- package/dist/work/docs/edited.js +32 -29
- package/dist/work/docs/index.js +4 -0
- package/dist/work/docs/labels.js +34 -34
- package/dist/work/docs/menu.js +113 -106
- package/dist/work/docs/outline.js +39 -29
- package/dist/work/gantt/logic.js +211 -235
- package/dist/work/inbox/inbox-logic.js +71 -75
- package/dist/work/inbox/inbox-statuses.js +75 -72
- package/dist/work/inbox/inbox-types.js +1 -0
- package/dist/work/kanban-drag.js +27 -22
- package/dist/work/kanban-types.js +1 -0
- package/dist/work/presets/sales.js +36 -32
- package/dist/work/reorder.js +9 -8
- package/dist/work/task-types.js +1 -0
- package/dist/work/time/duration.js +51 -46
- package/dist/work/time/time-types.js +23 -23
- package/dist/work/use-kanban-dnd.svelte.js +126 -125
- package/package.json +3 -1
- package/src/components/list-page/master-detail.svelte +3 -1
- package/src/components/list-page/rail-row.svelte +4 -4
- package/src/editor/markdown.ts +30 -35
|
@@ -1,284 +1,297 @@
|
|
|
1
|
+
// The path and arrowhead placement for one link, chosen by its route. Pure, so the choice is testable.
|
|
1
2
|
import { getBezierPath, getSmoothStepPath, getStraightPath, Position } from "@xyflow/svelte";
|
|
2
3
|
import { bestAnchors, sideDetour, sideFromHandle } from "../headless/edge-anchors.js";
|
|
3
4
|
import { parseBox } from "../headless/edge-memo.js";
|
|
5
|
+
/** The corner radius a stepped link shares with the cards it joins. */
|
|
4
6
|
const CORNER = 8;
|
|
7
|
+
/** How far a same-side link runs past the cards, and the least it keeps once bent. */
|
|
5
8
|
const DETOUR = 40;
|
|
6
9
|
const DETOUR_FLOOR = 8;
|
|
7
10
|
const OUT = {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
11
|
+
top: {
|
|
12
|
+
x: 0,
|
|
13
|
+
y: -1
|
|
14
|
+
},
|
|
15
|
+
right: {
|
|
16
|
+
x: 1,
|
|
17
|
+
y: 0
|
|
18
|
+
},
|
|
19
|
+
bottom: {
|
|
20
|
+
x: 0,
|
|
21
|
+
y: 1
|
|
22
|
+
},
|
|
23
|
+
left: {
|
|
24
|
+
x: -1,
|
|
25
|
+
y: 0
|
|
26
|
+
}
|
|
24
27
|
};
|
|
28
|
+
/** The bend an edge stores in its data: pixels the movable run sits off its unbent place. */
|
|
25
29
|
export function readBend(data) {
|
|
26
|
-
|
|
27
|
-
|
|
30
|
+
const raw = data && typeof data === "object" ? data.bend : null;
|
|
31
|
+
return typeof raw === "number" && Number.isFinite(raw) ? raw : 0;
|
|
28
32
|
}
|
|
33
|
+
/** The bend that puts a handle's run under the pointer, kept inside the handle's limits. */
|
|
29
34
|
export function bendFromPointer(handle, pointer) {
|
|
30
|
-
|
|
31
|
-
|
|
35
|
+
const at = handle.axis === "x" ? pointer.x : pointer.y;
|
|
36
|
+
return Math.round(Math.min(handle.max, Math.max(handle.min, at)) - handle.base);
|
|
32
37
|
}
|
|
33
38
|
function mid(a, b) {
|
|
34
|
-
|
|
39
|
+
return (a + b) / 2;
|
|
35
40
|
}
|
|
36
41
|
function clamp(value, a, b) {
|
|
37
|
-
|
|
42
|
+
return Math.min(Math.max(a, b), Math.max(Math.min(a, b), value));
|
|
38
43
|
}
|
|
44
|
+
/** Out from `s` to the run at `at`, across it, then in to `t`. */
|
|
39
45
|
function runPoints(s, t, horizontal, at) {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
46
|
+
return horizontal ? [
|
|
47
|
+
s,
|
|
48
|
+
{
|
|
49
|
+
x: at,
|
|
50
|
+
y: s.y
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
x: at,
|
|
54
|
+
y: t.y
|
|
55
|
+
},
|
|
56
|
+
t
|
|
57
|
+
] : [
|
|
58
|
+
s,
|
|
59
|
+
{
|
|
60
|
+
x: s.x,
|
|
61
|
+
y: at
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
x: t.x,
|
|
65
|
+
y: at
|
|
66
|
+
},
|
|
67
|
+
t
|
|
68
|
+
];
|
|
63
69
|
}
|
|
70
|
+
/** The handle on the run at `at`, or none when the two ends line up and there is nothing to slide. */
|
|
64
71
|
function runHandle({ source: s, target: t }, horizontal, at, limits) {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
72
|
+
const span = horizontal ? t.y - s.y : t.x - s.x;
|
|
73
|
+
if (!(Math.abs(span) > 1)) return null;
|
|
74
|
+
return {
|
|
75
|
+
axis: horizontal ? "x" : "y",
|
|
76
|
+
x: horizontal ? at : mid(s.x, t.x),
|
|
77
|
+
y: horizontal ? mid(s.y, t.y) : at,
|
|
78
|
+
...limits
|
|
79
|
+
};
|
|
73
80
|
}
|
|
81
|
+
/** Same side: out past both cards, along, back in. The run keeps a margin outside them. */
|
|
74
82
|
function sameSideElbow(anchors, bend) {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
83
|
+
const { source: s, target: t } = anchors;
|
|
84
|
+
const out = OUT[s.side];
|
|
85
|
+
const horizontal = out.x !== 0;
|
|
86
|
+
const base = sideDetour(anchors, DETOUR);
|
|
87
|
+
const edge = sideDetour(anchors, 0);
|
|
88
|
+
const outward = horizontal ? out.x : out.y;
|
|
89
|
+
const at = clamp(base + bend, edge + outward * DETOUR_FLOOR, outward > 0 ? Infinity : -Infinity);
|
|
90
|
+
const handle = runHandle(anchors, horizontal, at, {
|
|
91
|
+
base,
|
|
92
|
+
min: outward > 0 ? edge + DETOUR_FLOOR : -Infinity,
|
|
93
|
+
max: outward > 0 ? Infinity : edge - DETOUR_FLOOR
|
|
94
|
+
});
|
|
95
|
+
return {
|
|
96
|
+
points: runPoints(s, t, horizontal, at),
|
|
97
|
+
handle
|
|
98
|
+
};
|
|
91
99
|
}
|
|
100
|
+
/** Opposite sides: out, across at the middle, in. The across run is what a bend moves. */
|
|
92
101
|
function acrossElbow(anchors, bend) {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
102
|
+
const { source: s, target: t } = anchors;
|
|
103
|
+
const horizontal = OUT[s.side].x !== 0;
|
|
104
|
+
const base = horizontal ? mid(s.x, t.x) : mid(s.y, t.y);
|
|
105
|
+
const lo = horizontal ? Math.min(s.x, t.x) : Math.min(s.y, t.y);
|
|
106
|
+
const hi = horizontal ? Math.max(s.x, t.x) : Math.max(s.y, t.y);
|
|
107
|
+
const at = clamp(base + bend, lo, hi);
|
|
108
|
+
const handle = runHandle(anchors, horizontal, at, {
|
|
109
|
+
base,
|
|
110
|
+
min: lo,
|
|
111
|
+
max: hi
|
|
112
|
+
});
|
|
113
|
+
return {
|
|
114
|
+
points: runPoints(s, t, horizontal, at),
|
|
115
|
+
handle
|
|
116
|
+
};
|
|
108
117
|
}
|
|
118
|
+
/** Square sides: one corner, when both ends are on the way there. */
|
|
109
119
|
function cornerElbow(anchors) {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
120
|
+
const { source: s, target: t } = anchors;
|
|
121
|
+
const inward = OUT[t.side];
|
|
122
|
+
const horizontalOut = OUT[s.side].x !== 0;
|
|
123
|
+
if (horizontalOut === (inward.x !== 0)) return null;
|
|
124
|
+
const corner = horizontalOut ? {
|
|
125
|
+
x: t.x,
|
|
126
|
+
y: s.y
|
|
127
|
+
} : {
|
|
128
|
+
x: s.x,
|
|
129
|
+
y: t.y
|
|
130
|
+
};
|
|
131
|
+
const arriving = horizontalOut ? Math.sign(t.y - s.y) : Math.sign(t.x - s.x);
|
|
132
|
+
const wanted = horizontalOut ? -inward.y : -inward.x;
|
|
133
|
+
return arriving === wanted ? {
|
|
134
|
+
points: [
|
|
135
|
+
s,
|
|
136
|
+
corner,
|
|
137
|
+
t
|
|
138
|
+
],
|
|
139
|
+
handle: null
|
|
140
|
+
} : null;
|
|
131
141
|
}
|
|
142
|
+
/** The corners of an elbow between two anchors and the run a bend moves. Null when it must turn back, which getSmoothStepPath routes. */
|
|
132
143
|
function elbowPoints(anchors, bend) {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
144
|
+
const { source: s, target: t } = anchors;
|
|
145
|
+
if (s.side === t.side) return sameSideElbow(anchors, bend);
|
|
146
|
+
const out = OUT[s.side];
|
|
147
|
+
const inward = OUT[t.side];
|
|
148
|
+
const ahead = out.x * (t.x - s.x) + out.y * (t.y - s.y);
|
|
149
|
+
if (ahead <= 0) return null;
|
|
150
|
+
if (out.x === -inward.x && out.y === -inward.y) return acrossElbow(anchors, bend);
|
|
151
|
+
return cornerElbow(anchors);
|
|
141
152
|
}
|
|
153
|
+
/** Corners drawn as the same quadratic arcs getSmoothStepPath draws, so the two routes match. */
|
|
142
154
|
function roundedPath(points) {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
155
|
+
const pts = points.filter((p, i) => i === 0 || p.x !== points[i - 1].x || p.y !== points[i - 1].y);
|
|
156
|
+
let d = `M ${pts[0].x} ${pts[0].y}`;
|
|
157
|
+
for (let i = 1; i < pts.length - 1; i++) {
|
|
158
|
+
const a = pts[i - 1];
|
|
159
|
+
const b = pts[i];
|
|
160
|
+
const c = pts[i + 1];
|
|
161
|
+
const r = Math.min(CORNER, Math.hypot(b.x - a.x, b.y - a.y) / 2, Math.hypot(c.x - b.x, c.y - b.y) / 2);
|
|
162
|
+
const collinear = a.x === b.x && b.x === c.x || a.y === b.y && b.y === c.y;
|
|
163
|
+
if (collinear || !(r > .5)) {
|
|
164
|
+
d += ` L ${b.x} ${b.y}`;
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
const before = {
|
|
168
|
+
x: b.x - Math.sign(b.x - a.x) * r,
|
|
169
|
+
y: b.y - Math.sign(b.y - a.y) * r
|
|
170
|
+
};
|
|
171
|
+
const after = {
|
|
172
|
+
x: b.x + Math.sign(c.x - b.x) * r,
|
|
173
|
+
y: b.y + Math.sign(c.y - b.y) * r
|
|
174
|
+
};
|
|
175
|
+
d += ` L ${before.x} ${before.y} Q ${b.x} ${b.y} ${after.x} ${after.y}`;
|
|
176
|
+
}
|
|
177
|
+
const last = pts[pts.length - 1];
|
|
178
|
+
return `${d} L ${last.x} ${last.y}`;
|
|
167
179
|
}
|
|
180
|
+
/** The middle of the longest run, where a label sits when the link has no bend handle. */
|
|
168
181
|
function middleOf(points) {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
182
|
+
let best = {
|
|
183
|
+
length: -1,
|
|
184
|
+
at: points[0]
|
|
185
|
+
};
|
|
186
|
+
for (let i = 1; i < points.length; i++) {
|
|
187
|
+
const length = Math.hypot(points[i].x - points[i - 1].x, points[i].y - points[i - 1].y);
|
|
188
|
+
if (length > best.length) best = {
|
|
189
|
+
length,
|
|
190
|
+
at: {
|
|
191
|
+
x: mid(points[i].x, points[i - 1].x),
|
|
192
|
+
y: mid(points[i].y, points[i - 1].y)
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
return best.at;
|
|
184
197
|
}
|
|
198
|
+
/** The corners an elbow turns at, for a hand-ruled drawing to follow. Null for any other route. */
|
|
185
199
|
export function elbowCorners(route, anchors, bend = 0) {
|
|
186
|
-
|
|
187
|
-
|
|
200
|
+
if (route !== "elbow" || !anchors) return null;
|
|
201
|
+
return elbowPoints(anchors, bend)?.points ?? null;
|
|
188
202
|
}
|
|
189
203
|
export function routeEdgePath(route, geometry, anchors, bend = 0) {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
204
|
+
if (route === "straight") {
|
|
205
|
+
const [path, labelX, labelY] = getStraightPath(geometry);
|
|
206
|
+
return {
|
|
207
|
+
path,
|
|
208
|
+
labelX,
|
|
209
|
+
labelY,
|
|
210
|
+
bend: null
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
if (route === "curved") {
|
|
214
|
+
const [path, labelX, labelY] = getBezierPath(geometry);
|
|
215
|
+
return {
|
|
216
|
+
path,
|
|
217
|
+
labelX,
|
|
218
|
+
labelY,
|
|
219
|
+
bend: null
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
const plan = anchors ? elbowPoints(anchors, bend) : null;
|
|
223
|
+
if (plan) {
|
|
224
|
+
const label = plan.handle ?? middleOf(plan.points);
|
|
225
|
+
return {
|
|
226
|
+
path: roundedPath(plan.points),
|
|
227
|
+
labelX: label.x,
|
|
228
|
+
labelY: label.y,
|
|
229
|
+
bend: plan.handle
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
const [path, labelX, labelY] = getSmoothStepPath({
|
|
233
|
+
...geometry,
|
|
234
|
+
borderRadius: CORNER
|
|
235
|
+
});
|
|
236
|
+
return {
|
|
237
|
+
path,
|
|
238
|
+
labelX,
|
|
239
|
+
labelY,
|
|
240
|
+
bend: null
|
|
241
|
+
};
|
|
228
242
|
}
|
|
243
|
+
/** Everything one link draws: its sides, path, bend handle and arrowheads, from where its cards sit. */
|
|
229
244
|
export function planLink(input) {
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
245
|
+
const from = parseBox(input.fromBox);
|
|
246
|
+
const to = parseBox(input.toBox);
|
|
247
|
+
let anchors = null;
|
|
248
|
+
let geometry = input.fallback;
|
|
249
|
+
if (from && to) {
|
|
250
|
+
anchors = bestAnchors(from, to, {
|
|
251
|
+
source: sideFromHandle(input.sourceHandle),
|
|
252
|
+
target: sideFromHandle(input.targetHandle)
|
|
253
|
+
});
|
|
254
|
+
geometry = {
|
|
255
|
+
sourceX: anchors.source.x,
|
|
256
|
+
sourceY: anchors.source.y,
|
|
257
|
+
sourcePosition: anchors.source.side,
|
|
258
|
+
targetX: anchors.target.x,
|
|
259
|
+
targetY: anchors.target.y,
|
|
260
|
+
targetPosition: anchors.target.side
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
return {
|
|
264
|
+
...routeEdgePath(input.route, geometry, anchors, input.bend),
|
|
265
|
+
anchors,
|
|
266
|
+
geometry,
|
|
267
|
+
tips: arrowTips(input.route, geometry, anchors)
|
|
268
|
+
};
|
|
254
269
|
}
|
|
270
|
+
/** The direction a link travels when it meets a box on `side`: straight into it. */
|
|
255
271
|
function into(side) {
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
return Math.PI / 2;
|
|
263
|
-
case "bottom":
|
|
264
|
-
return -Math.PI / 2;
|
|
265
|
-
}
|
|
272
|
+
switch (side) {
|
|
273
|
+
case "left": return 0;
|
|
274
|
+
case "right": return Math.PI;
|
|
275
|
+
case "top": return Math.PI / 2;
|
|
276
|
+
case "bottom": return -Math.PI / 2;
|
|
277
|
+
}
|
|
266
278
|
}
|
|
279
|
+
/** Where an arrowhead sits and points at each end: along a straight link's line, square on to the box otherwise. */
|
|
267
280
|
export function arrowTips(route, geometry, anchors) {
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
281
|
+
const { sourceX, sourceY, targetX, targetY } = geometry;
|
|
282
|
+
const straight = Math.atan2(targetY - sourceY, targetX - sourceX);
|
|
283
|
+
const startAngle = route === "straight" || !anchors ? straight + Math.PI : into(anchors.source.side);
|
|
284
|
+
const endAngle = route === "straight" || !anchors ? straight : into(anchors.target.side);
|
|
285
|
+
return {
|
|
286
|
+
start: {
|
|
287
|
+
x: sourceX,
|
|
288
|
+
y: sourceY,
|
|
289
|
+
angle: startAngle
|
|
290
|
+
},
|
|
291
|
+
end: {
|
|
292
|
+
x: targetX,
|
|
293
|
+
y: targetY,
|
|
294
|
+
angle: endAngle
|
|
295
|
+
}
|
|
296
|
+
};
|
|
284
297
|
}
|
|
@@ -1,42 +1,45 @@
|
|
|
1
1
|
function rectOf(el) {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
2
|
+
if (!el) return null;
|
|
3
|
+
const r = el.getBoundingClientRect();
|
|
4
|
+
return {
|
|
5
|
+
x: r.x,
|
|
6
|
+
y: r.y,
|
|
7
|
+
width: r.width,
|
|
8
|
+
height: r.height
|
|
9
|
+
};
|
|
10
10
|
}
|
|
11
11
|
function tableCellOf(target) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
const cell = target.closest("[data-table-row]");
|
|
13
|
+
if (!cell) return null;
|
|
14
|
+
return {
|
|
15
|
+
row: Number(cell.dataset.tableRow),
|
|
16
|
+
col: Number(cell.dataset.tableCol)
|
|
17
|
+
};
|
|
18
18
|
}
|
|
19
|
+
/** Reads a right-click into an edge hit, or a canvas/node hit with its anchor
|
|
20
|
+
* rect and cell. The edge check runs first, because an arrow also carries
|
|
21
|
+
* `data-id`. */
|
|
19
22
|
export function resolveContextMenuHit(event, nodes) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
23
|
+
const target = event.target;
|
|
24
|
+
const position = {
|
|
25
|
+
x: event.clientX,
|
|
26
|
+
y: event.clientY
|
|
27
|
+
};
|
|
28
|
+
const edgeId = target.closest(".svelte-flow__edge")?.getAttribute("data-id");
|
|
29
|
+
if (edgeId) return {
|
|
30
|
+
kind: "edge",
|
|
31
|
+
edgeId,
|
|
32
|
+
position
|
|
33
|
+
};
|
|
34
|
+
const nodeElement = target.closest("[data-id]");
|
|
35
|
+
const nodeId = nodeElement?.getAttribute("data-id") ?? null;
|
|
36
|
+
const node = nodeId ? nodes.find((n) => n.id === nodeId) : undefined;
|
|
37
|
+
return {
|
|
38
|
+
kind: "canvas",
|
|
39
|
+
position,
|
|
40
|
+
anchorRect: rectOf(nodeElement),
|
|
41
|
+
nodeId,
|
|
42
|
+
nodeType: node?.type ?? null,
|
|
43
|
+
tableCell: tableCellOf(target)
|
|
44
|
+
};
|
|
42
45
|
}
|