@kabel-project/kabel 1.0.7 → 1.0.8

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 (273) hide show
  1. package/dist/comment-renderer/renderer.d.ts +32 -0
  2. package/dist/comment-renderer/renderer.d.ts.map +1 -0
  3. package/dist/controllers/base.d.ts +39 -0
  4. package/dist/controllers/base.d.ts.map +1 -0
  5. package/dist/controllers/wasd.d.ts +33 -0
  6. package/dist/controllers/wasd.d.ts.map +1 -0
  7. package/dist/events/comment-drag-handle.d.ts +2 -0
  8. package/dist/events/comment-drag-handle.d.ts.map +1 -0
  9. package/dist/events/comment-input.d.ts +4 -0
  10. package/dist/events/comment-input.d.ts.map +1 -0
  11. package/dist/events/connection-line.d.ts +2 -0
  12. package/dist/events/connection-line.d.ts.map +1 -0
  13. package/dist/events/connector.d.ts +2 -0
  14. package/dist/events/connector.d.ts.map +1 -0
  15. package/dist/events/draggable.d.ts +2 -0
  16. package/dist/events/draggable.d.ts.map +1 -0
  17. package/{events/events.ts → dist/events/events.d.ts} +8 -7
  18. package/dist/events/events.d.ts.map +1 -0
  19. package/dist/events/input-box.d.ts +2 -0
  20. package/dist/events/input-box.d.ts.map +1 -0
  21. package/dist/events/node-x-btn.d.ts +2 -0
  22. package/dist/events/node-x-btn.d.ts.map +1 -0
  23. package/dist/kabel.js +2 -0
  24. package/dist/kabel.js.map +1 -0
  25. package/dist/renderers/apollo/apollo.d.ts +12 -0
  26. package/dist/renderers/apollo/apollo.d.ts.map +1 -0
  27. package/dist/renderers/apollo/constants.d.ts +21 -0
  28. package/dist/renderers/apollo/constants.d.ts.map +1 -0
  29. package/dist/renderers/apollo/renderer.d.ts +97 -0
  30. package/dist/renderers/apollo/renderer.d.ts.map +1 -0
  31. package/{renderers/atlas/atlas.ts → dist/renderers/atlas/atlas.d.ts} +6 -15
  32. package/dist/renderers/atlas/atlas.d.ts.map +1 -0
  33. package/dist/renderers/constants.d.ts +51 -0
  34. package/dist/renderers/constants.d.ts.map +1 -0
  35. package/dist/renderers/renderer.d.ts +470 -0
  36. package/dist/renderers/renderer.d.ts.map +1 -0
  37. package/dist/renderers/representer-node.d.ts +27 -0
  38. package/dist/renderers/representer-node.d.ts.map +1 -0
  39. package/dist/renderers/representer.d.ts +13 -0
  40. package/dist/renderers/representer.d.ts.map +1 -0
  41. package/dist/src/category.d.ts +48 -0
  42. package/dist/src/category.d.ts.map +1 -0
  43. package/{src/colors.ts → dist/src/colors.d.ts} +21 -20
  44. package/dist/src/colors.d.ts.map +1 -0
  45. package/dist/src/comment.d.ts +88 -0
  46. package/dist/src/comment.d.ts.map +1 -0
  47. package/dist/src/connection.d.ts +52 -0
  48. package/dist/src/connection.d.ts.map +1 -0
  49. package/dist/src/context-menu.d.ts +76 -0
  50. package/dist/src/context-menu.d.ts.map +1 -0
  51. package/dist/src/coordinates.d.ts +52 -0
  52. package/dist/src/coordinates.d.ts.map +1 -0
  53. package/dist/src/core.d.ts +153 -0
  54. package/dist/src/core.d.ts.map +1 -0
  55. package/dist/src/ctx-menu-registry.d.ts +22 -0
  56. package/dist/src/ctx-menu-registry.d.ts.map +1 -0
  57. package/dist/src/dropdown-menu.d.ts +87 -0
  58. package/dist/src/dropdown-menu.d.ts.map +1 -0
  59. package/dist/src/field.d.ts +305 -0
  60. package/dist/src/field.d.ts.map +1 -0
  61. package/dist/src/flyout.d.ts +41 -0
  62. package/dist/src/flyout.d.ts.map +1 -0
  63. package/dist/src/fonts-manager.d.ts +6 -0
  64. package/dist/src/fonts-manager.d.ts.map +1 -0
  65. package/dist/src/grid.d.ts +60 -0
  66. package/dist/src/grid.d.ts.map +1 -0
  67. package/dist/src/headless-node.d.ts +11 -0
  68. package/dist/src/headless-node.d.ts.map +1 -0
  69. package/dist/src/index.d.ts +38 -0
  70. package/dist/src/index.d.ts.map +1 -0
  71. package/dist/src/inject-headless.d.ts +4 -0
  72. package/dist/src/inject-headless.d.ts.map +1 -0
  73. package/{src/inject.ts → dist/src/inject.d.ts} +142 -213
  74. package/dist/src/inject.d.ts.map +1 -0
  75. package/{src/main-workspace.ts → dist/src/main-workspace.d.ts} +31 -51
  76. package/dist/src/main-workspace.d.ts.map +1 -0
  77. package/dist/src/mutator.d.ts +2 -0
  78. package/dist/src/mutator.d.ts.map +1 -0
  79. package/{src/node-types.ts → dist/src/node-types.d.ts} +26 -27
  80. package/dist/src/node-types.d.ts.map +1 -0
  81. package/dist/src/nodesvg.d.ts +266 -0
  82. package/dist/src/nodesvg.d.ts.map +1 -0
  83. package/{src/prototypes.ts → dist/src/prototypes.d.ts} +10 -9
  84. package/dist/src/prototypes.d.ts.map +1 -0
  85. package/{src/renderer-map.ts → dist/src/renderer-map.d.ts} +51 -86
  86. package/dist/src/renderer-map.d.ts.map +1 -0
  87. package/dist/src/toolbox.d.ts +51 -0
  88. package/dist/src/toolbox.d.ts.map +1 -0
  89. package/{src/types.ts → dist/src/types.d.ts} +159 -205
  90. package/dist/src/types.d.ts.map +1 -0
  91. package/dist/src/undo-redo.d.ts +15 -0
  92. package/dist/src/undo-redo.d.ts.map +1 -0
  93. package/{src/visual-types.ts → dist/src/visual-types.d.ts} +34 -29
  94. package/dist/src/visual-types.d.ts.map +1 -0
  95. package/dist/src/widget-prototypes.d.ts +10 -0
  96. package/dist/src/widget-prototypes.d.ts.map +1 -0
  97. package/dist/src/widget.d.ts +62 -0
  98. package/dist/src/widget.d.ts.map +1 -0
  99. package/{src/workspace-coords.ts → dist/src/workspace-coords.d.ts} +10 -14
  100. package/dist/src/workspace-coords.d.ts.map +1 -0
  101. package/dist/src/workspace-svg.d.ts +371 -0
  102. package/dist/src/workspace-svg.d.ts.map +1 -0
  103. package/dist/src/workspace.d.ts +50 -0
  104. package/dist/src/workspace.d.ts.map +1 -0
  105. package/dist/themes/dark.d.ts +4 -0
  106. package/dist/themes/dark.d.ts.map +1 -0
  107. package/dist/themes/default.d.ts +4 -0
  108. package/dist/themes/default.d.ts.map +1 -0
  109. package/dist/themes/themes.d.ts +6 -0
  110. package/dist/themes/themes.d.ts.map +1 -0
  111. package/dist/util/emitter.d.ts +10 -0
  112. package/dist/util/emitter.d.ts.map +1 -0
  113. package/dist/util/env.d.ts +7 -0
  114. package/dist/util/env.d.ts.map +1 -0
  115. package/{util/escape-html.ts → dist/util/escape-html.d.ts} +16 -22
  116. package/dist/util/escape-html.d.ts.map +1 -0
  117. package/dist/util/eventer.d.ts +29 -0
  118. package/dist/util/eventer.d.ts.map +1 -0
  119. package/dist/util/has-prop.d.ts +2 -0
  120. package/dist/util/has-prop.d.ts.map +1 -0
  121. package/dist/util/parse-color.d.ts +6 -0
  122. package/dist/util/parse-color.d.ts.map +1 -0
  123. package/dist/util/path.d.ts +25 -0
  124. package/dist/util/path.d.ts.map +1 -0
  125. package/dist/util/styler.d.ts +12 -0
  126. package/dist/util/styler.d.ts.map +1 -0
  127. package/dist/util/uid.d.ts +42 -0
  128. package/dist/util/uid.d.ts.map +1 -0
  129. package/{util/unescape-html.ts → dist/util/unescape-html.d.ts} +16 -22
  130. package/dist/util/unescape-html.d.ts.map +1 -0
  131. package/dist/util/user-state.d.ts +37 -0
  132. package/dist/util/user-state.d.ts.map +1 -0
  133. package/{util/wait-anim-frames.ts → dist/util/wait-anim-frames.d.ts} +11 -24
  134. package/dist/util/wait-anim-frames.d.ts.map +1 -0
  135. package/dist/util/window-listeners.d.ts +8 -0
  136. package/dist/util/window-listeners.d.ts.map +1 -0
  137. package/package.json +4 -1
  138. package/(1.0.7)kabel.md +0 -18
  139. package/_READ_ME_MEDIA_/documentation/docs.md +0 -293
  140. package/_READ_ME_MEDIA_/workspace.png +0 -0
  141. package/comment-renderer/renderer.ts +0 -228
  142. package/controllers/base.ts +0 -186
  143. package/controllers/wasd.ts +0 -132
  144. package/docs/README.md +0 -98
  145. package/docs/_media/docs.md +0 -289
  146. package/docs/_media/workspace.png +0 -0
  147. package/docs/classes/CommentModel.md +0 -271
  148. package/docs/classes/CommentRenderer.md +0 -457
  149. package/docs/classes/ConnectableField.md +0 -597
  150. package/docs/classes/Connection.md +0 -191
  151. package/docs/classes/ContextMenuHTML.md +0 -163
  152. package/docs/classes/Coordinates.md +0 -187
  153. package/docs/classes/DropdownContainer.md +0 -300
  154. package/docs/classes/DummyField.md +0 -393
  155. package/docs/classes/Eventer.md +0 -185
  156. package/docs/classes/Field.md +0 -461
  157. package/docs/classes/InjectMsg.md +0 -85
  158. package/docs/classes/NodeSvg.md +0 -1011
  159. package/docs/classes/NumberField.md +0 -559
  160. package/docs/classes/OptConnectField.md +0 -624
  161. package/docs/classes/Renderer.md +0 -1636
  162. package/docs/classes/RendererConstants.md +0 -343
  163. package/docs/classes/Representer.md +0 -95
  164. package/docs/classes/RepresenterNode.md +0 -175
  165. package/docs/classes/TextField.md +0 -559
  166. package/docs/classes/Toolbox.md +0 -172
  167. package/docs/classes/WASDController.md +0 -616
  168. package/docs/classes/Widget.md +0 -195
  169. package/docs/classes/WorkspaceController.md +0 -385
  170. package/docs/classes/WorkspaceCoords.md +0 -218
  171. package/docs/classes/WorkspaceSvg.md +0 -1380
  172. package/docs/functions/clearMainWorkspace.md +0 -20
  173. package/docs/functions/getMainWorkspace.md +0 -19
  174. package/docs/functions/inject.md +0 -35
  175. package/docs/functions/setMainWorkspace.md +0 -28
  176. package/docs/globals.md +0 -95
  177. package/docs/interfaces/ColorStyle.md +0 -43
  178. package/docs/interfaces/ConnectorToFrom.md +0 -57
  179. package/docs/interfaces/DrawState.md +0 -81
  180. package/docs/interfaces/FieldConnectionData.md +0 -25
  181. package/docs/interfaces/FieldOptions.md +0 -63
  182. package/docs/interfaces/FieldRawBoxData.md +0 -25
  183. package/docs/interfaces/FieldVisualInfo.md +0 -65
  184. package/docs/interfaces/GridOptions.md +0 -61
  185. package/docs/interfaces/InjectOptions.md +0 -133
  186. package/docs/interfaces/InputFieldJson.md +0 -50
  187. package/docs/interfaces/KabelCommentRendering.md +0 -31
  188. package/docs/interfaces/KabelInterface.md +0 -469
  189. package/docs/interfaces/KabelNodeRendering.md +0 -77
  190. package/docs/interfaces/KabelUIX.md +0 -105
  191. package/docs/interfaces/KabelUtils.md +0 -215
  192. package/docs/interfaces/NodeEvents.md +0 -42
  193. package/docs/interfaces/NodeJson.md +0 -104
  194. package/docs/interfaces/NodePrototype.md +0 -82
  195. package/docs/interfaces/RegisteredEl.md +0 -53
  196. package/docs/interfaces/SerializedNode.md +0 -128
  197. package/docs/interfaces/TblxCategoryStruct.md +0 -41
  198. package/docs/interfaces/TblxFieldStruct.md +0 -28
  199. package/docs/interfaces/TblxNodeStruct.md +0 -35
  200. package/docs/interfaces/WidgetOptions.md +0 -115
  201. package/docs/interfaces/WidgetPrototypeList.md +0 -15
  202. package/docs/type-aliases/AnyField.md +0 -13
  203. package/docs/type-aliases/AnyFieldCls.md +0 -13
  204. package/docs/type-aliases/Color.md +0 -13
  205. package/docs/type-aliases/Connectable.md +0 -13
  206. package/docs/type-aliases/EventArgs.md +0 -11
  207. package/docs/type-aliases/EventSetupFn.md +0 -25
  208. package/docs/type-aliases/Hex.md +0 -13
  209. package/docs/type-aliases/RGBObject.md +0 -37
  210. package/docs/type-aliases/RGBString.md +0 -13
  211. package/docs/type-aliases/RGBTuple.md +0 -13
  212. package/docs/type-aliases/TblxObjStruct.md +0 -52
  213. package/docs/variables/CategoryColors.md +0 -29
  214. package/docs/variables/FieldMap.md +0 -41
  215. package/docs/variables/NodePrototypes.md +0 -18
  216. package/docs/variables/default.md +0 -11
  217. package/events/comment-drag-handle.ts +0 -61
  218. package/events/comment-input.ts +0 -291
  219. package/events/connection-line.ts +0 -68
  220. package/events/connector.ts +0 -116
  221. package/events/draggable.ts +0 -119
  222. package/events/input-box.ts +0 -213
  223. package/events/node-x-btn.ts +0 -25
  224. package/index.d.ts +0 -4
  225. package/renderers/apollo/apollo.ts +0 -21
  226. package/renderers/apollo/constants.ts +0 -40
  227. package/renderers/apollo/renderer.ts +0 -331
  228. package/renderers/constants.ts +0 -87
  229. package/renderers/renderer.ts +0 -1288
  230. package/renderers/representer-node.ts +0 -52
  231. package/renderers/representer.ts +0 -25
  232. package/src/category.ts +0 -107
  233. package/src/comment.ts +0 -142
  234. package/src/connection.ts +0 -114
  235. package/src/context-menu.ts +0 -194
  236. package/src/coordinates.ts +0 -74
  237. package/src/core.ts +0 -202
  238. package/src/ctx-menu-registry.ts +0 -143
  239. package/src/dropdown-menu.ts +0 -215
  240. package/src/field.ts +0 -595
  241. package/src/flyout.ts +0 -165
  242. package/src/fonts-manager.ts +0 -38
  243. package/src/grid.ts +0 -162
  244. package/src/headless-node.ts +0 -27
  245. package/src/index.ts +0 -115
  246. package/src/inject-headless.ts +0 -18
  247. package/src/mutator.ts +0 -40
  248. package/src/nodesvg.ts +0 -756
  249. package/src/styles.css +0 -224
  250. package/src/toolbox.ts +0 -125
  251. package/src/undo-redo.ts +0 -87
  252. package/src/widget-prototypes.ts +0 -11
  253. package/src/widget.ts +0 -139
  254. package/src/workspace-svg.ts +0 -736
  255. package/src/workspace.ts +0 -155
  256. package/test-server.js +0 -61
  257. package/themes/dark.ts +0 -32
  258. package/themes/default.ts +0 -28
  259. package/themes/themes.ts +0 -9
  260. package/tsconfig.json +0 -25
  261. package/typedoc.json +0 -10
  262. package/util/emitter.ts +0 -33
  263. package/util/env.ts +0 -11
  264. package/util/eventer.ts +0 -108
  265. package/util/has-prop.ts +0 -4
  266. package/util/parse-color.ts +0 -42
  267. package/util/path.ts +0 -99
  268. package/util/styler.ts +0 -41
  269. package/util/uid.ts +0 -184
  270. package/util/user-state.ts +0 -68
  271. package/util/window-listeners.ts +0 -62
  272. package/webpack.config.js +0 -80
  273. /package/{docs/_media → dist}/index.html +0 -0
@@ -1,213 +0,0 @@
1
- import { Element, Rect, Text } from "@svgdotjs/svg.js";
2
- import eventer, { EventSetupFn } from "../util/eventer";
3
- import userState from '../util/user-state';
4
- import { Renderer } from "../src";
5
-
6
- function initInputBox(element: Element, args: Record<string, any>) {
7
- let editing = false;
8
- let skipNextClick = false;
9
- let buffer = args.field.getDisplayValue?.() ?? "";
10
- let cursorPos = buffer.length;
11
- let anchorPos = buffer.length;
12
- const txt: Text = args.text;
13
- const rect: Rect = element as Rect;
14
- const renderer = args.renderer as Renderer;
15
- const PADDING_X = 4;
16
- const PADDING_Y = 4;
17
- let caretLine: Rect | null = null;
18
- let selectionRect: Rect | null = null;
19
- // @ts-ignore
20
- txt!.style('user-select', 'none');
21
- // @ts-ignore
22
- rect!.style('user-select', 'none');
23
-
24
- // Helper: measure width of text using renderer or fallback
25
- function measureTextWidth(text: string) {
26
-
27
- if (renderer.measureTextWidth) return renderer.measureTextWidth(text);
28
- return text.length * 8; // rough fallback
29
- }
30
-
31
- function getSelectionRange() {
32
- const start = Math.min(cursorPos, anchorPos);
33
- const end = Math.max(cursorPos, anchorPos);
34
- return { start, end };
35
- }
36
-
37
- function hasSelection() {
38
- return cursorPos !== anchorPos;
39
- }
40
-
41
- function deleteSelection() {
42
- if (!hasSelection()) return false;
43
- const { start, end } = getSelectionRange();
44
- buffer = buffer.slice(0, start) + buffer.slice(end);
45
- cursorPos = start;
46
- anchorPos = start;
47
- return true;
48
- }
49
-
50
- function updateText() {
51
- // redraw main text
52
- txt.text(buffer);
53
-
54
- const { start, end } = getSelectionRange();
55
- const { width: totalWidth } = renderer.measureRawField(buffer);
56
- const { height: rectHeight } = rect.bbox(); // actual rect height
57
-
58
- const textBBox = txt.bbox();
59
- const offsetY = (rectHeight - textBBox.height) / 2; // center vertically
60
-
61
- // --- selection highlight ---
62
- if (hasSelection()) {
63
- const textBeforeStart = buffer.slice(0, start);
64
- const textBeforeEnd = buffer.slice(0, end);
65
- const highlightX = args.startX + PADDING_X + measureTextWidth(textBeforeStart);
66
- const highlightWidth = Math.max(measureTextWidth(textBeforeEnd) - measureTextWidth(textBeforeStart), 1);
67
- const highlightY = offsetY; // use offsetY for vertical alignment
68
-
69
- if (!selectionRect) {
70
- // @ts-ignore
71
- selectionRect = rect.parent()!.rect(highlightWidth, textBBox.height)
72
- .fill('#3390ff')
73
- .attr({ 'fill-opacity': 0.35 });
74
- selectionRect!.node.parentNode!.insertBefore(selectionRect!.node, txt.node);
75
- } else {
76
- selectionRect.size(highlightWidth, textBBox.height);
77
- }
78
-
79
- selectionRect!.move(highlightX, highlightY);
80
- } else {
81
- if (selectionRect) { selectionRect.remove(); selectionRect = null; }
82
- }
83
-
84
- // --- caret ---
85
- if (editing) {
86
- const zoom = renderer.getWs().getZoom(); // workspace zoom
87
- const caretX = (args.startX + PADDING_X + measureTextWidth(buffer.slice(0, cursorPos))); // scale pos
88
- const caretH = textBBox.height;
89
- // @ts-ignore
90
- if (!caretLine) caretLine = rect.parent()!.rect(1, caretH).fill(renderer.constants.FIELD_RAW_TEXT_COLOR);
91
- caretLine!.size(1, caretH).move(caretX, offsetY);
92
- } else {
93
- if (caretLine) { caretLine.remove(); caretLine = null; }
94
- }
95
-
96
- // --- background rect ---
97
- rect.size(Math.max(16, totalWidth + PADDING_X * 2), Math.max(rectHeight, textBBox.height + PADDING_Y * 2));
98
- txt.move(args.startX + PADDING_X, offsetY);
99
- }
100
-
101
-
102
- function onKeyDown(e: KeyboardEvent) {
103
- if (!args.field.canEdit()) { // If editing isnt allowed, close the event early.
104
- if (editing) stopEditing();
105
- return;
106
- }
107
- if (!editing) return;
108
-
109
- if (e.key === "Escape") { e.preventDefault(); stopEditing(); return; }
110
- if (e.key === "Enter") { e.preventDefault(); stopEditing(); return; }
111
-
112
- if (e.key === "Backspace") {
113
- if (!deleteSelection() && cursorPos > 0) {
114
- buffer = buffer.slice(0, cursorPos - 1) + buffer.slice(cursorPos);
115
- cursorPos--;
116
- anchorPos = cursorPos;
117
- }
118
- } else if (e.key === "Delete") {
119
- if (!deleteSelection() && cursorPos < buffer.length) {
120
- buffer = buffer.slice(0, cursorPos) + buffer.slice(cursorPos + 1);
121
- }
122
- } else if (e.key === "ArrowLeft") {
123
- if (e.shiftKey) cursorPos = Math.max(0, cursorPos - 1);
124
- else { cursorPos = Math.max(0, cursorPos - 1); anchorPos = cursorPos; }
125
- } else if (e.key === "ArrowRight") {
126
- if (e.shiftKey) cursorPos = Math.min(buffer.length, cursorPos + 1);
127
- else { cursorPos = Math.min(buffer.length, cursorPos + 1); anchorPos = cursorPos; }
128
- } else if (e.key === "Home") {
129
- if (!e.shiftKey) anchorPos = 0;
130
- cursorPos = 0;
131
- } else if (e.key === "End") {
132
- if (!e.shiftKey) anchorPos = buffer.length;
133
- cursorPos = buffer.length;
134
- } else if (e.key.length === 1 && !e.ctrlKey && !e.metaKey) {
135
- if (hasSelection()) deleteSelection();
136
- buffer = buffer.slice(0, cursorPos) + e.key + buffer.slice(cursorPos);
137
- cursorPos++;
138
- anchorPos = cursorPos;
139
- } else return;
140
-
141
- e.preventDefault();
142
- updateText();
143
- args.field.setValue(buffer);
144
- }
145
-
146
- function onClickOutside(ev: MouseEvent) {
147
- if (!editing) return;
148
- if (skipNextClick) { skipNextClick = false; return; }
149
- const target = ev.target as Node;
150
- if (target !== rect.node && target !== txt.node) stopEditing();
151
- }
152
-
153
- function startEditing(ev?: MouseEvent) {
154
- if (!args.field.canEdit()) { // If editing isnt allowed, close the event early.
155
- if (editing) stopEditing();
156
- return;
157
- }
158
- if (editing) return;
159
- editing = true;
160
- buffer = args.field.getValue?.() ?? "";
161
- cursorPos = buffer.length;
162
- anchorPos = buffer.length;
163
-
164
- userState.setState('typing');
165
-
166
- if (ev) {
167
- const rectBox = rect.node.getBoundingClientRect();
168
- const zoom = renderer.getWs().getZoom(); // workspace zoom
169
- const clickX = (ev.clientX - rectBox.left - PADDING_X) / zoom;
170
-
171
- let cumulativeWidth = 0;
172
- cursorPos = 0;
173
- for (let i = 0; i < buffer.length; i++) {
174
- const charWidth = measureTextWidth(buffer[i]); // scale widths
175
- if (cumulativeWidth + charWidth / 2 >= clickX) break;
176
- cumulativeWidth += charWidth;
177
- cursorPos = i + 1;
178
- }
179
- }
180
-
181
- anchorPos = cursorPos;
182
- updateText();
183
- skipNextClick = true;
184
-
185
- document.addEventListener("keydown", onKeyDown);
186
- document.addEventListener("mousedown", onClickOutside);
187
- }
188
-
189
- function stopEditing() {
190
- editing = false;
191
- userState.removeState('typing');
192
- document.removeEventListener("keydown", onKeyDown);
193
- document.removeEventListener("mousedown", onClickOutside);
194
- args.field.setValue(buffer);
195
- updateText();
196
- renderer.getWs().redraw();
197
- renderer.getWs().emitChange();
198
- }
199
-
200
- rect.on("mousedown", (ev: Event) => startEditing(ev as MouseEvent));
201
- txt.on("mousedown", (ev: Event) => startEditing(ev as MouseEvent));
202
-
203
- updateText();
204
-
205
- return () => {
206
- rect.off("mousedown", startEditing as EventListener);
207
- txt.off("mousedown", startEditing as EventListener);
208
- document.removeEventListener("keydown", onKeyDown);
209
- document.removeEventListener("mousedown", onClickOutside);
210
- };
211
- }
212
-
213
- eventer.registerEvent("k_inputbox", initInputBox as EventSetupFn);
@@ -1,25 +0,0 @@
1
- import { Element, G } from '@svgdotjs/svg.js';
2
- import NodeSvg from '../src/nodesvg';
3
- import eventer, { EventSetupFn } from '../util/eventer';
4
- import WorkspaceSvg from '../src/workspace-svg';
5
-
6
- function initXButton(element: Element, args: Record<string, any>): () => void {
7
- const xBtnGroup = element as G;
8
- const ws: WorkspaceSvg = args.workspace;
9
-
10
- // click handler
11
- const onClick = () => {
12
- ws.removeNode(args.node);
13
- };
14
-
15
- // attach
16
- xBtnGroup.on('click', onClick);
17
-
18
- // return cleanup function
19
- return () => {
20
- xBtnGroup.off('click', onClick);
21
- };
22
- }
23
-
24
- // register as Kabel event
25
- eventer.registerEvent('k_closenode', initXButton as EventSetupFn);
package/index.d.ts DELETED
@@ -1,4 +0,0 @@
1
- declare module '*.svg' {
2
- const content: string;
3
- export default content;
4
- }
@@ -1,21 +0,0 @@
1
-
2
- import ApolloRenderer from "./renderer"
3
- import ApolloConstants from "./constants"
4
- import Representer from "../representer"
5
- import { RepresenterNode } from "../representer-node"
6
-
7
- export interface apolloType {
8
- Renderer: typeof ApolloRenderer;
9
- Constants: typeof ApolloConstants;
10
- Representer: typeof Representer;
11
- RepresenterNode: typeof RepresenterNode;
12
- }
13
-
14
-
15
- export {
16
- ApolloRenderer as Renderer,
17
- ApolloConstants as Constants,
18
- // Despite apollo not extending these, we still need to re-export them for the API.
19
- Representer,
20
- RepresenterNode
21
- }
@@ -1,40 +0,0 @@
1
- import { Color } from "../../src/visual-types";
2
- import RendererConstants from "../constants";
3
-
4
- // Define the new Dogear shape
5
- type DogearShape = {
6
- PathMain: string;
7
- Width: number;
8
- Height: number;
9
- };
10
-
11
- // Extend the original SHAPES type
12
- type ApolloShapes = RendererConstants['SHAPES'] & {
13
- Dogear?: DogearShape;
14
- };
15
-
16
- class ApolloConstants extends RendererConstants {
17
- SHAPES: ApolloShapes = {};
18
- CONNECTOR_COLOR: Color = '#9912e8ff'
19
- FIELD_RAW_COLOR: Color = '#343745ff';
20
- FIELD_RAW_TEXT_COLOR: Color = '#cfd4e4ff';
21
- FIELD_RAW_OUTLINE_COLOR: Color = '#202128ff';
22
- constructor(overrides: Partial<ApolloConstants>) {
23
- super(overrides);
24
- this.CONNECTOR_LINE_WIDTH = 2.5;
25
- this.CORNER_RADIUS = 10;
26
- this.FOOTER_HEIGHT = 25;
27
- this.CONNECTOR_LINE_WIDTH = 7;
28
- this.init();
29
- }
30
-
31
- init() {
32
- this.SHAPES.Dogear = {
33
- PathMain: `M -1 1 Q -1 21 0 30 L 26 0 Q 2 -1 0 0 Z`,
34
- Width: 26,
35
- Height: 30
36
- };
37
- }
38
- }
39
-
40
- export default ApolloConstants;
@@ -1,331 +0,0 @@
1
-
2
- import { Path as SvgPath, StrokeData, G } from "@svgdotjs/svg.js";
3
- import * as Path from '../../util/path'
4
- import { ColorStyle, Hex } from "../../src/visual-types";
5
- import WorkspaceSvg from "../../src/workspace-svg";
6
- import Renderer, { DrawState, NodeMeasurements } from "../renderer"; // Saying the value of "Renderer" is undefined when it's clearly defined and theres no circular refs.
7
- import ApolloConstants from "./constants";
8
- import { parseColor } from "../../util/parse-color";
9
- import eventer from "../../util/eventer";
10
- import NodeSvg from "../../src/nodesvg";
11
- import Connection from "../../src/connection";
12
- import { AnyField, FieldRawBoxData } from "../../src/field";
13
- console.log(Renderer);
14
-
15
- function darkenColor(hex: string, amount: number = 0.2): string {
16
- // Remove # if present
17
- hex = hex.replace(/^#/, "");
18
-
19
- // Parse r, g, b
20
- const r = parseInt(hex.substring(0, 2), 16);
21
- const g = parseInt(hex.substring(2, 4), 16);
22
- const b = parseInt(hex.substring(4, 6), 16);
23
-
24
- // Darken each channel
25
- const newR = Math.max(0, Math.floor(r * (1 - amount)));
26
- const newG = Math.max(0, Math.floor(g * (1 - amount)));
27
- const newB = Math.max(0, Math.floor(b * (1 - amount)));
28
-
29
- // Convert back to hex and pad with 0s
30
- const toHex = (c: number) => c.toString(16).padStart(2, "0");
31
-
32
- return `#${toHex(newR)}${toHex(newG)}${toHex(newB)}`;
33
- }
34
-
35
-
36
-
37
-
38
- /**
39
- * ApolloRenderer
40
- *
41
- * Custom renderer extending the base `Renderer` for a visual programming workspace.
42
- * This renderer provides a distinct node style:
43
- * - Node background uses the primary color entirely
44
- * - Topbar is hidden (but still present for dragging)
45
- * - Bottom-right dog-ear decoration
46
- * - Previous connection at the top, next connection at the bottom
47
- */
48
- class ApolloRenderer extends Renderer {
49
- declare _constants: ApolloConstants;
50
-
51
- static get NAME() {
52
- return 'apollo';
53
- }
54
- static get ElEMENT_TAG() {
55
- return 'ApolloElement';
56
- }
57
- /**
58
- * Constructor
59
- * @param workspace - The WorkspaceSvg instance
60
- * @param overrides - Partial constant overrides for ApolloConstants
61
- */
62
- constructor(workspace: WorkspaceSvg, overrides: Partial<ApolloConstants>) {
63
- super(workspace, overrides);
64
- }
65
-
66
- /**
67
- * Typed getter for renderer constants
68
- */
69
- get constants(): ApolloConstants {
70
- return super.constants as ApolloConstants;
71
- }
72
-
73
- /** Initialize constants using Apollo-specific overrides */
74
- initConstants() {
75
- this._constants = new ApolloConstants(this.constantOverrides);
76
- }
77
-
78
- /**
79
- * Draws the node's topbar.
80
- * Overridden to hide the topbar visually while retaining its group for dragging.
81
- * @param state - Current draw state
82
- * @param colors - Node colors
83
- * @param measurements - Node dimensions
84
- */
85
- drawNodeTopbar(state: DrawState, colors: ColorStyle, measurements: NodeMeasurements | null) {
86
- const c = this.constants;
87
- const width = measurements?.width ?? c.NODE_BASE_WIDTH;
88
- const radius = c.CORNER_RADIUS;
89
-
90
- state.topbar = state.group!.path(Path.roundedRect(width, c.TOPBAR_HEIGHT, radius))
91
- .fill('transparent');
92
- }
93
-
94
- /**
95
- * Draws the node background with rounded corners and bottom-right dog-ear cut.
96
- * Also creates a shadow.
97
- * @param state - Current draw state
98
- * @param measurements - Node dimensions
99
- */
100
- drawNodeBase(state: DrawState, measurements: NodeMeasurements | null) {
101
- const c = this.constants;
102
- const width = measurements?.width ?? c.NODE_BASE_WIDTH;
103
- const height = measurements?.height ?? c.NODE_BASE_HEIGHT;
104
- const r = c.CORNER_RADIUS;
105
-
106
- const dogear = this.constants.SHAPES.Dogear;
107
- const cutW = dogear?.Width ?? 0;
108
- const cutH = dogear?.Height ?? 0;
109
-
110
- // Rounded rect with bottom-right cut
111
- const roundedRect = `M${r},0 H${width - r} Q${width},0 ${width},${r} V${height - cutH} L${width - cutW},${height} H${r} Q0,${height} 0,${height - r} V${r} Q0,0 ${r},0 Z`;
112
-
113
- const colors = this.getNodeColors();
114
- const primary = parseColor(colors.primary) as string;
115
- const stroke = parseColor(colors.secondary) as string;
116
-
117
- // Node background
118
- state.bg = state.group!.path(roundedRect)
119
- .fill(primary)
120
- .stroke({ color: stroke, width: 2 });
121
-
122
- // Dog-ear decoration
123
- this.drawDogEar(state, state.group as G, width, height, colors);
124
-
125
- // Node shadow
126
- state.shadow = state.group!.path(roundedRect)
127
- .fill('rgba(0,0,0,0.2)')
128
- .stroke('none')
129
- .attr({ 'pointer-events': 'none' })
130
- .move(Number(state.bg.x()) + 5, Number(state.bg.y()) + 5)
131
- .back();
132
- }
133
-
134
- /**
135
- * Draws a dog-ear decoration at the node's bottom-right corner
136
- * @param state - Current draw state
137
- * @param nodeG - Node's SVG group
138
- * @param w - Node width
139
- * @param h - Node height
140
- * @param colors - Node colors
141
- */
142
- drawDogEar(state: DrawState, nodeG: G, w: number, h: number, colors: ColorStyle) {
143
- const pathDef = this.constants.SHAPES.Dogear?.PathMain;
144
- if (!pathDef) return;
145
-
146
- const dogEar = nodeG.path(pathDef)
147
- .fill(parseColor(colors.secondary) as string)
148
- .stroke({ color: parseColor(colors.tertiary) as string, width: 1 } as StrokeData);
149
-
150
- const offsetX = w - this.constants.SHAPES.Dogear!.Width;
151
- const offsetY = h - this.constants.SHAPES.Dogear!.Height;
152
- dogEar.move(offsetX, offsetY);
153
- dogEar.front();
154
- }
155
-
156
- /**
157
- * Draws previous and next connections for the node.
158
- * Previous connection is on top, next is on bottom.
159
- * @param state - Draw state
160
- * @param node - NodeSvg instance
161
- * @param nodeGroup - Node's SVG group
162
- * @param measurements - Node dimensions
163
- */
164
- drawPreviousNextConnections(state: DrawState, node: NodeSvg, nodeGroup: G, measurements: { width: number, height: number } | null = null) {
165
- if (!state || !node || !state.bg) return;
166
-
167
- const c = this.constants;
168
- const colors: ColorStyle = this.getNodeColors();
169
- const bbox = state.bg.bbox();
170
-
171
- // Top connector (previous)
172
- if (node.previousConnection) {
173
- const c1 = this.drawPrimaryConnector(nodeGroup, state.bg, 'top', parseColor(this._constants.CONNECTOR_COLOR) as string);
174
- if (c1) {
175
- const conn = {
176
- from: node.previousConnection,
177
- to: this.resolveConnectable(node.previousConnection.getFrom(), node.previousConnection) as Connection,
178
- fromCircle: c1 as SvgPath,
179
- originConn: node.previousConnection,
180
- originCircle: c1
181
- };
182
- this.setConnect(conn);
183
- eventer.addElement(c1, 'k_connectbubble', { connection: node.previousConnection, node })
184
- .tagElement(c1, [(this.constructor as typeof Renderer).ELEMENT_TAG, `node_${node.id}`]);
185
- this._fillOtherNodeConnectorCircle(node.previousConnection, c1 as SvgPath, true);
186
- }
187
- }
188
-
189
- // Bottom connector (next)
190
- if (node.nextConnection) {
191
- const c2 = this.drawPrimaryConnector(nodeGroup, state.bg, 'bottom', parseColor(this._constants.CONNECTOR_COLOR) as string);
192
- if (c2) {
193
- const conn = {
194
- from: node.nextConnection,
195
- to: this.resolveConnectable(node.nextConnection.getTo(), node.nextConnection) as Connection,
196
- fromCircle: c2 as SvgPath,
197
- originConn: node.nextConnection,
198
- originCircle: c2
199
- };
200
- this.setConnect(conn);
201
- eventer.addElement(c2, 'k_connectbubble', { connection: node.nextConnection, node })
202
- .tagElement(c2, [(this.constructor as typeof Renderer).ELEMENT_TAG, `node_${node.id}`]);
203
- this._fillOtherNodeConnectorCircle(node.nextConnection, c2 as SvgPath, false);
204
- }
205
- }
206
- }
207
-
208
- /**
209
- * Draws a primary connector (triangle or circle) on either the top or bottom edge.
210
- * @param nodeGroup - Node's SVG group
211
- * @param nodeBg - Node background path
212
- * @param side - 'top' or 'bottom'
213
- * @param color - Connector color
214
- * @returns SvgPath of the connector
215
- */
216
- drawPrimaryConnector(nodeGroup: G, nodeBg: SvgPath, side: 'top' | 'bottom', color: string): SvgPath | void {
217
- const c = this.constants;
218
- if (!nodeGroup || !nodeBg) return;
219
-
220
- const bbox = nodeBg.bbox();
221
- const triSize = c.CONNECTOR_TRI_SIZE;
222
- const radius = c.CONNECTOR_RADIUS;
223
- const x = bbox.width / 2;
224
- let y: number;
225
- let element: SvgPath;
226
-
227
- if (c.CONNECTOR_TRIANGLE) {
228
- let path = Path.roundedTri(triSize, triSize, 1);
229
- if (side === 'top') y = -triSize;
230
- else { y = bbox.height; path = Path.rotatePath(path, 180, triSize / 2, triSize / 2); }
231
-
232
- element = nodeGroup.path(path)
233
- .fill(parseColor(color as Hex))
234
- .stroke({ color: parseColor('#00000000'), width: 0 })
235
- .transform({ translateX: x - triSize / 2, translateY: y });
236
- } else {
237
- const circlePath = Path.circle(radius);
238
- y = side === 'top' ? 0 : bbox.height;
239
-
240
- element = nodeGroup.path(circlePath)
241
- .fill(parseColor(color as Hex))
242
- .stroke({ color: parseColor('#00000000'), width: 0 })
243
- .move(x - radius, y - radius);
244
- }
245
-
246
- element.attr({ class: (this.constructor as typeof Renderer).CONNECTOR_TAG });
247
- return element;
248
- }
249
- /**
250
- * Draws a raw input field.
251
- * @param fieldGroup - The SVG group element for the field.
252
- * @param field - The field to draw.
253
- * @param startX - The starting X position for the field.
254
- * @returns The rectangle and text elements of the raw field.
255
- */
256
- drawFieldRaw(fieldGroup: G, field: AnyField, startX: number = 0) {
257
- const c = this.constants;
258
- const value = field.getDisplayValue?.() ?? "";
259
- const { width, height } = this.measureRawField(value);
260
-
261
- // Draw the rectangle
262
- const rect = fieldGroup.rect(width, height)
263
- .fill(parseColor(c.FIELD_RAW_COLOR))
264
- .stroke({ color: parseColor(c.FIELD_RAW_OUTLINE_COLOR), width: c.FIELD_RAW_OUTLINE_STROKE })
265
- .radius(20);
266
-
267
- // Draw the text
268
- const txt = fieldGroup.text(value)
269
- .font({
270
- family: c.FONT_FAMILY,
271
- size: c.FONT_SIZE,
272
- anchor: 'start'
273
- })
274
- .fill(parseColor(c.FIELD_RAW_TEXT_COLOR));
275
- txt.node.style.userSelect = 'none';
276
-
277
- const rawBox: FieldRawBoxData = { box: rect, txt };
278
-
279
- // Measure text dimensions
280
- const textBBox = txt.bbox();
281
-
282
- // Vertical centering
283
- const offsetY = (height - textBBox.height) / 2;
284
-
285
- // Horizontal centering with padding
286
- const paddedWidth = width - 2 * c.INPUT_BOX_PADDING;
287
- const offsetX = startX + c.INPUT_BOX_PADDING + Math.max(0, (paddedWidth - textBBox.width) / 2);
288
-
289
- // Move elements
290
- rect.move(startX, 0);
291
- txt.move(offsetX, offsetY);
292
-
293
- // Add event listener
294
- eventer.addElement(rect, "k_inputbox", {
295
- field,
296
- text: txt,
297
- renderer: this,
298
- startX
299
- }).tagElement(rect, [(this.constructor as typeof Renderer).ELEMENT_TAG, `node_${this.node!.id}`]);
300
-
301
- return { rect, txt, rawBox };
302
- }
303
-
304
- /**
305
- * Draws the full node (base, topbar, fields, connectors, label, etc.)
306
- */
307
- drawNode() {
308
- if (!this.node) return;
309
-
310
- const colors = this.getNodeColors();
311
- const node = this.node;
312
- const state = this.drawState(this.createNodeGroup(node), node.id);
313
- this._nodeDraw = state;
314
-
315
- const measurements = this.measureNodeDimensions();
316
- if (!measurements) return;
317
-
318
- this.drawNodeBase(state, measurements as NodeMeasurements);
319
- this.drawNodeTopbar(state, colors, measurements as NodeMeasurements);
320
- this.drawNodeXButton();
321
- this.drawNodeLabel(state.group!);
322
- this.makeNodeDraggable(state.group!, state.topbar!, node);
323
-
324
- this.createFieldGroup(state);
325
- this.drawAllFieldsForNode(measurements as NodeMeasurements);
326
- this.drawPreviousNextConnections(state, node, state.group!, measurements as NodeMeasurements);
327
- }
328
- }
329
-
330
-
331
- export default ApolloRenderer;