@dxos/react-ui-mosaic 0.9.1-main.c7dcc2e112 → 0.10.0

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 (59) hide show
  1. package/dist/lib/browser/{chunk-DZ5WMCI2.mjs → chunk-OBVIYZLR.mjs} +177 -41
  2. package/dist/lib/browser/chunk-OBVIYZLR.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +2 -2
  4. package/dist/lib/browser/index.mjs.map +3 -3
  5. package/dist/lib/browser/meta.json +1 -1
  6. package/dist/lib/browser/testing/index.mjs +7 -5
  7. package/dist/lib/browser/testing/index.mjs.map +3 -3
  8. package/dist/lib/node-esm/{chunk-4IOJ5T6K.mjs → chunk-4IEMCMIV.mjs} +177 -41
  9. package/dist/lib/node-esm/chunk-4IEMCMIV.mjs.map +7 -0
  10. package/dist/lib/node-esm/index.mjs +2 -2
  11. package/dist/lib/node-esm/index.mjs.map +3 -3
  12. package/dist/lib/node-esm/meta.json +1 -1
  13. package/dist/lib/node-esm/testing/index.mjs +7 -5
  14. package/dist/lib/node-esm/testing/index.mjs.map +3 -3
  15. package/dist/types/src/components/Board/Board.d.ts +1 -1
  16. package/dist/types/src/components/Board/Board.d.ts.map +1 -1
  17. package/dist/types/src/components/Board/Board.stories.d.ts +2 -2
  18. package/dist/types/src/components/Board/Board.stories.d.ts.map +1 -1
  19. package/dist/types/src/components/Focus/Focus.d.ts +1 -1
  20. package/dist/types/src/components/Focus/Focus.d.ts.map +1 -1
  21. package/dist/types/src/components/Mosaic/Container.d.ts.map +1 -1
  22. package/dist/types/src/components/Mosaic/DragHandle.d.ts +28 -0
  23. package/dist/types/src/components/Mosaic/DragHandle.d.ts.map +1 -0
  24. package/dist/types/src/components/Mosaic/Mosaic.d.ts +17 -1
  25. package/dist/types/src/components/Mosaic/Mosaic.d.ts.map +1 -1
  26. package/dist/types/src/components/Mosaic/Placeholder.d.ts +2 -2
  27. package/dist/types/src/components/Mosaic/Placeholder.d.ts.map +1 -1
  28. package/dist/types/src/components/Mosaic/ResizeHandle.d.ts +14 -0
  29. package/dist/types/src/components/Mosaic/ResizeHandle.d.ts.map +1 -0
  30. package/dist/types/src/components/Mosaic/ResizeHandle.stories.d.ts +12 -0
  31. package/dist/types/src/components/Mosaic/ResizeHandle.stories.d.ts.map +1 -0
  32. package/dist/types/src/components/Mosaic/Root.d.ts +1 -1
  33. package/dist/types/src/components/Mosaic/Root.d.ts.map +1 -1
  34. package/dist/types/src/components/Mosaic/Stack.d.ts +1 -1
  35. package/dist/types/src/components/Mosaic/Stack.d.ts.map +1 -1
  36. package/dist/types/src/components/Mosaic/Tile.d.ts +34 -0
  37. package/dist/types/src/components/Mosaic/Tile.d.ts.map +1 -1
  38. package/dist/types/src/components/Mosaic/styles.d.ts.map +1 -1
  39. package/dist/types/src/testing/types.d.ts +10 -12
  40. package/dist/types/src/testing/types.d.ts.map +1 -1
  41. package/dist/types/tsconfig.tsbuildinfo +1 -1
  42. package/package.json +33 -33
  43. package/src/components/Board/Board.stories.tsx +3 -3
  44. package/src/components/Board/Board.tsx +1 -1
  45. package/src/components/Board/Item.tsx +1 -1
  46. package/src/components/Focus/Focus.tsx +1 -1
  47. package/src/components/Mosaic/Container.tsx +5 -7
  48. package/src/components/Mosaic/DragHandle.tsx +75 -0
  49. package/src/components/Mosaic/Mosaic.tsx +11 -5
  50. package/src/components/Mosaic/Placeholder.tsx +4 -2
  51. package/src/components/Mosaic/ResizeHandle.stories.tsx +119 -0
  52. package/src/components/Mosaic/ResizeHandle.tsx +56 -0
  53. package/src/components/Mosaic/Root.tsx +3 -1
  54. package/src/components/Mosaic/Stack.tsx +23 -2
  55. package/src/components/Mosaic/Tile.tsx +82 -4
  56. package/src/components/Mosaic/styles.ts +4 -3
  57. package/src/testing/types.ts +14 -14
  58. package/dist/lib/browser/chunk-DZ5WMCI2.mjs.map +0 -7
  59. package/dist/lib/node-esm/chunk-4IOJ5T6K.mjs.map +0 -7
@@ -40,9 +40,10 @@ var styles = {
40
40
  ],
41
41
  content: [
42
42
  "transition-all duration-0",
43
- // TODO(burdon): Don't animate open if placeholder is the source.
44
- // TODO(burdon): Flickers when start to drag since source is removed and then the placeholder shows up.
45
- // - Use absolute positioning?
43
+ // Placeholders open instantly (`duration-0`). The source slot is reserved on drag start by
44
+ // activating its placeholder (see Stack.tsx), so the stack no longer collapses/flickers when the
45
+ // dragged item is removed. NOTE: if the open animation below is ever enabled, exempt the source
46
+ // placeholder — animating its reserved gap from 0 would reintroduce the start-of-drag flicker.
46
47
  // 'group-data-[mosaic-placeholder-state=active]:duration-200',
47
48
  "group-data-[mosaic-placeholder-orientation=vertical]:h-0",
48
49
  "group-data-[mosaic-placeholder-orientation=vertical]:group-data-[mosaic-placeholder-state=active]:h-[var(--mosaic-placeholder-height)]",
@@ -143,6 +144,8 @@ var MosaicRoot = /* @__PURE__ */ forwardRef(({ children, asChild, debug }, forwa
143
144
  };
144
145
  let noTargetTimeout;
145
146
  return combine(monitorForElements({
147
+ // Only monitor Mosaic tile drags; other pragmatic-dnd sources under this root are not ours to handle.
148
+ canMonitor: ({ source }) => source.data.type === "tile",
146
149
  /**
147
150
  * Dragging started within any container.
148
151
  */
@@ -150,7 +153,7 @@ var MosaicRoot = /* @__PURE__ */ forwardRef(({ children, asChild, debug }, forwa
150
153
  log("Root.onDragStart", {
151
154
  source: source.data,
152
155
  location: location.current.dropTargets.map((target) => target.data)
153
- }, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 96, S: void 0 });
156
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 98, S: void 0 });
154
157
  handleChange({
155
158
  source,
156
159
  location
@@ -164,7 +167,7 @@ var MosaicRoot = /* @__PURE__ */ forwardRef(({ children, asChild, debug }, forwa
164
167
  log("Root.onDropTargetChange", {
165
168
  source: source.data,
166
169
  location: location.current.dropTargets.map((target) => target.data)
167
- }, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 109, S: void 0 });
170
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 111, S: void 0 });
168
171
  if (location.current.dropTargets.length === 0) {
169
172
  noTargetTimeout = setTimeout(() => setDragging(void 0), 1e3);
170
173
  } else {
@@ -198,18 +201,18 @@ var MosaicRoot = /* @__PURE__ */ forwardRef(({ children, asChild, debug }, forwa
198
201
  log.info("Root.onDrop", {
199
202
  source: source.data,
200
203
  location: location.current.dropTargets.map((target) => target.data)
201
- }, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 142, S: void 0 });
204
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 144, S: void 0 });
202
205
  const { data: sourceData, handler: sourceHandler } = getSourceHandler(source);
203
206
  if (!sourceHandler) {
204
207
  log.warn("invalid source", {
205
208
  source: sourceData,
206
209
  handlers: Object.keys(handlers)
207
- }, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 149, S: void 0 });
210
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 151, S: void 0 });
208
211
  return;
209
212
  }
210
213
  try {
211
214
  if (location.current.dropTargets.length === 0) {
212
- log.info("cancelled", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 163, S: void 0 });
215
+ log.info("cancelled", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 165, S: void 0 });
213
216
  } else {
214
217
  const { data: targetData, handler: targetHandler } = getTargetHandler(location);
215
218
  if (!targetHandler) {
@@ -217,7 +220,7 @@ var MosaicRoot = /* @__PURE__ */ forwardRef(({ children, asChild, debug }, forwa
217
220
  source: sourceData,
218
221
  location,
219
222
  handlers: Object.keys(handlers)
220
- }, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 168, S: void 0 });
223
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 170, S: void 0 });
221
224
  return;
222
225
  }
223
226
  if (sourceHandler === targetHandler) {
@@ -229,7 +232,7 @@ var MosaicRoot = /* @__PURE__ */ forwardRef(({ children, asChild, debug }, forwa
229
232
  if (!sourceHandler.onTake) {
230
233
  log.warn("invalid source", {
231
234
  source: sourceData
232
- }, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 183, S: void 0 });
235
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 185, S: void 0 });
233
236
  return;
234
237
  }
235
238
  sourceHandler.onTake?.({
@@ -391,10 +394,8 @@ var MosaicContainer = composable(({ children, eventHandler: eventHandlerProp, or
391
394
  source: data2
392
395
  }) || false;
393
396
  },
394
- // TODO(burdon): Provide semantic intent to onDrop.
395
- // getDropEffect: () => {
396
- // return 'move';
397
- // },
397
+ // Reorder is a move, not a copy — otherwise the browser shows the green "+" copy cursor.
398
+ getDropEffect: () => "move",
398
399
  /**
399
400
  * Dragging started in this container.
400
401
  */
@@ -443,9 +444,9 @@ var MosaicContainer = composable(({ children, eventHandler: eventHandlerProp, or
443
444
  autoscrollElement && [
444
445
  autoScrollForElements({
445
446
  element: autoscrollElement,
446
- // canScroll: ({ element: _ }) => {
447
- // return true;
448
- // },
447
+ // Only autoscroll for tile (reorder) drags. Resize-handle drags carry no tile data, so
448
+ // resizing a tile near a viewport edge must not scroll the container.
449
+ canScroll: ({ source }) => getSourceData(source) != null,
449
450
  getAllowedAxis: () => orientation,
450
451
  getConfiguration: () => ({
451
452
  maxScrollSpeed: "fast"
@@ -502,13 +503,14 @@ import { composeRefs } from "@radix-ui/react-compose-refs";
502
503
  import { createContext as createContext3 } from "@radix-ui/react-context";
503
504
  import { Primitive as Primitive3 } from "@radix-ui/react-primitive";
504
505
  import { Slot as Slot3 } from "@radix-ui/react-slot";
505
- import React3, { useLayoutEffect, useMemo as useMemo3, useRef as useRef3, useState as useState3 } from "react";
506
+ import React3, { useCallback as useCallback3, useLayoutEffect, useMemo as useMemo3, useRef as useRef3, useState as useState3 } from "react";
506
507
  import { createPortal } from "react-dom";
507
508
  import { composableProps as composableProps2, slottable } from "@dxos/react-ui";
509
+ import { resizeAttributes, sizeStyle } from "@dxos/react-ui-dnd";
508
510
  var MOSAIC_TILE_NAME = "Mosaic.Tile";
509
511
  var [MosaicTileContextProvider, useMosaicTileContext] = createContext3("MosaicTile");
510
512
  var MOSAIC_TILE_STATE_ATTR = "mosaic-tile-state";
511
- var MosaicTile = slottable(({ children, asChild, dragHandle, allowedEdges: allowedEdgesProp, location, id, data: dataProp, draggable: draggableProp, current, selected, debug: _, ...props }, forwardedRef) => {
513
+ var MosaicTile = slottable(({ children, asChild, dragHandle: dragHandleProp, allowedEdges: allowedEdgesProp, location, id, data: dataProp, draggable: draggableProp, current, selected, size: sizeProp, onSizeChange, minSize, maxSize, debug: _, ...props }, forwardedRef) => {
512
514
  const Comp = asChild ? Slot3 : Primitive3.div;
513
515
  const rootRef = useRef3(null);
514
516
  const composedRef = composeRefs(rootRef, forwardedRef);
@@ -516,6 +518,17 @@ var MosaicTile = slottable(({ children, asChild, dragHandle, allowedEdges: allow
516
518
  const [state, setState] = useState3({
517
519
  type: "idle"
518
520
  });
521
+ const [registeredDragHandle, setRegisteredDragHandle] = useState3(null);
522
+ const dragHandle = dragHandleProp ?? registeredDragHandle;
523
+ const [size, setInternalSize] = useState3(sizeProp);
524
+ const setSize = useCallback3((nextSize, commit) => {
525
+ setInternalSize(nextSize);
526
+ if (commit) {
527
+ onSizeChange?.(nextSize);
528
+ }
529
+ }, [
530
+ onSizeChange
531
+ ]);
519
532
  const allowedEdges = useMemo3(() => allowedEdgesProp || (orientation === "vertical" ? [
520
533
  "top",
521
534
  "bottom"
@@ -553,7 +566,14 @@ var MosaicTile = slottable(({ children, asChild, dragHandle, allowedEdges: allow
553
566
  });
554
567
  }
555
568
  };
569
+ const handleNativeDragStart = (event) => {
570
+ if (event.dataTransfer) {
571
+ event.dataTransfer.effectAllowed = "move";
572
+ }
573
+ };
574
+ root.addEventListener("dragstart", handleNativeDragStart);
556
575
  return combine3(
576
+ () => root.removeEventListener("dragstart", handleNativeDragStart),
557
577
  // Source.
558
578
  draggable({
559
579
  element: root,
@@ -605,6 +625,8 @@ var MosaicTile = slottable(({ children, asChild, dragHandle, allowedEdges: allow
605
625
  source: data2
606
626
  }) || false;
607
627
  },
628
+ // Reorder is a move, not a copy — otherwise the browser shows the green "+" copy cursor.
629
+ getDropEffect: () => "move",
608
630
  onDragEnter: ({ self, source }) => {
609
631
  handleChange({
610
632
  self,
@@ -645,10 +667,34 @@ var MosaicTile = slottable(({ children, asChild, dragHandle, allowedEdges: allow
645
667
  const { className, ...rest } = composableProps2(props, {
646
668
  classNames: "relative outline-none"
647
669
  });
670
+ const vertical = orientation === "vertical";
671
+ const sized = size != null;
672
+ const bounded = sized || minSize != null || maxSize != null;
673
+ const sizeStyles = {
674
+ ...sized && sizeStyle(size, vertical ? "vertical" : "horizontal"),
675
+ ...minSize != null && {
676
+ [vertical ? "minBlockSize" : "minInlineSize"]: `${minSize}rem`
677
+ },
678
+ ...maxSize != null && {
679
+ [vertical ? "maxBlockSize" : "maxInlineSize"]: `${maxSize}rem`
680
+ }
681
+ };
648
682
  return /* @__PURE__ */ React3.createElement(MosaicTileContextProvider, {
649
- state
683
+ state,
684
+ setDragHandle: setRegisteredDragHandle,
685
+ size,
686
+ setSize,
687
+ minSize,
688
+ maxSize
650
689
  }, /* @__PURE__ */ React3.createElement(Comp, {
651
690
  ...rest,
691
+ ...bounded && resizeAttributes,
692
+ ...bounded && {
693
+ style: {
694
+ ...rest.style,
695
+ ...sizeStyles
696
+ }
697
+ },
652
698
  "data-object-id": id,
653
699
  [`data-${MOSAIC_TILE_STATE_ATTR}`]: state.type,
654
700
  role: "listitem",
@@ -672,12 +718,56 @@ var MosaicTile = slottable(({ children, asChild, dragHandle, allowedEdges: allow
672
718
  });
673
719
  MosaicTile.displayName = MOSAIC_TILE_NAME;
674
720
 
721
+ // src/components/Mosaic/DragHandle.tsx
722
+ import { composeRefs as composeRefs2 } from "@radix-ui/react-compose-refs";
723
+ import React4, { forwardRef as forwardRef2 } from "react";
724
+ import { Button, IconButton, useTranslation } from "@dxos/react-ui";
725
+ var MOSAIC_DRAG_HANDLE_NAME = "Mosaic.DragHandle";
726
+ var REACT_UI_TRANSLATION_KEY = "@dxos/react-ui";
727
+ var MosaicDragHandle = /* @__PURE__ */ forwardRef2(({ icon = "ph--dots-six-vertical--regular", label, variant = "ghost", classNames, testId, children }, forwardedRef) => {
728
+ const { t } = useTranslation(REACT_UI_TRANSLATION_KEY);
729
+ const { setDragHandle } = useMosaicTileContext(MOSAIC_DRAG_HANDLE_NAME);
730
+ const ref = composeRefs2(forwardedRef, setDragHandle);
731
+ const testIdProps = testId ? {
732
+ "data-testid": testId
733
+ } : {};
734
+ if (children) {
735
+ return /* @__PURE__ */ React4.createElement(Button, {
736
+ ref,
737
+ variant,
738
+ tabIndex: -1,
739
+ classNames: [
740
+ "grid place-items-center cursor-grab",
741
+ classNames
742
+ ],
743
+ ...testIdProps
744
+ }, children, /* @__PURE__ */ React4.createElement("span", {
745
+ className: "sr-only"
746
+ }, label ?? t("toolbar-drag-handle.label")));
747
+ }
748
+ return /* @__PURE__ */ React4.createElement(IconButton, {
749
+ ref,
750
+ iconOnly: true,
751
+ noTooltip: true,
752
+ tabIndex: -1,
753
+ variant,
754
+ icon,
755
+ label: label ?? t("toolbar-drag-handle.label"),
756
+ classNames: [
757
+ "cursor-grab",
758
+ classNames
759
+ ],
760
+ ...testIdProps
761
+ });
762
+ });
763
+ MosaicDragHandle.displayName = MOSAIC_DRAG_HANDLE_NAME;
764
+
675
765
  // src/components/Mosaic/Placeholder.tsx
676
766
  import { DropIndicator as NaturalDropIndicator } from "@atlaskit/pragmatic-drag-and-drop-react-drop-indicator/box";
677
767
  import { dropTargetForElements as dropTargetForElements3 } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
678
768
  import { Primitive as Primitive4 } from "@radix-ui/react-primitive";
679
769
  import { Slot as Slot4 } from "@radix-ui/react-slot";
680
- import React4, { useLayoutEffect as useLayoutEffect2, useMemo as useMemo4, useRef as useRef4 } from "react";
770
+ import React5, { useLayoutEffect as useLayoutEffect2, useMemo as useMemo4, useRef as useRef4 } from "react";
681
771
  import { mx } from "@dxos/ui-theme";
682
772
  var MOSAIC_PLACEHOLDER_NAME = "Mosaic.Placeholder";
683
773
  var MOSAIC_PLACEHOLDER_ORIENTATION_ATTR = "mosaic-placeholder-orientation";
@@ -709,6 +799,8 @@ var MosaicPlaceholder = ({ classNames, children, asChild, orientation = "vertica
709
799
  source: data2
710
800
  }) || false;
711
801
  },
802
+ // Reorder is a move, not a copy — otherwise the browser shows the green "+" copy cursor.
803
+ getDropEffect: () => "move",
712
804
  onDragEnter: () => {
713
805
  setActiveLocation(data.location);
714
806
  },
@@ -725,7 +817,7 @@ var MosaicPlaceholder = ({ classNames, children, asChild, orientation = "vertica
725
817
  scrolling,
726
818
  setActiveLocation
727
819
  ]);
728
- return /* @__PURE__ */ React4.createElement(Comp, {
820
+ return /* @__PURE__ */ React5.createElement(Comp, {
729
821
  [`data-${MOSAIC_PLACEHOLDER_ORIENTATION_ATTR}`]: orientation,
730
822
  [`data-${MOSAIC_PLACEHOLDER_STATE_ATTR}`]: data.location === activeLocation ? "active" : "idle",
731
823
  [`data-${MOSAIC_PLACEHOLDER_LOCATION_ATTR}`]: String(location),
@@ -738,24 +830,46 @@ MosaicPlaceholder.displayName = MOSAIC_PLACEHOLDER_NAME;
738
830
  var DROP_INDICATOR_NAME = "Mosaic.DropIndicator";
739
831
  var MosaicDropIndicator = (props) => {
740
832
  const { state } = useMosaicTileContext(DROP_INDICATOR_NAME);
741
- return state.type === "target" && state.closestEdge ? /* @__PURE__ */ React4.createElement(NaturalDropIndicator, {
833
+ return state.type === "target" && state.closestEdge ? /* @__PURE__ */ React5.createElement(NaturalDropIndicator, {
742
834
  ...props,
743
835
  edge: state.closestEdge
744
836
  }) : null;
745
837
  };
746
838
  MosaicDropIndicator.displayName = DROP_INDICATOR_NAME;
747
839
 
840
+ // src/components/Mosaic/ResizeHandle.tsx
841
+ import React6 from "react";
842
+ import { ResizeHandle } from "@dxos/react-ui-dnd";
843
+ var MOSAIC_RESIZE_HANDLE_NAME = "Mosaic.ResizeHandle";
844
+ var MIN_WIDTH = 20;
845
+ var MIN_HEIGHT = 3;
846
+ var DEFAULT_EXTRINSIC_SIZE = 50;
847
+ var MosaicResizeHandle = ({ minSize, maxSize, fallbackSize = DEFAULT_EXTRINSIC_SIZE }) => {
848
+ const { orientation = "vertical" } = useMosaicContainerContext(MOSAIC_RESIZE_HANDLE_NAME);
849
+ const { size, setSize, minSize: tileMinSize, maxSize: tileMaxSize } = useMosaicTileContext(MOSAIC_RESIZE_HANDLE_NAME);
850
+ const horizontal = orientation === "horizontal";
851
+ return /* @__PURE__ */ React6.createElement(ResizeHandle, {
852
+ side: horizontal ? "inline-end" : "block-end",
853
+ fallbackSize,
854
+ minSize: minSize ?? tileMinSize ?? (horizontal ? MIN_WIDTH : MIN_HEIGHT),
855
+ maxSize: maxSize ?? tileMaxSize,
856
+ size,
857
+ onSizeChange: setSize
858
+ });
859
+ };
860
+ MosaicResizeHandle.displayName = MOSAIC_RESIZE_HANDLE_NAME;
861
+
748
862
  // src/components/Mosaic/Stack.tsx
749
863
  import { useComposedRefs as useComposedRefs3 } from "@radix-ui/react-compose-refs";
750
864
  import { useVirtualizer } from "@tanstack/react-virtual";
751
- import React5, { forwardRef as forwardRef2, Fragment, useCallback as useCallback3, useEffect as useEffect3, useRef as useRef5 } from "react";
865
+ import React7, { Fragment, forwardRef as forwardRef3, useCallback as useCallback4, useEffect as useEffect3, useLayoutEffect as useLayoutEffect3, useMemo as useMemo5, useRef as useRef5 } from "react";
752
866
  import { invariant } from "@dxos/invariant";
753
867
  import { composable as composable2, composableProps as composableProps3 } from "@dxos/react-ui";
754
868
  import { mx as mx2 } from "@dxos/ui-theme";
755
869
  var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/react-ui-mosaic/src/components/Mosaic/Stack.tsx";
756
870
  var MOSAIC_STACK_NAME = "MosaicStack";
757
871
  var MosaicStackInner = composable2(({ orientation: orientationProp = "vertical", getId, items, scrollIntoView = true, Tile, draggable: draggable2 = true, debug, ...props }, forwardedRef) => {
758
- const { id, orientation = orientationProp, dragging, currentId, selectedIds, registerScrollTo } = useMosaicContainerContext(MOSAIC_STACK_NAME);
872
+ const { id, orientation = orientationProp, dragging, currentId, selectedIds, registerScrollTo, setActiveLocation } = useMosaicContainerContext(MOSAIC_STACK_NAME);
759
873
  const visibleItems = useVisibleItems({
760
874
  id,
761
875
  items,
@@ -763,8 +877,28 @@ var MosaicStackInner = composable2(({ orientation: orientationProp = "vertical",
763
877
  getId
764
878
  });
765
879
  invariant(orientation === "vertical" || orientation === "horizontal", `Invalid orientation: ${orientation}`, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 46, S: void 0, A: ["orientation === 'vertical' || orientation === 'horizontal'", "`Invalid orientation: ${orientation}`"] });
880
+ const draggingSource = dragging?.source.data;
881
+ const sourceIndex = useMemo5(() => {
882
+ if (!items || !draggingSource || draggingSource.containerId !== id) {
883
+ return -1;
884
+ }
885
+ return items.findIndex((item) => getId(item) === draggingSource.id);
886
+ }, [
887
+ items,
888
+ draggingSource,
889
+ id,
890
+ getId
891
+ ]);
892
+ useLayoutEffect3(() => {
893
+ if (sourceIndex >= 0) {
894
+ setActiveLocation(sourceIndex + 0.5);
895
+ }
896
+ }, [
897
+ sourceIndex,
898
+ setActiveLocation
899
+ ]);
766
900
  const rootRef = useRef5(null);
767
- const scrollToId = useCallback3((targetId) => {
901
+ const scrollToId = useCallback4((targetId) => {
768
902
  if (!scrollIntoView) {
769
903
  return;
770
904
  }
@@ -784,7 +918,7 @@ var MosaicStackInner = composable2(({ orientation: orientationProp = "vertical",
784
918
  scrollToId
785
919
  ]);
786
920
  const composedRef = useComposedRefs3(rootRef, forwardedRef);
787
- return /* @__PURE__ */ React5.createElement("div", {
921
+ return /* @__PURE__ */ React7.createElement("div", {
788
922
  ...composableProps3(props, {
789
923
  role: "list",
790
924
  classNames: [
@@ -794,12 +928,12 @@ var MosaicStackInner = composable2(({ orientation: orientationProp = "vertical",
794
928
  ]
795
929
  }),
796
930
  ref: composedRef
797
- }, draggable2 && /* @__PURE__ */ React5.createElement(InternalPlaceholder, {
931
+ }, draggable2 && /* @__PURE__ */ React7.createElement(InternalPlaceholder, {
798
932
  orientation,
799
933
  location: 0.5
800
- }), visibleItems?.map((item, index) => /* @__PURE__ */ React5.createElement(Fragment, {
934
+ }), visibleItems?.map((item, index) => /* @__PURE__ */ React7.createElement(Fragment, {
801
935
  key: getId(item)
802
- }, /* @__PURE__ */ React5.createElement(Tile, {
936
+ }, /* @__PURE__ */ React7.createElement(Tile, {
803
937
  id: getId(item),
804
938
  data: item,
805
939
  location: index + 1,
@@ -807,7 +941,7 @@ var MosaicStackInner = composable2(({ orientation: orientationProp = "vertical",
807
941
  current: getId(item) === currentId,
808
942
  selected: selectedIds?.has(getId(item)),
809
943
  debug
810
- }), draggable2 && /* @__PURE__ */ React5.createElement(InternalPlaceholder, {
944
+ }), draggable2 && /* @__PURE__ */ React7.createElement(InternalPlaceholder, {
811
945
  orientation,
812
946
  location: index + 1.5
813
947
  }))));
@@ -815,8 +949,8 @@ var MosaicStackInner = composable2(({ orientation: orientationProp = "vertical",
815
949
  MosaicStackInner.displayName = MOSAIC_STACK_NAME;
816
950
  var MosaicStack = MosaicStackInner;
817
951
  var MOSAIC_VIRTUAL_STACK_NAME = "MosaicVirtualStack";
818
- var MosaicVirtualStackInner = /* @__PURE__ */ forwardRef2(({ orientation = "vertical", getId, items, scrollIntoView = true, Tile, estimateSize, getScrollElement, overscan = 8, gap, onChange, draggable: draggable2 = true, debug, ...props }, forwardedRef) => {
819
- invariant(Tile, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 103, S: void 0, A: ["Tile", ""] });
952
+ var MosaicVirtualStackInner = /* @__PURE__ */ forwardRef3(({ orientation = "vertical", getId, items, scrollIntoView = true, Tile, estimateSize, getScrollElement, overscan = 8, gap, onChange, draggable: draggable2 = true, debug, ...props }, forwardedRef) => {
953
+ invariant(Tile, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 128, S: void 0, A: ["Tile", ""] });
820
954
  const { id, dragging, currentId, selectedIds, registerScrollTo } = useMosaicContainerContext(MOSAIC_VIRTUAL_STACK_NAME);
821
955
  const visibleItems = useVisibleItems({
822
956
  id,
@@ -841,7 +975,7 @@ var MosaicVirtualStackInner = /* @__PURE__ */ forwardRef2(({ orientation = "vert
841
975
  overscan,
842
976
  onChange
843
977
  });
844
- const scrollToId = useCallback3((targetId) => {
978
+ const scrollToId = useCallback4((targetId) => {
845
979
  const itemIndex = visibleItems.findIndex((item) => getId(item) === targetId);
846
980
  if (itemIndex >= 0) {
847
981
  if (!scrollIntoView) {
@@ -890,7 +1024,7 @@ var MosaicVirtualStackInner = /* @__PURE__ */ forwardRef2(({ orientation = "vert
890
1024
  };
891
1025
  }
892
1026
  };
893
- return /* @__PURE__ */ React5.createElement("div", {
1027
+ return /* @__PURE__ */ React7.createElement("div", {
894
1028
  ...composableProps3(props, {
895
1029
  role: "list",
896
1030
  classNames: [
@@ -915,7 +1049,7 @@ var MosaicVirtualStackInner = /* @__PURE__ */ forwardRef2(({ orientation = "vert
915
1049
  ref: forwardedRef
916
1050
  }, virtualItems.map(({ key, index, start }) => {
917
1051
  const { data, location } = getData(index);
918
- return /* @__PURE__ */ React5.createElement("div", {
1052
+ return /* @__PURE__ */ React7.createElement("div", {
919
1053
  key,
920
1054
  "data-index": index,
921
1055
  style: {
@@ -931,7 +1065,7 @@ var MosaicVirtualStackInner = /* @__PURE__ */ forwardRef2(({ orientation = "vert
931
1065
  }
932
1066
  },
933
1067
  ref: virtualizer.measureElement
934
- }, data ? /* @__PURE__ */ React5.createElement(Tile, {
1068
+ }, data ? /* @__PURE__ */ React7.createElement(Tile, {
935
1069
  id: getId(data),
936
1070
  data,
937
1071
  location,
@@ -939,7 +1073,7 @@ var MosaicVirtualStackInner = /* @__PURE__ */ forwardRef2(({ orientation = "vert
939
1073
  current: getId(data) === currentId,
940
1074
  selected: selectedIds?.has(getId(data)),
941
1075
  debug
942
- }) : /* @__PURE__ */ React5.createElement(InternalPlaceholder, {
1076
+ }) : /* @__PURE__ */ React7.createElement(InternalPlaceholder, {
943
1077
  orientation,
944
1078
  location
945
1079
  }));
@@ -949,10 +1083,10 @@ MosaicVirtualStackInner.displayName = MOSAIC_VIRTUAL_STACK_NAME;
949
1083
  var MosaicVirtualStack = MosaicVirtualStackInner;
950
1084
  MosaicVirtualStack[/* @__PURE__ */ Symbol.for("dxos.composable")] = true;
951
1085
  var InternalPlaceholder = (props) => {
952
- return /* @__PURE__ */ React5.createElement(MosaicPlaceholder, {
1086
+ return /* @__PURE__ */ React7.createElement(MosaicPlaceholder, {
953
1087
  ...props,
954
1088
  classNames: styles.placeholder.root
955
- }, /* @__PURE__ */ React5.createElement("div", {
1089
+ }, /* @__PURE__ */ React7.createElement("div", {
956
1090
  className: mx2("flex h-full bg-base-surface border border-dashed border-separator rounded-xs", styles.placeholder.content)
957
1091
  }));
958
1092
  };
@@ -963,6 +1097,8 @@ var Mosaic = {
963
1097
  Root: MosaicRoot,
964
1098
  Container: MosaicContainer,
965
1099
  Tile: MosaicTile,
1100
+ DragHandle: MosaicDragHandle,
1101
+ ResizeHandle: MosaicResizeHandle,
966
1102
  Placeholder: MosaicPlaceholder,
967
1103
  DropIndicator: MosaicDropIndicator,
968
1104
  Stack: MosaicStack,
@@ -980,4 +1116,4 @@ export {
980
1116
  useMosaicTileContext,
981
1117
  Mosaic
982
1118
  };
983
- //# sourceMappingURL=chunk-DZ5WMCI2.mjs.map
1119
+ //# sourceMappingURL=chunk-OBVIYZLR.mjs.map