funda-ui 4.5.677 → 4.5.682

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 (40) hide show
  1. package/ColorPicker/index.js +3 -1
  2. package/DragDropList/index.css +188 -0
  3. package/DragDropList/index.d.ts +43 -0
  4. package/DragDropList/index.js +1589 -0
  5. package/LICENSE +21 -0
  6. package/MultipleSelect/index.css +237 -144
  7. package/MultipleSelect/index.d.ts +23 -10
  8. package/MultipleSelect/index.js +2242 -1225
  9. package/README.md +3 -1
  10. package/Utils/useBoundedDrag.d.ts +127 -0
  11. package/Utils/useBoundedDrag.js +382 -0
  12. package/Utils/useDragDropPosition.d.ts +169 -0
  13. package/Utils/useDragDropPosition.js +456 -0
  14. package/all.d.ts +1 -0
  15. package/all.js +1 -0
  16. package/lib/cjs/ColorPicker/index.js +3 -1
  17. package/lib/cjs/DragDropList/index.d.ts +43 -0
  18. package/lib/cjs/DragDropList/index.js +1589 -0
  19. package/lib/cjs/MultipleSelect/index.d.ts +23 -10
  20. package/lib/cjs/MultipleSelect/index.js +2242 -1225
  21. package/lib/cjs/Utils/useBoundedDrag.d.ts +127 -0
  22. package/lib/cjs/Utils/useBoundedDrag.js +382 -0
  23. package/lib/cjs/Utils/useDragDropPosition.d.ts +169 -0
  24. package/lib/cjs/Utils/useDragDropPosition.js +456 -0
  25. package/lib/cjs/index.d.ts +1 -0
  26. package/lib/cjs/index.js +1 -0
  27. package/lib/css/DragDropList/index.css +188 -0
  28. package/lib/css/MultipleSelect/index.css +237 -144
  29. package/lib/esm/ColorPicker/index.tsx +53 -49
  30. package/lib/esm/DragDropList/index.scss +245 -0
  31. package/lib/esm/DragDropList/index.tsx +493 -0
  32. package/lib/esm/MultipleSelect/index.scss +288 -183
  33. package/lib/esm/MultipleSelect/index.tsx +304 -166
  34. package/lib/esm/MultipleSelect/utils/func.ts +21 -1
  35. package/lib/esm/Tabs/Tabs.tsx +1 -1
  36. package/lib/esm/Utils/hooks/useBoundedDrag.tsx +303 -0
  37. package/lib/esm/Utils/hooks/useDragDropPosition.tsx +420 -0
  38. package/lib/esm/index.js +1 -0
  39. package/package.json +1 -1
  40. package/lib/esm/MultipleSelect/ItemList.tsx +0 -323
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Bounded Drag
3
+ *
4
+ * @usage:
5
+
6
+
7
+ const App = () => {
8
+ const [items, setItems] = useState<ListItem[]>([]);
9
+ // ... other states and refs
10
+
11
+ const deepCloneWithReactNode = (obj: any): any => {
12
+ if (obj === null || typeof obj !== 'object') {
13
+ return obj;
14
+ }
15
+
16
+ // Handle array
17
+ if (Array.isArray(obj)) {
18
+ return obj.map(item => deepCloneWithReactNode(item));
19
+ }
20
+
21
+ // Handle object
22
+ const clonedObj: any = {};
23
+ for (const key in obj) {
24
+ if (key === 'appendControl') {
25
+ clonedObj[key] = obj[key];
26
+ } else {
27
+ clonedObj[key] = deepCloneWithReactNode(obj[key]);
28
+ }
29
+ }
30
+ return clonedObj;
31
+ };
32
+
33
+
34
+ const getItemWithChildrenIndices = (items: ListItem[], startIndex: number): number[] => {
35
+ const indices = [startIndex];
36
+ const startItem = items[startIndex];
37
+ const startDepth = startItem.depth || 0;
38
+
39
+ // Check if subsequent items are child items
40
+ for (let i = startIndex + 1; i < items.length; i++) {
41
+ const currentItem = items[i];
42
+ const currentDepth = currentItem.depth || 0;
43
+ if (currentDepth > startDepth) {
44
+ indices.push(i);
45
+ } else {
46
+ break;
47
+ }
48
+ }
49
+
50
+ return indices;
51
+ };
52
+
53
+
54
+ const { isDragging, dragHandlers } = useBoundedDrag({
55
+ dragMode,
56
+ boundarySelector: '.custom-draggable-list',
57
+ itemSelector:'.custom-draggable-list__item',
58
+ dragHandleSelector: '.custom-draggable-list__handle',
59
+ onDragStart: (index: number) => {
60
+ // Additional drag start logic if needed
61
+ },
62
+ onDragOver: (dragIndex: number | null, dropIndex: number | null) => {
63
+ // Additional drag over logic if needed
64
+ },
65
+ onDragEnd: (dragIndex: number | null, dropIndex: number | null) => {
66
+ if (dragIndex !== null && dropIndex !== null && dragIndex !== dropIndex) {
67
+ // Handle item movement
68
+ const newItems = deepCloneWithReactNode(items);
69
+ const itemsToMove = getItemWithChildrenIndices(newItems, dragIndex);
70
+ const itemsBeingMoved = itemsToMove.map(index => newItems[index]);
71
+
72
+ // ... rest of your existing drag end logic ...
73
+
74
+ setItems(updatedItems);
75
+
76
+ }
77
+ }
78
+ });
79
+
80
+ // Update your JSX to use the new handlers
81
+ return (
82
+ <ul className="custom-draggable-list">
83
+ {items.map((item: any, index: number) => (
84
+ <li
85
+ // ... other props
86
+ draggable={!draggable ? undefined : editingItem !== item.id && "true"}
87
+ onDragStart={!draggable ? undefined : (e) => dragHandlers.handleDragStart(e, index)}
88
+ onDragOver={!draggable ? undefined : dragHandlers.handleDragOver}
89
+ onDragEnd={!draggable ? undefined : dragHandlers.handleDragEnd}
90
+ onTouchStart={!draggable ? undefined : (e) => dragHandlers.handleDragStart(e, index)}
91
+ onTouchMove={!draggable ? undefined : dragHandlers.handleDragOver}
92
+ onTouchEnd={!draggable ? undefined : dragHandlers.handleDragEnd}
93
+ >
94
+ <li className="custom-draggable-list__item">
95
+ <span className="custom-draggable-list__handle">☰</span>
96
+ <i>content {indec}<i>
97
+ </li>
98
+ </li>
99
+ ))}
100
+ </ul>
101
+ );
102
+ };
103
+
104
+
105
+ */
106
+ export interface TouchOffset {
107
+ x: number;
108
+ y: number;
109
+ }
110
+ export interface BoundedDragOptions {
111
+ dragMode?: 'handle' | 'block';
112
+ boundarySelector?: string;
113
+ itemSelector?: string;
114
+ dragHandleSelector?: string;
115
+ onDragStart?: (index: number) => void;
116
+ onDragOver?: (dragIndex: number | null, dropIndex: number | null) => void;
117
+ onDragEnd?: (dragIndex: number | null, dropIndex: number | null) => void;
118
+ }
119
+ export declare const useBoundedDrag: (options?: BoundedDragOptions) => {
120
+ isDragging: boolean;
121
+ dragHandlers: {
122
+ handleDragStart: (e: React.DragEvent | React.TouchEvent, position: number) => false | undefined;
123
+ handleDragOver: (e: React.DragEvent | React.TouchEvent) => void;
124
+ handleDragEnd: (e: React.DragEvent | React.TouchEvent) => void;
125
+ };
126
+ };
127
+ export default useBoundedDrag;
@@ -0,0 +1,382 @@
1
+ (function webpackUniversalModuleDefinition(root, factory) {
2
+ if(typeof exports === 'object' && typeof module === 'object')
3
+ module.exports = factory(require("react"));
4
+ else if(typeof define === 'function' && define.amd)
5
+ define(["react"], factory);
6
+ else if(typeof exports === 'object')
7
+ exports["RPB"] = factory(require("react"));
8
+ else
9
+ root["RPB"] = factory(root["React"]);
10
+ })(this, (__WEBPACK_EXTERNAL_MODULE__787__) => {
11
+ return /******/ (() => { // webpackBootstrap
12
+ /******/ "use strict";
13
+ /******/ var __webpack_modules__ = ({
14
+
15
+ /***/ 787:
16
+ /***/ ((module) => {
17
+
18
+ module.exports = __WEBPACK_EXTERNAL_MODULE__787__;
19
+
20
+ /***/ })
21
+
22
+ /******/ });
23
+ /************************************************************************/
24
+ /******/ // The module cache
25
+ /******/ var __webpack_module_cache__ = {};
26
+ /******/
27
+ /******/ // The require function
28
+ /******/ function __webpack_require__(moduleId) {
29
+ /******/ // Check if module is in cache
30
+ /******/ var cachedModule = __webpack_module_cache__[moduleId];
31
+ /******/ if (cachedModule !== undefined) {
32
+ /******/ return cachedModule.exports;
33
+ /******/ }
34
+ /******/ // Create a new module (and put it into the cache)
35
+ /******/ var module = __webpack_module_cache__[moduleId] = {
36
+ /******/ // no module.id needed
37
+ /******/ // no module.loaded needed
38
+ /******/ exports: {}
39
+ /******/ };
40
+ /******/
41
+ /******/ // Execute the module function
42
+ /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
43
+ /******/
44
+ /******/ // Return the exports of the module
45
+ /******/ return module.exports;
46
+ /******/ }
47
+ /******/
48
+ /************************************************************************/
49
+ /******/ /* webpack/runtime/compat get default export */
50
+ /******/ (() => {
51
+ /******/ // getDefaultExport function for compatibility with non-harmony modules
52
+ /******/ __webpack_require__.n = (module) => {
53
+ /******/ var getter = module && module.__esModule ?
54
+ /******/ () => (module['default']) :
55
+ /******/ () => (module);
56
+ /******/ __webpack_require__.d(getter, { a: getter });
57
+ /******/ return getter;
58
+ /******/ };
59
+ /******/ })();
60
+ /******/
61
+ /******/ /* webpack/runtime/define property getters */
62
+ /******/ (() => {
63
+ /******/ // define getter functions for harmony exports
64
+ /******/ __webpack_require__.d = (exports, definition) => {
65
+ /******/ for(var key in definition) {
66
+ /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
67
+ /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
68
+ /******/ }
69
+ /******/ }
70
+ /******/ };
71
+ /******/ })();
72
+ /******/
73
+ /******/ /* webpack/runtime/hasOwnProperty shorthand */
74
+ /******/ (() => {
75
+ /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
76
+ /******/ })();
77
+ /******/
78
+ /******/ /* webpack/runtime/make namespace object */
79
+ /******/ (() => {
80
+ /******/ // define __esModule on exports
81
+ /******/ __webpack_require__.r = (exports) => {
82
+ /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
83
+ /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
84
+ /******/ }
85
+ /******/ Object.defineProperty(exports, '__esModule', { value: true });
86
+ /******/ };
87
+ /******/ })();
88
+ /******/
89
+ /************************************************************************/
90
+ var __webpack_exports__ = {};
91
+ // This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
92
+ (() => {
93
+ __webpack_require__.r(__webpack_exports__);
94
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
95
+ /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__),
96
+ /* harmony export */ "useBoundedDrag": () => (/* binding */ useBoundedDrag)
97
+ /* harmony export */ });
98
+ /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(787);
99
+ /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
100
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
101
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
102
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
103
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
104
+ function _iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; if (null != _i) { var _s, _e, _x, _r, _arr = [], _n = !0, _d = !1; try { if (_x = (_i = _i.call(arr)).next, 0 === i) { if (Object(_i) !== _i) return; _n = !1; } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0); } catch (err) { _d = !0, _e = err; } finally { try { if (!_n && null != _i["return"] && (_r = _i["return"](), Object(_r) !== _r)) return; } finally { if (_d) throw _e; } } return _arr; } }
105
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
106
+ /**
107
+ * Bounded Drag
108
+ *
109
+ * @usage:
110
+
111
+
112
+ const App = () => {
113
+ const [items, setItems] = useState<ListItem[]>([]);
114
+ // ... other states and refs
115
+
116
+ const deepCloneWithReactNode = (obj: any): any => {
117
+ if (obj === null || typeof obj !== 'object') {
118
+ return obj;
119
+ }
120
+
121
+ // Handle array
122
+ if (Array.isArray(obj)) {
123
+ return obj.map(item => deepCloneWithReactNode(item));
124
+ }
125
+
126
+ // Handle object
127
+ const clonedObj: any = {};
128
+ for (const key in obj) {
129
+ if (key === 'appendControl') {
130
+ clonedObj[key] = obj[key];
131
+ } else {
132
+ clonedObj[key] = deepCloneWithReactNode(obj[key]);
133
+ }
134
+ }
135
+ return clonedObj;
136
+ };
137
+
138
+
139
+ const getItemWithChildrenIndices = (items: ListItem[], startIndex: number): number[] => {
140
+ const indices = [startIndex];
141
+ const startItem = items[startIndex];
142
+ const startDepth = startItem.depth || 0;
143
+
144
+ // Check if subsequent items are child items
145
+ for (let i = startIndex + 1; i < items.length; i++) {
146
+ const currentItem = items[i];
147
+ const currentDepth = currentItem.depth || 0;
148
+ if (currentDepth > startDepth) {
149
+ indices.push(i);
150
+ } else {
151
+ break;
152
+ }
153
+ }
154
+
155
+ return indices;
156
+ };
157
+
158
+
159
+ const { isDragging, dragHandlers } = useBoundedDrag({
160
+ dragMode,
161
+ boundarySelector: '.custom-draggable-list',
162
+ itemSelector:'.custom-draggable-list__item',
163
+ dragHandleSelector: '.custom-draggable-list__handle',
164
+ onDragStart: (index: number) => {
165
+ // Additional drag start logic if needed
166
+ },
167
+ onDragOver: (dragIndex: number | null, dropIndex: number | null) => {
168
+ // Additional drag over logic if needed
169
+ },
170
+ onDragEnd: (dragIndex: number | null, dropIndex: number | null) => {
171
+ if (dragIndex !== null && dropIndex !== null && dragIndex !== dropIndex) {
172
+ // Handle item movement
173
+ const newItems = deepCloneWithReactNode(items);
174
+ const itemsToMove = getItemWithChildrenIndices(newItems, dragIndex);
175
+ const itemsBeingMoved = itemsToMove.map(index => newItems[index]);
176
+
177
+ // ... rest of your existing drag end logic ...
178
+
179
+ setItems(updatedItems);
180
+
181
+ }
182
+ }
183
+ });
184
+
185
+ // Update your JSX to use the new handlers
186
+ return (
187
+ <ul className="custom-draggable-list">
188
+ {items.map((item: any, index: number) => (
189
+ <li
190
+ // ... other props
191
+ draggable={!draggable ? undefined : editingItem !== item.id && "true"}
192
+ onDragStart={!draggable ? undefined : (e) => dragHandlers.handleDragStart(e, index)}
193
+ onDragOver={!draggable ? undefined : dragHandlers.handleDragOver}
194
+ onDragEnd={!draggable ? undefined : dragHandlers.handleDragEnd}
195
+ onTouchStart={!draggable ? undefined : (e) => dragHandlers.handleDragStart(e, index)}
196
+ onTouchMove={!draggable ? undefined : dragHandlers.handleDragOver}
197
+ onTouchEnd={!draggable ? undefined : dragHandlers.handleDragEnd}
198
+ >
199
+ <li className="custom-draggable-list__item">
200
+ <span className="custom-draggable-list__handle">☰</span>
201
+ <i>content {indec}<i>
202
+ </li>
203
+ </li>
204
+ ))}
205
+ </ul>
206
+ );
207
+ };
208
+
209
+
210
+ */
211
+
212
+
213
+ var useBoundedDrag = function useBoundedDrag() {
214
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
215
+ var _options$dragMode = options.dragMode,
216
+ dragMode = _options$dragMode === void 0 ? 'handle' : _options$dragMode,
217
+ _options$boundarySele = options.boundarySelector,
218
+ boundarySelector = _options$boundarySele === void 0 ? '.custom-draggable-list' : _options$boundarySele,
219
+ _options$itemSelector = options.itemSelector,
220
+ itemSelector = _options$itemSelector === void 0 ? '.custom-draggable-list__item' : _options$itemSelector,
221
+ _options$dragHandleSe = options.dragHandleSelector,
222
+ dragHandleSelector = _options$dragHandleSe === void 0 ? '.custom-draggable-list__handle' : _options$dragHandleSe,
223
+ onDragStart = options.onDragStart,
224
+ onDragOver = options.onDragOver,
225
+ onDragEnd = options.onDragEnd;
226
+ var _useState = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false),
227
+ _useState2 = _slicedToArray(_useState, 2),
228
+ isDragging = _useState2[0],
229
+ setIsDragging = _useState2[1];
230
+ var dragItem = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
231
+ var dragOverItem = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
232
+ var dragNode = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
233
+ var touchOffset = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)({
234
+ x: 0,
235
+ y: 0
236
+ });
237
+ var currentHoverItem = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
238
+ var handleDragStart = function handleDragStart(e, position) {
239
+ var isTouch = ('touches' in e);
240
+ var target = e.target;
241
+
242
+ // For block mode or handle mode check
243
+ if (dragMode === 'handle') {
244
+ var handle = target.closest(dragHandleSelector);
245
+ if (!handle) {
246
+ if (!isTouch) e.preventDefault();
247
+ return false;
248
+ }
249
+ }
250
+
251
+ // Find the draggable item
252
+ var listItem = target.closest(itemSelector);
253
+ if (!listItem) return;
254
+
255
+ // Check boundary
256
+ var boundary = listItem.closest(boundarySelector);
257
+ if (!boundary) return;
258
+ dragItem.current = position;
259
+ onDragStart === null || onDragStart === void 0 ? void 0 : onDragStart(position);
260
+ if (isTouch) {
261
+ e.preventDefault(); // Prevent scrolling
262
+ var touch = e.touches[0];
263
+ var rect = listItem.getBoundingClientRect();
264
+ var boundaryRect = boundary.getBoundingClientRect();
265
+
266
+ // Calculate offset relative to the boundary
267
+ touchOffset.current = {
268
+ x: touch.clientX - rect.left,
269
+ y: touch.clientY - rect.top
270
+ };
271
+
272
+ // Clone the item for dragging
273
+ dragNode.current = listItem.cloneNode(true);
274
+ dragNode.current.classList.add('dragging');
275
+
276
+ // Style the clone
277
+ Object.assign(dragNode.current.style, {
278
+ position: 'fixed',
279
+ width: "".concat(rect.width, "px"),
280
+ height: "".concat(rect.height, "px"),
281
+ left: "".concat(rect.left, "px"),
282
+ top: "".concat(rect.top, "px"),
283
+ zIndex: '1000',
284
+ pointerEvents: 'none',
285
+ transform: 'scale(1.05)',
286
+ transition: 'transform 0.1s',
287
+ opacity: '0.9'
288
+ });
289
+ document.body.appendChild(dragNode.current);
290
+ setIsDragging(true);
291
+ listItem.classList.add('dragging-placeholder');
292
+ } else {
293
+ // ... desktop drag logic remains the same ...
294
+ }
295
+ };
296
+ var handleDragOver = function handleDragOver(e) {
297
+ e.preventDefault();
298
+ var isTouch = ('touches' in e);
299
+ if (!isTouch) {
300
+ e.dataTransfer.dropEffect = 'move';
301
+ }
302
+
303
+ // Get the current pointer/touch position
304
+ var point = isTouch ? e.touches[0] : {
305
+ clientX: e.clientX,
306
+ clientY: e.clientY
307
+ };
308
+
309
+ // Update dragged element position for touch events
310
+ if (isTouch && isDragging && dragNode.current) {
311
+ dragNode.current.style.left = "".concat(point.clientX - touchOffset.current.x, "px");
312
+ dragNode.current.style.top = "".concat(point.clientY - touchOffset.current.y, "px");
313
+ }
314
+
315
+ // Find the element below the pointer/touch
316
+ var elemBelow = document.elementFromPoint(point.clientX, point.clientY);
317
+ if (!elemBelow) return;
318
+
319
+ // Find the closest list item
320
+ var listItem = elemBelow.closest(itemSelector);
321
+ if (!listItem || listItem === currentHoverItem.current) return;
322
+
323
+ // Check boundary
324
+ var boundary = listItem.closest(boundarySelector);
325
+ if (!boundary) return;
326
+
327
+ // Update hover states
328
+ if (currentHoverItem.current) {
329
+ currentHoverItem.current.classList.remove('drag-over', 'drag-over-top', 'drag-over-bottom');
330
+ }
331
+ currentHoverItem.current = listItem;
332
+ listItem.classList.add('drag-over');
333
+
334
+ // Calculate position in list
335
+ var position = Array.from(listItem.parentNode.children).indexOf(listItem);
336
+ dragOverItem.current = position;
337
+
338
+ // Determine drop position (top/bottom)
339
+ var rect = listItem.getBoundingClientRect();
340
+ var middleY = rect.top + rect.height / 2;
341
+ if (point.clientY < middleY) {
342
+ listItem.classList.add('drag-over-top');
343
+ } else {
344
+ listItem.classList.add('drag-over-bottom');
345
+ }
346
+ onDragOver === null || onDragOver === void 0 ? void 0 : onDragOver(dragItem.current, dragOverItem.current);
347
+ };
348
+ var handleDragEnd = function handleDragEnd(e) {
349
+ var isTouch = ('touches' in e);
350
+ if (isTouch && !isDragging) return;
351
+ onDragEnd === null || onDragEnd === void 0 ? void 0 : onDragEnd(dragItem.current, dragOverItem.current);
352
+
353
+ // Cleanup
354
+ if (dragNode.current) {
355
+ dragNode.current.remove();
356
+ dragNode.current = null;
357
+ }
358
+ document.querySelectorAll(itemSelector).forEach(function (item) {
359
+ item.style.opacity = '1';
360
+ item.classList.remove('dragging', 'dragging-placeholder', 'drag-over', 'drag-over-top', 'drag-over-bottom');
361
+ });
362
+ setIsDragging(false);
363
+ currentHoverItem.current = null;
364
+ dragItem.current = null;
365
+ dragOverItem.current = null;
366
+ };
367
+ return {
368
+ isDragging: isDragging,
369
+ dragHandlers: {
370
+ handleDragStart: handleDragStart,
371
+ handleDragOver: handleDragOver,
372
+ handleDragEnd: handleDragEnd
373
+ }
374
+ };
375
+ };
376
+ /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (useBoundedDrag);
377
+ })();
378
+
379
+ /******/ return __webpack_exports__;
380
+ /******/ })()
381
+ ;
382
+ });
@@ -0,0 +1,169 @@
1
+ /**
2
+ * Drag Drop Object
3
+ *
4
+ * @usage:
5
+
6
+ import { useState, useCallback } from 'react';
7
+ import { useDragDropPosition } from '@/utils/hooks/useDragDropPosition';
8
+
9
+ const App = () => {
10
+
11
+ const [show, setShow] = useState<boolean>(false);
12
+
13
+ // drag & drop
14
+ //---------------、
15
+ const moveDelay = 150;
16
+ const pin = false;
17
+ const dimension = 32; // onject with dimension
18
+ const [objPosition, setObjPosition] = useState<{
19
+ x: number;
20
+ y: number;
21
+ }>({ x: 0, y: 0 });
22
+ const [isDragged, setIsDragged] = useState<boolean>(false);
23
+ const [isPressed, setIsPressed] = useState<boolean>(false);
24
+
25
+
26
+ const { setup, ref } = useDragDropPosition({
27
+ // usePercentage: true, // Enable percentage values
28
+ dimension,
29
+ onDragEnd: ({position, hasContainer}) => {
30
+ const { left, top } = position;
31
+ setObjPosition({
32
+ x: left || 0,
33
+ y: (top || 0),
34
+ });
35
+ setIsPressed(false);
36
+ setIsDragged(false);
37
+
38
+ // click event here (restore)
39
+ setShow(false);
40
+ },
41
+ onDragStart: ({position, hasContainer}) => {
42
+ const { left, top } = position;
43
+ setObjPosition({
44
+ x: left || 0,
45
+ y: (top || 0),
46
+ });
47
+ setIsDragged(true);
48
+
49
+ // click event here (restore)
50
+ setShow(false);
51
+ },
52
+ onInit: ({position, hasContainer}) => {
53
+ const { left, top } = position;
54
+ setObjPosition({
55
+ x: left || 0,
56
+ y: (top || 0),
57
+ });
58
+ },
59
+ onPointerDown: () => {
60
+ setIsPressed(true);
61
+ },
62
+ onPointerUp: useCallback(() => {
63
+ setIsPressed(false);
64
+
65
+ // click event here
66
+ setShow((prev) => !prev);
67
+
68
+ }, []),
69
+ onMove: ({position, hasContainer}) => {
70
+ const { left, top } = position;
71
+ setObjPosition({
72
+ x: left || 0,
73
+ y: (top || 0),
74
+ });
75
+ },
76
+ pin,
77
+ moveDelay
78
+ });
79
+
80
+
81
+
82
+ return (
83
+
84
+
85
+ <>
86
+
87
+ <div
88
+ ref={setup}
89
+ className="float-btn"
90
+ style={{position: 'fixed', left: '50%', top: '50%', zIndex: 1000, background: 'red'}}
91
+
92
+ >Move Here<small>{JSON.stringify(objPosition)}</small><br /><strong>{show ? 'Clicked' : 'None'}</strong></div>
93
+
94
+ </>
95
+ )
96
+ }
97
+
98
+
99
+
100
+
101
+ const App2 = () => {
102
+
103
+ const dragdropContainerRef = useRef<HTMLDivElement>(null);
104
+ ....
105
+
106
+ const { setup, ref } = useDragDropPosition({
107
+ container: dragdropContainerRef.current, // If there is a container with a drag range
108
+ ...
109
+ });
110
+
111
+
112
+ return (
113
+
114
+ <>
115
+
116
+ <div
117
+ ref={dragdropContainerRef}
118
+ style={{
119
+ width: '300px',
120
+ height: '300px',
121
+ border: '1px solid #ddd',
122
+ background: '#efefef',
123
+ position: 'relative'
124
+ }}
125
+ >
126
+ <div
127
+ ref={setup}
128
+ className="float-btn"
129
+ style={{ position: 'absolute', left: '50%', top: '50%', zIndex: 1000, background: 'red' }}
130
+
131
+ >Move Here<small>{JSON.stringify(objPosition)}</small><br /><strong>{show ? 'Clicked' : 'None'}</strong></div>
132
+
133
+ </div>
134
+
135
+
136
+
137
+ </>
138
+ )
139
+ }
140
+
141
+ */
142
+ /// <reference types="react" />
143
+ interface Position {
144
+ left: number;
145
+ top: number;
146
+ }
147
+ interface PositionResult {
148
+ position: Position;
149
+ hasContainer: boolean;
150
+ }
151
+ interface DragDropSettings {
152
+ container?: HTMLElement | null;
153
+ onPointerDown?: () => void;
154
+ onPointerUp?: () => void;
155
+ onDragStart?: (position: PositionResult) => void;
156
+ onDragEnd?: (position: PositionResult) => void;
157
+ onMove?: (position: PositionResult) => void;
158
+ onInit?: (position: PositionResult) => void;
159
+ dimension?: number;
160
+ pin?: boolean;
161
+ moveDelay?: number;
162
+ usePercentage?: boolean;
163
+ }
164
+ declare const useDragDropPosition: (settings: DragDropSettings) => {
165
+ ref: import("react").MutableRefObject<HTMLElement | null>;
166
+ setup: (node: HTMLElement | null) => void;
167
+ };
168
+ export { useDragDropPosition };
169
+ export type { DragDropSettings, Position, PositionResult };