@lazlon-platform/html-editor 0.7.2 → 0.7.4

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.
@@ -1,7 +1,6 @@
1
1
  import { isEqual } from "es-toolkit"
2
2
  import { useRef } from "react"
3
3
  import { useComputed } from "react-bolt"
4
- import { type HistoryAction } from "../model/history"
5
4
  import { Node } from "../model/node"
6
5
  import { useEditor } from "./editor"
7
6
 
@@ -13,15 +12,15 @@ export function reduce<T>(values: T[], fallback: T) {
13
12
  )
14
13
  }
15
14
 
16
- export function useNodeField<N extends Node, K extends keyof N>(
15
+ export function useNodeField<N extends Node, T>(
17
16
  nodes: Iterable<N>,
18
- key: K,
19
- fallback: N[K],
17
+ fallback: T,
18
+ getter: (node: N) => T,
20
19
  ) {
21
- return useComputed<N[K]>({
20
+ return useComputed<T>({
22
21
  equals: isEqual,
23
22
  fn: () => {
24
- const values = Array.from(nodes).map((node) => node[key])
23
+ const values = Array.from(nodes).map((node) => getter(node))
25
24
  return reduce(values, fallback)
26
25
  },
27
26
  })
@@ -38,11 +37,11 @@ export function useNodeFieldBatch<N extends Node, K extends keyof N>(
38
37
  key: K,
39
38
  fallback: N[K],
40
39
  ): NodeFieldBatch<N, N[K]> {
41
- const { history } = useEditor()
40
+ const editor = useEditor()
42
41
  const initial = useRef<Map<N, N[K]> | null>(null)
43
42
 
44
43
  return {
45
- value: useNodeField(nodes, key, fallback),
44
+ value: useNodeField(nodes, fallback, (node) => node[key]),
46
45
  onChange(set: N[K] | ((node: N) => N[K])) {
47
46
  if (nodes.length === 0) return
48
47
 
@@ -51,7 +50,9 @@ export function useNodeFieldBatch<N extends Node, K extends keyof N>(
51
50
  }
52
51
 
53
52
  for (const node of nodes) {
54
- node[key] = typeof set === "function" ? (set as (node: N) => N[K])(node) : set
53
+ if (!node.locked) {
54
+ node[key] = typeof set === "function" ? (set as (node: N) => N[K])(node) : set
55
+ }
55
56
  }
56
57
  },
57
58
  onChangeEnd(end: N[K] | ((node: N) => N[K])) {
@@ -59,19 +60,21 @@ export function useNodeFieldBatch<N extends Node, K extends keyof N>(
59
60
 
60
61
  const init = initial.current || new Map(nodes.map((n) => [n, n[key]]))
61
62
 
62
- const prev: HistoryAction[] = []
63
- const next: HistoryAction[] = []
64
-
65
- for (const node of nodes) {
66
- const nextValue =
67
- typeof end === "function" ? (end as (node: N) => N[K])(node) : end
68
-
69
- prev.push(["set-node-props", [node.id, { [key]: init.get(node) }]])
70
- next.push(["set-node-props", [node.id, { [key]: nextValue }]])
71
- node[key] = nextValue
72
- }
63
+ editor.pushHistory(
64
+ nodes
65
+ .filter((node) => !node.locked)
66
+ .map((node) => {
67
+ const nextValue =
68
+ typeof end === "function" ? (end as (node: N) => N[K])(node) : end
69
+
70
+ node[key] = nextValue
71
+ return {
72
+ undo: ["set-node-props", [node.id, { [key]: init.get(node) }]],
73
+ redo: ["set-node-props", [node.id, { [key]: nextValue }]],
74
+ }
75
+ }),
76
+ )
73
77
 
74
- history.push({ undo: ["batch", prev], redo: ["batch", next] })
75
78
  initial.current = null
76
79
  },
77
80
  }
@@ -88,30 +91,25 @@ type Writable<T> = Pick<T, WritableKeys<T>>
88
91
  type Props<N> = Partial<Writable<{ [K in keyof N]: N[K] }>>
89
92
 
90
93
  export function useBatchSet() {
91
- const { history } = useEditor()
94
+ const editor = useEditor()
92
95
 
93
96
  return function batchSet<N extends Node>(
94
97
  nodes: Iterable<N>,
95
98
  set: Props<N> | ((n: N) => Props<N>),
96
99
  ) {
97
- const prev: HistoryAction[] = []
98
- const next: HistoryAction[] = []
99
-
100
- for (const node of nodes) {
101
- const nextValues = typeof set === "function" ? set(node) : set
102
- const keys = Object.keys(nextValues) as WritableKeys<N>[]
103
- const prevValues = Object.fromEntries(keys.map((key) => [key, node[key]]))
104
- prev.push(["set-node-props", [node.id, prevValues]])
105
- next.push(["set-node-props", [node.id, nextValues]])
106
- Object.assign(node, nextValues)
107
- }
108
-
109
- if (next.length > 1) {
110
- history.push({ undo: ["batch", prev], redo: ["batch", next] })
111
- } else if (next.length > 0) {
112
- const [undo] = prev
113
- const [redo] = next
114
- history.push({ undo, redo })
115
- }
100
+ editor.pushHistory(
101
+ Array.from(nodes)
102
+ .filter((node) => !node.locked)
103
+ .map((node) => {
104
+ const nextValues = typeof set === "function" ? set(node) : set
105
+ const keys = Object.keys(nextValues) as WritableKeys<N>[]
106
+ const prevValues = Object.fromEntries(keys.map((key) => [key, node[key]]))
107
+ Object.assign(node, nextValues)
108
+ return {
109
+ undo: ["set-node-props", [node.id, prevValues]],
110
+ redo: ["set-node-props", [node.id, nextValues]],
111
+ }
112
+ }),
113
+ )
116
114
  }
117
115
  }
@@ -10,7 +10,7 @@ export {
10
10
  useToggleLockAction,
11
11
  useTrashAction,
12
12
  } from "./actions"
13
- export { useBatchSet, useNodeField, useNodeFieldBatch } from "./batch"
13
+ export { reduce, useBatchSet, useNodeField, useNodeFieldBatch } from "./batch"
14
14
  export { EditorContext, PageContext, useEditor, usePage } from "./editor"
15
15
  export { useMoveable } from "./pointer/useMoveable"
16
16
  export { useMovePoint } from "./pointer/useMovePoint"
package/lib/hooks/node.ts CHANGED
@@ -3,9 +3,9 @@ import { box, boxBounds, deg } from "../model/geometry/math"
3
3
  import { useNodeField, useNodeFieldBatch } from "./batch"
4
4
 
5
5
  export function useVisualPositionBatch(nodes: Node[]) {
6
- const rotation = useNodeField(nodes, "rotation", deg(0))
7
- const width = useNodeField(nodes, "width", NaN)
8
- const height = useNodeField(nodes, "height", NaN)
6
+ const rotation = useNodeField(nodes, deg(0), (node) => node.rotation)
7
+ const width = useNodeField(nodes, NaN, (node) => node.width)
8
+ const height = useNodeField(nodes, NaN, (node) => node.height)
9
9
  const x = useNodeFieldBatch(nodes, "x", NaN)
10
10
  const y = useNodeFieldBatch(nodes, "y", NaN)
11
11
  const bounds = boxBounds(box({ x: x.value, y: y.value, width, height }, rotation))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lazlon-platform/html-editor",
3
- "version": "0.7.2",
3
+ "version": "0.7.4",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "lib"