@dxos/react-ui-stack 0.8.3-staging.0fa589b → 0.8.4-main.1068cf700f

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 (111) hide show
  1. package/dist/lib/browser/index.mjs +767 -1016
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/browser/{testing → playwright}/index.mjs +5 -1
  5. package/dist/lib/browser/{testing → playwright}/index.mjs.map +3 -3
  6. package/dist/lib/node-esm/index.mjs +767 -1016
  7. package/dist/lib/node-esm/index.mjs.map +4 -4
  8. package/dist/lib/node-esm/meta.json +1 -1
  9. package/dist/lib/node-esm/{testing → playwright}/index.mjs +5 -1
  10. package/dist/lib/node-esm/{testing → playwright}/index.mjs.map +3 -3
  11. package/dist/types/src/{exemplars → components}/CardStack/CardStack.d.ts +24 -11
  12. package/dist/types/src/components/CardStack/CardStack.d.ts.map +1 -0
  13. package/dist/types/src/components/CardStack/CardStack.stories.d.ts +15 -0
  14. package/dist/types/src/components/CardStack/CardStack.stories.d.ts.map +1 -0
  15. package/dist/types/src/{exemplars → components}/CardStack/CardStackDragPreview.d.ts +4 -1
  16. package/dist/types/src/components/CardStack/CardStackDragPreview.d.ts.map +1 -0
  17. package/dist/types/src/components/CardStack/index.d.ts.map +1 -0
  18. package/dist/types/src/components/Stack/Stack.d.ts +15 -7
  19. package/dist/types/src/components/Stack/Stack.d.ts.map +1 -1
  20. package/dist/types/src/components/Stack/Stack.stories.d.ts +12 -3
  21. package/dist/types/src/components/Stack/Stack.stories.d.ts.map +1 -1
  22. package/dist/types/src/components/StackContext.d.ts +2 -1
  23. package/dist/types/src/components/StackContext.d.ts.map +1 -1
  24. package/dist/types/src/components/StackItem/StackItem.d.ts +9 -12
  25. package/dist/types/src/components/StackItem/StackItem.d.ts.map +1 -1
  26. package/dist/types/src/components/StackItem/StackItem.stories.d.ts +13 -5
  27. package/dist/types/src/components/StackItem/StackItem.stories.d.ts.map +1 -1
  28. package/dist/types/src/components/StackItem/StackItemContent.d.ts +4 -37
  29. package/dist/types/src/components/StackItem/StackItemContent.d.ts.map +1 -1
  30. package/dist/types/src/components/StackItem/StackItemHeading.d.ts +1 -1
  31. package/dist/types/src/components/StackItem/StackItemHeading.d.ts.map +1 -1
  32. package/dist/types/src/components/StackItem/StackItemResizeHandle.d.ts.map +1 -1
  33. package/dist/types/src/components/StackItem/StackItemSigil.d.ts +2 -2
  34. package/dist/types/src/components/StackItem/StackItemSigil.d.ts.map +1 -1
  35. package/dist/types/src/components/deprecated/LayoutControls.d.ts +3 -0
  36. package/dist/types/src/components/deprecated/LayoutControls.d.ts.map +1 -1
  37. package/dist/types/src/components/index.d.ts +2 -1
  38. package/dist/types/src/components/index.d.ts.map +1 -1
  39. package/dist/types/src/components/{defs.d.ts → types.d.ts} +1 -1
  40. package/dist/types/src/components/types.d.ts.map +1 -0
  41. package/dist/types/src/hooks/useStackDropForElements.d.ts +9 -7
  42. package/dist/types/src/hooks/useStackDropForElements.d.ts.map +1 -1
  43. package/dist/types/src/index.d.ts +1 -2
  44. package/dist/types/src/index.d.ts.map +1 -1
  45. package/dist/types/src/playwright/index.d.ts.map +1 -0
  46. package/dist/types/src/playwright/playwright.config.d.ts +3 -0
  47. package/dist/types/src/playwright/playwright.config.d.ts.map +1 -0
  48. package/dist/types/src/playwright/stack-manager.d.ts.map +1 -0
  49. package/dist/types/src/translations.d.ts +13 -14
  50. package/dist/types/src/translations.d.ts.map +1 -1
  51. package/dist/types/tsconfig.tsbuildinfo +1 -1
  52. package/package.json +48 -41
  53. package/src/components/CardStack/CardStack.stories.tsx +173 -0
  54. package/src/{exemplars → components}/CardStack/CardStack.tsx +115 -39
  55. package/src/{exemplars → components}/CardStack/CardStackDragPreview.tsx +12 -9
  56. package/src/components/Stack/Stack.stories.tsx +9 -10
  57. package/src/components/Stack/Stack.tsx +225 -26
  58. package/src/components/StackContext.tsx +2 -1
  59. package/src/components/StackItem/StackItem.stories.tsx +21 -17
  60. package/src/components/StackItem/StackItem.tsx +49 -29
  61. package/src/components/StackItem/StackItemContent.tsx +23 -42
  62. package/src/components/StackItem/StackItemHeading.tsx +5 -9
  63. package/src/components/StackItem/StackItemResizeHandle.tsx +2 -1
  64. package/src/components/StackItem/StackItemSigil.tsx +5 -4
  65. package/src/components/deprecated/LayoutControls.tsx +3 -0
  66. package/src/components/index.ts +2 -1
  67. package/src/hooks/useStackDropForElements.ts +59 -42
  68. package/src/index.ts +1 -5
  69. package/src/{testing → playwright}/index.ts +1 -1
  70. package/src/playwright/playwright.config.ts +17 -0
  71. package/src/playwright/smoke.spec.ts +7 -5
  72. package/src/translations.ts +5 -3
  73. package/dist/lib/node/index.cjs +0 -1220
  74. package/dist/lib/node/index.cjs.map +0 -7
  75. package/dist/lib/node/meta.json +0 -1
  76. package/dist/lib/node/testing/index.cjs +0 -81
  77. package/dist/lib/node/testing/index.cjs.map +0 -7
  78. package/dist/types/src/components/defs.d.ts.map +0 -1
  79. package/dist/types/src/exemplars/Card/Card.d.ts +0 -62
  80. package/dist/types/src/exemplars/Card/Card.d.ts.map +0 -1
  81. package/dist/types/src/exemplars/Card/Card.stories-todo.d.ts +0 -1
  82. package/dist/types/src/exemplars/Card/Card.stories-todo.d.ts.map +0 -1
  83. package/dist/types/src/exemplars/Card/CardDragPreview.d.ts +0 -6
  84. package/dist/types/src/exemplars/Card/CardDragPreview.d.ts.map +0 -1
  85. package/dist/types/src/exemplars/Card/fragments.d.ts +0 -13
  86. package/dist/types/src/exemplars/Card/fragments.d.ts.map +0 -1
  87. package/dist/types/src/exemplars/Card/index.d.ts +0 -4
  88. package/dist/types/src/exemplars/Card/index.d.ts.map +0 -1
  89. package/dist/types/src/exemplars/CardStack/CardStack.d.ts.map +0 -1
  90. package/dist/types/src/exemplars/CardStack/CardStack.stories-todo.d.ts +0 -1
  91. package/dist/types/src/exemplars/CardStack/CardStack.stories-todo.d.ts.map +0 -1
  92. package/dist/types/src/exemplars/CardStack/CardStackDragPreview.d.ts.map +0 -1
  93. package/dist/types/src/exemplars/CardStack/index.d.ts.map +0 -1
  94. package/dist/types/src/exemplars/index.d.ts +0 -3
  95. package/dist/types/src/exemplars/index.d.ts.map +0 -1
  96. package/dist/types/src/testing/index.d.ts.map +0 -1
  97. package/dist/types/src/testing/stack-manager.d.ts.map +0 -1
  98. package/src/exemplars/Card/Card.stories-todo.tsx +0 -135
  99. package/src/exemplars/Card/Card.tsx +0 -182
  100. package/src/exemplars/Card/CardDragPreview.tsx +0 -22
  101. package/src/exemplars/Card/fragments.ts +0 -25
  102. package/src/exemplars/Card/index.ts +0 -7
  103. package/src/exemplars/CardStack/CardStack.stories-todo.tsx +0 -80
  104. package/src/exemplars/index.ts +0 -6
  105. package/src/playwright/playwright.config.cts +0 -18
  106. /package/dist/types/src/{exemplars → components}/CardStack/index.d.ts +0 -0
  107. /package/dist/types/src/{testing → playwright}/index.d.ts +0 -0
  108. /package/dist/types/src/{testing → playwright}/stack-manager.d.ts +0 -0
  109. /package/src/{exemplars → components}/CardStack/index.ts +0 -0
  110. /package/src/components/{defs.ts → types.ts} +0 -0
  111. /package/src/{testing → playwright}/stack-manager.ts +0 -0
@@ -1,25 +1,31 @@
1
- // packages/ui/react-ui-stack/src/components/Stack/Stack.tsx
2
- import { useSignals as _useSignals } from "@preact-signals/safe-react/tracking";
3
- import { useArrowNavigationGroup } from "@fluentui/react-tabster";
1
+ // src/components/CardStack/CardStack.tsx
2
+ import { Slot } from "@radix-ui/react-slot";
3
+ import React2, { forwardRef as forwardRef2 } from "react";
4
+ import { Card } from "@dxos/react-ui-mosaic";
5
+ import { cardDefaultInlineSize, mx as mx2 } from "@dxos/ui-theme";
6
+
7
+ // src/components/Stack/Stack.tsx
4
8
  import { composeRefs } from "@radix-ui/react-compose-refs";
5
- import React, { Children, forwardRef, useState as useState2, useMemo, useCallback, useEffect } from "react";
6
- import { ListItem } from "@dxos/react-ui";
7
- import { mx } from "@dxos/react-ui-theme";
9
+ import React, { Children, forwardRef, useCallback, useEffect, useMemo, useState as useState2 } from "react";
10
+ import { ListItem, useId } from "@dxos/react-ui";
11
+ import { mx } from "@dxos/ui-theme";
8
12
 
9
- // packages/ui/react-ui-stack/src/hooks/useStackDropForElements.ts
13
+ // src/hooks/useStackDropForElements.ts
10
14
  import { combine } from "@atlaskit/pragmatic-drag-and-drop/combine";
11
15
  import { dropTargetForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
12
16
  import { autoScrollForElements } from "@atlaskit/pragmatic-drag-and-drop-auto-scroll/element";
13
17
  import { attachClosestEdge, extractClosestEdge } from "@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge";
14
18
  import { useLayoutEffect, useState } from "react";
15
- var useStackDropForElements = ({ id, element, scrollElement = element, selfDroppable, orientation, onRearrange }) => {
19
+ var noop = () => {
20
+ };
21
+ var useStackDropForElements = ({ id, element, scrollElement = element, orientation, selfDroppable, onRearrange }) => {
16
22
  const [dropping, setDropping] = useState(false);
17
23
  useLayoutEffect(() => {
18
- if (!element || !selfDroppable) {
24
+ if (!element) {
19
25
  return;
20
26
  }
21
27
  const acceptSourceType = orientation === "horizontal" ? "column" : "card";
22
- return combine(dropTargetForElements({
28
+ return combine(selfDroppable ? dropTargetForElements({
23
29
  element,
24
30
  getData: ({ input, element: element2 }) => {
25
31
  return attachClosestEdge({
@@ -52,16 +58,16 @@ var useStackDropForElements = ({ id, element, scrollElement = element, selfDropp
52
58
  onRearrange(source.data, self.data, extractClosestEdge(self.data));
53
59
  }
54
60
  }
55
- }), autoScrollForElements({
61
+ }) : noop, scrollElement ? autoScrollForElements({
56
62
  element: scrollElement,
57
63
  getAllowedAxis: () => orientation
58
- }));
64
+ }) : noop);
59
65
  }, [
66
+ id,
60
67
  element,
61
68
  scrollElement,
62
69
  selfDroppable,
63
70
  orientation,
64
- id,
65
71
  onRearrange
66
72
  ]);
67
73
  return {
@@ -69,7 +75,7 @@ var useStackDropForElements = ({ id, element, scrollElement = element, selfDropp
69
75
  };
70
76
  };
71
77
 
72
- // packages/ui/react-ui-stack/src/components/StackContext.tsx
78
+ // src/components/StackContext.tsx
73
79
  import { createContext, useContext } from "react";
74
80
  var StackContext = /* @__PURE__ */ createContext({
75
81
  orientation: "vertical",
@@ -92,7 +98,7 @@ var StackItemContext = /* @__PURE__ */ createContext({
92
98
  });
93
99
  var useStackItem = () => useContext(StackItemContext);
94
100
 
95
- // packages/ui/react-ui-stack/src/components/Stack/Stack.tsx
101
+ // src/components/Stack/Stack.tsx
96
102
  var railGridHorizontal = "grid-rows-[[rail-start]_var(--rail-size)_[content-start]_1fr_[content-end]]";
97
103
  var railGridVertical = "grid-cols-[[rail-start]_var(--rail-size)_[content-start]_1fr_[content-end]]";
98
104
  var railGridHorizontalContainFitContent = "grid-rows-[[rail-start]_var(--rail-size)_[content-start]_fit-content(calc(100%-var(--rail-size)*2+2px))_[content-end]]";
@@ -100,583 +106,799 @@ var railGridVerticalContainFitContent = "grid-cols-[[rail-start]_var(--rail-size
100
106
  var autoScrollRootAttributes = {
101
107
  "data-drag-autoscroll": "idle"
102
108
  };
103
- var Stack = /* @__PURE__ */ forwardRef(({ children, classNames, style, orientation = "vertical", rail = true, size = "intrinsic", onRearrange, itemsCount = Children.count(children), getDropElement, separatorOnScroll, ...props }, forwardedRef) => {
104
- var _effect = _useSignals();
105
- try {
106
- const [stackElement, stackRef] = useState2(null);
107
- const composedItemRef = composeRefs(stackRef, forwardedRef);
108
- const arrowNavigationAttrs = useArrowNavigationGroup({
109
- axis: orientation
110
- });
111
- const styles = {
112
- [orientation === "horizontal" ? "gridTemplateColumns" : "gridTemplateRows"]: `repeat(${itemsCount}, min-content) [tabster-dummies] 0`,
113
- ...style
114
- };
115
- const selfDroppable = !!(itemsCount < 1 && onRearrange && props.id);
116
- const { dropping } = useStackDropForElements({
117
- id: props.id,
118
- element: getDropElement && stackElement ? getDropElement(stackElement) : stackElement,
119
- scrollElement: stackElement,
120
- selfDroppable,
121
- orientation,
122
- onRearrange
123
- });
124
- const handleScroll = useCallback(() => {
125
- if (stackElement && Number.isFinite(separatorOnScroll)) {
126
- const scrollPosition = orientation === "horizontal" ? stackElement.scrollLeft : stackElement.scrollTop;
127
- const scrollSize = orientation === "horizontal" ? stackElement.scrollWidth : stackElement.scrollHeight;
128
- const clientSize = orientation === "horizontal" ? stackElement.clientWidth : stackElement.clientHeight;
129
- const separatorHost = stackElement.closest("[data-scroll-separator]");
130
- if (separatorHost) {
131
- separatorHost.setAttribute("data-scroll-separator", String(scrollPosition > separatorOnScroll));
132
- separatorHost.setAttribute("data-scroll-separator-end", String(scrollSize - (scrollPosition + clientSize) > separatorOnScroll));
133
- }
109
+ var PERPENDICULAR_FOCUS_THRESHHOLD = 128;
110
+ var scrollIntoViewAndFocus = (el, orientation) => {
111
+ el.scrollIntoView({
112
+ behavior: "instant",
113
+ [orientation === "vertical" ? "block" : "inline"]: "center"
114
+ });
115
+ return el.focus();
116
+ };
117
+ var Stack = /* @__PURE__ */ forwardRef(({ children, classNames, style, orientation = "vertical", rail = true, size = "intrinsic", onRearrange, itemsCount = Children.count(children), getDropElement, separatorOnScroll, circularFocus, ...props }, forwardedRef) => {
118
+ const stackId = useId("stack", props.id);
119
+ const [stackElement, stackRef] = useState2(null);
120
+ const [lastFocusedItem, setLastFocusedItem] = useState2();
121
+ const composedItemRef = composeRefs(stackRef, forwardedRef);
122
+ const styles = {
123
+ [orientation === "horizontal" ? "gridTemplateColumns" : "gridTemplateRows"]: size === "split" ? `repeat(${itemsCount}, 1fr)` : `repeat(${itemsCount}, min-content) [tabster-dummies] 0`,
124
+ ...style
125
+ };
126
+ const selfDroppable = !!(itemsCount < 1 && onRearrange && props.id);
127
+ const { dropping } = useStackDropForElements({
128
+ id: props.id,
129
+ element: getDropElement && stackElement ? getDropElement(stackElement) : stackElement,
130
+ scrollElement: stackElement,
131
+ selfDroppable,
132
+ orientation,
133
+ onRearrange
134
+ });
135
+ const handleScroll = useCallback(() => {
136
+ if (stackElement && Number.isFinite(separatorOnScroll)) {
137
+ const scrollPosition = orientation === "horizontal" ? stackElement.scrollLeft : stackElement.scrollTop;
138
+ const scrollSize = orientation === "horizontal" ? stackElement.scrollWidth : stackElement.scrollHeight;
139
+ const clientSize = orientation === "horizontal" ? stackElement.clientWidth : stackElement.clientHeight;
140
+ const separatorHost = stackElement.closest("[data-scroll-separator]");
141
+ if (separatorHost) {
142
+ separatorHost.setAttribute("data-scroll-separator", String(scrollPosition > separatorOnScroll));
143
+ separatorHost.setAttribute("data-scroll-separator-end", String(scrollSize - (scrollPosition + clientSize) > separatorOnScroll));
134
144
  }
135
- }, [
136
- stackElement,
137
- separatorOnScroll,
138
- orientation
139
- ]);
140
- const gridClasses = useMemo(() => {
141
- if (!rail) {
142
- return orientation === "horizontal" ? "grid-rows-1 pli-1" : "grid-cols-1 plb-1";
145
+ }
146
+ }, [
147
+ stackElement,
148
+ separatorOnScroll,
149
+ orientation
150
+ ]);
151
+ const handleBlur = useCallback((event) => {
152
+ if (event.target) {
153
+ const target = event.target;
154
+ const closestStackItem = target.closest(`[data-dx-item-id]`);
155
+ if (closestStackItem?.closest(`[data-dx-stack="${stackId}"]`)) {
156
+ setLastFocusedItem(closestStackItem?.getAttribute("data-dx-item-id") ?? void 0);
143
157
  }
144
- if (orientation === "horizontal") {
145
- return size === "contain-fit-content" ? railGridHorizontalContainFitContent : railGridHorizontal;
146
- } else {
147
- return size === "contain-fit-content" ? railGridVerticalContainFitContent : railGridVertical;
158
+ }
159
+ props.onBlur?.(event);
160
+ }, [
161
+ stackId,
162
+ props.onBlur
163
+ ]);
164
+ const handleKeyDown = useCallback((event) => {
165
+ const target = event.target;
166
+ if (event.key.startsWith("Arrow") && !target.closest(`input, textarea, [role="textbox"], [data-tabster*="mover"], [data-arrow-keys="all"], [data-arrow-keys~="${event.key.toLowerCase().slice(5)}"]`)) {
167
+ const closestOwnedItem = target.closest(`[data-dx-stack-item="${stackId}"]`);
168
+ const closestStack = target.closest("[data-dx-stack]");
169
+ const closestStackItems = Array.from(closestStack?.querySelectorAll(`[data-dx-stack-item="${stackId}"]`) ?? []);
170
+ const closestStackOrientation = closestStack?.getAttribute("aria-orientation");
171
+ const ancestorStack = closestStack?.parentElement?.closest("[data-dx-stack]");
172
+ if (closestOwnedItem && closestStack) {
173
+ const ancestorOrientation = ancestorStack?.getAttribute("aria-orientation");
174
+ const parallelDelta = (closestStackOrientation === "vertical" ? event.key === "ArrowUp" : event.key === "ArrowLeft") ? -1 : (closestStackOrientation === "vertical" ? event.key === "ArrowDown" : event.key === "ArrowRight") ? 1 : 0;
175
+ const perpendicularDelta = (closestStackOrientation === "vertical" ? event.key === "ArrowLeft" : event.key === "ArrowUp") ? -1 : (closestStackOrientation === "vertical" ? event.key === "ArrowRight" : event.key === "ArrowDown") ? 1 : 0;
176
+ if (parallelDelta !== 0) {
177
+ const currentIndex = closestStackItems.indexOf(closestOwnedItem);
178
+ const nextIndex = currentIndex + parallelDelta;
179
+ let adjacentItem;
180
+ if (circularFocus) {
181
+ adjacentItem = closestStackItems[(nextIndex + closestStackItems.length) % closestStackItems.length];
182
+ } else {
183
+ if (nextIndex >= 0 && nextIndex < closestStackItems.length) {
184
+ adjacentItem = closestStackItems[nextIndex];
185
+ }
186
+ }
187
+ if (adjacentItem) {
188
+ event.preventDefault();
189
+ scrollIntoViewAndFocus(adjacentItem, closestStackOrientation);
190
+ }
191
+ }
192
+ if (perpendicularDelta !== 0) {
193
+ if (ancestorStack && ancestorOrientation !== closestStackOrientation) {
194
+ const siblingStacks = Array.from(ancestorStack.querySelectorAll(`[data-dx-stack-item="${ancestorStack.getAttribute("data-dx-stack")}"] [data-dx-stack]`));
195
+ const currentStackIndex = siblingStacks.indexOf(closestStack);
196
+ const nextStackIndex = currentStackIndex + perpendicularDelta;
197
+ let adjacentStack;
198
+ if (ancestorStack.getAttribute("data-dx-stack-circular-focus") === "true") {
199
+ adjacentStack = siblingStacks[(nextStackIndex + siblingStacks.length) % siblingStacks.length];
200
+ } else {
201
+ if (nextStackIndex >= 0 && nextStackIndex < siblingStacks.length) {
202
+ adjacentStack = siblingStacks[nextStackIndex];
203
+ }
204
+ }
205
+ const adjacentStackSelfItem = adjacentStack?.closest(`[data-dx-stack-item=${ancestorStack.getAttribute("data-dx-stack")}]`);
206
+ const adjacentStackItems = adjacentStack ? Array.from(adjacentStack.querySelectorAll(`[data-dx-stack-item="${adjacentStack.getAttribute("data-dx-stack")}"]`)) : [];
207
+ if (adjacentStack && adjacentStackItems.length > 0) {
208
+ let closestItem = adjacentStackItems[0];
209
+ const lastFocusedItem2 = adjacentStack.querySelector(`[data-dx-item-id="${adjacentStack.getAttribute("data-dx-last-focused-item") ?? "never"}"]`);
210
+ if (lastFocusedItem2) {
211
+ closestItem = lastFocusedItem2;
212
+ } else {
213
+ const ownedItemRect = closestOwnedItem.getBoundingClientRect();
214
+ const targetPosition = closestStackOrientation === "vertical" ? ownedItemRect.top : ownedItemRect.left;
215
+ let closestDistance = Infinity;
216
+ for (const item of adjacentStackItems) {
217
+ const itemRect = item.getBoundingClientRect();
218
+ const itemPosition = closestStackOrientation === "vertical" ? itemRect.top : itemRect.left;
219
+ const distance = Math.abs(itemPosition - targetPosition);
220
+ if (distance < closestDistance) {
221
+ closestDistance = distance;
222
+ closestItem = item;
223
+ }
224
+ if (closestDistance <= PERPENDICULAR_FOCUS_THRESHHOLD) {
225
+ break;
226
+ }
227
+ }
228
+ }
229
+ event.preventDefault();
230
+ scrollIntoViewAndFocus(closestItem, closestStackOrientation);
231
+ } else if (adjacentStackSelfItem) {
232
+ event.preventDefault();
233
+ scrollIntoViewAndFocus(adjacentStackSelfItem, ancestorOrientation);
234
+ }
235
+ } else if (closestOwnedItem) {
236
+ const closestOwnedItemStack = closestOwnedItem.querySelector("[data-dx-stack]");
237
+ const closestOwnedItemStackItems = closestOwnedItemStack ? Array.from(closestOwnedItemStack.querySelectorAll(`[data-dx-stack-item="${closestOwnedItemStack.getAttribute("data-dx-stack")}"]`)) : [];
238
+ if (closestOwnedItemStackItems.length > 0) {
239
+ event.preventDefault();
240
+ scrollIntoViewAndFocus(closestOwnedItemStackItems[[
241
+ "ArrowUp",
242
+ "ArrowLeft"
243
+ ].includes(event.key) ? closestOwnedItemStackItems.length - 1 : 0], closestOwnedItemStack?.getAttribute("aria-orientation"));
244
+ }
245
+ }
246
+ }
148
247
  }
149
- }, [
150
- rail,
248
+ }
249
+ props.onKeyDown?.(event);
250
+ }, [
251
+ props.onKeyDown,
252
+ stackId,
253
+ circularFocus
254
+ ]);
255
+ const gridClasses = useMemo(() => {
256
+ if (!rail) {
257
+ return orientation === "horizontal" ? "grid-rows-1 pli-[--stack-gap]" : "grid-cols-1 plb-[--stack-gap]";
258
+ }
259
+ if (orientation === "horizontal") {
260
+ return railGridHorizontal;
261
+ } else {
262
+ return railGridVertical;
263
+ }
264
+ }, [
265
+ rail,
266
+ orientation,
267
+ size
268
+ ]);
269
+ useEffect(() => {
270
+ if (!(stackElement && Number.isFinite(separatorOnScroll))) {
271
+ return;
272
+ }
273
+ const observer = new MutationObserver(() => {
274
+ handleScroll();
275
+ });
276
+ observer.observe(stackElement, {
277
+ childList: true,
278
+ subtree: true
279
+ });
280
+ return () => {
281
+ observer.disconnect();
282
+ };
283
+ }, [
284
+ stackElement,
285
+ handleScroll
286
+ ]);
287
+ return /* @__PURE__ */ React.createElement(StackContext.Provider, {
288
+ value: {
151
289
  orientation,
152
- size
153
- ]);
154
- useEffect(() => {
155
- if (!(stackElement && Number.isFinite(separatorOnScroll))) {
156
- return;
157
- }
158
- const observer = new MutationObserver(() => {
159
- handleScroll();
160
- });
161
- observer.observe(stackElement, {
162
- childList: true,
163
- subtree: true
164
- });
165
- return () => {
166
- observer.disconnect();
167
- };
168
- }, [
169
- stackElement,
170
- handleScroll
171
- ]);
172
- return /* @__PURE__ */ React.createElement(StackContext.Provider, {
173
- value: {
174
- orientation,
175
- rail,
176
- size,
177
- onRearrange
178
- }
179
- }, /* @__PURE__ */ React.createElement("div", {
180
- ...props,
181
- ...arrowNavigationAttrs,
182
- className: mx("grid relative", gridClasses, (size === "contain" || size === "contain-fit-content") && (orientation === "horizontal" ? "overflow-x-auto min-bs-0 max-bs-full bs-full" : "overflow-y-auto min-is-0 max-is-full is-full"), classNames),
183
- "data-rail": rail,
184
- "aria-orientation": orientation,
185
- style: styles,
186
- ref: composedItemRef,
187
- ...Number.isFinite(separatorOnScroll) && {
188
- onScroll: handleScroll
290
+ rail,
291
+ size,
292
+ onRearrange,
293
+ stackId
294
+ }
295
+ }, /* @__PURE__ */ React.createElement("div", {
296
+ ...props,
297
+ className: mx("grid relative [--stack-gap:var(--dx-trimXs)]", gridClasses, size === "contain" && (orientation === "horizontal" ? "overflow-x-auto overscroll-x-contain min-bs-0 max-bs-full bs-full" : "overflow-y-auto min-is-0 max-is-full is-full"), classNames),
298
+ onKeyDown: handleKeyDown,
299
+ onBlur: handleBlur,
300
+ "data-dx-stack": stackId,
301
+ "data-dx-stack-circular-focus": circularFocus,
302
+ "data-dx-last-focused-item": lastFocusedItem,
303
+ "data-rail": rail,
304
+ "aria-orientation": orientation,
305
+ style: styles,
306
+ ref: composedItemRef,
307
+ ...Number.isFinite(separatorOnScroll) && {
308
+ onScroll: handleScroll
309
+ }
310
+ }, children, selfDroppable && dropping && /* @__PURE__ */ React.createElement(ListItem.DropIndicator, {
311
+ lineInset: 8,
312
+ terminalInset: -8,
313
+ gap: -8,
314
+ edge: orientation === "horizontal" ? "left" : "top"
315
+ })));
316
+ });
317
+
318
+ // src/components/CardStack/CardStack.tsx
319
+ var cardStackDefaultInlineSizeRem = cardDefaultInlineSize + 2.125;
320
+ var cardStackRoot = "flex flex-col";
321
+ var CardStackRoot = /* @__PURE__ */ forwardRef2(({ children, classNames, asChild, role = "none", ...props }, forwardedRef) => {
322
+ const Root = asChild ? Slot : "div";
323
+ const rootProps = asChild ? {
324
+ classNames: [
325
+ cardStackRoot,
326
+ classNames
327
+ ]
328
+ } : {
329
+ className: mx2(cardStackRoot, classNames),
330
+ role
331
+ };
332
+ return /* @__PURE__ */ React2.createElement(Root, {
333
+ ...props,
334
+ ...rootProps,
335
+ ref: forwardedRef
336
+ }, children);
337
+ });
338
+ var cardStackContent = "shrink min-bs-0 grid dx-focus-ring-group-x-indicator bg-baseSurface";
339
+ var CardStackContent = /* @__PURE__ */ forwardRef2(({ children, classNames, asChild, role = "none", footer, ...props }, forwardedRef) => {
340
+ const Root = asChild ? Slot : "div";
341
+ const baseClassNames = footer ? [
342
+ cardStackContent,
343
+ railGridHorizontalContainFitContent
344
+ ] : [
345
+ cardStackContent
346
+ ];
347
+ const rootProps = asChild ? {
348
+ classNames: [
349
+ ...baseClassNames,
350
+ classNames
351
+ ]
352
+ } : {
353
+ className: mx2(...baseClassNames, classNames),
354
+ role
355
+ };
356
+ return /* @__PURE__ */ React2.createElement(Root, {
357
+ ...props,
358
+ ...rootProps,
359
+ "data-scroll-separator": "false",
360
+ ref: forwardedRef
361
+ }, children);
362
+ });
363
+ var CardStackStack = /* @__PURE__ */ forwardRef2(({ children, classNames, itemsCount = 0, ...props }, forwardedRef) => {
364
+ return /* @__PURE__ */ React2.createElement(Stack, {
365
+ orientation: "vertical",
366
+ size: "contain",
367
+ rail: false,
368
+ classNames: (
369
+ /* NOTE(thure): Do not let this element have zero intrinsic size, otherwise the drop indicator will not display. See #9035. */
370
+ [
371
+ "plb-2",
372
+ classNames
373
+ ]
374
+ ),
375
+ itemsCount,
376
+ separatorOnScroll: 9,
377
+ "data-density": "fine",
378
+ ...props,
379
+ ref: forwardedRef
380
+ }, children);
381
+ });
382
+ var cardStackItem = "contain-layout pli-2 plb-1 first-of-type:pbs-0 last-of-type:pbe-0";
383
+ var CardStackItem = /* @__PURE__ */ forwardRef2(({ children, classNames, asChild, role = "none", ...props }, forwardedRef) => {
384
+ const Root = asChild ? Slot : "div";
385
+ const rootProps = asChild ? {
386
+ classNames: [
387
+ cardStackItem,
388
+ classNames
389
+ ]
390
+ } : {
391
+ className: mx2(cardStackItem, classNames),
392
+ role
393
+ };
394
+ return /* @__PURE__ */ React2.createElement(Root, {
395
+ ...props,
396
+ ...rootProps,
397
+ ref: forwardedRef
398
+ }, children);
399
+ });
400
+ var cardStackHeading = "mli-2 order-first bg-transparent rounded-bs-md flex items-center";
401
+ var CardStackHeading = /* @__PURE__ */ forwardRef2(({ children, classNames, asChild, role = "heading", ...props }, forwardedRef) => {
402
+ const Root = asChild ? Slot : "div";
403
+ const rootProps = asChild ? {
404
+ classNames: [
405
+ cardStackHeading,
406
+ classNames
407
+ ]
408
+ } : {
409
+ className: mx2(cardStackHeading, classNames),
410
+ role
411
+ };
412
+ return /* @__PURE__ */ React2.createElement(Root, {
413
+ ...props,
414
+ ...rootProps,
415
+ ref: forwardedRef
416
+ }, children);
417
+ });
418
+ var cardStackFooter = 'plb-2 mli-2 border-bs border-transparent [[data-scroll-separator-end="true"]_&]:border-subduedSeparator';
419
+ var CardStackFooter = /* @__PURE__ */ forwardRef2(({ children, classNames, asChild, role = "none", ...props }, forwardedRef) => {
420
+ const Root = asChild ? Slot : "div";
421
+ const rootProps = asChild ? {
422
+ classNames: [
423
+ cardStackFooter,
424
+ classNames
425
+ ]
426
+ } : {
427
+ className: mx2(cardStackFooter, classNames),
428
+ role
429
+ };
430
+ return /* @__PURE__ */ React2.createElement(Root, {
431
+ ...props,
432
+ ...rootProps,
433
+ ref: forwardedRef
434
+ }, children);
435
+ });
436
+ var CardStackDragHandle = Card.DragHandle;
437
+ var CardStack = {
438
+ Root: CardStackRoot,
439
+ Content: CardStackContent,
440
+ Stack: CardStackStack,
441
+ Heading: CardStackHeading,
442
+ Footer: CardStackFooter,
443
+ DragHandle: CardStackDragHandle,
444
+ Item: CardStackItem
445
+ };
446
+
447
+ // src/components/CardStack/CardStackDragPreview.tsx
448
+ import React3 from "react";
449
+ import { IconButton, ScrollArea, useTranslation } from "@dxos/react-ui";
450
+ import { mx as mx3 } from "@dxos/ui-theme";
451
+
452
+ // src/translations.ts
453
+ var translationKey = "@dxos/react-ui-stack";
454
+ var translations = [
455
+ {
456
+ "en-US": {
457
+ [translationKey]: {
458
+ "resize label": "Drag to resize",
459
+ "drag handle label": "Drag to rearrange",
460
+ "pin start label": "Pin to the left sidebar",
461
+ "pin end label": "Pin to the right sidebar",
462
+ "increment start label": "Move to the left",
463
+ "increment end label": "Move to the right",
464
+ "close label": "Close",
465
+ "minify label": "Minify"
189
466
  }
190
- }, children, selfDroppable && dropping && /* @__PURE__ */ React.createElement(ListItem.DropIndicator, {
191
- lineInset: 8,
192
- terminalInset: -8,
193
- gap: -8,
194
- edge: orientation === "horizontal" ? "left" : "top"
195
- })));
196
- } finally {
197
- _effect.f();
467
+ }
198
468
  }
199
- });
469
+ ];
200
470
 
201
- // packages/ui/react-ui-stack/src/components/StackItem/StackItem.tsx
202
- import { useSignals as _useSignals8 } from "@preact-signals/safe-react/tracking";
471
+ // src/components/CardStack/CardStackDragPreview.tsx
472
+ var CardStackDragPreviewRoot = ({ children }) => {
473
+ return /* @__PURE__ */ React3.createElement("div", {
474
+ className: "p-2"
475
+ }, /* @__PURE__ */ React3.createElement("div", {
476
+ className: "rounded-md max-bs-[calc(100dvh-1rem)] overflow-hidden bg-baseSurface border border-separator ring-focusLine ring-neutralFocusIndicator flex flex-col"
477
+ }, children));
478
+ };
479
+ var CardStackDragPreviewHeading = ({ children }) => {
480
+ const { t } = useTranslation(translationKey);
481
+ return /* @__PURE__ */ React3.createElement("div", {
482
+ className: "flex items-center p-2"
483
+ }, /* @__PURE__ */ React3.createElement(IconButton, {
484
+ iconOnly: true,
485
+ icon: "ph--dots-six-vertical--regular",
486
+ variant: "ghost",
487
+ label: t("column drag handle label"),
488
+ classNames: "pli-2"
489
+ }), children);
490
+ };
491
+ var CardStackDragPreviewContent = ({ children, itemsCount = 0 }) => {
492
+ return /* @__PURE__ */ React3.createElement(ScrollArea.Root, {
493
+ orientation: "vertical"
494
+ }, /* @__PURE__ */ React3.createElement(ScrollArea.Viewport, {
495
+ classNames: mx3("pli-2 plb-1 gap-2", itemsCount > 0 ? "plb-2" : "plb-1")
496
+ }, children));
497
+ };
498
+ var CardStackDragPreviewFooter = ({ children }) => {
499
+ return /* @__PURE__ */ React3.createElement("div", {
500
+ className: "p-2 border-bs border-separator"
501
+ }, children);
502
+ };
503
+ var CardStackDragPreview = {
504
+ Root: CardStackDragPreviewRoot,
505
+ Heading: CardStackDragPreviewHeading,
506
+ Content: CardStackDragPreviewContent,
507
+ Footer: CardStackDragPreviewFooter
508
+ };
509
+
510
+ // src/components/StackItem/StackItem.tsx
203
511
  import { combine as combine2 } from "@atlaskit/pragmatic-drag-and-drop/combine";
204
512
  import { draggable, dropTargetForElements as dropTargetForElements2 } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
205
513
  import { preserveOffsetOnSource } from "@atlaskit/pragmatic-drag-and-drop/element/preserve-offset-on-source";
206
514
  import { setCustomNativeDragPreview } from "@atlaskit/pragmatic-drag-and-drop/element/set-custom-native-drag-preview";
207
515
  import { attachClosestEdge as attachClosestEdge2, extractClosestEdge as extractClosestEdge2 } from "@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge";
208
- import { useFocusableGroup as useFocusableGroup2 } from "@fluentui/react-tabster";
516
+ import { useFocusableGroup } from "@fluentui/react-tabster";
209
517
  import { composeRefs as composeRefs2 } from "@radix-ui/react-compose-refs";
210
- import React8, { forwardRef as forwardRef5, useLayoutEffect as useLayoutEffect2, useState as useState4, useCallback as useCallback2, useMemo as useMemo3 } from "react";
518
+ import React10, { forwardRef as forwardRef6, useCallback as useCallback2, useLayoutEffect as useLayoutEffect2, useMemo as useMemo3, useState as useState4 } from "react";
211
519
  import { createPortal } from "react-dom";
212
520
  import { ListItem as ListItem2 } from "@dxos/react-ui";
213
521
  import { resizeAttributes, sizeStyle } from "@dxos/react-ui-dnd";
214
- import { mx as mx5 } from "@dxos/react-ui-theme";
522
+ import { mx as mx7 } from "@dxos/ui-theme";
215
523
 
216
- // packages/ui/react-ui-stack/src/components/StackItem/StackItemContent.tsx
217
- import { useSignals as _useSignals2 } from "@preact-signals/safe-react/tracking";
218
- import React2, { forwardRef as forwardRef2, useMemo as useMemo2 } from "react";
219
- import { mx as mx2 } from "@dxos/react-ui-theme";
220
- var StackItemContent = /* @__PURE__ */ forwardRef2(({ children, toolbar, statusbar, layoutManaged, classNames, size = "intrinsic", ...props }, forwardedRef) => {
221
- var _effect = _useSignals2();
222
- try {
223
- const { size: stackItemSize } = useStack();
224
- const { role } = useStackItem();
225
- const style = useMemo2(() => layoutManaged ? {} : {
226
- gridTemplateRows: [
227
- ...toolbar ? [
228
- role === "section" ? "calc(var(--toolbar-size) - 1px)" : "var(--toolbar-size)"
229
- ] : [],
230
- "1fr",
231
- ...statusbar ? [
232
- "var(--statusbar-size)"
233
- ] : []
234
- ].join(" ")
235
- }, [
236
- toolbar,
237
- statusbar,
238
- layoutManaged
239
- ]);
240
- return /* @__PURE__ */ React2.createElement("div", {
241
- role: "none",
242
- ...props,
243
- className: mx2("group grid grid-cols-[100%]", stackItemSize === "contain" && "min-bs-0 overflow-hidden", size === "video" ? "aspect-video" : size === "square" && "aspect-square", toolbar && "[&_.dx-toolbar]:relative [&_.dx-toolbar]:border-be [&_.dx-toolbar]:border-subduedSeparator", role === "section" && toolbar && "[&_.dx-toolbar]:sticky [&_.dx-toolbar]:z-[1] [&_.dx-toolbar]:block-start-0 [&_.dx-toolbar]:-mbe-px [&_.dx-toolbar]:min-is-0", classNames),
244
- style,
245
- "data-popover-collision-boundary": true,
246
- ref: forwardedRef
247
- }, children);
248
- } finally {
249
- _effect.f();
250
- }
524
+ // src/components/StackItem/StackItemContent.tsx
525
+ import React4, { forwardRef as forwardRef3, useMemo as useMemo2 } from "react";
526
+ import { mx as mx4 } from "@dxos/ui-theme";
527
+ var StackItemContent = /* @__PURE__ */ forwardRef3(({ classNames, children, toolbar, statusbar, ...props }, forwardedRef) => {
528
+ const { size: stackItemSize } = useStack();
529
+ const { role } = useStackItem();
530
+ const style = useMemo2(() => ({
531
+ gridTemplateRows: [
532
+ toolbar && role === "section" ? "calc(var(--toolbar-size) - 1px)" : "var(--toolbar-size)",
533
+ "1fr",
534
+ statusbar && "var(--statusbar-size)"
535
+ ].filter(Boolean).join(" ")
536
+ }), [
537
+ toolbar,
538
+ statusbar
539
+ ]);
540
+ return /* @__PURE__ */ React4.createElement("div", {
541
+ ...props,
542
+ role: "none",
543
+ style,
544
+ className: mx4("group grid grid-cols-[100%] density-coarse", stackItemSize === "contain" && "min-bs-0 overflow-hidden", toolbar && role === "section" && "[&_.dx-toolbar]:sticky [&_.dx-toolbar]:z-[1] [&_.dx-toolbar]:block-start-0 [&_.dx-toolbar]:-mbe-px [&_.dx-toolbar]:min-is-0", toolbar && "[&>.dx-toolbar]:relative [&>.dx-toolbar]:border-be [&>.dx-toolbar]:border-subduedSeparator", classNames),
545
+ "data-popover-collision-boundary": true,
546
+ ref: forwardedRef
547
+ }, children);
251
548
  });
549
+ StackItemContent.displayName = "StackItemContent";
252
550
 
253
- // packages/ui/react-ui-stack/src/components/StackItem/StackItemDragHandle.tsx
254
- import { useSignals as _useSignals3 } from "@preact-signals/safe-react/tracking";
255
- import { Slot } from "@radix-ui/react-slot";
256
- import React3 from "react";
551
+ // src/components/StackItem/StackItemDragHandle.tsx
552
+ import { Slot as Slot2 } from "@radix-ui/react-slot";
553
+ import React5 from "react";
257
554
  var StackItemDragHandle = ({ asChild, children }) => {
258
- var _effect = _useSignals3();
259
- try {
260
- const { selfDragHandleRef } = useStackItem();
261
- const Root = asChild ? Slot : "div";
262
- return /* @__PURE__ */ React3.createElement(Root, {
263
- ref: selfDragHandleRef,
264
- role: "button"
265
- }, children);
266
- } finally {
267
- _effect.f();
268
- }
555
+ const { selfDragHandleRef } = useStackItem();
556
+ const Root = asChild ? Slot2 : "div";
557
+ return /* @__PURE__ */ React5.createElement(Root, {
558
+ ref: selfDragHandleRef,
559
+ role: "button"
560
+ }, children);
269
561
  };
270
562
 
271
- // packages/ui/react-ui-stack/src/components/StackItem/StackItemHeading.tsx
272
- import { useSignals as _useSignals4 } from "@preact-signals/safe-react/tracking";
273
- import { useFocusableGroup } from "@fluentui/react-tabster";
274
- import { Slot as Slot2 } from "@radix-ui/react-slot";
275
- import React4, { forwardRef as forwardRef3 } from "react";
563
+ // src/components/StackItem/StackItemHeading.tsx
564
+ import { Slot as Slot3 } from "@radix-ui/react-slot";
565
+ import React6, { forwardRef as forwardRef4 } from "react";
276
566
  import { useAttention } from "@dxos/react-ui-attention";
277
- import { mx as mx3 } from "@dxos/react-ui-theme";
567
+ import { mx as mx5 } from "@dxos/ui-theme";
278
568
  var StackItemHeading = ({ children, classNames, asChild, separateOnScroll, ...props }) => {
279
- var _effect = _useSignals4();
280
- try {
281
- const { orientation } = useStack();
282
- const focusableGroupAttrs = useFocusableGroup({
283
- tabBehavior: "limited"
284
- });
285
- const Root = asChild ? Slot2 : "div";
286
- return /* @__PURE__ */ React4.createElement(Root, {
287
- role: "heading",
288
- ...props,
289
- tabIndex: 0,
290
- ...focusableGroupAttrs,
291
- className: mx3("flex items-center dx-focus-ring-inset-over-all relative !border-is-0 bg-headerSurface", separateOnScroll ? 'border-transparent [[data-scroll-separator="true"]_&]:border-subduedSeparator' : "border-subduedSeparator", orientation === "horizontal" ? "bs-[--rail-size]" : "is-[--rail-size] flex-col", orientation === "horizontal" ? "border-be" : "border-ie", classNames)
292
- }, children);
293
- } finally {
294
- _effect.f();
295
- }
569
+ const { orientation } = useStack();
570
+ const Root = asChild ? Slot3 : "div";
571
+ return /* @__PURE__ */ React6.createElement(Root, {
572
+ role: "heading",
573
+ ...props,
574
+ className: mx5("flex items-center !border-is-0 bg-headerSurface", separateOnScroll ? 'border-transparent [[data-scroll-separator="true"]_&]:border-subduedSeparator' : "border-subduedSeparator", orientation === "horizontal" ? "bs-[--rail-size]" : "is-[--rail-size] flex-col", orientation === "horizontal" ? "border-be" : "border-ie", classNames)
575
+ }, children);
296
576
  };
297
577
  var StackItemHeadingStickyContent = ({ children }) => {
298
- var _effect = _useSignals4();
299
- try {
300
- return /* @__PURE__ */ React4.createElement("div", {
301
- role: "none",
302
- className: "sticky block-start-0 bg-[--sticky-bg] p-1 is-full"
303
- }, children);
304
- } finally {
305
- _effect.f();
306
- }
578
+ return /* @__PURE__ */ React6.createElement("div", {
579
+ role: "none",
580
+ className: "sticky block-start-0 bg-[--sticky-bg] p-1 is-full"
581
+ }, children);
307
582
  };
308
- var StackItemHeadingLabel = /* @__PURE__ */ forwardRef3(({ attendableId, related, classNames, ...props }, forwardedRef) => {
309
- var _effect = _useSignals4();
310
- try {
311
- const { hasAttention, isAncestor, isRelated } = useAttention(attendableId);
312
- return /* @__PURE__ */ React4.createElement("h1", {
313
- ...props,
314
- "data-attention": (related && isRelated || hasAttention || isAncestor).toString(),
315
- className: mx3("pli-1 min-is-0 is-0 grow truncate font-medium text-baseText data-[attention=true]:text-accentText self-center", classNames),
316
- ref: forwardedRef
317
- });
318
- } finally {
319
- _effect.f();
320
- }
583
+ var StackItemHeadingLabel = /* @__PURE__ */ forwardRef4(({ attendableId, related, classNames, ...props }, forwardedRef) => {
584
+ const { hasAttention, isAncestor, isRelated } = useAttention(attendableId);
585
+ return /* @__PURE__ */ React6.createElement("h1", {
586
+ ...props,
587
+ "data-attention": (related && isRelated || hasAttention || isAncestor).toString(),
588
+ className: mx5("pli-1 min-is-0 is-0 grow truncate font-medium text-baseText data-[attention=true]:text-accentText self-center", classNames),
589
+ ref: forwardedRef
590
+ });
321
591
  });
322
592
 
323
- // packages/ui/react-ui-stack/src/components/StackItem/StackItemResizeHandle.tsx
324
- import { useSignals as _useSignals5 } from "@preact-signals/safe-react/tracking";
325
- import React5 from "react";
593
+ // src/components/StackItem/StackItemResizeHandle.tsx
594
+ import React7 from "react";
326
595
  import { ResizeHandle } from "@dxos/react-ui-dnd";
327
596
  var MIN_WIDTH = 20;
328
597
  var MIN_HEIGHT = 3;
329
598
  var StackItemResizeHandle = () => {
330
- var _effect = _useSignals5();
331
- try {
332
- const { orientation } = useStack();
333
- const { setSize, size } = useStackItem();
334
- return /* @__PURE__ */ React5.createElement(ResizeHandle, {
335
- side: orientation === "horizontal" ? "inline-end" : "block-end",
336
- fallbackSize: DEFAULT_EXTRINSIC_SIZE,
337
- minSize: orientation === "horizontal" ? MIN_WIDTH : MIN_HEIGHT,
338
- size,
339
- onSizeChange: setSize
340
- });
341
- } finally {
342
- _effect.f();
343
- }
599
+ const { orientation } = useStack();
600
+ const { setSize, size } = useStackItem();
601
+ return /* @__PURE__ */ React7.createElement(ResizeHandle, {
602
+ side: orientation === "horizontal" ? "inline-end" : "block-end",
603
+ fallbackSize: DEFAULT_EXTRINSIC_SIZE,
604
+ minSize: orientation === "horizontal" ? MIN_WIDTH : MIN_HEIGHT,
605
+ size,
606
+ onSizeChange: setSize
607
+ });
344
608
  };
345
609
 
346
- // packages/ui/react-ui-stack/src/components/StackItem/StackItemSigil.tsx
347
- import { useSignals as _useSignals7 } from "@preact-signals/safe-react/tracking";
348
- import React7, { Fragment, forwardRef as forwardRef4, useState as useState3 } from "react";
610
+ // src/components/StackItem/StackItemSigil.tsx
611
+ import React9, { Fragment, forwardRef as forwardRef5, useState as useState3 } from "react";
349
612
  import { keySymbols } from "@dxos/keyboard";
350
- import { Button, DropdownMenu, Icon, toLocalizedString, useTranslation } from "@dxos/react-ui";
613
+ import { Button, DropdownMenu, Icon, toLocalizedString, useTranslation as useTranslation2 } from "@dxos/react-ui";
351
614
  import { useAttention as useAttention2 } from "@dxos/react-ui-attention";
352
- import { descriptionText, mx as mx4 } from "@dxos/react-ui-theme";
615
+ import { descriptionText, mx as mx6 } from "@dxos/ui-theme";
353
616
  import { getHostPlatform } from "@dxos/util";
354
617
 
355
- // packages/ui/react-ui-stack/src/components/StackItem/MenuSignifier.tsx
356
- import { useSignals as _useSignals6 } from "@preact-signals/safe-react/tracking";
357
- import React6 from "react";
358
- var MenuSignifierHorizontal = () => {
359
- var _effect = _useSignals6();
360
- try {
361
- return /* @__PURE__ */ React6.createElement("svg", {
362
- className: "absolute block-end-[7px]",
363
- width: 20,
364
- height: 2,
365
- viewBox: "0 0 20 2",
366
- stroke: "currentColor",
367
- opacity: 0.5
368
- }, /* @__PURE__ */ React6.createElement("line", {
369
- x1: 0.5,
370
- y1: 0.75,
371
- x2: 19,
372
- y2: 0.75,
373
- strokeWidth: 1.25,
374
- strokeLinecap: "round",
375
- strokeDasharray: "6 20",
376
- strokeDashoffset: "-6.5"
377
- }));
378
- } finally {
379
- _effect.f();
380
- }
381
- };
382
-
383
- // packages/ui/react-ui-stack/src/translations.ts
384
- var translationKey = "stack";
385
- var translations_default = [
386
- {
387
- "en-US": {
388
- [translationKey]: {
389
- "resize label": "Drag to resize",
390
- "drag handle label": "Drag to rearrange",
391
- "pin start label": "Pin to the left sidebar",
392
- "pin end label": "Pin to the right sidebar",
393
- "increment start label": "Move to the left",
394
- "increment end label": "Move to the right",
395
- "close label": "Close",
396
- "minify label": "Minify"
397
- }
398
- }
399
- }
400
- ];
618
+ // src/components/StackItem/MenuSignifier.tsx
619
+ import React8 from "react";
620
+ var MenuSignifierHorizontal = () => /* @__PURE__ */ React8.createElement("svg", {
621
+ className: "absolute block-end-[7px]",
622
+ width: 20,
623
+ height: 2,
624
+ viewBox: "0 0 20 2",
625
+ stroke: "currentColor",
626
+ opacity: 0.5
627
+ }, /* @__PURE__ */ React8.createElement("line", {
628
+ x1: 0.5,
629
+ y1: 0.75,
630
+ x2: 19,
631
+ y2: 0.75,
632
+ strokeWidth: 1.25,
633
+ strokeLinecap: "round",
634
+ strokeDasharray: "6 20",
635
+ strokeDashoffset: "-6.5"
636
+ }));
401
637
 
402
- // packages/ui/react-ui-stack/src/components/StackItem/StackItemSigil.tsx
403
- var StackItemSigilButton = /* @__PURE__ */ forwardRef4(({ attendableId, classNames, related, isMenu = true, children, ...props }, forwardedRef) => {
404
- var _effect = _useSignals7();
405
- try {
406
- const { hasAttention, isAncestor, isRelated } = useAttention2(attendableId);
407
- const variant = related && isRelated || hasAttention || isAncestor ? "primary" : "ghost";
408
- return /* @__PURE__ */ React7.createElement(Button, {
409
- ...props,
410
- variant,
411
- classNames: [
412
- "shrink-0 pli-0 min-bs-0 is-[--rail-action] bs-[--rail-action] relative app-no-drag",
413
- classNames
414
- ],
415
- ref: forwardedRef
416
- }, isMenu && /* @__PURE__ */ React7.createElement(MenuSignifierHorizontal, null), children);
417
- } finally {
418
- _effect.f();
419
- }
638
+ // src/components/StackItem/StackItemSigil.tsx
639
+ var StackItemSigilButton = /* @__PURE__ */ forwardRef5(({ attendableId, classNames, related, isMenu = true, children, ...props }, forwardedRef) => {
640
+ const { hasAttention, isAncestor, isRelated } = useAttention2(attendableId);
641
+ const variant = related && isRelated || hasAttention || isAncestor ? "primary" : "ghost";
642
+ return /* @__PURE__ */ React9.createElement(Button, {
643
+ ...props,
644
+ variant,
645
+ classNames: [
646
+ "shrink-0 pli-0 min-bs-0 is-[--rail-action] bs-[--rail-action] relative app-no-drag",
647
+ classNames
648
+ ],
649
+ ref: forwardedRef
650
+ }, isMenu && /* @__PURE__ */ React9.createElement(MenuSignifierHorizontal, null), children);
420
651
  });
421
- var StackItemSigil = /* @__PURE__ */ forwardRef4(({ actions: actionGroups, onAction, triggerLabel, attendableId, icon, related, children }, forwardedRef) => {
422
- var _effect = _useSignals7();
423
- try {
424
- const { t } = useTranslation(translationKey);
425
- const [optionsMenuOpen, setOptionsMenuOpen] = useState3(false);
426
- const hasActions = actionGroups && actionGroups.length > 0;
427
- const button = /* @__PURE__ */ React7.createElement(StackItemSigilButton, {
428
- attendableId,
429
- related,
430
- isMenu: hasActions,
431
- // TODO(wittjosiah): Better disabling of interactive styles when no action are available.
432
- // Remove underscore icon when no actions are available?
433
- classNames: !hasActions && "cursor-default"
434
- }, /* @__PURE__ */ React7.createElement("span", {
435
- className: "sr-only"
436
- }, triggerLabel), /* @__PURE__ */ React7.createElement(Icon, {
437
- icon,
438
- size: 5
439
- }));
440
- if (!hasActions) {
441
- return button;
442
- }
443
- return /* @__PURE__ */ React7.createElement(DropdownMenu.Root, {
444
- open: optionsMenuOpen,
445
- onOpenChange: setOptionsMenuOpen
446
- }, /* @__PURE__ */ React7.createElement(DropdownMenu.Trigger, {
447
- asChild: true,
448
- ref: forwardedRef
449
- }, button), /* @__PURE__ */ React7.createElement(DropdownMenu.Portal, null, /* @__PURE__ */ React7.createElement(DropdownMenu.Content, {
450
- classNames: "z-[31]"
451
- }, /* @__PURE__ */ React7.createElement(DropdownMenu.Viewport, null, actionGroups?.map((actions, index) => {
452
- const separator = index > 0 ? /* @__PURE__ */ React7.createElement(DropdownMenu.Separator, null) : null;
453
- return /* @__PURE__ */ React7.createElement(Fragment, {
454
- key: index
455
- }, separator, actions.map((action) => {
456
- const shortcut = typeof action.properties.keyBinding === "string" ? action.properties.keyBinding : action.properties.keyBinding?.[getHostPlatform()];
457
- const menuItemType = action.properties.menuItemType;
458
- const Root = menuItemType === "toggle" ? DropdownMenu.CheckboxItem : DropdownMenu.Item;
459
- return /* @__PURE__ */ React7.createElement(Root, {
460
- key: action.id,
461
- onClick: (event) => {
462
- if (action.properties.disabled) {
463
- return;
464
- }
465
- event.stopPropagation();
466
- setOptionsMenuOpen(false);
467
- onAction?.(action);
468
- },
469
- classNames: "gap-2",
470
- disabled: action.properties.disabled,
471
- checked: menuItemType === "toggle" ? action.properties.isChecked : void 0,
472
- ...action.properties?.testId && {
473
- "data-testid": action.properties.testId
652
+ var StackItemSigil = /* @__PURE__ */ forwardRef5(({ actions: actionGroups, onAction, triggerLabel, attendableId, icon, related, children }, forwardedRef) => {
653
+ const { t } = useTranslation2(translationKey);
654
+ const [optionsMenuOpen, setOptionsMenuOpen] = useState3(false);
655
+ const hasActions = actionGroups && actionGroups.length > 0;
656
+ const button = /* @__PURE__ */ React9.createElement(StackItemSigilButton, {
657
+ attendableId,
658
+ related,
659
+ isMenu: hasActions,
660
+ // TODO(wittjosiah): Better disabling of interactive styles when no action are available.
661
+ // Remove underscore icon when no actions are available?
662
+ classNames: !hasActions && "cursor-default"
663
+ }, /* @__PURE__ */ React9.createElement("span", {
664
+ className: "sr-only"
665
+ }, triggerLabel), /* @__PURE__ */ React9.createElement(Icon, {
666
+ icon,
667
+ size: 5
668
+ }));
669
+ if (!hasActions) {
670
+ return button;
671
+ }
672
+ return /* @__PURE__ */ React9.createElement(DropdownMenu.Root, {
673
+ open: optionsMenuOpen,
674
+ onOpenChange: setOptionsMenuOpen
675
+ }, /* @__PURE__ */ React9.createElement(DropdownMenu.Trigger, {
676
+ asChild: true,
677
+ ref: forwardedRef
678
+ }, button), /* @__PURE__ */ React9.createElement(DropdownMenu.Portal, null, /* @__PURE__ */ React9.createElement(DropdownMenu.Content, {
679
+ classNames: "z-[31]"
680
+ }, /* @__PURE__ */ React9.createElement(DropdownMenu.Viewport, null, actionGroups?.map((actions, index) => {
681
+ const separator = index > 0 ? /* @__PURE__ */ React9.createElement(DropdownMenu.Separator, null) : null;
682
+ return /* @__PURE__ */ React9.createElement(Fragment, {
683
+ key: index
684
+ }, separator, actions.map((action) => {
685
+ const shortcut = typeof action.properties.keyBinding === "string" ? action.properties.keyBinding : action.properties.keyBinding?.[getHostPlatform()];
686
+ const menuItemType = action.properties.menuItemType;
687
+ const Root = menuItemType === "toggle" ? DropdownMenu.CheckboxItem : DropdownMenu.Item;
688
+ return /* @__PURE__ */ React9.createElement(Root, {
689
+ key: action.id,
690
+ onClick: (event) => {
691
+ if (action.properties.disabled) {
692
+ return;
474
693
  }
475
- }, /* @__PURE__ */ React7.createElement(Icon, {
476
- icon: action.properties.icon ?? "ph--placeholder--regular",
477
- size: 4
478
- }), /* @__PURE__ */ React7.createElement("span", {
479
- className: "grow truncate"
480
- }, toLocalizedString(action.properties.label ?? "", t)), menuItemType === "toggle" && /* @__PURE__ */ React7.createElement(DropdownMenu.ItemIndicator, {
481
- asChild: true
482
- }, /* @__PURE__ */ React7.createElement(Icon, {
483
- icon: "ph--check--regular",
484
- size: 4
485
- })), shortcut && /* @__PURE__ */ React7.createElement("span", {
486
- className: mx4("shrink-0", descriptionText)
487
- }, keySymbols(shortcut).join("")));
488
- }));
489
- }), children), /* @__PURE__ */ React7.createElement(DropdownMenu.Arrow, null))));
490
- } finally {
491
- _effect.f();
492
- }
694
+ event.stopPropagation();
695
+ setOptionsMenuOpen(false);
696
+ onAction?.(action);
697
+ },
698
+ classNames: "gap-2",
699
+ disabled: action.properties.disabled,
700
+ checked: menuItemType === "toggle" ? action.properties.isChecked : void 0,
701
+ ...action.properties?.testId && {
702
+ "data-testid": action.properties.testId
703
+ }
704
+ }, /* @__PURE__ */ React9.createElement(Icon, {
705
+ icon: action.properties.icon ?? "ph--placeholder--regular",
706
+ size: 4
707
+ }), /* @__PURE__ */ React9.createElement("span", {
708
+ className: "grow truncate"
709
+ }, toLocalizedString(action.properties.label ?? "", t)), menuItemType === "toggle" && /* @__PURE__ */ React9.createElement(DropdownMenu.ItemIndicator, {
710
+ asChild: true
711
+ }, /* @__PURE__ */ React9.createElement(Icon, {
712
+ icon: "ph--check--regular",
713
+ size: 4
714
+ })), shortcut && /* @__PURE__ */ React9.createElement("span", {
715
+ className: mx6("shrink-0", descriptionText)
716
+ }, keySymbols(shortcut).join("")));
717
+ }));
718
+ }), children), /* @__PURE__ */ React9.createElement(DropdownMenu.Arrow, null))));
493
719
  });
494
720
 
495
- // packages/ui/react-ui-stack/src/components/StackItem/StackItem.tsx
721
+ // src/components/StackItem/StackItem.tsx
496
722
  var DEFAULT_HORIZONTAL_SIZE = 48;
497
723
  var DEFAULT_VERTICAL_SIZE = "min-content";
498
724
  var DEFAULT_EXTRINSIC_SIZE = DEFAULT_HORIZONTAL_SIZE;
499
- var StackItemRoot = /* @__PURE__ */ forwardRef5(({ item, children, classNames, size: propsSize, onSizeChange, role, order, prevSiblingId, nextSiblingId, style, disableRearrange, focusIndicatorVariant = "over-all", ...props }, forwardedRef) => {
500
- var _effect = _useSignals8();
501
- try {
502
- const [itemElement, itemRef] = useState4(null);
503
- const [selfDragHandleElement, selfDragHandleRef] = useState4(null);
504
- const [closestEdge, setEdge] = useState4(null);
505
- const [sourceId, setSourceId] = useState4(null);
506
- const [dragState, setDragState] = useState4(idle);
507
- const { orientation, rail, onRearrange } = useStack();
508
- const [size = orientation === "horizontal" ? DEFAULT_HORIZONTAL_SIZE : DEFAULT_VERTICAL_SIZE, setInternalSize] = useState4(propsSize);
509
- const Root = role ?? "div";
510
- const composedItemRef = composeRefs2(itemRef, forwardedRef);
511
- const setSize = useCallback2((nextSize, commit) => {
512
- setInternalSize(nextSize);
513
- if (commit) {
514
- onSizeChange?.(nextSize);
515
- }
516
- }, [
517
- onSizeChange
518
- ]);
519
- const type = orientation === "horizontal" ? "column" : "card";
520
- useLayoutEffect2(() => {
521
- if (!itemElement || !onRearrange || disableRearrange) {
522
- return;
725
+ var StackItemRoot = /* @__PURE__ */ forwardRef6(({ item, children, classNames, size: propsSize, onSizeChange, role, order, prevSiblingId, nextSiblingId, style, disableRearrange, focusIndicatorVariant = "over-all", ...props }, forwardedRef) => {
726
+ const [itemElement, itemRef] = useState4(null);
727
+ const composedItemRef = composeRefs2(itemRef, forwardedRef);
728
+ const [selfDragHandleElement, selfDragHandleRef] = useState4(null);
729
+ const [closestEdge, setEdge] = useState4(null);
730
+ const [sourceId, setSourceId] = useState4(null);
731
+ const [dragState, setDragState] = useState4(idle);
732
+ const { orientation, rail, onRearrange, size: stackSize, stackId } = useStack();
733
+ const [size = orientation === "horizontal" ? DEFAULT_HORIZONTAL_SIZE : DEFAULT_VERTICAL_SIZE, setInternalSize] = useState4(propsSize);
734
+ const Root = role ?? "div";
735
+ const setSize = useCallback2((nextSize, commit) => {
736
+ setInternalSize(nextSize);
737
+ if (commit) {
738
+ onSizeChange?.(nextSize);
739
+ }
740
+ }, [
741
+ onSizeChange
742
+ ]);
743
+ const type = orientation === "horizontal" ? "column" : "card";
744
+ useLayoutEffect2(() => {
745
+ if (!itemElement || !onRearrange || disableRearrange) {
746
+ return;
747
+ }
748
+ return combine2(draggable({
749
+ element: itemElement,
750
+ ...selfDragHandleElement && {
751
+ dragHandle: selfDragHandleElement
752
+ },
753
+ getInitialData: () => ({
754
+ id: item.id,
755
+ type
756
+ }),
757
+ onGenerateDragPreview: ({ nativeSetDragImage, source, location }) => {
758
+ document.body.setAttribute("data-drag-preview", "true");
759
+ const offsetFn = preserveOffsetOnSource({
760
+ element: source.element,
761
+ input: location.current.input
762
+ });
763
+ const rect = source.element.getBoundingClientRect();
764
+ setCustomNativeDragPreview({
765
+ nativeSetDragImage,
766
+ getOffset: ({ container }) => {
767
+ return offsetFn({
768
+ container
769
+ });
770
+ },
771
+ render: ({ container }) => {
772
+ container.style.width = rect.width + "px";
773
+ setDragState({
774
+ type: "preview",
775
+ container,
776
+ item
777
+ });
778
+ return () => {
779
+ };
780
+ }
781
+ });
782
+ },
783
+ onDragStart: () => {
784
+ document.body.removeAttribute("data-drag-preview");
785
+ itemElement?.closest("[data-drag-autoscroll]")?.setAttribute("data-drag-autoscroll", "active");
786
+ setDragState({
787
+ type: "is-dragging",
788
+ item
789
+ });
790
+ },
791
+ onDrop: () => {
792
+ itemElement?.closest("[data-drag-autoscroll]")?.setAttribute("data-drag-autoscroll", "idle");
793
+ setDragState(idle);
523
794
  }
524
- return combine2(draggable({
525
- element: itemElement,
526
- ...selfDragHandleElement && {
527
- dragHandle: selfDragHandleElement
528
- },
529
- getInitialData: () => ({
795
+ }), dropTargetForElements2({
796
+ element: itemElement,
797
+ getData: ({ input, element }) => {
798
+ return attachClosestEdge2({
530
799
  id: item.id,
531
800
  type
532
- }),
533
- onGenerateDragPreview: ({ nativeSetDragImage, source, location }) => {
534
- document.body.setAttribute("data-drag-preview", "true");
535
- const offsetFn = preserveOffsetOnSource({
536
- element: source.element,
537
- input: location.current.input
538
- });
539
- const rect = source.element.getBoundingClientRect();
540
- setCustomNativeDragPreview({
541
- nativeSetDragImage,
542
- getOffset: ({ container }) => {
543
- return offsetFn({
544
- container
545
- });
546
- },
547
- render: ({ container }) => {
548
- container.style.width = rect.width + "px";
549
- setDragState({
550
- type: "preview",
551
- container,
552
- item
553
- });
554
- return () => {
555
- };
556
- }
557
- });
558
- },
559
- onDragStart: () => {
560
- document.body.removeAttribute("data-drag-preview");
561
- itemElement?.closest("[data-drag-autoscroll]")?.setAttribute("data-drag-autoscroll", "active");
562
- setDragState({
563
- type: "is-dragging",
564
- item
565
- });
566
- },
567
- onDrop: () => {
568
- itemElement?.closest("[data-drag-autoscroll]")?.setAttribute("data-drag-autoscroll", "idle");
569
- setDragState(idle);
801
+ }, {
802
+ input,
803
+ element,
804
+ allowedEdges: orientation === "horizontal" ? [
805
+ "left",
806
+ "right"
807
+ ] : [
808
+ "top",
809
+ "bottom"
810
+ ]
811
+ });
812
+ },
813
+ onDragEnter: ({ self, source }) => {
814
+ if (source.data.type === self.data.type) {
815
+ setEdge(extractClosestEdge2(self.data));
816
+ setSourceId(source.data.id);
570
817
  }
571
- }), dropTargetForElements2({
572
- element: itemElement,
573
- getData: ({ input, element }) => {
574
- return attachClosestEdge2({
575
- id: item.id,
576
- type
577
- }, {
578
- input,
579
- element,
580
- allowedEdges: orientation === "horizontal" ? [
581
- "left",
582
- "right"
583
- ] : [
584
- "top",
585
- "bottom"
586
- ]
587
- });
588
- },
589
- onDragEnter: ({ self, source }) => {
590
- if (source.data.type === self.data.type) {
591
- setEdge(extractClosestEdge2(self.data));
592
- setSourceId(source.data.id);
593
- }
594
- },
595
- onDrag: ({ self, source }) => {
596
- if (source.data.type === self.data.type) {
597
- setEdge(extractClosestEdge2(self.data));
598
- setSourceId(source.data.id);
599
- }
600
- },
601
- onDragLeave: () => {
602
- setEdge(null);
603
- setSourceId(null);
604
- },
605
- onDrop: ({ self, source }) => {
606
- setEdge(null);
607
- setSourceId(null);
608
- if (source.data.type === self.data.type) {
609
- onRearrange(source.data, self.data, extractClosestEdge2(self.data));
610
- }
818
+ },
819
+ onDrag: ({ self, source }) => {
820
+ if (source.data.type === self.data.type) {
821
+ setEdge(extractClosestEdge2(self.data));
822
+ setSourceId(source.data.id);
823
+ }
824
+ },
825
+ onDragLeave: () => {
826
+ setEdge(null);
827
+ setSourceId(null);
828
+ },
829
+ onDrop: ({ self, source }) => {
830
+ setEdge(null);
831
+ setSourceId(null);
832
+ if (source.data.type === self.data.type) {
833
+ onRearrange(source.data, self.data, extractClosestEdge2(self.data));
611
834
  }
612
- }));
613
- }, [
614
- orientation,
615
- item,
616
- onRearrange,
617
- selfDragHandleElement,
618
- itemElement
619
- ]);
620
- const focusableGroupAttrs = useFocusableGroup2({
621
- tabBehavior: "limited"
622
- });
623
- const shouldShowDropIndicator = () => {
624
- if (!closestEdge || !sourceId) {
625
- return false;
626
- }
627
- if (sourceId === item.id) {
628
- return false;
629
- }
630
- const isTrailingEdgeOfPrevSibling = prevSiblingId !== void 0 && sourceId === prevSiblingId && (orientation === "horizontal" && closestEdge === "left" || orientation === "vertical" && closestEdge === "top");
631
- if (isTrailingEdgeOfPrevSibling) {
632
- return false;
633
- }
634
- const isLeadingEdgeOfNextSibling = nextSiblingId !== void 0 && sourceId === nextSiblingId && (orientation === "horizontal" && closestEdge === "right" || orientation === "vertical" && closestEdge === "bottom");
635
- if (isLeadingEdgeOfNextSibling) {
636
- return false;
637
835
  }
638
- return true;
639
- };
640
- const stackItemContextValue = useMemo3(() => ({
641
- selfDragHandleRef,
642
- size,
643
- setSize,
644
- state: dragState,
645
- setState: setDragState,
646
- role
647
- }), [
648
- selfDragHandleRef,
649
- size,
650
- setSize,
651
- dragState,
652
- setDragState,
653
- role
654
- ]);
655
- return /* @__PURE__ */ React8.createElement(StackItemContext.Provider, {
656
- value: stackItemContextValue
657
- }, /* @__PURE__ */ React8.createElement(Root, {
658
- ...props,
659
- tabIndex: 0,
660
- ...focusableGroupAttrs,
661
- className: mx5("group/stack-item grid relative", focusIndicatorVariant === "over-all" ? "dx-focus-ring-inset-over-all" : orientation === "horizontal" ? "dx-focus-ring-group-x" : "dx-focus-ring-group-y", orientation === "horizontal" ? "grid-rows-subgrid" : "grid-cols-subgrid", rail && (orientation === "horizontal" ? "row-span-2" : "col-span-2"), role === "section" && orientation !== "horizontal" && "border-be border-subduedSeparator", classNames),
662
- "data-dx-stack-item": true,
663
- ...resizeAttributes,
664
- style: {
665
- ...sizeStyle(size, orientation),
666
- ...Number.isFinite(order) && {
667
- [orientation === "horizontal" ? "gridColumn" : "gridRow"]: `${order}`
668
- },
669
- ...style
836
+ }));
837
+ }, [
838
+ orientation,
839
+ item,
840
+ onRearrange,
841
+ selfDragHandleElement,
842
+ itemElement
843
+ ]);
844
+ const focusableGroupAttrs = useFocusableGroup({
845
+ tabBehavior: "limited"
846
+ });
847
+ const shouldShowDropIndicator = () => {
848
+ if (!closestEdge || !sourceId) {
849
+ return false;
850
+ }
851
+ if (sourceId === item.id) {
852
+ return false;
853
+ }
854
+ const isTrailingEdgeOfPrevSibling = prevSiblingId !== void 0 && sourceId === prevSiblingId && (orientation === "horizontal" && closestEdge === "left" || orientation === "vertical" && closestEdge === "top");
855
+ if (isTrailingEdgeOfPrevSibling) {
856
+ return false;
857
+ }
858
+ const isLeadingEdgeOfNextSibling = nextSiblingId !== void 0 && sourceId === nextSiblingId && (orientation === "horizontal" && closestEdge === "right" || orientation === "vertical" && closestEdge === "bottom");
859
+ if (isLeadingEdgeOfNextSibling) {
860
+ return false;
861
+ }
862
+ return true;
863
+ };
864
+ const stackItemContextValue = useMemo3(() => ({
865
+ selfDragHandleRef,
866
+ size,
867
+ setSize,
868
+ state: dragState,
869
+ setState: setDragState,
870
+ role
871
+ }), [
872
+ selfDragHandleRef,
873
+ size,
874
+ setSize,
875
+ dragState,
876
+ setDragState,
877
+ role
878
+ ]);
879
+ return /* @__PURE__ */ React10.createElement(StackItemContext.Provider, {
880
+ value: stackItemContextValue
881
+ }, /* @__PURE__ */ React10.createElement(Root, {
882
+ ...props,
883
+ tabIndex: 0,
884
+ ...focusableGroupAttrs,
885
+ className: mx7("group/stack-item grid relative", focusIndicatorVariant === "over-all" ? "dx-focus-ring-inset-over-all" : focusIndicatorVariant === "over-all-always" ? "dx-focus-ring-inset-over-all-always" : orientation === "horizontal" ? focusIndicatorVariant === "group-always" ? "dx-focus-ring-group-x-always" : "dx-focus-ring-group-x" : focusIndicatorVariant === "group-always" ? "dx-focus-ring-group-y-always" : "dx-focus-ring-group-y", orientation === "horizontal" ? "grid-rows-subgrid" : "grid-cols-subgrid", rail && (orientation === "horizontal" ? "row-span-2" : "col-span-2"), role === "section" && orientation !== "horizontal" && "border-be border-subduedSeparator", classNames),
886
+ "data-dx-stack-item": stackId,
887
+ "data-dx-item-id": item.id,
888
+ ...resizeAttributes,
889
+ style: {
890
+ ...stackSize !== "split" && sizeStyle(size, orientation),
891
+ ...Number.isFinite(order) && {
892
+ [orientation === "horizontal" ? "gridColumn" : "gridRow"]: `${order}`
670
893
  },
671
- ref: composedItemRef
672
- }, children, shouldShowDropIndicator() && closestEdge && /* @__PURE__ */ React8.createElement(ListItem2.DropIndicator, {
673
- lineInset: 8,
674
- terminalInset: -8,
675
- edge: closestEdge
676
- })));
677
- } finally {
678
- _effect.f();
679
- }
894
+ ...style
895
+ },
896
+ ref: composedItemRef
897
+ }, children, shouldShowDropIndicator() && closestEdge && /* @__PURE__ */ React10.createElement(ListItem2.DropIndicator, {
898
+ lineInset: 8,
899
+ terminalInset: -8,
900
+ edge: closestEdge
901
+ })));
680
902
  });
681
903
  var StackItemDragPreview = ({ children }) => {
682
904
  const { state } = useStackItem();
@@ -687,477 +909,16 @@ var StackItemDragPreview = ({ children }) => {
687
909
  var StackItem = {
688
910
  Root: StackItemRoot,
689
911
  Content: StackItemContent,
912
+ DragHandle: StackItemDragHandle,
913
+ DragPreview: StackItemDragPreview,
690
914
  Heading: StackItemHeading,
691
915
  HeadingLabel: StackItemHeadingLabel,
692
916
  HeadingStickyContent: StackItemHeadingStickyContent,
693
917
  ResizeHandle: StackItemResizeHandle,
694
- DragHandle: StackItemDragHandle,
695
918
  Sigil: StackItemSigil,
696
- SigilButton: StackItemSigilButton,
697
- DragPreview: StackItemDragPreview
698
- };
699
-
700
- // packages/ui/react-ui-stack/src/exemplars/Card/Card.tsx
701
- import { useSignals as _useSignals9 } from "@preact-signals/safe-react/tracking";
702
- import { Primitive } from "@radix-ui/react-primitive";
703
- import { Slot as Slot3 } from "@radix-ui/react-slot";
704
- import React9, { forwardRef as forwardRef6 } from "react";
705
- import { Icon as Icon2, IconButton, Toolbar, useTranslation as useTranslation2 } from "@dxos/react-ui";
706
- import { hoverableControls, mx as mx6 } from "@dxos/react-ui-theme";
707
-
708
- // packages/ui/react-ui-stack/src/exemplars/Card/fragments.ts
709
- var cardRoot = "contain-layout pli-2 plb-1 first-of-type:pbs-0 last-of-type:pbe-0";
710
- var cardContent = "rounded overflow-hidden bg-cardSurface border border-separator dark:border-subduedSeparator dx-focus-ring-group-y-indicator relative min-bs-[--rail-item] group/card";
711
- var cardSpacing = "pli-cardSpacingInline mlb-cardSpacingBlock";
712
- var labelSpacing = "mbs-inputSpacingBlock mbe-labelSpacingBlock";
713
- var cardDialogContent = "p-0 bs-content min-bs-[8rem] max-bs-full md:max-is-[32rem] overflow-hidden";
714
- var cardDialogHeader = "pli-cardSpacingInline mbs-cardSpacingBlock flex justify-between";
715
- var cardDialogOverflow = "overflow-y-auto min-bs-0 flex-1";
716
- var cardDialogPaddedOverflow = `${cardDialogOverflow} plb-cardSpacingBlock`;
717
- var cardDialogSearchListRoot = "pli-cardSpacingInline pbs-cardSpacingBlock [&>input]:mbe-0 min-bs-0 flex-1 flex flex-col";
718
- var cardText = cardSpacing;
719
- var cardHeading = "text-lg font-medium line-clamp-2";
720
- var cardChrome = "pli-[--dx-cardSpacingChrome] mlb-[--dx-cardSpacingChrome] [&_.dx-button]:text-start [&_.dx-button]:is-full";
721
-
722
- // packages/ui/react-ui-stack/src/exemplars/Card/Card.tsx
723
- var CardRoot = /* @__PURE__ */ forwardRef6(({ children, classNames, asChild, role = "none", ...props }, forwardedRef) => {
724
- var _effect = _useSignals9();
725
- try {
726
- const Root = asChild ? Slot3 : "div";
727
- const rootProps = asChild ? {
728
- classNames: [
729
- cardRoot,
730
- classNames
731
- ]
732
- } : {
733
- className: mx6(cardRoot, classNames),
734
- role
735
- };
736
- return /* @__PURE__ */ React9.createElement(Root, {
737
- ...props,
738
- ...rootProps,
739
- ref: forwardedRef
740
- }, children);
741
- } finally {
742
- _effect.f();
743
- }
744
- });
745
- var CardContent = /* @__PURE__ */ forwardRef6(({ children, classNames, asChild, role = "group", ...props }, forwardedRef) => {
746
- var _effect = _useSignals9();
747
- try {
748
- const Root = asChild ? Slot3 : "div";
749
- const rootProps = asChild ? {
750
- classNames: [
751
- cardContent,
752
- classNames
753
- ]
754
- } : {
755
- className: mx6(cardContent, classNames),
756
- role
757
- };
758
- return /* @__PURE__ */ React9.createElement(Root, {
759
- ...props,
760
- ...rootProps,
761
- ref: forwardedRef
762
- }, children);
763
- } finally {
764
- _effect.f();
765
- }
766
- });
767
- var CardConditionalContent = ({ role, children }) => {
768
- var _effect = _useSignals9();
769
- try {
770
- if ([
771
- "popover",
772
- "card--kanban"
773
- ].includes(role ?? "never")) {
774
- return /* @__PURE__ */ React9.createElement("div", {
775
- className: role === "popover" ? "popover-card-width" : role === "card--kanban" ? "contents" : ""
776
- }, children);
777
- } else {
778
- return /* @__PURE__ */ React9.createElement(CardContent, role === "card--document" && {
779
- classNames: [
780
- "mlb-[1em]",
781
- hoverableControls
782
- ]
783
- }, children);
784
- }
785
- } finally {
786
- _effect.f();
787
- }
788
- };
789
- var CardHeading = /* @__PURE__ */ forwardRef6(({ children, classNames, asChild, role = "heading", ...props }, forwardedRef) => {
790
- var _effect = _useSignals9();
791
- try {
792
- const Root = asChild ? Slot3 : "div";
793
- const rootProps = asChild ? {
794
- classNames: [
795
- cardHeading,
796
- cardText,
797
- classNames
798
- ]
799
- } : {
800
- className: mx6(cardHeading, cardText, classNames),
801
- role
802
- };
803
- return /* @__PURE__ */ React9.createElement(Root, {
804
- ...props,
805
- ...rootProps,
806
- ref: forwardedRef
807
- }, children);
808
- } finally {
809
- _effect.f();
810
- }
811
- });
812
- var CardToolbar = /* @__PURE__ */ forwardRef6(({ children, classNames, ...props }, forwardedRef) => {
813
- var _effect = _useSignals9();
814
- try {
815
- return /* @__PURE__ */ React9.createElement(Toolbar.Root, {
816
- ...props,
817
- classNames: [
818
- "bg-transparent",
819
- classNames
820
- ],
821
- ref: forwardedRef
822
- }, children);
823
- } finally {
824
- _effect.f();
825
- }
826
- });
827
- var CardToolbarIconButton = Toolbar.IconButton;
828
- var CardToolbarSeparator = Toolbar.Separator;
829
- var CardDragHandle = /* @__PURE__ */ forwardRef6(({ toolbarItem }, forwardedRef) => {
830
- var _effect = _useSignals9();
831
- try {
832
- const { t } = useTranslation2(translationKey);
833
- const Root = toolbarItem ? Toolbar.IconButton : IconButton;
834
- return /* @__PURE__ */ React9.createElement(Root, {
835
- iconOnly: true,
836
- icon: "ph--dots-six-vertical--regular",
837
- variant: "ghost",
838
- label: t("card drag handle label"),
839
- classNames: "pli-2",
840
- ref: forwardedRef
841
- });
842
- } finally {
843
- _effect.f();
844
- }
845
- });
846
- var CardDragPreview = StackItem.DragPreview;
847
- var CardMenu = Primitive.div;
848
- var CardPoster = (props) => {
849
- var _effect = _useSignals9();
850
- try {
851
- const aspect = props.aspect === "auto" ? "aspect-auto" : "aspect-video";
852
- if (props.image) {
853
- return /* @__PURE__ */ React9.createElement("img", {
854
- className: `dx-card__poster ${aspect} object-cover is-full bs-auto`,
855
- src: props.image,
856
- alt: props.alt
857
- });
858
- }
859
- if (props.icon) {
860
- return /* @__PURE__ */ React9.createElement("div", {
861
- role: "image",
862
- className: `dx-card__poster grid ${aspect} place-items-center bg-inputSurface text-subdued`,
863
- "aria-label": props.alt
864
- }, /* @__PURE__ */ React9.createElement(Icon2, {
865
- icon: props.icon,
866
- size: 10
867
- }));
868
- }
869
- } finally {
870
- _effect.f();
871
- }
872
- };
873
- var CardChrome = /* @__PURE__ */ forwardRef6(({ children, classNames, asChild, role = "none", ...props }, forwardedRef) => {
874
- var _effect = _useSignals9();
875
- try {
876
- const Root = asChild ? Slot3 : "div";
877
- const rootProps = asChild ? {
878
- classNames: [
879
- cardChrome,
880
- classNames
881
- ]
882
- } : {
883
- className: mx6(cardChrome, classNames),
884
- role
885
- };
886
- return /* @__PURE__ */ React9.createElement(Root, {
887
- ...props,
888
- ...rootProps,
889
- ref: forwardedRef
890
- }, children);
891
- } finally {
892
- _effect.f();
893
- }
894
- });
895
- var CardText = /* @__PURE__ */ forwardRef6(({ children, classNames, asChild, role = "none", ...props }, forwardedRef) => {
896
- var _effect = _useSignals9();
897
- try {
898
- const Root = asChild ? Slot3 : "p";
899
- const rootProps = asChild ? {
900
- classNames: [
901
- cardText,
902
- classNames
903
- ]
904
- } : {
905
- className: mx6(cardText, classNames),
906
- role
907
- };
908
- return /* @__PURE__ */ React9.createElement(Root, {
909
- ...props,
910
- ...rootProps,
911
- ref: forwardedRef
912
- }, children);
913
- } finally {
914
- _effect.f();
915
- }
916
- });
917
- var Card = {
918
- Root: CardRoot,
919
- Content: CardContent,
920
- Container: CardConditionalContent,
921
- Heading: CardHeading,
922
- Toolbar: CardToolbar,
923
- ToolbarIconButton: CardToolbarIconButton,
924
- ToolbarSeparator: CardToolbarSeparator,
925
- DragHandle: CardDragHandle,
926
- DragPreview: CardDragPreview,
927
- Menu: CardMenu,
928
- Poster: CardPoster,
929
- Chrome: CardChrome,
930
- Text: CardText
931
- };
932
-
933
- // packages/ui/react-ui-stack/src/exemplars/Card/CardDragPreview.tsx
934
- import { useSignals as _useSignals10 } from "@preact-signals/safe-react/tracking";
935
- import React10 from "react";
936
- import { mx as mx7 } from "@dxos/react-ui-theme";
937
- var CardDragPreviewRoot = ({ children }) => {
938
- var _effect = _useSignals10();
939
- try {
940
- return /* @__PURE__ */ React10.createElement("div", {
941
- className: "p-2"
942
- }, children);
943
- } finally {
944
- _effect.f();
945
- }
946
- };
947
- var CardDragPreviewContent = ({ children }) => {
948
- var _effect = _useSignals10();
949
- try {
950
- return /* @__PURE__ */ React10.createElement("div", {
951
- className: mx7(cardContent, "ring-focusLine ring-neutralFocusIndicator")
952
- }, children);
953
- } finally {
954
- _effect.f();
955
- }
956
- };
957
- var CardDragPreview2 = {
958
- Root: CardDragPreviewRoot,
959
- Content: CardDragPreviewContent
960
- };
961
-
962
- // packages/ui/react-ui-stack/src/exemplars/CardStack/CardStack.tsx
963
- import { useSignals as _useSignals11 } from "@preact-signals/safe-react/tracking";
964
- import { Slot as Slot4 } from "@radix-ui/react-slot";
965
- import React11, { forwardRef as forwardRef7 } from "react";
966
- import { mx as mx8 } from "@dxos/react-ui-theme";
967
- var CardStackStack = /* @__PURE__ */ forwardRef7(({ children, classNames, itemsCount = 0, ...props }, forwardedRef) => {
968
- var _effect = _useSignals11();
969
- try {
970
- return /* @__PURE__ */ React11.createElement(Stack, {
971
- orientation: "vertical",
972
- size: "contain",
973
- rail: false,
974
- classNames: (
975
- /* NOTE(thure): Do not let this element have zero intrinsic size, otherwise the drop indicator will not display. See #9035. */
976
- [
977
- "plb-1",
978
- itemsCount > 0 && "plb-2",
979
- classNames
980
- ]
981
- ),
982
- itemsCount,
983
- separatorOnScroll: 9,
984
- "data-density": "fine",
985
- ...props,
986
- ref: forwardedRef
987
- }, children);
988
- } finally {
989
- _effect.f();
990
- }
991
- });
992
- var CardStackDragHandle = Card.DragHandle;
993
- var cardStackHeading = "mli-2 order-first bg-transparent rounded-bs-md flex items-center";
994
- var CardStackHeading = /* @__PURE__ */ forwardRef7(({ children, classNames, asChild, role = "heading", ...props }, forwardedRef) => {
995
- var _effect = _useSignals11();
996
- try {
997
- const Root = asChild ? Slot4 : "div";
998
- const rootProps = asChild ? {
999
- classNames: [
1000
- cardStackHeading,
1001
- classNames
1002
- ]
1003
- } : {
1004
- className: mx8(cardStackHeading, classNames),
1005
- role
1006
- };
1007
- return /* @__PURE__ */ React11.createElement(Root, {
1008
- ...props,
1009
- ...rootProps,
1010
- ref: forwardedRef
1011
- }, children);
1012
- } finally {
1013
- _effect.f();
1014
- }
1015
- });
1016
- var cardStackFooter = 'plb-2 mli-2 border-bs border-transparent [[data-scroll-separator-end="true"]_&]:border-subduedSeparator';
1017
- var CardStackFooter = /* @__PURE__ */ forwardRef7(({ children, classNames, asChild, role = "none", ...props }, forwardedRef) => {
1018
- var _effect = _useSignals11();
1019
- try {
1020
- const Root = asChild ? Slot4 : "div";
1021
- const rootProps = asChild ? {
1022
- classNames: [
1023
- cardStackFooter,
1024
- classNames
1025
- ]
1026
- } : {
1027
- className: mx8(cardStackFooter, classNames),
1028
- role
1029
- };
1030
- return /* @__PURE__ */ React11.createElement(Root, {
1031
- ...props,
1032
- ...rootProps,
1033
- ref: forwardedRef
1034
- }, children);
1035
- } finally {
1036
- _effect.f();
1037
- }
1038
- });
1039
- var cardStackContent = [
1040
- "shrink min-bs-0 bg-baseSurface border border-separator rounded-md grid dx-focus-ring-group-x-indicator kanban-drop",
1041
- railGridHorizontalContainFitContent
1042
- ];
1043
- var CardStackContent = /* @__PURE__ */ forwardRef7(({ children, classNames, asChild, role = "none", ...props }, forwardedRef) => {
1044
- var _effect = _useSignals11();
1045
- try {
1046
- const Root = asChild ? Slot4 : "div";
1047
- const rootProps = asChild ? {
1048
- classNames: [
1049
- ...cardStackContent,
1050
- classNames
1051
- ]
1052
- } : {
1053
- className: mx8(...cardStackContent, classNames),
1054
- role
1055
- };
1056
- return /* @__PURE__ */ React11.createElement(Root, {
1057
- ...props,
1058
- ...rootProps,
1059
- "data-scroll-separator": "false",
1060
- ref: forwardedRef
1061
- }, children);
1062
- } finally {
1063
- _effect.f();
1064
- }
1065
- });
1066
- var cardStackRoot = "flex flex-col pli-2 plb-2";
1067
- var CardStackRoot = /* @__PURE__ */ forwardRef7(({ children, classNames, asChild, role = "none", ...props }, forwardedRef) => {
1068
- var _effect = _useSignals11();
1069
- try {
1070
- const Root = asChild ? Slot4 : "div";
1071
- const rootProps = asChild ? {
1072
- classNames: [
1073
- cardStackRoot,
1074
- classNames
1075
- ]
1076
- } : {
1077
- className: mx8(cardStackRoot, classNames),
1078
- role
1079
- };
1080
- return /* @__PURE__ */ React11.createElement(Root, {
1081
- ...props,
1082
- ...rootProps,
1083
- ref: forwardedRef
1084
- }, children);
1085
- } finally {
1086
- _effect.f();
1087
- }
1088
- });
1089
- var CardStack = {
1090
- Root: CardStackRoot,
1091
- Content: CardStackContent,
1092
- Stack: CardStackStack,
1093
- Heading: CardStackHeading,
1094
- Footer: CardStackFooter,
1095
- DragHandle: CardStackDragHandle
1096
- };
1097
-
1098
- // packages/ui/react-ui-stack/src/exemplars/CardStack/CardStackDragPreview.tsx
1099
- import { useSignals as _useSignals12 } from "@preact-signals/safe-react/tracking";
1100
- import React12 from "react";
1101
- import { IconButton as IconButton2, useTranslation as useTranslation3 } from "@dxos/react-ui";
1102
- import { mx as mx9 } from "@dxos/react-ui-theme";
1103
- var CardStackDragPreviewRoot = ({ children }) => {
1104
- var _effect = _useSignals12();
1105
- try {
1106
- return /* @__PURE__ */ React12.createElement("div", {
1107
- className: "p-2"
1108
- }, /* @__PURE__ */ React12.createElement("div", {
1109
- className: "rounded-md max-bs-[calc(100dvh-1rem)] overflow-hidden bg-baseSurface border border-separator ring-focusLine ring-neutralFocusIndicator flex flex-col"
1110
- }, children));
1111
- } finally {
1112
- _effect.f();
1113
- }
1114
- };
1115
- var CardStackDragPreviewHeading = ({ children }) => {
1116
- var _effect = _useSignals12();
1117
- try {
1118
- const { t } = useTranslation3(translationKey);
1119
- return /* @__PURE__ */ React12.createElement("div", {
1120
- className: "flex items-center p-2"
1121
- }, /* @__PURE__ */ React12.createElement(IconButton2, {
1122
- iconOnly: true,
1123
- icon: "ph--dots-six-vertical--regular",
1124
- variant: "ghost",
1125
- label: t("column drag handle label"),
1126
- classNames: "pli-2"
1127
- }), children);
1128
- } finally {
1129
- _effect.f();
1130
- }
1131
- };
1132
- var CardStackDragPreviewContent = ({ children, itemsCount = 0 }) => {
1133
- var _effect = _useSignals12();
1134
- try {
1135
- return /* @__PURE__ */ React12.createElement("div", {
1136
- className: mx9("overflow-y-auto flex-1 pli-2 flex flex-col gap-2", "plb-1", itemsCount > 0 ? "plb-2" : "plb-1")
1137
- }, children);
1138
- } finally {
1139
- _effect.f();
1140
- }
1141
- };
1142
- var CardStackDragPreviewFooter = ({ children }) => {
1143
- var _effect = _useSignals12();
1144
- try {
1145
- return /* @__PURE__ */ React12.createElement("div", {
1146
- className: "p-2 border-t border-separator"
1147
- }, children);
1148
- } finally {
1149
- _effect.f();
1150
- }
1151
- };
1152
- var CardStackDragPreview = {
1153
- Root: CardStackDragPreviewRoot,
1154
- Heading: CardStackDragPreviewHeading,
1155
- Content: CardStackDragPreviewContent,
1156
- Footer: CardStackDragPreviewFooter
919
+ SigilButton: StackItemSigilButton
1157
920
  };
1158
921
  export {
1159
- Card,
1160
- CardDragPreview2 as CardDragPreview,
1161
922
  CardStack,
1162
923
  CardStackDragPreview,
1163
924
  DEFAULT_EXTRINSIC_SIZE,
@@ -1166,28 +927,18 @@ export {
1166
927
  Stack,
1167
928
  StackContext,
1168
929
  StackItem,
1169
- StackItemDragPreview,
1170
930
  autoScrollRootAttributes,
1171
- cardChrome,
1172
- cardContent,
1173
- cardDialogContent,
1174
- cardDialogHeader,
1175
- cardDialogOverflow,
1176
- cardDialogPaddedOverflow,
1177
- cardDialogSearchListRoot,
1178
- cardHeading,
1179
- cardRoot,
1180
- cardSpacing,
1181
931
  cardStackContent,
932
+ cardStackDefaultInlineSizeRem,
1182
933
  cardStackFooter,
1183
934
  cardStackHeading,
935
+ cardStackItem,
1184
936
  cardStackRoot,
1185
- cardText,
1186
- labelSpacing,
1187
937
  railGridHorizontal,
1188
938
  railGridHorizontalContainFitContent,
1189
939
  railGridVertical,
1190
940
  railGridVerticalContainFitContent,
1191
- translations_default as translations
941
+ translationKey,
942
+ translations
1192
943
  };
1193
944
  //# sourceMappingURL=index.mjs.map