@dxos/react-ui-mosaic 0.7.1 → 0.7.2-main.f1adc9f

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.
@@ -0,0 +1,705 @@
1
+ import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
+
3
+ // packages/ui/react-ui-mosaic/src/mosaic/hooks/useContainer.ts
4
+ import { useContext } from "react";
5
+
6
+ // packages/ui/react-ui-mosaic/src/mosaic/Container.tsx
7
+ import React, { createContext, useEffect, forwardRef } from "react";
8
+ var DEFAULT_TRANSITION = 200;
9
+ var DEFAULT_TYPE = "unknown";
10
+ var DEFAULT_COMPONENT = /* @__PURE__ */ forwardRef(() => /* @__PURE__ */ React.createElement(React.Fragment, null, "missing component"));
11
+ var MosaicOperations = [
12
+ "transfer",
13
+ "copy",
14
+ "rearrange",
15
+ "reject"
16
+ ];
17
+ var MosaicContainerContext = /* @__PURE__ */ createContext({
18
+ id: "never",
19
+ type: DEFAULT_TYPE,
20
+ Component: DEFAULT_COMPONENT
21
+ });
22
+ var MosaicContainer = ({ children, id, debug, type = DEFAULT_TYPE, Component: Component2 = DEFAULT_COMPONENT, transitionDuration = DEFAULT_TRANSITION, modifier, getOverlayProps, getOverlayStyle, onOver, onDrop, onMove, onDragEnd }) => {
23
+ const mosaic = useMosaic();
24
+ const container = {
25
+ id,
26
+ debug,
27
+ type,
28
+ Component: Component2,
29
+ transitionDuration,
30
+ modifier,
31
+ getOverlayProps,
32
+ getOverlayStyle,
33
+ onOver,
34
+ onDrop,
35
+ onMove,
36
+ onDragEnd
37
+ };
38
+ useEffect(() => {
39
+ mosaic.setContainer(container.id, container);
40
+ return () => {
41
+ };
42
+ }, Object.values(container));
43
+ return /* @__PURE__ */ React.createElement(MosaicContainerContext.Provider, {
44
+ value: container
45
+ }, children);
46
+ };
47
+
48
+ // packages/ui/react-ui-mosaic/src/mosaic/hooks/useContainer.ts
49
+ var useContainer = () => useContext(MosaicContainerContext);
50
+
51
+ // packages/ui/react-ui-mosaic/src/mosaic/hooks/useItemsWithPreview.ts
52
+ import { useEffect as useEffect2, useState as useState2 } from "react";
53
+
54
+ // packages/ui/react-ui-mosaic/src/mosaic/hooks/useMosaic.ts
55
+ import { useContext as useContext2 } from "react";
56
+ import { raise } from "@dxos/debug";
57
+
58
+ // packages/ui/react-ui-mosaic/src/mosaic/Root.tsx
59
+ import { DndContext, KeyboardSensor, MouseSensor, pointerWithin, rectIntersection, TouchSensor, useSensor, useSensors } from "@dnd-kit/core";
60
+ import { sortableKeyboardCoordinates } from "@dnd-kit/sortable";
61
+ import React4, { createContext as createContext2, useState } from "react";
62
+ import { createPortal } from "react-dom";
63
+ import { pick } from "@dxos/util";
64
+
65
+ // packages/ui/react-ui-mosaic/src/mosaic/Debug.tsx
66
+ import React2 from "react";
67
+ import { mx } from "@dxos/react-ui-theme";
68
+ var Debug = ({ data, position }) => /* @__PURE__ */ React2.createElement("pre", {
69
+ className: mx("font-mono text-xs overflow-hidden m-2 p-1 z-[100]", "bg-neutral-50 dark:bg-neutral-700 border border-neutral-300 rounded", position === "bottom-left" && "fixed left-0 bottom-0", position === "bottom-right" && "fixed right-0 bottom-0")
70
+ }, JSON.stringify(data, void 0, 1));
71
+
72
+ // packages/ui/react-ui-mosaic/src/mosaic/DefaultComponent.tsx
73
+ import React3, { forwardRef as forwardRef2 } from "react";
74
+ import { Card } from "@dxos/react-ui-card";
75
+
76
+ // packages/ui/react-ui-mosaic/src/mosaic/util/data.ts
77
+ import { arrayMove } from "@dxos/util";
78
+ var swapItems = (items, from, to) => {
79
+ const fromIndex = items.findIndex((item) => item.id === from.id);
80
+ const toIndex = items.findIndex((item) => item.id === to.id);
81
+ return fromIndex !== -1 && toIndex !== -1 ? arrayMove(items, fromIndex, toIndex) : items;
82
+ };
83
+
84
+ // packages/ui/react-ui-mosaic/src/mosaic/util/path.ts
85
+ var SEPARATOR = "~";
86
+ var Path = {
87
+ create: (...args) => args.join(SEPARATOR),
88
+ parts: (path) => path.split(SEPARATOR),
89
+ length: (path) => path.split(SEPARATOR).length,
90
+ first: (path) => path.split(SEPARATOR)[0] ?? path,
91
+ last: (path) => path.split(SEPARATOR).at(-1) ?? path,
92
+ parent: (path) => path.split(SEPARATOR).slice(0, -1).join(SEPARATOR),
93
+ hasRoot: (path, id) => Path.first(path) === id,
94
+ hasChild: (path, compare) => Path.parent(compare) === path,
95
+ hasDescendent: (path, compare) => compare !== path && compare.startsWith(path),
96
+ siblings: (path, compare) => Path.parent(path) === Path.parent(compare),
97
+ onPath: (path, id) => Path.parts(path).includes(id)
98
+ };
99
+
100
+ // packages/ui/react-ui-mosaic/src/mosaic/util/props.ts
101
+ var isTileProps = (props) => typeof props.path === "string" && typeof props.item === "object" && props.item ? "id" in props.item && typeof props.item.id === "string" : false;
102
+ var isTileComponentProps = (props) => isTileProps(props) && typeof props.operation === "string" && MosaicOperations.includes(props.operation);
103
+
104
+ // packages/ui/react-ui-mosaic/src/mosaic/util/styles.ts
105
+ import { CSS } from "@dnd-kit/utilities";
106
+ var getTransformCSS = (transform) => transform ? CSS.Transform.toString(Object.assign(transform, {
107
+ scaleX: 1,
108
+ scaleY: 1
109
+ })) : void 0;
110
+
111
+ // packages/ui/react-ui-mosaic/src/mosaic/DefaultComponent.tsx
112
+ var DefaultComponent = /* @__PURE__ */ forwardRef2(({ draggableStyle, draggableProps, item: { id }, path }, forwardRef4) => {
113
+ return /* @__PURE__ */ React3.createElement(Card.Root, {
114
+ ref: forwardRef4,
115
+ style: draggableStyle
116
+ }, /* @__PURE__ */ React3.createElement(Card.Header, null, /* @__PURE__ */ React3.createElement(Card.DragHandle, draggableProps), /* @__PURE__ */ React3.createElement(Card.Title, {
117
+ title: Path.create(path, id),
118
+ classNames: "truncate font-mono text-xs"
119
+ })));
120
+ });
121
+ DefaultComponent.displayName = "DefaultComponent";
122
+
123
+ // packages/ui/react-ui-mosaic/src/mosaic/Root.tsx
124
+ var DEFAULT_COMPONENT_ID = "__default";
125
+ var MosaicContext = /* @__PURE__ */ createContext2(void 0);
126
+ var defaultDropAnimation = {
127
+ duration: 0
128
+ };
129
+ var MosaicRoot = ({ Component: Component2 = DefaultComponent, debug, children }) => {
130
+ const [containers, setContainers] = useState({
131
+ [DEFAULT_COMPONENT_ID]: {
132
+ id: DEFAULT_COMPONENT_ID,
133
+ Component: Component2
134
+ }
135
+ });
136
+ const handleSetContainer = (id, container) => {
137
+ setContainers((containers2) => {
138
+ if (container) {
139
+ return {
140
+ ...containers2,
141
+ [id]: container
142
+ };
143
+ } else {
144
+ const { [id]: _, ...rest } = containers2;
145
+ return rest;
146
+ }
147
+ });
148
+ };
149
+ const [activeItem, setActiveItem] = useState();
150
+ const [overItem, setOverItem] = useState();
151
+ const [operation, setOperation] = useState("reject");
152
+ const [moveDetails, setMoveDetails] = useState();
153
+ const [dropAnimation, setDropAnimation] = useState(defaultDropAnimation);
154
+ const collisionDetection = (args) => {
155
+ const pointerCollisions = pointerWithin(args);
156
+ if (pointerCollisions.length > 0) {
157
+ return pointerCollisions;
158
+ }
159
+ return rectIntersection(args);
160
+ };
161
+ const modifiers = (props) => {
162
+ const { transform } = props;
163
+ if (activeItem) {
164
+ const container = containers[Path.first(activeItem.path)];
165
+ return container?.modifier?.(activeItem, props) ?? transform;
166
+ } else {
167
+ return transform;
168
+ }
169
+ };
170
+ const sensors = useSensors(useSensor(MouseSensor, {
171
+ activationConstraint: {
172
+ distance: 10
173
+ }
174
+ }), useSensor(TouchSensor, {
175
+ activationConstraint: {
176
+ delay: 200,
177
+ tolerance: 5
178
+ }
179
+ }), useSensor(KeyboardSensor, {
180
+ coordinateGetter: sortableKeyboardCoordinates
181
+ }));
182
+ const handleDragStart = (event) => {
183
+ setActiveItem(pick(event.active.data.current, [
184
+ "path",
185
+ "type",
186
+ "item",
187
+ "position"
188
+ ]));
189
+ };
190
+ const handleDragMove = (event) => {
191
+ const nextOverItem = pick(event.over?.data.current, [
192
+ "path",
193
+ "type",
194
+ "item",
195
+ "position"
196
+ ]);
197
+ const nextOverContainer = nextOverItem && nextOverItem?.path ? containers[Path.first(nextOverItem.path)] : void 0;
198
+ if (!event.over || !nextOverItem || !nextOverContainer) {
199
+ setOperation("reject");
200
+ setOverItem(void 0);
201
+ return;
202
+ }
203
+ if (overItem !== nextOverItem) {
204
+ setOverItem(nextOverItem);
205
+ }
206
+ if (activeItem && nextOverItem && nextOverContainer?.onMove) {
207
+ const { operation: nextOperation, details: nextDetails } = nextOverContainer.onMove({
208
+ active: activeItem,
209
+ over: nextOverItem,
210
+ details: {
211
+ delta: event.delta
212
+ }
213
+ });
214
+ setOperation(nextOperation);
215
+ if (
216
+ // always set falsy symbols
217
+ !nextDetails || // always set if details become truthy
218
+ !moveDetails && nextDetails || // only update if details change
219
+ Object.entries(nextDetails).find(([key, value]) => !(key in moveDetails) || moveDetails[key] !== value)
220
+ ) {
221
+ setMoveDetails(nextDetails);
222
+ }
223
+ }
224
+ };
225
+ const handleDragOver = (event) => {
226
+ const overItem2 = pick(event.over?.data.current, [
227
+ "path",
228
+ "type",
229
+ "item",
230
+ "position"
231
+ ]);
232
+ const overContainer = overItem2 && overItem2?.path ? containers[Path.first(overItem2.path)] : void 0;
233
+ if (overContainer?.onMove) {
234
+ return;
235
+ }
236
+ const activeContainer = activeItem && containers[Path.first(activeItem.path)];
237
+ if (!event.over || !overItem2 || !overContainer || !activeItem || !activeContainer) {
238
+ setOperation("reject");
239
+ setOverItem(void 0);
240
+ return;
241
+ }
242
+ let operation2 = "reject";
243
+ if (overContainer.onOver) {
244
+ operation2 = overContainer.onOver({
245
+ active: activeItem,
246
+ over: overItem2,
247
+ details: moveDetails
248
+ });
249
+ }
250
+ setOperation(operation2);
251
+ setOverItem(overItem2);
252
+ };
253
+ const handleDragCancel = (event) => {
254
+ setOperation("reject");
255
+ setActiveItem(void 0);
256
+ setOverItem(void 0);
257
+ };
258
+ const handleDragEnd = (event) => {
259
+ const overContainer = overItem && containers[Path.first(overItem.path)];
260
+ if (operation !== "reject" && activeItem && overItem) {
261
+ let nextDropAnimation = defaultDropAnimation;
262
+ const activeContainer = containers[Path.first(activeItem.path)];
263
+ if (activeContainer) {
264
+ nextDropAnimation = activeContainer.onDrop?.({
265
+ operation,
266
+ active: activeItem,
267
+ over: overItem,
268
+ details: moveDetails
269
+ });
270
+ if (overContainer && overContainer !== activeContainer) {
271
+ nextDropAnimation = overContainer.onDrop?.({
272
+ operation,
273
+ active: activeItem,
274
+ over: overItem,
275
+ details: moveDetails
276
+ });
277
+ }
278
+ }
279
+ setDropAnimation(nextDropAnimation);
280
+ }
281
+ Object.values(containers).forEach((container) => container?.onDragEnd?.(event));
282
+ setTimeout(() => {
283
+ setOperation("reject");
284
+ setOverItem(void 0);
285
+ setActiveItem(void 0);
286
+ }, overContainer?.transitionDuration ?? DEFAULT_TRANSITION);
287
+ };
288
+ return /* @__PURE__ */ React4.createElement(MosaicContext.Provider, {
289
+ value: {
290
+ containers,
291
+ setContainer: handleSetContainer,
292
+ activeItem,
293
+ overItem,
294
+ operation,
295
+ moveDetails,
296
+ dropAnimation
297
+ }
298
+ }, /* @__PURE__ */ React4.createElement(DndContext, {
299
+ collisionDetection,
300
+ modifiers: [
301
+ modifiers
302
+ ],
303
+ sensors,
304
+ // TODO(burdon): Allow container to veto drop.
305
+ cancelDrop: (event) => false,
306
+ onDragStart: handleDragStart,
307
+ onDragMove: handleDragMove,
308
+ onDragOver: handleDragOver,
309
+ onDragCancel: handleDragCancel,
310
+ onDragEnd: handleDragEnd
311
+ }, children, debug && /* @__PURE__ */ createPortal(/* @__PURE__ */ React4.createElement(MosaicDebug, {
312
+ containers,
313
+ operation,
314
+ activeItem,
315
+ overItem
316
+ }), document.body)));
317
+ };
318
+ var MosaicDebug = ({ containers, operation, activeItem, overItem }) => {
319
+ return /* @__PURE__ */ React4.createElement(Debug, {
320
+ position: "bottom-right",
321
+ data: {
322
+ containers: Object.keys(containers).map((id) => id),
323
+ operation,
324
+ active: {
325
+ id: activeItem?.item?.id.slice(0, 16),
326
+ path: activeItem?.path && Path.create(...Path.parts(activeItem.path).map((part) => part.slice(0, 16))),
327
+ type: activeItem?.type,
328
+ position: activeItem?.position
329
+ },
330
+ over: {
331
+ id: overItem?.item?.id.slice(0, 16),
332
+ path: overItem?.path && Path.create(...Path.parts(overItem.path).map((part) => part.slice(0, 16))),
333
+ type: overItem?.type,
334
+ position: overItem?.position
335
+ }
336
+ }
337
+ });
338
+ };
339
+
340
+ // packages/ui/react-ui-mosaic/src/mosaic/hooks/useMosaic.ts
341
+ var useMosaic = () => useContext2(MosaicContext) ?? raise(new Error("Missing MosaicContext"));
342
+
343
+ // packages/ui/react-ui-mosaic/src/mosaic/hooks/useItemsWithPreview.ts
344
+ var useItemsWithPreview = ({ path, items }) => {
345
+ const { operation, activeItem, overItem } = useMosaic();
346
+ const [itemsWithPreview, setItemsWithPreview] = useState2(items);
347
+ const overParent = (
348
+ // If over the sortable context itself & active item is foreign, then treat self as the parent.
349
+ // This allows items to be appended to the end of the sortable.
350
+ overItem?.path === path && activeItem && Path.parent(activeItem.path) !== overItem.path ? path : overItem && !!overItem.path && Path.parent(overItem.path)
351
+ );
352
+ const [lastOverParent, setLastOverParent] = useState2(overParent);
353
+ useEffect2(() => {
354
+ if (!activeItem || !overItem) {
355
+ setLastOverParent(void 0);
356
+ setItemsWithPreview(items);
357
+ return;
358
+ }
359
+ if (lastOverParent === overParent) {
360
+ return;
361
+ }
362
+ const activeIsChild = Path.hasChild(path, activeItem.path);
363
+ const overIsChild = Path.hasChild(path, overItem.path);
364
+ const overSelf = overItem.path === path;
365
+ if (operation === "reject" || operation === "rearrange") {
366
+ setLastOverParent(void 0);
367
+ setItemsWithPreview(items);
368
+ return;
369
+ } else {
370
+ setLastOverParent(overParent);
371
+ }
372
+ if (!activeIsChild && overIsChild) {
373
+ setItemsWithPreview((items2) => {
374
+ const position = overItem.position;
375
+ return [
376
+ ...items2.slice(0, position),
377
+ activeItem.item,
378
+ ...items2.slice(position)
379
+ ];
380
+ });
381
+ } else if (!activeIsChild && overSelf) {
382
+ setItemsWithPreview((items2) => [
383
+ ...items2,
384
+ activeItem.item
385
+ ]);
386
+ } else if (activeIsChild && !overIsChild) {
387
+ setItemsWithPreview((items2) => items2.filter((item) => item.id !== activeItem.item.id));
388
+ } else {
389
+ setItemsWithPreview(items);
390
+ }
391
+ }, [
392
+ operation,
393
+ activeItem,
394
+ overItem,
395
+ overParent,
396
+ lastOverParent,
397
+ path,
398
+ items
399
+ ]);
400
+ return items.length === itemsWithPreview.length ? items : itemsWithPreview;
401
+ };
402
+
403
+ // packages/ui/react-ui-mosaic/src/mosaic/hooks/useItemsWithOrigin.ts
404
+ var useItemsWithOrigin = (path, items) => {
405
+ const { operation, activeItem, overItem } = useMosaic();
406
+ if (!activeItem || !overItem) {
407
+ return items;
408
+ }
409
+ const activeIsChild = Path.hasChild(path, activeItem.path);
410
+ const overIsChild = Path.hasChild(path, overItem.path);
411
+ if (activeIsChild && !overIsChild && operation !== "rearrange") {
412
+ return items.map((item) => {
413
+ if (item.id === activeItem.item.id) {
414
+ return {
415
+ ...item,
416
+ id: `${item.id}--origin`
417
+ };
418
+ } else {
419
+ return item;
420
+ }
421
+ });
422
+ } else {
423
+ return items;
424
+ }
425
+ };
426
+
427
+ // packages/ui/react-ui-mosaic/src/mosaic/DragOverlay.tsx
428
+ import { DragOverlay } from "@dnd-kit/core";
429
+ import React5, { Component, useEffect as useEffect3, useRef, useState as useState3 } from "react";
430
+ import { log } from "@dxos/log";
431
+ var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-mosaic/src/mosaic/DragOverlay.tsx";
432
+ var MosaicDragOverlay = ({ delay = 200, debug = false, ...overlayProps }) => {
433
+ const { containers, operation, activeItem, overItem, dropAnimation } = useMosaic();
434
+ const [state, setState] = useState3({});
435
+ const timer = useRef();
436
+ useEffect3(() => {
437
+ if (activeItem && operation !== "reject") {
438
+ let container2;
439
+ let OverlayComponent2;
440
+ if (overItem?.path) {
441
+ container2 = containers[Path.first(overItem.path)];
442
+ OverlayComponent2 = container2?.Component;
443
+ }
444
+ if (!OverlayComponent2) {
445
+ container2 = containers[Path.first(activeItem.path)];
446
+ OverlayComponent2 = container2?.Component ?? DefaultComponent;
447
+ }
448
+ clearTimeout(timer.current);
449
+ timer.current = setTimeout(() => setState({
450
+ container: container2,
451
+ OverlayComponent: OverlayComponent2
452
+ }), timer.current ? delay : 0);
453
+ } else {
454
+ setState({});
455
+ }
456
+ }, [
457
+ activeItem,
458
+ overItem
459
+ ]);
460
+ const container = state.container ?? (activeItem && containers[Path.first(activeItem.path)]);
461
+ const OverlayComponent = state.OverlayComponent ?? container?.Component;
462
+ const FallbackComponent = (activeItem && containers[Path.first(activeItem.path)])?.Component ?? DefaultComponent;
463
+ return (
464
+ // TODO(burdon): Set custom animations (e.g., in/out/around).
465
+ /* @__PURE__ */ React5.createElement(DragOverlay, {
466
+ adjustScale: false,
467
+ ...overlayProps,
468
+ dropAnimation,
469
+ style: {
470
+ ...container?.getOverlayStyle?.()
471
+ }
472
+ }, activeItem?.path && container && OverlayComponent && /* @__PURE__ */ React5.createElement(OverlayErrorBoundary, {
473
+ fallback: /* @__PURE__ */ React5.createElement(FallbackComponent, {
474
+ ...container.getOverlayProps?.(),
475
+ item: activeItem.item,
476
+ path: activeItem.path,
477
+ operation,
478
+ active: "overlay"
479
+ })
480
+ }, /* @__PURE__ */ React5.createElement(OverlayComponent, {
481
+ ...container.getOverlayProps?.(),
482
+ item: activeItem.item,
483
+ path: activeItem.path,
484
+ type: activeItem.type,
485
+ operation,
486
+ active: "overlay"
487
+ }), debug && /* @__PURE__ */ React5.createElement("div", {
488
+ className: "flex flex-wrap mt-1 p-1 bg-neutral-50 dark:bg-neutral-700 text-xs border rounded overflow-hidden gap-1"
489
+ }, /* @__PURE__ */ React5.createElement("span", {
490
+ className: "truncate"
491
+ }, /* @__PURE__ */ React5.createElement("span", {
492
+ className: "text-neutral-400"
493
+ }, "container "), container.id), /* @__PURE__ */ React5.createElement("span", {
494
+ className: "truncate"
495
+ }, /* @__PURE__ */ React5.createElement("span", {
496
+ className: "text-neutral-400"
497
+ }, "item "), activeItem.item.id.slice(0, 8)))))
498
+ );
499
+ };
500
+ var OverlayErrorBoundary = class extends Component {
501
+ constructor(props) {
502
+ super(props);
503
+ this.state = {
504
+ error: null
505
+ };
506
+ this.fallback = props.fallback ?? /* @__PURE__ */ React5.createElement("p", null, "ERROR: $", String(this.state.error));
507
+ }
508
+ static getDerivedStateFromError(error) {
509
+ return {
510
+ error
511
+ };
512
+ }
513
+ componentDidCatch(error, info) {
514
+ log.catch(error, {
515
+ info
516
+ }, {
517
+ F: __dxlog_file,
518
+ L: 140,
519
+ S: this,
520
+ C: (f, a) => f(...a)
521
+ });
522
+ }
523
+ render() {
524
+ if (this.state.error) {
525
+ return this.fallback;
526
+ }
527
+ return this.props.children;
528
+ }
529
+ };
530
+
531
+ // packages/ui/react-ui-mosaic/src/mosaic/SortableContext.tsx
532
+ import { SortableContext, horizontalListSortingStrategy, verticalListSortingStrategy } from "@dnd-kit/sortable";
533
+ import React6 from "react";
534
+ var MosaicSortableContext = ({ id, items = [], direction = "vertical", children }) => {
535
+ const { operation, activeItem, overItem } = useMosaic();
536
+ const container = useContainer();
537
+ const contextId = id ?? container.id;
538
+ const Sortable = direction === "vertical" ? Column : Row;
539
+ const ids = items.map((item) => {
540
+ const path = Path.create(contextId, item.id);
541
+ const isPreview = activeItem && activeItem.item.id === item.id && overItem && overItem.path && (Path.siblings(overItem.path, path) || Path.hasChild(overItem.path, path)) && operation !== "reject";
542
+ return isPreview ? activeItem.path : path;
543
+ });
544
+ return /* @__PURE__ */ React6.createElement(Sortable, {
545
+ id: contextId,
546
+ items: ids
547
+ }, children);
548
+ };
549
+ var Column = ({ children, id, items }) => /* @__PURE__ */ React6.createElement(SortableContext, {
550
+ id,
551
+ items,
552
+ strategy: verticalListSortingStrategy
553
+ }, children);
554
+ var Row = ({ children, id, items }) => /* @__PURE__ */ React6.createElement(SortableContext, {
555
+ id,
556
+ items,
557
+ strategy: horizontalListSortingStrategy
558
+ }, children);
559
+
560
+ // packages/ui/react-ui-mosaic/src/mosaic/Tile.tsx
561
+ import { useDraggable, useDroppable } from "@dnd-kit/core";
562
+ import { defaultAnimateLayoutChanges, useSortable } from "@dnd-kit/sortable";
563
+ import { useComposedRefs } from "@radix-ui/react-compose-refs";
564
+ import React7, { forwardRef as forwardRef3 } from "react";
565
+ var DraggableTile = ({ path: parentPath, type = DEFAULT_TYPE, item, Component: Component2 = DefaultComponent, position, draggableStyle, ...props }) => {
566
+ const { operation } = useMosaic();
567
+ const path = Path.create(parentPath, item.id);
568
+ const {
569
+ setNodeRef,
570
+ attributes,
571
+ listeners,
572
+ /* transform, */
573
+ isDragging
574
+ } = useDraggable({
575
+ id: path,
576
+ data: {
577
+ path,
578
+ type,
579
+ item,
580
+ position
581
+ }
582
+ });
583
+ return /* @__PURE__ */ React7.createElement(Component2, {
584
+ ref: setNodeRef,
585
+ item,
586
+ path,
587
+ type,
588
+ position,
589
+ operation,
590
+ isDragging,
591
+ draggableStyle: {
592
+ // TODO(burdon): Override by container?
593
+ // transform: getTransformCSS(transform),
594
+ ...draggableStyle
595
+ },
596
+ draggableProps: {
597
+ ...attributes,
598
+ ...listeners
599
+ },
600
+ ...props
601
+ });
602
+ };
603
+ var DroppableTile = /* @__PURE__ */ forwardRef3(({ path: parentPath, type = DEFAULT_TYPE, item, Component: Component2 = DefaultComponent, position, ...props }, forwardedRef) => {
604
+ const { operation } = useMosaic();
605
+ const path = parentPath === item.id ? parentPath : Path.create(parentPath, item.id);
606
+ const { setNodeRef, isOver } = useDroppable({
607
+ id: path,
608
+ data: {
609
+ path,
610
+ type,
611
+ item,
612
+ position
613
+ }
614
+ });
615
+ const ref = useComposedRefs(setNodeRef, forwardedRef);
616
+ return /* @__PURE__ */ React7.createElement(Component2, {
617
+ item,
618
+ path,
619
+ type,
620
+ position,
621
+ operation,
622
+ isOver,
623
+ ...props,
624
+ ref
625
+ });
626
+ });
627
+ var SortableTile = ({ path: parentPath, type = DEFAULT_TYPE, item, Component: OverrideComponent, position, draggableStyle, ...props }) => {
628
+ const { operation, activeItem, overItem } = useMosaic();
629
+ const { transitionDuration, Component: ContainerComponent } = useContainer();
630
+ const path = Path.create(parentPath, item.id);
631
+ const isPreview = activeItem && activeItem.item.id === item.id && overItem && activeItem.path && overItem.path && !Path.siblings(activeItem.path, overItem.path) && (Path.siblings(overItem.path, path) || Path.hasChild(overItem.path, path)) && operation !== "reject";
632
+ const { setNodeRef, attributes, listeners, transform, isDragging, isOver } = useSortable({
633
+ id: isPreview ? activeItem.path : path,
634
+ data: {
635
+ path,
636
+ type,
637
+ item,
638
+ position
639
+ },
640
+ animateLayoutChanges: (args) => defaultAnimateLayoutChanges({
641
+ ...args,
642
+ wasDragging: item.id !== activeItem?.item.id
643
+ })
644
+ });
645
+ let active;
646
+ if (isDragging) {
647
+ if (operation === "rearrange" || operation === "reject") {
648
+ active = "rearrange";
649
+ } else if (activeItem && activeItem.path && Path.parent(activeItem.path) !== parentPath) {
650
+ active = "destination";
651
+ } else {
652
+ active = "origin";
653
+ }
654
+ }
655
+ const Component2 = OverrideComponent ?? ContainerComponent ?? DefaultComponent;
656
+ return /* @__PURE__ */ React7.createElement(Component2, {
657
+ ref: setNodeRef,
658
+ item,
659
+ path,
660
+ type,
661
+ position,
662
+ operation,
663
+ active,
664
+ isDragging,
665
+ isOver,
666
+ draggableStyle: {
667
+ transform: getTransformCSS(transform),
668
+ transition: transform ? `transform ${transitionDuration}ms ease` : "none",
669
+ ...draggableStyle
670
+ },
671
+ draggableProps: {
672
+ ...attributes,
673
+ ...listeners
674
+ },
675
+ ...props
676
+ });
677
+ };
678
+
679
+ // packages/ui/react-ui-mosaic/src/mosaic/Mosaic.ts
680
+ var Mosaic = {
681
+ Root: MosaicRoot,
682
+ Container: MosaicContainer,
683
+ DragOverlay: MosaicDragOverlay,
684
+ SortableContext: MosaicSortableContext,
685
+ DraggableTile,
686
+ DroppableTile,
687
+ SortableTile,
688
+ // TODO(wittjosiah): Consider factoring out or using inline styles instead depending on DXOS UI theme/tailwind.
689
+ DefaultComponent,
690
+ // TODO(burdon): Don't export; move to util.
691
+ Debug
692
+ };
693
+ export {
694
+ Mosaic,
695
+ Path,
696
+ getTransformCSS,
697
+ isTileComponentProps,
698
+ isTileProps,
699
+ swapItems,
700
+ useContainer,
701
+ useItemsWithOrigin,
702
+ useItemsWithPreview,
703
+ useMosaic
704
+ };
705
+ //# sourceMappingURL=index.mjs.map