@lazlon-platform/html-editor 0.1.0 → 0.2.1

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 (42) hide show
  1. package/package.json +14 -11
  2. package/.claude/settings.local.json +0 -9
  3. package/.github/workflows/ci.yml +0 -34
  4. package/demo/App.tsx +0 -62
  5. package/demo/EditorView/PageView/NodeContent.tsx +0 -35
  6. package/demo/EditorView/PageView/SnapLines.tsx +0 -28
  7. package/demo/EditorView/PageView/index.tsx +0 -45
  8. package/demo/EditorView/SelectionFrame/Corner.tsx +0 -24
  9. package/demo/EditorView/SelectionFrame/Edge.tsx +0 -21
  10. package/demo/EditorView/SelectionFrame/index.tsx +0 -27
  11. package/demo/EditorView/SelectionOverlay/ActionHud.tsx +0 -32
  12. package/demo/EditorView/SelectionOverlay/Rotation.tsx +0 -39
  13. package/demo/EditorView/SelectionOverlay/Toolbar.tsx +0 -128
  14. package/demo/EditorView/SelectionOverlay/index.tsx +0 -21
  15. package/demo/EditorView/Toolbar/index.tsx +0 -68
  16. package/demo/EditorView/index.tsx +0 -47
  17. package/demo/Navbar/index.tsx +0 -33
  18. package/demo/Sidebar/index.tsx +0 -71
  19. package/demo/hotkeys.ts +0 -93
  20. package/demo/main.tsx +0 -10
  21. package/demo/style.css +0 -1
  22. package/eslint.config.js +0 -43
  23. package/index.html +0 -14
  24. package/tests/createTestEditor.ts +0 -19
  25. package/tests/hooks/actions.test.tsx +0 -736
  26. package/tests/hooks/batch.test.tsx +0 -332
  27. package/tests/hooks/editor.test.tsx +0 -56
  28. package/tests/hooks/page.test.tsx +0 -135
  29. package/tests/hooks/pointer/pointer.test.tsx +0 -244
  30. package/tests/hooks/textMarks.test.tsx +0 -624
  31. package/tests/model/editor.test.ts +0 -384
  32. package/tests/model/history.test.ts +0 -293
  33. package/tests/model/node/group.test.ts +0 -294
  34. package/tests/model/node/image.test.ts +0 -150
  35. package/tests/model/node/polygon.test.ts +0 -408
  36. package/tests/model/node/text.test.ts +0 -158
  37. package/tests/model/node.test.ts +0 -276
  38. package/tests/model/page.test.ts +0 -150
  39. package/tests/setup.ts +0 -7
  40. package/tsconfig.json +0 -28
  41. package/vite.config.ts +0 -9
  42. package/vitest.config.ts +0 -13
@@ -1,244 +0,0 @@
1
- import { act, renderHook } from "@testing-library/react"
2
- import { beforeEach, describe, expect, it, vi } from "vitest"
3
- import { usePointer } from "../../../lib/hooks/pointer/pointer"
4
-
5
- describe("usePointer", () => {
6
- function createPointerEvent(
7
- type: "pointerdown" | "pointermove" | "pointerup",
8
- props: Partial<React.PointerEvent> = {},
9
- ): React.PointerEvent {
10
- return {
11
- type,
12
- button: 0,
13
- clientX: 0,
14
- clientY: 0,
15
- ...props,
16
- } as unknown as React.PointerEvent
17
- }
18
-
19
- function createGlobalPointerEvent(
20
- type: "pointermove" | "pointerup" | "pointercancel",
21
- props: Partial<PointerEvent> = {},
22
- ): PointerEvent {
23
- return new PointerEvent(type, {
24
- clientX: props.clientX ?? 0,
25
- clientY: props.clientY ?? 0,
26
- ...props,
27
- })
28
- }
29
-
30
- beforeEach(() => {
31
- // Clear any existing listeners
32
- vi.clearAllMocks()
33
- })
34
-
35
- it("calls onDown handler on pointer down", () => {
36
- const onDown = vi.fn()
37
- const { result } = renderHook(() => usePointer({ onDown }))
38
-
39
- act(() => {
40
- result.current.onPointerDown(
41
- createPointerEvent("pointerdown", { clientX: 100, clientY: 100 }),
42
- )
43
- })
44
-
45
- expect(onDown).toHaveBeenCalledTimes(1)
46
- })
47
-
48
- it("does not proceed if onDown returns false", () => {
49
- const onDown = vi.fn(() => false)
50
- const onMove = vi.fn()
51
- const { result } = renderHook(() => usePointer({ onDown, onMove }))
52
-
53
- act(() => {
54
- result.current.onPointerDown(createPointerEvent("pointerdown"))
55
- })
56
-
57
- // Simulate global pointermove - should not trigger onMove
58
- act(() => {
59
- window.dispatchEvent(
60
- createGlobalPointerEvent("pointermove", { clientX: 50, clientY: 50 }),
61
- )
62
- })
63
-
64
- expect(onMove).not.toHaveBeenCalled()
65
- })
66
-
67
- it("ignores non-left-button clicks", () => {
68
- const onDown = vi.fn()
69
- const { result } = renderHook(() => usePointer({ onDown }))
70
-
71
- act(() => {
72
- result.current.onPointerDown(createPointerEvent("pointerdown", { button: 2 }))
73
- })
74
-
75
- expect(onDown).not.toHaveBeenCalled()
76
- })
77
-
78
- it("tracks moving state", () => {
79
- const { result } = renderHook(() => usePointer({}))
80
-
81
- expect(result.current.isMoving()).toBe(false)
82
-
83
- act(() => {
84
- result.current.onPointerDown(createPointerEvent("pointerdown"))
85
- })
86
-
87
- // Initially not moving
88
- expect(result.current.isMoving()).toBe(false)
89
-
90
- // After move, should be moving
91
- act(() => {
92
- window.dispatchEvent(
93
- createGlobalPointerEvent("pointermove", { clientX: 50, clientY: 50 }),
94
- )
95
- })
96
-
97
- expect(result.current.isMoving()).toBe(true)
98
-
99
- // After up, should not be moving
100
- act(() => {
101
- window.dispatchEvent(createGlobalPointerEvent("pointerup"))
102
- })
103
-
104
- expect(result.current.isMoving()).toBe(false)
105
- })
106
-
107
- it("calls onCancel when pointer up without move", () => {
108
- const onCancel = vi.fn()
109
- const onEnd = vi.fn()
110
- const { result } = renderHook(() => usePointer({ onCancel, onEnd }))
111
-
112
- act(() => {
113
- result.current.onPointerDown(createPointerEvent("pointerdown"))
114
- })
115
-
116
- // Simulate pointerup without pointermove
117
- act(() => {
118
- window.dispatchEvent(createGlobalPointerEvent("pointerup"))
119
- })
120
-
121
- expect(onCancel).toHaveBeenCalledTimes(1)
122
- expect(onEnd).not.toHaveBeenCalled()
123
- })
124
-
125
- it("calls onEnd when pointer up after move", () => {
126
- const onEnd = vi.fn()
127
- const onCancel = vi.fn()
128
- const { result } = renderHook(() => usePointer({ onEnd, onCancel }))
129
-
130
- act(() => {
131
- result.current.onPointerDown(createPointerEvent("pointerdown"))
132
- })
133
-
134
- // Simulate pointermove
135
- act(() => {
136
- window.dispatchEvent(
137
- createGlobalPointerEvent("pointermove", { clientX: 50, clientY: 50 }),
138
- )
139
- })
140
-
141
- // Simulate pointerup
142
- act(() => {
143
- window.dispatchEvent(
144
- createGlobalPointerEvent("pointerup", { clientX: 50, clientY: 50 }),
145
- )
146
- })
147
-
148
- expect(onEnd).toHaveBeenCalledTimes(1)
149
- expect(onCancel).not.toHaveBeenCalled()
150
- })
151
-
152
- it("provides start and current event to onMove", () => {
153
- const onMove = vi.fn()
154
- const { result } = renderHook(() => usePointer({ onMove }))
155
-
156
- act(() => {
157
- result.current.onPointerDown(
158
- createPointerEvent("pointerdown", { clientX: 10, clientY: 20 }),
159
- )
160
- })
161
-
162
- act(() => {
163
- window.dispatchEvent(
164
- createGlobalPointerEvent("pointermove", { clientX: 30, clientY: 40 }),
165
- )
166
- })
167
-
168
- expect(onMove).toHaveBeenCalledWith(
169
- expect.objectContaining({
170
- start: expect.objectContaining({ clientX: 10, clientY: 20 }),
171
- event: expect.objectContaining({ clientX: 30, clientY: 40 }),
172
- }),
173
- )
174
- })
175
-
176
- it("provides start and current event to onEnd", () => {
177
- const onEnd = vi.fn()
178
- const { result } = renderHook(() => usePointer({ onEnd }))
179
-
180
- act(() => {
181
- result.current.onPointerDown(
182
- createPointerEvent("pointerdown", { clientX: 10, clientY: 20 }),
183
- )
184
- })
185
-
186
- // Move first to trigger end instead of cancel
187
- act(() => {
188
- window.dispatchEvent(
189
- createGlobalPointerEvent("pointermove", { clientX: 50, clientY: 60 }),
190
- )
191
- })
192
-
193
- act(() => {
194
- window.dispatchEvent(
195
- createGlobalPointerEvent("pointerup", { clientX: 100, clientY: 120 }),
196
- )
197
- })
198
-
199
- expect(onEnd).toHaveBeenCalledWith(
200
- expect.objectContaining({
201
- start: expect.objectContaining({ clientX: 10, clientY: 20 }),
202
- event: expect.objectContaining({ clientX: 100, clientY: 120 }),
203
- }),
204
- )
205
- })
206
-
207
- it("calls onMove multiple times during drag", () => {
208
- const onMove = vi.fn()
209
- const { result } = renderHook(() => usePointer({ onMove }))
210
-
211
- act(() => {
212
- result.current.onPointerDown(createPointerEvent("pointerdown"))
213
- })
214
-
215
- act(() => {
216
- window.dispatchEvent(
217
- createGlobalPointerEvent("pointermove", { clientX: 10, clientY: 10 }),
218
- )
219
- window.dispatchEvent(
220
- createGlobalPointerEvent("pointermove", { clientX: 20, clientY: 20 }),
221
- )
222
- window.dispatchEvent(
223
- createGlobalPointerEvent("pointermove", { clientX: 30, clientY: 30 }),
224
- )
225
- })
226
-
227
- expect(onMove).toHaveBeenCalledTimes(3)
228
- })
229
-
230
- it("handles pointercancel like pointerup", () => {
231
- const onCancel = vi.fn()
232
- const { result } = renderHook(() => usePointer({ onCancel }))
233
-
234
- act(() => {
235
- result.current.onPointerDown(createPointerEvent("pointerdown"))
236
- })
237
-
238
- act(() => {
239
- window.dispatchEvent(createGlobalPointerEvent("pointercancel"))
240
- })
241
-
242
- expect(onCancel).toHaveBeenCalledTimes(1)
243
- })
244
- })