@vuu-ui/vuu-ui-controls 2.1.19-beta.1 → 2.1.19-beta.2

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 (180) hide show
  1. package/package.json +12 -13
  2. package/src/calendar/Calendar.css.js +10 -0
  3. package/src/calendar/Calendar.js +70 -0
  4. package/src/calendar/index.js +4 -0
  5. package/src/calendar/internal/CalendarCarousel.css.js +19 -0
  6. package/src/calendar/internal/CalendarCarousel.js +73 -0
  7. package/src/calendar/internal/CalendarContext.js +9 -0
  8. package/src/calendar/internal/CalendarDay.css.js +116 -0
  9. package/src/calendar/internal/CalendarDay.js +64 -0
  10. package/src/calendar/internal/CalendarMonth.css.js +13 -0
  11. package/src/calendar/internal/CalendarMonth.js +43 -0
  12. package/src/calendar/internal/CalendarNavigation.css.js +24 -0
  13. package/src/calendar/internal/CalendarNavigation.js +185 -0
  14. package/src/calendar/internal/CalendarWeekHeader.css.js +23 -0
  15. package/src/calendar/internal/CalendarWeekHeader.js +31 -0
  16. package/src/calendar/internal/useFocusManagement.js +66 -0
  17. package/src/calendar/internal/utils.js +57 -0
  18. package/src/calendar/useCalendar.js +116 -0
  19. package/src/calendar/useCalendarDay.js +74 -0
  20. package/src/calendar/useSelection.js +202 -0
  21. package/src/column-picker/ColumnPicker.css.js +8 -0
  22. package/src/column-picker/ColumnPicker.js +108 -0
  23. package/src/column-picker/ColumnSearch.css.js +61 -0
  24. package/src/column-picker/ColumnSearch.js +66 -0
  25. package/src/column-picker/index.js +2 -0
  26. package/src/column-picker/moving-window.js +49 -0
  27. package/src/common-hooks/index.js +3 -0
  28. package/src/common-hooks/selectionTypes.js +8 -0
  29. package/src/common-hooks/use-resize-observer.js +122 -0
  30. package/src/common-hooks/useControlled.js +45 -0
  31. package/src/context-panel-provider/ContextPanelProvider.js +80 -0
  32. package/src/cycle-state-button/CycleStateButton.js +30 -0
  33. package/src/cycle-state-button/index.js +1 -0
  34. package/src/date-input/DateInput.css.js +195 -0
  35. package/src/date-input/DateInput.js +210 -0
  36. package/src/date-input/index.js +1 -0
  37. package/src/date-picker/DatePicker.js +137 -0
  38. package/src/date-picker/DatePickerContext.js +20 -0
  39. package/src/date-picker/DatePickerPanel.css.js +25 -0
  40. package/src/date-picker/DatePickerPanel.js +124 -0
  41. package/src/date-picker/index.js +1 -0
  42. package/src/drag-drop/DragDropProvider.js +123 -0
  43. package/src/drag-drop/DragDropState.js +25 -0
  44. package/src/drag-drop/Draggable.css.js +57 -0
  45. package/src/drag-drop/Draggable.js +77 -0
  46. package/src/drag-drop/DropIndicator.css.js +11 -0
  47. package/src/drag-drop/DropIndicator.js +28 -0
  48. package/src/drag-drop/dragDropTypes.js +3 -0
  49. package/src/drag-drop/drop-target-utils.js +199 -0
  50. package/src/drag-drop/index.js +6 -0
  51. package/src/drag-drop/useAutoScroll.js +53 -0
  52. package/src/drag-drop/useDragDisplacers.js +126 -0
  53. package/src/drag-drop/useDragDrop.js +435 -0
  54. package/src/drag-drop/useDragDropCopy.js +22 -0
  55. package/src/drag-drop/useDragDropIndicator.js +182 -0
  56. package/src/drag-drop/useDragDropNaturalMovement.js +205 -0
  57. package/src/drag-drop/useDropIndicator.js +21 -0
  58. package/src/drag-drop/useGlobalDragDrop.js +67 -0
  59. package/src/drag-drop/useTransition.js +11 -0
  60. package/src/editable/index.js +1 -0
  61. package/src/editable/useEditableText.js +199 -0
  62. package/src/editable-label/EditableLabel.css.js +81 -0
  63. package/src/editable-label/EditableLabel.js +125 -0
  64. package/src/editable-label/index.js +1 -0
  65. package/src/expando-input/ExpandoInput.css.js +67 -0
  66. package/src/expando-input/ExpandoInput.js +40 -0
  67. package/src/expando-input/index.js +1 -0
  68. package/src/highlighter/Highlighter.css.js +8 -0
  69. package/src/highlighter/Highlighter.js +27 -0
  70. package/src/highlighter/index.js +1 -0
  71. package/src/hover-overlay/HoverOverlay.js +92 -0
  72. package/src/icon-button/Icon.css.js +8 -0
  73. package/src/icon-button/Icon.js +26 -0
  74. package/src/icon-button/IconButton.css.js +10 -0
  75. package/src/icon-button/IconButton.js +28 -0
  76. package/src/icon-button/ToggleIconButton.css.js +47 -0
  77. package/src/icon-button/ToggleIconButton.js +26 -0
  78. package/src/icon-button/index.js +3 -0
  79. package/src/index.js +31 -0
  80. package/src/instrument-picker/SearchCell.css.js +17 -0
  81. package/src/instrument-picker/SearchCell.js +29 -0
  82. package/src/instrument-picker/TablePicker.css.js +23 -0
  83. package/src/instrument-picker/TablePicker.js +89 -0
  84. package/src/instrument-picker/index.js +1 -0
  85. package/src/instrument-picker/moving-window.js +49 -0
  86. package/src/instrument-picker/useDataSource.js +38 -0
  87. package/src/instrument-picker/useTablePicker.js +136 -0
  88. package/src/measured-container/MeasuredContainer.css.js +11 -0
  89. package/src/measured-container/MeasuredContainer.js +50 -0
  90. package/src/measured-container/index.js +2 -0
  91. package/src/measured-container/useMeasuredContainer.js +156 -0
  92. package/src/modal-provider/ModalProvider.js +147 -0
  93. package/src/overflow-container/OverflowContainer.css.js +135 -0
  94. package/src/overflow-container/OverflowContainer.js +87 -0
  95. package/src/overflow-container/index.js +2 -0
  96. package/src/overflow-container/overflow-utils.js +211 -0
  97. package/src/overflow-container/useOverflowContainer.js +108 -0
  98. package/src/price-ticker/PriceTicker.css.js +32 -0
  99. package/src/price-ticker/PriceTicker.js +51 -0
  100. package/src/price-ticker/index.js +1 -0
  101. package/src/prompt/Prompt.css.js +48 -0
  102. package/src/prompt/Prompt.js +112 -0
  103. package/src/sortable-list/SortableList.js +39 -0
  104. package/src/split-button/SplitButton.css.js +117 -0
  105. package/src/split-button/SplitButton.js +60 -0
  106. package/src/split-button/SplitStateButton.css.js +66 -0
  107. package/src/split-button/SplitStateButton.js +23 -0
  108. package/src/split-button/index.js +2 -0
  109. package/src/split-button/useSplitButton.js +61 -0
  110. package/src/table-search/SearchCell.css.js +20 -0
  111. package/src/table-search/SearchCell.js +26 -0
  112. package/src/table-search/TableSearch.css.js +27 -0
  113. package/src/table-search/TableSearch.js +81 -0
  114. package/src/table-search/index.js +1 -0
  115. package/src/table-search/moving-window.js +49 -0
  116. package/src/table-search/useTableSearch.js +30 -0
  117. package/src/tabs-next/TabBar.css.js +26 -0
  118. package/src/tabs-next/TabBar.js +27 -0
  119. package/src/tabs-next/TabListNext.css.js +36 -0
  120. package/src/tabs-next/TabListNext.js +94 -0
  121. package/src/tabs-next/TabNext.css.js +76 -0
  122. package/src/tabs-next/TabNext.js +91 -0
  123. package/src/tabs-next/TabNextAction.js +26 -0
  124. package/src/tabs-next/TabNextContext.js +14 -0
  125. package/src/tabs-next/TabNextPanel.css.js +17 -0
  126. package/src/tabs-next/TabNextPanel.js +69 -0
  127. package/src/tabs-next/TabNextTrigger.css.js +22 -0
  128. package/src/tabs-next/TabNextTrigger.js +66 -0
  129. package/src/tabs-next/TabOverflowList.css.js +77 -0
  130. package/src/tabs-next/TabOverflowList.js +115 -0
  131. package/src/tabs-next/TabsNext.js +149 -0
  132. package/src/tabs-next/TabsNextContext.js +28 -0
  133. package/src/tabs-next/hooks/useCollection.js +80 -0
  134. package/src/tabs-next/hooks/useFocusOutside.js +23 -0
  135. package/src/tabs-next/hooks/useOverflow.js +118 -0
  136. package/src/tabs-next/index.js +7 -0
  137. package/src/tabstrip/Tab.css.js +148 -0
  138. package/src/tabstrip/Tab.js +107 -0
  139. package/src/tabstrip/TabMenu.css.js +8 -0
  140. package/src/tabstrip/TabMenu.js +48 -0
  141. package/src/tabstrip/TabMenuOptions.js +14 -0
  142. package/src/tabstrip/TabsTypes.js +0 -0
  143. package/src/tabstrip/Tabstrip.css.js +121 -0
  144. package/src/tabstrip/Tabstrip.js +106 -0
  145. package/src/tabstrip/ThemeTabstrip.css.js +20 -0
  146. package/src/tabstrip/index.js +4 -0
  147. package/src/tabstrip/tabstrip-dom-utils.js +11 -0
  148. package/src/tabstrip/useAnimatedSelectionThumb.js +68 -0
  149. package/src/tabstrip/useKeyboardNavigation.js +191 -0
  150. package/src/tabstrip/useSelection.js +50 -0
  151. package/src/tabstrip/useTabstrip.js +181 -0
  152. package/src/time-input/MaskedInput.js +285 -0
  153. package/src/time-input/TimeInput.css.js +39 -0
  154. package/src/time-input/TimeInput.js +37 -0
  155. package/src/time-input/useTimeInput.js +82 -0
  156. package/src/toolbar/Toolbar.css.js +46 -0
  157. package/src/toolbar/Toolbar.js +62 -0
  158. package/src/toolbar/index.js +1 -0
  159. package/src/toolbar/toolbar-dom-utils.js +11 -0
  160. package/src/toolbar/useKeyboardNavigation.js +240 -0
  161. package/src/toolbar/useSelection.js +82 -0
  162. package/src/toolbar/useToolbar.js +73 -0
  163. package/src/utils/deprecated-types.js +0 -0
  164. package/src/utils/escapeRegExp.js +5 -0
  165. package/src/utils/forwardCallbackProps.js +15 -0
  166. package/src/utils/index.js +5 -0
  167. package/src/utils/isOverflowElement.js +2 -0
  168. package/src/utils/isPlainObject.js +2 -0
  169. package/src/vuu-date-picker/VuuDatePicker.js +92 -0
  170. package/src/vuu-date-picker/index.js +1 -0
  171. package/src/vuu-input/VuuInput.css.js +13 -0
  172. package/src/vuu-input/VuuInput.js +85 -0
  173. package/src/vuu-input/index.js +1 -0
  174. package/src/vuu-time-picker/TimeRangePicker.js +0 -0
  175. package/src/vuu-time-picker/VuuTimePicker.css.js +14 -0
  176. package/src/vuu-time-picker/VuuTimePicker.js +26 -0
  177. package/src/vuu-typeahead-input/VuuTypeaheadInput.css.js +49 -0
  178. package/src/vuu-typeahead-input/VuuTypeaheadInput.js +46 -0
  179. package/src/vuu-typeahead-input/index.js +1 -0
  180. package/src/vuu-typeahead-input/useVuuTypeaheadInput.js +140 -0
@@ -0,0 +1,182 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { useCallback, useRef, useState } from "react";
3
+ import { useDropIndicator } from "./useDropIndicator.js";
4
+ import { dimensions, getItemById, getNextDropTarget, measureDropTargets, removeDraggedItem } from "./drop-target-utils.js";
5
+ import { Draggable, createDropIndicator } from "./Draggable.js";
6
+ const NOT_OVERFLOWED = ':not([data-overflowed="true"])';
7
+ const NOT_HIDDEN = ':not([aria-hidden="true"])';
8
+ const useDragDropIndicator = ({ orientation = "horizontal", containerRef, itemQuery = "*", selected, viewportRange })=>{
9
+ const dragDirectionRef = useRef(void 0);
10
+ const dropIndicatorRef = useRef(null);
11
+ const dropTargetRef = useRef(null);
12
+ const dropZoneRef = useRef("");
13
+ const isScrollable = useRef(false);
14
+ const dragPosRef = useRef(-1);
15
+ const measuredDropTargets = useRef([]);
16
+ const overflowMenuShowingRef = useRef(false);
17
+ const [showOverflow, setShowOverflow] = useState(false);
18
+ const [dropIndicator, setDropIndicator] = useState();
19
+ const { clearSpacer, positionDropIndicator } = useDropIndicator();
20
+ const draggedItemRef = useRef(void 0);
21
+ const fullItemQuery = `:is(${itemQuery}${NOT_OVERFLOWED}${NOT_HIDDEN},[data-overflow-indicator])`;
22
+ const indexOf = (dropTarget)=>measuredDropTargets.current.findIndex((d)=>d.id === dropTarget.id);
23
+ const reposition = (dropTarget, distance, indexShift)=>{
24
+ dropTarget.start += distance;
25
+ dropTarget.mid += distance;
26
+ dropTarget.end += distance;
27
+ if ("number" == typeof indexShift) dropTarget.currentIndex += indexShift;
28
+ };
29
+ const rangeRef = useRef(void 0);
30
+ rangeRef.current = viewportRange;
31
+ const handleScrollStart = useCallback(()=>{
32
+ clearSpacer();
33
+ }, [
34
+ clearSpacer
35
+ ]);
36
+ const handleScrollStop = useCallback((scrollDirection, _scrollPos, atEnd)=>{
37
+ const { current: container } = containerRef;
38
+ const { current: draggedItem } = draggedItemRef;
39
+ if (container && draggedItem) {
40
+ measuredDropTargets.current = measureDropTargets(container, orientation, fullItemQuery, rangeRef.current);
41
+ const { size } = draggedItem;
42
+ const dragPos = dragPosRef.current;
43
+ const midPos = dragPos + size / 2;
44
+ const { current: dropTargets } = measuredDropTargets;
45
+ const nextDropTarget = getNextDropTarget(dropTargets, midPos, size, "fwd");
46
+ if (nextDropTarget) atEnd && "fwd" === scrollDirection ? positionDropIndicator(dropTargets[dropTargets.length - 1], "start") : positionDropIndicator(nextDropTarget, "start");
47
+ }
48
+ }, [
49
+ containerRef,
50
+ positionDropIndicator,
51
+ fullItemQuery,
52
+ orientation
53
+ ]);
54
+ const beginDrag = useCallback((dragElement)=>{
55
+ if (dragElement.ariaSelected && Array.isArray(selected) && selected.length > 1) console.log("its a selected element, and we have a multi select");
56
+ const { current: container } = containerRef;
57
+ if (container && dragElement) {
58
+ const { SCROLL_SIZE, CLIENT_SIZE } = dimensions(orientation);
59
+ const { id: draggedItemId } = dragElement;
60
+ const { [SCROLL_SIZE]: scrollSize, [CLIENT_SIZE]: clientSize } = container;
61
+ isScrollable.current = scrollSize > clientSize;
62
+ const dropTargets = measuredDropTargets.current = measureDropTargets(container, orientation, fullItemQuery, viewportRange);
63
+ const draggedItem = getItemById(dropTargets, draggedItemId);
64
+ if (draggedItem && container) {
65
+ const targetIndex = indexOf(draggedItem);
66
+ removeDraggedItem(dropTargets, targetIndex);
67
+ draggedItemRef.current = draggedItem;
68
+ const { current: range } = rangeRef;
69
+ if (range?.atEnd) for(let i = 0; i < dropTargets.length; i++)reposition(dropTargets[i], draggedItem.size);
70
+ for(let i = targetIndex; i < dropTargets.length; i++)reposition(dropTargets[i], -draggedItem.size, -1);
71
+ const [dropTarget, dropZone] = draggedItem.isLast ? [
72
+ dropTargets[dropTargets.length - 1],
73
+ "end"
74
+ ] : [
75
+ dropTargets[targetIndex],
76
+ "start"
77
+ ];
78
+ dropTargetRef.current = dropTarget;
79
+ dropZoneRef.current = dropZone;
80
+ const dropIndicatorPosition = positionDropIndicator(dropTarget, dropZone);
81
+ const { top, left, width } = dropIndicatorPosition.getBoundingClientRect();
82
+ const dropIndicatorRect = {
83
+ top: draggedItem.isLast ? range?.atEnd && !range.atStart ? top + draggedItem.size - 2 : top - 2 : top - draggedItem.size - 2,
84
+ left,
85
+ width,
86
+ height: 2
87
+ };
88
+ setDropIndicator(/*#__PURE__*/ jsx(Draggable, {
89
+ wrapperClassName: "dropIndicatorContainer",
90
+ style: dropIndicatorRect,
91
+ ref: dropIndicatorRef,
92
+ element: createDropIndicator()
93
+ }));
94
+ }
95
+ }
96
+ }, [
97
+ selected,
98
+ containerRef,
99
+ orientation,
100
+ fullItemQuery,
101
+ viewportRange,
102
+ positionDropIndicator
103
+ ]);
104
+ const drag = useCallback((dragPos, mouseMoveDirection)=>{
105
+ const { current: currentDropTarget } = dropTargetRef;
106
+ const { current: draggedItem } = draggedItemRef;
107
+ if (draggedItem) {
108
+ if (containerRef.current) {
109
+ const START = "horizontal" === orientation ? "left" : "top";
110
+ dragPosRef.current = dragPos;
111
+ const { current: dropTargets } = measuredDropTargets;
112
+ const nextDropTarget = getNextDropTarget(dropTargets, dragPos, draggedItem.size, mouseMoveDirection);
113
+ if (nextDropTarget && nextDropTarget.index !== currentDropTarget?.index) {
114
+ if (nextDropTarget.isOverflowIndicator) setShowOverflow(overflowMenuShowingRef.current = true);
115
+ else if (dropIndicatorRef.current) {
116
+ const targetIndex = indexOf(nextDropTarget);
117
+ if (targetIndex === dropTargets.length - 1) {
118
+ const dropTarget = dropTargets[dropTargets.length - 1];
119
+ const dropIndicatorPosition = positionDropIndicator(dropTarget, "start");
120
+ const dropIndicatorRect = dropIndicatorPosition.getBoundingClientRect();
121
+ dropIndicatorRef.current.style[START] = `${dropIndicatorRect.top}px`;
122
+ } else {
123
+ const dropIndicatorPosition = positionDropIndicator(nextDropTarget, "start");
124
+ const dropIndicatorRect = dropIndicatorPosition.getBoundingClientRect();
125
+ dropIndicatorRef.current.style[START] = `${dropIndicatorRect.top}px`;
126
+ }
127
+ setShowOverflow(overflowMenuShowingRef.current = false);
128
+ }
129
+ dropTargetRef.current = nextDropTarget;
130
+ dragDirectionRef.current = mouseMoveDirection;
131
+ }
132
+ }
133
+ }
134
+ }, [
135
+ containerRef,
136
+ orientation,
137
+ positionDropIndicator
138
+ ]);
139
+ const drop = useCallback(()=>{
140
+ clearSpacer();
141
+ const { current: draggedItem } = draggedItemRef;
142
+ const { current: dropTarget } = dropTargetRef;
143
+ const { current: dropZone } = dropZoneRef;
144
+ const { current: range } = rangeRef;
145
+ if (draggedItem && range && dropTarget) {
146
+ const { index: fromIndex } = draggedItem;
147
+ const dropBefore = "start" === dropZone;
148
+ const { index: originalDropTargetIndex, currentIndex: currentDropTargetIndex } = dropTarget;
149
+ dropTargetRef.current = null;
150
+ dragDirectionRef.current = void 0;
151
+ setDropIndicator(void 0);
152
+ setShowOverflow(false);
153
+ if (overflowMenuShowingRef.current) return {
154
+ fromIndex,
155
+ toIndex: -1
156
+ };
157
+ if (fromIndex < originalDropTargetIndex) return {
158
+ fromIndex,
159
+ toIndex: dropBefore ? currentDropTargetIndex : currentDropTargetIndex + 1
160
+ };
161
+ return {
162
+ fromIndex,
163
+ toIndex: dropBefore ? originalDropTargetIndex : originalDropTargetIndex + 1
164
+ };
165
+ }
166
+ throw Error("useDragDropIndicator drop error");
167
+ }, [
168
+ clearSpacer
169
+ ]);
170
+ const releaseDrag = useCallback(()=>{}, []);
171
+ return {
172
+ beginDrag,
173
+ drag,
174
+ drop,
175
+ dropIndicator,
176
+ handleScrollStart,
177
+ handleScrollStop,
178
+ releaseDrag,
179
+ revealOverflowedItems: showOverflow
180
+ };
181
+ };
182
+ export { useDragDropIndicator };
@@ -0,0 +1,205 @@
1
+ import { useCallback, useMemo, useRef, useState } from "react";
2
+ import { useDragDisplacers } from "./useDragDisplacers.js";
3
+ import { dispatchMouseEvent } from "@vuu-ui/vuu-utils";
4
+ import { NOT_HIDDEN, NOT_OVERFLOWED, dimensions, getIndexOfDraggedItem, getItemParentContainer, getNextDropTarget, measureDropTargets } from "./drop-target-utils.js";
5
+ const useDragDropNaturalMovement = ({ containerRef, orientation = "horizontal", itemQuery = "*", selected, viewportRange })=>{
6
+ const dragPositionRef = useRef({
7
+ direction: void 0,
8
+ insertionPosition: -1
9
+ });
10
+ const isScrollable = useRef(false);
11
+ const dragPosRef = useRef(-1);
12
+ const measuredDropTargets = useRef([]);
13
+ const overflowMenuShowingRef = useRef(false);
14
+ const [showOverflow, setShowOverflow] = useState(false);
15
+ const { clearSpacers, displaceItem, displaceLastItem, setTerminalSpacer } = useDragDisplacers(orientation);
16
+ const draggedItemRef = useRef(void 0);
17
+ const fullItemQuery = `:is(${itemQuery}${NOT_OVERFLOWED}${NOT_HIDDEN},.vuuOverflowContainer-OverflowIndicator)`;
18
+ const indexOf = (dropTarget)=>measuredDropTargets.current.findIndex((d)=>d.id === dropTarget.id);
19
+ const rangeRef = useRef(void 0);
20
+ rangeRef.current = viewportRange;
21
+ const handleScrollStart = useCallback((scrollDirection)=>{
22
+ const itemContainer = getItemParentContainer(containerRef.current, itemQuery);
23
+ const { current: draggedItem } = draggedItemRef;
24
+ if (itemContainer && draggedItem) setTerminalSpacer(itemContainer, "fwd" === scrollDirection ? "end" : "start", draggedItem.size);
25
+ }, [
26
+ containerRef,
27
+ itemQuery,
28
+ setTerminalSpacer
29
+ ]);
30
+ const handleScrollStop = useCallback((scrollDirection)=>{
31
+ const { current: container } = containerRef;
32
+ const { current: draggedItem } = draggedItemRef;
33
+ const { current: dragPosition } = dragPositionRef;
34
+ if (container && draggedItem) {
35
+ const dropTargets = measuredDropTargets.current = measureDropTargets(container, orientation, fullItemQuery, rangeRef.current);
36
+ const dropTargetAtBoundary = "fwd" === scrollDirection ? dropTargets.at(-1) : dropTargets.at(0);
37
+ if (dropTargetAtBoundary) {
38
+ const { mid, end, size, start } = dropTargetAtBoundary;
39
+ if ("fwd" === scrollDirection) {
40
+ const draggedDropTarget = {
41
+ ...draggedItem,
42
+ start: Math.round(start + size),
43
+ mid: Math.round(mid + size),
44
+ end: Math.round(end + size)
45
+ };
46
+ dropTargets.push(draggedDropTarget);
47
+ dragPosition.insertionPosition = dropTargetAtBoundary.index + 1;
48
+ } else {
49
+ const draggedDropTarget = {
50
+ ...draggedItem,
51
+ start: Math.round(start - size),
52
+ mid: Math.round(mid - size),
53
+ end: Math.round(end - size)
54
+ };
55
+ dropTargets.unshift(draggedDropTarget);
56
+ dragPosition.insertionPosition = 0;
57
+ }
58
+ }
59
+ }
60
+ }, [
61
+ containerRef,
62
+ fullItemQuery,
63
+ orientation
64
+ ]);
65
+ const beginDrag = useCallback((dragElement)=>{
66
+ if (dragElement.ariaSelected && Array.isArray(selected) && selected.length > 1) console.log("its a selected element, and we have a multi select");
67
+ const { current: container } = containerRef;
68
+ const { current: dragPosition } = dragPositionRef;
69
+ if (container && dragElement) {
70
+ const internalDrag = container.contains(dragElement);
71
+ const { SCROLL_SIZE, CLIENT_SIZE } = dimensions(orientation);
72
+ const { id: draggedItemId } = dragElement;
73
+ const { [SCROLL_SIZE]: scrollSize, [CLIENT_SIZE]: clientSize } = container;
74
+ isScrollable.current = scrollSize > clientSize;
75
+ const dropTargets = measuredDropTargets.current = measureDropTargets(container, orientation, fullItemQuery, viewportRange, draggedItemId);
76
+ if (internalDrag) {
77
+ const indexOfDraggedItem = getIndexOfDraggedItem(dropTargets);
78
+ const draggedItem = dropTargets[indexOfDraggedItem];
79
+ if (draggedItem && container) {
80
+ draggedItemRef.current = draggedItem;
81
+ const displaceFunction = draggedItem.isLast ? displaceLastItem : displaceItem;
82
+ dragPosition.insertionPosition = displaceFunction(dropTargets, draggedItem, draggedItem.size, false, "static");
83
+ }
84
+ } else {
85
+ const { top: dragPos, height: size } = dragElement.getBoundingClientRect();
86
+ const dropTarget = getNextDropTarget(dropTargets, dragPos, size, "fwd");
87
+ const index = dropTargets.indexOf(dropTarget);
88
+ const { start, end, mid } = dropTarget;
89
+ const draggedItem = draggedItemRef.current = {
90
+ end,
91
+ mid,
92
+ start,
93
+ isDraggedItem: true,
94
+ isExternal: true,
95
+ size
96
+ };
97
+ const indexOfDropTarget = dropTargets.indexOf(dropTarget);
98
+ dropTargets.splice(indexOfDropTarget, 0, draggedItem);
99
+ for(let i = index + 1; i < dropTargets.length; i++){
100
+ const target = dropTargets[i];
101
+ target.mid += size;
102
+ target.end += size;
103
+ target.start += size;
104
+ }
105
+ const displaceFunction = dropTarget.isLast ? displaceLastItem : displaceItem;
106
+ displaceFunction(dropTargets, dropTarget, dropTarget.size, true, "static");
107
+ }
108
+ }
109
+ }, [
110
+ containerRef,
111
+ displaceItem,
112
+ displaceLastItem,
113
+ fullItemQuery,
114
+ orientation,
115
+ selected,
116
+ viewportRange
117
+ ]);
118
+ const [showPopup, hidePopup] = useMemo(()=>{
119
+ let popupShowing = false;
120
+ const show = (dropTarget)=>{
121
+ if (!popupShowing) {
122
+ popupShowing = true;
123
+ const button = dropTarget.element.querySelector(".vuuPopupMenu");
124
+ if (button) dispatchMouseEvent(button, "click");
125
+ }
126
+ };
127
+ const hide = (dropTarget)=>{
128
+ if (popupShowing) {
129
+ popupShowing = false;
130
+ const button = dropTarget.element.querySelector(".vuuPopupMenu");
131
+ if (button) dispatchMouseEvent(button, "click");
132
+ }
133
+ };
134
+ return [
135
+ show,
136
+ hide
137
+ ];
138
+ }, []);
139
+ const drag = useCallback((dragPos, mouseMoveDirection)=>{
140
+ const { current: draggedItem } = draggedItemRef;
141
+ const { current: dragPosition } = dragPositionRef;
142
+ if (draggedItem) {
143
+ if (containerRef.current) {
144
+ dragPosRef.current = dragPos;
145
+ const { current: dropTargets } = measuredDropTargets;
146
+ const nextDropTarget = getNextDropTarget(dropTargets, dragPos, draggedItem.size, mouseMoveDirection);
147
+ if (nextDropTarget && !nextDropTarget.isDraggedItem) if (nextDropTarget.isOverflowIndicator) {
148
+ setShowOverflow(overflowMenuShowingRef.current = true);
149
+ showPopup(nextDropTarget);
150
+ } else {
151
+ const { size } = draggedItem;
152
+ const targetIndex = indexOf(nextDropTarget);
153
+ const displaceFunc = targetIndex === dropTargets.length - 1 ? displaceLastItem : displaceItem;
154
+ dragPosition.insertionPosition = displaceFunc(dropTargets, nextDropTarget, size, true, mouseMoveDirection);
155
+ const overflowIndicator = dropTargets.at(-1);
156
+ hidePopup(overflowIndicator);
157
+ setShowOverflow(overflowMenuShowingRef.current = false);
158
+ }
159
+ dragPosition.direction = mouseMoveDirection;
160
+ }
161
+ }
162
+ }, [
163
+ containerRef,
164
+ displaceItem,
165
+ displaceLastItem,
166
+ hidePopup,
167
+ showPopup
168
+ ]);
169
+ const drop = useCallback(()=>{
170
+ clearSpacers();
171
+ const { current: dropTargets } = measuredDropTargets;
172
+ const { current: dragPosition } = dragPositionRef;
173
+ const indexOfDraggedItem = getIndexOfDraggedItem(dropTargets);
174
+ const draggedItem = dropTargets[indexOfDraggedItem];
175
+ const { insertionPosition } = dragPosition;
176
+ const { index: fromIndex, isExternal } = draggedItem;
177
+ if (overflowMenuShowingRef.current) setShowOverflow(false);
178
+ dragPosition.direction = void 0;
179
+ dragPosition.insertionPosition = -1;
180
+ const isLastItem = indexOfDraggedItem === dropTargets.length - 1;
181
+ const toIndex = overflowMenuShowingRef.current ? -1 : fromIndex < insertionPosition && !isLastItem ? insertionPosition - 1 : insertionPosition;
182
+ return {
183
+ fromIndex,
184
+ toIndex,
185
+ isExternal
186
+ };
187
+ }, [
188
+ clearSpacers
189
+ ]);
190
+ const releaseDrag = useCallback(()=>{
191
+ clearSpacers(true);
192
+ }, [
193
+ clearSpacers
194
+ ]);
195
+ return {
196
+ beginDrag,
197
+ drag,
198
+ drop,
199
+ handleScrollStart,
200
+ handleScrollStop,
201
+ releaseDrag,
202
+ revealOverflowedItems: showOverflow
203
+ };
204
+ };
205
+ export { useDragDropNaturalMovement };
@@ -0,0 +1,21 @@
1
+ import { useCallback, useMemo } from "react";
2
+ import { createDropIndicatorPosition } from "./Draggable.js";
3
+ const SPACER_SIZE = 0;
4
+ const useDropIndicator = ()=>{
5
+ const spacer = useMemo(()=>createDropIndicatorPosition(), []);
6
+ const clearSpacer = useCallback(()=>spacer.remove(), [
7
+ spacer
8
+ ]);
9
+ const positionDropIndicator = useCallback((dropTarget, dropZone = "end")=>{
10
+ if ("end" === dropZone) dropTarget.element.after(spacer);
11
+ else dropTarget.element.before(spacer);
12
+ return spacer;
13
+ }, [
14
+ spacer
15
+ ]);
16
+ return {
17
+ positionDropIndicator,
18
+ clearSpacer
19
+ };
20
+ };
21
+ export { SPACER_SIZE, useDropIndicator };
@@ -0,0 +1,67 @@
1
+ import { boxContainsPoint, dispatchCustomEvent } from "@vuu-ui/vuu-utils";
2
+ import { useCallback, useRef } from "react";
3
+ const useGlobalDragDrop = ({ onDragOverDropTarget, onDrop })=>{
4
+ const dropTargetRef = useRef(void 0);
5
+ const measuredDropTargetsRef = useRef(void 0);
6
+ const dragDropStateRef = useRef(null);
7
+ const mousePosRef = useRef({
8
+ x: 0,
9
+ y: 0
10
+ });
11
+ const overDropTarget = useCallback((x, y)=>{
12
+ const { current: dropTargets } = measuredDropTargetsRef;
13
+ if (dropTargets) {
14
+ for (const [id, measuredTarget] of Object.entries(dropTargets))if (boxContainsPoint(measuredTarget, x, y)) return id;
15
+ }
16
+ }, []);
17
+ const dragMouseMoveHandler = useCallback((evt)=>{
18
+ const { clientX, clientY } = evt;
19
+ const { current: dragDropState } = dragDropStateRef;
20
+ mousePosRef.current.x = clientX;
21
+ mousePosRef.current.y = clientY;
22
+ if (dragDropState?.draggableElement) {
23
+ const { draggableElement, mouseOffset } = dragDropState;
24
+ const dragPosX = mousePosRef.current.x - mouseOffset.x;
25
+ const dragPosY = mousePosRef.current.y - mouseOffset.y;
26
+ draggableElement.style.top = `${dragPosY}px`;
27
+ draggableElement.style.left = `${dragPosX}px`;
28
+ const dropTargetId = overDropTarget(dragPosX, dragPosY);
29
+ if (dropTargetId) {
30
+ const dropTargetWillResumeDrag = onDragOverDropTarget(dropTargetId, dragDropState);
31
+ if (dropTargetWillResumeDrag) {
32
+ document.removeEventListener("mousemove", dragMouseMoveHandler, false);
33
+ document.removeEventListener("mouseup", dragMouseUpHandler, false);
34
+ dragDropStateRef.current = null;
35
+ dropTargetRef.current = void 0;
36
+ } else dropTargetRef.current = dropTargetId;
37
+ } else dropTargetRef.current = void 0;
38
+ }
39
+ }, []);
40
+ const dragMouseUpHandler = useCallback(()=>{
41
+ document.removeEventListener("mousemove", dragMouseMoveHandler, false);
42
+ document.removeEventListener("mouseup", dragMouseUpHandler, false);
43
+ const { current: dragDropState } = dragDropStateRef;
44
+ if (dragDropState) {
45
+ dragDropStateRef.current = null;
46
+ if (dropTargetRef.current) onDrop(dropTargetRef.current, dragDropState);
47
+ if (dragDropState.draggableElement) dispatchCustomEvent(dragDropState.draggableElement, "vuu-dropped");
48
+ }
49
+ }, [
50
+ dragMouseMoveHandler,
51
+ onDrop
52
+ ]);
53
+ const resumeDrag = useCallback((dragDropState)=>{
54
+ dragDropStateRef.current = dragDropState;
55
+ document.addEventListener("mousemove", dragMouseMoveHandler, false);
56
+ document.addEventListener("mouseup", dragMouseUpHandler, false);
57
+ return true;
58
+ }, [
59
+ dragMouseMoveHandler,
60
+ dragMouseUpHandler
61
+ ]);
62
+ return {
63
+ measuredDropTargetsRef,
64
+ resumeDrag
65
+ };
66
+ };
67
+ export { useGlobalDragDrop };
@@ -0,0 +1,11 @@
1
+ import { useCallback } from "react";
2
+ const animationDuration = "0.15s";
3
+ const useTransition = ()=>{
4
+ const applyTransition = useCallback((element, property, value)=>{
5
+ element.style.cssText = `${property}: ${value};transition: ${property} ${animationDuration};`;
6
+ }, []);
7
+ return {
8
+ applyTransition
9
+ };
10
+ };
11
+ export { useTransition };
@@ -0,0 +1 @@
1
+ export * from "./useEditableText.js";