@dreamtree-org/twreact-ui 2.0.3 → 2.0.5

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 (55) hide show
  1. package/README.md +17 -6
  2. package/ai-skills/dreamtree-ui.md +12 -5
  3. package/dist/ai-schema.json +150 -1
  4. package/dist/charts/index.d.ts +2 -1
  5. package/dist/charts/index.js +297 -12
  6. package/dist/components/charts/ChartFrame.d.ts +1 -0
  7. package/dist/components/charts/ChartFrame.d.ts.map +1 -1
  8. package/dist/components/charts/ScatterChart.d.ts +4 -0
  9. package/dist/components/charts/ScatterChart.d.ts.map +1 -0
  10. package/dist/components/charts/ScatterTooltip.d.ts +14 -0
  11. package/dist/components/charts/ScatterTooltip.d.ts.map +1 -0
  12. package/dist/components/charts/scatterData.d.ts +17 -0
  13. package/dist/components/charts/scatterData.d.ts.map +1 -0
  14. package/dist/components/core/DatePicker.d.ts.map +1 -1
  15. package/dist/components/core/DateRangePicker.d.ts.map +1 -1
  16. package/dist/components/core/Select.d.ts.map +1 -1
  17. package/dist/components/navigation/Navbar.d.ts.map +1 -1
  18. package/dist/components/navigation/Sidebar.d.ts +2 -0
  19. package/dist/components/navigation/Sidebar.d.ts.map +1 -1
  20. package/dist/components/utility/Sortable.d.ts.map +1 -1
  21. package/dist/components/utility/SortableGroup.d.ts +15 -0
  22. package/dist/components/utility/SortableGroup.d.ts.map +1 -0
  23. package/dist/esm/charts/index.js +1 -0
  24. package/dist/esm/components/charts/ChartFrame.js +5 -5
  25. package/dist/esm/components/charts/ScatterChart.js +204 -0
  26. package/dist/esm/components/charts/ScatterTooltip.js +61 -0
  27. package/dist/esm/components/charts/scatterData.js +43 -0
  28. package/dist/esm/components/core/DatePicker.js +4 -1
  29. package/dist/esm/components/core/DateRangePicker.js +6 -2
  30. package/dist/esm/components/core/Select.js +6 -2
  31. package/dist/esm/components/navigation/Navbar.js +23 -6
  32. package/dist/esm/components/navigation/Sidebar.js +9 -2
  33. package/dist/esm/components/utility/Sortable.js +70 -48
  34. package/dist/esm/components/utility/SortableGroup.js +48 -0
  35. package/dist/esm/hooks/useFocusTrap.js +21 -9
  36. package/dist/esm/hooks/useSortable.js +96 -30
  37. package/dist/esm/hooks/useSortableGroup.js +268 -0
  38. package/dist/esm/index.js +1 -0
  39. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  40. package/dist/hooks/useSortable.d.ts +12 -3
  41. package/dist/hooks/useSortable.d.ts.map +1 -1
  42. package/dist/hooks/useSortableGroup.d.ts +43 -0
  43. package/dist/hooks/useSortableGroup.d.ts.map +1 -0
  44. package/dist/index.css +1 -1
  45. package/dist/index.d.ts +2 -1
  46. package/dist/index.esm.css +1 -1
  47. package/dist/index.esm.js +936 -498
  48. package/dist/index.js +936 -497
  49. package/dist/types/charts.d.ts +28 -0
  50. package/dist/types/charts.d.ts.map +1 -1
  51. package/dist/types/index.d.ts +40 -1
  52. package/dist/types/index.d.ts.map +1 -1
  53. package/doc/README.md +2 -0
  54. package/mcp/catalog.snapshot.json +252 -14
  55. package/package.json +1 -1
@@ -3,47 +3,35 @@ import { objectWithoutProperties as _objectWithoutProperties, objectSpread2 as _
3
3
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
4
4
  import { forwardRef, useId, useMemo, useState, useRef, useCallback, useLayoutEffect, useEffect } from 'react';
5
5
  import { cn } from '../../utils/cn.js';
6
- import { DEFAULT_SORTABLE_MESSAGES, useSortableKeyboard, useSortablePointer } from '../../hooks/useSortable.js';
6
+ import { setRefs } from '../../utils/position.js';
7
+ import { DEFAULT_SORTABLE_MESSAGES, useSortableKeyboard, useSortablePointer, defaultGetKey, arrayMove, defaultGetItemLabel } from '../../hooks/useSortable.js';
8
+ import { useSortableGroupMember } from '../../hooks/useSortableGroup.js';
9
+ import { SortablePlaceholder } from './SortableGroup.js';
7
10
 
8
11
  var _excluded = ["items", "onReorder", "renderItem", "getKey", "getItemLabel", "disabled", "handle", "orientation", "as", "itemClassName", "messages", "className"];
9
12
  var useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
10
- var defaultGetKey = function defaultGetKey(item, index) {
11
- var _ref, _item$id;
12
- return (_ref = (_item$id = item === null || item === void 0 ? void 0 : item.id) !== null && _item$id !== void 0 ? _item$id : item === null || item === void 0 ? void 0 : item.key) !== null && _ref !== void 0 ? _ref : index;
13
- };
14
- var defaultGetItemLabel = function defaultGetItemLabel(item, index) {
15
- var _ref2, _ref3, _item$label;
16
- return typeof item === "string" || typeof item === "number" ? String(item) : (_ref2 = (_ref3 = (_item$label = item === null || item === void 0 ? void 0 : item.label) !== null && _item$label !== void 0 ? _item$label : item === null || item === void 0 ? void 0 : item.title) !== null && _ref3 !== void 0 ? _ref3 : item === null || item === void 0 ? void 0 : item.name) !== null && _ref2 !== void 0 ? _ref2 : "Item ".concat(index + 1);
17
- };
18
- function arrayMove(list, from, to) {
19
- var next = list.slice();
20
- var _next$splice = next.splice(from, 1),
21
- _next$splice2 = _slicedToArray(_next$splice, 1),
22
- moved = _next$splice2[0];
23
- next.splice(to, 0, moved);
24
- return next;
25
- }
26
- var Sortable = /*#__PURE__*/forwardRef(function (_ref4, ref) {
27
- var _ref4$items = _ref4.items,
28
- items = _ref4$items === void 0 ? [] : _ref4$items,
29
- onReorder = _ref4.onReorder,
30
- renderItem = _ref4.renderItem,
31
- _ref4$getKey = _ref4.getKey,
32
- getKey = _ref4$getKey === void 0 ? defaultGetKey : _ref4$getKey,
33
- _ref4$getItemLabel = _ref4.getItemLabel,
34
- getItemLabel = _ref4$getItemLabel === void 0 ? defaultGetItemLabel : _ref4$getItemLabel,
35
- _ref4$disabled = _ref4.disabled,
36
- disabled = _ref4$disabled === void 0 ? false : _ref4$disabled,
37
- _ref4$handle = _ref4.handle,
38
- handle = _ref4$handle === void 0 ? false : _ref4$handle,
39
- _ref4$orientation = _ref4.orientation,
40
- orientation = _ref4$orientation === void 0 ? "vertical" : _ref4$orientation,
41
- _ref4$as = _ref4.as,
42
- List = _ref4$as === void 0 ? "ul" : _ref4$as,
43
- itemClassName = _ref4.itemClassName,
44
- messages = _ref4.messages,
45
- className = _ref4.className,
46
- rest = _objectWithoutProperties(_ref4, _excluded);
13
+ var Sortable = /*#__PURE__*/forwardRef(function (_ref, ref) {
14
+ var _rest$ariaLabel;
15
+ var _ref$items = _ref.items,
16
+ items = _ref$items === void 0 ? [] : _ref$items,
17
+ onReorder = _ref.onReorder,
18
+ renderItem = _ref.renderItem,
19
+ _ref$getKey = _ref.getKey,
20
+ getKey = _ref$getKey === void 0 ? defaultGetKey : _ref$getKey,
21
+ _ref$getItemLabel = _ref.getItemLabel,
22
+ getItemLabel = _ref$getItemLabel === void 0 ? defaultGetItemLabel : _ref$getItemLabel,
23
+ _ref$disabled = _ref.disabled,
24
+ disabled = _ref$disabled === void 0 ? false : _ref$disabled,
25
+ _ref$handle = _ref.handle,
26
+ handle = _ref$handle === void 0 ? false : _ref$handle,
27
+ _ref$orientation = _ref.orientation,
28
+ orientation = _ref$orientation === void 0 ? "vertical" : _ref$orientation,
29
+ _ref$as = _ref.as,
30
+ List = _ref$as === void 0 ? "ul" : _ref$as,
31
+ itemClassName = _ref.itemClassName,
32
+ messages = _ref.messages,
33
+ className = _ref.className,
34
+ rest = _objectWithoutProperties(_ref, _excluded);
47
35
  var instructionsId = "sortable-instructions-".concat(useId());
48
36
  var text = useMemo(function () {
49
37
  return _objectSpread2(_objectSpread2({}, DEFAULT_SORTABLE_MESSAGES), messages);
@@ -58,6 +46,10 @@ var Sortable = /*#__PURE__*/forwardRef(function (_ref4, ref) {
58
46
  announcement = _useState4[0],
59
47
  setAnnouncement = _useState4[1];
60
48
  var nodes = useRef(new Map());
49
+ var listRef = useRef(null);
50
+ var setListRef = useCallback(function (node) {
51
+ return setRefs(node, listRef, ref);
52
+ }, [ref]);
61
53
  var itemKeys = items.map(function (item, i) {
62
54
  return getKey(item, i);
63
55
  });
@@ -91,13 +83,32 @@ var Sortable = /*#__PURE__*/forwardRef(function (_ref4, ref) {
91
83
  var nodeFor = useCallback(function (key) {
92
84
  return nodes.current.get(key);
93
85
  }, []);
86
+ // Inside a <SortableGroup>, `id` names this list; `cross` handles moves to other lists.
87
+ var _useSortableGroupMemb = useSortableGroupMember({
88
+ listId: rest.id,
89
+ label: (_rest$ariaLabel = rest["aria-label"]) !== null && _rest$ariaLabel !== void 0 ? _rest$ariaLabel : String(rest.id),
90
+ items: items,
91
+ itemKeys: itemKeys,
92
+ keys: keys,
93
+ getKey: getKey,
94
+ nodeFor: nodeFor,
95
+ listRef: listRef,
96
+ orientation: axis,
97
+ setDraft: setDraft,
98
+ announce: announce,
99
+ labelFor: labelFor
100
+ }),
101
+ cross = _useSortableGroupMemb.cross,
102
+ incoming = _useSortableGroupMemb.incoming,
103
+ outgoing = _useSortableGroupMemb.outgoing;
94
104
  var keyboard = useSortableKeyboard({
95
105
  keys: keys,
96
106
  setDraft: setDraft,
97
107
  commit: commit,
98
108
  announce: announce,
99
109
  labelFor: labelFor,
100
- orientation: axis
110
+ orientation: axis,
111
+ cross: cross
101
112
  });
102
113
  var pointer = useSortablePointer({
103
114
  keys: keys,
@@ -105,7 +116,8 @@ var Sortable = /*#__PURE__*/forwardRef(function (_ref4, ref) {
105
116
  commit: commit,
106
117
  nodeFor: nodeFor,
107
118
  orientation: axis,
108
- disabled: disabled
119
+ disabled: disabled,
120
+ cross: cross
109
121
  });
110
122
  // Moving DOM nodes can drop focus; keep it on the item being carried.
111
123
  useIsomorphicLayoutEffect(function () {
@@ -124,24 +136,30 @@ var Sortable = /*#__PURE__*/forwardRef(function (_ref4, ref) {
124
136
  var isNativeList = List === "ul" || List === "ol";
125
137
  var ItemTag = isNativeList ? "li" : "div";
126
138
  return jsxs(Fragment, {
127
- children: [jsx(List, _objectSpread2(_objectSpread2({
128
- ref: ref,
139
+ children: [jsxs(List, _objectSpread2(_objectSpread2({
140
+ ref: setListRef,
129
141
  className: cn("flex", axis === "horizontal" ? "flex-row gap-2" : "flex-col gap-2", className),
130
142
  "data-orientation": axis,
143
+ "data-drop-target": incoming ? incoming.allowed ? "allowed" : "refused" : undefined,
131
144
  role: isNativeList ? undefined : "list"
132
145
  }, rest), {}, {
133
- children: keys.map(function (key, index) {
146
+ children: [keys.flatMap(function (key, index) {
134
147
  var _byKey$get = byKey.get(key),
135
148
  item = _byKey$get.item,
136
149
  originalIndex = _byKey$get.index;
137
150
  var isGrabbed = keyboard.grabbed === key;
138
151
  var isDragging = pointer.dragging === key;
152
+ var isLeaving = outgoing !== null && (isGrabbed || isDragging);
139
153
  var startDrag = disabled ? undefined : pointer.startFor(key);
140
154
  // Whole-item drags wait for a long-press on touch so the page still scrolls.
141
155
  var startItemDrag = disabled || handle ? undefined : pointer.startFor(key, {
142
156
  longPress: true
143
157
  });
144
- return jsx(ItemTag, {
158
+ var placeholder = (incoming === null || incoming === void 0 ? void 0 : incoming.index) === index ? [jsx(SortablePlaceholder, {
159
+ as: ItemTag,
160
+ allowed: incoming.allowed
161
+ }, "dt-sortable-placeholder")] : [];
162
+ return placeholder.concat(jsx(ItemTag, {
145
163
  ref: function ref(node) {
146
164
  if (node) nodes.current.set(key, node);else nodes.current["delete"](key);
147
165
  },
@@ -151,12 +169,13 @@ var Sortable = /*#__PURE__*/forwardRef(function (_ref4, ref) {
151
169
  role: isNativeList ? undefined : "listitem",
152
170
  "data-dragging": isDragging || undefined,
153
171
  "data-grabbed": isGrabbed || undefined,
172
+ "data-leaving": isLeaving ? outgoing.allowed ? "allowed" : "refused" : undefined,
154
173
  onKeyDown: disabled ? undefined : keyboard.keyDownFor(key),
155
174
  onBlur: function onBlur(e) {
156
175
  if (isGrabbed && e.relatedTarget && !e.currentTarget.contains(e.relatedTarget)) keyboard.cancel();
157
176
  },
158
177
  onPointerDown: startItemDrag,
159
- className: cn("rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500 dark:focus:ring-offset-gray-900", !disabled && !handle && "cursor-grab select-none [-webkit-touch-callout:none]", (isGrabbed || isDragging) && "relative z-10 shadow-lg ring-2 ring-primary-500 opacity-90", itemClassName),
178
+ className: cn("rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500 dark:focus:ring-offset-gray-900", !disabled && !handle && "cursor-grab select-none [-webkit-touch-callout:none]", (isGrabbed || isDragging) && "relative z-10 shadow-lg ring-2 ring-primary-500 opacity-90", isLeaving && (outgoing.allowed ? "opacity-50" : "cursor-not-allowed ring-error-500 opacity-50"), itemClassName),
160
179
  children: renderItem ? renderItem(item, {
161
180
  index: index,
162
181
  originalIndex: originalIndex,
@@ -174,12 +193,15 @@ var Sortable = /*#__PURE__*/forwardRef(function (_ref4, ref) {
174
193
  return moveBy(originalIndex, 1);
175
194
  }
176
195
  }) : labelFor(key)
177
- }, key);
178
- })
196
+ }, key));
197
+ }), incoming && incoming.index >= keys.length && jsx(SortablePlaceholder, {
198
+ as: ItemTag,
199
+ allowed: incoming.allowed
200
+ })]
179
201
  })), jsx("span", {
180
202
  id: instructionsId,
181
203
  className: "sr-only",
182
- children: text.instructions
204
+ children: cross ? "".concat(text.instructions, " ").concat(text.groupInstructions) : text.instructions
183
205
  }), jsx("span", {
184
206
  role: "status",
185
207
  "aria-live": "assertive",
@@ -0,0 +1,48 @@
1
+ 'use client';
2
+ import { objectWithoutProperties as _objectWithoutProperties, objectSpread2 as _objectSpread2 } from '../../_virtual/_rollupPluginBabelHelpers.js';
3
+ import { jsx } from 'react/jsx-runtime';
4
+ import { forwardRef } from 'react';
5
+ import { cn } from '../../utils/cn.js';
6
+ import { useSortableGroupState, SortableGroupContext } from '../../hooks/useSortableGroup.js';
7
+
8
+ var _excluded = ["onMove", "canDrop", "className", "children"];
9
+ /**
10
+ * Connects several `<Sortable id="…">` lists so items can move between them
11
+ * (pointer drag, or the cross-axis arrow keys while an item is picked up).
12
+ * `canDrop(item, target, from)` is asked before a target is shown as droppable;
13
+ * a refused target is marked as such and dropping there does nothing.
14
+ */
15
+ var SortableGroup = /*#__PURE__*/forwardRef(function (_ref, ref) {
16
+ var onMove = _ref.onMove,
17
+ canDrop = _ref.canDrop,
18
+ className = _ref.className,
19
+ children = _ref.children,
20
+ rest = _objectWithoutProperties(_ref, _excluded);
21
+ var value = useSortableGroupState({
22
+ onMove: onMove,
23
+ canDrop: canDrop
24
+ });
25
+ return jsx(SortableGroupContext.Provider, {
26
+ value: value,
27
+ children: jsx("div", _objectSpread2(_objectSpread2({
28
+ ref: ref,
29
+ className: cn(className),
30
+ "data-sortable-group": ""
31
+ }, rest), {}, {
32
+ children: children
33
+ }))
34
+ });
35
+ });
36
+ SortableGroup.displayName = "SortableGroup";
37
+ /** Where an item from another list would land; styled by whether `canDrop` allows it. */
38
+ function SortablePlaceholder(_ref2) {
39
+ var Tag = _ref2.as,
40
+ allowed = _ref2.allowed;
41
+ return jsx(Tag, {
42
+ "aria-hidden": "true",
43
+ "data-sortable-placeholder": allowed ? "allowed" : "refused",
44
+ className: cn("min-h-10 rounded-md border-2 border-dashed", allowed ? "border-primary-500 bg-primary-50 dark:bg-primary-950/40" : "cursor-not-allowed border-error-500 bg-error-50 opacity-60 dark:bg-error-950/40")
45
+ });
46
+ }
47
+
48
+ export { SortablePlaceholder, SortableGroup as default };
@@ -5,9 +5,29 @@ import { useLatestRef } from './useLatestRef.js';
5
5
  // Internal (not exported from the package). Shared focus management for the
6
6
  // overlay primitives (Drawer, Dialog, Popover, Tour, Sidebar, AppShell).
7
7
  var FOCUSABLE_SELECTOR = ["a[href]", "button:not([disabled])", "textarea:not([disabled])", "input:not([disabled])", "select:not([disabled])", '[tabindex]:not([tabindex="-1"])'].join(",");
8
+ // A responsive drawer (Sidebar's `md:hidden`, AppShell's `lg:hidden`) can be
9
+ // "open" while CSS hides it on wide viewports; there is nothing to trap then.
10
+ // `stopAt` (exclusive) bounds the walk, so getFocusable checks only the
11
+ // elements between a candidate and its root.
12
+ var isDisplayNone = function isDisplayNone(el) {
13
+ var stopAt = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
14
+ for (var node = el; node && node.nodeType === 1 && node !== stopAt; node = node.parentElement) {
15
+ if (window.getComputedStyle(node).display === "none") return true;
16
+ }
17
+ return false;
18
+ };
19
+ // `.focus()` silently fails on an element that is not rendered (`display:none`
20
+ // on it or an ancestor) or is `visibility:hidden` (inherited, so the element's
21
+ // own computed value covers its ancestors). getClientRects() is not used:
22
+ // jsdom reports empty rects for every element.
23
+ var isRendered = function isRendered(el, root) {
24
+ return window.getComputedStyle(el).visibility !== "hidden" && !isDisplayNone(el, root);
25
+ };
26
+ // Tabbable, rendered descendants of `root`, in DOM order. Used for the initial
27
+ // focus and for the Tab trap's first/last items.
8
28
  var getFocusable = function getFocusable(root) {
9
29
  return root ? Array.from(root.querySelectorAll(FOCUSABLE_SELECTOR)).filter(function (el) {
10
- return el.getAttribute("aria-hidden") !== "true";
30
+ return el.getAttribute("aria-hidden") !== "true" && isRendered(el, root);
11
31
  }) : [];
12
32
  };
13
33
  // Only the most recently opened overlay reacts to Escape / Tab, so a Popover
@@ -16,14 +36,6 @@ var layerStack = [];
16
36
  var isTopLayer = function isTopLayer(token) {
17
37
  return layerStack[layerStack.length - 1] === token;
18
38
  };
19
- // A responsive drawer (Sidebar's `md:hidden`, AppShell's `lg:hidden`) can be
20
- // "open" while CSS hides it on wide viewports; there is nothing to trap then.
21
- var isDisplayNone = function isDisplayNone(el) {
22
- for (var node = el; node && node.nodeType === 1; node = node.parentElement) {
23
- if (window.getComputedStyle(node).display === "none") return true;
24
- }
25
- return false;
26
- };
27
39
  function cycleFocus(e, panel) {
28
40
  if (isDisplayNone(panel)) return;
29
41
  var focusables = getFocusable(panel);
@@ -5,7 +5,25 @@ import { useLatestRef } from './useLatestRef.js';
5
5
 
6
6
  // Internal (not exported). Keyboard + pointer reordering for Sortable. Both
7
7
  // work on a draft list of keys while the user is moving an item and only call
8
- // `commit(fromIndex, toIndex)` when the item is dropped.
8
+ // `commit(fromIndex, toIndex)` when the item is dropped. Inside a SortableGroup
9
+ // they also get a `cross` object (see useSortableGroup.js) that takes over when
10
+ // the item is carried into another list; without one they behave as before.
11
+ var defaultGetKey = function defaultGetKey(item, index) {
12
+ var _ref, _item$id;
13
+ return (_ref = (_item$id = item === null || item === void 0 ? void 0 : item.id) !== null && _item$id !== void 0 ? _item$id : item === null || item === void 0 ? void 0 : item.key) !== null && _ref !== void 0 ? _ref : index;
14
+ };
15
+ var defaultGetItemLabel = function defaultGetItemLabel(item, index) {
16
+ var _ref2, _ref3, _item$label;
17
+ return typeof item === "string" || typeof item === "number" ? String(item) : (_ref2 = (_ref3 = (_item$label = item === null || item === void 0 ? void 0 : item.label) !== null && _item$label !== void 0 ? _item$label : item === null || item === void 0 ? void 0 : item.title) !== null && _ref3 !== void 0 ? _ref3 : item === null || item === void 0 ? void 0 : item.name) !== null && _ref2 !== void 0 ? _ref2 : "Item ".concat(index + 1);
18
+ };
19
+ function arrayMove(list, from, to) {
20
+ var next = list.slice();
21
+ var _next$splice = next.splice(from, 1),
22
+ _next$splice2 = _slicedToArray(_next$splice, 1),
23
+ moved = _next$splice2[0];
24
+ next.splice(to, 0, moved);
25
+ return next;
26
+ }
9
27
  function moveKey(keys, key, toIndex) {
10
28
  var next = keys.filter(function (k) {
11
29
  return k !== key;
@@ -26,6 +44,17 @@ var DEFAULT_SORTABLE_MESSAGES = {
26
44
  },
27
45
  cancelled: function cancelled(label, position) {
28
46
  return "Reorder cancelled. ".concat(label, " returned to position ").concat(position, ".");
47
+ },
48
+ // Only used inside a SortableGroup.
49
+ groupInstructions: "Use the arrow keys across the list (Left and Right in a vertical list) to carry it to the previous or next list.",
50
+ movedToList: function movedToList(label, list, position, total) {
51
+ return "".concat(label, " moved to ").concat(list, ", position ").concat(position, " of ").concat(total, ".");
52
+ },
53
+ droppedInList: function droppedInList(label, list, position, total) {
54
+ return "".concat(label, " dropped in ").concat(list, " at position ").concat(position, " of ").concat(total, ".");
55
+ },
56
+ refused: function refused(label, list) {
57
+ return "".concat(label, " cannot be dropped in ").concat(list, ".");
29
58
  }
30
59
  };
31
60
  var PREV_KEYS = {
@@ -36,13 +65,31 @@ var NEXT_KEYS = {
36
65
  vertical: ["ArrowDown"],
37
66
  horizontal: ["ArrowRight"]
38
67
  };
39
- function useSortableKeyboard(_ref) {
40
- var keys = _ref.keys,
41
- setDraft = _ref.setDraft,
42
- commit = _ref.commit,
43
- announce = _ref.announce,
44
- labelFor = _ref.labelFor,
45
- orientation = _ref.orientation;
68
+ // Cross-axis arrows step between the lists of a SortableGroup.
69
+ var LIST_KEYS = {
70
+ vertical: {
71
+ ArrowLeft: -1,
72
+ ArrowRight: 1
73
+ },
74
+ horizontal: {
75
+ ArrowUp: -1,
76
+ ArrowDown: 1
77
+ }
78
+ };
79
+ var stepOf = function stepOf(e, orientation, cross) {
80
+ return {
81
+ delta: PREV_KEYS[orientation].includes(e.key) ? -1 : NEXT_KEYS[orientation].includes(e.key) ? 1 : 0,
82
+ list: cross ? LIST_KEYS[orientation][e.key] || 0 : 0
83
+ };
84
+ };
85
+ function useSortableKeyboard(_ref4) {
86
+ var keys = _ref4.keys,
87
+ setDraft = _ref4.setDraft,
88
+ commit = _ref4.commit,
89
+ announce = _ref4.announce,
90
+ labelFor = _ref4.labelFor,
91
+ orientation = _ref4.orientation,
92
+ cross = _ref4.cross;
46
93
  var _useState = useState(null),
47
94
  _useState2 = _slicedToArray(_useState, 2),
48
95
  grabbed = _useState2[0],
@@ -60,21 +107,27 @@ function useSortableKeyboard(_ref) {
60
107
  setGrabbed(key);
61
108
  setDraft(keys);
62
109
  announce("grabbed", labelFor(key), index + 1, total);
63
- } else {
64
- setGrabbed(null);
65
- commit(origin.current, index);
66
- announce("dropped", labelFor(key), index + 1, total);
110
+ return;
67
111
  }
112
+ var crossed = cross === null || cross === void 0 ? void 0 : cross.drop(key);
113
+ if (crossed === "refused") return;
114
+ setGrabbed(null);
115
+ if (crossed) return;
116
+ commit(origin.current, index);
117
+ announce("dropped", labelFor(key), index + 1, total);
68
118
  } else if (grabbed === key && e.key === "Escape") {
69
119
  e.preventDefault();
70
120
  setGrabbed(null);
71
121
  setDraft(null);
122
+ cross === null || cross === void 0 || cross.cancel();
72
123
  announce("cancelled", labelFor(key), origin.current + 1, total);
73
124
  } else if (grabbed === key) {
74
- var delta = PREV_KEYS[orientation].includes(e.key) ? -1 : NEXT_KEYS[orientation].includes(e.key) ? 1 : 0;
75
- if (!delta) return;
125
+ var step = stepOf(e, orientation, cross);
126
+ if (!step.delta && !step.list) return;
76
127
  e.preventDefault();
77
- var to = Math.max(0, Math.min(total - 1, index + delta));
128
+ if (step.list) return cross.step(key, step.list);
129
+ if (cross !== null && cross !== void 0 && cross.nudge(key, step.delta)) return;
130
+ var to = Math.max(0, Math.min(total - 1, index + step.delta));
78
131
  if (to === index) return;
79
132
  setDraft(moveKey(keys, key, to));
80
133
  announce("moved", labelFor(key), to + 1, total);
@@ -84,7 +137,8 @@ function useSortableKeyboard(_ref) {
84
137
  var cancel = useCallback(function () {
85
138
  setGrabbed(null);
86
139
  setDraft(null);
87
- }, [setDraft]);
140
+ cross === null || cross === void 0 || cross.cancel();
141
+ }, [setDraft, cross]);
88
142
  return {
89
143
  grabbed: grabbed,
90
144
  keyDownFor: keyDownFor,
@@ -130,13 +184,14 @@ var raf = function raf(cb) {
130
184
  var caf = function caf(id) {
131
185
  return typeof window.cancelAnimationFrame === "function" ? window.cancelAnimationFrame(id) : clearTimeout(id);
132
186
  };
133
- function useSortablePointer(_ref2) {
134
- var keys = _ref2.keys,
135
- setDraft = _ref2.setDraft,
136
- commit = _ref2.commit,
137
- nodeFor = _ref2.nodeFor,
138
- orientation = _ref2.orientation,
139
- disabled = _ref2.disabled;
187
+ function useSortablePointer(_ref5) {
188
+ var keys = _ref5.keys,
189
+ setDraft = _ref5.setDraft,
190
+ commit = _ref5.commit,
191
+ nodeFor = _ref5.nodeFor,
192
+ orientation = _ref5.orientation,
193
+ disabled = _ref5.disabled,
194
+ cross = _ref5.cross;
140
195
  var _useState3 = useState(null),
141
196
  _useState4 = _slicedToArray(_useState3, 2),
142
197
  dragging = _useState4[0],
@@ -146,7 +201,8 @@ function useSortablePointer(_ref2) {
146
201
  keys: keys,
147
202
  commit: commit,
148
203
  nodeFor: nodeFor,
149
- orientation: orientation
204
+ orientation: orientation,
205
+ cross: cross
150
206
  });
151
207
  var end = useCallback(function () {
152
208
  var _session$current;
@@ -175,9 +231,9 @@ function useSortablePointer(_ref2) {
175
231
  // `longPress`: on touch, wait LONG_PRESS_DELAY before picking the item up (used
176
232
  // when the whole item is the drag source, so the list still scrolls on swipe).
177
233
  var startFor = function startFor(key) {
178
- var _ref3 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
179
- _ref3$longPress = _ref3.longPress,
180
- longPress = _ref3$longPress === void 0 ? false : _ref3$longPress;
234
+ var _ref6 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
235
+ _ref6$longPress = _ref6.longPress,
236
+ longPress = _ref6$longPress === void 0 ? false : _ref6$longPress;
181
237
  return function (e) {
182
238
  if (disabled || e.button > 0) return;
183
239
  var start = {
@@ -190,6 +246,12 @@ function useSortablePointer(_ref2) {
190
246
  var point = start;
191
247
  var pressTimer = null;
192
248
  var frame = null;
249
+ // Over another list of the group, the source list keeps its original order
250
+ // and the target list shows where the item would land.
251
+ var track = function track() {
252
+ var _latest$current$cross;
253
+ if ((_latest$current$cross = latest.current.cross) !== null && _latest$current$cross !== void 0 && _latest$current$cross.over(point, key)) setDraft(null);else setDraft(moveKey(latest.current.keys, key, targetIndex(point, key)));
254
+ };
193
255
  var scrollTarget = function scrollTarget() {
194
256
  return getScrollParent(latest.current.nodeFor(key), latest.current.orientation);
195
257
  };
@@ -214,7 +276,7 @@ function useSortablePointer(_ref2) {
214
276
  } else if (typeof window.scrollBy === "function") {
215
277
  window.scrollBy(dx, dy);
216
278
  }
217
- setDraft(moveKey(latest.current.keys, key, targetIndex(point, key)));
279
+ track();
218
280
  frame = raf(_autoScroll);
219
281
  };
220
282
  var activate = function activate() {
@@ -236,20 +298,24 @@ function useSortablePointer(_ref2) {
236
298
  if (distance < DRAG_THRESHOLD) return;
237
299
  activate();
238
300
  }
239
- setDraft(moveKey(latest.current.keys, key, targetIndex(point, key)));
301
+ track();
240
302
  if (frame === null) frame = raf(_autoScroll);
241
303
  };
242
304
  var onUp = function onUp() {
305
+ var _latest$current$cross2;
243
306
  end();
244
307
  if (!active) return;
245
308
  setDragging(null);
309
+ if ((_latest$current$cross2 = latest.current.cross) !== null && _latest$current$cross2 !== void 0 && _latest$current$cross2.release()) return;
246
310
  latest.current.commit(from, latest.current.keys.indexOf(key));
247
311
  };
248
312
  var onCancel = function onCancel() {
313
+ var _latest$current$cross3;
249
314
  end();
250
315
  if (!active) return;
251
316
  setDragging(null);
252
317
  setDraft(null);
318
+ (_latest$current$cross3 = latest.current.cross) === null || _latest$current$cross3 === void 0 || _latest$current$cross3.cancel();
253
319
  };
254
320
  // Once a touch drag is live, stop the browser from scrolling (and from firing
255
321
  // pointercancel); before that, let the page scroll normally.
@@ -287,4 +353,4 @@ function useSortablePointer(_ref2) {
287
353
  };
288
354
  }
289
355
 
290
- export { AUTO_SCROLL_EDGE, DEFAULT_SORTABLE_MESSAGES, DRAG_THRESHOLD, LONG_PRESS_DELAY, LONG_PRESS_TOLERANCE, edgeSpeed, getScrollParent, moveKey, useSortableKeyboard, useSortablePointer };
356
+ export { AUTO_SCROLL_EDGE, DEFAULT_SORTABLE_MESSAGES, DRAG_THRESHOLD, LONG_PRESS_DELAY, LONG_PRESS_TOLERANCE, arrayMove, defaultGetItemLabel, defaultGetKey, edgeSpeed, getScrollParent, moveKey, useSortableKeyboard, useSortablePointer };