@dxos/react-ui-mosaic 0.8.4-main.21d9917 → 0.8.4-main.2244d791bb

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 (158) hide show
  1. package/dist/lib/browser/{chunk-FS5LRPMY.mjs → chunk-XNANTBOP.mjs} +768 -934
  2. package/dist/lib/browser/chunk-XNANTBOP.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +572 -55
  4. package/dist/lib/browser/index.mjs.map +4 -4
  5. package/dist/lib/browser/meta.json +1 -1
  6. package/dist/lib/browser/testing/index.mjs +27 -274
  7. package/dist/lib/browser/testing/index.mjs.map +4 -4
  8. package/dist/lib/node-esm/{chunk-E5JUEEB7.mjs → chunk-LWXG4JVG.mjs} +768 -934
  9. package/dist/lib/node-esm/chunk-LWXG4JVG.mjs.map +7 -0
  10. package/dist/lib/node-esm/index.mjs +572 -55
  11. package/dist/lib/node-esm/index.mjs.map +4 -4
  12. package/dist/lib/node-esm/meta.json +1 -1
  13. package/dist/lib/node-esm/testing/index.mjs +27 -274
  14. package/dist/lib/node-esm/testing/index.mjs.map +4 -4
  15. package/dist/types/src/components/Board/Board.d.ts +82 -0
  16. package/dist/types/src/components/Board/Board.d.ts.map +1 -0
  17. package/dist/types/src/components/{Mosaic/Mosaic.stories.d.ts → Board/Board.stories.d.ts} +12 -2
  18. package/dist/types/src/components/Board/Board.stories.d.ts.map +1 -0
  19. package/dist/types/src/components/Board/Column.d.ts +35 -0
  20. package/dist/types/src/components/Board/Column.d.ts.map +1 -0
  21. package/dist/types/src/components/Board/Item.d.ts +9 -0
  22. package/dist/types/src/components/Board/Item.d.ts.map +1 -0
  23. package/dist/types/src/components/Board/index.d.ts +2 -0
  24. package/dist/types/src/components/Board/index.d.ts.map +1 -0
  25. package/dist/types/src/components/Card/Card.d.ts +7 -4
  26. package/dist/types/src/components/Card/Card.d.ts.map +1 -1
  27. package/dist/types/src/components/Focus/Focus.d.ts +5 -4
  28. package/dist/types/src/components/Focus/Focus.d.ts.map +1 -1
  29. package/dist/types/src/components/Focus/styles.d.ts.map +1 -1
  30. package/dist/types/src/components/Mosaic/Container.d.ts +42 -0
  31. package/dist/types/src/components/Mosaic/Container.d.ts.map +1 -0
  32. package/dist/types/src/components/Mosaic/Mosaic.d.ts +35 -120
  33. package/dist/types/src/components/Mosaic/Mosaic.d.ts.map +1 -1
  34. package/dist/types/src/components/Mosaic/Placeholder.d.ts +21 -0
  35. package/dist/types/src/components/Mosaic/Placeholder.d.ts.map +1 -0
  36. package/dist/types/src/components/Mosaic/Root.d.ts +36 -0
  37. package/dist/types/src/components/Mosaic/Root.d.ts.map +1 -0
  38. package/dist/types/src/components/Mosaic/Stack.d.ts +23 -0
  39. package/dist/types/src/components/Mosaic/Stack.d.ts.map +1 -0
  40. package/dist/types/src/components/{Stack → Mosaic}/Stack.stories.d.ts +2 -2
  41. package/dist/types/src/components/Mosaic/Stack.stories.d.ts.map +1 -0
  42. package/dist/types/src/components/Mosaic/Tile.d.ts +48 -0
  43. package/dist/types/src/components/Mosaic/Tile.d.ts.map +1 -0
  44. package/dist/types/src/components/Mosaic/styles.d.ts.map +1 -1
  45. package/dist/types/src/components/Mosaic/types.d.ts +9 -2
  46. package/dist/types/src/components/Mosaic/types.d.ts.map +1 -1
  47. package/dist/types/src/components/index.d.ts +1 -2
  48. package/dist/types/src/components/index.d.ts.map +1 -1
  49. package/dist/types/src/hooks/index.d.ts +2 -0
  50. package/dist/types/src/hooks/index.d.ts.map +1 -1
  51. package/dist/types/src/hooks/useContainerDebug.d.ts +9 -0
  52. package/dist/types/src/hooks/useContainerDebug.d.ts.map +1 -0
  53. package/dist/types/src/hooks/useDefaultColumnEventHandler.d.ts +15 -0
  54. package/dist/types/src/hooks/useDefaultColumnEventHandler.d.ts.map +1 -0
  55. package/dist/types/src/hooks/useEventHandlerAdapter.d.ts +1 -1
  56. package/dist/types/src/hooks/useEventHandlerAdapter.d.ts.map +1 -1
  57. package/dist/types/src/hooks/useVisibleItems.d.ts +2 -2
  58. package/dist/types/src/hooks/useVisibleItems.d.ts.map +1 -1
  59. package/dist/types/src/index.d.ts +1 -0
  60. package/dist/types/src/index.d.ts.map +1 -1
  61. package/dist/types/src/playwright/board-manager.d.ts +45 -0
  62. package/dist/types/src/playwright/board-manager.d.ts.map +1 -0
  63. package/dist/types/src/playwright/playwright.config.d.ts +3 -0
  64. package/dist/types/src/playwright/playwright.config.d.ts.map +1 -0
  65. package/dist/types/src/playwright/smoke.spec.d.ts +2 -0
  66. package/dist/types/src/playwright/smoke.spec.d.ts.map +1 -0
  67. package/dist/types/src/testing/CardContainer.d.ts +1 -1
  68. package/dist/types/src/testing/CardContainer.d.ts.map +1 -1
  69. package/dist/types/src/testing/DefaultStackTile.d.ts +2 -2
  70. package/dist/types/src/testing/DefaultStackTile.d.ts.map +1 -1
  71. package/dist/types/src/testing/index.d.ts +1 -1
  72. package/dist/types/src/testing/index.d.ts.map +1 -1
  73. package/dist/types/src/testing/{Board.d.ts → types.d.ts} +2 -15
  74. package/dist/types/src/testing/types.d.ts.map +1 -0
  75. package/dist/types/src/translations.d.ts +4 -1
  76. package/dist/types/src/translations.d.ts.map +1 -1
  77. package/dist/types/tsconfig.tsbuildinfo +1 -1
  78. package/package.json +27 -26
  79. package/src/components/Board/Board.stories.tsx +264 -0
  80. package/src/components/Board/Board.tsx +193 -0
  81. package/src/components/Board/Column.tsx +270 -0
  82. package/src/components/Board/Item.tsx +84 -0
  83. package/src/components/{Layout → Board}/index.ts +1 -1
  84. package/src/components/Card/Card.stories.tsx +1 -1
  85. package/src/components/Card/Card.tsx +25 -2
  86. package/src/components/Card/styles.ts +1 -1
  87. package/src/components/Focus/Focus.tsx +9 -9
  88. package/src/components/Focus/styles.ts +3 -6
  89. package/src/components/Image/Image.stories.tsx +1 -1
  90. package/src/components/Mosaic/Container.tsx +289 -0
  91. package/src/components/Mosaic/Mosaic.tsx +32 -937
  92. package/src/components/Mosaic/Placeholder.tsx +133 -0
  93. package/src/components/Mosaic/Root.tsx +292 -0
  94. package/src/components/{Stack → Mosaic}/Stack.stories.tsx +33 -28
  95. package/src/components/Mosaic/Stack.tsx +246 -0
  96. package/src/components/Mosaic/Tile.tsx +240 -0
  97. package/src/components/Mosaic/styles.ts +14 -11
  98. package/src/components/Mosaic/types.ts +15 -3
  99. package/src/components/index.ts +1 -2
  100. package/src/hooks/index.ts +2 -0
  101. package/src/hooks/useContainerDebug.tsx +48 -0
  102. package/src/hooks/useDefaultColumnEventHandler.ts +35 -0
  103. package/src/hooks/useEventHandlerAdapter.ts +15 -6
  104. package/src/hooks/useVisibleItems.ts +10 -2
  105. package/src/index.ts +1 -0
  106. package/src/playwright/board-manager.ts +144 -0
  107. package/src/playwright/playwright.config.ts +16 -0
  108. package/src/playwright/smoke.spec.ts +138 -0
  109. package/src/testing/CardContainer.tsx +12 -7
  110. package/src/testing/DefaultStackTile.tsx +2 -2
  111. package/src/testing/index.ts +1 -1
  112. package/src/testing/types.ts +38 -0
  113. package/src/translations.ts +4 -1
  114. package/dist/lib/browser/chunk-FS5LRPMY.mjs.map +0 -7
  115. package/dist/lib/browser/index.css +0 -13
  116. package/dist/lib/browser/index.css.map +0 -7
  117. package/dist/lib/browser/testing/index.css +0 -13
  118. package/dist/lib/browser/testing/index.css.map +0 -7
  119. package/dist/lib/node-esm/chunk-E5JUEEB7.mjs.map +0 -7
  120. package/dist/lib/node-esm/index.css +0 -13
  121. package/dist/lib/node-esm/index.css.map +0 -7
  122. package/dist/lib/node-esm/testing/index.css +0 -13
  123. package/dist/lib/node-esm/testing/index.css.map +0 -7
  124. package/dist/types/src/components/Layout/Layout.d.ts +0 -33
  125. package/dist/types/src/components/Layout/Layout.d.ts.map +0 -1
  126. package/dist/types/src/components/Layout/Layout.stories.d.ts +0 -10
  127. package/dist/types/src/components/Layout/Layout.stories.d.ts.map +0 -1
  128. package/dist/types/src/components/Layout/index.d.ts +0 -2
  129. package/dist/types/src/components/Layout/index.d.ts.map +0 -1
  130. package/dist/types/src/components/Mosaic/Mosaic.stories.d.ts.map +0 -1
  131. package/dist/types/src/components/Scrollable/Scrollable.d.ts +0 -17
  132. package/dist/types/src/components/Scrollable/Scrollable.d.ts.map +0 -1
  133. package/dist/types/src/components/Scrollable/Scrollable.stories.d.ts +0 -8
  134. package/dist/types/src/components/Scrollable/Scrollable.stories.d.ts.map +0 -1
  135. package/dist/types/src/components/Scrollable/index.d.ts +0 -2
  136. package/dist/types/src/components/Scrollable/index.d.ts.map +0 -1
  137. package/dist/types/src/components/Stack/Stack.d.ts +0 -24
  138. package/dist/types/src/components/Stack/Stack.d.ts.map +0 -1
  139. package/dist/types/src/components/Stack/Stack.stories.d.ts.map +0 -1
  140. package/dist/types/src/components/Stack/index.d.ts +0 -2
  141. package/dist/types/src/components/Stack/index.d.ts.map +0 -1
  142. package/dist/types/src/testing/Board.d.ts.map +0 -1
  143. package/dist/types/src/testing/Slot.stories.d.ts +0 -14
  144. package/dist/types/src/testing/Slot.stories.d.ts.map +0 -1
  145. package/dist/types/src/testing/Virtualizer.stories.d.ts +0 -12
  146. package/dist/types/src/testing/Virtualizer.stories.d.ts.map +0 -1
  147. package/src/components/Layout/Layout.stories.tsx +0 -59
  148. package/src/components/Layout/Layout.tsx +0 -108
  149. package/src/components/Mosaic/Mosaic.stories.tsx +0 -113
  150. package/src/components/Scrollable/Scrollable.stories.tsx +0 -33
  151. package/src/components/Scrollable/Scrollable.tsx +0 -99
  152. package/src/components/Scrollable/index.ts +0 -5
  153. package/src/components/Scrollable/scrollable.css +0 -20
  154. package/src/components/Stack/Stack.tsx +0 -210
  155. package/src/components/Stack/index.ts +0 -5
  156. package/src/testing/Board.tsx +0 -262
  157. package/src/testing/Slot.stories.tsx +0 -101
  158. package/src/testing/Virtualizer.stories.tsx +0 -133
@@ -1,424 +1,37 @@
1
- // src/components/Card/styles.ts
2
- var styles = {
3
- root: "group/card relative min-bs-[--rail-item] overflow-hidden is-full card-min-width __card-max-width",
4
- border: "bg-cardSurface border border-separator dark:border-subduedSeparator rounded-sm dx-focus-ring-group-y-indicator",
5
- /**
6
- * Row grid.
7
- * NOTE: Rows should provide their own line padding (since they may need to encapsulate buttons, etc.)
8
- */
9
- grid_3: "grid grid-cols-[var(--rail-item)_minmax(0,1fr)_var(--rail-item)] gap-x-1",
10
- grid_2: "grid grid-cols-[var(--rail-item)_minmax(0,1fr)] gap-x-1",
11
- // TODO(burdon): Address density.
12
- grid_3_coarse: "grid grid-cols-[var(--l0-avatar-size)_minmax(0,1fr)_var(--rail-item)] gap-x-1",
13
- poster: "max-bs-[200px]"
14
- };
15
-
16
- // src/components/Image/Image.tsx
17
- import React, { useCallback, useRef, useState } from "react";
18
- import { mx } from "@dxos/ui-theme";
19
- var cache = /* @__PURE__ */ new Map();
20
- var Image = ({ classNames, src, alt = "", crossOrigin = "anonymous", sampleSize = 64, contrast = 0.9 }) => {
21
- const [crossOriginState, setCrossOriginState] = useState(crossOrigin);
22
- const [dominantColor, setDominantColor] = useState(void 0);
23
- const [imageLoaded, setImageLoaded] = useState(false);
24
- const canvasRef = useRef(null);
25
- const handleImageError = () => {
26
- setCrossOriginState(void 0);
27
- };
28
- const handleImageLoad = useCallback(({ target }) => {
29
- const rgb = cache.get(src);
30
- if (rgb) {
31
- setDominantColor(rgb);
32
- setImageLoaded(true);
33
- return;
34
- }
35
- const img = target;
36
- if (!canvasRef.current) {
37
- return;
1
+ // src/hooks/useVisibleItems.ts
2
+ import { useMemo } from "react";
3
+ var useVisibleItems = ({ id, items, dragging, getId }) => {
4
+ const visibleItems = useMemo(() => {
5
+ if (!items || !dragging || id !== dragging.containerId) {
6
+ return items ?? [];
38
7
  }
39
- try {
40
- const color = extractDominantColor(canvasRef.current, img, {
41
- sampleSize,
42
- contrast
43
- });
44
- if (color) {
45
- const rgb2 = `rgb(${color[0]}, ${color[1]}, ${color[2]})`;
46
- cache.set(src, rgb2);
47
- setDominantColor(rgb2);
48
- }
49
- } catch {
50
- setCrossOriginState(void 0);
8
+ const idx = items.findIndex((item) => getId(item) === dragging.id);
9
+ if (idx === -1) {
10
+ return items;
51
11
  }
52
- setImageLoaded(true);
12
+ const visibleItems2 = items.slice();
13
+ visibleItems2.splice(idx, 1);
14
+ return visibleItems2;
53
15
  }, [
54
- sampleSize,
55
- contrast,
56
- src
16
+ id,
17
+ items,
18
+ dragging,
19
+ getId
57
20
  ]);
58
- return /* @__PURE__ */ React.createElement("div", {
59
- className: mx(`relative flex is-full justify-center overflow-hidden transition-all duration-700`, classNames),
60
- style: {
61
- backgroundColor: dominantColor
62
- }
63
- }, /* @__PURE__ */ React.createElement("canvas", {
64
- ref: canvasRef,
65
- style: {
66
- display: "none"
67
- },
68
- "aria-hidden": "true"
69
- }), /* @__PURE__ */ React.createElement("div", {
70
- className: "absolute inset-0 pointer-events-none",
71
- style: {
72
- background: dominantColor ? `radial-gradient(circle at center, transparent 30%, ${dominantColor} 100%)` : void 0,
73
- transition: "opacity 0.7s ease-in-out",
74
- opacity: 0.5
75
- }
76
- }), /* @__PURE__ */ React.createElement("img", {
77
- src,
78
- alt,
79
- crossOrigin: crossOriginState,
80
- onError: handleImageError,
81
- onLoad: handleImageLoad,
82
- className: mx("z-10 object-contain transition-opacity duration-500", classNames),
83
- style: {
84
- opacity: imageLoaded ? 1 : 0
85
- }
86
- }));
87
- };
88
- var extractDominantColor = (canvas, img, { sampleSize = 64, contrast = 0.95 }) => {
89
- const ctx = canvas.getContext("2d");
90
- if (!ctx) {
91
- return null;
92
- }
93
- canvas.width = sampleSize;
94
- canvas.height = sampleSize;
95
- ctx.drawImage(img, 0, 0, sampleSize, sampleSize);
96
- const imageData = ctx.getImageData(0, 0, sampleSize, sampleSize);
97
- const pixels = imageData.data;
98
- if (isTransparent(pixels, sampleSize)) {
99
- return null;
100
- }
101
- let r = 0;
102
- let g = 0;
103
- let b = 0;
104
- let totalWeight = 0;
105
- const cornerSize = Math.floor(sampleSize * 0.125);
106
- for (let y = 0; y < sampleSize; y++) {
107
- for (let x = 0; x < sampleSize; x++) {
108
- const isInTopLeft = x < cornerSize && y < cornerSize;
109
- const isInTopRight = x >= sampleSize - cornerSize && y < cornerSize;
110
- const isInBottomLeft = x < cornerSize && y >= sampleSize - cornerSize;
111
- const isInBottomRight = x >= sampleSize - cornerSize && y >= sampleSize - cornerSize;
112
- if (!isInTopLeft && !isInTopRight && !isInBottomLeft && !isInBottomRight) {
113
- continue;
114
- }
115
- const i = (y * sampleSize + x) * 4;
116
- const red = pixels[i];
117
- const green = pixels[i + 1];
118
- const blue = pixels[i + 2];
119
- const alpha = pixels[i + 3];
120
- if (alpha === 0) continue;
121
- const max = Math.max(red, green, blue);
122
- const min = Math.min(red, green, blue);
123
- const saturation = max === 0 ? 0 : (max - min) / max;
124
- const weight = 1 + saturation * 2;
125
- r += red * weight;
126
- g += green * weight;
127
- b += blue * weight;
128
- totalWeight += weight;
129
- }
130
- }
131
- if (totalWeight > 0) {
132
- r = Math.round(Math.round(r / totalWeight) * contrast);
133
- g = Math.round(Math.round(g / totalWeight) * contrast);
134
- b = Math.round(Math.round(b / totalWeight) * contrast);
135
- return [
136
- r,
137
- g,
138
- b
139
- ];
140
- }
141
- return null;
142
- };
143
- var isTransparent = (pixels, sampleSize, threshold = 0.5) => {
144
- let edgeTransparentPixels = 0;
145
- const edgePixels = sampleSize * 4 - 4;
146
- for (let x = 0; x < sampleSize; x++) {
147
- const topIndex = x * 4;
148
- if (pixels[topIndex + 3] === 0) edgeTransparentPixels++;
149
- const bottomIndex = ((sampleSize - 1) * sampleSize + x) * 4;
150
- if (pixels[bottomIndex + 3] === 0) edgeTransparentPixels++;
151
- }
152
- for (let y = 1; y < sampleSize - 1; y++) {
153
- const leftIndex = y * sampleSize * 4;
154
- if (pixels[leftIndex + 3] === 0) edgeTransparentPixels++;
155
- const rightIndex = (y * sampleSize + sampleSize - 1) * 4;
156
- if (pixels[rightIndex + 3] === 0) edgeTransparentPixels++;
157
- }
158
- return edgeTransparentPixels / edgePixels > threshold;
159
- };
160
-
161
- // src/components/Card/Card.tsx
162
- import { Slot } from "@radix-ui/react-slot";
163
- import React2, { createContext, forwardRef, useContext } from "react";
164
- import { Button, DropdownMenu, Icon, Toolbar, useTranslation } from "@dxos/react-ui";
165
- import { mx as mx2 } from "@dxos/ui-theme";
166
-
167
- // src/translations.ts
168
- var translationKey = "@dxos/react-ui-mosaic";
169
- var translations = [
170
- {
171
- "en-US": {
172
- [translationKey]: {}
173
- }
174
- }
175
- ];
176
-
177
- // src/components/Card/Card.tsx
178
- var CardContext = /* @__PURE__ */ createContext({});
179
- var CardRoot = /* @__PURE__ */ forwardRef(({ children, classNames, className, id, asChild, role = "group", border = true, fullWidth, ...props }, forwardedRef) => {
180
- const Root2 = asChild ? Slot : "div";
181
- return /* @__PURE__ */ React2.createElement(Root2, {
182
- ...id && {
183
- "data-object-id": id
184
- },
185
- ...props,
186
- role,
187
- className: mx2(styles.root, border && styles.border, fullWidth && "!max-is-none", className, classNames),
188
- ref: forwardedRef
189
- }, children);
190
- });
191
- var CardToolbar = /* @__PURE__ */ forwardRef(({ children, classNames, density = "fine", ...props }, forwardedRef) => {
192
- return /* @__PURE__ */ React2.createElement(Toolbar.Root, {
193
- ...props,
194
- classNames: [
195
- "density-fine bg-transparent",
196
- density === "fine" ? styles.grid_3 : styles.grid_3_coarse,
197
- classNames
198
- ],
199
- ref: forwardedRef
200
- }, children);
201
- });
202
- var CardToolbarIconButton = Toolbar.IconButton;
203
- var CardToolbarSeparator = Toolbar.Separator;
204
- var CardDragHandle = /* @__PURE__ */ forwardRef((_, forwardedRef) => {
205
- const { t } = useTranslation(translationKey);
206
- return /* @__PURE__ */ React2.createElement(Toolbar.IconButton, {
207
- "data-testid": "card-drag-handle",
208
- noTooltip: true,
209
- iconOnly: true,
210
- icon: "ph--dots-six-vertical--regular",
211
- variant: "ghost",
212
- label: t("drag handle label"),
213
- classNames: "cursor-pointer",
214
- size: 5,
215
- disabled: !forwardedRef,
216
- ref: forwardedRef
217
- });
218
- });
219
- var CardClose = /* @__PURE__ */ forwardRef(({ onClick }, forwardedRef) => {
220
- const { t } = useTranslation(translationKey);
221
- return /* @__PURE__ */ React2.createElement(Toolbar.IconButton, {
222
- iconOnly: true,
223
- icon: "ph--x--regular",
224
- variant: "ghost",
225
- label: t("card close label"),
226
- classNames: "cursor-pointer",
227
- size: 5,
228
- onClick,
229
- ref: forwardedRef
230
- });
231
- });
232
- var CardMenu = ({ context, items }) => {
233
- const { t } = useTranslation(translationKey);
234
- const { menuItems } = useContext(CardContext) ?? {};
235
- const combinedItems = [
236
- ...items ?? [],
237
- ...menuItems ?? []
238
- ];
239
- return /* @__PURE__ */ React2.createElement(DropdownMenu.Root, null, /* @__PURE__ */ React2.createElement(DropdownMenu.Trigger, {
240
- disabled: !combinedItems.length,
241
- asChild: true
242
- }, /* @__PURE__ */ React2.createElement(Card.ToolbarIconButton, {
243
- iconOnly: true,
244
- variant: "ghost",
245
- icon: "ph--dots-three-vertical--regular",
246
- label: t("action menu label")
247
- })), (combinedItems?.length ?? 0) > 0 && /* @__PURE__ */ React2.createElement(DropdownMenu.Portal, null, /* @__PURE__ */ React2.createElement(DropdownMenu.Content, null, /* @__PURE__ */ React2.createElement(DropdownMenu.Viewport, null, combinedItems?.map(({ label, onClick: onSelect }, i) => /* @__PURE__ */ React2.createElement(DropdownMenu.Item, {
248
- key: i,
249
- onSelect: () => onSelect(context)
250
- }, label))), /* @__PURE__ */ React2.createElement(DropdownMenu.Arrow, null))));
251
- };
252
- var CardTitle = /* @__PURE__ */ forwardRef(({ children, classNames, className, asChild, role = "heading", ...props }, forwardedRef) => {
253
- const Root2 = asChild ? Slot : "div";
254
- return /* @__PURE__ */ React2.createElement(Root2, {
255
- ...props,
256
- role,
257
- className: mx2("grow truncate", classNames, className),
258
- ref: forwardedRef
259
- }, children);
260
- });
261
- var CardContent = /* @__PURE__ */ forwardRef(({ children, ...props }, forwardedRef) => {
262
- return /* @__PURE__ */ React2.createElement("div", {
263
- role: "none",
264
- className: "contents [&>:last-child]:pbe-1",
265
- ...props,
266
- ref: forwardedRef
267
- }, children);
268
- });
269
- var CardRow = /* @__PURE__ */ forwardRef(({ children, classNames, className, role = "none", icon, ...props }, forwardedRef) => {
270
- return /* @__PURE__ */ React2.createElement("div", {
271
- ...props,
272
- role,
273
- className: mx2(styles.grid_2, "pli-1", classNames, className),
274
- ref: forwardedRef
275
- }, icon && /* @__PURE__ */ React2.createElement(CardIcon, {
276
- classNames: "text-subdued",
277
- icon
278
- }) || /* @__PURE__ */ React2.createElement("div", null), children);
279
- });
280
- var CardHeading = /* @__PURE__ */ forwardRef(({ children, classNames, className, asChild, role = "heading", variant = "default", ...props }, forwardedRef) => {
281
- const Root2 = asChild ? Slot : "div";
282
- const variantClassNames = {
283
- default: "plb-1",
284
- subtitle: "plb-2 text-xs text-description font-medium uppercase"
285
- };
286
- return /* @__PURE__ */ React2.createElement(Root2, {
287
- ...props,
288
- role,
289
- className: mx2(variantClassNames[variant], classNames, className),
290
- ref: forwardedRef
291
- }, children);
292
- });
293
- var CardText = /* @__PURE__ */ forwardRef(({ children, classNames, className, asChild, role = "none", truncate, variant = "default", ...props }, forwardedRef) => {
294
- const Root2 = asChild ? Slot : "div";
295
- const variantClassNames = {
296
- default: {
297
- root: "plb-1"
298
- },
299
- description: {
300
- root: "plb-1.5",
301
- span: "text-sm text-description line-clamp-3"
302
- }
303
- };
304
- return /* @__PURE__ */ React2.createElement(Root2, {
305
- ...props,
306
- role,
307
- className: mx2("flex overflow-hidden", variantClassNames[variant].root, classNames, className),
308
- ref: forwardedRef
309
- }, /* @__PURE__ */ React2.createElement("span", {
310
- className: mx2(variantClassNames[variant].span, truncate && "truncate")
311
- }, children));
312
- });
313
- var CardPoster = (props) => {
314
- const aspect = props.aspect === "auto" ? "aspect-auto" : "aspect-video";
315
- if (props.image) {
316
- return /* @__PURE__ */ React2.createElement("div", {
317
- role: "none",
318
- className: "mbe-1"
319
- }, /* @__PURE__ */ React2.createElement(Image, {
320
- classNames: [
321
- styles.poster,
322
- aspect,
323
- props.classNames
324
- ],
325
- src: props.image,
326
- alt: props.alt
327
- }));
328
- }
329
- if (props.icon) {
330
- return /* @__PURE__ */ React2.createElement("div", {
331
- role: "image",
332
- className: mx2("grid place-items-center bg-inputSurface text-subdued", styles.poster, aspect, props.classNames),
333
- "aria-label": props.alt
334
- }, /* @__PURE__ */ React2.createElement(Icon, {
335
- icon: props.icon,
336
- size: 10
337
- }));
338
- }
339
- };
340
- var CardAction = ({ icon, actionIcon = "ph--arrow-right--regular", label, onClick }) => {
341
- return /* @__PURE__ */ React2.createElement("div", {
342
- role: "none",
343
- className: "is-full pli-1"
344
- }, /* @__PURE__ */ React2.createElement(Button, {
345
- variant: "ghost",
346
- classNames: mx2(styles.grid_3, "!p-0 is-full text-start overflow-hidden"),
347
- onClick
348
- }, icon ? /* @__PURE__ */ React2.createElement(CardIcon, {
349
- classNames: "text-subdued",
350
- icon
351
- }) : /* @__PURE__ */ React2.createElement("div", null), /* @__PURE__ */ React2.createElement("span", {
352
- className: mx2("min-is-0 flex-1 truncate", !actionIcon && "col-span-2")
353
- }, label), actionIcon && /* @__PURE__ */ React2.createElement(CardIcon, {
354
- icon: actionIcon
355
- })));
356
- };
357
- var CardLink = ({ label, href }) => {
358
- return /* @__PURE__ */ React2.createElement("div", {
359
- role: "none",
360
- className: "is-full pli-1"
361
- }, /* @__PURE__ */ React2.createElement("a", {
362
- className: mx2(styles.grid_3, "group !p-0 dx-button dx-focus-ring !min-bs-1"),
363
- "data-variant": "ghost",
364
- href,
365
- target: "_blank",
366
- rel: "noreferrer"
367
- }, /* @__PURE__ */ React2.createElement(CardIcon, {
368
- classNames: "text-subdued",
369
- icon: "ph--link--regular"
370
- }), /* @__PURE__ */ React2.createElement("span", {
371
- className: mx2("min-is-0 flex-1 truncate")
372
- }, label), /* @__PURE__ */ React2.createElement(CardIcon, {
373
- classNames: "invisible group-hover:visible",
374
- icon: "ph--arrow-square-out--regular"
375
- })));
376
- };
377
- var CardIcon = ({ toolbar, ...props }) => {
378
- return /* @__PURE__ */ React2.createElement("div", {
379
- role: "none",
380
- className: "grid bs-[var(--rail-item)] is-[var(--rail-item)] place-items-center"
381
- }, /* @__PURE__ */ React2.createElement(Icon, {
382
- ...props,
383
- size: toolbar ? 5 : 4
384
- }));
385
- };
386
- var Card = {
387
- Context: CardContext,
388
- Root: CardRoot,
389
- // Toolbar
390
- Toolbar: CardToolbar,
391
- ToolbarIconButton: CardToolbarIconButton,
392
- ToolbarSeparator: CardToolbarSeparator,
393
- DragHandle: CardDragHandle,
394
- Title: CardTitle,
395
- Close: CardClose,
396
- Menu: CardMenu,
397
- Icon: CardIcon,
398
- // Content
399
- Content: CardContent,
400
- Row: CardRow,
401
- Heading: CardHeading,
402
- Text: CardText,
403
- Poster: CardPoster,
404
- Action: CardAction,
405
- Link: CardLink
21
+ return visibleItems;
406
22
  };
407
23
 
408
24
  // src/components/Focus/styles.ts
409
- var styles2 = {
25
+ var styles = {
410
26
  container: {
411
- // TODO(burdon): Handle selection (aria-current?)
412
- // TODO(burdon): Use ring instead of border?
413
27
  root: [
414
- "outline-none border border-separator rounded-sm",
28
+ // TODO(burdon): Option for border/rounded; ring/outline vs border?
29
+ "outline-none border border-separator md:rounded-sm",
415
30
  // Focus (e.g., via tabster).
416
- // TODO(burdon): Why is ! required?
417
31
  "focus:!border-accentSurface",
418
32
  // Active (e.g., drop target).
419
33
  "data-[focus-state=active]:border-neutralFocusIndicator",
420
34
  // Error
421
- // TODO(burdon): Error token.
422
35
  "data-[focus-state=error]:border-rose-500"
423
36
  ]
424
37
  }
@@ -428,32 +41,32 @@ var styles2 = {
428
41
  import { useArrowNavigationGroup, useFocusableGroup, useMergedTabsterAttributes_unstable } from "@fluentui/react-tabster";
429
42
  import { useComposedRefs } from "@radix-ui/react-compose-refs";
430
43
  import { Primitive } from "@radix-ui/react-primitive";
431
- import { Slot as Slot2 } from "@radix-ui/react-slot";
432
- import React3, { createContext as createContext2, forwardRef as forwardRef2, useContext as useContext2, useRef as useRef2, useState as useState2 } from "react";
433
- import { mx as mx3 } from "@dxos/ui-theme";
44
+ import { Slot } from "@radix-ui/react-slot";
45
+ import React, { createContext, forwardRef, useContext, useRef, useState } from "react";
46
+ import { mx } from "@dxos/ui-theme";
434
47
  var FOCUS_STATE_ATTR = "focus-state";
435
- var FocusContext = /* @__PURE__ */ createContext2({});
436
- var useFocus = () => useContext2(FocusContext);
437
- var Group = /* @__PURE__ */ forwardRef2(({ classNames, className, children, asChild, axis = "vertical", ...props }, forwardedRef) => {
438
- const rootRef = useRef2(null);
48
+ var FocusContext = /* @__PURE__ */ createContext({});
49
+ var useFocus = () => useContext(FocusContext);
50
+ var Group = /* @__PURE__ */ forwardRef(({ classNames, className, children, asChild, orientation = "vertical", ...props }, forwardedRef) => {
51
+ const rootRef = useRef(null);
439
52
  const composedRef = useComposedRefs(rootRef, forwardedRef);
440
- const Root2 = asChild ? Slot2 : Primitive.div;
53
+ const Root = asChild ? Slot : Primitive.div;
441
54
  const focusableGroupAttrs = useFocusableGroup({
442
55
  tabBehavior: "limited-trap-focus"
443
56
  });
444
57
  const arrowNavigationAttrs = useArrowNavigationGroup({
445
- axis,
58
+ axis: orientation,
446
59
  memorizeCurrent: true
447
60
  });
448
61
  const tabsterAttrs = useMergedTabsterAttributes_unstable(focusableGroupAttrs, arrowNavigationAttrs);
449
- const [state, setState] = useState2();
450
- return /* @__PURE__ */ React3.createElement(FocusContext.Provider, {
62
+ const [state, setState] = useState();
63
+ return /* @__PURE__ */ React.createElement(FocusContext.Provider, {
451
64
  value: {
452
65
  setFocus: setState
453
66
  }
454
- }, /* @__PURE__ */ React3.createElement(Root2, {
67
+ }, /* @__PURE__ */ React.createElement(Root, {
455
68
  tabIndex: 0,
456
- className: mx3(styles2.container.root, className, classNames),
69
+ className: mx(styles.container.root, className, classNames),
457
70
  ...tabsterAttrs,
458
71
  ...state && {
459
72
  [`data-${FOCUS_STATE_ATTR}`]: state
@@ -467,288 +80,59 @@ var Focus = {
467
80
  };
468
81
 
469
82
  // src/components/Mosaic/styles.ts
470
- var styles3 = {
83
+ var styles2 = {
471
84
  placeholder: {
472
85
  root: [
473
86
  "group opacity-0",
474
- 'group-data-[mosaic-debug="true"]:bg-orange-500',
475
87
  'group-data-[mosaic-debug="true"]:opacity-100',
88
+ 'group-data-[mosaic-debug="true"]:bg-orange-500',
476
89
  "data-[mosaic-placeholder-state=active]:opacity-100",
477
- "data-[mosaic-placeholder-axis=vertical]:plb-1",
478
- "data-[mosaic-placeholder-axis=vertical]:data-[mosaic-placeholder-state=active]:plb-2.5",
479
- "data-[mosaic-placeholder-axis=horizontal]:pli-1",
480
- "data-[mosaic-placeholder-axis=horizontal]:data-[mosaic-placeholder-state=active]:pli-2.5"
90
+ "data-[mosaic-placeholder-orientation=vertical]:snap-start",
91
+ "data-[mosaic-placeholder-orientation=vertical]:plb-1",
92
+ "data-[mosaic-placeholder-orientation=vertical]:data-[mosaic-placeholder-state=active]:plb-2.5",
93
+ "data-[mosaic-placeholder-orientation=horizontal]:pli-1",
94
+ "data-[mosaic-placeholder-orientation=horizontal]:data-[mosaic-placeholder-state=active]:pli-2.5"
481
95
  ],
482
- // TODO(burdon): Don't animate open if placeholder is the source.
483
96
  content: [
484
97
  "transition-all duration-0",
485
- "group-data-[mosaic-placeholder-state=active]:duration-200",
486
- "group-data-[mosaic-placeholder-axis=vertical]:bs-0",
487
- "group-data-[mosaic-placeholder-axis=horizontal]:is-0",
488
- "group-data-[mosaic-placeholder-axis=vertical]:group-data-[mosaic-placeholder-state=active]:bs-[var(--mosaic-placeholder-height)]",
489
- "group-data-[mosaic-placeholder-axis=horizontal]:group-data-[mosaic-placeholder-state=active]:is-[var(--mosaic-placeholder-width)]"
98
+ // TODO(burdon): Don't animate open if placeholder is the source.
99
+ // TODO(burdon): Flickers when start to drag since source is removed and then the placeholder shows up.
100
+ // - Use absolute positioning?
101
+ // 'group-data-[mosaic-placeholder-state=active]:duration-200',
102
+ "group-data-[mosaic-placeholder-orientation=vertical]:bs-0",
103
+ "group-data-[mosaic-placeholder-orientation=vertical]:group-data-[mosaic-placeholder-state=active]:bs-[var(--mosaic-placeholder-height)]",
104
+ "group-data-[mosaic-placeholder-orientation=horizontal]:is-0",
105
+ "group-data-[mosaic-placeholder-orientation=horizontal]:group-data-[mosaic-placeholder-state=active]:is-[var(--mosaic-placeholder-width)]"
490
106
  ]
491
107
  }
492
108
  };
493
109
 
494
- // src/components/Mosaic/extension.ts
495
- import { StateEffect, StateField } from "@codemirror/state";
496
- import { Decoration, EditorView, ViewPlugin, WidgetType } from "@codemirror/view";
497
- var dropHandler = ({ onDrop = handleDrop } = {}) => {
498
- const views = /* @__PURE__ */ new Set();
499
- let state = null;
500
- const reset = () => {
501
- views.forEach((view) => view.dispatch({
502
- effects: setDrop.of(null)
503
- }));
504
- state = null;
505
- };
506
- const extension = [
507
- dropField,
508
- ViewPlugin.fromClass(class {
509
- _view;
510
- constructor(_view) {
511
- this._view = _view;
512
- views.add(_view);
513
- }
514
- destroy() {
515
- views.delete(this._view);
516
- }
517
- })
518
- ];
519
- return {
520
- extension,
521
- update: (position) => {
522
- if (!position) {
523
- reset();
524
- return;
525
- }
526
- views.forEach((view) => {
527
- const rect = view.dom.getBoundingClientRect();
528
- if (position.x >= rect.left && position.x <= rect.right && position.y >= rect.top && position.y <= rect.bottom) {
529
- let pos = view.posAtCoords(position);
530
- if (pos !== null) {
531
- const word = view.state.wordAt(pos);
532
- if (word) {
533
- const startDist = Math.abs(pos - word.from);
534
- const endDist = Math.abs(pos - word.to);
535
- pos = startDist < endDist ? word.from : word.to;
536
- }
537
- view.dispatch({
538
- effects: setDrop.of(pos)
539
- });
540
- state = {
541
- view,
542
- pos
543
- };
544
- return;
545
- }
546
- }
547
- view.dispatch({
548
- effects: setDrop.of(null)
549
- });
550
- });
551
- },
552
- cancel: () => {
553
- reset();
554
- },
555
- drop: ({ text, url }) => {
556
- if (state) {
557
- onDrop(state.view, state.pos, {
558
- text,
559
- url
560
- });
561
- }
562
- reset();
563
- }
564
- };
565
- };
566
- var handleDrop = (view, pos, event) => {
567
- const line = view.state.doc.lineAt(pos);
568
- if (line.text.trim() === "") {
569
- view.dispatch({
570
- changes: {
571
- from: pos,
572
- insert: `
573
- ![${event.text}](${event.url})
574
- `
575
- },
576
- effects: setDrop.of(null)
577
- });
578
- } else {
579
- view.dispatch({
580
- changes: {
581
- from: pos,
582
- insert: ` [${event.text}](${event.url})`
583
- },
584
- effects: setDrop.of(null)
585
- });
586
- }
587
- };
588
- var setDrop = StateEffect.define();
589
- var dropField = StateField.define({
590
- create: () => Decoration.none,
591
- update: (decorations, tr) => {
592
- for (const effect of tr.effects) {
593
- if (effect.is(setDrop)) {
594
- if (effect.value === null) {
595
- return Decoration.none;
596
- }
597
- return Decoration.set([
598
- Decoration.widget({
599
- widget: new class extends WidgetType {
600
- toDOM() {
601
- const dom = document.createElement("span");
602
- dom.className = "cm-drop-cursor";
603
- dom.style.borderLeft = "2px solid var(--dx-accentSurface)";
604
- dom.style.display = "inline-block";
605
- dom.style.height = "1em";
606
- dom.style.verticalAlign = "middle";
607
- return dom;
608
- }
609
- }(),
610
- side: 0
611
- }).range(effect.value)
612
- ]);
613
- }
614
- }
615
- return decorations.map(tr.changes);
616
- },
617
- provide: (field) => EditorView.decorations.from(field)
618
- });
619
-
620
- // src/components/Stack/Stack.tsx
621
- import { useVirtualizer } from "@tanstack/react-virtual";
622
- import React6, { Fragment, forwardRef as forwardRef5 } from "react";
623
- import { invariant } from "@dxos/invariant";
624
- import { mx as mx6 } from "@dxos/ui-theme";
625
-
626
- // src/hooks/useVisibleItems.ts
627
- import { useMemo } from "react";
628
- var useVisibleItems = ({ id, items, dragging, getId }) => {
629
- const visibleItems = useMemo(() => {
630
- if (!items || !dragging || id !== dragging.containerId) {
631
- return items ?? [];
632
- }
633
- const idx = items.findIndex((item) => getId(item) === dragging.id);
634
- if (idx === -1) {
635
- return items;
636
- }
637
- const visibleItems2 = items.slice();
638
- visibleItems2.splice(idx, 1);
639
- return visibleItems2;
640
- }, [
641
- id,
642
- items,
643
- dragging,
644
- getId
645
- ]);
646
- return visibleItems;
110
+ // src/components/Mosaic/types.ts
111
+ var getSourceData = (source) => {
112
+ return source.data.type === "tile" ? source.data : null;
647
113
  };
648
114
 
649
- // src/components/Mosaic/Mosaic.tsx
115
+ // src/components/Mosaic/Root.tsx
650
116
  import { combine } from "@atlaskit/pragmatic-drag-and-drop/combine";
651
- import { draggable, dropTargetForElements, monitorForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
652
- import { preserveOffsetOnSource } from "@atlaskit/pragmatic-drag-and-drop/element/preserve-offset-on-source";
653
- import { setCustomNativeDragPreview } from "@atlaskit/pragmatic-drag-and-drop/element/set-custom-native-drag-preview";
654
- import { autoScrollForElements } from "@atlaskit/pragmatic-drag-and-drop-auto-scroll/element";
655
- import { attachClosestEdge, extractClosestEdge } from "@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge";
656
- import { DropIndicator as NativeDropIndicator } from "@atlaskit/pragmatic-drag-and-drop-react-drop-indicator/box";
657
- import { composeRefs, useComposedRefs as useComposedRefs2 } from "@radix-ui/react-compose-refs";
658
- import { createContext as createContext3 } from "@radix-ui/react-context";
117
+ import { monitorForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
118
+ import { useComposedRefs as useComposedRefs2 } from "@radix-ui/react-compose-refs";
119
+ import { createContext as createContext2 } from "@radix-ui/react-context";
659
120
  import { Primitive as Primitive2 } from "@radix-ui/react-primitive";
660
- import { Slot as Slot3 } from "@radix-ui/react-slot";
661
- import { bind } from "bind-event-listener";
662
- import React5, { forwardRef as forwardRef4, useCallback as useCallback2, useEffect as useEffect2, useLayoutEffect, useMemo as useMemo3, useRef as useRef4, useState as useState3 } from "react";
663
- import { createPortal } from "react-dom";
121
+ import { Slot as Slot2 } from "@radix-ui/react-slot";
122
+ import React2, { forwardRef as forwardRef2, useCallback, useEffect, useRef as useRef2, useState as useState2 } from "react";
664
123
  import { log } from "@dxos/log";
665
- import { Json } from "@dxos/react-ui-syntax-highlighter";
666
- import { mx as mx5 } from "@dxos/ui-theme";
667
- import { isTruthy } from "@dxos/util";
668
-
669
- // src/components/Scrollable/Scrollable.tsx
670
- import { OverlayScrollbarsComponent } from "overlayscrollbars-react";
671
- import React4, { forwardRef as forwardRef3, useEffect, useMemo as useMemo2, useRef as useRef3 } from "react";
672
- import { mx as mx4 } from "@dxos/ui-theme";
673
- import "overlayscrollbars/styles/overlayscrollbars.css";
674
- var defaultOptions = {
675
- scrollbars: {
676
- autoHide: "leave",
677
- autoHideDelay: 1e3,
678
- autoHideSuspend: true
679
- }
680
- };
681
- var Scrollable = /* @__PURE__ */ forwardRef3(({ classNames, axis = "vertical", padding, options: optionsProp = defaultOptions, onScroll, viewportRef, ...props }, forwardedRef) => {
682
- const osRef = useRef3(null);
683
- const options = useMemo2(() => {
684
- const options2 = {
685
- ...optionsProp
686
- };
687
- if (axis) {
688
- options2.overflow = {
689
- x: axis === "horizontal" ? "scroll" : "hidden",
690
- y: axis === "vertical" ? "scroll" : "hidden"
691
- };
692
- }
693
- return options2;
694
- }, [
695
- axis,
696
- optionsProp
697
- ]);
698
- useEffect(() => {
699
- const hostElement = osRef.current?.getElement();
700
- if (forwardedRef) {
701
- if (typeof forwardedRef === "function") {
702
- forwardedRef(hostElement ?? null);
703
- } else {
704
- forwardedRef.current = hostElement ?? null;
705
- }
706
- }
707
- });
708
- useEffect(() => {
709
- const instance = osRef.current?.osInstance();
710
- if (viewportRef) {
711
- viewportRef.current = instance?.elements().viewport ?? null;
712
- }
713
- }, [
714
- osRef,
715
- viewportRef
716
- ]);
717
- const events = useMemo2(() => {
718
- if (!onScroll) {
719
- return null;
720
- }
721
- return {
722
- scroll: (_, event) => {
723
- onScroll(event);
724
- }
725
- };
726
- }, [
727
- onScroll
728
- ]);
729
- return /* @__PURE__ */ React4.createElement(OverlayScrollbarsComponent, {
730
- ...props,
731
- className: mx4(padding && axis === "vertical" ? "pli-3" : "pbe-3", classNames),
732
- options,
733
- events,
734
- ref: osRef
735
- });
736
- });
737
-
738
- // src/components/Mosaic/Mosaic.tsx
739
- var __dxlog_file = "/__w/dxos/dxos/packages/ui/react-ui-mosaic/src/components/Mosaic/Mosaic.tsx";
740
- var getSourceData = (source) => {
741
- return source.data.type === "tile" ? source.data : null;
742
- };
743
- var [RootContextProvider, useRootContext] = createContext3("MosaicRoot");
744
- var ROOT_DEBUG_ATTR = "mosaic-debug";
745
- var Root = /* @__PURE__ */ forwardRef4(({ classNames, children, asChild, debug }, forwardedRef) => {
746
- const rootRef = useRef4(null);
124
+ import { mx as mx2 } from "@dxos/ui-theme";
125
+ var __dxlog_file = "/__w/dxos/dxos/packages/ui/react-ui-mosaic/src/components/Mosaic/Root.tsx";
126
+ var [MosaicRootContextProvider, useMosaicRootContext] = createContext2("MosaicRoot");
127
+ var MOSAIC_ROOT_NAME = "Mosaic.Root";
128
+ var MOSAIC_ROOT_DEBUG_ATTR = "mosaic-debug";
129
+ var MosaicRoot = /* @__PURE__ */ forwardRef2(({ classNames, children, asChild, debug }, forwardedRef) => {
130
+ const rootRef = useRef2(null);
747
131
  const composedRef = useComposedRefs2(rootRef, forwardedRef);
748
- const Root2 = asChild ? Slot3 : Primitive2.div;
749
- const [handlers, setHandlers] = useState3({});
750
- const [dragging, setDragging] = useState3();
751
- const getSourceHandler = useCallback2((source) => {
132
+ const Root = asChild ? Slot2 : Primitive2.div;
133
+ const [handlers, setHandlers] = useState2({});
134
+ const [dragging, setDragging] = useState2();
135
+ const getSourceHandler = useCallback((source) => {
752
136
  const data = source.data;
753
137
  return {
754
138
  data,
@@ -757,7 +141,7 @@ var Root = /* @__PURE__ */ forwardRef4(({ classNames, children, asChild, debug }
757
141
  }, [
758
142
  handlers
759
143
  ]);
760
- const getTargetHandler = useCallback2((location) => {
144
+ const getTargetHandler = useCallback((location) => {
761
145
  for (const target of location.current.dropTargets) {
762
146
  const data = target.data;
763
147
  let containerId;
@@ -782,7 +166,7 @@ var Root = /* @__PURE__ */ forwardRef4(({ classNames, children, asChild, debug }
782
166
  }, [
783
167
  handlers
784
168
  ]);
785
- useEffect2(() => {
169
+ useEffect(() => {
786
170
  const handleChange = ({ source, location }) => {
787
171
  const { data: sourceData } = getSourceHandler(source);
788
172
  const { data: targetData, handler } = getTargetHandler(location);
@@ -802,7 +186,19 @@ var Root = /* @__PURE__ */ forwardRef4(({ classNames, children, asChild, debug }
802
186
  };
803
187
  });
804
188
  };
805
- return monitorForElements({
189
+ const handleCancel = () => {
190
+ setDragging((dragging2) => {
191
+ requestAnimationFrame(() => {
192
+ dragging2?.target?.handler?.onCancel?.();
193
+ dragging2?.source?.container?.dispatchEvent(new CustomEvent("dnd:cancel", {
194
+ bubbles: true
195
+ }));
196
+ });
197
+ return void 0;
198
+ });
199
+ };
200
+ let noTargetTimeout;
201
+ return combine(monitorForElements({
806
202
  /**
807
203
  * Dragging started within any container.
808
204
  */
@@ -812,7 +208,7 @@ var Root = /* @__PURE__ */ forwardRef4(({ classNames, children, asChild, debug }
812
208
  location: location.current.dropTargets.map((target) => target.data)
813
209
  }, {
814
210
  F: __dxlog_file,
815
- L: 203,
211
+ L: 149,
816
212
  S: void 0,
817
213
  C: (f, a) => f(...a)
818
214
  });
@@ -825,19 +221,24 @@ var Root = /* @__PURE__ */ forwardRef4(({ classNames, children, asChild, debug }
825
221
  * Dragging entered a new container.
826
222
  */
827
223
  onDropTargetChange: ({ source, location }) => {
224
+ clearTimeout(noTargetTimeout);
828
225
  log("Root.onDropTargetChange", {
829
226
  source: source.data,
830
227
  location: location.current.dropTargets.map((target) => target.data)
831
228
  }, {
832
229
  F: __dxlog_file,
833
- L: 215,
230
+ L: 162,
834
231
  S: void 0,
835
232
  C: (f, a) => f(...a)
836
233
  });
837
- handleChange({
838
- source,
839
- location
840
- });
234
+ if (location.current.dropTargets.length === 0) {
235
+ noTargetTimeout = setTimeout(() => setDragging(void 0), 1e3);
236
+ } else {
237
+ handleChange({
238
+ source,
239
+ location
240
+ });
241
+ }
841
242
  },
842
243
  /**
843
244
  * Dragging within any container.
@@ -860,12 +261,12 @@ var Root = /* @__PURE__ */ forwardRef4(({ classNames, children, asChild, debug }
860
261
  * Dragging ended.
861
262
  */
862
263
  onDrop: ({ source, location }) => {
863
- log("Root.onDrop", {
264
+ log.info("Root.onDrop", {
864
265
  source: source.data,
865
266
  location: location.current.dropTargets.map((target) => target.data)
866
267
  }, {
867
268
  F: __dxlog_file,
868
- L: 239,
269
+ L: 191,
869
270
  S: void 0,
870
271
  C: (f, a) => f(...a)
871
272
  });
@@ -876,14 +277,21 @@ var Root = /* @__PURE__ */ forwardRef4(({ classNames, children, asChild, debug }
876
277
  handlers: Object.keys(handlers)
877
278
  }, {
878
279
  F: __dxlog_file,
879
- L: 247,
280
+ L: 199,
880
281
  S: void 0,
881
282
  C: (f, a) => f(...a)
882
283
  });
883
284
  return;
884
285
  }
885
286
  try {
886
- if (location.current.dropTargets.length > 0) {
287
+ if (location.current.dropTargets.length === 0) {
288
+ log.info("cancelled", void 0, {
289
+ F: __dxlog_file,
290
+ L: 214,
291
+ S: void 0,
292
+ C: (f, a) => f(...a)
293
+ });
294
+ } else {
887
295
  const { data: targetData, handler: targetHandler } = getTargetHandler(location);
888
296
  if (!targetHandler) {
889
297
  log.warn("invalid target", {
@@ -892,7 +300,7 @@ var Root = /* @__PURE__ */ forwardRef4(({ classNames, children, asChild, debug }
892
300
  handlers: Object.keys(handlers)
893
301
  }, {
894
302
  F: __dxlog_file,
895
- L: 260,
303
+ L: 219,
896
304
  S: void 0,
897
305
  C: (f, a) => f(...a)
898
306
  });
@@ -909,7 +317,7 @@ var Root = /* @__PURE__ */ forwardRef4(({ classNames, children, asChild, debug }
909
317
  source: sourceData
910
318
  }, {
911
319
  F: __dxlog_file,
912
- L: 276,
320
+ L: 235,
913
321
  S: void 0,
914
322
  C: (f, a) => f(...a)
915
323
  });
@@ -919,7 +327,6 @@ var Root = /* @__PURE__ */ forwardRef4(({ classNames, children, asChild, debug }
919
327
  source: sourceData
920
328
  }, async (object) => {
921
329
  targetHandler.onDrop?.({
922
- // TODO(burdon): Change source!!!
923
330
  source: {
924
331
  ...sourceData,
925
332
  data: object
@@ -931,24 +338,16 @@ var Root = /* @__PURE__ */ forwardRef4(({ classNames, children, asChild, debug }
931
338
  }
932
339
  }
933
340
  } finally {
934
- setDragging((dragging2) => {
935
- requestAnimationFrame(() => {
936
- dragging2?.target?.handler?.onCancel?.();
937
- dragging2?.source?.container?.dispatchEvent(new CustomEvent("dnd:cancel", {
938
- bubbles: true
939
- }));
940
- });
941
- return void 0;
942
- });
341
+ handleCancel();
943
342
  }
944
343
  }
945
- });
344
+ }));
946
345
  }, [
947
346
  handlers,
948
347
  getSourceHandler,
949
348
  getTargetHandler
950
349
  ]);
951
- return /* @__PURE__ */ React5.createElement(RootContextProvider, {
350
+ return /* @__PURE__ */ React2.createElement(MosaicRootContextProvider, {
952
351
  containers: handlers,
953
352
  addContainer: (container) => setHandlers((containers) => ({
954
353
  ...containers,
@@ -961,27 +360,42 @@ var Root = /* @__PURE__ */ forwardRef4(({ classNames, children, asChild, debug }
961
360
  };
962
361
  }),
963
362
  dragging
964
- }, /* @__PURE__ */ React5.createElement(Root2, {
965
- className: mx5("group overflow-hidden", classNames),
966
- [`data-${ROOT_DEBUG_ATTR}`]: debug,
363
+ }, /* @__PURE__ */ React2.createElement(Root, {
364
+ className: mx2("group", classNames),
365
+ [`data-${MOSAIC_ROOT_DEBUG_ATTR}`]: debug,
967
366
  ref: composedRef
968
367
  }, children));
969
368
  });
970
- var [ContainerContextProvider, useContainerContext] = createContext3("MosaicContainer");
971
- var CONTAINER_STATE_ATTR = "mosaic-container-state";
972
- var CONTAINER_PLACEHOLDER_WIDTH = "--mosaic-placeholder-width";
973
- var CONTAINER_PLACEHOLDER_HEIGHT = "--mosaic-placeholder-height";
369
+ MosaicRoot.displayName = MOSAIC_ROOT_NAME;
370
+
371
+ // src/components/Mosaic/Container.tsx
372
+ import { combine as combine2 } from "@atlaskit/pragmatic-drag-and-drop/combine";
373
+ import { dropTargetForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
374
+ import { autoScrollForElements } from "@atlaskit/pragmatic-drag-and-drop-auto-scroll/element";
375
+ import { useComposedRefs as useComposedRefs3 } from "@radix-ui/react-compose-refs";
376
+ import { createContext as createContext3 } from "@radix-ui/react-context";
377
+ import { Primitive as Primitive3 } from "@radix-ui/react-primitive";
378
+ import { Slot as Slot3 } from "@radix-ui/react-slot";
379
+ import { bind } from "bind-event-listener";
380
+ import React3, { forwardRef as forwardRef3, useEffect as useEffect2, useMemo as useMemo2, useRef as useRef3, useState as useState3 } from "react";
381
+ import { mx as mx3 } from "@dxos/ui-theme";
382
+ import { isTruthy } from "@dxos/util";
383
+ var MOSAIC_CONTAINER_NAME = "Mosaic.Container";
384
+ var [MosaicContainerContextProvider, useMosaicContainerContext] = createContext3("MosaicContainer");
385
+ var MOSAIC_CONTAINER_STATE_ATTR = "mosaic-container-state";
386
+ var MOSAIC_CONTAINER_PLACEHOLDER_WIDTH = "--mosaic-placeholder-width";
387
+ var MOSAIC_CONTAINER_PLACEHOLDER_HEIGHT = "--mosaic-placeholder-height";
974
388
  var counter = 0;
975
- var Container = /* @__PURE__ */ forwardRef4(({ className, classNames, children, eventHandler: eventHandlerProp, axis = "vertical", asChild, autoScroll: autoscrollElement, withFocus, debug, ...props }, forwardedRef) => {
976
- const rootRef = useRef4(null);
977
- const composedRef = useComposedRefs2(rootRef, forwardedRef);
978
- const Root2 = asChild ? Slot3 : Primitive2.div;
979
- const eventHandler = useMemo3(() => eventHandlerProp ?? {
389
+ var MosaicContainer = /* @__PURE__ */ forwardRef3(({ classNames, className, children, eventHandler: eventHandlerProp, orientation = "vertical", asChild, autoScroll: autoscrollElement, withFocus, debug, ...props }, forwardedRef) => {
390
+ const rootRef = useRef3(null);
391
+ const composedRef = useComposedRefs3(rootRef, forwardedRef);
392
+ const Root = asChild ? Slot3 : Primitive3.div;
393
+ const eventHandler = useMemo2(() => eventHandlerProp ?? {
980
394
  id: `mosaic-container-${counter++}`
981
395
  }, [
982
396
  eventHandlerProp
983
397
  ]);
984
- const { dragging } = useRootContext(Container.displayName);
398
+ const { dragging } = useMosaicRootContext(MOSAIC_CONTAINER_NAME);
985
399
  const [state, setState] = useState3({
986
400
  type: "idle"
987
401
  });
@@ -997,14 +411,14 @@ var Container = /* @__PURE__ */ forwardRef4(({ className, classNames, children,
997
411
  withFocus,
998
412
  state
999
413
  ]);
1000
- const { addContainer, removeContainer } = useRootContext(eventHandler.id);
414
+ const { addContainer, removeContainer } = useMosaicRootContext(eventHandler.id);
1001
415
  useEffect2(() => {
1002
416
  addContainer(eventHandler);
1003
417
  return () => removeContainer(eventHandler.id);
1004
418
  }, [
1005
419
  eventHandler
1006
420
  ]);
1007
- const data = useMemo3(() => ({
421
+ const data = useMemo2(() => ({
1008
422
  type: "container",
1009
423
  id: eventHandler.id
1010
424
  }), [
@@ -1022,24 +436,18 @@ var Container = /* @__PURE__ */ forwardRef4(({ className, classNames, children,
1022
436
  setScrolling(false);
1023
437
  }, 500);
1024
438
  };
1025
- return combine(...[
1026
- autoscrollElement && [
1027
- autoScrollForElements({
1028
- element: autoscrollElement,
1029
- canScroll: ({ element: _ }) => {
1030
- return true;
1031
- },
1032
- getAllowedAxis: () => axis,
1033
- getConfiguration: () => ({
1034
- maxScrollSpeed: "fast"
1035
- })
1036
- }),
1037
- bind(autoscrollElement, {
1038
- type: "scroll",
1039
- listener: handleScroll
1040
- }),
1041
- () => setScrolling(false)
1042
- ],
439
+ return combine2(...[
440
+ /**
441
+ * Custom event for dragging cancellation.
442
+ */
443
+ bind(rootRef.current, {
444
+ type: "dnd:cancel",
445
+ listener: () => {
446
+ setState({
447
+ type: "idle"
448
+ });
449
+ }
450
+ }),
1043
451
  // Target.
1044
452
  dropTargetForElements({
1045
453
  element: rootRef.current,
@@ -1100,17 +508,26 @@ var Container = /* @__PURE__ */ forwardRef4(({ className, classNames, children,
1100
508
  });
1101
509
  }
1102
510
  }),
1103
- /**
1104
- * Custom event for dragging cancellation.
1105
- */
1106
- bind(rootRef.current, {
1107
- type: "dnd:cancel",
1108
- listener: () => {
1109
- setState({
1110
- type: "idle"
1111
- });
1112
- }
1113
- })
511
+ // Autoscroll.
512
+ // NOTE: When used with Scrollable we get a spurious warning (in dev mode).
513
+ // "Auto scrolling has been attached to an element that appears not to be scrollable."
514
+ autoscrollElement && [
515
+ autoScrollForElements({
516
+ element: autoscrollElement,
517
+ // canScroll: ({ element: _ }) => {
518
+ // return true;
519
+ // },
520
+ getAllowedAxis: () => orientation,
521
+ getConfiguration: () => ({
522
+ maxScrollSpeed: "fast"
523
+ })
524
+ }),
525
+ bind(autoscrollElement, {
526
+ type: "scroll",
527
+ listener: handleScroll
528
+ }),
529
+ () => setScrolling(false)
530
+ ]
1114
531
  ].filter(isTruthy).flatMap((x) => x));
1115
532
  }, [
1116
533
  rootRef,
@@ -1118,76 +535,53 @@ var Container = /* @__PURE__ */ forwardRef4(({ className, classNames, children,
1118
535
  data,
1119
536
  autoscrollElement
1120
537
  ]);
1121
- return /* @__PURE__ */ React5.createElement(ContainerContextProvider, {
538
+ return /* @__PURE__ */ React3.createElement(MosaicContainerContextProvider, {
1122
539
  id: eventHandler.id,
1123
540
  eventHandler,
1124
- axis,
541
+ orientation,
1125
542
  state,
1126
543
  dragging: state.type === "active" ? dragging : void 0,
1127
544
  scrolling,
1128
545
  activeLocation,
1129
546
  setActiveLocation
1130
- }, /* @__PURE__ */ React5.createElement(Root2, {
1131
- className: mx5("bs-full", className, classNames),
547
+ }, /* @__PURE__ */ React3.createElement(Root, {
548
+ className: mx3("bs-full", className, classNames),
1132
549
  style: {
1133
- [CONTAINER_PLACEHOLDER_WIDTH]: state.type === "active" && state.bounds ? `${state.bounds.width}px` : "0px",
1134
- [CONTAINER_PLACEHOLDER_HEIGHT]: state.type === "active" && state.bounds ? `${state.bounds.height}px` : "0px"
550
+ [MOSAIC_CONTAINER_PLACEHOLDER_WIDTH]: state.type === "active" && state.bounds ? `${state.bounds.width}px` : "0px",
551
+ [MOSAIC_CONTAINER_PLACEHOLDER_HEIGHT]: state.type === "active" && state.bounds ? `${state.bounds.height}px` : "0px"
1135
552
  },
1136
553
  ...props,
1137
- [`data-${CONTAINER_STATE_ATTR}`]: state.type,
554
+ [`data-${MOSAIC_CONTAINER_STATE_ATTR}`]: state.type,
1138
555
  ref: composedRef
1139
556
  }, children), debug?.());
1140
557
  });
1141
- Container.displayName = "MosaicContainer";
1142
- var useContainerDebug = (debug) => {
1143
- const debugRef = useRef4(null);
1144
- return useMemo3(() => {
1145
- if (!debug) {
1146
- return [
1147
- () => null,
1148
- void 0
1149
- ];
1150
- }
1151
- return [
1152
- ({ classNames }) => /* @__PURE__ */ React5.createElement("div", {
1153
- role: "none",
1154
- className: mx5("overflow-hidden", classNames),
1155
- ref: debugRef
1156
- }),
1157
- () => debugRef.current && /* @__PURE__ */ createPortal(/* @__PURE__ */ React5.createElement(ContainerInfo, null), debugRef.current)
1158
- ];
1159
- }, [
1160
- debug,
1161
- debugRef
1162
- ]);
1163
- };
1164
- var ContainerInfo = /* @__PURE__ */ forwardRef4(({ classNames }, forwardedRef) => {
1165
- const { id, state, activeLocation, scrolling } = useContainerContext(ContainerInfo.displayName);
1166
- const counter2 = useRef4(0);
1167
- return /* @__PURE__ */ React5.createElement(Json, {
1168
- data: {
1169
- id,
1170
- activeLocation,
1171
- scrolling,
1172
- state,
1173
- count: counter2.current++
1174
- },
1175
- classNames: mx5("text-xs", classNames),
1176
- ref: forwardedRef
1177
- });
1178
- });
1179
- ContainerInfo.displayName = "ContainerInfo";
1180
- var [TileContextProvider, useTileContext] = createContext3("MosaicTile");
1181
- var TILE_STATE_ATTR = "mosaic-tile-state";
1182
- var Tile = /* @__PURE__ */ forwardRef4(({ className, classNames, children, asChild, dragHandle, allowedEdges: allowedEdgesProp, location, id, data: dataProp, debug: _ }, forwardedRef) => {
558
+ MosaicContainer.displayName = MOSAIC_CONTAINER_NAME;
559
+
560
+ // src/components/Mosaic/Tile.tsx
561
+ import { combine as combine3 } from "@atlaskit/pragmatic-drag-and-drop/combine";
562
+ import { draggable, dropTargetForElements as dropTargetForElements2 } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
563
+ import { preserveOffsetOnSource } from "@atlaskit/pragmatic-drag-and-drop/element/preserve-offset-on-source";
564
+ import { setCustomNativeDragPreview } from "@atlaskit/pragmatic-drag-and-drop/element/set-custom-native-drag-preview";
565
+ import { attachClosestEdge, extractClosestEdge } from "@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge";
566
+ import { composeRefs } from "@radix-ui/react-compose-refs";
567
+ import { createContext as createContext4 } from "@radix-ui/react-context";
568
+ import { Primitive as Primitive4 } from "@radix-ui/react-primitive";
569
+ import { Slot as Slot4 } from "@radix-ui/react-slot";
570
+ import React4, { forwardRef as forwardRef4, useLayoutEffect, useMemo as useMemo3, useRef as useRef4, useState as useState4 } from "react";
571
+ import { createPortal } from "react-dom";
572
+ import { mx as mx4 } from "@dxos/ui-theme";
573
+ var MOSAIC_TILE_NAME = "Mosaic.Tile";
574
+ var [MosaicTileContextProvider, useMosaicTileContext] = createContext4("MosaicTile");
575
+ var MOSAIC_TILE_STATE_ATTR = "mosaic-tile-state";
576
+ var MosaicTile = /* @__PURE__ */ forwardRef4(({ classNames, className, children, asChild, dragHandle, allowedEdges: allowedEdgesProp, location, id, data: dataProp, debug: _ }, forwardedRef) => {
1183
577
  const rootRef = useRef4(null);
1184
578
  const composedRef = composeRefs(rootRef, forwardedRef);
1185
- const Root2 = asChild ? Slot3 : Primitive2.div;
1186
- const { id: containerId, eventHandler, axis, scrolling, setActiveLocation } = useContainerContext(Tile.displayName);
1187
- const [state, setState] = useState3({
579
+ const Root = asChild ? Slot4 : Primitive4.div;
580
+ const { id: containerId, eventHandler, orientation, scrolling, setActiveLocation } = useMosaicContainerContext(MOSAIC_TILE_NAME);
581
+ const [state, setState] = useState4({
1188
582
  type: "idle"
1189
583
  });
1190
- const allowedEdges = useMemo3(() => allowedEdgesProp || (axis === "vertical" ? [
584
+ const allowedEdges = useMemo3(() => allowedEdgesProp || (orientation === "vertical" ? [
1191
585
  "top",
1192
586
  "bottom"
1193
587
  ] : [
@@ -1195,7 +589,7 @@ var Tile = /* @__PURE__ */ forwardRef4(({ className, classNames, children, asChi
1195
589
  "right"
1196
590
  ]), [
1197
591
  allowedEdgesProp,
1198
- axis
592
+ orientation
1199
593
  ]);
1200
594
  const data = useMemo3(() => ({
1201
595
  type: "tile",
@@ -1224,7 +618,7 @@ var Tile = /* @__PURE__ */ forwardRef4(({ className, classNames, children, asChi
1224
618
  });
1225
619
  }
1226
620
  };
1227
- return combine(
621
+ return combine3(
1228
622
  // Source.
1229
623
  draggable({
1230
624
  element: root,
@@ -1263,7 +657,7 @@ var Tile = /* @__PURE__ */ forwardRef4(({ className, classNames, children, asChi
1263
657
  }
1264
658
  }),
1265
659
  // Target.
1266
- dropTargetForElements({
660
+ dropTargetForElements2({
1267
661
  element: root,
1268
662
  getData: ({ input, element }) => attachClosestEdge(data, {
1269
663
  input,
@@ -1311,152 +705,582 @@ var Tile = /* @__PURE__ */ forwardRef4(({ className, classNames, children, asChi
1311
705
  allowedEdges,
1312
706
  setActiveLocation
1313
707
  ]);
1314
- return /* @__PURE__ */ React5.createElement(TileContextProvider, {
708
+ return /* @__PURE__ */ React4.createElement(MosaicTileContextProvider, {
1315
709
  state
1316
- }, /* @__PURE__ */ React5.createElement(Root2, {
1317
- [`data-${TILE_STATE_ATTR}`]: state.type,
710
+ }, /* @__PURE__ */ React4.createElement(Root, {
711
+ [`data-${MOSAIC_TILE_STATE_ATTR}`]: state.type,
1318
712
  role: "listitem",
1319
- className: mx5("relative", className, classNames),
713
+ className: mx4("relative", className, classNames),
1320
714
  ref: composedRef
1321
- }, children), state.type === "preview" && /* @__PURE__ */ createPortal(/* @__PURE__ */ React5.createElement(Root2, {
715
+ }, children), state.type === "preview" && /* @__PURE__ */ createPortal(/* @__PURE__ */ React4.createElement(Root, {
1322
716
  // NOTE: Use to control appearance while dragging.
1323
- [`data-${TILE_STATE_ATTR}`]: state.type,
717
+ [`data-${MOSAIC_TILE_STATE_ATTR}`]: state.type,
1324
718
  // TODO(burdon): Configure drop animation.
1325
- className: mx5("relative", className, classNames),
719
+ className: mx4("relative", className, classNames),
1326
720
  style: {
1327
721
  width: `${state.rect.width}px`,
1328
722
  height: `${state.rect.height}px`
1329
723
  }
1330
- }, children), state.container));
724
+ }, children), state.container));
725
+ });
726
+ MosaicTile.displayName = MOSAIC_TILE_NAME;
727
+
728
+ // src/components/Mosaic/Placeholder.tsx
729
+ import { dropTargetForElements as dropTargetForElements3 } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
730
+ import { DropIndicator as NativeDropIndicator } from "@atlaskit/pragmatic-drag-and-drop-react-drop-indicator/box";
731
+ import { Primitive as Primitive5 } from "@radix-ui/react-primitive";
732
+ import { Slot as Slot5 } from "@radix-ui/react-slot";
733
+ import React5, { useLayoutEffect as useLayoutEffect2, useMemo as useMemo4, useRef as useRef5 } from "react";
734
+ import { mx as mx5 } from "@dxos/ui-theme";
735
+ var MOSAIC_PLACEHOLDER_NAME = "Mosaic.Placeholder";
736
+ var MOSAIC_PLACEHOLDER_ORIENTATION_ATTR = "mosaic-placeholder-orientation";
737
+ var MOSAIC_PLACEHOLDER_STATE_ATTR = "mosaic-placeholder-state";
738
+ var MosaicPlaceholder = ({ classNames, children, asChild, orientation = "vertical", location }) => {
739
+ const rootRef = useRef5(null);
740
+ const Root = asChild ? Slot5 : Primitive5.div;
741
+ const { id: containerId, eventHandler, scrolling, activeLocation, setActiveLocation } = useMosaicContainerContext(MOSAIC_PLACEHOLDER_NAME);
742
+ const data = useMemo4(() => ({
743
+ type: "placeholder",
744
+ containerId,
745
+ location
746
+ }), [
747
+ containerId,
748
+ location
749
+ ]);
750
+ useLayoutEffect2(() => {
751
+ const root = rootRef.current;
752
+ if (!root || scrolling) {
753
+ return;
754
+ }
755
+ return dropTargetForElements3({
756
+ element: root,
757
+ getData: () => data,
758
+ canDrop: ({ source }) => {
759
+ const data2 = getSourceData(source);
760
+ return data2 && eventHandler.canDrop?.({
761
+ source: data2
762
+ }) || false;
763
+ },
764
+ onDragEnter: () => {
765
+ setActiveLocation(data.location);
766
+ },
767
+ onDragLeave: () => {
768
+ setActiveLocation(void 0);
769
+ },
770
+ onDrop: () => {
771
+ setActiveLocation(void 0);
772
+ }
773
+ });
774
+ }, [
775
+ rootRef,
776
+ data,
777
+ scrolling,
778
+ setActiveLocation
779
+ ]);
780
+ return /* @__PURE__ */ React5.createElement(Root, {
781
+ [`data-${MOSAIC_PLACEHOLDER_ORIENTATION_ATTR}`]: orientation,
782
+ [`data-${MOSAIC_PLACEHOLDER_STATE_ATTR}`]: data.location === activeLocation ? "active" : "idle",
783
+ role: "none",
784
+ className: mx5("relative", classNames),
785
+ ref: rootRef
786
+ }, children);
787
+ };
788
+ MosaicPlaceholder.displayName = MOSAIC_PLACEHOLDER_NAME;
789
+ var DROP_INDICATOR_NAME = "Mosaic.DropIndicator";
790
+ var MosaicDropIndicator = (props) => {
791
+ const { state } = useMosaicTileContext(DROP_INDICATOR_NAME);
792
+ return state.type === "target" && state.closestEdge ? /* @__PURE__ */ React5.createElement(NativeDropIndicator, {
793
+ ...props,
794
+ edge: state.closestEdge
795
+ }) : null;
796
+ };
797
+ MosaicDropIndicator.displayName = DROP_INDICATOR_NAME;
798
+
799
+ // src/components/Mosaic/Stack.tsx
800
+ import { useVirtualizer } from "@tanstack/react-virtual";
801
+ import React8, { Fragment, forwardRef as forwardRef6 } from "react";
802
+ import { invariant } from "@dxos/invariant";
803
+ import { mx as mx8 } from "@dxos/ui-theme";
804
+
805
+ // src/translations.ts
806
+ var translationKey = "@dxos/react-ui-mosaic";
807
+ var translations = [
808
+ {
809
+ "en-US": {
810
+ [translationKey]: {
811
+ "add item label": "Add item",
812
+ "delete menu label": "Delete"
813
+ }
814
+ }
815
+ }
816
+ ];
817
+
818
+ // src/components/Card/styles.ts
819
+ var styles3 = {
820
+ root: "group/card relative min-bs-[--rail-item] is-full card-min-width overflow-hidden",
821
+ border: "bg-cardSurface border border-separator dark:border-subduedSeparator rounded-sm dx-focus-ring-group-y-indicator",
822
+ /**
823
+ * Row grid.
824
+ * NOTE: Rows should provide their own line padding (since they may need to encapsulate buttons, etc.)
825
+ */
826
+ grid_3: "grid grid-cols-[var(--rail-item)_minmax(0,1fr)_var(--rail-item)] gap-x-1",
827
+ grid_2: "grid grid-cols-[var(--rail-item)_minmax(0,1fr)] gap-x-1",
828
+ // TODO(burdon): Address density.
829
+ grid_3_coarse: "grid grid-cols-[var(--l0-avatar-size)_minmax(0,1fr)_var(--rail-item)] gap-x-1",
830
+ poster: "max-bs-[200px]"
831
+ };
832
+
833
+ // src/components/Card/Card.tsx
834
+ import { Slot as Slot6 } from "@radix-ui/react-slot";
835
+ import React7, { createContext as createContext5, forwardRef as forwardRef5, useContext as useContext2 } from "react";
836
+ import { Button, DropdownMenu, Icon, Toolbar, useTranslation } from "@dxos/react-ui";
837
+ import { mx as mx7 } from "@dxos/ui-theme";
838
+
839
+ // src/components/Image/Image.tsx
840
+ import React6, { useCallback as useCallback2, useRef as useRef6, useState as useState5 } from "react";
841
+ import { mx as mx6 } from "@dxos/ui-theme";
842
+ var cache = /* @__PURE__ */ new Map();
843
+ var Image = ({ classNames, src, alt = "", crossOrigin = "anonymous", sampleSize = 64, contrast = 0.9 }) => {
844
+ const [crossOriginState, setCrossOriginState] = useState5(crossOrigin);
845
+ const [dominantColor, setDominantColor] = useState5(void 0);
846
+ const [imageLoaded, setImageLoaded] = useState5(false);
847
+ const canvasRef = useRef6(null);
848
+ const handleImageError = () => {
849
+ setCrossOriginState(void 0);
850
+ };
851
+ const handleImageLoad = useCallback2(({ target }) => {
852
+ const rgb = cache.get(src);
853
+ if (rgb) {
854
+ setDominantColor(rgb);
855
+ setImageLoaded(true);
856
+ return;
857
+ }
858
+ const img = target;
859
+ if (!canvasRef.current) {
860
+ return;
861
+ }
862
+ try {
863
+ const color = extractDominantColor(canvasRef.current, img, {
864
+ sampleSize,
865
+ contrast
866
+ });
867
+ if (color) {
868
+ const rgb2 = `rgb(${color[0]}, ${color[1]}, ${color[2]})`;
869
+ cache.set(src, rgb2);
870
+ setDominantColor(rgb2);
871
+ }
872
+ } catch {
873
+ setCrossOriginState(void 0);
874
+ }
875
+ setImageLoaded(true);
876
+ }, [
877
+ sampleSize,
878
+ contrast,
879
+ src
880
+ ]);
881
+ return /* @__PURE__ */ React6.createElement("div", {
882
+ className: mx6(`relative flex is-full justify-center overflow-hidden transition-all duration-700`, classNames),
883
+ style: {
884
+ backgroundColor: dominantColor
885
+ }
886
+ }, /* @__PURE__ */ React6.createElement("canvas", {
887
+ ref: canvasRef,
888
+ style: {
889
+ display: "none"
890
+ },
891
+ "aria-hidden": "true"
892
+ }), /* @__PURE__ */ React6.createElement("div", {
893
+ className: "absolute inset-0 pointer-events-none",
894
+ style: {
895
+ background: dominantColor ? `radial-gradient(circle at center, transparent 30%, ${dominantColor} 100%)` : void 0,
896
+ transition: "opacity 0.7s ease-in-out",
897
+ opacity: 0.5
898
+ }
899
+ }), /* @__PURE__ */ React6.createElement("img", {
900
+ src,
901
+ alt,
902
+ crossOrigin: crossOriginState,
903
+ onError: handleImageError,
904
+ onLoad: handleImageLoad,
905
+ className: mx6("z-10 object-contain transition-opacity duration-500", classNames),
906
+ style: {
907
+ opacity: imageLoaded ? 1 : 0
908
+ }
909
+ }));
910
+ };
911
+ var extractDominantColor = (canvas, img, { sampleSize = 64, contrast = 0.95 }) => {
912
+ const ctx = canvas.getContext("2d");
913
+ if (!ctx) {
914
+ return null;
915
+ }
916
+ canvas.width = sampleSize;
917
+ canvas.height = sampleSize;
918
+ ctx.drawImage(img, 0, 0, sampleSize, sampleSize);
919
+ const imageData = ctx.getImageData(0, 0, sampleSize, sampleSize);
920
+ const pixels = imageData.data;
921
+ if (isTransparent(pixels, sampleSize)) {
922
+ return null;
923
+ }
924
+ let r = 0;
925
+ let g = 0;
926
+ let b = 0;
927
+ let totalWeight = 0;
928
+ const cornerSize = Math.floor(sampleSize * 0.125);
929
+ for (let y = 0; y < sampleSize; y++) {
930
+ for (let x = 0; x < sampleSize; x++) {
931
+ const isInTopLeft = x < cornerSize && y < cornerSize;
932
+ const isInTopRight = x >= sampleSize - cornerSize && y < cornerSize;
933
+ const isInBottomLeft = x < cornerSize && y >= sampleSize - cornerSize;
934
+ const isInBottomRight = x >= sampleSize - cornerSize && y >= sampleSize - cornerSize;
935
+ if (!isInTopLeft && !isInTopRight && !isInBottomLeft && !isInBottomRight) {
936
+ continue;
937
+ }
938
+ const i = (y * sampleSize + x) * 4;
939
+ const red = pixels[i];
940
+ const green = pixels[i + 1];
941
+ const blue = pixels[i + 2];
942
+ const alpha = pixels[i + 3];
943
+ if (alpha === 0) continue;
944
+ const max = Math.max(red, green, blue);
945
+ const min = Math.min(red, green, blue);
946
+ const saturation = max === 0 ? 0 : (max - min) / max;
947
+ const weight = 1 + saturation * 2;
948
+ r += red * weight;
949
+ g += green * weight;
950
+ b += blue * weight;
951
+ totalWeight += weight;
952
+ }
953
+ }
954
+ if (totalWeight > 0) {
955
+ r = Math.round(Math.round(r / totalWeight) * contrast);
956
+ g = Math.round(Math.round(g / totalWeight) * contrast);
957
+ b = Math.round(Math.round(b / totalWeight) * contrast);
958
+ return [
959
+ r,
960
+ g,
961
+ b
962
+ ];
963
+ }
964
+ return null;
965
+ };
966
+ var isTransparent = (pixels, sampleSize, threshold = 0.5) => {
967
+ let edgeTransparentPixels = 0;
968
+ const edgePixels = sampleSize * 4 - 4;
969
+ for (let x = 0; x < sampleSize; x++) {
970
+ const topIndex = x * 4;
971
+ if (pixels[topIndex + 3] === 0) edgeTransparentPixels++;
972
+ const bottomIndex = ((sampleSize - 1) * sampleSize + x) * 4;
973
+ if (pixels[bottomIndex + 3] === 0) edgeTransparentPixels++;
974
+ }
975
+ for (let y = 1; y < sampleSize - 1; y++) {
976
+ const leftIndex = y * sampleSize * 4;
977
+ if (pixels[leftIndex + 3] === 0) edgeTransparentPixels++;
978
+ const rightIndex = (y * sampleSize + sampleSize - 1) * 4;
979
+ if (pixels[rightIndex + 3] === 0) edgeTransparentPixels++;
980
+ }
981
+ return edgeTransparentPixels / edgePixels > threshold;
982
+ };
983
+
984
+ // src/components/Card/Card.tsx
985
+ var CardContext = /* @__PURE__ */ createContext5({});
986
+ var CardRoot = /* @__PURE__ */ forwardRef5(({ children, classNames, className, id, asChild, role = "group", border = true, fullWidth, ...props }, forwardedRef) => {
987
+ const Root = asChild ? Slot6 : "div";
988
+ return /* @__PURE__ */ React7.createElement(Root, {
989
+ ...id && {
990
+ "data-object-id": id
991
+ },
992
+ ...props,
993
+ role,
994
+ className: mx7(styles3.root, border && styles3.border, fullWidth && "!max-is-none", className, classNames),
995
+ ref: forwardedRef
996
+ }, children);
1331
997
  });
1332
- Tile.displayName = "MosaicTile";
1333
- var PLACEHOLDER_AXIS_ATTR = "mosaic-placeholder-axis";
1334
- var PLACEHOLDER_STATE_ATTR = "mosaic-placeholder-state";
1335
- var Placeholder = ({ classNames, children, asChild, axis = "vertical", location }) => {
1336
- const rootRef = useRef4(null);
1337
- const Root2 = asChild ? Slot3 : Primitive2.div;
1338
- const { id: containerId, eventHandler, scrolling, activeLocation, setActiveLocation } = useContainerContext(Placeholder.displayName);
1339
- const data = useMemo3(() => ({
1340
- type: "placeholder",
1341
- containerId,
1342
- location
1343
- }), [
1344
- containerId,
1345
- location
1346
- ]);
1347
- useLayoutEffect(() => {
1348
- const root = rootRef.current;
1349
- if (!root || scrolling) {
1350
- return;
998
+ var CardToolbar = /* @__PURE__ */ forwardRef5(({ children, classNames, density = "fine", ...props }, forwardedRef) => {
999
+ return /* @__PURE__ */ React7.createElement(Toolbar.Root, {
1000
+ ...props,
1001
+ classNames: [
1002
+ "density-fine bg-transparent",
1003
+ density === "fine" ? styles3.grid_3 : styles3.grid_3_coarse,
1004
+ classNames
1005
+ ],
1006
+ ref: forwardedRef
1007
+ }, children);
1008
+ });
1009
+ var CardToolbarIconButton = Toolbar.IconButton;
1010
+ var CardToolbarSeparator = Toolbar.Separator;
1011
+ var CardDragHandle = /* @__PURE__ */ forwardRef5((_, forwardedRef) => {
1012
+ const { t } = useTranslation(translationKey);
1013
+ return /* @__PURE__ */ React7.createElement(Toolbar.IconButton, {
1014
+ "data-testid": "card-drag-handle",
1015
+ noTooltip: true,
1016
+ iconOnly: true,
1017
+ icon: "ph--dots-six-vertical--regular",
1018
+ variant: "ghost",
1019
+ label: t("drag handle label"),
1020
+ classNames: "cursor-pointer",
1021
+ size: 5,
1022
+ disabled: !forwardedRef,
1023
+ ref: forwardedRef
1024
+ });
1025
+ });
1026
+ var CardClose = /* @__PURE__ */ forwardRef5(({ onClick }, forwardedRef) => {
1027
+ const { t } = useTranslation(translationKey);
1028
+ return /* @__PURE__ */ React7.createElement(Toolbar.IconButton, {
1029
+ iconOnly: true,
1030
+ icon: "ph--x--regular",
1031
+ variant: "ghost",
1032
+ label: t("card close label"),
1033
+ classNames: "cursor-pointer",
1034
+ size: 5,
1035
+ onClick,
1036
+ ref: forwardedRef
1037
+ });
1038
+ });
1039
+ var CardMenu = ({ context, items }) => {
1040
+ const { t } = useTranslation(translationKey);
1041
+ const { menuItems } = useContext2(CardContext) ?? {};
1042
+ const combinedItems = [
1043
+ ...items ?? [],
1044
+ ...menuItems ?? []
1045
+ ];
1046
+ return /* @__PURE__ */ React7.createElement(DropdownMenu.Root, null, /* @__PURE__ */ React7.createElement(DropdownMenu.Trigger, {
1047
+ disabled: !combinedItems.length,
1048
+ asChild: true
1049
+ }, /* @__PURE__ */ React7.createElement(Card.ToolbarIconButton, {
1050
+ iconOnly: true,
1051
+ variant: "ghost",
1052
+ icon: "ph--dots-three-vertical--regular",
1053
+ label: t("action menu label")
1054
+ })), (combinedItems?.length ?? 0) > 0 && /* @__PURE__ */ React7.createElement(DropdownMenu.Portal, null, /* @__PURE__ */ React7.createElement(DropdownMenu.Content, null, /* @__PURE__ */ React7.createElement(DropdownMenu.Viewport, null, combinedItems?.map(({ label, onClick: onSelect }, i) => /* @__PURE__ */ React7.createElement(DropdownMenu.Item, {
1055
+ key: i,
1056
+ onSelect: () => onSelect(context)
1057
+ }, label))), /* @__PURE__ */ React7.createElement(DropdownMenu.Arrow, null))));
1058
+ };
1059
+ var CardTitle = /* @__PURE__ */ forwardRef5(({ children, classNames, className, asChild, role = "heading", ...props }, forwardedRef) => {
1060
+ const Root = asChild ? Slot6 : "div";
1061
+ return /* @__PURE__ */ React7.createElement(Root, {
1062
+ ...props,
1063
+ role,
1064
+ className: mx7("grow truncate", classNames, className),
1065
+ ref: forwardedRef
1066
+ }, children);
1067
+ });
1068
+ var CardContent = /* @__PURE__ */ forwardRef5(({ children, ...props }, forwardedRef) => {
1069
+ return /* @__PURE__ */ React7.createElement("div", {
1070
+ role: "none",
1071
+ className: "contents [&>:last-child]:pbe-1",
1072
+ ...props,
1073
+ ref: forwardedRef
1074
+ }, children);
1075
+ });
1076
+ var CardRow = /* @__PURE__ */ forwardRef5(({ children, classNames, className, role = "none", icon, ...props }, forwardedRef) => {
1077
+ return /* @__PURE__ */ React7.createElement("div", {
1078
+ ...props,
1079
+ role,
1080
+ className: mx7(styles3.grid_2, "pli-1", classNames, className),
1081
+ ref: forwardedRef
1082
+ }, icon && /* @__PURE__ */ React7.createElement(CardIcon, {
1083
+ classNames: "text-subdued",
1084
+ icon
1085
+ }) || /* @__PURE__ */ React7.createElement("div", null), children);
1086
+ });
1087
+ var CardHeading = /* @__PURE__ */ forwardRef5(({ children, classNames, className, asChild, role = "heading", variant = "default", ...props }, forwardedRef) => {
1088
+ const Root = asChild ? Slot6 : "div";
1089
+ const variantClassNames = {
1090
+ default: "plb-1",
1091
+ subtitle: "plb-2 text-xs text-description font-medium uppercase"
1092
+ };
1093
+ return /* @__PURE__ */ React7.createElement(Root, {
1094
+ ...props,
1095
+ role,
1096
+ className: mx7(variantClassNames[variant], classNames, className),
1097
+ ref: forwardedRef
1098
+ }, children);
1099
+ });
1100
+ var CardText = /* @__PURE__ */ forwardRef5(({ children, classNames, className, asChild, role = "none", truncate, variant = "default", ...props }, forwardedRef) => {
1101
+ const Root = asChild ? Slot6 : "div";
1102
+ const variantClassNames = {
1103
+ default: {
1104
+ root: "plb-1"
1105
+ },
1106
+ description: {
1107
+ root: "plb-1.5",
1108
+ span: "text-sm text-description line-clamp-3"
1351
1109
  }
1352
- return dropTargetForElements({
1353
- element: root,
1354
- getData: () => data,
1355
- canDrop: ({ source }) => {
1356
- const data2 = getSourceData(source);
1357
- return data2 && eventHandler.canDrop?.({
1358
- source: data2
1359
- }) || false;
1360
- },
1361
- onDragEnter: () => {
1362
- setActiveLocation(data.location);
1363
- },
1364
- onDragLeave: () => {
1365
- setActiveLocation(void 0);
1366
- },
1367
- onDrop: () => {
1368
- setActiveLocation(void 0);
1369
- }
1370
- });
1371
- }, [
1372
- rootRef,
1373
- data,
1374
- scrolling,
1375
- setActiveLocation
1376
- ]);
1377
- return /* @__PURE__ */ React5.createElement(Root2, {
1378
- [`data-${PLACEHOLDER_AXIS_ATTR}`]: axis,
1379
- [`data-${PLACEHOLDER_STATE_ATTR}`]: data.location === activeLocation ? "active" : "idle",
1110
+ };
1111
+ return /* @__PURE__ */ React7.createElement(Root, {
1112
+ ...props,
1113
+ role,
1114
+ className: mx7("flex overflow-hidden", variantClassNames[variant].root, classNames, className),
1115
+ ref: forwardedRef
1116
+ }, /* @__PURE__ */ React7.createElement("span", {
1117
+ className: mx7(variantClassNames[variant].span, truncate && "truncate")
1118
+ }, children));
1119
+ });
1120
+ var CardPoster = (props) => {
1121
+ const aspect = props.aspect === "auto" ? "aspect-auto" : "aspect-video";
1122
+ if (props.image) {
1123
+ return /* @__PURE__ */ React7.createElement("div", {
1124
+ role: "none",
1125
+ className: "mbe-1"
1126
+ }, /* @__PURE__ */ React7.createElement(Image, {
1127
+ classNames: [
1128
+ styles3.poster,
1129
+ aspect,
1130
+ props.classNames
1131
+ ],
1132
+ src: props.image,
1133
+ alt: props.alt
1134
+ }));
1135
+ }
1136
+ if (props.icon) {
1137
+ return /* @__PURE__ */ React7.createElement("div", {
1138
+ role: "image",
1139
+ className: mx7("grid place-items-center bg-inputSurface text-subdued", styles3.poster, aspect, props.classNames),
1140
+ "aria-label": props.alt
1141
+ }, /* @__PURE__ */ React7.createElement(Icon, {
1142
+ icon: props.icon,
1143
+ size: 10
1144
+ }));
1145
+ }
1146
+ };
1147
+ var CardAction = ({ icon, actionIcon = "ph--arrow-right--regular", label, onClick }) => {
1148
+ return /* @__PURE__ */ React7.createElement("div", {
1380
1149
  role: "none",
1381
- className: mx5("relative", classNames),
1382
- ref: rootRef
1150
+ className: "is-full pli-1"
1151
+ }, /* @__PURE__ */ React7.createElement(Button, {
1152
+ variant: "ghost",
1153
+ classNames: mx7(styles3.grid_3, "!p-0 is-full text-start overflow-hidden"),
1154
+ onClick
1155
+ }, icon ? /* @__PURE__ */ React7.createElement(CardIcon, {
1156
+ classNames: "text-subdued",
1157
+ icon
1158
+ }) : /* @__PURE__ */ React7.createElement("div", null), /* @__PURE__ */ React7.createElement("span", {
1159
+ className: mx7("min-is-0 flex-1 truncate", !actionIcon && "col-span-2")
1160
+ }, label), actionIcon && /* @__PURE__ */ React7.createElement(CardIcon, {
1161
+ icon: actionIcon
1162
+ })));
1163
+ };
1164
+ var CardLink = ({ label, href }) => {
1165
+ return /* @__PURE__ */ React7.createElement("div", {
1166
+ role: "none",
1167
+ className: "is-full pli-1"
1168
+ }, /* @__PURE__ */ React7.createElement("a", {
1169
+ className: mx7(styles3.grid_3, "group !p-0 dx-button dx-focus-ring !min-bs-1"),
1170
+ "data-variant": "ghost",
1171
+ href,
1172
+ target: "_blank",
1173
+ rel: "noreferrer"
1174
+ }, /* @__PURE__ */ React7.createElement(CardIcon, {
1175
+ classNames: "text-subdued",
1176
+ icon: "ph--link--regular"
1177
+ }), /* @__PURE__ */ React7.createElement("span", {
1178
+ className: mx7("min-is-0 flex-1 truncate")
1179
+ }, label), /* @__PURE__ */ React7.createElement(CardIcon, {
1180
+ classNames: "invisible group-hover:visible",
1181
+ icon: "ph--arrow-square-out--regular"
1182
+ })));
1183
+ };
1184
+ var CardIconBlock = ({ classNames, children, role = "none", ...props }) => {
1185
+ return /* @__PURE__ */ React7.createElement("div", {
1186
+ ...props,
1187
+ role,
1188
+ className: mx7("grid bs-[var(--rail-item)] is-[var(--rail-item)] place-items-center", classNames)
1383
1189
  }, children);
1384
1190
  };
1385
- Placeholder.displayName = "MosaicPlaceholder";
1386
- var DropIndicator = (props) => {
1387
- const { state } = useTileContext(DropIndicator.displayName);
1388
- return state.type === "target" && state.closestEdge ? /* @__PURE__ */ React5.createElement(NativeDropIndicator, {
1191
+ var CardIcon = ({ toolbar, ...props }) => {
1192
+ return /* @__PURE__ */ React7.createElement(CardIconBlock, null, /* @__PURE__ */ React7.createElement(Icon, {
1389
1193
  ...props,
1390
- edge: state.closestEdge
1391
- }) : null;
1194
+ size: toolbar ? 5 : 4
1195
+ }));
1392
1196
  };
1393
- DropIndicator.displayName = "MosaicDropIndicator";
1394
- var Mosaic = {
1395
- Root,
1396
- Container,
1397
- ContainerInfo,
1398
- Tile,
1399
- Placeholder,
1400
- DropIndicator,
1401
- // TODO(burdon): Move out of Mosaic namespace?
1402
- Viewport: Scrollable,
1403
- Stack,
1404
- VirtualStack
1197
+ var Card = {
1198
+ Context: CardContext,
1199
+ Root: CardRoot,
1200
+ // Toolbar
1201
+ Toolbar: CardToolbar,
1202
+ ToolbarIconButton: CardToolbarIconButton,
1203
+ ToolbarSeparator: CardToolbarSeparator,
1204
+ DragHandle: CardDragHandle,
1205
+ Title: CardTitle,
1206
+ Close: CardClose,
1207
+ Menu: CardMenu,
1208
+ Icon: CardIcon,
1209
+ IconBlock: CardIconBlock,
1210
+ // Content
1211
+ Content: CardContent,
1212
+ Row: CardRow,
1213
+ Heading: CardHeading,
1214
+ Text: CardText,
1215
+ Poster: CardPoster,
1216
+ Action: CardAction,
1217
+ Link: CardLink
1405
1218
  };
1406
1219
 
1407
- // src/components/Stack/Stack.tsx
1408
- var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/react-ui-mosaic/src/components/Stack/Stack.tsx";
1409
- var StackInner = /* @__PURE__ */ forwardRef5(({ className, classNames, role = "list", axis = "vertical", draggable: draggable2 = true, items, getId, Tile: Tile2, debug, ...props }, forwardedRef) => {
1410
- invariant(Tile2, void 0, {
1220
+ // src/components/Mosaic/Stack.tsx
1221
+ var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/react-ui-mosaic/src/components/Mosaic/Stack.tsx";
1222
+ var MOSAIC_STACK_NAME = "MosaicStack";
1223
+ var MosaicStackInner = /* @__PURE__ */ forwardRef6(({ classNames, className, role = "list", orientation: orientationProp = "vertical", draggable: draggable2 = true, items, getId, Tile, debug, ...props }, forwardedRef) => {
1224
+ invariant(Tile, void 0, {
1411
1225
  F: __dxlog_file2,
1412
- L: 44,
1226
+ L: 75,
1413
1227
  S: void 0,
1414
1228
  A: [
1415
1229
  "Tile",
1416
1230
  ""
1417
1231
  ]
1418
1232
  });
1419
- const { id, dragging } = useContainerContext(StackInner.displayName);
1233
+ const { id, orientation = orientationProp, dragging } = useMosaicContainerContext(MOSAIC_STACK_NAME);
1420
1234
  const visibleItems = useVisibleItems({
1421
1235
  id,
1422
1236
  items,
1423
1237
  dragging: dragging?.source.data,
1424
1238
  getId
1425
1239
  });
1426
- return /* @__PURE__ */ React6.createElement("div", {
1240
+ invariant(orientation === "vertical" || orientation === "horizontal", `Invalid orientation: ${orientation}`, {
1241
+ F: __dxlog_file2,
1242
+ L: 78,
1243
+ S: void 0,
1244
+ A: [
1245
+ "orientation === 'vertical' || orientation === 'horizontal'",
1246
+ "`Invalid orientation: ${orientation}`"
1247
+ ]
1248
+ });
1249
+ return /* @__PURE__ */ React8.createElement("div", {
1427
1250
  ...props,
1428
1251
  role,
1429
- className: mx6("flex", axis === "horizontal" && "bs-full [&>*]:shrink-0", axis === "vertical" && "flex-col", classNames, className),
1252
+ className: mx8("flex", orientation === "horizontal" && "bs-full [&>*]:shrink-0", orientation === "vertical" && "flex-col", classNames, className),
1430
1253
  ref: forwardedRef
1431
- }, /* @__PURE__ */ React6.createElement(Placeholder2, {
1432
- axis,
1254
+ }, /* @__PURE__ */ React8.createElement(InternalPlaceholder, {
1255
+ orientation,
1433
1256
  location: 0.5
1434
- }), visibleItems?.map((item, index) => /* @__PURE__ */ React6.createElement(Fragment, {
1257
+ }), visibleItems?.map((item, index) => /* @__PURE__ */ React8.createElement(Fragment, {
1435
1258
  key: getId(item)
1436
- }, /* @__PURE__ */ React6.createElement(Tile2, {
1259
+ }, /* @__PURE__ */ React8.createElement(Tile, {
1437
1260
  id: getId(item),
1438
1261
  data: item,
1439
1262
  location: index + 1,
1440
1263
  draggable: draggable2,
1441
1264
  debug
1442
- }), /* @__PURE__ */ React6.createElement(Placeholder2, {
1443
- axis,
1265
+ }), /* @__PURE__ */ React8.createElement(InternalPlaceholder, {
1266
+ orientation,
1444
1267
  location: index + 1.5
1445
1268
  }))));
1446
1269
  });
1447
- StackInner.displayName = "Stack";
1448
- var Stack = StackInner;
1449
- var VirtualStackInner = /* @__PURE__ */ forwardRef5(({ className, classNames, role = "list", axis = "vertical", items, getId, Tile: Tile2, estimateSize, getScrollElement, overscan = 8, onChange, debug, ...props }, forwardedRef) => {
1450
- invariant(Tile2, void 0, {
1270
+ MosaicStackInner.displayName = MOSAIC_STACK_NAME;
1271
+ var MosaicStack = MosaicStackInner;
1272
+ var MOSAIC_VIRTUAL_STACK_NAME = "MosaicVirtualStack";
1273
+ var MosaicVirtualStackInner = /* @__PURE__ */ forwardRef6(({ classNames, className, role = "list", orientation = "vertical", items, getId, Tile, estimateSize, getScrollElement, overscan = 8, onChange, debug, ...props }, forwardedRef) => {
1274
+ invariant(Tile, void 0, {
1451
1275
  F: __dxlog_file2,
1452
- L: 106,
1276
+ L: 142,
1453
1277
  S: void 0,
1454
1278
  A: [
1455
1279
  "Tile",
1456
1280
  ""
1457
1281
  ]
1458
1282
  });
1459
- const { id, dragging } = useContainerContext(VirtualStackInner.displayName);
1283
+ const { id, dragging } = useMosaicContainerContext(MOSAIC_VIRTUAL_STACK_NAME);
1460
1284
  const visibleItems = useVisibleItems({
1461
1285
  id,
1462
1286
  items,
@@ -1471,13 +1295,13 @@ var VirtualStackInner = /* @__PURE__ */ forwardRef5(({ className, classNames, ro
1471
1295
  onChange
1472
1296
  });
1473
1297
  const virtualItems = virtualizer.getVirtualItems();
1474
- return /* @__PURE__ */ React6.createElement("div", {
1298
+ return /* @__PURE__ */ React8.createElement("div", {
1475
1299
  ...props,
1476
1300
  role,
1477
- className: mx6("flex", axis === "horizontal" && "bs-full [&>*]:shrink-0", axis === "vertical" && "flex-col", classNames, className),
1301
+ className: mx8("flex", orientation === "horizontal" && "bs-full [&>*]:shrink-0", orientation === "vertical" && "flex-col", classNames, className),
1478
1302
  style: {
1479
1303
  position: "relative",
1480
- ...axis === "vertical" ? {
1304
+ ...orientation === "vertical" ? {
1481
1305
  width: "100%",
1482
1306
  height: virtualizer.getTotalSize()
1483
1307
  } : {
@@ -1488,14 +1312,14 @@ var VirtualStackInner = /* @__PURE__ */ forwardRef5(({ className, classNames, ro
1488
1312
  ref: forwardedRef
1489
1313
  }, virtualItems.map((virtualItem) => {
1490
1314
  const data = visibleItems[Math.floor(virtualItem.index / 2)];
1491
- return /* @__PURE__ */ React6.createElement("div", {
1315
+ return /* @__PURE__ */ React8.createElement("div", {
1492
1316
  key: virtualItem.key,
1493
1317
  "data-index": virtualItem.index,
1494
1318
  style: {
1495
1319
  position: "absolute",
1496
1320
  top: 0,
1497
1321
  left: 0,
1498
- ...axis === "vertical" ? {
1322
+ ...orientation === "vertical" ? {
1499
1323
  width: "100%",
1500
1324
  transform: `translateY(${virtualItem.start}px)`
1501
1325
  } : {
@@ -1504,10 +1328,10 @@ var VirtualStackInner = /* @__PURE__ */ forwardRef5(({ className, classNames, ro
1504
1328
  }
1505
1329
  },
1506
1330
  ref: virtualizer.measureElement
1507
- }, virtualItem.index % 2 === 0 ? /* @__PURE__ */ React6.createElement(Placeholder2, {
1508
- axis,
1331
+ }, virtualItem.index % 2 === 0 ? /* @__PURE__ */ React8.createElement(InternalPlaceholder, {
1332
+ orientation,
1509
1333
  location: Math.floor(virtualItem.index / 2) + 0.5
1510
- }) : /* @__PURE__ */ React6.createElement(Tile2, {
1334
+ }) : /* @__PURE__ */ React8.createElement(Tile, {
1511
1335
  id: getId(data),
1512
1336
  data,
1513
1337
  location: Math.floor(virtualItem.index / 2) + 1,
@@ -1515,33 +1339,43 @@ var VirtualStackInner = /* @__PURE__ */ forwardRef5(({ className, classNames, ro
1515
1339
  }));
1516
1340
  }));
1517
1341
  });
1518
- VirtualStackInner.displayName = "VirtualStackInner";
1519
- var VirtualStack = VirtualStackInner;
1520
- var Placeholder2 = (props) => {
1521
- return /* @__PURE__ */ React6.createElement(Mosaic.Placeholder, {
1342
+ MosaicVirtualStackInner.displayName = MOSAIC_VIRTUAL_STACK_NAME;
1343
+ var MosaicVirtualStack = MosaicVirtualStackInner;
1344
+ var InternalPlaceholder = (props) => {
1345
+ return /* @__PURE__ */ React8.createElement(MosaicPlaceholder, {
1522
1346
  ...props,
1523
- classNames: styles3.placeholder.root
1524
- }, /* @__PURE__ */ React6.createElement("div", {
1525
- className: mx6("flex bs-full bg-baseSurface border border-dashed border-separator rounded-sm", styles3.placeholder.content)
1347
+ classNames: styles2.placeholder.root
1348
+ }, /* @__PURE__ */ React8.createElement("div", {
1349
+ className: mx8("flex bs-full bg-baseSurface border border-dashed border-separator rounded-sm", styles2.placeholder.content)
1526
1350
  }));
1527
1351
  };
1528
- Placeholder2.displayName = "Placeholder";
1352
+ InternalPlaceholder.displayName = "InternalPlaceholder";
1353
+
1354
+ // src/components/Mosaic/Mosaic.tsx
1355
+ var Mosaic = {
1356
+ Root: MosaicRoot,
1357
+ Container: MosaicContainer,
1358
+ Tile: MosaicTile,
1359
+ Placeholder: MosaicPlaceholder,
1360
+ DropIndicator: MosaicDropIndicator,
1361
+ Stack: MosaicStack,
1362
+ VirtualStack: MosaicVirtualStack
1363
+ };
1529
1364
 
1530
1365
  export {
1366
+ useVisibleItems,
1531
1367
  styles,
1532
- Image,
1533
- Card,
1534
- styles2,
1535
1368
  useFocus,
1536
1369
  Focus,
1370
+ styles2,
1371
+ getSourceData,
1372
+ useMosaicRootContext,
1373
+ useMosaicContainerContext,
1374
+ useMosaicTileContext,
1375
+ Mosaic,
1376
+ translationKey,
1537
1377
  styles3,
1538
- dropHandler,
1539
- Stack,
1540
- VirtualStack,
1541
- useRootContext,
1542
- useContainerContext,
1543
- useContainerDebug,
1544
- useTileContext,
1545
- Mosaic
1378
+ Image,
1379
+ Card
1546
1380
  };
1547
- //# sourceMappingURL=chunk-FS5LRPMY.mjs.map
1381
+ //# sourceMappingURL=chunk-XNANTBOP.mjs.map