@node-edit-utils/core 2.2.7 → 2.2.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 (34) hide show
  1. package/dist/lib/node-tools/events/click/handleNodeClick.d.ts +2 -1
  2. package/dist/lib/node-tools/events/setupEventListener.d.ts +2 -1
  3. package/dist/lib/node-tools/highlight/createCornerHandles.d.ts +1 -1
  4. package/dist/lib/node-tools/highlight/createHighlightFrame.d.ts +1 -1
  5. package/dist/lib/node-tools/highlight/createToolsContainer.d.ts +1 -1
  6. package/dist/lib/node-tools/select/selectNode.d.ts +2 -1
  7. package/dist/lib/node-tools/text/helpers/enterTextEditMode.d.ts +2 -0
  8. package/dist/lib/node-tools/text/helpers/handleTextChange.d.ts +1 -0
  9. package/dist/lib/node-tools/text/helpers/shouldEnterTextEditMode.d.ts +1 -0
  10. package/dist/node-edit-utils.cjs.js +217 -82
  11. package/dist/node-edit-utils.esm.js +217 -82
  12. package/dist/node-edit-utils.umd.js +217 -82
  13. package/dist/node-edit-utils.umd.min.js +1 -1
  14. package/dist/styles.css +1 -1
  15. package/package.json +1 -1
  16. package/src/index.ts +0 -2
  17. package/src/lib/node-tools/createNodeTools.ts +2 -16
  18. package/src/lib/node-tools/events/click/handleNodeClick.ts +3 -2
  19. package/src/lib/node-tools/events/setupEventListener.ts +3 -2
  20. package/src/lib/node-tools/highlight/clearHighlightFrame.ts +7 -2
  21. package/src/lib/node-tools/highlight/createCornerHandles.ts +12 -6
  22. package/src/lib/node-tools/highlight/createHighlightFrame.ts +25 -7
  23. package/src/lib/node-tools/highlight/createTagLabel.ts +25 -1
  24. package/src/lib/node-tools/highlight/createToolsContainer.ts +4 -1
  25. package/src/lib/node-tools/highlight/helpers/getHighlightFrameElement.ts +5 -1
  26. package/src/lib/node-tools/highlight/highlightNode.ts +17 -6
  27. package/src/lib/node-tools/highlight/refreshHighlightFrame.ts +37 -4
  28. package/src/lib/node-tools/highlight/updateHighlightFrameVisibility.ts +4 -1
  29. package/src/lib/node-tools/select/selectNode.ts +24 -5
  30. package/src/lib/node-tools/text/events/setupMutationObserver.ts +17 -3
  31. package/src/lib/node-tools/text/helpers/enterTextEditMode.ts +9 -0
  32. package/src/lib/node-tools/text/helpers/handleTextChange.ts +27 -0
  33. package/src/lib/node-tools/text/helpers/shouldEnterTextEditMode.ts +9 -0
  34. package/src/lib/styles/styles.css +23 -8
@@ -1,3 +1,5 @@
1
+ import { enterTextEditMode } from "../text/helpers/enterTextEditMode";
2
+ import type { NodeText } from "../text/types";
1
3
  import { IGNORED_DOM_ELEMENTS } from "./constants";
2
4
  import { getElementsFromPoint } from "./helpers/getElementsFromPoint";
3
5
  import { isInsideComponent } from "./helpers/isInsideComponent";
@@ -6,7 +8,9 @@ import { targetSameCandidates } from "./helpers/targetSameCandidates";
6
8
  let candidateCache: Element[] = [];
7
9
  let attempt = 0;
8
10
 
9
- export const selectNode = (event: MouseEvent, editableNode: HTMLElement | null): HTMLElement | null => {
11
+ let lastSelectedNode: HTMLElement | null = null;
12
+
13
+ export const selectNode = (event: MouseEvent, nodeProvider: HTMLElement | null, text: NodeText): HTMLElement | null => {
10
14
  let selectedNode: HTMLElement | null = null;
11
15
 
12
16
  const clickX = event.clientX;
@@ -21,19 +25,29 @@ export const selectNode = (event: MouseEvent, editableNode: HTMLElement | null):
21
25
  !isInsideComponent(element)
22
26
  );
23
27
 
28
+ const editableNode = text.getEditableNode();
24
29
  if (editableNode && candidates.includes(editableNode)) {
25
- return editableNode;
30
+ selectedNode = editableNode;
31
+ lastSelectedNode = selectedNode;
32
+
33
+ return selectedNode;
26
34
  }
27
35
 
28
36
  if (clickThrough) {
29
37
  candidateCache = [];
30
-
31
38
  selectedNode = candidates[0] as HTMLElement;
39
+
40
+ if (lastSelectedNode && lastSelectedNode === selectedNode) {
41
+ enterTextEditMode(selectedNode, nodeProvider, text);
42
+ }
43
+
44
+ lastSelectedNode = selectedNode;
45
+
32
46
  return selectedNode;
33
47
  }
34
48
 
35
49
  if (targetSameCandidates(candidateCache, candidates)) {
36
- attempt <= candidates.length && attempt++;
50
+ attempt <= candidates.length - 2 && attempt++;
37
51
  } else {
38
52
  attempt = 0;
39
53
  }
@@ -41,8 +55,13 @@ export const selectNode = (event: MouseEvent, editableNode: HTMLElement | null):
41
55
  const nodeIndex = candidates.length - 1 - attempt;
42
56
 
43
57
  selectedNode = candidates[nodeIndex] as HTMLElement;
44
-
45
58
  candidateCache = candidates;
46
59
 
60
+ if (lastSelectedNode && lastSelectedNode === selectedNode) {
61
+ enterTextEditMode(selectedNode, nodeProvider, text);
62
+ }
63
+
64
+ lastSelectedNode = selectedNode;
65
+
47
66
  return selectedNode;
48
67
  };
@@ -1,10 +1,24 @@
1
1
  import { connectMutationObserver } from "../../../helpers/observer/connectMutationObserver";
2
+ import { withRAFThrottle } from "../../../helpers/withRAF";
2
3
  import { refreshHighlightFrame } from "../../highlight/refreshHighlightFrame";
4
+ import { handleTextChange } from "../helpers/handleTextChange";
3
5
 
4
- export const setupMutationObserver = (node: HTMLElement, nodeProvider: HTMLElement, canvasName: string = "canvas"): (() => void) | undefined => {
5
- const mutationObserver = connectMutationObserver(node, () => {
6
+ export const setupMutationObserver = (
7
+ node: HTMLElement,
8
+ nodeProvider: HTMLElement,
9
+ canvasName: string = "canvas"
10
+ ): (() => void) | undefined => {
11
+ const throttledHandleTextChange = withRAFThrottle((mutations: MutationRecord[]) => {
12
+ handleTextChange(node, mutations);
13
+ });
14
+
15
+ const mutationObserver = connectMutationObserver(node, (mutations) => {
16
+ throttledHandleTextChange(mutations);
6
17
  refreshHighlightFrame(node, nodeProvider, canvasName);
7
18
  });
8
19
 
9
- return () => mutationObserver.disconnect();
20
+ return () => {
21
+ mutationObserver.disconnect();
22
+ throttledHandleTextChange.cleanup();
23
+ };
10
24
  };
@@ -0,0 +1,9 @@
1
+ import type { NodeText } from "../types";
2
+
3
+ export const enterTextEditMode = (node: HTMLElement, nodeProvider: HTMLElement | null, text: NodeText): void => {
4
+ if (!node || !nodeProvider) {
5
+ return;
6
+ }
7
+
8
+ text.enableEditMode(node, nodeProvider);
9
+ };
@@ -0,0 +1,27 @@
1
+ import { sendPostMessage } from "@/lib/post-message/sendPostMessage";
2
+
3
+ export const handleTextChange = (node: HTMLElement, mutations: MutationRecord[]): void => {
4
+ // Check if any mutation is a text content change
5
+ const hasTextChange = mutations.some((mutation) => {
6
+ return (
7
+ mutation.type === "characterData" ||
8
+ (mutation.type === "childList" && (mutation.addedNodes.length > 0 || mutation.removedNodes.length > 0))
9
+ );
10
+ });
11
+
12
+ if (!hasTextChange) {
13
+ return;
14
+ }
15
+
16
+ // Get the text content of the node
17
+ const textContent = node.textContent ?? "";
18
+
19
+ // Get the node ID
20
+ const nodeId = node.getAttribute("data-node-id");
21
+
22
+ // Send postMessage with the text change
23
+ sendPostMessage("textContentChanged", {
24
+ nodeId,
25
+ textContent,
26
+ });
27
+ };
@@ -0,0 +1,9 @@
1
+ import { hasTextContent } from "./hasTextContent";
2
+
3
+ export const shouldEnterTextEditMode = (node: HTMLElement | null): boolean => {
4
+ if (!node) {
5
+ return false;
6
+ }
7
+
8
+ return hasTextContent(node);
9
+ };
@@ -2,6 +2,8 @@
2
2
  --primary-color: oklch(0.6235 0.22 294);
3
3
  --uncode-color: oklch(45.7% 0.24 277.023);
4
4
  --component-color: oklch(65.6% 0.241 354.308);
5
+ --text-edit-color: oklch(62.3% 0.214 259.815);
6
+ --text-edit-selection-color: oklch(62.3% 0.214 259.815 / 0.2);
5
7
 
6
8
  --handle-color: oklch(55.2% 0.016 285.938);
7
9
  --handle-color-transparent: oklch(55.2% 0.016 285.938 / 0.7);
@@ -19,7 +21,7 @@
19
21
  --transition-medium: 0.2s ease-in-out;
20
22
 
21
23
  --z-index-high: 10000;
22
- --z-index-highlight: 5000;
24
+ --z-index-highlight: 500;
23
25
  --z-index-medium: 1000;
24
26
 
25
27
  --letter-spacing: 0.02em;
@@ -58,7 +60,7 @@
58
60
  }
59
61
 
60
62
  .highlight-frame-overlay {
61
- position: fixed;
63
+ position: absolute;
62
64
  inset: 0;
63
65
  width: 100vw;
64
66
  height: 100vh;
@@ -79,6 +81,10 @@
79
81
  stroke: var(--component-color);
80
82
  }
81
83
 
84
+ .highlight-frame-overlay.is-text-edit .highlight-frame-rect {
85
+ stroke: var(--text-edit-color);
86
+ }
87
+
82
88
  .highlight-frame-handle {
83
89
  fill: white;
84
90
  stroke: var(--primary-color);
@@ -91,6 +97,10 @@
91
97
  stroke: var(--component-color);
92
98
  }
93
99
 
100
+ .highlight-frame-overlay.is-text-edit .highlight-frame-handle {
101
+ stroke: var(--text-edit-color);
102
+ }
103
+
94
104
  .highlight-frame-handle.handle-top-left {
95
105
  cursor: nwse-resize;
96
106
  }
@@ -108,7 +118,7 @@
108
118
  }
109
119
 
110
120
  .highlight-frame-tools-wrapper {
111
- position: fixed;
121
+ position: absolute;
112
122
  left: 0;
113
123
  top: 0;
114
124
  pointer-events: none;
@@ -121,14 +131,14 @@
121
131
  color: var(--text-color-white);
122
132
  font-size: 0.575rem;
123
133
  font-weight: 500;
124
- text-transform: uppercase;
125
134
  height: 1rem;
126
135
  padding: 0.5625rem var(--spacing-sm);
127
- line-height: 1;
136
+ line-height: 1.4;
128
137
  border-radius: var(--spacing-sm);
129
138
  display: flex;
130
139
  align-items: center;
131
140
  justify-content: center;
141
+ white-space: nowrap;
132
142
  }
133
143
 
134
144
  .highlight-frame-tools-wrapper.is-instance .tag-label,
@@ -136,6 +146,11 @@
136
146
  background-color: var(--component-color);
137
147
  }
138
148
 
149
+ .highlight-frame-tools-wrapper.is-text-edit .tag-label,
150
+ .node-tools.is-text-edit .tag-label {
151
+ background-color: var(--text-edit-color);
152
+ }
153
+
139
154
  .viewport {
140
155
  position: relative;
141
156
  width: var(--container-width);
@@ -233,14 +248,14 @@
233
248
  user-select: text;
234
249
 
235
250
  &::selection {
236
- background: var(--primary-color-selection);
251
+ background: var(--text-edit-selection-color);
237
252
  }
238
253
 
239
254
  &::-moz-selection {
240
- background: var(--primary-color-selection);
255
+ background: var(--text-edit-selection-color);
241
256
  }
242
257
 
243
258
  &::-webkit-selection {
244
- background: var(--primary-color-selection);
259
+ background: var(--text-edit-selection-color);
245
260
  }
246
261
  }