@dxos/react-ui-mosaic 0.8.4-main.d05673bc65 → 0.8.4-main.fcfe5033a5

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 (68) hide show
  1. package/dist/lib/browser/{chunk-75KCPN67.mjs → chunk-33NNDFD6.mjs} +229 -179
  2. package/dist/lib/browser/chunk-33NNDFD6.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +46 -42
  4. package/dist/lib/browser/index.mjs.map +3 -3
  5. package/dist/lib/browser/meta.json +1 -1
  6. package/dist/lib/browser/playwright/index.mjs +18 -8
  7. package/dist/lib/browser/playwright/index.mjs.map +3 -3
  8. package/dist/lib/browser/testing/index.mjs +13 -9
  9. package/dist/lib/browser/testing/index.mjs.map +3 -3
  10. package/dist/lib/node-esm/{chunk-XYWWHOXN.mjs → chunk-Y4LG7O67.mjs} +229 -179
  11. package/dist/lib/node-esm/chunk-Y4LG7O67.mjs.map +7 -0
  12. package/dist/lib/node-esm/index.mjs +46 -42
  13. package/dist/lib/node-esm/index.mjs.map +3 -3
  14. package/dist/lib/node-esm/meta.json +1 -1
  15. package/dist/lib/node-esm/playwright/index.mjs +18 -8
  16. package/dist/lib/node-esm/playwright/index.mjs.map +3 -3
  17. package/dist/lib/node-esm/testing/index.mjs +13 -9
  18. package/dist/lib/node-esm/testing/index.mjs.map +3 -3
  19. package/dist/types/src/components/Board/Board.d.ts +6 -7
  20. package/dist/types/src/components/Board/Board.d.ts.map +1 -1
  21. package/dist/types/src/components/Board/Board.stories.d.ts +5 -5
  22. package/dist/types/src/components/Board/Board.stories.d.ts.map +1 -1
  23. package/dist/types/src/components/Board/Column.d.ts +9 -9
  24. package/dist/types/src/components/Board/Column.d.ts.map +1 -1
  25. package/dist/types/src/components/Board/Item.d.ts +3 -0
  26. package/dist/types/src/components/Board/Item.d.ts.map +1 -1
  27. package/dist/types/src/components/Focus/Focus.d.ts +1 -25
  28. package/dist/types/src/components/Focus/Focus.d.ts.map +1 -1
  29. package/dist/types/src/components/Mosaic/Container.d.ts +15 -11
  30. package/dist/types/src/components/Mosaic/Container.d.ts.map +1 -1
  31. package/dist/types/src/components/Mosaic/Mosaic.d.ts +12 -25
  32. package/dist/types/src/components/Mosaic/Mosaic.d.ts.map +1 -1
  33. package/dist/types/src/components/Mosaic/Placeholder.d.ts.map +1 -1
  34. package/dist/types/src/components/Mosaic/Root.d.ts +5 -6
  35. package/dist/types/src/components/Mosaic/Root.d.ts.map +1 -1
  36. package/dist/types/src/components/Mosaic/Stack.d.ts +7 -6
  37. package/dist/types/src/components/Mosaic/Stack.d.ts.map +1 -1
  38. package/dist/types/src/components/Mosaic/Stack.stories.d.ts +11 -0
  39. package/dist/types/src/components/Mosaic/Stack.stories.d.ts.map +1 -1
  40. package/dist/types/src/components/Mosaic/Tile.d.ts +16 -10
  41. package/dist/types/src/components/Mosaic/Tile.d.ts.map +1 -1
  42. package/dist/types/src/hooks/useDefaultColumnEventHandler.d.ts.map +1 -1
  43. package/dist/types/src/playwright/board-manager.d.ts.map +1 -1
  44. package/dist/types/src/testing/DefaultStackTile.d.ts.map +1 -1
  45. package/dist/types/src/translations.d.ts +3 -3
  46. package/dist/types/tsconfig.tsbuildinfo +1 -1
  47. package/package.json +26 -26
  48. package/src/AUDIT.md +106 -0
  49. package/src/components/Board/Board.stories.tsx +17 -19
  50. package/src/components/Board/Board.tsx +5 -7
  51. package/src/components/Board/Column.tsx +41 -40
  52. package/src/components/Board/Item.tsx +23 -24
  53. package/src/components/Focus/Focus.tsx +2 -102
  54. package/src/components/Mosaic/Container.tsx +51 -23
  55. package/src/components/Mosaic/Placeholder.tsx +1 -1
  56. package/src/components/Mosaic/Root.tsx +199 -205
  57. package/src/components/Mosaic/Stack.stories.tsx +125 -69
  58. package/src/components/Mosaic/Stack.tsx +162 -52
  59. package/src/components/Mosaic/Tile.tsx +41 -34
  60. package/src/hooks/useContainerDebug.tsx +1 -1
  61. package/src/hooks/useDefaultColumnEventHandler.ts +0 -1
  62. package/src/playwright/board-manager.ts +18 -13
  63. package/src/playwright/smoke.spec.ts +10 -5
  64. package/src/testing/CardContainer.tsx +2 -2
  65. package/src/testing/DefaultStackTile.tsx +22 -19
  66. package/src/translations.ts +3 -3
  67. package/dist/lib/browser/chunk-75KCPN67.mjs.map +0 -7
  68. package/dist/lib/node-esm/chunk-XYWWHOXN.mjs.map +0 -7
@@ -22,56 +22,7 @@ var useVisibleItems = ({ id, items, dragging, getId }) => {
22
22
  };
23
23
 
24
24
  // src/components/Focus/Focus.tsx
25
- import { useArrowNavigationGroup, useFocusableGroup, useMergedTabsterAttributes_unstable } from "@fluentui/react-tabster";
26
- import { useComposedRefs } from "@radix-ui/react-compose-refs";
27
- import { Primitive } from "@radix-ui/react-primitive";
28
- import { Slot } from "@radix-ui/react-slot";
29
- import React, { createContext, forwardRef, useContext, useRef, useState } from "react";
30
- import { composableProps, mx } from "@dxos/ui-theme";
31
- var FOCUS_STATE_ATTR = "focus-state";
32
- var FocusContext = /* @__PURE__ */ createContext({});
33
- var useFocus = () => useContext(FocusContext);
34
- var Group = /* @__PURE__ */ forwardRef(({ children, asChild, orientation = "vertical", ...props }, forwardedRef) => {
35
- const { className, ...rest } = composableProps(props);
36
- const Comp = asChild ? Slot : Primitive.div;
37
- const rootRef = useRef(null);
38
- const composedRef = useComposedRefs(rootRef, forwardedRef);
39
- const focusableGroupAttrs = useFocusableGroup({
40
- tabBehavior: "limited-trap-focus"
41
- });
42
- const arrowNavigationAttrs = useArrowNavigationGroup({
43
- axis: orientation,
44
- memorizeCurrent: true
45
- });
46
- const tabsterAttrs = useMergedTabsterAttributes_unstable(focusableGroupAttrs, arrowNavigationAttrs);
47
- const [state, setState] = useState();
48
- return /* @__PURE__ */ React.createElement(FocusContext.Provider, {
49
- value: {
50
- setFocus: setState
51
- }
52
- }, /* @__PURE__ */ React.createElement(Comp, {
53
- ...rest,
54
- ...tabsterAttrs,
55
- ...state && {
56
- [`data-${FOCUS_STATE_ATTR}`]: state
57
- },
58
- tabIndex: 0,
59
- className: mx([
60
- // TODO(burdon): Option for border/rounded; ring/outline vs border?
61
- "outline-hidden border border-separator md:rounded-xs",
62
- // Focus (e.g., via tabster).
63
- "focus:!border-accent-surface",
64
- // Active (e.g., drop target).
65
- "data-[focus-state=active]:border-neutral-focus-indicator",
66
- // Error
67
- "data-[focus-state=error]:border-rose-500"
68
- ], className),
69
- ref: composedRef
70
- }, children));
71
- });
72
- var Focus = {
73
- Group
74
- };
25
+ import { Focus, useFocus } from "@dxos/react-ui";
75
26
 
76
27
  // src/components/Mosaic/styles.ts
77
28
  var styles = {
@@ -109,23 +60,22 @@ var getSourceData = (source) => {
109
60
  // src/components/Mosaic/Root.tsx
110
61
  import { combine } from "@atlaskit/pragmatic-drag-and-drop/combine";
111
62
  import { monitorForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
112
- import { useComposedRefs as useComposedRefs2 } from "@radix-ui/react-compose-refs";
113
- import { createContext as createContext2 } from "@radix-ui/react-context";
114
- import { Primitive as Primitive2 } from "@radix-ui/react-primitive";
115
- import { Slot as Slot2 } from "@radix-ui/react-slot";
116
- import React2, { forwardRef as forwardRef2, useCallback, useEffect, useRef as useRef2, useState as useState2 } from "react";
63
+ import { useComposedRefs } from "@radix-ui/react-compose-refs";
64
+ import { createContext } from "@radix-ui/react-context";
65
+ import { Primitive } from "@radix-ui/react-primitive";
66
+ import { Slot } from "@radix-ui/react-slot";
67
+ import React, { forwardRef, useCallback, useEffect, useRef, useState } from "react";
117
68
  import { log } from "@dxos/log";
118
- import { mx as mx2 } from "@dxos/ui-theme";
119
69
  var __dxlog_file = "/__w/dxos/dxos/packages/ui/react-ui-mosaic/src/components/Mosaic/Root.tsx";
120
- var [MosaicRootContextProvider, useMosaicRootContext] = createContext2("MosaicRoot");
70
+ var [MosaicRootContextProvider, useMosaicRootContext] = createContext("MosaicRoot");
121
71
  var MOSAIC_ROOT_NAME = "Mosaic.Root";
122
72
  var MOSAIC_ROOT_DEBUG_ATTR = "mosaic-debug";
123
- var MosaicRoot = /* @__PURE__ */ forwardRef2(({ classNames, children, asChild, debug }, forwardedRef) => {
124
- const rootRef = useRef2(null);
125
- const composedRef = useComposedRefs2(rootRef, forwardedRef);
126
- const Comp = asChild ? Slot2 : Primitive2.div;
127
- const [handlers, setHandlers] = useState2({});
128
- const [dragging, setDragging] = useState2();
73
+ var MosaicRoot = /* @__PURE__ */ forwardRef(({ children, asChild, debug }, forwardedRef) => {
74
+ const rootRef = useRef(null);
75
+ const composedRef = useComposedRefs(rootRef, forwardedRef);
76
+ const Comp = asChild ? Slot : Primitive.div;
77
+ const [handlers, setHandlers] = useState({});
78
+ const [dragging, setDragging] = useState();
129
79
  const getSourceHandler = useCallback((source) => {
130
80
  const data = source.data;
131
81
  return {
@@ -170,7 +120,7 @@ var MosaicRoot = /* @__PURE__ */ forwardRef2(({ classNames, children, asChild, d
170
120
  source: {
171
121
  data: sourceData,
172
122
  handler: handlers[sourceData.containerId],
173
- // TOOD(burdon): Check id matches.
123
+ // TODO(burdon): Check id matches.
174
124
  container: location.initial.dropTargets.find((target) => target.data.type === "container")?.element
175
125
  },
176
126
  target: targetData && {
@@ -202,7 +152,7 @@ var MosaicRoot = /* @__PURE__ */ forwardRef2(({ classNames, children, asChild, d
202
152
  location: location.current.dropTargets.map((target) => target.data)
203
153
  }, {
204
154
  F: __dxlog_file,
205
- L: 149,
155
+ L: 144,
206
156
  S: void 0,
207
157
  C: (f, a) => f(...a)
208
158
  });
@@ -221,7 +171,7 @@ var MosaicRoot = /* @__PURE__ */ forwardRef2(({ classNames, children, asChild, d
221
171
  location: location.current.dropTargets.map((target) => target.data)
222
172
  }, {
223
173
  F: __dxlog_file,
224
- L: 162,
174
+ L: 157,
225
175
  S: void 0,
226
176
  C: (f, a) => f(...a)
227
177
  });
@@ -260,7 +210,7 @@ var MosaicRoot = /* @__PURE__ */ forwardRef2(({ classNames, children, asChild, d
260
210
  location: location.current.dropTargets.map((target) => target.data)
261
211
  }, {
262
212
  F: __dxlog_file,
263
- L: 191,
213
+ L: 186,
264
214
  S: void 0,
265
215
  C: (f, a) => f(...a)
266
216
  });
@@ -271,7 +221,7 @@ var MosaicRoot = /* @__PURE__ */ forwardRef2(({ classNames, children, asChild, d
271
221
  handlers: Object.keys(handlers)
272
222
  }, {
273
223
  F: __dxlog_file,
274
- L: 199,
224
+ L: 194,
275
225
  S: void 0,
276
226
  C: (f, a) => f(...a)
277
227
  });
@@ -281,7 +231,7 @@ var MosaicRoot = /* @__PURE__ */ forwardRef2(({ classNames, children, asChild, d
281
231
  if (location.current.dropTargets.length === 0) {
282
232
  log.info("cancelled", void 0, {
283
233
  F: __dxlog_file,
284
- L: 214,
234
+ L: 209,
285
235
  S: void 0,
286
236
  C: (f, a) => f(...a)
287
237
  });
@@ -294,7 +244,7 @@ var MosaicRoot = /* @__PURE__ */ forwardRef2(({ classNames, children, asChild, d
294
244
  handlers: Object.keys(handlers)
295
245
  }, {
296
246
  F: __dxlog_file,
297
- L: 219,
247
+ L: 214,
298
248
  S: void 0,
299
249
  C: (f, a) => f(...a)
300
250
  });
@@ -311,7 +261,7 @@ var MosaicRoot = /* @__PURE__ */ forwardRef2(({ classNames, children, asChild, d
311
261
  source: sourceData
312
262
  }, {
313
263
  F: __dxlog_file,
314
- L: 235,
264
+ L: 230,
315
265
  S: void 0,
316
266
  C: (f, a) => f(...a)
317
267
  });
@@ -341,7 +291,7 @@ var MosaicRoot = /* @__PURE__ */ forwardRef2(({ classNames, children, asChild, d
341
291
  getSourceHandler,
342
292
  getTargetHandler
343
293
  ]);
344
- return /* @__PURE__ */ React2.createElement(MosaicRootContextProvider, {
294
+ return /* @__PURE__ */ React.createElement(MosaicRootContextProvider, {
345
295
  containers: handlers,
346
296
  addContainer: (container) => setHandlers((containers) => ({
347
297
  ...containers,
@@ -354,8 +304,8 @@ var MosaicRoot = /* @__PURE__ */ forwardRef2(({ classNames, children, asChild, d
354
304
  };
355
305
  }),
356
306
  dragging
357
- }, /* @__PURE__ */ React2.createElement(Comp, {
358
- className: mx2("group", classNames),
307
+ }, /* @__PURE__ */ React.createElement(Comp, {
308
+ className: "contents group",
359
309
  [`data-${MOSAIC_ROOT_DEBUG_ATTR}`]: debug,
360
310
  ref: composedRef
361
311
  }, children));
@@ -363,39 +313,52 @@ var MosaicRoot = /* @__PURE__ */ forwardRef2(({ classNames, children, asChild, d
363
313
  MosaicRoot.displayName = MOSAIC_ROOT_NAME;
364
314
 
365
315
  // src/components/Mosaic/Container.tsx
316
+ import { autoScrollForElements } from "@atlaskit/pragmatic-drag-and-drop-auto-scroll/element";
366
317
  import { combine as combine2 } from "@atlaskit/pragmatic-drag-and-drop/combine";
367
318
  import { dropTargetForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
368
- import { autoScrollForElements } from "@atlaskit/pragmatic-drag-and-drop-auto-scroll/element";
369
- import { useComposedRefs as useComposedRefs3 } from "@radix-ui/react-compose-refs";
370
- import { createContext as createContext3 } from "@radix-ui/react-context";
371
- import { Primitive as Primitive3 } from "@radix-ui/react-primitive";
372
- import { Slot as Slot3 } from "@radix-ui/react-slot";
319
+ import { useComposedRefs as useComposedRefs2 } from "@radix-ui/react-compose-refs";
320
+ import { createContext as createContext2 } from "@radix-ui/react-context";
321
+ import { Primitive as Primitive2 } from "@radix-ui/react-primitive";
322
+ import { Slot as Slot2 } from "@radix-ui/react-slot";
373
323
  import { bind } from "bind-event-listener";
374
- import React3, { forwardRef as forwardRef3, useEffect as useEffect2, useMemo as useMemo2, useRef as useRef3, useState as useState3 } from "react";
375
- import { composableProps as composableProps2, mx as mx3 } from "@dxos/ui-theme";
324
+ import React2, { useCallback as useCallback2, useEffect as useEffect2, useMemo as useMemo2, useRef as useRef2, useState as useState2 } from "react";
325
+ import { composable, composableProps } from "@dxos/ui-theme";
376
326
  import { isTruthy } from "@dxos/util";
377
327
  var MOSAIC_CONTAINER_NAME = "Mosaic.Container";
378
- var [MosaicContainerContextProvider, useMosaicContainerContext] = createContext3("MosaicContainer");
328
+ var [MosaicContainerContextProvider, useMosaicContainerContext] = createContext2("MosaicContainer");
379
329
  var MOSAIC_CONTAINER_STATE_ATTR = "mosaic-container-state";
380
330
  var MOSAIC_CONTAINER_PLACEHOLDER_WIDTH = "--mosaic-placeholder-width";
381
331
  var MOSAIC_CONTAINER_PLACEHOLDER_HEIGHT = "--mosaic-placeholder-height";
382
332
  var counter = 0;
383
- var MosaicContainer = /* @__PURE__ */ forwardRef3(({ children, eventHandler: eventHandlerProp, orientation = "vertical", asChild, autoScroll: autoscrollElement, withFocus, debug, ...props }, forwardedRef) => {
384
- const { className, ...rest } = composableProps2(props);
385
- const Comp = asChild ? Slot3 : Primitive3.div;
386
- const rootRef = useRef3(null);
387
- const composedRef = useComposedRefs3(rootRef, forwardedRef);
333
+ var MosaicContainer = composable(({ children, eventHandler: eventHandlerProp, orientation = "vertical", asChild, autoScroll: autoscrollElement, withFocus, currentId, onCurrentChange, debug, ...props }, forwardedRef) => {
334
+ const Comp = asChild ? Slot2 : Primitive2.div;
335
+ const rootRef = useRef2(null);
336
+ const composedRef = useComposedRefs2(rootRef, forwardedRef);
388
337
  const eventHandler = useMemo2(() => eventHandlerProp ?? {
389
338
  id: `mosaic-container-${counter++}`
390
339
  }, [
391
340
  eventHandlerProp
392
341
  ]);
393
342
  const { dragging } = useMosaicRootContext(MOSAIC_CONTAINER_NAME);
394
- const [state, setState] = useState3({
343
+ const [state, setState] = useState2({
395
344
  type: "idle"
396
345
  });
397
- const [activeLocation, setActiveLocation] = useState3();
398
- const [scrolling, setScrolling] = useState3(false);
346
+ const [activeLocation, setActiveLocation] = useState2();
347
+ const [scrolling, setScrolling] = useState2(false);
348
+ const setCurrentId = useCallback2((id) => onCurrentChange?.(id), [
349
+ onCurrentChange
350
+ ]);
351
+ const scrollToRef = useRef2(void 0);
352
+ const registerScrollTo = useCallback2((fn) => {
353
+ scrollToRef.current = fn;
354
+ }, []);
355
+ useEffect2(() => {
356
+ if (currentId) {
357
+ scrollToRef.current?.(currentId);
358
+ }
359
+ }, [
360
+ currentId
361
+ ]);
399
362
  const { setFocus } = useFocus();
400
363
  useEffect2(() => {
401
364
  if (withFocus) {
@@ -530,7 +493,7 @@ var MosaicContainer = /* @__PURE__ */ forwardRef3(({ children, eventHandler: eve
530
493
  data,
531
494
  autoscrollElement
532
495
  ]);
533
- return /* @__PURE__ */ React3.createElement(MosaicContainerContextProvider, {
496
+ return /* @__PURE__ */ React2.createElement(MosaicContainerContextProvider, {
534
497
  id: eventHandler.id,
535
498
  eventHandler,
536
499
  orientation,
@@ -538,14 +501,18 @@ var MosaicContainer = /* @__PURE__ */ forwardRef3(({ children, eventHandler: eve
538
501
  dragging: state.type === "active" ? dragging : void 0,
539
502
  scrolling,
540
503
  activeLocation,
541
- setActiveLocation
542
- }, /* @__PURE__ */ React3.createElement(Comp, {
543
- className: mx3("h-full", className),
544
- style: {
545
- [MOSAIC_CONTAINER_PLACEHOLDER_WIDTH]: state.type === "active" && state.bounds ? `${state.bounds.width}px` : "0px",
546
- [MOSAIC_CONTAINER_PLACEHOLDER_HEIGHT]: state.type === "active" && state.bounds ? `${state.bounds.height}px` : "0px"
547
- },
548
- ...rest,
504
+ setActiveLocation,
505
+ currentId,
506
+ setCurrentId,
507
+ registerScrollTo
508
+ }, /* @__PURE__ */ React2.createElement(Comp, {
509
+ ...composableProps(props, {
510
+ classNames: "h-full",
511
+ style: {
512
+ [MOSAIC_CONTAINER_PLACEHOLDER_WIDTH]: state.type === "active" && state.bounds ? `${state.bounds.width}px` : "0px",
513
+ [MOSAIC_CONTAINER_PLACEHOLDER_HEIGHT]: state.type === "active" && state.bounds ? `${state.bounds.height}px` : "0px"
514
+ }
515
+ }),
549
516
  [`data-${MOSAIC_CONTAINER_STATE_ATTR}`]: state.type,
550
517
  ref: composedRef
551
518
  }, children), debug?.());
@@ -553,28 +520,27 @@ var MosaicContainer = /* @__PURE__ */ forwardRef3(({ children, eventHandler: eve
553
520
  MosaicContainer.displayName = MOSAIC_CONTAINER_NAME;
554
521
 
555
522
  // src/components/Mosaic/Tile.tsx
523
+ import { attachClosestEdge, extractClosestEdge } from "@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge";
556
524
  import { combine as combine3 } from "@atlaskit/pragmatic-drag-and-drop/combine";
557
525
  import { draggable, dropTargetForElements as dropTargetForElements2 } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
558
526
  import { preserveOffsetOnSource } from "@atlaskit/pragmatic-drag-and-drop/element/preserve-offset-on-source";
559
527
  import { setCustomNativeDragPreview } from "@atlaskit/pragmatic-drag-and-drop/element/set-custom-native-drag-preview";
560
- import { attachClosestEdge, extractClosestEdge } from "@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge";
561
528
  import { composeRefs } from "@radix-ui/react-compose-refs";
562
- import { createContext as createContext4 } from "@radix-ui/react-context";
563
- import { Primitive as Primitive4 } from "@radix-ui/react-primitive";
564
- import { Slot as Slot4 } from "@radix-ui/react-slot";
565
- import React4, { forwardRef as forwardRef4, useLayoutEffect, useMemo as useMemo3, useRef as useRef4, useState as useState4 } from "react";
529
+ import { createContext as createContext3 } from "@radix-ui/react-context";
530
+ import { Primitive as Primitive3 } from "@radix-ui/react-primitive";
531
+ import { Slot as Slot3 } from "@radix-ui/react-slot";
532
+ import React3, { useLayoutEffect, useMemo as useMemo3, useRef as useRef3, useState as useState3 } from "react";
566
533
  import { createPortal } from "react-dom";
567
- import { composableProps as composableProps3, mx as mx4 } from "@dxos/ui-theme";
534
+ import { composableProps as composableProps2, slottable } from "@dxos/ui-theme";
568
535
  var MOSAIC_TILE_NAME = "Mosaic.Tile";
569
- var [MosaicTileContextProvider, useMosaicTileContext] = createContext4("MosaicTile");
536
+ var [MosaicTileContextProvider, useMosaicTileContext] = createContext3("MosaicTile");
570
537
  var MOSAIC_TILE_STATE_ATTR = "mosaic-tile-state";
571
- var MosaicTile = /* @__PURE__ */ forwardRef4(({ children, asChild, dragHandle, allowedEdges: allowedEdgesProp, location, id, data: dataProp, debug: _, ...props }, forwardedRef) => {
572
- const { className, ...rest } = composableProps3(props);
573
- const Comp = asChild ? Slot4 : Primitive4.div;
574
- const rootRef = useRef4(null);
538
+ var MosaicTile = slottable(({ children, asChild, dragHandle, allowedEdges: allowedEdgesProp, location, id, data: dataProp, draggable: draggableProp, current: _current, debug: _, ...props }, forwardedRef) => {
539
+ const Comp = asChild ? Slot3 : Primitive3.div;
540
+ const rootRef = useRef3(null);
575
541
  const composedRef = composeRefs(rootRef, forwardedRef);
576
542
  const { id: containerId, eventHandler, orientation, scrolling, setActiveLocation } = useMosaicContainerContext(MOSAIC_TILE_NAME);
577
- const [state, setState] = useState4({
543
+ const [state, setState] = useState3({
578
544
  type: "idle"
579
545
  });
580
546
  const allowedEdges = useMemo3(() => allowedEdgesProp || (orientation === "vertical" ? [
@@ -600,7 +566,7 @@ var MosaicTile = /* @__PURE__ */ forwardRef4(({ children, asChild, dragHandle, a
600
566
  ]);
601
567
  useLayoutEffect(() => {
602
568
  const root = rootRef.current;
603
- if (!root || !containerId || scrolling) {
569
+ if (!draggableProp || !root || !containerId || scrolling) {
604
570
  return;
605
571
  }
606
572
  const handleChange = ({ self, source }) => {
@@ -694,6 +660,8 @@ var MosaicTile = /* @__PURE__ */ forwardRef4(({ children, asChild, dragHandle, a
694
660
  );
695
661
  }, [
696
662
  rootRef,
663
+ forwardedRef,
664
+ containerId,
697
665
  dragHandle,
698
666
  eventHandler,
699
667
  data,
@@ -701,19 +669,22 @@ var MosaicTile = /* @__PURE__ */ forwardRef4(({ children, asChild, dragHandle, a
701
669
  allowedEdges,
702
670
  setActiveLocation
703
671
  ]);
704
- return /* @__PURE__ */ React4.createElement(MosaicTileContextProvider, {
672
+ const { className, ...rest } = composableProps2(props, {
673
+ classNames: "relative outline-none"
674
+ });
675
+ return /* @__PURE__ */ React3.createElement(MosaicTileContextProvider, {
705
676
  state
706
- }, /* @__PURE__ */ React4.createElement(Comp, {
677
+ }, /* @__PURE__ */ React3.createElement(Comp, {
707
678
  ...rest,
679
+ "data-object-id": id,
708
680
  [`data-${MOSAIC_TILE_STATE_ATTR}`]: state.type,
709
681
  role: "listitem",
710
- className: mx4("relative", className),
682
+ className,
711
683
  ref: composedRef
712
- }, children), state.type === "preview" && /* @__PURE__ */ createPortal(/* @__PURE__ */ React4.createElement(Comp, {
684
+ }, children), state.type === "preview" && /* @__PURE__ */ createPortal(/* @__PURE__ */ React3.createElement(Comp, {
713
685
  // NOTE: Use to control appearance while dragging.
714
686
  [`data-${MOSAIC_TILE_STATE_ATTR}`]: state.type,
715
- // TODO(burdon): Configure drop animation.
716
- className: mx4("relative", className),
687
+ className,
717
688
  style: {
718
689
  width: `${state.rect.width}px`,
719
690
  height: `${state.rect.height}px`
@@ -723,18 +694,18 @@ var MosaicTile = /* @__PURE__ */ forwardRef4(({ children, asChild, dragHandle, a
723
694
  MosaicTile.displayName = MOSAIC_TILE_NAME;
724
695
 
725
696
  // src/components/Mosaic/Placeholder.tsx
726
- import { dropTargetForElements as dropTargetForElements3 } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
727
697
  import { DropIndicator as NaturalDropIndicator } from "@atlaskit/pragmatic-drag-and-drop-react-drop-indicator/box";
728
- import { Primitive as Primitive5 } from "@radix-ui/react-primitive";
729
- import { Slot as Slot5 } from "@radix-ui/react-slot";
730
- import React5, { useLayoutEffect as useLayoutEffect2, useMemo as useMemo4, useRef as useRef5 } from "react";
731
- import { mx as mx5 } from "@dxos/ui-theme";
698
+ import { dropTargetForElements as dropTargetForElements3 } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
699
+ import { Primitive as Primitive4 } from "@radix-ui/react-primitive";
700
+ import { Slot as Slot4 } from "@radix-ui/react-slot";
701
+ import React4, { useLayoutEffect as useLayoutEffect2, useMemo as useMemo4, useRef as useRef4 } from "react";
702
+ import { mx } from "@dxos/ui-theme";
732
703
  var MOSAIC_PLACEHOLDER_NAME = "Mosaic.Placeholder";
733
704
  var MOSAIC_PLACEHOLDER_ORIENTATION_ATTR = "mosaic-placeholder-orientation";
734
705
  var MOSAIC_PLACEHOLDER_STATE_ATTR = "mosaic-placeholder-state";
735
706
  var MosaicPlaceholder = ({ classNames, children, asChild, orientation = "vertical", location }) => {
736
- const rootRef = useRef5(null);
737
- const Comp = asChild ? Slot5 : Primitive5.div;
707
+ const rootRef = useRef4(null);
708
+ const Comp = asChild ? Slot4 : Primitive4.div;
738
709
  const { id: containerId, eventHandler, scrolling, activeLocation, setActiveLocation } = useMosaicContainerContext(MOSAIC_PLACEHOLDER_NAME);
739
710
  const data = useMemo4(() => ({
740
711
  type: "placeholder",
@@ -774,11 +745,11 @@ var MosaicPlaceholder = ({ classNames, children, asChild, orientation = "vertica
774
745
  scrolling,
775
746
  setActiveLocation
776
747
  ]);
777
- return /* @__PURE__ */ React5.createElement(Comp, {
748
+ return /* @__PURE__ */ React4.createElement(Comp, {
778
749
  [`data-${MOSAIC_PLACEHOLDER_ORIENTATION_ATTR}`]: orientation,
779
750
  [`data-${MOSAIC_PLACEHOLDER_STATE_ATTR}`]: data.location === activeLocation ? "active" : "idle",
780
751
  role: "none",
781
- className: mx5("relative", classNames),
752
+ className: mx("relative", classNames),
782
753
  ref: rootRef
783
754
  }, children);
784
755
  };
@@ -786,7 +757,7 @@ MosaicPlaceholder.displayName = MOSAIC_PLACEHOLDER_NAME;
786
757
  var DROP_INDICATOR_NAME = "Mosaic.DropIndicator";
787
758
  var MosaicDropIndicator = (props) => {
788
759
  const { state } = useMosaicTileContext(DROP_INDICATOR_NAME);
789
- return state.type === "target" && state.closestEdge ? /* @__PURE__ */ React5.createElement(NaturalDropIndicator, {
760
+ return state.type === "target" && state.closestEdge ? /* @__PURE__ */ React4.createElement(NaturalDropIndicator, {
790
761
  ...props,
791
762
  edge: state.closestEdge
792
763
  }) : null;
@@ -794,24 +765,15 @@ var MosaicDropIndicator = (props) => {
794
765
  MosaicDropIndicator.displayName = DROP_INDICATOR_NAME;
795
766
 
796
767
  // src/components/Mosaic/Stack.tsx
768
+ import { useComposedRefs as useComposedRefs3 } from "@radix-ui/react-compose-refs";
797
769
  import { useVirtualizer } from "@tanstack/react-virtual";
798
- import React6, { Fragment, forwardRef as forwardRef5 } from "react";
770
+ import React5, { forwardRef as forwardRef2, Fragment, useCallback as useCallback3, useEffect as useEffect3, useRef as useRef5 } from "react";
799
771
  import { invariant } from "@dxos/invariant";
800
- import { composableProps as composableProps4, mx as mx6 } from "@dxos/ui-theme";
772
+ import { composable as composable2, composableProps as composableProps3, mx as mx2 } from "@dxos/ui-theme";
801
773
  var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/react-ui-mosaic/src/components/Mosaic/Stack.tsx";
802
774
  var MOSAIC_STACK_NAME = "MosaicStack";
803
- var MosaicStackInner = /* @__PURE__ */ forwardRef5(({ role = "list", orientation: orientationProp = "vertical", draggable: draggable2 = true, items, getId, Tile, debug, ...props }, forwardedRef) => {
804
- const { className, ...rest } = composableProps4(props);
805
- invariant(Tile, void 0, {
806
- F: __dxlog_file2,
807
- L: 63,
808
- S: void 0,
809
- A: [
810
- "Tile",
811
- ""
812
- ]
813
- });
814
- const { id, orientation = orientationProp, dragging } = useMosaicContainerContext(MOSAIC_STACK_NAME);
775
+ var MosaicStackInner = composable2(({ orientation: orientationProp = "vertical", getId, items, scrollIntoView = true, Tile, draggable: draggable2 = true, debug, ...props }, forwardedRef) => {
776
+ const { id, orientation = orientationProp, dragging, currentId, registerScrollTo } = useMosaicContainerContext(MOSAIC_STACK_NAME);
815
777
  const visibleItems = useVisibleItems({
816
778
  id,
817
779
  items,
@@ -820,30 +782,57 @@ var MosaicStackInner = /* @__PURE__ */ forwardRef5(({ role = "list", orientation
820
782
  });
821
783
  invariant(orientation === "vertical" || orientation === "horizontal", `Invalid orientation: ${orientation}`, {
822
784
  F: __dxlog_file2,
823
- L: 66,
785
+ L: 91,
824
786
  S: void 0,
825
787
  A: [
826
788
  "orientation === 'vertical' || orientation === 'horizontal'",
827
789
  "`Invalid orientation: ${orientation}`"
828
790
  ]
829
791
  });
830
- return /* @__PURE__ */ React6.createElement("div", {
831
- ...rest,
832
- role,
833
- className: mx6("flex", orientation === "horizontal" && "h-full [&>*]:shrink-0", orientation === "vertical" && "flex-col", className),
834
- ref: forwardedRef
835
- }, /* @__PURE__ */ React6.createElement(InternalPlaceholder, {
792
+ const rootRef = useRef5(null);
793
+ const scrollToId = useCallback3((targetId) => {
794
+ if (!scrollIntoView) {
795
+ return;
796
+ }
797
+ const el = rootRef.current?.querySelector(`[data-object-id="${CSS.escape(targetId)}"]`);
798
+ el?.scrollIntoView({
799
+ block: "nearest",
800
+ behavior: "smooth"
801
+ });
802
+ }, [
803
+ scrollIntoView
804
+ ]);
805
+ useEffect3(() => {
806
+ registerScrollTo(scrollToId);
807
+ return () => registerScrollTo(void 0);
808
+ }, [
809
+ registerScrollTo,
810
+ scrollToId
811
+ ]);
812
+ const composedRef = useComposedRefs3(rootRef, forwardedRef);
813
+ return /* @__PURE__ */ React5.createElement("div", {
814
+ ...composableProps3(props, {
815
+ role: "list",
816
+ classNames: [
817
+ "flex",
818
+ orientation === "horizontal" && "h-full [&>*]:shrink-0",
819
+ orientation === "vertical" && "flex-col"
820
+ ]
821
+ }),
822
+ ref: composedRef
823
+ }, draggable2 && /* @__PURE__ */ React5.createElement(InternalPlaceholder, {
836
824
  orientation,
837
825
  location: 0.5
838
- }), visibleItems?.map((item, index) => /* @__PURE__ */ React6.createElement(Fragment, {
826
+ }), visibleItems?.map((item, index) => /* @__PURE__ */ React5.createElement(Fragment, {
839
827
  key: getId(item)
840
- }, /* @__PURE__ */ React6.createElement(Tile, {
828
+ }, /* @__PURE__ */ React5.createElement(Tile, {
841
829
  id: getId(item),
842
830
  data: item,
843
831
  location: index + 1,
844
832
  draggable: draggable2,
833
+ current: getId(item) === currentId,
845
834
  debug
846
- }), /* @__PURE__ */ React6.createElement(InternalPlaceholder, {
835
+ }), draggable2 && /* @__PURE__ */ React5.createElement(InternalPlaceholder, {
847
836
  orientation,
848
837
  location: index + 1.5
849
838
  }))));
@@ -851,36 +840,94 @@ var MosaicStackInner = /* @__PURE__ */ forwardRef5(({ role = "list", orientation
851
840
  MosaicStackInner.displayName = MOSAIC_STACK_NAME;
852
841
  var MosaicStack = MosaicStackInner;
853
842
  var MOSAIC_VIRTUAL_STACK_NAME = "MosaicVirtualStack";
854
- var MosaicVirtualStackInner = /* @__PURE__ */ forwardRef5(({ role = "list", orientation = "vertical", items, getId, Tile, estimateSize, getScrollElement, overscan = 8, onChange, debug, ...props }, forwardedRef) => {
855
- const { className, ...rest } = composableProps4(props);
843
+ var MosaicVirtualStackInner = /* @__PURE__ */ forwardRef2(({ orientation = "vertical", getId, items, scrollIntoView = true, Tile, estimateSize, getScrollElement, overscan = 8, gap, onChange, draggable: draggable2 = true, debug, ...props }, forwardedRef) => {
856
844
  invariant(Tile, void 0, {
857
845
  F: __dxlog_file2,
858
- L: 128,
846
+ L: 180,
859
847
  S: void 0,
860
848
  A: [
861
849
  "Tile",
862
850
  ""
863
851
  ]
864
852
  });
865
- const { id, dragging } = useMosaicContainerContext(MOSAIC_VIRTUAL_STACK_NAME);
853
+ const { id, dragging, currentId, registerScrollTo } = useMosaicContainerContext(MOSAIC_VIRTUAL_STACK_NAME);
866
854
  const visibleItems = useVisibleItems({
867
855
  id,
868
856
  items,
869
857
  dragging: dragging?.source.data,
870
858
  getId
871
859
  });
860
+ const wrappedEstimateSize = draggable2 ? (index) => index % 2 === 0 ? 0 : estimateSize(Math.floor(index / 2)) : estimateSize;
872
861
  const virtualizer = useVirtualizer({
873
- count: visibleItems.length * 2 + 1,
874
- estimateSize,
862
+ // NOTE: When draggable we double the number of items to allow for placeholders.
863
+ count: draggable2 ? visibleItems.length * 2 + 1 : visibleItems.length,
864
+ estimateSize: wrappedEstimateSize,
865
+ gap,
866
+ // Key measurements by stable item ID so the size cache survives scrolling;
867
+ // without this, measurements are indexed by position and are lost when items reorder.
868
+ getItemKey: draggable2 ? (index) => index % 2 === 0 ? `ph-${index}` : getId(visibleItems[Math.floor(index / 2)]) : (index) => getId(visibleItems[index]),
875
869
  getScrollElement,
876
870
  overscan,
877
871
  onChange
878
872
  });
873
+ const scrollToId = useCallback3((targetId) => {
874
+ const itemIndex = visibleItems.findIndex((item) => getId(item) === targetId);
875
+ if (itemIndex >= 0) {
876
+ if (!scrollIntoView) {
877
+ return;
878
+ }
879
+ const virtualIndex = draggable2 ? itemIndex * 2 + 1 : itemIndex;
880
+ virtualizer.scrollToIndex(virtualIndex, {
881
+ align: "start",
882
+ behavior: "smooth"
883
+ });
884
+ }
885
+ }, [
886
+ visibleItems,
887
+ getId,
888
+ draggable2,
889
+ virtualizer,
890
+ scrollIntoView
891
+ ]);
892
+ useEffect3(() => {
893
+ registerScrollTo(scrollToId);
894
+ return () => registerScrollTo(void 0);
895
+ }, [
896
+ registerScrollTo,
897
+ scrollToId
898
+ ]);
879
899
  const virtualItems = virtualizer.getVirtualItems();
880
- return /* @__PURE__ */ React6.createElement("div", {
881
- ...rest,
882
- role,
883
- className: mx6("flex", orientation === "horizontal" && "h-full [&>*]:shrink-0", orientation === "vertical" && "flex-col", className),
900
+ const getData = (index) => {
901
+ if (draggable2) {
902
+ if (index % 2 === 0) {
903
+ return {
904
+ location: Math.floor(index / 2) + 0.5
905
+ };
906
+ } else {
907
+ return {
908
+ data: visibleItems[Math.floor(index / 2)],
909
+ location: Math.floor(index / 2) + 1
910
+ };
911
+ }
912
+ } else {
913
+ return {
914
+ data: visibleItems[index],
915
+ location: index + 1
916
+ };
917
+ }
918
+ };
919
+ return /* @__PURE__ */ React5.createElement("div", {
920
+ ...composableProps3(props, {
921
+ role: "list",
922
+ classNames: [
923
+ // shrink-0 is required: this div sets an explicit height via inline style (getTotalSize).
924
+ // Without it, a parent flex container (e.g. ScrollArea.Viewport) would shrink this div
925
+ // to the viewport height, collapsing the scroll content and causing scrollbar drift.
926
+ "flex shrink-0",
927
+ orientation === "horizontal" && "h-full [&>*]:shrink-0",
928
+ orientation === "vertical" && "flex-col"
929
+ ]
930
+ }),
884
931
  style: {
885
932
  position: "relative",
886
933
  ...orientation === "vertical" ? {
@@ -892,43 +939,46 @@ var MosaicVirtualStackInner = /* @__PURE__ */ forwardRef5(({ role = "list", orie
892
939
  }
893
940
  },
894
941
  ref: forwardedRef
895
- }, virtualItems.map((virtualItem) => {
896
- const data = visibleItems[Math.floor(virtualItem.index / 2)];
897
- return /* @__PURE__ */ React6.createElement("div", {
898
- key: virtualItem.key,
899
- "data-index": virtualItem.index,
942
+ }, virtualItems.map(({ key, index, start }) => {
943
+ const { data, location } = getData(index);
944
+ return /* @__PURE__ */ React5.createElement("div", {
945
+ key,
946
+ "data-index": index,
900
947
  style: {
901
948
  position: "absolute",
902
949
  top: 0,
903
950
  left: 0,
904
951
  ...orientation === "vertical" ? {
905
952
  width: "100%",
906
- transform: `translateY(${virtualItem.start}px)`
953
+ transform: `translateY(${start}px)`
907
954
  } : {
908
955
  height: "100%",
909
- transform: `translateX(${virtualItem.start}px)`
956
+ transform: `translateX(${start}px)`
910
957
  }
911
958
  },
912
959
  ref: virtualizer.measureElement
913
- }, virtualItem.index % 2 === 0 ? /* @__PURE__ */ React6.createElement(InternalPlaceholder, {
914
- orientation,
915
- location: Math.floor(virtualItem.index / 2) + 0.5
916
- }) : /* @__PURE__ */ React6.createElement(Tile, {
960
+ }, data ? /* @__PURE__ */ React5.createElement(Tile, {
917
961
  id: getId(data),
918
962
  data,
919
- location: Math.floor(virtualItem.index / 2) + 1,
963
+ location,
964
+ draggable: draggable2,
965
+ current: getId(data) === currentId,
920
966
  debug
967
+ }) : /* @__PURE__ */ React5.createElement(InternalPlaceholder, {
968
+ orientation,
969
+ location
921
970
  }));
922
971
  }));
923
972
  });
924
973
  MosaicVirtualStackInner.displayName = MOSAIC_VIRTUAL_STACK_NAME;
925
974
  var MosaicVirtualStack = MosaicVirtualStackInner;
975
+ MosaicVirtualStack[/* @__PURE__ */ Symbol.for("dxos.composable")] = true;
926
976
  var InternalPlaceholder = (props) => {
927
- return /* @__PURE__ */ React6.createElement(MosaicPlaceholder, {
977
+ return /* @__PURE__ */ React5.createElement(MosaicPlaceholder, {
928
978
  ...props,
929
979
  classNames: styles.placeholder.root
930
- }, /* @__PURE__ */ React6.createElement("div", {
931
- className: mx6("flex h-full bg-base-surface border border-dashed border-separator rounded-xs", styles.placeholder.content)
980
+ }, /* @__PURE__ */ React5.createElement("div", {
981
+ className: mx2("flex h-full bg-base-surface border border-dashed border-separator rounded-xs", styles.placeholder.content)
932
982
  }));
933
983
  };
934
984
  InternalPlaceholder.displayName = "InternalPlaceholder";
@@ -946,8 +996,8 @@ var Mosaic = {
946
996
 
947
997
  export {
948
998
  useVisibleItems,
949
- useFocus,
950
999
  Focus,
1000
+ useFocus,
951
1001
  styles,
952
1002
  getSourceData,
953
1003
  useMosaicRootContext,
@@ -955,4 +1005,4 @@ export {
955
1005
  useMosaicTileContext,
956
1006
  Mosaic
957
1007
  };
958
- //# sourceMappingURL=chunk-75KCPN67.mjs.map
1008
+ //# sourceMappingURL=chunk-33NNDFD6.mjs.map