@bemedev/mind-flow 0.1.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/README.md +10 -10
  2. package/lib/helpers/createContext.d.ts +7 -2
  3. package/lib/helpers/createContext.d.ts.map +1 -1
  4. package/lib/index.cjs.js +1 -1
  5. package/lib/index.es.js +556 -510
  6. package/lib/output.css +1 -1
  7. package/lib/server.cjs.js +645 -418
  8. package/lib/server.es.js +649 -422
  9. package/lib/services/main.machine.d.ts +4857 -218
  10. package/lib/services/main.machine.d.ts.map +1 -1
  11. package/lib/{ui/components/FlowChart.data.d.ts → services/main.machine.data.d.ts} +4 -2
  12. package/lib/services/main.machine.data.d.ts.map +1 -0
  13. package/lib/services/main.machine.helpers.d.ts +32 -0
  14. package/lib/services/main.machine.helpers.d.ts.map +1 -0
  15. package/lib/services/main.machine.typings.d.ts +126 -0
  16. package/lib/services/main.machine.typings.d.ts.map +1 -0
  17. package/lib/ui/Flow.d.ts +2 -0
  18. package/lib/ui/Flow.d.ts.map +1 -1
  19. package/lib/ui/components/Bounds.d.ts +2 -0
  20. package/lib/ui/components/Bounds.d.ts.map +1 -1
  21. package/lib/ui/components/EdgeComponent.d.ts +3 -2
  22. package/lib/ui/components/EdgeComponent.d.ts.map +1 -1
  23. package/lib/ui/components/EdgesBoard.d.ts +2 -0
  24. package/lib/ui/components/EdgesBoard.d.ts.map +1 -1
  25. package/lib/ui/components/FlowChart.context.d.ts +5608 -996
  26. package/lib/ui/components/FlowChart.context.d.ts.map +1 -1
  27. package/lib/ui/components/FlowChart.d.ts +3 -1
  28. package/lib/ui/components/FlowChart.d.ts.map +1 -1
  29. package/lib/ui/components/NodeComponent.d.ts +2 -10
  30. package/lib/ui/components/NodeComponent.d.ts.map +1 -1
  31. package/lib/ui/components/NodesBoard.d.ts +2 -0
  32. package/lib/ui/components/NodesBoard.d.ts.map +1 -1
  33. package/package.json +8 -8
  34. package/src/helpers/createContext.ts +7 -2
  35. package/src/{ui/components/FlowChart.data.ts → services/main.machine.data.ts} +3 -1
  36. package/src/services/main.machine.helpers.ts +55 -0
  37. package/src/services/main.machine.ts +288 -70
  38. package/src/services/main.machine.typings.ts +98 -0
  39. package/src/ui/Flow.tsx +2 -0
  40. package/src/ui/components/Bounds.tsx +13 -8
  41. package/src/ui/components/EdgeComponent.tsx +78 -56
  42. package/src/ui/components/EdgesBoard.tsx +13 -36
  43. package/src/ui/components/FlowChart.context.ts +204 -310
  44. package/src/ui/components/FlowChart.tsx +16 -16
  45. package/src/ui/components/NodeComponent.tsx +60 -104
  46. package/src/ui/components/NodesBoard.tsx +74 -47
  47. package/src/ui/components/classes.ts +1 -1
  48. package/lib/services/main.typings.d.ts +0 -68
  49. package/lib/services/main.typings.d.ts.map +0 -1
  50. package/lib/ui/components/FlowChart.data.d.ts.map +0 -1
  51. package/src/services/main.typings.ts +0 -50
@@ -1,7 +1,9 @@
1
- import { useState } from '@bemedev/app-solidjs';
2
- import { Component, createEffect, createSignal, Show } from 'solid-js';
1
+ import { createState } from '@bemedev/app-solidjs';
2
+ import { dequal } from 'dequal';
3
+ import { Component, Show } from 'solid-js';
4
+
5
+ import type { Vector } from '#services/main.machine.typings';
3
6
 
4
- import type { Vector } from '../../services/main.typings';
5
7
  import { useFlow } from './FlowChart.context';
6
8
 
7
9
  /** Properties for rendering an SVG connection edge between two points. */
@@ -10,7 +12,7 @@ type Props = {
10
12
  id: string;
11
13
  /** Whether this is a temporary edge currently being dragged. */
12
14
  isNew?: boolean;
13
- } & Vector;
15
+ };
14
16
 
15
17
  /**
16
18
  * Computes bezier curve control point offset based on horizontal distance.
@@ -28,6 +30,8 @@ const calculateOffset = (value: number) => (value * 100) / 200;
28
30
  * @param vector - Vector coordinates of type {@linkcode Vector}.
29
31
  *
30
32
  * @returns SVG cubic bezier path string.
33
+ *
34
+ * @see {@linkcode calculateOffset}
31
35
  */
32
36
  const draw = ({ x0, y0, x1, y1 }: Vector) => {
33
37
  return `M ${x0} ${y0} C ${x0 + calculateOffset(Math.abs(x1 - x0))} ${y0}, ${x1 - calculateOffset(Math.abs(x1 - x0))} ${y1}, ${x1} ${y1}`;
@@ -40,66 +44,84 @@ const draw = ({ x0, y0, x1, y1 }: Vector) => {
40
44
  * @param props - Edge properties of type {@linkcode Props}.
41
45
  *
42
46
  * @returns The rendered SVG JSX elements.
47
+ *
48
+ * @see {@linkcode draw}, {@linkcode useFlow}
43
49
  */
44
50
  export const EdgeComponent: Component<Props> = props => {
45
- const [middlePoint, setMiddlePoint] = createSignal({
46
- x: props.x0 + (props.x1 - props.x0) / 2,
47
- y: props.y0 + (props.y1 - props.y0) / 2,
48
- });
49
-
50
- const { service } = useFlow();
51
+ const service = useFlow();
51
52
 
52
- createEffect(() => {
53
- const middleX = props.x0 + (props.x1 - props.x0) / 2;
54
- const middleY = props.y0 + (props.y1 - props.y0) / 2;
55
- setMiddlePoint({ x: middleX, y: middleY });
53
+ const vector = createState(service, {
54
+ selector: ({ context }) => {
55
+ if (props.isNew) {
56
+ const edge = context.newEdge;
57
+ if (!edge) return undefined;
58
+ return { x0: edge.x0, y0: edge.y0, x1: edge.x1, y1: edge.y1 };
59
+ }
60
+ return context.edgesPositions[props.id];
61
+ },
62
+ equals: dequal,
56
63
  });
57
64
 
58
- const selected = useState(service, {
65
+ const selected = createState(service, {
59
66
  selector: s => s.context.selected === props.id,
60
67
  });
61
68
 
69
+ /** Computes the 2D midpoint coordinate of the edge curve for handle placement. */
70
+ const middlePoint = () => {
71
+ const v = vector();
72
+ if (!v) return { x: 0, y: 0 };
73
+ return { x: v.x0 + (v.x1 - v.x0) / 2, y: v.y0 + (v.y1 - v.y0) / 2 };
74
+ };
75
+
62
76
  return (
63
- <>
64
- <path
65
- class='relative cursor-pointer fill-transparent'
66
- classList={{
67
- 'stroke-[rgba(168,168,168,0.4)] stroke-3 z-200': !!props.isNew,
68
- 'stroke-[rgba(168,168,168,1)] stroke-4 z-100': selected() && !props.isNew,
69
- 'stroke-[rgba(168,168,168,0.8)] stroke-3': !selected() && !props.isNew,
70
- }}
71
- style={{ 'pointer-events': props.isNew ? 'none' : 'all' }}
72
- d={draw(props)}
73
- onMouseDown={e => e.stopPropagation()}
74
- onClick={() => service.send({ type: 'SELECT', payload: props.id })}
75
- />
76
- <Show when={selected()}>
77
- <g
78
- cursor='pointer'
79
- transform={`translate(${middlePoint().x}, ${middlePoint().y})`}
80
- onMouseDown={e => {
81
- e.stopPropagation();
82
- service.send({ type: 'DELETE', payload: props.id });
83
- }}
84
- style={{ 'pointer-events': 'all', 'z-index': '30' }}
85
- >
86
- <circle cx='0' cy='0' r='12' fill='rgba(168, 168, 168, 1)' />
87
- <svg
88
- fill='currentColor'
89
- stroke-width='0'
90
- xmlns='http://www.w3.org/2000/svg'
91
- class='h-25 w-25 bg-white fill-white'
92
- width='20'
93
- height='20'
94
- viewBox='0 0 20 20'
95
- color='white'
96
- x='-10'
97
- y='-10'
98
- >
99
- <path d='M10.185,1.417c-4.741,0-8.583,3.842-8.583,8.583c0,4.74,3.842,8.582,8.583,8.582S18.768,14.74,18.768,10C18.768,5.259,14.926,1.417,10.185,1.417 M10.185,17.68c-4.235,0-7.679-3.445-7.679-7.68c0-4.235,3.444-7.679,7.679-7.679S17.864,5.765,17.864,10C17.864,14.234,14.42,17.68,10.185,17.68 M10.824,10l2.842-2.844c0.178-0.176,0.178-0.46,0-0.637c-0.177-0.178-0.461-0.178-0.637,0l-2.844,2.841L7.341,6.52c-0.176-0.178-0.46-0.178-0.637,0c-0.178,0.176-0.178,0.461,0,0.637L9.546,10l-2.841,2.844c-0.178,0.176-0.178,0.461,0,0.637c0.178,0.178,0.459,0.178,0.637,0l2.844-2.841l2.844,2.841c0.178,0.178,0.459,0.178,0.637,0c0.178-0.176,0.178-0.461,0-0.637L10.824,10z'></path>
100
- </svg>
101
- </g>
102
- </Show>
103
- </>
77
+ <Show when={vector()}>
78
+ {v => (
79
+ <>
80
+ <path
81
+ class='relative cursor-pointer fill-transparent'
82
+ classList={{
83
+ 'stroke-[rgba(168,168,168,0.4)] stroke-3 z-200': !!props.isNew,
84
+ 'stroke-[rgba(168,168,168,1)] stroke-4 z-100':
85
+ selected() && !props.isNew,
86
+ 'stroke-[rgba(168,168,168,0.8)] stroke-3': !selected() && !props.isNew,
87
+ }}
88
+ style={{ 'pointer-events': props.isNew ? 'none' : 'all' }}
89
+ d={draw(v())}
90
+
91
+ onMouseDown={e => {
92
+ e.stopPropagation();
93
+ return service.send({ type: 'SELECT', payload: props.id });
94
+ }}
95
+ />
96
+ <Show when={selected()}>
97
+ <g
98
+ cursor='pointer'
99
+ transform={`translate(${middlePoint().x}, ${middlePoint().y})`}
100
+ onMouseDown={e => {
101
+ e.stopPropagation();
102
+ service.send({ type: 'DELETE', payload: props.id });
103
+ }}
104
+ style={{ 'pointer-events': 'all', 'z-index': '30' }}
105
+ >
106
+ <circle cx='0' cy='0' r='12' fill='rgba(168, 168, 168, 1)' />
107
+ <svg
108
+ fill='currentColor'
109
+ stroke-width='0'
110
+ xmlns='http://www.w3.org/2000/svg'
111
+ class='h-25 w-25 bg-white fill-white'
112
+ width='20'
113
+ height='20'
114
+ viewBox='0 0 20 20'
115
+ color='white'
116
+ x='-10'
117
+ y='-10'
118
+ >
119
+ <path d='M10.185,1.417c-4.741,0-8.583,3.842-8.583,8.583c0,4.74,3.842,8.582,8.583,8.582S18.768,14.74,18.768,10C18.768,5.259,14.926,1.417,10.185,1.417 M10.185,17.68c-4.235,0-7.679-3.445-7.679-7.68c0-4.235,3.444-7.679,7.679-7.679S17.864,5.765,17.864,10C17.864,14.234,14.42,17.68,10.185,17.68 M10.824,10l2.842-2.844c0.178-0.176,0.178-0.46,0-0.637c-0.177-0.178-0.461-0.178-0.637,0l-2.844,2.841L7.341,6.52c-0.176-0.178-0.46-0.178-0.637,0c-0.178,0.176-0.178,0.461,0,0.637L9.546,10l-2.841,2.844c-0.178,0.176-0.178,0.461,0,0.637c0.178,0.178,0.459,0.178,0.637,0l2.844-2.841l2.844,2.841c0.178,0.178,0.459,0.178,0.637,0c0.178-0.176,0.178-0.461,0-0.637L10.824,10z'></path>
120
+ </svg>
121
+ </g>
122
+ </Show>
123
+ </>
124
+ )}
125
+ </Show>
104
126
  );
105
127
  };
@@ -1,11 +1,5 @@
1
- import {
2
- Component,
3
- createEffect,
4
- createMemo,
5
- createSignal,
6
- For,
7
- Show,
8
- } from 'solid-js';
1
+ import { createState } from '@bemedev/app-solidjs';
2
+ import { Component, For, Show } from 'solid-js';
9
3
 
10
4
  import { EdgeComponent } from './EdgeComponent';
11
5
  import { useFlow } from './FlowChart.context';
@@ -15,43 +9,26 @@ import { useFlow } from './FlowChart.context';
15
9
  * edge creation previews.
16
10
  *
17
11
  * @returns The rendered SVG JSX element.
12
+ *
13
+ * @see {@linkcode EdgeComponent}, {@linkcode useFlow}
18
14
  */
19
15
  export const EdgesBoard: Component = () => {
20
- const [selected, setSelected] = createSignal<string>();
21
-
22
- const {
23
- newEdge: [newEdge],
24
- edgesPositions: [edgesPositions],
25
- } = useFlow();
16
+ const service = useFlow();
26
17
 
27
- const datas = createMemo(() => {
28
- const entries = Object.entries(edgesPositions());
29
- return entries.map(([id, vector]) => ({ id, ...vector }));
30
- });
18
+ const hasNewEdge = createState(service, { selector: s => !!s.context.newEdge });
31
19
 
32
- createEffect(() => {
33
- if (selected() && newEdge()) setSelected();
20
+ const edgeIds = createState(service, {
21
+ selector: ({ context }) => Object.keys(context.edgesPositions),
22
+ equals: (prev, next) => prev.length === next.length,
34
23
  });
35
24
 
36
25
  return (
37
- <svg
38
- class='pointer-events-none h-full w-full overflow-visible'
39
- // style={{ scale: zoom() }}
40
- >
41
- <Show when={newEdge()}>
42
- {value => (
43
- <EdgeComponent
44
- id='__#new-edge#__TEMP'
45
- isNew
46
- x0={value().x0}
47
- y0={value().y0}
48
- x1={value().x1}
49
- y1={value().y1}
50
- />
51
- )}
26
+ <svg class='pointer-events-none h-full w-full overflow-visible'>
27
+ <Show when={hasNewEdge()}>
28
+ <EdgeComponent id='__#new-edge#__TEMP' isNew />
52
29
  </Show>
53
30
 
54
- <For each={datas()} children={EdgeComponent} />
31
+ <For each={edgeIds()}>{id => <EdgeComponent id={id} />}</For>
55
32
  </svg>
56
33
  );
57
34
  };