@dxos/react-ui-mosaic 0.9.0 → 0.9.1-staging.ee54ba693a

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 (64) hide show
  1. package/dist/lib/browser/{chunk-I3M5WM6C.mjs → chunk-OBVIYZLR.mjs} +182 -43
  2. package/dist/lib/browser/chunk-OBVIYZLR.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +20 -17
  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 +13 -9
  7. package/dist/lib/browser/testing/index.mjs.map +3 -3
  8. package/dist/lib/node-esm/{chunk-DVJLDZLE.mjs → chunk-4IEMCMIV.mjs} +182 -43
  9. package/dist/lib/node-esm/chunk-4IEMCMIV.mjs.map +7 -0
  10. package/dist/lib/node-esm/index.mjs +20 -17
  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 +13 -9
  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/Board/Item.d.ts.map +1 -1
  20. package/dist/types/src/components/Focus/Focus.d.ts +1 -1
  21. package/dist/types/src/components/Focus/Focus.d.ts.map +1 -1
  22. package/dist/types/src/components/Mosaic/Container.d.ts +10 -1
  23. package/dist/types/src/components/Mosaic/Container.d.ts.map +1 -1
  24. package/dist/types/src/components/Mosaic/DragHandle.d.ts +28 -0
  25. package/dist/types/src/components/Mosaic/DragHandle.d.ts.map +1 -0
  26. package/dist/types/src/components/Mosaic/Mosaic.d.ts +18 -2
  27. package/dist/types/src/components/Mosaic/Mosaic.d.ts.map +1 -1
  28. package/dist/types/src/components/Mosaic/Placeholder.d.ts +2 -2
  29. package/dist/types/src/components/Mosaic/Placeholder.d.ts.map +1 -1
  30. package/dist/types/src/components/Mosaic/ResizeHandle.d.ts +14 -0
  31. package/dist/types/src/components/Mosaic/ResizeHandle.d.ts.map +1 -0
  32. package/dist/types/src/components/Mosaic/ResizeHandle.stories.d.ts +12 -0
  33. package/dist/types/src/components/Mosaic/ResizeHandle.stories.d.ts.map +1 -0
  34. package/dist/types/src/components/Mosaic/Root.d.ts +1 -1
  35. package/dist/types/src/components/Mosaic/Root.d.ts.map +1 -1
  36. package/dist/types/src/components/Mosaic/Stack.d.ts +1 -1
  37. package/dist/types/src/components/Mosaic/Stack.d.ts.map +1 -1
  38. package/dist/types/src/components/Mosaic/Tile.d.ts +34 -0
  39. package/dist/types/src/components/Mosaic/Tile.d.ts.map +1 -1
  40. package/dist/types/src/components/Mosaic/styles.d.ts.map +1 -1
  41. package/dist/types/src/testing/DefaultStackTile.d.ts.map +1 -1
  42. package/dist/types/src/testing/types.d.ts +10 -12
  43. package/dist/types/src/testing/types.d.ts.map +1 -1
  44. package/dist/types/tsconfig.tsbuildinfo +1 -1
  45. package/package.json +33 -33
  46. package/src/components/Board/Board.stories.tsx +3 -3
  47. package/src/components/Board/Board.tsx +1 -1
  48. package/src/components/Board/Item.tsx +20 -12
  49. package/src/components/Focus/Focus.tsx +1 -1
  50. package/src/components/Mosaic/Container.tsx +21 -7
  51. package/src/components/Mosaic/DragHandle.tsx +75 -0
  52. package/src/components/Mosaic/Mosaic.tsx +12 -4
  53. package/src/components/Mosaic/Placeholder.tsx +4 -2
  54. package/src/components/Mosaic/ResizeHandle.stories.tsx +119 -0
  55. package/src/components/Mosaic/ResizeHandle.tsx +56 -0
  56. package/src/components/Mosaic/Root.tsx +3 -1
  57. package/src/components/Mosaic/Stack.tsx +23 -2
  58. package/src/components/Mosaic/Tile.tsx +82 -4
  59. package/src/components/Mosaic/styles.ts +4 -3
  60. package/src/components/SearchStack/SearchStack.tsx +1 -1
  61. package/src/testing/DefaultStackTile.tsx +6 -4
  62. package/src/testing/types.ts +14 -14
  63. package/dist/lib/browser/chunk-I3M5WM6C.mjs.map +0 -7
  64. package/dist/lib/node-esm/chunk-DVJLDZLE.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?.({
@@ -286,7 +289,7 @@ import { createContext as createContext2 } from "@radix-ui/react-context";
286
289
  import { Primitive as Primitive2 } from "@radix-ui/react-primitive";
287
290
  import { Slot as Slot2 } from "@radix-ui/react-slot";
288
291
  import { bind } from "bind-event-listener";
289
- import React2, { useCallback as useCallback2, useEffect as useEffect2, useMemo as useMemo2, useRef as useRef2, useState as useState2 } from "react";
292
+ import React2, { useCallback as useCallback2, useEffect as useEffect2, useImperativeHandle, useMemo as useMemo2, useRef as useRef2, useState as useState2 } from "react";
290
293
  import { composable, composableProps } from "@dxos/react-ui";
291
294
  import { isTruthy } from "@dxos/util";
292
295
  var MOSAIC_CONTAINER_NAME = "Mosaic.Container";
@@ -295,7 +298,7 @@ var MOSAIC_CONTAINER_STATE_ATTR = "mosaic-container-state";
295
298
  var MOSAIC_CONTAINER_PLACEHOLDER_WIDTH = "--mosaic-placeholder-width";
296
299
  var MOSAIC_CONTAINER_PLACEHOLDER_HEIGHT = "--mosaic-placeholder-height";
297
300
  var counter = 0;
298
- var MosaicContainer = composable(({ children, eventHandler: eventHandlerProp, orientation = "vertical", asChild, autoScroll: autoscrollElement, withFocus, currentId, onCurrentChange, selectedIds, onSelectionChange, debug, ...props }, forwardedRef) => {
301
+ var MosaicContainer = composable(({ children, eventHandler: eventHandlerProp, orientation = "vertical", asChild, autoScroll: autoscrollElement, withFocus, controllerRef, currentId, onCurrentChange, selectedIds, onSelectionChange, debug, ...props }, forwardedRef) => {
299
302
  const Comp = asChild ? Slot2 : Primitive2.div;
300
303
  const rootRef = useRef2(null);
301
304
  const composedRef = useComposedRefs2(rootRef, forwardedRef);
@@ -320,6 +323,9 @@ var MosaicContainer = composable(({ children, eventHandler: eventHandlerProp, or
320
323
  const registerScrollTo = useCallback2((fn) => {
321
324
  scrollToRef.current = fn;
322
325
  }, []);
326
+ useImperativeHandle(controllerRef, () => ({
327
+ scrollToItem: (id) => scrollToRef.current?.(id)
328
+ }), []);
323
329
  useEffect2(() => {
324
330
  if (currentId) {
325
331
  scrollToRef.current?.(currentId);
@@ -388,10 +394,8 @@ var MosaicContainer = composable(({ children, eventHandler: eventHandlerProp, or
388
394
  source: data2
389
395
  }) || false;
390
396
  },
391
- // TODO(burdon): Provide semantic intent to onDrop.
392
- // getDropEffect: () => {
393
- // return 'move';
394
- // },
397
+ // Reorder is a move, not a copy — otherwise the browser shows the green "+" copy cursor.
398
+ getDropEffect: () => "move",
395
399
  /**
396
400
  * Dragging started in this container.
397
401
  */
@@ -440,9 +444,9 @@ var MosaicContainer = composable(({ children, eventHandler: eventHandlerProp, or
440
444
  autoscrollElement && [
441
445
  autoScrollForElements({
442
446
  element: autoscrollElement,
443
- // canScroll: ({ element: _ }) => {
444
- // return true;
445
- // },
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,
446
450
  getAllowedAxis: () => orientation,
447
451
  getConfiguration: () => ({
448
452
  maxScrollSpeed: "fast"
@@ -499,13 +503,14 @@ import { composeRefs } from "@radix-ui/react-compose-refs";
499
503
  import { createContext as createContext3 } from "@radix-ui/react-context";
500
504
  import { Primitive as Primitive3 } from "@radix-ui/react-primitive";
501
505
  import { Slot as Slot3 } from "@radix-ui/react-slot";
502
- 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";
503
507
  import { createPortal } from "react-dom";
504
508
  import { composableProps as composableProps2, slottable } from "@dxos/react-ui";
509
+ import { resizeAttributes, sizeStyle } from "@dxos/react-ui-dnd";
505
510
  var MOSAIC_TILE_NAME = "Mosaic.Tile";
506
511
  var [MosaicTileContextProvider, useMosaicTileContext] = createContext3("MosaicTile");
507
512
  var MOSAIC_TILE_STATE_ATTR = "mosaic-tile-state";
508
- 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) => {
509
514
  const Comp = asChild ? Slot3 : Primitive3.div;
510
515
  const rootRef = useRef3(null);
511
516
  const composedRef = composeRefs(rootRef, forwardedRef);
@@ -513,6 +518,17 @@ var MosaicTile = slottable(({ children, asChild, dragHandle, allowedEdges: allow
513
518
  const [state, setState] = useState3({
514
519
  type: "idle"
515
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
+ ]);
516
532
  const allowedEdges = useMemo3(() => allowedEdgesProp || (orientation === "vertical" ? [
517
533
  "top",
518
534
  "bottom"
@@ -550,7 +566,14 @@ var MosaicTile = slottable(({ children, asChild, dragHandle, allowedEdges: allow
550
566
  });
551
567
  }
552
568
  };
569
+ const handleNativeDragStart = (event) => {
570
+ if (event.dataTransfer) {
571
+ event.dataTransfer.effectAllowed = "move";
572
+ }
573
+ };
574
+ root.addEventListener("dragstart", handleNativeDragStart);
553
575
  return combine3(
576
+ () => root.removeEventListener("dragstart", handleNativeDragStart),
554
577
  // Source.
555
578
  draggable({
556
579
  element: root,
@@ -602,6 +625,8 @@ var MosaicTile = slottable(({ children, asChild, dragHandle, allowedEdges: allow
602
625
  source: data2
603
626
  }) || false;
604
627
  },
628
+ // Reorder is a move, not a copy — otherwise the browser shows the green "+" copy cursor.
629
+ getDropEffect: () => "move",
605
630
  onDragEnter: ({ self, source }) => {
606
631
  handleChange({
607
632
  self,
@@ -642,10 +667,34 @@ var MosaicTile = slottable(({ children, asChild, dragHandle, allowedEdges: allow
642
667
  const { className, ...rest } = composableProps2(props, {
643
668
  classNames: "relative outline-none"
644
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
+ };
645
682
  return /* @__PURE__ */ React3.createElement(MosaicTileContextProvider, {
646
- state
683
+ state,
684
+ setDragHandle: setRegisteredDragHandle,
685
+ size,
686
+ setSize,
687
+ minSize,
688
+ maxSize
647
689
  }, /* @__PURE__ */ React3.createElement(Comp, {
648
690
  ...rest,
691
+ ...bounded && resizeAttributes,
692
+ ...bounded && {
693
+ style: {
694
+ ...rest.style,
695
+ ...sizeStyles
696
+ }
697
+ },
649
698
  "data-object-id": id,
650
699
  [`data-${MOSAIC_TILE_STATE_ATTR}`]: state.type,
651
700
  role: "listitem",
@@ -669,12 +718,56 @@ var MosaicTile = slottable(({ children, asChild, dragHandle, allowedEdges: allow
669
718
  });
670
719
  MosaicTile.displayName = MOSAIC_TILE_NAME;
671
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
+
672
765
  // src/components/Mosaic/Placeholder.tsx
673
766
  import { DropIndicator as NaturalDropIndicator } from "@atlaskit/pragmatic-drag-and-drop-react-drop-indicator/box";
674
767
  import { dropTargetForElements as dropTargetForElements3 } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
675
768
  import { Primitive as Primitive4 } from "@radix-ui/react-primitive";
676
769
  import { Slot as Slot4 } from "@radix-ui/react-slot";
677
- 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";
678
771
  import { mx } from "@dxos/ui-theme";
679
772
  var MOSAIC_PLACEHOLDER_NAME = "Mosaic.Placeholder";
680
773
  var MOSAIC_PLACEHOLDER_ORIENTATION_ATTR = "mosaic-placeholder-orientation";
@@ -706,6 +799,8 @@ var MosaicPlaceholder = ({ classNames, children, asChild, orientation = "vertica
706
799
  source: data2
707
800
  }) || false;
708
801
  },
802
+ // Reorder is a move, not a copy — otherwise the browser shows the green "+" copy cursor.
803
+ getDropEffect: () => "move",
709
804
  onDragEnter: () => {
710
805
  setActiveLocation(data.location);
711
806
  },
@@ -722,7 +817,7 @@ var MosaicPlaceholder = ({ classNames, children, asChild, orientation = "vertica
722
817
  scrolling,
723
818
  setActiveLocation
724
819
  ]);
725
- return /* @__PURE__ */ React4.createElement(Comp, {
820
+ return /* @__PURE__ */ React5.createElement(Comp, {
726
821
  [`data-${MOSAIC_PLACEHOLDER_ORIENTATION_ATTR}`]: orientation,
727
822
  [`data-${MOSAIC_PLACEHOLDER_STATE_ATTR}`]: data.location === activeLocation ? "active" : "idle",
728
823
  [`data-${MOSAIC_PLACEHOLDER_LOCATION_ATTR}`]: String(location),
@@ -735,24 +830,46 @@ MosaicPlaceholder.displayName = MOSAIC_PLACEHOLDER_NAME;
735
830
  var DROP_INDICATOR_NAME = "Mosaic.DropIndicator";
736
831
  var MosaicDropIndicator = (props) => {
737
832
  const { state } = useMosaicTileContext(DROP_INDICATOR_NAME);
738
- return state.type === "target" && state.closestEdge ? /* @__PURE__ */ React4.createElement(NaturalDropIndicator, {
833
+ return state.type === "target" && state.closestEdge ? /* @__PURE__ */ React5.createElement(NaturalDropIndicator, {
739
834
  ...props,
740
835
  edge: state.closestEdge
741
836
  }) : null;
742
837
  };
743
838
  MosaicDropIndicator.displayName = DROP_INDICATOR_NAME;
744
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
+
745
862
  // src/components/Mosaic/Stack.tsx
746
863
  import { useComposedRefs as useComposedRefs3 } from "@radix-ui/react-compose-refs";
747
864
  import { useVirtualizer } from "@tanstack/react-virtual";
748
- 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";
749
866
  import { invariant } from "@dxos/invariant";
750
867
  import { composable as composable2, composableProps as composableProps3 } from "@dxos/react-ui";
751
868
  import { mx as mx2 } from "@dxos/ui-theme";
752
869
  var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/react-ui-mosaic/src/components/Mosaic/Stack.tsx";
753
870
  var MOSAIC_STACK_NAME = "MosaicStack";
754
871
  var MosaicStackInner = composable2(({ orientation: orientationProp = "vertical", getId, items, scrollIntoView = true, Tile, draggable: draggable2 = true, debug, ...props }, forwardedRef) => {
755
- 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);
756
873
  const visibleItems = useVisibleItems({
757
874
  id,
758
875
  items,
@@ -760,8 +877,28 @@ var MosaicStackInner = composable2(({ orientation: orientationProp = "vertical",
760
877
  getId
761
878
  });
762
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
+ ]);
763
900
  const rootRef = useRef5(null);
764
- const scrollToId = useCallback3((targetId) => {
901
+ const scrollToId = useCallback4((targetId) => {
765
902
  if (!scrollIntoView) {
766
903
  return;
767
904
  }
@@ -781,7 +918,7 @@ var MosaicStackInner = composable2(({ orientation: orientationProp = "vertical",
781
918
  scrollToId
782
919
  ]);
783
920
  const composedRef = useComposedRefs3(rootRef, forwardedRef);
784
- return /* @__PURE__ */ React5.createElement("div", {
921
+ return /* @__PURE__ */ React7.createElement("div", {
785
922
  ...composableProps3(props, {
786
923
  role: "list",
787
924
  classNames: [
@@ -791,12 +928,12 @@ var MosaicStackInner = composable2(({ orientation: orientationProp = "vertical",
791
928
  ]
792
929
  }),
793
930
  ref: composedRef
794
- }, draggable2 && /* @__PURE__ */ React5.createElement(InternalPlaceholder, {
931
+ }, draggable2 && /* @__PURE__ */ React7.createElement(InternalPlaceholder, {
795
932
  orientation,
796
933
  location: 0.5
797
- }), visibleItems?.map((item, index) => /* @__PURE__ */ React5.createElement(Fragment, {
934
+ }), visibleItems?.map((item, index) => /* @__PURE__ */ React7.createElement(Fragment, {
798
935
  key: getId(item)
799
- }, /* @__PURE__ */ React5.createElement(Tile, {
936
+ }, /* @__PURE__ */ React7.createElement(Tile, {
800
937
  id: getId(item),
801
938
  data: item,
802
939
  location: index + 1,
@@ -804,7 +941,7 @@ var MosaicStackInner = composable2(({ orientation: orientationProp = "vertical",
804
941
  current: getId(item) === currentId,
805
942
  selected: selectedIds?.has(getId(item)),
806
943
  debug
807
- }), draggable2 && /* @__PURE__ */ React5.createElement(InternalPlaceholder, {
944
+ }), draggable2 && /* @__PURE__ */ React7.createElement(InternalPlaceholder, {
808
945
  orientation,
809
946
  location: index + 1.5
810
947
  }))));
@@ -812,8 +949,8 @@ var MosaicStackInner = composable2(({ orientation: orientationProp = "vertical",
812
949
  MosaicStackInner.displayName = MOSAIC_STACK_NAME;
813
950
  var MosaicStack = MosaicStackInner;
814
951
  var MOSAIC_VIRTUAL_STACK_NAME = "MosaicVirtualStack";
815
- var MosaicVirtualStackInner = /* @__PURE__ */ forwardRef2(({ orientation = "vertical", getId, items, scrollIntoView = true, Tile, estimateSize, getScrollElement, overscan = 8, gap, onChange, draggable: draggable2 = true, debug, ...props }, forwardedRef) => {
816
- 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", ""] });
817
954
  const { id, dragging, currentId, selectedIds, registerScrollTo } = useMosaicContainerContext(MOSAIC_VIRTUAL_STACK_NAME);
818
955
  const visibleItems = useVisibleItems({
819
956
  id,
@@ -838,7 +975,7 @@ var MosaicVirtualStackInner = /* @__PURE__ */ forwardRef2(({ orientation = "vert
838
975
  overscan,
839
976
  onChange
840
977
  });
841
- const scrollToId = useCallback3((targetId) => {
978
+ const scrollToId = useCallback4((targetId) => {
842
979
  const itemIndex = visibleItems.findIndex((item) => getId(item) === targetId);
843
980
  if (itemIndex >= 0) {
844
981
  if (!scrollIntoView) {
@@ -887,7 +1024,7 @@ var MosaicVirtualStackInner = /* @__PURE__ */ forwardRef2(({ orientation = "vert
887
1024
  };
888
1025
  }
889
1026
  };
890
- return /* @__PURE__ */ React5.createElement("div", {
1027
+ return /* @__PURE__ */ React7.createElement("div", {
891
1028
  ...composableProps3(props, {
892
1029
  role: "list",
893
1030
  classNames: [
@@ -912,7 +1049,7 @@ var MosaicVirtualStackInner = /* @__PURE__ */ forwardRef2(({ orientation = "vert
912
1049
  ref: forwardedRef
913
1050
  }, virtualItems.map(({ key, index, start }) => {
914
1051
  const { data, location } = getData(index);
915
- return /* @__PURE__ */ React5.createElement("div", {
1052
+ return /* @__PURE__ */ React7.createElement("div", {
916
1053
  key,
917
1054
  "data-index": index,
918
1055
  style: {
@@ -928,7 +1065,7 @@ var MosaicVirtualStackInner = /* @__PURE__ */ forwardRef2(({ orientation = "vert
928
1065
  }
929
1066
  },
930
1067
  ref: virtualizer.measureElement
931
- }, data ? /* @__PURE__ */ React5.createElement(Tile, {
1068
+ }, data ? /* @__PURE__ */ React7.createElement(Tile, {
932
1069
  id: getId(data),
933
1070
  data,
934
1071
  location,
@@ -936,7 +1073,7 @@ var MosaicVirtualStackInner = /* @__PURE__ */ forwardRef2(({ orientation = "vert
936
1073
  current: getId(data) === currentId,
937
1074
  selected: selectedIds?.has(getId(data)),
938
1075
  debug
939
- }) : /* @__PURE__ */ React5.createElement(InternalPlaceholder, {
1076
+ }) : /* @__PURE__ */ React7.createElement(InternalPlaceholder, {
940
1077
  orientation,
941
1078
  location
942
1079
  }));
@@ -946,10 +1083,10 @@ MosaicVirtualStackInner.displayName = MOSAIC_VIRTUAL_STACK_NAME;
946
1083
  var MosaicVirtualStack = MosaicVirtualStackInner;
947
1084
  MosaicVirtualStack[/* @__PURE__ */ Symbol.for("dxos.composable")] = true;
948
1085
  var InternalPlaceholder = (props) => {
949
- return /* @__PURE__ */ React5.createElement(MosaicPlaceholder, {
1086
+ return /* @__PURE__ */ React7.createElement(MosaicPlaceholder, {
950
1087
  ...props,
951
1088
  classNames: styles.placeholder.root
952
- }, /* @__PURE__ */ React5.createElement("div", {
1089
+ }, /* @__PURE__ */ React7.createElement("div", {
953
1090
  className: mx2("flex h-full bg-base-surface border border-dashed border-separator rounded-xs", styles.placeholder.content)
954
1091
  }));
955
1092
  };
@@ -960,6 +1097,8 @@ var Mosaic = {
960
1097
  Root: MosaicRoot,
961
1098
  Container: MosaicContainer,
962
1099
  Tile: MosaicTile,
1100
+ DragHandle: MosaicDragHandle,
1101
+ ResizeHandle: MosaicResizeHandle,
963
1102
  Placeholder: MosaicPlaceholder,
964
1103
  DropIndicator: MosaicDropIndicator,
965
1104
  Stack: MosaicStack,
@@ -977,4 +1116,4 @@ export {
977
1116
  useMosaicTileContext,
978
1117
  Mosaic
979
1118
  };
980
- //# sourceMappingURL=chunk-I3M5WM6C.mjs.map
1119
+ //# sourceMappingURL=chunk-OBVIYZLR.mjs.map