@lazlon-platform/html-editor 0.7.2 → 0.7.3
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/hooks/batch.ts +39 -41
- package/lib/hooks/node.ts +3 -3
- package/package.json +1 -1
package/lib/hooks/batch.ts
CHANGED
|
@@ -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,
|
|
15
|
+
export function useNodeField<N extends Node, T>(
|
|
17
16
|
nodes: Iterable<N>,
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
fallback: T,
|
|
18
|
+
getter: (node: N) => T,
|
|
20
19
|
) {
|
|
21
|
-
return useComputed<
|
|
20
|
+
return useComputed<T>({
|
|
22
21
|
equals: isEqual,
|
|
23
22
|
fn: () => {
|
|
24
|
-
const values = Array.from(nodes).map((node) => node
|
|
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
|
|
40
|
+
const editor = useEditor()
|
|
42
41
|
const initial = useRef<Map<N, N[K]> | null>(null)
|
|
43
42
|
|
|
44
43
|
return {
|
|
45
|
-
value: useNodeField(nodes,
|
|
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
|
-
|
|
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
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
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
|
|
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
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
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
|
}
|
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,
|
|
7
|
-
const width = useNodeField(nodes,
|
|
8
|
-
const height = useNodeField(nodes,
|
|
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))
|