seat-editor 2.0.0 → 2.1.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 (101) hide show
  1. package/package.json +1 -1
  2. package/dist/app/constant.d.ts +0 -101
  3. package/dist/app/constant.js +0 -3064
  4. package/dist/app/layout.d.ts +0 -6
  5. package/dist/app/layout.jsx +0 -27
  6. package/dist/app/new-board/page.d.ts +0 -1
  7. package/dist/app/new-board/page.jsx +0 -56
  8. package/dist/app/old-board/page.d.ts +0 -3
  9. package/dist/app/old-board/page.jsx +0 -510
  10. package/dist/app/only-view/constant.d.ts +0 -40
  11. package/dist/app/only-view/constant.js +0 -1336
  12. package/dist/app/only-view/page.d.ts +0 -2
  13. package/dist/app/only-view/page.jsx +0 -40
  14. package/dist/app/page.d.ts +0 -2
  15. package/dist/app/page.jsx +0 -13
  16. package/dist/app/test/page.d.ts +0 -2
  17. package/dist/app/test/page.jsx +0 -45
  18. package/dist/app/v2/page.d.ts +0 -2
  19. package/dist/app/v2/page.jsx +0 -13
  20. package/dist/components/button-tools/index.d.ts +0 -11
  21. package/dist/components/button-tools/index.jsx +0 -17
  22. package/dist/components/form-tools/label.d.ts +0 -2
  23. package/dist/components/form-tools/label.jsx +0 -44
  24. package/dist/components/form-tools/shape.d.ts +0 -4
  25. package/dist/components/form-tools/shape.jsx +0 -66
  26. package/dist/components/input/number-indicator.d.ts +0 -7
  27. package/dist/components/input/number-indicator.jsx +0 -36
  28. package/dist/components/joystick/index.d.ts +0 -12
  29. package/dist/components/joystick/index.jsx +0 -49
  30. package/dist/components/layer/index.d.ts +0 -19
  31. package/dist/components/layer/index.jsx +0 -383
  32. package/dist/components/layer-v2/index.d.ts +0 -19
  33. package/dist/components/layer-v2/index.jsx +0 -370
  34. package/dist/components/layer-v3/index.d.ts +0 -19
  35. package/dist/components/layer-v3/index.jsx +0 -418
  36. package/dist/components/lib/index.d.ts +0 -8
  37. package/dist/components/lib/index.jsx +0 -33
  38. package/dist/components/modal-preview/index.d.ts +0 -4
  39. package/dist/components/modal-preview/index.jsx +0 -11
  40. package/dist/features/board/board-slice.d.ts +0 -14
  41. package/dist/features/board/board-slice.js +0 -52
  42. package/dist/features/board/index.d.ts +0 -6
  43. package/dist/features/board/index.jsx +0 -725
  44. package/dist/features/board-v2/board-slice.d.ts +0 -14
  45. package/dist/features/board-v2/board-slice.js +0 -52
  46. package/dist/features/board-v2/index.d.ts +0 -8
  47. package/dist/features/board-v2/index.jsx +0 -869
  48. package/dist/features/board-v3/board-slice.d.ts +0 -16
  49. package/dist/features/board-v3/board-slice.js +0 -83
  50. package/dist/features/board-v3/history-slice.d.ts +0 -27
  51. package/dist/features/board-v3/history-slice.js +0 -27
  52. package/dist/features/board-v3/index.d.ts +0 -8
  53. package/dist/features/board-v3/index.jsx +0 -863
  54. package/dist/features/navbar/index.d.ts +0 -2
  55. package/dist/features/navbar/index.jsx +0 -5
  56. package/dist/features/package/index.d.ts +0 -31
  57. package/dist/features/package/index.jsx +0 -114
  58. package/dist/features/panel/index.d.ts +0 -11
  59. package/dist/features/panel/index.jsx +0 -138
  60. package/dist/features/panel/panel-slice.d.ts +0 -16
  61. package/dist/features/panel/panel-slice.js +0 -31
  62. package/dist/features/panel/select-tool.d.ts +0 -6
  63. package/dist/features/panel/select-tool.jsx +0 -60
  64. package/dist/features/panel/square-circle-tool.d.ts +0 -2
  65. package/dist/features/panel/square-circle-tool.jsx +0 -10
  66. package/dist/features/panel/table-seat-circle.d.ts +0 -2
  67. package/dist/features/panel/table-seat-circle.jsx +0 -31
  68. package/dist/features/panel/text-tool.d.ts +0 -2
  69. package/dist/features/panel/text-tool.jsx +0 -26
  70. package/dist/features/panel/upload-tool.d.ts +0 -14
  71. package/dist/features/panel/upload-tool.jsx +0 -152
  72. package/dist/features/side-tool/index.d.ts +0 -8
  73. package/dist/features/side-tool/index.jsx +0 -371
  74. package/dist/features/side-tool/side-tool-slice.d.ts +0 -16
  75. package/dist/features/side-tool/side-tool-slice.js +0 -28
  76. package/dist/features/theme/theme-slice.d.ts +0 -12
  77. package/dist/features/theme/theme-slice.js +0 -15
  78. package/dist/features/view/index.d.ts +0 -19
  79. package/dist/features/view/index.jsx +0 -228
  80. package/dist/features/view-only/index.d.ts +0 -19
  81. package/dist/features/view-only/index.jsx +0 -206
  82. package/dist/features/view-only-2/index.d.ts +0 -19
  83. package/dist/features/view-only-2/index.jsx +0 -181
  84. package/dist/hooks/use-redux.d.ts +0 -4
  85. package/dist/hooks/use-redux.js +0 -3
  86. package/dist/index.d.ts +0 -8
  87. package/dist/index.js +0 -8
  88. package/dist/libs/middleware.d.ts +0 -2
  89. package/dist/libs/middleware.js +0 -5
  90. package/dist/libs/rootReducer.d.ts +0 -12
  91. package/dist/libs/rootReducer.js +0 -14
  92. package/dist/libs/store.d.ts +0 -18
  93. package/dist/libs/store.js +0 -19
  94. package/dist/provider/antd-provider.d.ts +0 -4
  95. package/dist/provider/antd-provider.jsx +0 -46
  96. package/dist/provider/redux-provider.d.ts +0 -3
  97. package/dist/provider/redux-provider.jsx +0 -6
  98. package/dist/provider/store-provider.d.ts +0 -4
  99. package/dist/provider/store-provider.jsx +0 -10
  100. package/dist/utils/injectCss.d.ts +0 -1
  101. package/dist/utils/injectCss.js +0 -13
@@ -1,725 +0,0 @@
1
- "use client";
2
- import { useCallback, useEffect, useRef, useState } from "react";
3
- import { TransformWrapper, TransformComponent, MiniMap, } from "react-zoom-pan-pinch";
4
- import { useAppSelector, useAppDispatch } from "../../hooks/use-redux";
5
- import Layers from "../../components/layer";
6
- import { throttle } from "lodash";
7
- import ModalPreview from "../../components/modal-preview";
8
- import LayerView from "../view";
9
- import { isEqual, debounce } from "lodash";
10
- import { ZoomIn, ZoomOut } from "lucide-react";
11
- import { Button } from "antd";
12
- const BoardTemplate = ({ onSelectComponent }) => {
13
- const dispatch = useAppDispatch();
14
- const theme = useAppSelector((state) => state.theme);
15
- const transformRef = useRef(null);
16
- const containerRef = useRef(null);
17
- const [widthBoard, setWidthBoard] = useState(0);
18
- const [heightBoard, setHeightBoard] = useState(0);
19
- const svgRef = useRef(null);
20
- const [shadowShape, setShadowShape] = useState([]);
21
- const [startPoint, setStartPoint] = useState(null);
22
- const [dragOffset, setDragOffset] = useState({ x: 0, y: 0 });
23
- // const [moveComponent, setMoveComponent] = useState(false);
24
- const [scale, setScale] = useState(1);
25
- const activeTool = useAppSelector((state) => state.tool.active);
26
- const grid = useAppSelector((state) => state.tool.grid);
27
- const { components: componentsProps, extraComponents: extraComponentsProps, flagChange, } = useAppSelector((state) => state.board);
28
- const isTouching = useRef(false);
29
- useEffect(() => {
30
- var _a;
31
- if (activeTool !== ((_a = shadowShape[0]) === null || _a === void 0 ? void 0 : _a.shape)) {
32
- setShadowShape([]);
33
- }
34
- }, [activeTool]);
35
- // const [isDragging, setIsDragging] = useState(false);
36
- const [resizeDirection, setResizeDirection] = useState(null);
37
- const backgroundColor = useAppSelector((state) => state.board.backgroundColor);
38
- const selectedComponentProps = useAppSelector((state) => state.panel.selectedComponent);
39
- const screenCTMRef = useRef(null);
40
- const dragIndex = useRef(null);
41
- const [componentsState, setComponentsState] = useState([]);
42
- const [extraComponentsState, setExtraComponentsState] = useState([]);
43
- const [selectedComponent, setSelectedComponent] = useState(null);
44
- const isSyncingFromRedux = useRef(false);
45
- const startPos = useRef({ x: 0, y: 0 });
46
- const isDragging = useRef(false);
47
- const moveComponent = useRef(false);
48
- const debouncedSyncToReduxSelected = useRef(debounce((data) => {
49
- throttledDispatch(data);
50
- }, 300)).current;
51
- const debouncedSyncComponents = useRef(debounce((data) => {
52
- dispatch({
53
- type: "board/setNewComponents",
54
- payload: data,
55
- });
56
- }, 300));
57
- const debouncedSyncExtraComponents = useRef(debounce((data) => {
58
- dispatch({
59
- type: "board/setNewExtraComponents",
60
- payload: data,
61
- });
62
- }, 300));
63
- // Redux → Local
64
- useEffect(() => {
65
- if (flagChange) {
66
- if (!isEqual(componentsProps, componentsState)) {
67
- isSyncingFromRedux.current = true;
68
- setComponentsState(componentsProps !== null && componentsProps !== void 0 ? componentsProps : []);
69
- }
70
- if (!isEqual(extraComponentsProps, extraComponentsState)) {
71
- isSyncingFromRedux.current = true;
72
- setExtraComponentsState(extraComponentsProps !== null && extraComponentsProps !== void 0 ? extraComponentsProps : []);
73
- }
74
- if (!isEqual(selectedComponentProps, selectedComponent)) {
75
- isSyncingFromRedux.current = true;
76
- setSelectedComponent(selectedComponentProps !== null && selectedComponentProps !== void 0 ? selectedComponentProps : []);
77
- }
78
- dispatch({ type: "board/setFlagChange", payload: false });
79
- }
80
- }, [
81
- componentsProps,
82
- extraComponentsProps,
83
- selectedComponentProps,
84
- flagChange,
85
- ]);
86
- // Local → Redux
87
- useEffect(() => {
88
- if (isSyncingFromRedux.current) {
89
- isSyncingFromRedux.current = false;
90
- return;
91
- }
92
- if (!isEqual(componentsState, componentsProps) &&
93
- !isEqual(componentsState, [])) {
94
- debouncedSyncComponents.current(componentsState);
95
- }
96
- if (!isEqual(extraComponentsState, extraComponentsProps) && !isEqual(extraComponentsState, [])) {
97
- debouncedSyncExtraComponents.current(extraComponentsState);
98
- }
99
- }, [componentsState, extraComponentsState]);
100
- const handleAddComponent = (shape) => {
101
- dispatch({
102
- type: activeTool === "text"
103
- ? "board/setExtraComponent"
104
- : "board/addComponent",
105
- payload: Object.assign(Object.assign({}, shape), { fill: theme === null || theme === void 0 ? void 0 : theme.primaryColor }),
106
- });
107
- const payload = Object.assign(Object.assign({}, shape), { fill: theme === null || theme === void 0 ? void 0 : theme.primaryColor });
108
- if (activeTool === "text") {
109
- setExtraComponentsState((prev) => [...prev, payload]);
110
- }
111
- else {
112
- setComponentsState((prev) => [...prev, payload]);
113
- }
114
- };
115
- const getSvgCoords = (e) => {
116
- var _a;
117
- const svg = svgRef.current;
118
- const point = svg.createSVGPoint();
119
- point.x = e.clientX;
120
- point.y = e.clientY;
121
- const transformed = point.matrixTransform((_a = svg.getScreenCTM()) === null || _a === void 0 ? void 0 : _a.inverse());
122
- return { x: transformed.x, y: transformed.y };
123
- };
124
- const createShape = (x, y, fill) => ({
125
- x,
126
- y,
127
- width: 50,
128
- height: 50,
129
- shape: activeTool,
130
- id: Date.now(),
131
- fill,
132
- rotation: activeTool === "diamond" ? 45 : 0,
133
- seatCount: activeTool === "table-seat-circle" ? 6 : 0,
134
- openSpace: activeTool === "table-seat-circle" ? 0 : undefined,
135
- seatFill: activeTool === "table-seat-circle" ? "#DADADA" : undefined,
136
- text: activeTool === "text" ? "Text" : "",
137
- fontColor: activeTool === "text" ? "#DADADA" : undefined,
138
- });
139
- const handleMouseDown = (e, item, direction) => {
140
- if (activeTool === "select" && item && !direction) {
141
- startPos.current = { x: e.clientX, y: e.clientY };
142
- const rectBox = (e === null || e === void 0 ? void 0 : e.target).getBoundingClientRect();
143
- setDragOffset({
144
- x: e.clientX - rectBox.left + ((item === null || item === void 0 ? void 0 : item.strokeWidth) || 0),
145
- y: e.clientY - rectBox.top + ((item === null || item === void 0 ? void 0 : item.strokeWidth) || 0),
146
- });
147
- const handleMouseMove = (event) => {
148
- const dx = Math.abs(event.clientX - startPos.current.x);
149
- const dy = Math.abs(event.clientY - startPos.current.y);
150
- if (dx > 1 || dy > 1) {
151
- if (!moveComponent.current && item) {
152
- dispatch({ type: "panel/setSelectedComponent", payload: item });
153
- setSelectedComponent(item);
154
- }
155
- moveComponent.current = true;
156
- }
157
- };
158
- const handleMouseUp = () => {
159
- document.removeEventListener("mousemove", handleMouseMove);
160
- document.removeEventListener("mouseup", handleMouseUp);
161
- if (moveComponent.current) {
162
- moveComponent.current = false;
163
- }
164
- else {
165
- isDragging.current = true;
166
- moveComponent.current = false;
167
- setResizeDirection(direction);
168
- if (item) {
169
- dispatch({ type: "panel/setSelectedComponent", payload: item });
170
- dispatch({ type: "panel/setShow", payload: true });
171
- setSelectedComponent(item);
172
- }
173
- }
174
- };
175
- // Pasang ke `document` agar global
176
- document.addEventListener("mousemove", handleMouseMove);
177
- document.addEventListener("mouseup", handleMouseUp);
178
- }
179
- if (activeTool === "select" && direction) {
180
- setResizeDirection(direction);
181
- }
182
- };
183
- const handleMouseEnter = () => {
184
- if (![
185
- "square",
186
- "circle",
187
- "diamond",
188
- "table-seat-circle",
189
- "table-seat-square",
190
- "text",
191
- ].includes(activeTool))
192
- return;
193
- };
194
- const handleMouseLeave = () => {
195
- if (![
196
- "square",
197
- "circle",
198
- "diamond",
199
- "table-seat-circle",
200
- "table-seat-square",
201
- "text",
202
- ].includes(activeTool))
203
- return;
204
- setShadowShape([]);
205
- };
206
- const handleMouseClick = (e) => {
207
- if (activeTool === "select" && selectedComponent) {
208
- handleUnSelectComponent();
209
- return;
210
- }
211
- if (![
212
- "square",
213
- "circle",
214
- "diamond",
215
- "table-seat-circle",
216
- "table-seat-square",
217
- "text",
218
- ].includes(activeTool)) {
219
- return;
220
- }
221
- const { x, y } = getSvgCoords(e);
222
- setStartPoint({ x, y });
223
- handleAddComponent(createShape(x, y, theme === null || theme === void 0 ? void 0 : theme.primaryColor));
224
- };
225
- const throttledDispatch = useCallback(throttle((component) => {
226
- // dispatch({
227
- // type: "board/updateComponent",
228
- // payload: component,
229
- // });
230
- dispatch({
231
- type: "panel/updateSelectedComponent",
232
- payload: component,
233
- });
234
- }, 16), // 16ms ≈ 60fps
235
- [dispatch]);
236
- const handleMouseMove = (e) => {
237
- if ([
238
- "square",
239
- "circle",
240
- "diamond",
241
- "table-seat-circle",
242
- "table-seat-square",
243
- "text",
244
- "ruler",
245
- ].includes(activeTool)) {
246
- const { x, y } = getSvgCoords(e);
247
- setShadowShape([createShape(x, y, theme === null || theme === void 0 ? void 0 : theme.primaryColor)]);
248
- return;
249
- }
250
- if (activeTool === "select" &&
251
- selectedComponent &&
252
- moveComponent.current &&
253
- dragOffset &&
254
- // !isTouching.current &&
255
- !resizeDirection) {
256
- const workspaceRect = e.currentTarget.getBoundingClientRect();
257
- const newX = e.clientX - workspaceRect.left - (dragOffset === null || dragOffset === void 0 ? void 0 : dragOffset.x);
258
- const newY = e.clientY - workspaceRect.top - (dragOffset === null || dragOffset === void 0 ? void 0 : dragOffset.y);
259
- let newPosition = {
260
- x: newX / scale,
261
- y: newY / scale,
262
- };
263
- requestAnimationFrame(() => {
264
- setComponentsState((prev) => {
265
- return prev.map((component) => {
266
- if (component.id === selectedComponent.id) {
267
- return Object.assign(Object.assign({}, component), { x: newPosition.x, y: newPosition.y });
268
- }
269
- return component;
270
- });
271
- });
272
- setExtraComponentsState((prev) => {
273
- return prev.map((component) => {
274
- if (component.id === selectedComponent.id) {
275
- return Object.assign(Object.assign({}, component), { x: newPosition.x, y: newPosition.y });
276
- }
277
- return component;
278
- });
279
- });
280
- setSelectedComponent((prev) => {
281
- return Object.assign(Object.assign({}, prev), { x: newPosition.x, y: newPosition.y });
282
- });
283
- });
284
- debouncedSyncToReduxSelected(Object.assign(Object.assign({}, selectedComponent), newPosition));
285
- return;
286
- }
287
- if (activeTool === "select" && resizeDirection) {
288
- const workspaceRect = e.currentTarget.getBoundingClientRect();
289
- const currentX = e.clientX - workspaceRect.left;
290
- const currentY = e.clientY - workspaceRect.top;
291
- const { x, y, width, height } = selectedComponent;
292
- let newShape = Object.assign({}, selectedComponent);
293
- if (!["table-seat-circle", "table-seat-square"].includes(selectedComponent.shape)) {
294
- switch (resizeDirection) {
295
- case "top-left":
296
- newShape.width = width + (x - currentX);
297
- newShape.height = height + (y - currentY);
298
- newShape.x = currentX;
299
- newShape.y = currentY;
300
- break;
301
- case "top-right":
302
- newShape.width = currentX - newShape.x;
303
- newShape.height = newShape.height + (newShape.y - currentY);
304
- newShape.y = currentY;
305
- break;
306
- case "bottom-left":
307
- newShape.width += newShape.x - currentX;
308
- newShape.height = currentY - newShape.y;
309
- newShape.x = currentX;
310
- break;
311
- case "bottom-right":
312
- newShape.width = currentX - newShape.x;
313
- newShape.height = currentY - newShape.y;
314
- break;
315
- case "left-center":
316
- newShape.width += newShape.x - currentX;
317
- newShape.x = currentX;
318
- break;
319
- case "right-center":
320
- newShape.width = currentX - newShape.x;
321
- break;
322
- case "top-center":
323
- newShape.height += newShape.y - currentY;
324
- newShape.y = currentY;
325
- break;
326
- case "bottom-center":
327
- newShape.height = currentY - newShape.y;
328
- break;
329
- default:
330
- break;
331
- }
332
- }
333
- else if (["table-seat-circle", "table-seat-square"].includes(selectedComponent.shape)) {
334
- switch (resizeDirection) {
335
- case "top-left":
336
- newShape.width = width + (x - currentX);
337
- newShape.height = height + (y - currentY);
338
- newShape.x = currentX;
339
- newShape.y = currentY;
340
- break;
341
- case "top-right":
342
- newShape.width = currentX - newShape.x;
343
- newShape.height = newShape.height + (newShape.y - currentY);
344
- newShape.y = currentY;
345
- break;
346
- case "bottom-left":
347
- newShape.width += newShape.x - currentX;
348
- newShape.height = currentY - newShape.y;
349
- newShape.x = currentX;
350
- break;
351
- case "bottom-right":
352
- newShape.width = currentX - newShape.x;
353
- newShape.height = currentY - newShape.y;
354
- break;
355
- default:
356
- break;
357
- }
358
- }
359
- // updateComponentRef({
360
- // ...(typeof selectedComponent === "object" && selectedComponent !== null
361
- // ? selectedComponent
362
- // : {}),
363
- // ...newShape,
364
- // });
365
- requestAnimationFrame(() => {
366
- setComponentsState((prev) => {
367
- return prev.map((component) => {
368
- if (component.id === selectedComponent.id) {
369
- return Object.assign(Object.assign({}, component), newShape);
370
- }
371
- return component;
372
- });
373
- });
374
- setExtraComponentsState((prev) => {
375
- return prev.map((component) => {
376
- if (component.id === selectedComponent.id) {
377
- return Object.assign(Object.assign({}, component), newShape);
378
- }
379
- return component;
380
- });
381
- });
382
- setSelectedComponent(newShape);
383
- });
384
- debouncedSyncToReduxSelected(newShape);
385
- }
386
- };
387
- const handleMouseUp = () => {
388
- if (activeTool === "select" && selectedComponent && isDragging.current) {
389
- setResizeDirection(null);
390
- }
391
- };
392
- useEffect(() => {
393
- if (containerRef.current) {
394
- setWidthBoard(containerRef.current.offsetWidth);
395
- setHeightBoard(containerRef.current.offsetHeight);
396
- }
397
- });
398
- const handleUnSelectComponent = () => {
399
- dispatch({ type: "panel/setSelectedComponent", payload: null });
400
- setSelectedComponent(null);
401
- dispatch({ type: "panel/setShow", payload: true });
402
- };
403
- const handleTouchStart = (e, items, direction) => {
404
- var _a, _b, _c, _d;
405
- if (activeTool === "select" && !direction && items) {
406
- // dispatch({ type: "panel/setShow", payload: false });
407
- // setMoveComponent(true);
408
- moveComponent.current = true;
409
- isTouching.current = true;
410
- // dispatch({ type: "panel/setSelectedComponent", payload: item });
411
- onSelectComponent && onSelectComponent(items);
412
- dispatch({ type: "panel/setSelectedComponent", payload: items });
413
- setSelectedComponent(items);
414
- // selectedComponentRef.current = items;
415
- const touch = e.touches[0];
416
- const svg = e.currentTarget.ownerSVGElement;
417
- const pt = svg.createSVGPoint();
418
- if (!svg)
419
- return;
420
- pt.x = touch.clientX;
421
- pt.y = touch.clientY;
422
- const cursorpt = pt.matrixTransform((_a = svg.getScreenCTM()) === null || _a === void 0 ? void 0 : _a.inverse());
423
- screenCTMRef.current = ((_b = svg.getScreenCTM()) === null || _b === void 0 ? void 0 : _b.inverse()) || null;
424
- setDragOffset({
425
- x: cursorpt.x - items.x,
426
- y: cursorpt.y - items.y,
427
- });
428
- // dragOffset.current = {
429
- // x: cursorpt.x - items.x,
430
- // y: cursorpt.y - items.y
431
- // }
432
- }
433
- else if (activeTool === "select" && direction) {
434
- setResizeDirection(direction);
435
- // setIsDragging(true);
436
- // setMoveComponent(true);
437
- moveComponent.current = true;
438
- isDragging.current = true;
439
- isTouching.current = true;
440
- const touch = e.touches[0];
441
- const svg = e.currentTarget.ownerSVGElement;
442
- const pt = svg.createSVGPoint();
443
- if (!svg)
444
- return;
445
- pt.x = touch.clientX;
446
- pt.y = touch.clientY;
447
- const cursorpt = pt.matrixTransform((_c = svg.getScreenCTM()) === null || _c === void 0 ? void 0 : _c.inverse());
448
- screenCTMRef.current = ((_d = svg.getScreenCTM()) === null || _d === void 0 ? void 0 : _d.inverse()) || null;
449
- setDragOffset({
450
- x: cursorpt.x - items.x,
451
- y: cursorpt.y - items.y,
452
- });
453
- // dragOffset.current = {
454
- // x: cursorpt.x - items.x,
455
- // y: cursorpt.y - items.y
456
- // }
457
- }
458
- };
459
- const handleTouchMove = (e) => {
460
- if (activeTool === "select" &&
461
- moveComponent &&
462
- isTouching.current &&
463
- !resizeDirection) {
464
- isDragging.current = true;
465
- moveComponent.current = true;
466
- const touch = e.touches[0];
467
- const svg = e.currentTarget.ownerSVGElement;
468
- if (!svg)
469
- return;
470
- const pt = svg.createSVGPoint();
471
- pt.x = touch.clientX;
472
- pt.y = touch.clientY;
473
- const cursorpt = pt.matrixTransform(screenCTMRef.current);
474
- requestAnimationFrame(() => {
475
- if ((selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.shape) != "background") {
476
- setComponentsState((prev) => {
477
- return prev.map((component) => {
478
- if (component.id === selectedComponent.id) {
479
- return Object.assign(Object.assign({}, component), { x: cursorpt.x - (dragOffset === null || dragOffset === void 0 ? void 0 : dragOffset.x), y: cursorpt.y - (dragOffset === null || dragOffset === void 0 ? void 0 : dragOffset.y) });
480
- }
481
- return component;
482
- });
483
- });
484
- }
485
- if ((selectedComponent === null || selectedComponent === void 0 ? void 0 : selectedComponent.shape) == "background") {
486
- setExtraComponentsState((prev) => {
487
- return prev.map((component) => {
488
- if (component.id === selectedComponent.id) {
489
- return Object.assign(Object.assign({}, component), { x: cursorpt.x - (dragOffset === null || dragOffset === void 0 ? void 0 : dragOffset.x), y: cursorpt.y - (dragOffset === null || dragOffset === void 0 ? void 0 : dragOffset.y) });
490
- }
491
- return component;
492
- });
493
- });
494
- }
495
- setSelectedComponent(Object.assign(Object.assign({}, selectedComponent), { x: cursorpt.x - (dragOffset === null || dragOffset === void 0 ? void 0 : dragOffset.x), y: cursorpt.y - (dragOffset === null || dragOffset === void 0 ? void 0 : dragOffset.y) }));
496
- });
497
- // updateComponentRef({
498
- // ...(typeof selectedComponent === "object" && selectedComponent !== null
499
- // ? selectedComponent
500
- // : {}),
501
- // x: cursorpt.x - dragOffset?.current.x,
502
- // y: cursorpt.y - dragOffset?.current.y,
503
- // });
504
- }
505
- else if (activeTool === "select" &&
506
- moveComponent.current &&
507
- isTouching.current &&
508
- resizeDirection) {
509
- // setIsDragging(true);
510
- isDragging.current = true;
511
- const touch = e.touches[0];
512
- const svg = e.currentTarget.ownerSVGElement;
513
- if (!svg)
514
- return;
515
- const pt = svg.createSVGPoint();
516
- pt.x = touch.clientX;
517
- pt.y = touch.clientY;
518
- const cursorpt = pt.matrixTransform(screenCTMRef.current);
519
- let newShape = Object.assign({}, selectedComponent);
520
- switch (resizeDirection) {
521
- case "top-left":
522
- newShape.width = newShape.width + (newShape.x - cursorpt.x);
523
- newShape.height = newShape.height + (newShape.y - cursorpt.y);
524
- newShape.x = cursorpt.x;
525
- newShape.y = cursorpt.y;
526
- break;
527
- case "top-right":
528
- newShape.width = cursorpt.x - newShape.x;
529
- newShape.height = newShape.height + (newShape.y - cursorpt.y);
530
- newShape.y = cursorpt.y;
531
- break;
532
- case "bottom-left":
533
- newShape.width = newShape.width + (newShape.x - cursorpt.x);
534
- newShape.height = cursorpt.y - newShape.y;
535
- newShape.x = cursorpt.x;
536
- break;
537
- case "bottom-right":
538
- newShape.width = cursorpt.x - newShape.x;
539
- newShape.height = cursorpt.y - newShape.y;
540
- break;
541
- case "top-center":
542
- newShape.height = newShape.height + (newShape.y - cursorpt.y);
543
- newShape.y = cursorpt.y;
544
- break;
545
- case "bottom-center":
546
- newShape.height = cursorpt.y - newShape.y;
547
- break;
548
- case "right-center":
549
- newShape.width = cursorpt.x - newShape.x;
550
- break;
551
- case "left-center":
552
- newShape.width = newShape.width + (newShape.x - cursorpt.x);
553
- newShape.x = cursorpt.x;
554
- break;
555
- default:
556
- break;
557
- }
558
- // updateComponentRef({
559
- // ...(typeof selectedComponent === "object" && selectedComponent !== null
560
- // ? selectedComponent
561
- // : {}),
562
- // ...newShape,
563
- // });
564
- requestAnimationFrame(() => {
565
- setComponentsState((prev) => {
566
- return prev.map((component) => {
567
- if (component.id === selectedComponent.id) {
568
- return Object.assign(Object.assign({}, component), newShape);
569
- }
570
- return component;
571
- });
572
- });
573
- setExtraComponentsState((prev) => {
574
- return prev.map((component) => {
575
- if (component.id === selectedComponent.id) {
576
- return Object.assign(Object.assign({}, component), newShape);
577
- }
578
- return component;
579
- });
580
- });
581
- setSelectedComponent(Object.assign(Object.assign({}, selectedComponent), newShape));
582
- });
583
- debouncedSyncToReduxSelected(newShape);
584
- }
585
- };
586
- const handleTouchEnd = () => {
587
- // setMoveComponent(false);
588
- // setIsDragging(false);
589
- moveComponent.current = false;
590
- isDragging.current = false;
591
- isTouching.current = false;
592
- setResizeDirection(null);
593
- };
594
- const getCursorStyle = () => {
595
- if (activeTool === "select" && moveComponent.current) {
596
- return "grabbing";
597
- }
598
- else if (activeTool === "select" && resizeDirection) {
599
- return "grab";
600
- }
601
- else if (activeTool === "grab") {
602
- return "grab";
603
- }
604
- else if (activeTool === "ruler") {
605
- return "crosshair";
606
- }
607
- };
608
- const renderMiniMap = () => {
609
- return (<MiniMap width={250} height={250}>
610
- <div className="w-full h-full">
611
- <svg id="workspace" width="100%" height="100%" viewBox={`0 0 ${widthBoard} ${heightBoard}`} className="h-screen w-full" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid meet" style={{
612
- background: "#f5f5f5",
613
- display: "block",
614
- }}>
615
- <Layers shadowShape={shadowShape} components={[...extraComponentsState, ...componentsState]} activeTool={activeTool}
616
- // onClick={handleSelectComponent}
617
- // onMouseDown={handleMouseDown}
618
- // onMouseUp={handleMouseUp}
619
- // onBlur={handleUnSelectComponent}
620
- selectedComponent={selectedComponent}/>
621
- </svg>
622
- </div>
623
- </MiniMap>);
624
- };
625
- const handelZoomIn = () => {
626
- var _a;
627
- if (activeTool !== "grab") {
628
- dispatch({
629
- type: "tool/setActiveTool",
630
- payload: "grab",
631
- });
632
- }
633
- (_a = transformRef.current) === null || _a === void 0 ? void 0 : _a.zoomIn();
634
- };
635
- const handleZoomOut = () => {
636
- var _a;
637
- if (activeTool !== "grab") {
638
- dispatch({
639
- type: "tool/setActiveTool",
640
- payload: "grab",
641
- });
642
- }
643
- (_a = transformRef.current) === null || _a === void 0 ? void 0 : _a.zoomOut();
644
- };
645
- // activeTool === "select" &&
646
- // moveComponent &&
647
- // isTouching.current &&
648
- // !resizeDirection
649
- return (<>
650
- <ModalPreview>
651
- <LayerView statusKey="status"/>
652
- </ModalPreview>
653
- <div className="relative w-full h-screen flex-1 overflow-hidden" ref={containerRef}>
654
- <div className="absolute bottom-5 left-1/2 transform -translate-x-1/2 z-10">
655
- <div className="flex gap-2">
656
- <Button icon={<ZoomIn />} onClick={handelZoomIn}/>
657
- <Button icon={<ZoomOut />} onClick={handleZoomOut}/>
658
- </div>
659
- </div>
660
- <TransformWrapper ref={transformRef} panning={{ disabled: activeTool === "select" }} centerZoomedOut={true} onTransformed={({ state: { scale } }) => setScale(scale)} minScale={1} // sangat kecil = bisa zoom out jauh
661
- maxScale={1000} initialScale={1} pinch={{ step: 1 }} smooth={true} doubleClick={{ step: 1, disabled: activeTool === "select" }} disablePadding>
662
- {scale > 1 && (<div className="absolute bottom-[60px] left-1/2 transform -translate-x-1/2 z-10">
663
- {renderMiniMap()}
664
- </div>)}
665
- <TransformComponent wrapperStyle={{
666
- width: "100%",
667
- height: "100%",
668
- overflow: "hidden",
669
- }} contentStyle={{
670
- width: "100%",
671
- height: "100%",
672
- }}>
673
- <svg id="workspace" ref={svgRef} width="100%" height="100%" viewBox={`0 0 ${widthBoard} ${heightBoard}`} className="h-screen" onMouseUp={handleMouseUp} onMouseMove={handleMouseMove} onMouseEnter={handleMouseEnter} onClick={(e) => {
674
- e.stopPropagation();
675
- handleMouseClick(e);
676
- }} onMouseLeave={handleMouseLeave} xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid meet" style={{
677
- background: backgroundColor,
678
- display: "block",
679
- cursor: activeTool === "ruler" ? "crosshair" : "auto",
680
- }}>
681
- <Layers shadowShape={shadowShape} components={[...extraComponentsState, ...componentsState]} style={{
682
- cursor: getCursorStyle(),
683
- }}
684
- // onClick={handleSelectComponent}
685
- onMouseDown={handleMouseDown}
686
- // onMouseUp={handleMouseUp}
687
- onBlur={handleUnSelectComponent} selectedComponent={selectedComponent} activeTool={activeTool} onTouchStart={(e, item, direction) => handleTouchStart(e, item, direction)} onTouchMove={(e) => handleTouchMove(e)} onTouchEnd={handleTouchEnd}/>
688
- {activeTool === "ruler" && (<>
689
- <g id="horizontal-ruler">
690
- <rect x="0" y="0" width={window.innerWidth} height="30" fill="#e0e0e0"/>
691
- <g stroke="#888" font-size="10" text-anchor="middle">
692
- {Array.from({ length: window.innerWidth / 50 }, (_, i) => (<g key={i}>
693
- <line x1={i * 50} y1="0" x2={i * 50} y2="10"/>
694
- <text x={i * 50} y="15">
695
- {i * 50}
696
- </text>
697
- </g>))}
698
- </g>
699
- </g>
700
- <g id="vertical-ruler">
701
- <rect x="0" y="0" width="30" height={window.innerHeight} fill="#e0e0e0"/>
702
- <g stroke="#888" font-size="10" text-anchor="middle">
703
- {Array.from({ length: window.innerHeight / 10 }, (_, i) => (<g key={i}>
704
- <line x1="0" y1={i * 50} x2="10" y2={i * 50}/>
705
- <text x="15" y={i * 50}>
706
- {i * 50}
707
- </text>
708
- </g>))}
709
- </g>
710
- </g>
711
- </>)}
712
- {grid && (<g stroke="#ddd" strokeWidth={0.5}>
713
- {/* Vertical lines */}
714
- {Array.from({ length: widthBoard / 10 }, (_, i) => (<line key={`v-${i}`} x1={i * 10} y1={0} x2={i * 10} y2={heightBoard}/>))}
715
-
716
- {/* Horizontal lines */}
717
- {Array.from({ length: heightBoard / 10 }, (_, i) => (<line key={`h-${i}`} x1={0} y1={i * 10} x2={widthBoard} y2={i * 10}/>))}
718
- </g>)}
719
- </svg>
720
- </TransformComponent>
721
- </TransformWrapper>
722
- </div>
723
- </>);
724
- };
725
- export default BoardTemplate;