@bemedev/mind-flow 1.3.0 → 1.4.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/lib/index.cjs.js +1 -1
- package/lib/index.es.js +721 -819
- package/lib/output.css +1 -1
- package/lib/server.cjs.js +136 -314
- package/lib/server.es.js +138 -316
- package/lib/ui/Flow.d.ts +3 -3
- package/lib/ui/Flow.d.ts.map +1 -1
- package/lib/ui/components/EditPanel.d.ts.map +1 -1
- package/lib/ui/components/FlowChart.d.ts.map +1 -1
- package/lib/ui/components/FlowChart.types.d.ts +8 -8
- package/lib/ui/components/NodeComponent.d.ts.map +1 -1
- package/lib/ui/components/Panels.d.ts.map +1 -1
- package/package.json +5 -4
- package/src/ui/Flow.tsx +7 -28
- package/src/ui/components/EditPanel.tsx +6 -1
- package/src/ui/components/FlowChart.tsx +65 -23
- package/src/ui/components/FlowChart.types.ts +8 -8
- package/src/ui/components/NodeComponent.tsx +3 -6
- package/src/ui/components/Panels.tsx +38 -15
package/lib/ui/Flow.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Flow.d.ts","sourceRoot":"","sources":["../../src/ui/Flow.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"Flow.d.ts","sourceRoot":"","sources":["../../src/ui/Flow.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,UAAU,CAAC;AAEpC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kCAAkC,CAAC;AAGjE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAE9D;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,IAAI,GAAI,CAAC,SAAS,QAAQ,GAAG,QAAQ,EAChD,OAAO,SAAS,CAAC,CAAC,CAAC,KAClB,GAAG,CAAC,OAeN,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EditPanel.d.ts","sourceRoot":"","sources":["../../../src/ui/components/EditPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,GAAG,EAAQ,MAAM,UAAU,CAAC;AAE1C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAK/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,SAAS,GAAI,CAAC,SAAS,QAAQ,GAAG,QAAQ,EACrD,OAAO,cAAc,CAAC,CAAC,CAAC,KACvB,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"EditPanel.d.ts","sourceRoot":"","sources":["../../../src/ui/components/EditPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,GAAG,EAAQ,MAAM,UAAU,CAAC;AAE1C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAK/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,SAAS,GAAI,CAAC,SAAS,QAAQ,GAAG,QAAQ,EACrD,OAAO,cAAc,CAAC,CAAC,CAAC,KACvB,GAAG,CAAC,OAoEN,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FlowChart.d.ts","sourceRoot":"","sources":["../../../src/ui/components/FlowChart.tsx"],"names":[],"mappings":"AACA,OAAO,EAAgB,KAAK,GAAG,EAAsB,MAAM,UAAU,CAAC;AAGtE,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAG1E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAGnD,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;AAIpC;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,SAAS,GAAI,CAAC,SAAS,QAAQ,GAAG,QAAQ,EACrD,OAAO,SAAS,CAAC,CAAC,CAAC,KAClB,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"FlowChart.d.ts","sourceRoot":"","sources":["../../../src/ui/components/FlowChart.tsx"],"names":[],"mappings":"AACA,OAAO,EAAgB,KAAK,GAAG,EAAsB,MAAM,UAAU,CAAC;AAGtE,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAG1E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAGnD,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;AAIpC;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,SAAS,GAAI,CAAC,SAAS,QAAQ,GAAG,QAAQ,EACrD,OAAO,SAAS,CAAC,CAAC,CAAC,KAClB,GAAG,CAAC,OAuGN,CAAC"}
|
|
@@ -15,8 +15,8 @@ export type FlowPanels = {
|
|
|
15
15
|
* Configuration options and callback handlers for the {@linkcode FlowChart}
|
|
16
16
|
* component.
|
|
17
17
|
*
|
|
18
|
-
* @template | {@linkcode NodeData} `D` - Custom node data dictionary type
|
|
19
|
-
* {@linkcode NodeData}.
|
|
18
|
+
* @template | Type {@linkcode NodeData} `D` - Custom node data dictionary type
|
|
19
|
+
* extending type {@linkcode NodeData}.
|
|
20
20
|
*/
|
|
21
21
|
export type FlowProps<D extends NodeData = NodeData> = {
|
|
22
22
|
/** Optional delay in milliseconds before mounting the flowchart canvas. */
|
|
@@ -64,24 +64,24 @@ export type FlowProps<D extends NodeData = NodeData> = {
|
|
|
64
64
|
/**
|
|
65
65
|
* Type alias extracting the non-undefined flowchart configuration object.
|
|
66
66
|
*
|
|
67
|
-
* @template | {@linkcode NodeData} `D` - Custom node data dictionary type
|
|
68
|
-
* {@linkcode NodeData}.
|
|
67
|
+
* @template | Type {@linkcode NodeData} `D` - Custom node data dictionary type
|
|
68
|
+
* extending type {@linkcode NodeData}.
|
|
69
69
|
*/
|
|
70
70
|
export type ConfigFrom<D extends NodeData = NodeData> = NotUndefined<FlowProps<D>['config']>;
|
|
71
71
|
/**
|
|
72
72
|
* Type alias extracting the non-undefined list of nodes from flowchart
|
|
73
73
|
* configuration.
|
|
74
74
|
*
|
|
75
|
-
* @template | {@linkcode NodeData} `D` - Custom node data dictionary type
|
|
76
|
-
* {@linkcode NodeData}.
|
|
75
|
+
* @template | Type {@linkcode NodeData} `D` - Custom node data dictionary type
|
|
76
|
+
* extending type {@linkcode NodeData}.
|
|
77
77
|
*/
|
|
78
78
|
export type NodesFrom<D extends NodeData> = NotUndefined<ConfigFrom<D>['nodes']>;
|
|
79
79
|
/**
|
|
80
80
|
* Type alias extracting the non-undefined list of edges from flowchart
|
|
81
81
|
* configuration.
|
|
82
82
|
*
|
|
83
|
-
* @template | {@linkcode NodeData} `D` - Custom node data dictionary type
|
|
84
|
-
* {@linkcode NodeData}.
|
|
83
|
+
* @template | Type {@linkcode NodeData} `D` - Custom node data dictionary type
|
|
84
|
+
* extending type {@linkcode NodeData}.
|
|
85
85
|
*/
|
|
86
86
|
export type EdgesFrom<D extends NodeData> = NotUndefined<ConfigFrom<D>['edges']>;
|
|
87
87
|
//# sourceMappingURL=FlowChart.types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NodeComponent.d.ts","sourceRoot":"","sources":["../../../src/ui/components/NodeComponent.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,SAAS,EAAO,KAAK,GAAG,EAAQ,MAAM,UAAU,CAAC;AAQ/D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAK/D,uEAAuE;AACvE,MAAM,MAAM,kBAAkB,CAAC,CAAC,SAAS,QAAQ,GAAG,QAAQ,IAAI;IAC9D,qCAAqC;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,iEAAiE;IACjE,QAAQ,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;CACzB,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,aAAa,GAAI,CAAC,SAAS,QAAQ,GAAG,QAAQ,EACzD,OAAO,kBAAkB,CAAC,CAAC,CAAC,KAC3B,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"NodeComponent.d.ts","sourceRoot":"","sources":["../../../src/ui/components/NodeComponent.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,SAAS,EAAO,KAAK,GAAG,EAAQ,MAAM,UAAU,CAAC;AAQ/D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAK/D,uEAAuE;AACvE,MAAM,MAAM,kBAAkB,CAAC,CAAC,SAAS,QAAQ,GAAG,QAAQ,IAAI;IAC9D,qCAAqC;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,iEAAiE;IACjE,QAAQ,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;CACzB,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,aAAa,GAAI,CAAC,SAAS,QAAQ,GAAG,QAAQ,EACzD,OAAO,kBAAkB,CAAC,CAAC,CAAC,KAC3B,GAAG,CAAC,OA4NN,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Panels.d.ts","sourceRoot":"","sources":["../../../src/ui/components/Panels.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Panels.d.ts","sourceRoot":"","sources":["../../../src/ui/components/Panels.tsx"],"names":[],"mappings":"AACA,OAAO,EAAQ,KAAK,SAAS,EAAE,MAAM,UAAU,CAAC;AAGhD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAiCpD;;;;;;;GAOG;AACH,eAAO,MAAM,MAAM,EAAE,SAAS,CAAC,UAAU,CAQxC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bemedev/mind-flow",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.1",
|
|
4
4
|
"description": "Flow Chart UI library for Solid.js applications",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"diagram",
|
|
@@ -65,13 +65,13 @@
|
|
|
65
65
|
"@bemedev/app": "^2.5.0",
|
|
66
66
|
"@bemedev/app-cli": "^2.5.0",
|
|
67
67
|
"@bemedev/app-solidjs": "^2.5.1",
|
|
68
|
-
"@bemedev/dev-utils": "^1.
|
|
68
|
+
"@bemedev/dev-utils": "^1.5.0",
|
|
69
69
|
"@rollup/plugin-babel": "^7.1.0",
|
|
70
70
|
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
71
71
|
"@size-limit/file": "^13.0.3",
|
|
72
72
|
"@tailwindcss/cli": "^4.3.3",
|
|
73
73
|
"@tailwindcss/vite": "^4.3.3",
|
|
74
|
-
"@types/node": "^26.
|
|
74
|
+
"@types/node": "^26.4.0",
|
|
75
75
|
"@vitest/coverage-v8": "^4.1.11",
|
|
76
76
|
"glob": "^13.0.6",
|
|
77
77
|
"globals": "^17.11.0",
|
|
@@ -113,7 +113,8 @@
|
|
|
113
113
|
"node": ">=22"
|
|
114
114
|
},
|
|
115
115
|
"scripts": {
|
|
116
|
-
"build": "pnpm rm:lib && pnpm run build:
|
|
116
|
+
"build": "pnpm rm:lib && pnpm run build:dev",
|
|
117
|
+
"build:dev": "pnpm run build:server && pnpm run build:client && pnpm run build:css",
|
|
117
118
|
"build:client": "vite build",
|
|
118
119
|
"build:server": "vite build --mode server",
|
|
119
120
|
"build:css": "pnpx @tailwindcss/cli -i ./input.css -o ../lib/output.css --minify --cwd ./src",
|
package/src/ui/Flow.tsx
CHANGED
|
@@ -1,33 +1,27 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {} from 'solid-js/web';
|
|
1
|
+
import { type JSX } from 'solid-js';
|
|
3
2
|
|
|
4
3
|
import type { NodeData } from '../services/main.machine.typings';
|
|
5
4
|
import { FlowChart } from './components/FlowChart';
|
|
6
5
|
import { Provider } from './components/FlowChart.context';
|
|
7
6
|
import type { FlowProps } from './components/FlowChart.types';
|
|
8
|
-
import { LoadingFallback } from './globals/components/organisms/LoadingFallback';
|
|
9
7
|
|
|
10
8
|
/**
|
|
11
9
|
* Root Flow component wrapping the {@linkcode FlowChart} inside the flow context
|
|
12
10
|
* provider.
|
|
13
11
|
*
|
|
14
|
-
* @template | {@linkcode NodeData} `D` - Custom node data dictionary type
|
|
15
|
-
* {@linkcode NodeData}.
|
|
12
|
+
* @template | Type {@linkcode NodeData} `D` - Custom node data dictionary type
|
|
13
|
+
* extending type {@linkcode NodeData}.
|
|
16
14
|
*
|
|
17
15
|
* @param props - Flow chart configuration and callbacks of type
|
|
18
16
|
* {@linkcode FlowProps}.
|
|
19
17
|
*
|
|
20
18
|
* @returns The rendered Solid component.
|
|
21
19
|
*
|
|
22
|
-
* @see {@linkcode Provider}
|
|
20
|
+
* @see {@linkcode Provider}
|
|
23
21
|
*/
|
|
24
22
|
export const Flow = <D extends NodeData = NodeData>(
|
|
25
23
|
props: FlowProps<D>,
|
|
26
24
|
): JSX.Element => {
|
|
27
|
-
const [isMounted, setIsMounted] = createSignal(false);
|
|
28
|
-
|
|
29
|
-
// onMount never runs on the server, only in the browser
|
|
30
|
-
onMount(() => setTimeout(() => setIsMounted(true), props.delay));
|
|
31
25
|
return (
|
|
32
26
|
<div
|
|
33
27
|
style={{
|
|
@@ -37,24 +31,9 @@ export const Flow = <D extends NodeData = NodeData>(
|
|
|
37
31
|
|
|
38
32
|
class='relative flex h-full w-full rounded-lg border-2 border-gray-600 bg-white bg-size-[30px_30px]'
|
|
39
33
|
>
|
|
40
|
-
<
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
fallback={
|
|
44
|
-
<div class='relative flex flex-1 items-center justify-center'>
|
|
45
|
-
<LoadingFallback
|
|
46
|
-
message='Chart is loading...'
|
|
47
|
-
interval={35}
|
|
48
|
-
rewind
|
|
49
|
-
rewindDelay={1_000}
|
|
50
|
-
/>
|
|
51
|
-
</div>
|
|
52
|
-
}
|
|
53
|
-
>
|
|
54
|
-
<Provider>
|
|
55
|
-
<FlowChart {...props} />
|
|
56
|
-
</Provider>
|
|
57
|
-
</Show>
|
|
34
|
+
<Provider>
|
|
35
|
+
<FlowChart {...props} />
|
|
36
|
+
</Provider>
|
|
58
37
|
</div>
|
|
59
38
|
);
|
|
60
39
|
};
|
|
@@ -25,6 +25,7 @@ export const EditPanel = <D extends NodeData = NodeData>(
|
|
|
25
25
|
props: EditPanelProps<D>,
|
|
26
26
|
): JSX.Element => {
|
|
27
27
|
void clickOutside;
|
|
28
|
+
// const editing
|
|
28
29
|
const hooks = useHook<D>(props.timeout);
|
|
29
30
|
const classList = () =>
|
|
30
31
|
props.classList instanceof Function ? props.classList(hooks) : props.classList;
|
|
@@ -36,7 +37,11 @@ export const EditPanel = <D extends NodeData = NodeData>(
|
|
|
36
37
|
class={cn(
|
|
37
38
|
`w-80 cursor-default rounded-2xl border border-gray-200 bg-white/95 p-4 shadow-xl backdrop-blur-md transition-all ${props.class ?? ''}`,
|
|
38
39
|
)}
|
|
39
|
-
classList={
|
|
40
|
+
classList={{
|
|
41
|
+
...classList(),
|
|
42
|
+
'pointer-events-none! -z-10': !hooks.editing(),
|
|
43
|
+
'pointer-events-all! z-50': !!hooks.editing(),
|
|
44
|
+
}}
|
|
40
45
|
style={props.style}
|
|
41
46
|
onMouseDown={e => e.stopPropagation()}
|
|
42
47
|
use:clickOutside={hooks.close}
|
|
@@ -32,7 +32,9 @@ export const FlowChart = <D extends NodeData = NodeData>(
|
|
|
32
32
|
const primaryNodes = props.config?.nodes ?? DEFAULT_NODES;
|
|
33
33
|
const primaryEdges = props.config?.edges;
|
|
34
34
|
const service = useFlow();
|
|
35
|
-
const
|
|
35
|
+
const fromSignal = createState(service, {
|
|
36
|
+
selector: s => s.context.newEdge?.from,
|
|
37
|
+
});
|
|
36
38
|
onCleanup(service.pause);
|
|
37
39
|
|
|
38
40
|
onMount(() => {
|
|
@@ -47,33 +49,73 @@ export const FlowChart = <D extends NodeData = NodeData>(
|
|
|
47
49
|
});
|
|
48
50
|
});
|
|
49
51
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
52
|
+
let added = false;
|
|
53
|
+
|
|
54
|
+
// Track the currently enlarged handle during edge drag
|
|
55
|
+
let activeHandle: HTMLElement | null = null;
|
|
56
|
+
|
|
57
|
+
const clearActiveHandle = () => {
|
|
58
|
+
if (activeHandle) {
|
|
59
|
+
activeHandle.classList.remove('scale-150');
|
|
60
|
+
activeHandle = null;
|
|
61
|
+
added = false;
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const handlePointerMove = (e: MouseEvent | PointerEvent) => {
|
|
66
|
+
service.send({ type: 'MOVE_NEW_EDGE', payload: { x: e.clientX, y: e.clientY } });
|
|
67
|
+
|
|
68
|
+
const elements = document.elementsFromPoint(e.clientX, e.clientY);
|
|
69
|
+
const inputHandle = elements
|
|
70
|
+
.map(el => el.closest<HTMLElement>('.rounded-full[data-handle-type="input"]'))
|
|
71
|
+
.find((handle): handle is HTMLElement =>
|
|
72
|
+
Boolean(handle && handle.id !== 'inputs'),
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
// If cursor moved away from previous handle, reset its scale
|
|
76
|
+
if (activeHandle && activeHandle !== inputHandle) {
|
|
77
|
+
clearActiveHandle();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// If cursor entered a valid target handle, enlarge it
|
|
81
|
+
if (inputHandle) {
|
|
82
|
+
if (activeHandle !== inputHandle) {
|
|
83
|
+
inputHandle.classList.add('scale-150');
|
|
84
|
+
activeHandle = inputHandle;
|
|
85
|
+
added = true;
|
|
69
86
|
}
|
|
70
|
-
|
|
71
|
-
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const createHandlePointerUp = (from: string) => (e: MouseEvent | PointerEvent) => {
|
|
91
|
+
const elements = document.elementsFromPoint(e.clientX, e.clientY);
|
|
92
|
+
const inputHandle = elements
|
|
93
|
+
.map(el => el.closest<HTMLElement>('.rounded-full[data-handle-type="input"]'))
|
|
94
|
+
.find((handle): handle is HTMLElement =>
|
|
95
|
+
Boolean(handle && handle.id !== 'inputs'),
|
|
96
|
+
);
|
|
97
|
+
const to = inputHandle?.getAttribute('data-node-id');
|
|
98
|
+
|
|
99
|
+
if (inputHandle && to) {
|
|
100
|
+
service.send({ type: 'ADD_EDGE', payload: { from, to } });
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Cleanup on release
|
|
104
|
+
clearActiveHandle();
|
|
105
|
+
service.send('CLEAR_NEW_EDGE');
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
createEffect(() => {
|
|
109
|
+
const from = fromSignal();
|
|
110
|
+
if (!from || added) return;
|
|
72
111
|
|
|
112
|
+
const handlePointerUp = createHandlePointerUp(from);
|
|
73
113
|
window.addEventListener('pointermove', handlePointerMove);
|
|
74
114
|
window.addEventListener('pointerup', handlePointerUp);
|
|
75
115
|
|
|
76
116
|
onCleanup(() => {
|
|
117
|
+
// Cleanup on effect disposal
|
|
118
|
+
clearActiveHandle();
|
|
77
119
|
window.removeEventListener('pointermove', handlePointerMove);
|
|
78
120
|
window.removeEventListener('pointerup', handlePointerUp);
|
|
79
121
|
});
|
|
@@ -83,7 +125,7 @@ export const FlowChart = <D extends NodeData = NodeData>(
|
|
|
83
125
|
<div class='relative h-full w-full'>
|
|
84
126
|
<div
|
|
85
127
|
class='h-full w-full'
|
|
86
|
-
style={{ cursor:
|
|
128
|
+
style={{ cursor: fromSignal() ? 'inherit' : 'crosshair' }}
|
|
87
129
|
>
|
|
88
130
|
<NodesBoard panels={props.panels} component={props.component} />
|
|
89
131
|
</div>
|
|
@@ -19,8 +19,8 @@ export type FlowPanels = {
|
|
|
19
19
|
* Configuration options and callback handlers for the {@linkcode FlowChart}
|
|
20
20
|
* component.
|
|
21
21
|
*
|
|
22
|
-
* @template | {@linkcode NodeData} `D` - Custom node data dictionary type
|
|
23
|
-
* {@linkcode NodeData}.
|
|
22
|
+
* @template | Type {@linkcode NodeData} `D` - Custom node data dictionary type
|
|
23
|
+
* extending type {@linkcode NodeData}.
|
|
24
24
|
*/
|
|
25
25
|
export type FlowProps<D extends NodeData = NodeData> = {
|
|
26
26
|
/** Optional delay in milliseconds before mounting the flowchart canvas. */
|
|
@@ -66,8 +66,8 @@ export type FlowProps<D extends NodeData = NodeData> = {
|
|
|
66
66
|
/**
|
|
67
67
|
* Type alias extracting the non-undefined flowchart configuration object.
|
|
68
68
|
*
|
|
69
|
-
* @template | {@linkcode NodeData} `D` - Custom node data dictionary type
|
|
70
|
-
* {@linkcode NodeData}.
|
|
69
|
+
* @template | Type {@linkcode NodeData} `D` - Custom node data dictionary type
|
|
70
|
+
* extending type {@linkcode NodeData}.
|
|
71
71
|
*/
|
|
72
72
|
export type ConfigFrom<D extends NodeData = NodeData> = NotUndefined<
|
|
73
73
|
FlowProps<D>['config']
|
|
@@ -77,8 +77,8 @@ export type ConfigFrom<D extends NodeData = NodeData> = NotUndefined<
|
|
|
77
77
|
* Type alias extracting the non-undefined list of nodes from flowchart
|
|
78
78
|
* configuration.
|
|
79
79
|
*
|
|
80
|
-
* @template | {@linkcode NodeData} `D` - Custom node data dictionary type
|
|
81
|
-
* {@linkcode NodeData}.
|
|
80
|
+
* @template | Type {@linkcode NodeData} `D` - Custom node data dictionary type
|
|
81
|
+
* extending type {@linkcode NodeData}.
|
|
82
82
|
*/
|
|
83
83
|
export type NodesFrom<D extends NodeData> = NotUndefined<ConfigFrom<D>['nodes']>;
|
|
84
84
|
|
|
@@ -86,7 +86,7 @@ export type NodesFrom<D extends NodeData> = NotUndefined<ConfigFrom<D>['nodes']>
|
|
|
86
86
|
* Type alias extracting the non-undefined list of edges from flowchart
|
|
87
87
|
* configuration.
|
|
88
88
|
*
|
|
89
|
-
* @template | {@linkcode NodeData} `D` - Custom node data dictionary type
|
|
90
|
-
* {@linkcode NodeData}.
|
|
89
|
+
* @template | Type {@linkcode NodeData} `D` - Custom node data dictionary type
|
|
90
|
+
* extending type {@linkcode NodeData}.
|
|
91
91
|
*/
|
|
92
92
|
export type EdgesFrom<D extends NodeData> = NotUndefined<ConfigFrom<D>['edges']>;
|
|
@@ -200,8 +200,6 @@ export const NodeComponent = <D extends NodeData = NodeData>(
|
|
|
200
200
|
|
|
201
201
|
<div
|
|
202
202
|
id='inputs'
|
|
203
|
-
data-handle-type='input'
|
|
204
|
-
data-node-id={props.id}
|
|
205
203
|
class='pointer-events-none absolute top-0 z-10 flex cursor-default flex-col'
|
|
206
204
|
style={{ left: `-${HANDLE_CONTAINER_OFFSET_X}px` }}
|
|
207
205
|
>
|
|
@@ -211,7 +209,7 @@ export const NodeComponent = <D extends NodeData = NodeData>(
|
|
|
211
209
|
onMouseDown={event => event.stopPropagation()}
|
|
212
210
|
onPointerDown={e => e.stopPropagation()}
|
|
213
211
|
|
|
214
|
-
class='cursor-default rounded-full bg-[#e38b29] shadow-md transition-transform'
|
|
212
|
+
class='cursor-default rounded-full bg-[#e38b29] shadow-md transition-transform duration-150 ease-in-out hover:scale-150'
|
|
215
213
|
|
|
216
214
|
style={{
|
|
217
215
|
width: `${HANDLE_SIZE}px`,
|
|
@@ -233,8 +231,7 @@ export const NodeComponent = <D extends NodeData = NodeData>(
|
|
|
233
231
|
</div>
|
|
234
232
|
<div
|
|
235
233
|
id='outputs'
|
|
236
|
-
|
|
237
|
-
data-node-id={props.id}
|
|
234
|
+
|
|
238
235
|
style={{ right: `-${HANDLE_CONTAINER_OFFSET_X}px` }}
|
|
239
236
|
|
|
240
237
|
class='pointer-events-none absolute top-0 z-10 flex flex-col'
|
|
@@ -242,7 +239,7 @@ export const NodeComponent = <D extends NodeData = NodeData>(
|
|
|
242
239
|
<div
|
|
243
240
|
data-handle-type='output'
|
|
244
241
|
data-node-id={props.id}
|
|
245
|
-
class='cursor-crosshair rounded-full bg-[#e38b29] shadow-md transition-transform'
|
|
242
|
+
class='cursor-crosshair rounded-full bg-[#e38b29] shadow-md transition-transform duration-150 ease-in-out hover:scale-150'
|
|
246
243
|
style={{
|
|
247
244
|
width: `${HANDLE_SIZE}px`,
|
|
248
245
|
height: `${HANDLE_SIZE}px`,
|
|
@@ -1,7 +1,40 @@
|
|
|
1
|
+
import { isDefined } from '@bemedev/app/bemedev';
|
|
1
2
|
import { Show, type Component } from 'solid-js';
|
|
2
3
|
|
|
4
|
+
import { cn } from '../utils';
|
|
3
5
|
import type { FlowPanels } from './FlowChart.types';
|
|
4
6
|
|
|
7
|
+
/** Properties for the internal {@linkcode Panel} wrapper component. */
|
|
8
|
+
type PanelProps = {
|
|
9
|
+
/** Optional component to render inside the panel container. */
|
|
10
|
+
children?: Component;
|
|
11
|
+
/** CSS class names for positioning and layout. */
|
|
12
|
+
class: string;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Overlay slot component rendering an optional panel component with z-index
|
|
17
|
+
* positioning.
|
|
18
|
+
*
|
|
19
|
+
* @param props - Panel properties of type {@linkcode PanelProps}.
|
|
20
|
+
*
|
|
21
|
+
* @returns The rendered panel container element or fallback.
|
|
22
|
+
*
|
|
23
|
+
* @see {@linkcode cn}
|
|
24
|
+
*/
|
|
25
|
+
const Panel: Component<PanelProps> = props => {
|
|
26
|
+
const exists = isDefined(props.children);
|
|
27
|
+
return (
|
|
28
|
+
<Show when={props.children} keyed>
|
|
29
|
+
{Children => (
|
|
30
|
+
<div class={cn(props.class)} classList={{ 'z-50': exists }}>
|
|
31
|
+
<Children />
|
|
32
|
+
</div>
|
|
33
|
+
)}
|
|
34
|
+
</Show>
|
|
35
|
+
);
|
|
36
|
+
};
|
|
37
|
+
|
|
5
38
|
/**
|
|
6
39
|
* Overlay container rendering custom panel slots positioned around the flowchart
|
|
7
40
|
* canvas.
|
|
@@ -12,20 +45,10 @@ import type { FlowPanels } from './FlowChart.types';
|
|
|
12
45
|
*/
|
|
13
46
|
export const Panels: Component<FlowPanels> = props => {
|
|
14
47
|
return (
|
|
15
|
-
|
|
16
|
-
<
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
{/* Top-Right Panel */}
|
|
21
|
-
<Show when={props.topRight} keyed>
|
|
22
|
-
{Panel => <div class='absolute top-4 right-4 z-50'>{<Panel />}</div>}
|
|
23
|
-
</Show>
|
|
24
|
-
|
|
25
|
-
{/* Bottom-Left Panel */}
|
|
26
|
-
<Show when={props.bottomLeft} keyed>
|
|
27
|
-
{Panel => <div class='absolute bottom-4 left-4 z-50'>{<Panel />}</div>}
|
|
28
|
-
</Show>
|
|
29
|
-
</>
|
|
48
|
+
<div class='pointer-events-none absolute inset-0'>
|
|
49
|
+
<Panel children={props.topLeft} class='absolute top-4 left-4' />
|
|
50
|
+
<Panel children={props.topRight} class='absolute top-4 right-4' />
|
|
51
|
+
<Panel children={props.bottomLeft} class='absolute bottom-4 left-4' />
|
|
52
|
+
</div>
|
|
30
53
|
);
|
|
31
54
|
};
|