@bemedev/mind-flow 0.0.1 → 0.1.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 +95 -0
- package/lib/helpers/createContext.d.ts +8 -11
- package/lib/helpers/createContext.d.ts.map +1 -1
- package/lib/index.cjs.js +1 -1
- package/lib/index.es.js +240 -235
- package/lib/server.cjs.js +181 -121
- package/lib/server.es.js +181 -121
- package/lib/services/main.machine.d.ts +7 -9
- package/lib/services/main.machine.d.ts.map +1 -1
- package/lib/services/main.typings.d.ts +3 -3
- package/lib/services/main.typings.d.ts.map +1 -1
- package/lib/ui/Flow.d.ts +2 -2
- package/lib/ui/Flow.d.ts.map +1 -1
- package/lib/ui/components/Bounds.d.ts +4 -4
- package/lib/ui/components/Bounds.d.ts.map +1 -1
- package/lib/ui/components/EdgeComponent.d.ts +2 -2
- package/lib/ui/components/EdgeComponent.d.ts.map +1 -1
- package/lib/ui/components/EdgesBoard.d.ts +2 -2
- package/lib/ui/components/EdgesBoard.d.ts.map +1 -1
- package/lib/ui/components/FlowChart.context.d.ts +10 -18
- package/lib/ui/components/FlowChart.context.d.ts.map +1 -1
- package/lib/ui/components/FlowChart.d.ts +4 -10
- package/lib/ui/components/FlowChart.d.ts.map +1 -1
- package/lib/ui/components/FlowChart.data.d.ts +10 -11
- package/lib/ui/components/FlowChart.data.d.ts.map +1 -1
- package/lib/ui/components/NodeComponent.d.ts +2 -2
- package/lib/ui/components/NodeComponent.d.ts.map +1 -1
- package/lib/ui/components/NodesBoard.d.ts +2 -2
- package/lib/ui/components/NodesBoard.d.ts.map +1 -1
- package/lib/ui/components/classes.d.ts +2 -2
- package/package.json +3 -9
- package/src/README.md +2 -2
- package/src/helpers/createContext.ts +8 -11
- package/src/services/main.machine.ts +18 -46
- package/src/services/main.typings.ts +3 -3
- package/src/ui/Flow.tsx +3 -2
- package/src/ui/components/Bounds.tsx +35 -44
- package/src/ui/components/EdgeComponent.tsx +7 -8
- package/src/ui/components/EdgesBoard.tsx +3 -2
- package/src/ui/components/FlowChart.context.ts +75 -82
- package/src/ui/components/FlowChart.data.ts +12 -15
- package/src/ui/components/FlowChart.tsx +6 -11
- package/src/ui/components/NodeComponent.tsx +13 -25
- package/src/ui/components/NodesBoard.tsx +120 -111
- package/src/ui/components/classes.ts +2 -2
package/lib/server.cjs.js
CHANGED
|
@@ -11,8 +11,8 @@ let _thisbeyond_solid_dnd = require("@thisbeyond/solid-dnd");
|
|
|
11
11
|
let dequal = require("dequal");
|
|
12
12
|
//#region src/ui/components/classes.ts
|
|
13
13
|
/**
|
|
14
|
-
* List of Tailwind CSS class names used across flowchart UI components to
|
|
15
|
-
*
|
|
14
|
+
* List of Tailwind CSS class names used across flowchart UI components to ensure
|
|
15
|
+
* compilation safelist.
|
|
16
16
|
*/
|
|
17
17
|
var CLASSES = [
|
|
18
18
|
"fill-transparent",
|
|
@@ -98,19 +98,16 @@ var CLASSES = [
|
|
|
98
98
|
//#endregion
|
|
99
99
|
//#region src/helpers/createContext.ts
|
|
100
100
|
/**
|
|
101
|
-
* Creates a Solid context provider component and a custom hook to consume
|
|
102
|
-
* it.
|
|
101
|
+
* Creates a Solid context provider component and a custom hook to consume it.
|
|
103
102
|
*
|
|
104
|
-
* @template T - The type of the context value.
|
|
103
|
+
* @template `T` - The type of the context value.
|
|
105
104
|
*
|
|
106
|
-
* @param context - Factory function returning a non-nullable context value
|
|
107
|
-
*
|
|
108
|
-
* @param options - Optional context configuration of type
|
|
109
|
-
* {@linkcode Options}.
|
|
105
|
+
* @param context - Factory function returning a non-nullable context value of type
|
|
106
|
+
* `NonNullable<T>`.
|
|
107
|
+
* @param options - Optional context configuration of type {@linkcode Options}.
|
|
110
108
|
*
|
|
111
|
-
* @returns A tuple containing the Provider component of
|
|
112
|
-
* {@linkcode ParentComponent}, the accessor hook, and the Solid context
|
|
113
|
-
* object.
|
|
109
|
+
* @returns A tuple containing the Provider component of interface
|
|
110
|
+
* {@linkcode ParentComponent}, the accessor hook, and the Solid context object.
|
|
114
111
|
*/
|
|
115
112
|
var createContext = (context, options) => {
|
|
116
113
|
const _context = (0, solid_js.createContext)(context(), options);
|
|
@@ -136,7 +133,7 @@ var point = (0, _bemedev_app_bemedev.type)({
|
|
|
136
133
|
input: optional(use(point)),
|
|
137
134
|
output: use(point)
|
|
138
135
|
}));
|
|
139
|
-
/** Schema definition for edge extremities */
|
|
136
|
+
/** Schema definition for edge extremities. */
|
|
140
137
|
var extremities = (0, _bemedev_app_bemedev.type)({
|
|
141
138
|
from: "string",
|
|
142
139
|
to: "string"
|
|
@@ -168,8 +165,7 @@ var edgeJSON = extremities;
|
|
|
168
165
|
//#endregion
|
|
169
166
|
//#region src/services/main.machine.ts
|
|
170
167
|
/**
|
|
171
|
-
* Constructs a unique edge identifier string from source and destination
|
|
172
|
-
* node IDs.
|
|
168
|
+
* Constructs a unique edge identifier string from source and destination node IDs.
|
|
173
169
|
*
|
|
174
170
|
* @param out - The source node ID string.
|
|
175
171
|
* @param _in - The destination node ID string.
|
|
@@ -190,8 +186,8 @@ var buildNodeID = (generated) => {
|
|
|
190
186
|
return `node-${generated}`;
|
|
191
187
|
};
|
|
192
188
|
/**
|
|
193
|
-
* State machine managing flowchart state transitions, nodes, edges,
|
|
194
|
-
*
|
|
189
|
+
* State machine managing flowchart state transitions, nodes, edges, selection, and
|
|
190
|
+
* layout actions.
|
|
195
191
|
*/
|
|
196
192
|
var machine = (0, _bemedev_app.createMachine)({
|
|
197
193
|
initial: "idle",
|
|
@@ -208,15 +204,10 @@ var machine = (0, _bemedev_app.createMachine)({
|
|
|
208
204
|
target: "/working"
|
|
209
205
|
} },
|
|
210
206
|
working: { on: {
|
|
211
|
-
MOVE: {
|
|
212
|
-
actions: ["moveNode", "buildUI"],
|
|
213
|
-
target: "/construction"
|
|
214
|
-
},
|
|
215
207
|
MOVE_IMMEDIATE: { actions: [{
|
|
216
208
|
name: "buildImmediateUI",
|
|
217
209
|
description: "Must be in the ui"
|
|
218
210
|
}] },
|
|
219
|
-
UPDATE_UI: "/construction",
|
|
220
211
|
ADD_CHILD: {
|
|
221
212
|
actions: [
|
|
222
213
|
"generateID",
|
|
@@ -250,6 +241,10 @@ var machine = (0, _bemedev_app.createMachine)({
|
|
|
250
241
|
],
|
|
251
242
|
target: "/construction"
|
|
252
243
|
},
|
|
244
|
+
MOVE: {
|
|
245
|
+
actions: ["moveNode", "buildUI"],
|
|
246
|
+
target: "/construction"
|
|
247
|
+
},
|
|
253
248
|
ADD_EDGE: {
|
|
254
249
|
actions: ["addEdge"],
|
|
255
250
|
target: "/construction"
|
|
@@ -287,6 +282,7 @@ var machine = (0, _bemedev_app.createMachine)({
|
|
|
287
282
|
DESELECT: "never",
|
|
288
283
|
ADD_EDGE: use(extremities)
|
|
289
284
|
})),
|
|
285
|
+
sync: true,
|
|
290
286
|
pContext: (0, _bemedev_app_bemedev.type)(({ union }) => ({ generatedId: union("string", "null") })),
|
|
291
287
|
context: (0, _bemedev_app_bemedev.type)(({ optional, use, array }) => ({
|
|
292
288
|
data: optional({
|
|
@@ -301,8 +297,7 @@ var machine = (0, _bemedev_app.createMachine)({
|
|
|
301
297
|
}),
|
|
302
298
|
selected: optional("string"),
|
|
303
299
|
updatingUI: optional("boolean")
|
|
304
|
-
}))
|
|
305
|
-
sync: true
|
|
300
|
+
}))
|
|
306
301
|
}).provideOptions(({ assign, batch, erase }) => ({ actions: {
|
|
307
302
|
configure: batch(assign("context.data", () => ({
|
|
308
303
|
nodes: [],
|
|
@@ -386,14 +381,17 @@ var getDefaultOutputOffset = (width = 0) => ({
|
|
|
386
381
|
y: 18
|
|
387
382
|
});
|
|
388
383
|
/**
|
|
389
|
-
* Boundary padding constraints for node dragging and positioning within
|
|
390
|
-
*
|
|
384
|
+
* Boundary padding constraints for node dragging and positioning within the
|
|
385
|
+
* viewport.
|
|
391
386
|
*/
|
|
392
387
|
var BOUNDS_CONSTRAINTS = {
|
|
393
|
-
horizontal:
|
|
394
|
-
vertical:
|
|
388
|
+
horizontal: 55,
|
|
389
|
+
vertical: 40
|
|
395
390
|
};
|
|
396
|
-
/**
|
|
391
|
+
/**
|
|
392
|
+
* Default node items of type {@linkcode NodeProps} provided when no initial
|
|
393
|
+
* configuration is given.
|
|
394
|
+
*/
|
|
397
395
|
var DEFAULT_NODES = [{
|
|
398
396
|
id: "node-0",
|
|
399
397
|
data: {
|
|
@@ -409,22 +407,31 @@ var DEFAULT_NODES = [{
|
|
|
409
407
|
//#endregion
|
|
410
408
|
//#region src/ui/components/FlowChart.context.ts
|
|
411
409
|
/**
|
|
412
|
-
*
|
|
413
|
-
*
|
|
414
|
-
*/
|
|
415
|
-
var service = (0, _bemedev_app.interpret)(machine, {
|
|
416
|
-
context: {},
|
|
417
|
-
pContext: { generatedId: null }
|
|
418
|
-
});
|
|
419
|
-
/**
|
|
420
|
-
* Solid Context Provider component and hook for accessing flowchart board
|
|
421
|
-
* state, services, and zoom.
|
|
410
|
+
* Solid Context Provider component and hook for accessing flowchart board state,
|
|
411
|
+
* services, and zoom.
|
|
422
412
|
*/
|
|
423
413
|
var [Provider, useFlow] = createContext(() => {
|
|
414
|
+
/**
|
|
415
|
+
* Shared state machine interpreter service instance for flowchart state
|
|
416
|
+
* management.
|
|
417
|
+
*/
|
|
418
|
+
const service = (0, _bemedev_app.interpret)(machine, {
|
|
419
|
+
context: {},
|
|
420
|
+
pContext: { generatedId: null }
|
|
421
|
+
});
|
|
424
422
|
const zoom = (0, solid_js.createSignal)(1);
|
|
425
423
|
const newEdge = (0, solid_js.createSignal)();
|
|
426
424
|
const [boardRef, setBoardRef] = (0, solid_js.createSignal)();
|
|
427
425
|
const [dimensions, setDimensions] = (0, solid_js.createSignal)({}, { equals: dequal_lite.dequal });
|
|
426
|
+
/**
|
|
427
|
+
* Converts client viewport coordinates to board canvas coordinates adjusted for
|
|
428
|
+
* zoom and scroll.
|
|
429
|
+
*
|
|
430
|
+
* @param clientX - Viewport horizontal coordinate.
|
|
431
|
+
* @param clientY - Viewport vertical coordinate.
|
|
432
|
+
*
|
|
433
|
+
* @returns Board coordinate point of type {@linkcode Point}.
|
|
434
|
+
*/
|
|
428
435
|
const getBoardPoint = (clientX, clientY) => {
|
|
429
436
|
const el = boardRef();
|
|
430
437
|
if (!el) return {
|
|
@@ -434,11 +441,21 @@ var [Provider, useFlow] = createContext(() => {
|
|
|
434
441
|
const rect = el.getBoundingClientRect();
|
|
435
442
|
const currentZoom = zoom[0]();
|
|
436
443
|
return {
|
|
437
|
-
x:
|
|
438
|
-
y:
|
|
444
|
+
x: clientX - rect.left / currentZoom,
|
|
445
|
+
y: clientY - rect.top / currentZoom
|
|
439
446
|
};
|
|
440
447
|
};
|
|
441
448
|
const [edgesPositions, setEdgesPositions] = (0, solid_js.createSignal)({}, { equals: false });
|
|
449
|
+
/**
|
|
450
|
+
* Clamps node coordinates within the visible container boundaries.
|
|
451
|
+
*
|
|
452
|
+
* @param x - Desired horizontal X coordinate.
|
|
453
|
+
* @param y - Desired vertical Y coordinate.
|
|
454
|
+
* @param nodeWidth - Width of the node element in pixels, defaults to `192`.
|
|
455
|
+
* @param nodeHeight - Height of the node element in pixels, defaults to `50`.
|
|
456
|
+
*
|
|
457
|
+
* @returns Clamped coordinate point of type {@linkcode Point}.
|
|
458
|
+
*/
|
|
442
459
|
const clampPosition = (x, y, nodeWidth = 192, nodeHeight = 50) => {
|
|
443
460
|
const container = boardRef()?.parentElement;
|
|
444
461
|
if (!container) return {
|
|
@@ -518,9 +535,7 @@ var [Provider, useFlow] = createContext(() => {
|
|
|
518
535
|
buildUI: batch(voidAction(({ context: { data } }) => {
|
|
519
536
|
const edges = data?.edges ?? [];
|
|
520
537
|
setEdgesPositions((data) => {
|
|
521
|
-
const array = Object.entries({ ...data }).filter(([id]) =>
|
|
522
|
-
return edges?.some((edge) => edge.id === id);
|
|
523
|
-
});
|
|
538
|
+
const array = Object.entries({ ...data }).filter(([id]) => edges.some((edge) => edge.id === id));
|
|
524
539
|
return Object.fromEntries(array);
|
|
525
540
|
});
|
|
526
541
|
}), voidAction({
|
|
@@ -639,17 +654,18 @@ var [Provider, useFlow] = createContext(() => {
|
|
|
639
654
|
getBoardPoint,
|
|
640
655
|
edgesPositions: [edgesPositions, setEdgesPositions],
|
|
641
656
|
service,
|
|
642
|
-
zoom
|
|
657
|
+
zoom,
|
|
658
|
+
clampPosition
|
|
643
659
|
};
|
|
644
660
|
}, { name: "FlowContext" });
|
|
645
661
|
//#endregion
|
|
646
662
|
//#region src/ui/components/Bounds.tsx
|
|
647
663
|
/**
|
|
648
|
-
* Drag boundary transformer component that clamps draggable nodes within
|
|
649
|
-
*
|
|
664
|
+
* Drag boundary transformer component that clamps draggable nodes within container
|
|
665
|
+
* scroll bounds.
|
|
650
666
|
*
|
|
651
|
-
* @returns `null` as this component performs side-effect transformer
|
|
652
|
-
*
|
|
667
|
+
* @returns `null` as this component performs side-effect transformer registrations
|
|
668
|
+
* only.
|
|
653
669
|
*/
|
|
654
670
|
var DragBounds = () => {
|
|
655
671
|
const { board: [ref], zoom: [zoom] } = useFlow();
|
|
@@ -658,23 +674,23 @@ var DragBounds = () => {
|
|
|
658
674
|
id: "clamp-to-container",
|
|
659
675
|
order: 100,
|
|
660
676
|
callback: (transform) => {
|
|
661
|
-
const container = ref()
|
|
677
|
+
const container = ref();
|
|
662
678
|
const activeDraggable = state.active.draggable;
|
|
663
679
|
if (!container || !activeDraggable) return transform;
|
|
664
|
-
const
|
|
665
|
-
|
|
666
|
-
const innerLeft = containerRect.left + container.clientLeft;
|
|
667
|
-
const innerTop = containerRect.top + container.clientTop;
|
|
668
|
-
const innerRight = innerLeft + container.clientWidth;
|
|
669
|
-
const innerBottom = innerTop + container.clientHeight;
|
|
680
|
+
const node = activeDraggable.node;
|
|
681
|
+
if (!node) return transform;
|
|
670
682
|
const currentZoom = zoom();
|
|
671
|
-
const
|
|
672
|
-
const
|
|
673
|
-
const
|
|
674
|
-
const
|
|
683
|
+
const minBoardX = BOUNDS_CONSTRAINTS.horizontal;
|
|
684
|
+
const maxBoardX = Math.max(minBoardX, container.clientWidth / currentZoom - node.offsetWidth - BOUNDS_CONSTRAINTS.horizontal);
|
|
685
|
+
const minBoardY = BOUNDS_CONSTRAINTS.vertical;
|
|
686
|
+
const maxBoardY = Math.max(minBoardY, container.clientHeight / currentZoom - node.offsetHeight - BOUNDS_CONSTRAINTS.vertical);
|
|
687
|
+
const minTransformX = (minBoardX - node.offsetLeft) * currentZoom;
|
|
688
|
+
const maxTransformX = (maxBoardX - node.offsetLeft) * currentZoom;
|
|
689
|
+
const minTransformY = (minBoardY - node.offsetTop) * currentZoom;
|
|
690
|
+
const maxTransformY = (maxBoardY - node.offsetTop) * currentZoom;
|
|
675
691
|
return {
|
|
676
|
-
x: Math.min(Math.max(transform.x,
|
|
677
|
-
y: Math.min(Math.max(transform.y,
|
|
692
|
+
x: Math.min(Math.max(transform.x, minTransformX), maxTransformX),
|
|
693
|
+
y: Math.min(Math.max(transform.y, minTransformY), maxTransformY)
|
|
678
694
|
};
|
|
679
695
|
}
|
|
680
696
|
};
|
|
@@ -695,7 +711,7 @@ var _tmpl$$4 = [
|
|
|
695
711
|
"\"",
|
|
696
712
|
"></path>"
|
|
697
713
|
];
|
|
698
|
-
var _tmpl$2$
|
|
714
|
+
var _tmpl$2$2 = [
|
|
699
715
|
"<g",
|
|
700
716
|
" cursor=\"pointer\" transform=\"",
|
|
701
717
|
"\" style=\"",
|
|
@@ -710,8 +726,8 @@ var _tmpl$2$1 = [
|
|
|
710
726
|
*/
|
|
711
727
|
var calculateOffset = (value) => value * 100 / 200;
|
|
712
728
|
/**
|
|
713
|
-
* Generates an SVG cubic bezier path `d` string between coordinates `(x0,
|
|
714
|
-
*
|
|
729
|
+
* Generates an SVG cubic bezier path `d` string between coordinates `(x0, y0)` and
|
|
730
|
+
* `(x1, y1)`.
|
|
715
731
|
*
|
|
716
732
|
* @param vector - Vector coordinates of type {@linkcode Vector}.
|
|
717
733
|
*
|
|
@@ -721,8 +737,8 @@ var draw = ({ x0, y0, x1, y1 }) => {
|
|
|
721
737
|
return `M ${x0} ${y0} C ${x0 + calculateOffset(Math.abs(x1 - x0))} ${y0}, ${x1 - calculateOffset(Math.abs(x1 - x0))} ${y1}, ${x1} ${y1}`;
|
|
722
738
|
};
|
|
723
739
|
/**
|
|
724
|
-
* SVG edge component rendering bezier curves and delete interaction
|
|
725
|
-
*
|
|
740
|
+
* SVG edge component rendering bezier curves and delete interaction handles for node
|
|
741
|
+
* connections.
|
|
726
742
|
*
|
|
727
743
|
* @param props - Edge properties of type {@linkcode Props}.
|
|
728
744
|
*
|
|
@@ -748,7 +764,7 @@ var EdgeComponent = (props) => {
|
|
|
748
764
|
return selected();
|
|
749
765
|
},
|
|
750
766
|
get children() {
|
|
751
|
-
return (0, solid_js_web.ssr)(_tmpl$2$
|
|
767
|
+
return (0, solid_js_web.ssr)(_tmpl$2$2, (0, solid_js_web.ssrHydrationKey)(), `translate(${(0, solid_js_web.escape)(middlePoint().x, true)}, ${(0, solid_js_web.escape)(middlePoint().y, true)})`, (0, solid_js_web.ssrStyleProperty)("pointer-events:", "all") + (0, solid_js_web.ssrStyleProperty)(";z-index:", "30"));
|
|
752
768
|
}
|
|
753
769
|
})];
|
|
754
770
|
};
|
|
@@ -761,8 +777,8 @@ var _tmpl$$3 = [
|
|
|
761
777
|
"<!--/--></svg>"
|
|
762
778
|
];
|
|
763
779
|
/**
|
|
764
|
-
* SVG board overlay component that renders all active connecting edges and
|
|
765
|
-
*
|
|
780
|
+
* SVG board overlay component that renders all active connecting edges and ongoing
|
|
781
|
+
* edge creation previews.
|
|
766
782
|
*
|
|
767
783
|
* @returns The rendered SVG JSX element.
|
|
768
784
|
*/
|
|
@@ -812,13 +828,13 @@ var _tmpl$$2 = [
|
|
|
812
828
|
" class=\"cursor-pointer overflow-visible rounded-full bg-green-500 p-0.5 text-center font-bold hover:bg-green-600\" style=\"",
|
|
813
829
|
"\" viewBox=\"0 0 1024 1024\" preserveAspectRatio=\"xMaxYMax\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"white\"><g id=\"background\"><path d=\"M467.40667,277.66696c-0.05948,-14.53055 5.75527,-22.95613 -8.62044,-20.90487c-112.55699,16.0607 -222.1609,112.14558 -245.06161,239.85765c-46.52056,259.43466 231.33083,443.06705 449.51209,316.97506c117.31668,-67.80002 160.95215,-190.43324 151.34416,-288.29849c-5.92276,-60.32819 -27.80273,-107.95668 -53.44246,-144.25469l59.39269,-42.05363c111.72214,156.309 73.11535,351.55635 -25.06953,459.45565c-184.18877,202.4124 -470.46624,145.52064 -592.95027,-32.92123c-156.18269,-227.53604 -27.15324,-543.64371 261.18883,-582.44416c5.0579,-0.68061 3.56556,-7.04079 3.56442,-8.58985c-0.05594,-76.3354 -0.11021,-76.7687 1.10909,-77.24589c2.06886,-0.80969 151.41433,118.4561 151.92482,118.95524c4.65592,4.55233 -0.99548,7.829 -29.07828,30.50907c-120.49369,97.31245 -120.4977,98.55675 -123.0691,97.87586c-0.43639,-0.11555 -0.80698,-0.31322 -0.74442,-66.91571Z\"></path><path d=\"M316.61562,611.03414c0.11517,-90.16257 -0.25516,-99.92912 0.64739,-101.78856c1.56486,-3.22393 131.99102,0.91032 134.6959,-1.89763c2.21336,-2.2977 -0.59362,-129.97807 1.1376,-132.37034c0.7253,-1.00225 11.10552,-0.99175 12.07474,-0.99077c104.50336,0.10564 104.90098,-0.37811 105.967,0.85765c1.56461,1.81373 0.25596,114.18436 0.67852,129.81412c0.1322,4.88975 3.22386,3.28152 99.72028,3.4563c33.0841,0.05992 36.14259,-1.40368 36.21852,4.50462c0.11713,9.11348 1.41954,110.45369 -0.40274,113.92715c-1.81106,3.45208 -130.39967,-0.42618 -134.48289,1.62075c-2.29035,1.14816 -0.36989,101.12392 -1.11542,130.51904c-0.09548,3.76459 -2.13506,3.20617 -47.84854,3.17365c-69.30253,-0.0493 -69.31099,-0.25627 -69.65762,-0.42191c-3.77927,-1.80595 0.16287,-129.33555 -2.24266,-132.58994c-1.79931,-2.43424 -124.06108,-0.29118 -132.80252,-0.97392c-3.81102,-0.29766 -2.58229,-14.8847 -2.58758,-16.8402Z\"></path></g></svg>"
|
|
814
830
|
];
|
|
815
|
-
var _tmpl$2 = [
|
|
831
|
+
var _tmpl$2$1 = [
|
|
816
832
|
"<div",
|
|
817
833
|
" id=\"outputs\" class=\"pointer-events-none absolute top-0 z-10 flex cursor-default flex-col\" style=\"",
|
|
818
834
|
"\"><div class=\"cursor-default rounded-full bg-[#e38b29] shadow-md\" style=\"",
|
|
819
835
|
"\"></div></div>"
|
|
820
836
|
];
|
|
821
|
-
var _tmpl$3 = [
|
|
837
|
+
var _tmpl$3$1 = [
|
|
822
838
|
"<div",
|
|
823
839
|
" class=\"",
|
|
824
840
|
"\" style=\"",
|
|
@@ -844,8 +860,8 @@ var _tmpl$5 = [
|
|
|
844
860
|
"</div>"
|
|
845
861
|
];
|
|
846
862
|
/**
|
|
847
|
-
* Interactive flowchart node component supporting dragging, selection,
|
|
848
|
-
*
|
|
863
|
+
* Interactive flowchart node component supporting dragging, selection, handle
|
|
864
|
+
* connections, and child/sibling creation.
|
|
849
865
|
*
|
|
850
866
|
* @param props - Node rendering properties of type {@linkcode Props}.
|
|
851
867
|
*
|
|
@@ -855,17 +871,17 @@ var NodeComponent = (props) => {
|
|
|
855
871
|
const [ref, setRef] = (0, solid_js.createSignal)();
|
|
856
872
|
const { dimensions: [dimensions, setDimensions], newEdge: [newEdge, setNewEdge], getBoardPoint, service, zoom: [zoom] } = useFlow();
|
|
857
873
|
const selected = (0, _bemedev_app_solidjs.useState)(service, { selector: (s) => s.context.selected === props.id });
|
|
858
|
-
(0, solid_js.
|
|
874
|
+
(0, solid_js.onMount)(() => {
|
|
859
875
|
ref();
|
|
860
876
|
zoom();
|
|
861
877
|
});
|
|
862
878
|
const hasParent = (0, _bemedev_app_solidjs.useState)(service, { selector: ({ context: { data } }) => {
|
|
863
879
|
const edges = data?.edges;
|
|
864
880
|
if (!edges) return false;
|
|
865
|
-
return
|
|
881
|
+
return edges.some(({ to }) => to === props.id);
|
|
866
882
|
} });
|
|
867
883
|
(0, _thisbeyond_solid_dnd.createDraggable)(props.id);
|
|
868
|
-
return (0, solid_js_web.ssr)(_tmpl$3, (0, solid_js_web.ssrHydrationKey)() + (0, solid_js_web.ssrAttribute)("id", (0, solid_js_web.escape)(props.id, true), false), `flex flex-col absolute cursor-grab bg-white rounded-md shadow-md select-none transition-[border,box-shadow] duration-200 ease-in-out hover:shadow-lg draggable ${selected() ? "border border-[#e38c29] z-[100]" : ""} ${!selected() ? "border border-[#e6d4be] z-[1]" : ""} min-w-48`, (0, solid_js_web.ssrStyleProperty)("top:", `${(0, solid_js_web.escape)(props.y, true)}px`) + (0, solid_js_web.ssrStyleProperty)(";left:", `${(0, solid_js_web.escape)(props.x, true)}px`), `pointer-events-none absolute flex items-center justify-end -top-7.5 right-0 transition-all duration-200 ease-in-out space-x-2 ${selected() ? "w-full opacity-100" : ""} ${!selected() ? "w-0 -right-3 opacity-0 overflow-hidden" : ""}`, (0, solid_js_web.ssrStyleProperty)("overflow:", "visible") + (0, solid_js_web.ssrStyleProperty)(";pointer-events:", "all") + (0, solid_js_web.ssrStyleProperty)(";width:", `${(0, solid_js_web.escape)(12, true) * 2}px`) + (0, solid_js_web.ssrStyleProperty)(";height:", `${(0, solid_js_web.escape)(12, true) * 2}px`), (0, solid_js_web.escape)((0, solid_js_web.createComponent)(solid_js.Show, {
|
|
884
|
+
return (0, solid_js_web.ssr)(_tmpl$3$1, (0, solid_js_web.ssrHydrationKey)() + (0, solid_js_web.ssrAttribute)("id", (0, solid_js_web.escape)(props.id, true), false), `flex flex-col absolute cursor-grab bg-white rounded-md shadow-md select-none transition-[border,box-shadow] duration-200 ease-in-out hover:shadow-lg draggable ${selected() ? "border border-[#e38c29] z-[100]" : ""} ${!selected() ? "border border-[#e6d4be] z-[1]" : ""} min-w-48`, (0, solid_js_web.ssrStyleProperty)("top:", `${(0, solid_js_web.escape)(props.y, true)}px`) + (0, solid_js_web.ssrStyleProperty)(";left:", `${(0, solid_js_web.escape)(props.x, true)}px`), `pointer-events-none absolute flex items-center justify-end -top-7.5 right-0 transition-all duration-200 ease-in-out space-x-2 ${selected() ? "w-full opacity-100" : ""} ${!selected() ? "w-0 -right-3 opacity-0 overflow-hidden" : ""}`, (0, solid_js_web.ssrStyleProperty)("overflow:", "visible") + (0, solid_js_web.ssrStyleProperty)(";pointer-events:", "all") + (0, solid_js_web.ssrStyleProperty)(";width:", `${(0, solid_js_web.escape)(12, true) * 2}px`) + (0, solid_js_web.ssrStyleProperty)(";height:", `${(0, solid_js_web.escape)(12, true) * 2}px`), (0, solid_js_web.escape)((0, solid_js_web.createComponent)(solid_js.Show, {
|
|
869
885
|
get when() {
|
|
870
886
|
return hasParent();
|
|
871
887
|
},
|
|
@@ -889,7 +905,7 @@ var NodeComponent = (props) => {
|
|
|
889
905
|
return props.input || hasParent();
|
|
890
906
|
},
|
|
891
907
|
get children() {
|
|
892
|
-
return (0, solid_js_web.ssr)(_tmpl$2, (0, solid_js_web.ssrHydrationKey)(), (0, solid_js_web.ssrStyleProperty)("left:", `-${(0, solid_js_web.escape)(18, true)}px`), (0, solid_js_web.ssrStyleProperty)("width:", `${(0, solid_js_web.escape)(12, true)}px`) + (0, solid_js_web.ssrStyleProperty)(";height:", `${(0, solid_js_web.escape)(12, true)}px`) + (0, solid_js_web.ssrStyleProperty)(";margin-top:", `${(0, solid_js_web.escape)(12, true)}px`) + (0, solid_js_web.ssrStyleProperty)(";pointer-events:", "all"));
|
|
908
|
+
return (0, solid_js_web.ssr)(_tmpl$2$1, (0, solid_js_web.ssrHydrationKey)(), (0, solid_js_web.ssrStyleProperty)("left:", `-${(0, solid_js_web.escape)(18, true)}px`), (0, solid_js_web.ssrStyleProperty)("width:", `${(0, solid_js_web.escape)(12, true)}px`) + (0, solid_js_web.ssrStyleProperty)(";height:", `${(0, solid_js_web.escape)(12, true)}px`) + (0, solid_js_web.ssrStyleProperty)(";margin-top:", `${(0, solid_js_web.escape)(12, true)}px`) + (0, solid_js_web.ssrStyleProperty)(";pointer-events:", "all"));
|
|
893
909
|
}
|
|
894
910
|
})), (0, solid_js_web.ssrStyleProperty)("right:", `-${(0, solid_js_web.escape)(18, true)}px`), (0, solid_js_web.ssrStyleProperty)("width:", `${(0, solid_js_web.escape)(12, true)}px`) + (0, solid_js_web.ssrStyleProperty)(";height:", `${(0, solid_js_web.escape)(12, true)}px`) + (0, solid_js_web.ssrStyleProperty)(";margin-top:", `${(0, solid_js_web.escape)(12, true)}px`) + (0, solid_js_web.ssrStyleProperty)(";pointer-events:", "all"));
|
|
895
911
|
};
|
|
@@ -897,22 +913,33 @@ var NodeComponent = (props) => {
|
|
|
897
913
|
//#region src/ui/components/NodesBoard.tsx
|
|
898
914
|
var _tmpl$$1 = [
|
|
899
915
|
"<div",
|
|
900
|
-
" class=\"relative
|
|
901
|
-
"<!--/--><!--$-->",
|
|
916
|
+
" class=\"relative h-full w-full overflow-scroll rounded-lg border-2 border-gray-600\"><!--$-->",
|
|
902
917
|
"<!--/--><div class=\"",
|
|
903
918
|
"\" style=\"",
|
|
919
|
+
"\"><div class=\"relative h-full w-full\" style=\"",
|
|
904
920
|
"\"><!--$-->",
|
|
905
921
|
"<!--/--><!--$-->",
|
|
906
|
-
"
|
|
907
|
-
"
|
|
922
|
+
"<!--/--><!--$-->",
|
|
923
|
+
"<!--/--></div></div></div>"
|
|
924
|
+
];
|
|
925
|
+
var _tmpl$2 = [
|
|
926
|
+
"<div",
|
|
927
|
+
" class=\"absolute right-4 bottom-4 z-50 flex items-center gap-2 rounded-xl border border-gray-200 bg-white/90 p-2 shadow-lg backdrop-blur-md\"><button type=\"button\" class=\"flex size-9 cursor-pointer items-center justify-center rounded-lg bg-gray-100 text-lg font-bold text-gray-700 shadow-sm transition-all duration-150 hover:bg-gray-200 active:scale-95\" title=\"Zoom out\" aria-label=\"Zoom out\">-</button><button type=\"button\" class=\"h-9 cursor-pointer rounded-lg px-2 text-xs font-semibold text-gray-700 transition-colors hover:bg-gray-100\" title=\"Reset zoom\" aria-label=\"Reset zoom\"><!--$-->",
|
|
928
|
+
"<!--/-->%</button><button type=\"button\" class=\"flex size-9 cursor-pointer items-center justify-center rounded-lg bg-gray-100 text-lg font-bold text-gray-700 shadow-sm transition-all duration-150 hover:bg-gray-200 active:scale-95\" title=\"Zoom in\" aria-label=\"Zoom in\">+</button><div class=\"h-5 w-px bg-gray-300\"></div><button type=\"button\" class=\"flex size-9 cursor-pointer items-center justify-center rounded-lg bg-blue-600 text-white shadow transition-all duration-150 hover:bg-blue-700 active:scale-95\" title=\"Add parent node\" aria-label=\"Add parent node\"><svg class=\"size-5\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z\"></path></svg></button></div>"
|
|
929
|
+
];
|
|
930
|
+
var _tmpl$3 = [
|
|
931
|
+
"<div",
|
|
932
|
+
" class=\"relative mx-auto h-[calc(100vh-64px)] w-[calc(100vw-32px)] overflow-hidden\">",
|
|
933
|
+
"</div>"
|
|
908
934
|
];
|
|
909
935
|
/**
|
|
910
|
-
* Interactive board component containing the drag-drop viewport, zoom
|
|
911
|
-
*
|
|
936
|
+
* Interactive board component containing the drag-drop viewport, zoom controls,
|
|
937
|
+
* panning gestures, and rendered nodes/edges.
|
|
912
938
|
*
|
|
913
939
|
* @returns The rendered Solid component.
|
|
914
940
|
*/
|
|
915
941
|
var NodesBoard = () => {
|
|
942
|
+
let containerRef;
|
|
916
943
|
const [isPanning, setIsPanning] = (0, solid_js.createSignal)(false);
|
|
917
944
|
const [transform, setTransform] = (0, solid_js.createSignal)({
|
|
918
945
|
x: 0,
|
|
@@ -920,11 +947,23 @@ var NodesBoard = () => {
|
|
|
920
947
|
});
|
|
921
948
|
const [id, setId] = (0, solid_js.createSignal)("");
|
|
922
949
|
const [previousZoom, setPreviousZoom] = (0, solid_js.createSignal)();
|
|
923
|
-
let
|
|
924
|
-
|
|
950
|
+
let percentX = 0;
|
|
951
|
+
let percentY = 0;
|
|
925
952
|
const { board: [, setRef], service, newEdge: [newEdge], zoom: [zoom, setZoom] } = useFlow();
|
|
926
|
-
(0, solid_js.createEffect)((0, solid_js.on)(zoom, () => {
|
|
953
|
+
(0, solid_js.createEffect)((0, solid_js.on)(zoom, () => {
|
|
954
|
+
const maxScrollX = containerRef.scrollWidth - containerRef.clientWidth;
|
|
955
|
+
const maxScrollY = containerRef.scrollHeight - containerRef.clientHeight;
|
|
956
|
+
if (maxScrollX > 0) containerRef.scrollLeft = percentX * maxScrollX;
|
|
957
|
+
if (maxScrollY > 0) containerRef.scrollTop = percentY * maxScrollY;
|
|
958
|
+
}, { defer: true }));
|
|
927
959
|
const selectedId = (0, _bemedev_app_solidjs.useState)(service, { selector: (s) => s.context?.selected });
|
|
960
|
+
/**
|
|
961
|
+
* Determines whether the given element ID matches the currently selected entity.
|
|
962
|
+
*
|
|
963
|
+
* @param id - The node or edge identifier to check.
|
|
964
|
+
*
|
|
965
|
+
* @returns `true` if the item is currently selected, otherwise `false`.
|
|
966
|
+
*/
|
|
928
967
|
const selected = (id) => selectedId() === id;
|
|
929
968
|
const nodes = (0, _bemedev_app_solidjs.useState)(service, {
|
|
930
969
|
selector: (s) => {
|
|
@@ -939,21 +978,27 @@ var NodesBoard = () => {
|
|
|
939
978
|
},
|
|
940
979
|
equals: dequal.dequal
|
|
941
980
|
});
|
|
942
|
-
const
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
}
|
|
947
|
-
return (0, solid_js_web.createComponent)(_thisbeyond_solid_dnd.DragDropProvider, {
|
|
948
|
-
onDragMove: ({ draggable: { transform: _transform, node, id }
|
|
981
|
+
const CANVAS_SIZE = 500;
|
|
982
|
+
const MARGIN_X = 265;
|
|
983
|
+
const MARGIN_Y = 425;
|
|
984
|
+
const cWidth = () => `calc((${CANVAS_SIZE}vw - ${MARGIN_X}px) * ${zoom()})`;
|
|
985
|
+
const cHeight = () => `calc((${CANVAS_SIZE}vh - ${MARGIN_Y}px) * ${zoom()})`;
|
|
986
|
+
return (0, solid_js_web.ssr)(_tmpl$3, (0, solid_js_web.ssrHydrationKey)(), (0, solid_js_web.escape)((0, solid_js_web.createComponent)(_thisbeyond_solid_dnd.DragDropProvider, {
|
|
987
|
+
onDragMove: ({ draggable: { transform: _transform, node, id } }) => {
|
|
949
988
|
setId(id);
|
|
950
989
|
if (selected(id)) {
|
|
951
|
-
const
|
|
952
|
-
const
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
const
|
|
956
|
-
const
|
|
990
|
+
const grandParent = node.parentElement?.parentElement;
|
|
991
|
+
const currentZoom = zoom();
|
|
992
|
+
const minX = 0;
|
|
993
|
+
const maxX = grandParent ? Math.max(0, grandParent.clientWidth / currentZoom - node.offsetWidth) : Infinity;
|
|
994
|
+
const minY = 0;
|
|
995
|
+
const maxY = grandParent ? Math.max(0, grandParent.clientHeight / currentZoom - node.offsetHeight) : Infinity;
|
|
996
|
+
const targetX = node.offsetLeft + _transform.x / currentZoom;
|
|
997
|
+
const targetY = node.offsetTop + _transform.y / currentZoom;
|
|
998
|
+
const x = Math.min(Math.max(targetX, minX), maxX);
|
|
999
|
+
const y = Math.min(Math.max(targetY, minY), maxY);
|
|
1000
|
+
const deltaX = x - node.offsetLeft;
|
|
1001
|
+
const deltaY = y - node.offsetTop;
|
|
957
1002
|
node.style.setProperty("transform", `translate3d(${deltaX}px, ${deltaY}px, 0)`);
|
|
958
1003
|
service.send({
|
|
959
1004
|
type: "MOVE_IMMEDIATE",
|
|
@@ -963,13 +1008,24 @@ var NodesBoard = () => {
|
|
|
963
1008
|
y
|
|
964
1009
|
}
|
|
965
1010
|
});
|
|
966
|
-
setTransform({
|
|
1011
|
+
setTransform({
|
|
1012
|
+
x: deltaX * currentZoom,
|
|
1013
|
+
y: deltaY * currentZoom
|
|
1014
|
+
});
|
|
967
1015
|
}
|
|
968
1016
|
},
|
|
969
1017
|
onDragEnd: ({ draggable: { node, id } }) => {
|
|
970
1018
|
if (!selected(id)) return;
|
|
971
|
-
const
|
|
972
|
-
const
|
|
1019
|
+
const grandParent = node.parentElement?.parentElement;
|
|
1020
|
+
const currentZoom = zoom();
|
|
1021
|
+
const minX = 0;
|
|
1022
|
+
const maxX = grandParent ? Math.max(0, grandParent.clientWidth / currentZoom - node.offsetWidth) : Infinity;
|
|
1023
|
+
const minY = 0;
|
|
1024
|
+
const maxY = grandParent ? Math.max(0, grandParent.clientHeight / currentZoom - node.offsetHeight) : Infinity;
|
|
1025
|
+
const rawX = node.offsetLeft + transform().x / currentZoom;
|
|
1026
|
+
const rawY = node.offsetTop + transform().y / currentZoom;
|
|
1027
|
+
const X = Math.min(Math.max(rawX, minX), maxX);
|
|
1028
|
+
const Y = Math.min(Math.max(rawY, minY), maxY);
|
|
973
1029
|
node.style.setProperty("top", Y + "px");
|
|
974
1030
|
node.style.setProperty("left", X + "px");
|
|
975
1031
|
node.style.removeProperty("transform");
|
|
@@ -989,21 +1045,25 @@ var NodesBoard = () => {
|
|
|
989
1045
|
}, 0);
|
|
990
1046
|
},
|
|
991
1047
|
get children() {
|
|
992
|
-
return [
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1048
|
+
return [
|
|
1049
|
+
(0, solid_js_web.ssr)(_tmpl$$1, (0, solid_js_web.ssrHydrationKey)(), (0, solid_js_web.escape)((0, solid_js_web.createComponent)(_thisbeyond_solid_dnd.DragDropSensors, {})), `relative cursor-crosshair overflow-hidden ${isPanning() ? "cursor-grabbing" : ""}`, (0, solid_js_web.ssrStyleProperty)("height:", (0, solid_js_web.escape)(cHeight(), true)) + (0, solid_js_web.ssrStyleProperty)(";width:", (0, solid_js_web.escape)(cWidth(), true)), (0, solid_js_web.ssrStyleProperty)("scale:", (0, solid_js_web.escape)(zoom(), true)) + (0, solid_js_web.ssrStyleProperty)(";transform-origin:", "top left"), (0, solid_js_web.escape)((0, solid_js_web.createComponent)(DragBounds, {})), (0, solid_js_web.escape)((0, solid_js_web.createComponent)(EdgesBoard, {})), (0, solid_js_web.escape)((0, solid_js_web.createComponent)(solid_js.For, {
|
|
1050
|
+
get each() {
|
|
1051
|
+
return nodes();
|
|
1052
|
+
},
|
|
1053
|
+
children: NodeComponent
|
|
1054
|
+
}))),
|
|
1055
|
+
(0, solid_js_web.ssr)(_tmpl$2, (0, solid_js_web.ssrHydrationKey)(), (0, solid_js_web.escape)(Math.round(zoom() * 100))),
|
|
1056
|
+
(0, solid_js_web.createComponent)(solid_js.Show, {
|
|
1057
|
+
get when() {
|
|
1058
|
+
return !id() || !selected(id());
|
|
1059
|
+
},
|
|
1060
|
+
get children() {
|
|
1061
|
+
return (0, solid_js_web.createComponent)(_thisbeyond_solid_dnd.DragOverlay, { children: "" });
|
|
1062
|
+
}
|
|
1063
|
+
})
|
|
1064
|
+
];
|
|
1005
1065
|
}
|
|
1006
|
-
});
|
|
1066
|
+
})));
|
|
1007
1067
|
};
|
|
1008
1068
|
//#endregion
|
|
1009
1069
|
//#region src/ui/components/FlowChart.tsx
|
|
@@ -1014,8 +1074,8 @@ var _tmpl$ = [
|
|
|
1014
1074
|
"</div></div>"
|
|
1015
1075
|
];
|
|
1016
1076
|
/**
|
|
1017
|
-
* Flowchart board canvas component that renders interactive nodes, edges,
|
|
1018
|
-
*
|
|
1077
|
+
* Flowchart board canvas component that renders interactive nodes, edges, pan/zoom,
|
|
1078
|
+
* and toolbar controls.
|
|
1019
1079
|
*
|
|
1020
1080
|
* @param props - Flowchart configuration and event handlers of type
|
|
1021
1081
|
* {@linkcode FlowProps}.
|
|
@@ -1042,8 +1102,8 @@ var FlowChart = (props) => {
|
|
|
1042
1102
|
//#endregion
|
|
1043
1103
|
//#region src/ui/Flow.tsx
|
|
1044
1104
|
/**
|
|
1045
|
-
* Root Flow component wrapping the {@linkcode FlowChart} inside the flow
|
|
1046
|
-
*
|
|
1105
|
+
* Root Flow component wrapping the {@linkcode FlowChart} inside the flow context
|
|
1106
|
+
* provider.
|
|
1047
1107
|
*
|
|
1048
1108
|
* @param props - Flow chart configuration and callbacks of type
|
|
1049
1109
|
* {@linkcode FlowProps}.
|