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