polarvo-layout 1.0.19 → 1.0.21

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 (28) hide show
  1. package/package.json +1 -1
  2. package/src/components/FastMenu/DesignFastmenu.vue +2 -2
  3. package/src/components/FastMenu/DisplayFastMenu.vue +2 -2
  4. package/src/components/FastMenu/LayoutFastMenu.vue +18 -10
  5. package/src/components/Layout/CanvasContainer.vue +30 -6
  6. package/src/components/SideBar/ElementSideBar.vue +2 -2
  7. package/src/components/SideBar/LayoutSettingSideBar.vue +18 -10
  8. package/src/components/SideBar/LayoutSideBar.vue +19 -8
  9. package/src/configs/index.js +1 -0
  10. package/src/core/engines/DisplayEngine.js +72 -64
  11. package/src/core/engines/FreeDropEngine.js +40 -42
  12. package/src/core/engines/GridDropEngine.js +33 -43
  13. package/src/core/engines/HistoryEngine.js +55 -51
  14. package/src/core/engines/LayoutEngine.js +89 -68
  15. package/src/core/engines/originals/FreeDropEngine_0402.js +786 -0
  16. package/src/core/engines/originals/GridDropEngine_0402.js +557 -0
  17. package/src/core/managers/EngineManager.js +93 -131
  18. package/src/core/managers/originals/EngineManager_0402.js +826 -0
  19. package/src/library/DisplayLibrary.js +14 -17
  20. package/src/library/FreeDropLibrary.js +6 -4
  21. package/src/library/GridDropLibrary.js +3 -5
  22. package/src/library/LayoutLibrary.js +45 -48
  23. package/src/library/originals/DisplayLibrary_0402.js +137 -0
  24. package/src/library/originals/FreeDropLibrary_0402.js +185 -0
  25. package/src/library/originals/GridDropLibrary_0402.js +202 -0
  26. package/src/library/originals/HistoryLibrary_0402.js +98 -0
  27. package/src/library/originals/LayoutLibrary_0402.js +264 -0
  28. package/src/utils/index.js +8 -3
@@ -37,30 +37,27 @@ function useDisplay(api) {
37
37
  });
38
38
 
39
39
  // layoutName 세팅 감지
40
- _subscribe('display:setLayoutName', ({ displayMode, displaySize }) => {
41
- state.displayMode = displayMode;
42
- state.displaySize = { ...displaySize };
40
+ _subscribe('layout:setLayoutName', ({ $screenConfig }) => {
41
+ state.displayMode = $screenConfig.displayMode;
42
+ state.displaySize = { ...$screenConfig.displaySize };
43
43
  });
44
44
 
45
45
  // activeMenu 변경 감지
46
- _subscribe('display:updateActiveMenu', ({ menu }) => {
47
- state.activeMenu = menu;
46
+ _subscribe('display:updateActiveMenu', ({ $menu }) => {
47
+ state.activeMenu = $menu;
48
48
  });
49
49
 
50
50
  // activeDesign 변경 감지
51
- _subscribe('display:updateActiveDesign', ({ design }) => {
52
- state.activeDesign = design;
51
+ _subscribe('display:updateActiveDesign', ({ $design }) => {
52
+ state.activeDesign = $design;
53
53
  });
54
54
 
55
55
  // displayMode 변경 감지 (displaySize가 함께 초기화됨)
56
- _subscribe('display:updateDisplayMode', ({ displayMode, displaySize }) => {
57
- state.displayMode = displayMode;
58
- state.displaySize = { ...displaySize };
59
- });
60
-
61
- // displaySize 변경 감지 (px 또는 percent 값 변경 감지)
62
- _subscribe('display:updateDisplaySize', ({ displaySize }) => {
63
- state.displaySize = { ...displaySize };
56
+ _subscribe('display:displayChanged', ({ type, $displayMode, $displaySize }) => {
57
+ if (type === 'mode') {
58
+ state.displayMode = $displayMode;
59
+ }
60
+ state.displaySize = { ...$displaySize };
64
61
  });
65
62
 
66
63
  _subscribe('display:restoredState', ({ stateData }) => {
@@ -118,9 +115,9 @@ function useDisplay(api) {
118
115
 
119
116
  const setDisplaySize = (type, size) => {
120
117
  try {
121
- api.display.setDisplaySize(type, size);
118
+ return api.display.setDisplaySize(type, size);
122
119
  } catch (error) {
123
- console.error('[useDisplay] setDisplaySize 실행 중 오류 발생:', error);
120
+ console.error('[DisplayLibrary] setDisplaySize 실행 중 오류 발생:', error);
124
121
  }
125
122
  };
126
123
 
@@ -62,6 +62,8 @@ function useFreeDrop(api) {
62
62
  const index = state.elements.findIndex((el) => el.id === element.id);
63
63
  if (index !== -1) {
64
64
  state.elements[index] = element;
65
+ state.activeElement = element;
66
+ state.activeId = element?.id ?? null;
65
67
  }
66
68
  });
67
69
 
@@ -74,12 +76,12 @@ function useFreeDrop(api) {
74
76
 
75
77
  _subscribe('freeDrop:requestUpdateData', ({ elements, guides }) => {
76
78
  state.elements = elements;
77
- state.guides = guides;
79
+ state.guides = guides ?? { x: null, y: null, w: null, h: null };
78
80
  });
79
81
 
80
- _subscribe('system:requestUpdateElements', ({ elements, guides }) => {
81
- state.elements = elements;
82
- state.guides = guides;
82
+ _subscribe('system:requestElementsScale', ({ $elements, guides }) => {
83
+ state.elements = $elements;
84
+ state.guides = guides ?? { x: null, y: null, w: null, h: null };
83
85
  });
84
86
 
85
87
  _subscribe('freeDrop:requestUpdateLocalBounds', ({ elementId, position, size, guides }) => {
@@ -51,11 +51,9 @@ function useGridDrop(api) {
51
51
  const index = state.elements.findIndex((el) => el.id === element.id);
52
52
  if (index !== -1) {
53
53
  state.elements[index] = element;
54
-
55
54
  state.activeElement = element;
56
55
  state.activeId = element?.id ?? null;
57
-
58
- }
56
+ }
59
57
  });
60
58
 
61
59
  _subscribe('gridDrop:toggleLock', ({ elementId }) => {
@@ -69,8 +67,8 @@ function useGridDrop(api) {
69
67
  state.elements = elements;
70
68
  });
71
69
 
72
- _subscribe('system:requestUpdateElements', ({ elements }) => {
73
- state.elements = elements;
70
+ _subscribe('system:requestElementsScale', ({ $elements }) => {
71
+ state.elements = $elements;
74
72
  });
75
73
 
76
74
  _subscribe('gridDrop:requestUpdateLocalBounds', ({ elementId, position, size }) => {
@@ -9,6 +9,9 @@ function useLayout(api) {
9
9
  elements: null,
10
10
  layoutData: null,
11
11
  activeSection: null,
12
+ activeMode: null,
13
+ activeConfig: null,
14
+
12
15
  activeData: null,
13
16
 
14
17
  gapSize: null,
@@ -45,37 +48,43 @@ function useLayout(api) {
45
48
  });
46
49
 
47
50
  // layoutName 변경 감지 (layoutData, gridNumber, gridRatio가 함께 초기화됨)
48
- _subscribe('layout:setLayoutName', ({ screenConfig, gridNumber, gridRatio }) => {
49
- state.layoutName = screenConfig.layoutName;
50
- state.layoutData = screenConfig.layoutData;
51
- state.gridNumber = gridNumber;
52
- state.gridRatio = gridRatio;
53
- state.gapSize = screenConfig.gapSize;
51
+ _subscribe('layout:setLayoutName', ({ $screenConfig, $layoutData, $gridNumber, $gridRatio }) => {
52
+ state.layoutName = $screenConfig.layoutName;
53
+ state.layoutData = $layoutData;
54
+ state.gridNumber = $gridNumber;
55
+ state.gridRatio = $gridRatio;
56
+ state.gapSize = $screenConfig.gapSize;
57
+
58
+ state.activeSection = 'section1'; // 초기 활성 섹션 설정 (필요에 따라 조정)
59
+ state.activeMode = $layoutData.section1?.mode || 'free';
60
+ state.activeConfig = $layoutData.section1?.config || {};
54
61
  });
55
- _subscribe('layout:updateLayoutName', ({ layoutName, layoutData, gridNumber, gridRatio, gapSize }) => {
56
- state.layoutName = layoutName;
57
- state.layoutData = layoutData;
58
- state.gridNumber = gridNumber;
59
- state.gridRatio = gridRatio;
60
- if (gapSize) {
61
- state.gapSize = gapSize;
62
+
63
+ _subscribe('layout:updateLayoutName', ({ $layoutName, $layoutData, $gridNumber, $gridRatio, $gapSize }) => {
64
+ state.layoutName = $layoutName;
65
+ state.layoutData = $layoutData;
66
+ state.gridNumber = $gridNumber;
67
+ state.gridRatio = $gridRatio;
68
+ if ($gapSize != null) {
69
+ state.gapSize = $gapSize;
62
70
  }
63
71
  });
64
72
 
65
73
  // gapSize 변경 감지
66
- _subscribe('layout:updateGapSize', ({ gapSize }) => {
67
- state.gapSize = gapSize;
74
+ _subscribe('layout:updateGapSize', ({ $gapSize }) => {
75
+ state.gapSize = $gapSize;
68
76
  });
69
77
 
70
- // gridNumber 변경 감지
71
- _subscribe('layout:updateRatio', ({ gridRatio }) => {
72
- state.gridRatio = gridRatio;
78
+ // gridRatio 변경 감지
79
+ _subscribe('layout:updateRatio', ({ $type, $gridRatio }) => {
80
+ state.gridRatio[$type] = [...$gridRatio[$type]];
73
81
  });
74
82
 
75
83
  // activeSection 변경 감지 (activeData가 함께 초기화됨)
76
- _subscribe('system:updateActiveSection', ({ activeSection, activeData }) => {
77
- state.activeSection = activeSection;
78
- state.activeData = activeData;
84
+ _subscribe('system:updateActiveSection', ({ $section, $mode, $config }) => {
85
+ state.activeSection = $section;
86
+ state.activeMode = $mode;
87
+ state.activeConfig = $config;
79
88
  });
80
89
 
81
90
  // elements 변경 감지
@@ -86,32 +95,29 @@ function useLayout(api) {
86
95
  }
87
96
  });
88
97
 
89
- _subscribe('system:setElements', ({ elements }) => {
90
- state.elements = elements;
98
+ _subscribe('system:setElements', ({ $elements }) => {
99
+ state.elements = $elements;
91
100
  });
92
101
 
93
- _subscribe('system:updateActiveSectionConfig', ({ layoutData, activeData }) => {
94
- state.layoutData = layoutData;
95
- state.activeData = activeData;
102
+ _subscribe('layout:updateLayoutData', ({ $layoutData, $section, $mode, $config }) => {
103
+ state.activeSection = $section;
104
+ state.layoutData[$section] = { ...$layoutData[$section] };
105
+ state.activeMode = $mode;
106
+ state.activeConfig = $config;
96
107
  });
97
108
 
98
- _subscribe('system:requestUpdateData', ({ layoutData, activeData, elements }) => {
99
- state.layoutData = layoutData;
100
- state.activeData = activeData;
101
- state.elements = elements;
109
+ _subscribe('system:requestUpdateData', ({ $elements }) => {
110
+ state.elements = $elements;
102
111
  });
103
112
 
104
- _subscribe('system:requestUpdateElements', ({ elements }) => {
105
- state.elements = elements;
113
+ _subscribe('system:requestElementsScale', ({ $elements }) => {
114
+ state.elements = $elements;
106
115
  });
107
116
 
108
117
  _subscribe('system:restoredState', ({ stateData }) => {
109
118
  state.elements = stateData.elements;
110
119
  state.layoutData = stateData.layoutData;
111
120
  state.activeSection = stateData.activeSection;
112
-
113
- // state.layoutData = cloneDeep(api.layout.getLayoutData());
114
- // state.activeData = cloneDeep(api.layout.getActiveData());
115
121
  });
116
122
 
117
123
  _subscribe('layout:restoredState', ({ stateData }) => {
@@ -144,7 +150,7 @@ function useLayout(api) {
144
150
  };
145
151
 
146
152
  // 메서드
147
- const getContainerSize = () => {
153
+ const getContainerSize = () => {
148
154
  try {
149
155
  return api.layout.getContainerSize();
150
156
  } catch (error) {
@@ -160,7 +166,7 @@ function useLayout(api) {
160
166
  console.error('[LayoutLibrary] setContainerSize 실행 중 오류 발생:', error);
161
167
  }
162
168
  };
163
-
169
+
164
170
  const setLayoutName = (name, userData = null, setting = false) => {
165
171
  try {
166
172
  api.layout.setLayoutName(name, userData, setting);
@@ -179,20 +185,12 @@ function useLayout(api) {
179
185
 
180
186
  const setRatio = (type, index, ratio) => {
181
187
  try {
182
- api.layout.setRatio(type, index, ratio);
188
+ return api.layout.setRatio(type, index, ratio);
183
189
  } catch (error) {
184
190
  console.error('[useLayout] setRatio 실행 중 오류 발생:', error);
185
191
  }
186
192
  };
187
193
 
188
- // const setUserLayoutData = (userData) => {
189
- // try {
190
- // api.layout.setUserLayoutData(userData);
191
- // } catch (error) {
192
- // console.error('[useLayout] setUserLayoutData 실행 중 오류 발생:', error);
193
- // }
194
- // };
195
-
196
194
  const setActiveSection = (name) => {
197
195
  try {
198
196
  api.layout.setActiveSection(name);
@@ -227,7 +225,7 @@ function useLayout(api) {
227
225
 
228
226
  const setSectionConfig = (type, config) => {
229
227
  try {
230
- api.layout.setSectionConfig(type, config);
228
+ return api.layout.setSectionConfig(type, config);
231
229
  } catch (error) {
232
230
  console.error('[useLayout] setSectionConfig 실행 중 오류 발생:', error);
233
231
  }
@@ -241,7 +239,6 @@ function useLayout(api) {
241
239
  setLayoutName,
242
240
  setGapSize,
243
241
  setRatio,
244
- // setUserLayoutData,
245
242
  setActiveSection,
246
243
  setElements,
247
244
  updateActiveElement,
@@ -0,0 +1,137 @@
1
+ import { reactive, readonly } from 'vue';
2
+
3
+ function useDisplay(api) {
4
+ const state = reactive({
5
+ activeMenu: null,
6
+ activeDesign: null,
7
+ displayMode: 'desktop',
8
+ displaySize: null,
9
+ });
10
+
11
+ const _subscriptions = [];
12
+
13
+ const syncState = () => {
14
+ try {
15
+ const displayState = api.getDisplayState();
16
+ Object.assign(state, displayState);
17
+ } catch (error) {
18
+ console.error('[DisplayLibrary] 상태 동기화 중 오류 발생:', error);
19
+ }
20
+ };
21
+
22
+ const _subscribe = (name, handler) => {
23
+ const unsubscribe = api.eventBus.subscribe(name, handler);
24
+ _subscriptions.push(unsubscribe);
25
+ return unsubscribe;
26
+ };
27
+
28
+ // 이벤트 구독
29
+ const _setupSubscriptions = () => {
30
+ // 다시 초기화 되는 경우를 대비
31
+ _subscribe('system:engineInitialized', () => {
32
+ syncState();
33
+ });
34
+
35
+ _subscribe('system:enginesReset', () => {
36
+ syncState();
37
+ });
38
+
39
+ // layoutName 세팅 감지
40
+ _subscribe('display:setLayoutName', ({ displayMode, displaySize }) => {
41
+ state.displayMode = displayMode;
42
+ state.displaySize = { ...displaySize };
43
+ });
44
+
45
+ // activeMenu 변경 감지
46
+ _subscribe('display:updateActiveMenu', ({ menu }) => {
47
+ state.activeMenu = menu;
48
+ });
49
+
50
+ // activeDesign 변경 감지
51
+ _subscribe('display:updateActiveDesign', ({ design }) => {
52
+ state.activeDesign = design;
53
+ });
54
+
55
+ // displayMode 변경 감지 (displaySize가 함께 초기화됨)
56
+ _subscribe('display:updateDisplayMode', ({ displayMode, displaySize }) => {
57
+ state.displayMode = displayMode;
58
+ state.displaySize = { ...displaySize };
59
+ });
60
+
61
+ // displaySize 변경 감지 (px 또는 percent 값 변경 감지)
62
+ _subscribe('display:updateDisplaySize', ({ displaySize }) => {
63
+ state.displaySize = { ...displaySize };
64
+ });
65
+
66
+ _subscribe('display:restoredState', ({ stateData }) => {
67
+ state.displayMode = stateData.displayMode;
68
+ state.displaySize = { ...stateData.displaySize };
69
+ state.activeMenu = stateData.activeMenu;
70
+ state.activeDesign = stateData.activeDesign;
71
+ });
72
+ };
73
+
74
+ if (api.eventBus) {
75
+ _setupSubscriptions();
76
+
77
+ // 초기화가 이미 완료된 경우 즉시 동기화
78
+ if (api.isReady && api.isReady()) {
79
+ syncState();
80
+ }
81
+ }
82
+
83
+ // 라이브러리 cleanup
84
+ const cleanup = () => {
85
+ _subscriptions.forEach((unsubscribe) => {
86
+ if (typeof unsubscribe === 'function') {
87
+ unsubscribe();
88
+ }
89
+
90
+ _subscriptions.length = 0;
91
+ });
92
+ };
93
+
94
+ // 메서드
95
+ const setActiveMenu = (name) => {
96
+ try {
97
+ api.display.setActiveMenu(name);
98
+ } catch (error) {
99
+ console.error('[DisplayLibrary] setActiveMenu 실행 중 오류 발생:', error);
100
+ }
101
+ };
102
+
103
+ const setActiveDesign = (name) => {
104
+ try {
105
+ api.display.setActiveDesign(name);
106
+ } catch (error) {
107
+ console.error('[DisplayLibrary] setActiveDesign 실행 중 오류 발생:', error);
108
+ }
109
+ };
110
+
111
+ const setDisplayMode = (mode) => {
112
+ try {
113
+ api.display.setDisplayMode(mode);
114
+ } catch (error) {
115
+ console.error('[DisplayLibrary] setDisplayMode 실행 중 오류 발생:', error);
116
+ }
117
+ };
118
+
119
+ const setDisplaySize = (type, size) => {
120
+ try {
121
+ api.display.setDisplaySize(type, size);
122
+ } catch (error) {
123
+ console.error('[useDisplay] setDisplaySize 실행 중 오류 발생:', error);
124
+ }
125
+ };
126
+
127
+ return {
128
+ state: readonly(state),
129
+ cleanup,
130
+ setActiveMenu,
131
+ setActiveDesign,
132
+ setDisplayMode,
133
+ setDisplaySize,
134
+ };
135
+ }
136
+
137
+ export default useDisplay;
@@ -0,0 +1,185 @@
1
+ import { cloneDeep } from 'lodash-es';
2
+ import { reactive, readonly } from 'vue';
3
+
4
+ function useFreeDrop(api) {
5
+ const state = reactive({
6
+ handles: [],
7
+ elements: [],
8
+ guides: { x: null, y: null, w: null, h: null },
9
+ activeElement: null,
10
+ activeId: null,
11
+ });
12
+
13
+ const _subscriptions = [];
14
+
15
+ const syncState = () => {
16
+ try {
17
+ const freeDropState = api.getFreeDropState();
18
+ Object.assign(state, freeDropState);
19
+ } catch (error) {
20
+ console.error('[FreeDropLibrary] 상태 동기화 중 오류 발생:', error);
21
+ }
22
+ };
23
+
24
+ const _subscribe = (name, handler) => {
25
+ const unsubscribe = api.eventBus.subscribe(name, handler);
26
+ _subscriptions.push(unsubscribe);
27
+ return unsubscribe;
28
+ };
29
+
30
+ // 이벤트 구독
31
+ const _setupSubscriptions = () => {
32
+ // 다시 초기화 되는 경우를 대비
33
+ _subscribe('system:engineInitialized', () => {
34
+ syncState();
35
+ });
36
+
37
+ _subscribe('system:enginesReset', () => {
38
+ syncState();
39
+ });
40
+
41
+ _subscribe('freeDrop:setElements', ({ elements }) => {
42
+ state.elements = elements;
43
+ });
44
+
45
+ _subscribe('freeDrop:setActiveElement', ({ action, activeElement }) => {
46
+ if (!activeElement) {
47
+ state.guides = { x: null, y: null, w: null, h: null };
48
+ }
49
+
50
+ // 신규 추가인 경우에만 elements 업데이트 (새 요소 1개만 추가)
51
+ if (action === 'add' && activeElement) {
52
+ state.elements = [...state.elements, activeElement];
53
+ }
54
+
55
+ // state.elements = elements;
56
+ state.activeElement = activeElement;
57
+ state.activeId = activeElement?.id ?? null;
58
+ });
59
+
60
+ _subscribe('freeDrop:requestUpdateActiveElement', ({ element }) => {
61
+ // state.elements = elements;
62
+ const index = state.elements.findIndex((el) => el.id === element.id);
63
+ if (index !== -1) {
64
+ state.elements[index] = element;
65
+ }
66
+ });
67
+
68
+ _subscribe('freeDrop:toggleLock', ({ elementId }) => {
69
+ const element = state.elements.find((el) => el.id === elementId);
70
+ if (element) {
71
+ element.isLocked = !element.isLocked;
72
+ }
73
+ });
74
+
75
+ _subscribe('freeDrop:requestUpdateData', ({ elements, guides }) => {
76
+ state.elements = elements;
77
+ state.guides = guides;
78
+ });
79
+
80
+ _subscribe('system:requestUpdateElements', ({ elements, guides }) => {
81
+ state.elements = elements;
82
+ state.guides = guides;
83
+ });
84
+
85
+ _subscribe('freeDrop:requestUpdateLocalBounds', ({ elementId, position, size, guides }) => {
86
+ const element = state.elements.find((el) => el.id === elementId);
87
+
88
+ if (element) {
89
+ state.guides = guides;
90
+ state.elements = state.elements.map((element) =>
91
+ element.id === state.activeId ? { ...state.activeElement, position: { ...position }, size: { ...size } } : element,
92
+ );
93
+ } else {
94
+ state.elements.push(state.activeElement);
95
+ }
96
+ });
97
+
98
+ _subscribe('freeDrop:restoredState', ({ elements }) => {
99
+ state.elements = elements;
100
+ });
101
+ };
102
+
103
+ if (api.eventBus) {
104
+ _setupSubscriptions();
105
+
106
+ // 초기화가 이미 완료된 경우 즉시 동기화
107
+ if (api.isReady && api.isReady()) {
108
+ syncState();
109
+ }
110
+ }
111
+
112
+ // 라이브러리 cleanup
113
+ const cleanup = () => {
114
+ _subscriptions.forEach((unsubscribe) => {
115
+ if (typeof unsubscribe === 'function') {
116
+ unsubscribe();
117
+ }
118
+
119
+ _subscriptions.length = 0;
120
+ });
121
+ };
122
+
123
+ // 메서드
124
+ const getElementStyle = (element) => {
125
+ try {
126
+ return api.freeDrop.getElementStyle(element);
127
+ } catch (error) {
128
+ console.warn('[FreeDropLibrary] getElementStyle 실행 중 오류 발생:', error);
129
+ return {};
130
+ }
131
+ };
132
+
133
+ const setActiveElement = (element, type) => {
134
+ try {
135
+ api.freeDrop.setActiveElement(element, type);
136
+ } catch (error) {
137
+ console.warn('[FreeDropLibrary] setActiveElement 실행 중 오류 발생:', error);
138
+ }
139
+ };
140
+
141
+ const addElement = (event, elName) => {
142
+ try {
143
+ api.freeDrop.addElement(event, elName);
144
+ } catch (error) {
145
+ console.warn('[FreeDropLibrary] addElement 실행 중 오류 발생:', error);
146
+ }
147
+ };
148
+
149
+ const toggleLock = () => {
150
+ try {
151
+ api.freeDrop.toggleLock();
152
+ } catch (error) {
153
+ console.warn('[FreeDropLibrary] toggleLock 실행 중 오류 발생:', error);
154
+ }
155
+ };
156
+
157
+ const handleMouseDown = (event, id) => {
158
+ try {
159
+ api.freeDrop.handleMouseDown(event, id);
160
+ } catch (error) {
161
+ console.warn('[FreeDropLibrary] handleMouseDown 실행 중 오류 발생:', error);
162
+ }
163
+ };
164
+
165
+ const startResize = (event, direction) => {
166
+ try {
167
+ api.freeDrop.startResize(event, direction);
168
+ } catch (error) {
169
+ console.warn('[FreeDropLibrary] startResize 실행 중 오류 발생:', error);
170
+ }
171
+ };
172
+
173
+ return {
174
+ state: readonly(state),
175
+ cleanup,
176
+ getElementStyle,
177
+ setActiveElement,
178
+ addElement,
179
+ toggleLock,
180
+ handleMouseDown,
181
+ startResize,
182
+ };
183
+ }
184
+
185
+ export default useFreeDrop;