@dxos/react-ui-stack 0.8.2-main.fbd8ed0 → 0.8.2-staging.42af850

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 (30) hide show
  1. package/dist/lib/browser/index.mjs +454 -322
  2. package/dist/lib/browser/index.mjs.map +3 -3
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/browser/testing/index.mjs.map +3 -3
  5. package/dist/lib/node/index.cjs +452 -319
  6. package/dist/lib/node/index.cjs.map +3 -3
  7. package/dist/lib/node/meta.json +1 -1
  8. package/dist/lib/node/testing/index.cjs.map +3 -3
  9. package/dist/lib/node-esm/index.mjs +454 -322
  10. package/dist/lib/node-esm/index.mjs.map +3 -3
  11. package/dist/lib/node-esm/meta.json +1 -1
  12. package/dist/lib/node-esm/testing/index.mjs.map +3 -3
  13. package/dist/types/src/components/Stack/Stack.d.ts +2 -0
  14. package/dist/types/src/components/Stack/Stack.d.ts.map +1 -1
  15. package/dist/types/src/components/Stack/Stack.stories.d.ts.map +1 -1
  16. package/dist/types/src/components/StackContext.d.ts +13 -0
  17. package/dist/types/src/components/StackContext.d.ts.map +1 -1
  18. package/dist/types/src/components/StackItem/StackItem.d.ts +12 -3
  19. package/dist/types/src/components/StackItem/StackItem.d.ts.map +1 -1
  20. package/dist/types/src/components/StackItem/StackItemHeading.d.ts.map +1 -1
  21. package/dist/types/src/components/StackItem/StackItemSigil.d.ts.map +1 -1
  22. package/dist/types/src/testing/stack-manager.d.ts.map +1 -1
  23. package/package.json +21 -20
  24. package/src/components/Stack/Stack.stories.tsx +14 -4
  25. package/src/components/Stack/Stack.tsx +34 -3
  26. package/src/components/StackContext.tsx +20 -0
  27. package/src/components/StackItem/StackItem.tsx +87 -10
  28. package/src/components/StackItem/StackItemHeading.tsx +2 -1
  29. package/src/components/StackItem/StackItemSigil.tsx +2 -14
  30. package/src/testing/stack-manager.ts +6 -6
@@ -34,6 +34,7 @@ __export(node_exports, {
34
34
  Stack: () => Stack,
35
35
  StackContext: () => StackContext,
36
36
  StackItem: () => StackItem,
37
+ StackItemDragPreview: () => StackItemDragPreview,
37
38
  autoScrollRootAttributes: () => autoScrollRootAttributes,
38
39
  railGridHorizontal: () => railGridHorizontal,
39
40
  railGridHorizontalContainFitContent: () => railGridHorizontalContainFitContent,
@@ -42,6 +43,7 @@ __export(node_exports, {
42
43
  translations: () => translations_default
43
44
  });
44
45
  module.exports = __toCommonJS(node_exports);
46
+ var import_tracking = require("@preact-signals/safe-react/tracking");
45
47
  var import_react_tabster = require("@fluentui/react-tabster");
46
48
  var import_react_compose_refs = require("@radix-ui/react-compose-refs");
47
49
  var import_react = __toESM(require("react"));
@@ -53,33 +55,41 @@ var import_element = require("@atlaskit/pragmatic-drag-and-drop-auto-scroll/elem
53
55
  var import_closest_edge = require("@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge");
54
56
  var import_react2 = require("react");
55
57
  var import_react3 = require("react");
58
+ var import_tracking2 = require("@preact-signals/safe-react/tracking");
56
59
  var import_combine2 = require("@atlaskit/pragmatic-drag-and-drop/combine");
57
60
  var import_adapter2 = require("@atlaskit/pragmatic-drag-and-drop/element/adapter");
58
61
  var import_preserve_offset_on_source = require("@atlaskit/pragmatic-drag-and-drop/element/preserve-offset-on-source");
59
- var import_scroll_just_enough_into_view = require("@atlaskit/pragmatic-drag-and-drop/element/scroll-just-enough-into-view");
62
+ var import_set_custom_native_drag_preview = require("@atlaskit/pragmatic-drag-and-drop/element/set-custom-native-drag-preview");
60
63
  var import_closest_edge2 = require("@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge");
61
64
  var import_react_tabster2 = require("@fluentui/react-tabster");
62
65
  var import_react_compose_refs2 = require("@radix-ui/react-compose-refs");
63
66
  var import_react4 = __toESM(require("react"));
67
+ var import_react_dom = require("react-dom");
64
68
  var import_react_ui2 = require("@dxos/react-ui");
65
69
  var import_react_ui_dnd = require("@dxos/react-ui-dnd");
66
70
  var import_react_ui_theme2 = require("@dxos/react-ui-theme");
71
+ var import_tracking3 = require("@preact-signals/safe-react/tracking");
67
72
  var import_react5 = __toESM(require("react"));
68
73
  var import_react_ui_theme3 = require("@dxos/react-ui-theme");
74
+ var import_tracking4 = require("@preact-signals/safe-react/tracking");
69
75
  var import_react_slot = require("@radix-ui/react-slot");
70
76
  var import_react6 = __toESM(require("react"));
77
+ var import_tracking5 = require("@preact-signals/safe-react/tracking");
71
78
  var import_react_tabster3 = require("@fluentui/react-tabster");
72
79
  var import_react7 = __toESM(require("react"));
73
80
  var import_react_ui_attention = require("@dxos/react-ui-attention");
74
81
  var import_react_ui_theme4 = require("@dxos/react-ui-theme");
82
+ var import_tracking6 = require("@preact-signals/safe-react/tracking");
75
83
  var import_react8 = __toESM(require("react"));
76
84
  var import_react_ui_dnd2 = require("@dxos/react-ui-dnd");
85
+ var import_tracking7 = require("@preact-signals/safe-react/tracking");
77
86
  var import_react9 = __toESM(require("react"));
78
87
  var import_keyboard = require("@dxos/keyboard");
79
88
  var import_react_ui3 = require("@dxos/react-ui");
80
89
  var import_react_ui_attention2 = require("@dxos/react-ui-attention");
81
90
  var import_react_ui_theme5 = require("@dxos/react-ui-theme");
82
91
  var import_util = require("@dxos/util");
92
+ var import_tracking8 = require("@preact-signals/safe-react/tracking");
83
93
  var import_react10 = __toESM(require("react"));
84
94
  var useStackDropForElements = ({ id, element, selfDroppable, orientation, onRearrange }) => {
85
95
  const [dropping, setDropping] = (0, import_react2.useState)(false);
@@ -142,11 +152,17 @@ var StackContext = /* @__PURE__ */ (0, import_react3.createContext)({
142
152
  size: "intrinsic"
143
153
  });
144
154
  var useStack = () => (0, import_react3.useContext)(StackContext);
155
+ var idle = {
156
+ type: "idle"
157
+ };
145
158
  var StackItemContext = /* @__PURE__ */ (0, import_react3.createContext)({
146
159
  selfDragHandleRef: () => {
147
160
  },
148
161
  size: "min-content",
149
162
  setSize: () => {
163
+ },
164
+ state: idle,
165
+ setState: () => {
150
166
  }
151
167
  });
152
168
  var useStackItem = () => (0, import_react3.useContext)(StackItemContext);
@@ -157,141 +173,197 @@ var railGridVerticalContainFitContent = "grid-cols-[[rail-start]_var(--rail-size
157
173
  var autoScrollRootAttributes = {
158
174
  "data-drag-autoscroll": "idle"
159
175
  };
160
- var Stack = /* @__PURE__ */ (0, import_react.forwardRef)(({ children, classNames, style, orientation = "vertical", rail = true, size = "intrinsic", onRearrange, itemsCount = import_react.Children.count(children), ...props }, forwardedRef) => {
161
- const [stackElement, stackRef] = (0, import_react.useState)(null);
162
- const composedItemRef = (0, import_react_compose_refs.composeRefs)(stackRef, forwardedRef);
163
- const arrowNavigationAttrs = (0, import_react_tabster.useArrowNavigationGroup)({
164
- axis: orientation
165
- });
166
- const styles = {
167
- [orientation === "horizontal" ? "gridTemplateColumns" : "gridTemplateRows"]: `repeat(${itemsCount}, min-content) [tabster-dummies] 0`,
168
- ...style
169
- };
170
- const selfDroppable = !!(itemsCount < 1 && onRearrange && props.id);
171
- const { dropping } = useStackDropForElements({
172
- id: props.id,
173
- element: stackElement,
174
- selfDroppable,
175
- orientation,
176
- onRearrange
177
- });
178
- const gridClasses = (0, import_react.useMemo)(() => {
179
- if (!rail) {
180
- return orientation === "horizontal" ? "grid-rows-1 pli-1" : "grid-cols-1 plb-1";
181
- }
182
- if (orientation === "horizontal") {
183
- return size === "contain-fit-content" ? railGridHorizontalContainFitContent : railGridHorizontal;
184
- } else {
185
- return size === "contain-fit-content" ? railGridVerticalContainFitContent : railGridVertical;
186
- }
187
- }, [
188
- rail,
189
- orientation,
190
- size
191
- ]);
192
- return /* @__PURE__ */ import_react.default.createElement(StackContext.Provider, {
193
- value: {
176
+ var Stack = /* @__PURE__ */ (0, import_react.forwardRef)(({ children, classNames, style, orientation = "vertical", rail = true, size = "intrinsic", onRearrange, itemsCount = import_react.Children.count(children), getDropElement, separatorOnScroll, ...props }, forwardedRef) => {
177
+ var _effect = (0, import_tracking.useSignals)();
178
+ try {
179
+ const [stackElement, stackRef] = (0, import_react.useState)(null);
180
+ const composedItemRef = (0, import_react_compose_refs.composeRefs)(stackRef, forwardedRef);
181
+ const arrowNavigationAttrs = (0, import_react_tabster.useArrowNavigationGroup)({
182
+ axis: orientation
183
+ });
184
+ const styles = {
185
+ [orientation === "horizontal" ? "gridTemplateColumns" : "gridTemplateRows"]: `repeat(${itemsCount}, min-content) [tabster-dummies] 0`,
186
+ ...style
187
+ };
188
+ const selfDroppable = !!(itemsCount < 1 && onRearrange && props.id);
189
+ const { dropping } = useStackDropForElements({
190
+ id: props.id,
191
+ element: getDropElement && stackElement ? getDropElement(stackElement) : stackElement,
192
+ selfDroppable,
194
193
  orientation,
195
- rail,
196
- size,
197
194
  onRearrange
198
- }
199
- }, /* @__PURE__ */ import_react.default.createElement("div", {
200
- ...props,
201
- ...arrowNavigationAttrs,
202
- className: (0, import_react_ui_theme.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),
203
- "data-rail": rail,
204
- "aria-orientation": orientation,
205
- style: styles,
206
- ref: composedItemRef
207
- }, children, selfDroppable && dropping && /* @__PURE__ */ import_react.default.createElement(import_react_ui.ListItem.DropIndicator, {
208
- lineInset: 8,
209
- terminalInset: -8,
210
- gap: -8,
211
- edge: orientation === "horizontal" ? "left" : "top"
212
- })));
195
+ });
196
+ const handleScroll = (0, import_react.useCallback)(() => {
197
+ if (stackElement && Number.isFinite(separatorOnScroll)) {
198
+ const scrollPosition = orientation === "horizontal" ? stackElement.scrollLeft : stackElement.scrollTop;
199
+ const scrollSize = orientation === "horizontal" ? stackElement.scrollWidth : stackElement.scrollHeight;
200
+ const clientSize = orientation === "horizontal" ? stackElement.clientWidth : stackElement.clientHeight;
201
+ const separatorHost = stackElement.closest("[data-scroll-separator]");
202
+ if (separatorHost) {
203
+ separatorHost.setAttribute("data-scroll-separator", String(scrollPosition > separatorOnScroll));
204
+ separatorHost.setAttribute("data-scroll-separator-end", String(scrollSize - (scrollPosition + clientSize) > separatorOnScroll));
205
+ }
206
+ }
207
+ }, [
208
+ stackElement,
209
+ separatorOnScroll,
210
+ orientation
211
+ ]);
212
+ const gridClasses = (0, import_react.useMemo)(() => {
213
+ if (!rail) {
214
+ return orientation === "horizontal" ? "grid-rows-1 pli-1" : "grid-cols-1 plb-1";
215
+ }
216
+ if (orientation === "horizontal") {
217
+ return size === "contain-fit-content" ? railGridHorizontalContainFitContent : railGridHorizontal;
218
+ } else {
219
+ return size === "contain-fit-content" ? railGridVerticalContainFitContent : railGridVertical;
220
+ }
221
+ }, [
222
+ rail,
223
+ orientation,
224
+ size
225
+ ]);
226
+ return /* @__PURE__ */ import_react.default.createElement(StackContext.Provider, {
227
+ value: {
228
+ orientation,
229
+ rail,
230
+ size,
231
+ onRearrange
232
+ }
233
+ }, /* @__PURE__ */ import_react.default.createElement("div", {
234
+ ...props,
235
+ ...arrowNavigationAttrs,
236
+ className: (0, import_react_ui_theme.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),
237
+ "data-rail": rail,
238
+ "aria-orientation": orientation,
239
+ style: styles,
240
+ ref: composedItemRef,
241
+ ...Number.isFinite(separatorOnScroll) && {
242
+ onScroll: handleScroll
243
+ }
244
+ }, children, selfDroppable && dropping && /* @__PURE__ */ import_react.default.createElement(import_react_ui.ListItem.DropIndicator, {
245
+ lineInset: 8,
246
+ terminalInset: -8,
247
+ gap: -8,
248
+ edge: orientation === "horizontal" ? "left" : "top"
249
+ })));
250
+ } finally {
251
+ _effect.f();
252
+ }
213
253
  });
214
254
  var StackItemContent = /* @__PURE__ */ (0, import_react5.forwardRef)(({ children, toolbar, statusbar, classNames, size = "intrinsic", ...props }, forwardedRef) => {
215
- const { size: stackItemSize } = useStack();
216
- return /* @__PURE__ */ import_react5.default.createElement("div", {
217
- role: "none",
218
- ...props,
219
- className: (0, import_react_ui_theme3.mx)("group grid grid-cols-[100%]", stackItemSize === "contain" && "min-bs-0 overflow-hidden", size === "video" ? "aspect-video" : size === "square" && "aspect-square", classNames),
220
- style: {
221
- gridTemplateRows: [
222
- ...toolbar ? [
223
- "var(--rail-action)"
224
- ] : [],
225
- "1fr",
226
- ...statusbar ? [
227
- "var(--statusbar-size)"
228
- ] : []
229
- ].join(" ")
230
- },
231
- "data-popover-collision-boundary": true,
232
- ref: forwardedRef
233
- }, children);
255
+ var _effect = (0, import_tracking3.useSignals)();
256
+ try {
257
+ const { size: stackItemSize } = useStack();
258
+ return /* @__PURE__ */ import_react5.default.createElement("div", {
259
+ role: "none",
260
+ ...props,
261
+ className: (0, import_react_ui_theme3.mx)("group grid grid-cols-[100%]", stackItemSize === "contain" && "min-bs-0 overflow-hidden", size === "video" ? "aspect-video" : size === "square" && "aspect-square", classNames),
262
+ style: {
263
+ gridTemplateRows: [
264
+ ...toolbar ? [
265
+ "var(--rail-action)"
266
+ ] : [],
267
+ "1fr",
268
+ ...statusbar ? [
269
+ "var(--statusbar-size)"
270
+ ] : []
271
+ ].join(" ")
272
+ },
273
+ "data-popover-collision-boundary": true,
274
+ ref: forwardedRef
275
+ }, children);
276
+ } finally {
277
+ _effect.f();
278
+ }
234
279
  });
235
280
  var StackItemDragHandle = ({ asChild, children }) => {
236
- const { selfDragHandleRef } = useStackItem();
237
- const Root = asChild ? import_react_slot.Slot : "div";
238
- return /* @__PURE__ */ import_react6.default.createElement(Root, {
239
- ref: selfDragHandleRef,
240
- role: "button"
241
- }, children);
281
+ var _effect = (0, import_tracking4.useSignals)();
282
+ try {
283
+ const { selfDragHandleRef } = useStackItem();
284
+ const Root = asChild ? import_react_slot.Slot : "div";
285
+ return /* @__PURE__ */ import_react6.default.createElement(Root, {
286
+ ref: selfDragHandleRef,
287
+ role: "button"
288
+ }, children);
289
+ } finally {
290
+ _effect.f();
291
+ }
242
292
  };
243
293
  var StackItemHeading = ({ children, classNames, ...props }) => {
244
- const { orientation } = useStack();
245
- const focusableGroupAttrs = (0, import_react_tabster3.useFocusableGroup)({
246
- tabBehavior: "limited"
247
- });
248
- return /* @__PURE__ */ import_react7.default.createElement("div", {
249
- role: "heading",
250
- ...props,
251
- tabIndex: 0,
252
- ...focusableGroupAttrs,
253
- className: (0, import_react_ui_theme4.mx)("flex items-center dx-focus-ring-inset-over-all relative !border-is-0 bg-headerSurface", orientation === "horizontal" ? "bs-[--rail-size]" : "is-[--rail-size] flex-col", classNames)
254
- }, children);
294
+ var _effect = (0, import_tracking5.useSignals)();
295
+ try {
296
+ const { orientation } = useStack();
297
+ const focusableGroupAttrs = (0, import_react_tabster3.useFocusableGroup)({
298
+ tabBehavior: "limited"
299
+ });
300
+ return /* @__PURE__ */ import_react7.default.createElement("div", {
301
+ role: "heading",
302
+ ...props,
303
+ tabIndex: 0,
304
+ ...focusableGroupAttrs,
305
+ className: (0, import_react_ui_theme4.mx)('flex items-center dx-focus-ring-inset-over-all relative !border-is-0 bg-headerSurface border-transparent [[data-scroll-separator="true"]_&]:border-subduedSeparator', orientation === "horizontal" ? "bs-[--rail-size]" : "is-[--rail-size] flex-col", orientation === "horizontal" ? "border-be" : "border-ie", classNames)
306
+ }, children);
307
+ } finally {
308
+ _effect.f();
309
+ }
255
310
  };
256
311
  var StackItemHeadingLabel = /* @__PURE__ */ (0, import_react7.forwardRef)(({ attendableId, related, classNames, ...props }, forwardedRef) => {
257
- const { hasAttention, isAncestor, isRelated } = (0, import_react_ui_attention.useAttention)(attendableId);
258
- return /* @__PURE__ */ import_react7.default.createElement("h1", {
259
- ...props,
260
- "data-attention": (related && isRelated || hasAttention || isAncestor).toString(),
261
- className: (0, import_react_ui_theme4.mx)("pli-1 min-is-0 is-0 grow truncate font-medium text-baseText data-[attention=true]:text-accentText self-center", classNames),
262
- ref: forwardedRef
263
- });
312
+ var _effect = (0, import_tracking5.useSignals)();
313
+ try {
314
+ const { hasAttention, isAncestor, isRelated } = (0, import_react_ui_attention.useAttention)(attendableId);
315
+ return /* @__PURE__ */ import_react7.default.createElement("h1", {
316
+ ...props,
317
+ "data-attention": (related && isRelated || hasAttention || isAncestor).toString(),
318
+ className: (0, import_react_ui_theme4.mx)("pli-1 min-is-0 is-0 grow truncate font-medium text-baseText data-[attention=true]:text-accentText self-center", classNames),
319
+ ref: forwardedRef
320
+ });
321
+ } finally {
322
+ _effect.f();
323
+ }
264
324
  });
265
325
  var MIN_WIDTH = 20;
266
326
  var MIN_HEIGHT = 3;
267
327
  var StackItemResizeHandle = () => {
268
- const { orientation } = useStack();
269
- const { setSize, size } = useStackItem();
270
- return /* @__PURE__ */ import_react8.default.createElement(import_react_ui_dnd2.ResizeHandle, {
271
- side: orientation === "horizontal" ? "inline-end" : "block-end",
272
- fallbackSize: DEFAULT_EXTRINSIC_SIZE,
273
- minSize: orientation === "horizontal" ? MIN_WIDTH : MIN_HEIGHT,
274
- size,
275
- onSizeChange: setSize
276
- });
328
+ var _effect = (0, import_tracking6.useSignals)();
329
+ try {
330
+ const { orientation } = useStack();
331
+ const { setSize, size } = useStackItem();
332
+ return /* @__PURE__ */ import_react8.default.createElement(import_react_ui_dnd2.ResizeHandle, {
333
+ side: orientation === "horizontal" ? "inline-end" : "block-end",
334
+ fallbackSize: DEFAULT_EXTRINSIC_SIZE,
335
+ minSize: orientation === "horizontal" ? MIN_WIDTH : MIN_HEIGHT,
336
+ size,
337
+ onSizeChange: setSize
338
+ });
339
+ } finally {
340
+ _effect.f();
341
+ }
342
+ };
343
+ var MenuSignifierHorizontal = () => {
344
+ var _effect = (0, import_tracking8.useSignals)();
345
+ try {
346
+ return /* @__PURE__ */ import_react10.default.createElement("svg", {
347
+ className: "absolute block-end-[7px]",
348
+ width: 20,
349
+ height: 2,
350
+ viewBox: "0 0 20 2",
351
+ stroke: "currentColor",
352
+ opacity: 0.5
353
+ }, /* @__PURE__ */ import_react10.default.createElement("line", {
354
+ x1: 0.5,
355
+ y1: 0.75,
356
+ x2: 19,
357
+ y2: 0.75,
358
+ strokeWidth: 1.25,
359
+ strokeLinecap: "round",
360
+ strokeDasharray: "6 20",
361
+ strokeDashoffset: "-6.5"
362
+ }));
363
+ } finally {
364
+ _effect.f();
365
+ }
277
366
  };
278
- var MenuSignifierHorizontal = () => /* @__PURE__ */ import_react10.default.createElement("svg", {
279
- className: "absolute block-end-[7px]",
280
- width: 20,
281
- height: 2,
282
- viewBox: "0 0 20 2",
283
- stroke: "currentColor",
284
- opacity: 0.5
285
- }, /* @__PURE__ */ import_react10.default.createElement("line", {
286
- x1: 0.5,
287
- y1: 0.75,
288
- x2: 19,
289
- y2: 0.75,
290
- strokeWidth: 1.25,
291
- strokeLinecap: "round",
292
- strokeDasharray: "6 20",
293
- strokeDashoffset: "-6.5"
294
- }));
295
367
  var translationKey = "stack";
296
368
  var translations_default = [
297
369
  {
@@ -309,219 +381,278 @@ var translations_default = [
309
381
  }
310
382
  ];
311
383
  var StackItemSigilButton = /* @__PURE__ */ (0, import_react9.forwardRef)(({ attendableId, classNames, related, isMenu = true, children, ...props }, forwardedRef) => {
312
- const { hasAttention, isAncestor, isRelated } = (0, import_react_ui_attention2.useAttention)(attendableId);
313
- const variant = related && isRelated || hasAttention || isAncestor ? "primary" : "ghost";
314
- return /* @__PURE__ */ import_react9.default.createElement(import_react_ui3.Button, {
315
- ...props,
316
- variant,
317
- classNames: [
318
- "shrink-0 pli-0 min-bs-0 is-[--rail-action] bs-[--rail-action] relative app-no-drag",
319
- classNames
320
- ],
321
- ref: forwardedRef
322
- }, isMenu && /* @__PURE__ */ import_react9.default.createElement(MenuSignifierHorizontal, null), children);
384
+ var _effect = (0, import_tracking7.useSignals)();
385
+ try {
386
+ const { hasAttention, isAncestor, isRelated } = (0, import_react_ui_attention2.useAttention)(attendableId);
387
+ const variant = related && isRelated || hasAttention || isAncestor ? "primary" : "ghost";
388
+ return /* @__PURE__ */ import_react9.default.createElement(import_react_ui3.Button, {
389
+ ...props,
390
+ variant,
391
+ classNames: [
392
+ "shrink-0 pli-0 min-bs-0 is-[--rail-action] bs-[--rail-action] relative app-no-drag",
393
+ classNames
394
+ ],
395
+ ref: forwardedRef
396
+ }, isMenu && /* @__PURE__ */ import_react9.default.createElement(MenuSignifierHorizontal, null), children);
397
+ } finally {
398
+ _effect.f();
399
+ }
323
400
  });
324
401
  var StackItemSigil = /* @__PURE__ */ (0, import_react9.forwardRef)(({ actions: actionGroups, onAction, triggerLabel, attendableId, icon, related, children }, forwardedRef) => {
325
- const { t } = (0, import_react_ui3.useTranslation)(translationKey);
326
- const suppressNextTooltip = (0, import_react9.useRef)(false);
327
- const [optionsMenuOpen, setOptionsMenuOpen] = (0, import_react9.useState)(false);
328
- const hasActions = actionGroups && actionGroups.length > 0;
329
- const button = /* @__PURE__ */ import_react9.default.createElement(StackItemSigilButton, {
330
- attendableId,
331
- related,
332
- isMenu: hasActions,
333
- // TODO(wittjosiah): Better disabling of interactive styles when no action are available.
334
- // Remove underscore icon when no actions are available?
335
- classNames: !hasActions && "cursor-default"
336
- }, /* @__PURE__ */ import_react9.default.createElement("span", {
337
- className: "sr-only"
338
- }, triggerLabel), /* @__PURE__ */ import_react9.default.createElement(import_react_ui3.Icon, {
339
- icon,
340
- size: 5
341
- }));
342
- if (!hasActions) {
343
- return button;
344
- }
345
- return /* @__PURE__ */ import_react9.default.createElement(import_react_ui3.DropdownMenu.Root, {
346
- open: optionsMenuOpen,
347
- onOpenChange: (nextOpen) => {
348
- if (!nextOpen) {
349
- suppressNextTooltip.current = true;
350
- }
351
- return setOptionsMenuOpen(nextOpen);
402
+ var _effect = (0, import_tracking7.useSignals)();
403
+ try {
404
+ const { t } = (0, import_react_ui3.useTranslation)(translationKey);
405
+ const [optionsMenuOpen, setOptionsMenuOpen] = (0, import_react9.useState)(false);
406
+ const hasActions = actionGroups && actionGroups.length > 0;
407
+ const button = /* @__PURE__ */ import_react9.default.createElement(StackItemSigilButton, {
408
+ attendableId,
409
+ related,
410
+ isMenu: hasActions,
411
+ // TODO(wittjosiah): Better disabling of interactive styles when no action are available.
412
+ // Remove underscore icon when no actions are available?
413
+ classNames: !hasActions && "cursor-default"
414
+ }, /* @__PURE__ */ import_react9.default.createElement("span", {
415
+ className: "sr-only"
416
+ }, triggerLabel), /* @__PURE__ */ import_react9.default.createElement(import_react_ui3.Icon, {
417
+ icon,
418
+ size: 5
419
+ }));
420
+ if (!hasActions) {
421
+ return button;
352
422
  }
353
- }, /* @__PURE__ */ import_react9.default.createElement(import_react_ui3.DropdownMenu.Trigger, {
354
- asChild: true,
355
- ref: forwardedRef
356
- }, button), /* @__PURE__ */ import_react9.default.createElement(import_react_ui3.DropdownMenu.Portal, null, /* @__PURE__ */ import_react9.default.createElement(import_react_ui3.DropdownMenu.Content, {
357
- classNames: "z-[31]"
358
- }, /* @__PURE__ */ import_react9.default.createElement(import_react_ui3.DropdownMenu.Viewport, null, actionGroups?.map((actions, index) => {
359
- const separator = index > 0 ? /* @__PURE__ */ import_react9.default.createElement(import_react_ui3.DropdownMenu.Separator, null) : null;
360
- return /* @__PURE__ */ import_react9.default.createElement(import_react9.Fragment, {
361
- key: index
362
- }, separator, actions.map((action) => {
363
- const shortcut = typeof action.properties.keyBinding === "string" ? action.properties.keyBinding : action.properties.keyBinding?.[(0, import_util.getHostPlatform)()];
364
- const menuItemType = action.properties.menuItemType;
365
- const Root = menuItemType === "toggle" ? import_react_ui3.DropdownMenu.CheckboxItem : import_react_ui3.DropdownMenu.Item;
366
- return /* @__PURE__ */ import_react9.default.createElement(Root, {
367
- key: action.id,
368
- onClick: (event) => {
369
- if (action.properties.disabled) {
370
- return;
423
+ return /* @__PURE__ */ import_react9.default.createElement(import_react_ui3.DropdownMenu.Root, {
424
+ open: optionsMenuOpen,
425
+ onOpenChange: setOptionsMenuOpen
426
+ }, /* @__PURE__ */ import_react9.default.createElement(import_react_ui3.DropdownMenu.Trigger, {
427
+ asChild: true,
428
+ ref: forwardedRef
429
+ }, button), /* @__PURE__ */ import_react9.default.createElement(import_react_ui3.DropdownMenu.Portal, null, /* @__PURE__ */ import_react9.default.createElement(import_react_ui3.DropdownMenu.Content, {
430
+ classNames: "z-[31]"
431
+ }, /* @__PURE__ */ import_react9.default.createElement(import_react_ui3.DropdownMenu.Viewport, null, actionGroups?.map((actions, index) => {
432
+ const separator = index > 0 ? /* @__PURE__ */ import_react9.default.createElement(import_react_ui3.DropdownMenu.Separator, null) : null;
433
+ return /* @__PURE__ */ import_react9.default.createElement(import_react9.Fragment, {
434
+ key: index
435
+ }, separator, actions.map((action) => {
436
+ const shortcut = typeof action.properties.keyBinding === "string" ? action.properties.keyBinding : action.properties.keyBinding?.[(0, import_util.getHostPlatform)()];
437
+ const menuItemType = action.properties.menuItemType;
438
+ const Root = menuItemType === "toggle" ? import_react_ui3.DropdownMenu.CheckboxItem : import_react_ui3.DropdownMenu.Item;
439
+ return /* @__PURE__ */ import_react9.default.createElement(Root, {
440
+ key: action.id,
441
+ onClick: (event) => {
442
+ if (action.properties.disabled) {
443
+ return;
444
+ }
445
+ event.stopPropagation();
446
+ setOptionsMenuOpen(false);
447
+ onAction?.(action);
448
+ },
449
+ classNames: "gap-2",
450
+ disabled: action.properties.disabled,
451
+ checked: menuItemType === "toggle" ? action.properties.isChecked : void 0,
452
+ ...action.properties?.testId && {
453
+ "data-testid": action.properties.testId
371
454
  }
372
- event.stopPropagation();
373
- suppressNextTooltip.current = true;
374
- setOptionsMenuOpen(false);
375
- onAction?.(action);
376
- },
377
- classNames: "gap-2",
378
- disabled: action.properties.disabled,
379
- checked: menuItemType === "toggle" ? action.properties.isChecked : void 0,
380
- ...action.properties?.testId && {
381
- "data-testid": action.properties.testId
382
- }
383
- }, /* @__PURE__ */ import_react9.default.createElement(import_react_ui3.Icon, {
384
- icon: action.properties.icon ?? "ph--placeholder--regular",
385
- size: 4
386
- }), /* @__PURE__ */ import_react9.default.createElement("span", {
387
- className: "grow truncate"
388
- }, (0, import_react_ui3.toLocalizedString)(action.properties.label ?? "", t)), menuItemType === "toggle" && /* @__PURE__ */ import_react9.default.createElement(import_react_ui3.DropdownMenu.ItemIndicator, {
389
- asChild: true
390
- }, /* @__PURE__ */ import_react9.default.createElement(import_react_ui3.Icon, {
391
- icon: "ph--check--regular",
392
- size: 4
393
- })), shortcut && /* @__PURE__ */ import_react9.default.createElement("span", {
394
- className: (0, import_react_ui_theme5.mx)("shrink-0", import_react_ui_theme5.descriptionText)
395
- }, (0, import_keyboard.keySymbols)(shortcut).join("")));
396
- }));
397
- }), children), /* @__PURE__ */ import_react9.default.createElement(import_react_ui3.DropdownMenu.Arrow, null))));
455
+ }, /* @__PURE__ */ import_react9.default.createElement(import_react_ui3.Icon, {
456
+ icon: action.properties.icon ?? "ph--placeholder--regular",
457
+ size: 4
458
+ }), /* @__PURE__ */ import_react9.default.createElement("span", {
459
+ className: "grow truncate"
460
+ }, (0, import_react_ui3.toLocalizedString)(action.properties.label ?? "", t)), menuItemType === "toggle" && /* @__PURE__ */ import_react9.default.createElement(import_react_ui3.DropdownMenu.ItemIndicator, {
461
+ asChild: true
462
+ }, /* @__PURE__ */ import_react9.default.createElement(import_react_ui3.Icon, {
463
+ icon: "ph--check--regular",
464
+ size: 4
465
+ })), shortcut && /* @__PURE__ */ import_react9.default.createElement("span", {
466
+ className: (0, import_react_ui_theme5.mx)("shrink-0", import_react_ui_theme5.descriptionText)
467
+ }, (0, import_keyboard.keySymbols)(shortcut).join("")));
468
+ }));
469
+ }), children), /* @__PURE__ */ import_react9.default.createElement(import_react_ui3.DropdownMenu.Arrow, null))));
470
+ } finally {
471
+ _effect.f();
472
+ }
398
473
  });
399
474
  var DEFAULT_HORIZONTAL_SIZE = 48;
400
475
  var DEFAULT_VERTICAL_SIZE = "min-content";
401
476
  var DEFAULT_EXTRINSIC_SIZE = DEFAULT_HORIZONTAL_SIZE;
402
- var StackItemRoot = /* @__PURE__ */ (0, import_react4.forwardRef)(({ item, children, classNames, size: propsSize, onSizeChange, role, order, style, disableRearrange, focusIndicatorVariant = "over-all", ...props }, forwardedRef) => {
403
- const [itemElement, itemRef] = (0, import_react4.useState)(null);
404
- const [selfDragHandleElement, selfDragHandleRef] = (0, import_react4.useState)(null);
405
- const [closestEdge, setEdge] = (0, import_react4.useState)(null);
406
- const { orientation, rail, onRearrange } = useStack();
407
- const [size = orientation === "horizontal" ? DEFAULT_HORIZONTAL_SIZE : DEFAULT_VERTICAL_SIZE, setInternalSize] = (0, import_react4.useState)(propsSize);
408
- const Root = role ?? "div";
409
- const composedItemRef = (0, import_react_compose_refs2.composeRefs)(itemRef, forwardedRef);
410
- const setSize = (0, import_react4.useCallback)((nextSize, commit) => {
411
- setInternalSize(nextSize);
412
- if (commit) {
413
- onSizeChange?.(nextSize);
414
- }
415
- }, [
416
- onSizeChange
417
- ]);
418
- const type = orientation === "horizontal" ? "column" : "card";
419
- (0, import_react4.useLayoutEffect)(() => {
420
- if (!itemElement || !onRearrange || disableRearrange) {
421
- return;
422
- }
423
- return (0, import_combine2.combine)((0, import_adapter2.draggable)({
424
- element: itemElement,
425
- ...selfDragHandleElement && {
426
- dragHandle: selfDragHandleElement
427
- },
428
- getInitialData: () => ({
429
- id: item.id,
430
- type
431
- }),
432
- onGenerateDragPreview: ({ nativeSetDragImage, source, location }) => {
433
- document.body.setAttribute("data-drag-preview", "true");
434
- (0, import_scroll_just_enough_into_view.scrollJustEnoughIntoView)({
435
- element: source.element
436
- });
437
- const { x, y } = (0, import_preserve_offset_on_source.preserveOffsetOnSource)({
438
- element: source.element,
439
- input: location.current.input
440
- })({
441
- container: source.element.offsetParent ?? document.body
442
- });
443
- nativeSetDragImage?.(source.element, x, y);
444
- },
445
- onDragStart: () => {
446
- document.body.removeAttribute("data-drag-preview");
447
- itemElement?.closest("[data-drag-autoscroll]")?.setAttribute("data-drag-autoscroll", "active");
448
- },
449
- onDrop: () => {
450
- itemElement?.closest("[data-drag-autoscroll]")?.setAttribute("data-drag-autoscroll", "idle");
477
+ var StackItemRoot = /* @__PURE__ */ (0, import_react4.forwardRef)(({ item, children, classNames, size: propsSize, onSizeChange, role, order, prevSiblingId, nextSiblingId, style, disableRearrange, focusIndicatorVariant = "over-all", ...props }, forwardedRef) => {
478
+ var _effect = (0, import_tracking2.useSignals)();
479
+ try {
480
+ const [itemElement, itemRef] = (0, import_react4.useState)(null);
481
+ const [selfDragHandleElement, selfDragHandleRef] = (0, import_react4.useState)(null);
482
+ const [closestEdge, setEdge] = (0, import_react4.useState)(null);
483
+ const [sourceId, setSourceId] = (0, import_react4.useState)(null);
484
+ const [dragState, setDragState] = (0, import_react4.useState)(idle);
485
+ const { orientation, rail, onRearrange } = useStack();
486
+ const [size = orientation === "horizontal" ? DEFAULT_HORIZONTAL_SIZE : DEFAULT_VERTICAL_SIZE, setInternalSize] = (0, import_react4.useState)(propsSize);
487
+ const Root = role ?? "div";
488
+ const composedItemRef = (0, import_react_compose_refs2.composeRefs)(itemRef, forwardedRef);
489
+ const setSize = (0, import_react4.useCallback)((nextSize, commit) => {
490
+ setInternalSize(nextSize);
491
+ if (commit) {
492
+ onSizeChange?.(nextSize);
493
+ }
494
+ }, [
495
+ onSizeChange
496
+ ]);
497
+ const type = orientation === "horizontal" ? "column" : "card";
498
+ (0, import_react4.useLayoutEffect)(() => {
499
+ if (!itemElement || !onRearrange || disableRearrange) {
500
+ return;
451
501
  }
452
- }), (0, import_adapter2.dropTargetForElements)({
453
- element: itemElement,
454
- getData: ({ input, element }) => {
455
- return (0, import_closest_edge2.attachClosestEdge)({
502
+ return (0, import_combine2.combine)((0, import_adapter2.draggable)({
503
+ element: itemElement,
504
+ ...selfDragHandleElement && {
505
+ dragHandle: selfDragHandleElement
506
+ },
507
+ getInitialData: () => ({
456
508
  id: item.id,
457
509
  type
458
- }, {
459
- input,
460
- element,
461
- allowedEdges: orientation === "horizontal" ? [
462
- "left",
463
- "right"
464
- ] : [
465
- "top",
466
- "bottom"
467
- ]
468
- });
469
- },
470
- onDragEnter: ({ self, source }) => {
471
- if (source.data.type === self.data.type) {
472
- setEdge((0, import_closest_edge2.extractClosestEdge)(self.data));
473
- }
474
- },
475
- onDrag: ({ self, source }) => {
476
- if (source.data.type === self.data.type) {
477
- setEdge((0, import_closest_edge2.extractClosestEdge)(self.data));
510
+ }),
511
+ onGenerateDragPreview: ({ nativeSetDragImage, source, location }) => {
512
+ document.body.setAttribute("data-drag-preview", "true");
513
+ const offsetFn = (0, import_preserve_offset_on_source.preserveOffsetOnSource)({
514
+ element: source.element,
515
+ input: location.current.input
516
+ });
517
+ const rect = source.element.getBoundingClientRect();
518
+ (0, import_set_custom_native_drag_preview.setCustomNativeDragPreview)({
519
+ nativeSetDragImage,
520
+ getOffset: ({ container }) => {
521
+ return offsetFn({
522
+ container
523
+ });
524
+ },
525
+ render: ({ container }) => {
526
+ container.style.width = rect.width + "px";
527
+ setDragState({
528
+ type: "preview",
529
+ container,
530
+ item
531
+ });
532
+ return () => {
533
+ };
534
+ }
535
+ });
536
+ },
537
+ onDragStart: () => {
538
+ document.body.removeAttribute("data-drag-preview");
539
+ itemElement?.closest("[data-drag-autoscroll]")?.setAttribute("data-drag-autoscroll", "active");
540
+ setDragState({
541
+ type: "is-dragging",
542
+ item
543
+ });
544
+ },
545
+ onDrop: () => {
546
+ itemElement?.closest("[data-drag-autoscroll]")?.setAttribute("data-drag-autoscroll", "idle");
547
+ setDragState(idle);
478
548
  }
479
- },
480
- onDragLeave: () => setEdge(null),
481
- onDrop: ({ self, source }) => {
482
- setEdge(null);
483
- if (source.data.type === self.data.type) {
484
- onRearrange(source.data, self.data, (0, import_closest_edge2.extractClosestEdge)(self.data));
549
+ }), (0, import_adapter2.dropTargetForElements)({
550
+ element: itemElement,
551
+ getData: ({ input, element }) => {
552
+ return (0, import_closest_edge2.attachClosestEdge)({
553
+ id: item.id,
554
+ type
555
+ }, {
556
+ input,
557
+ element,
558
+ allowedEdges: orientation === "horizontal" ? [
559
+ "left",
560
+ "right"
561
+ ] : [
562
+ "top",
563
+ "bottom"
564
+ ]
565
+ });
566
+ },
567
+ onDragEnter: ({ self, source }) => {
568
+ if (source.data.type === self.data.type) {
569
+ setEdge((0, import_closest_edge2.extractClosestEdge)(self.data));
570
+ setSourceId(source.data.id);
571
+ }
572
+ },
573
+ onDrag: ({ self, source }) => {
574
+ if (source.data.type === self.data.type) {
575
+ setEdge((0, import_closest_edge2.extractClosestEdge)(self.data));
576
+ setSourceId(source.data.id);
577
+ }
578
+ },
579
+ onDragLeave: () => {
580
+ setEdge(null);
581
+ setSourceId(null);
582
+ },
583
+ onDrop: ({ self, source }) => {
584
+ setEdge(null);
585
+ setSourceId(null);
586
+ if (source.data.type === self.data.type) {
587
+ onRearrange(source.data, self.data, (0, import_closest_edge2.extractClosestEdge)(self.data));
588
+ }
485
589
  }
590
+ }));
591
+ }, [
592
+ orientation,
593
+ item,
594
+ onRearrange,
595
+ selfDragHandleElement,
596
+ itemElement
597
+ ]);
598
+ const focusableGroupAttrs = (0, import_react_tabster2.useFocusableGroup)({
599
+ tabBehavior: "limited"
600
+ });
601
+ const shouldShowDropIndicator = () => {
602
+ if (!closestEdge || !sourceId) {
603
+ return false;
486
604
  }
487
- }));
488
- }, [
489
- orientation,
490
- item,
491
- onRearrange,
492
- selfDragHandleElement,
493
- itemElement
494
- ]);
495
- const focusableGroupAttrs = (0, import_react_tabster2.useFocusableGroup)({
496
- tabBehavior: "limited"
497
- });
498
- return /* @__PURE__ */ import_react4.default.createElement(StackItemContext.Provider, {
499
- value: {
500
- selfDragHandleRef,
501
- size,
502
- setSize
503
- }
504
- }, /* @__PURE__ */ import_react4.default.createElement(Root, {
505
- ...props,
506
- tabIndex: 0,
507
- ...focusableGroupAttrs,
508
- className: (0, import_react_ui_theme2.mx)("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"), classNames),
509
- "data-dx-stack-item": true,
510
- ...import_react_ui_dnd.resizeAttributes,
511
- style: {
512
- ...(0, import_react_ui_dnd.sizeStyle)(size, orientation),
513
- ...Number.isFinite(order) && {
514
- [orientation === "horizontal" ? "gridColumn" : "gridRow"]: `${order}`
605
+ if (sourceId === item.id) {
606
+ return false;
607
+ }
608
+ const isTrailingEdgeOfPrevSibling = prevSiblingId !== void 0 && sourceId === prevSiblingId && (orientation === "horizontal" && closestEdge === "left" || orientation === "vertical" && closestEdge === "top");
609
+ if (isTrailingEdgeOfPrevSibling) {
610
+ return false;
611
+ }
612
+ const isLeadingEdgeOfNextSibling = nextSiblingId !== void 0 && sourceId === nextSiblingId && (orientation === "horizontal" && closestEdge === "right" || orientation === "vertical" && closestEdge === "bottom");
613
+ if (isLeadingEdgeOfNextSibling) {
614
+ return false;
615
+ }
616
+ return true;
617
+ };
618
+ return /* @__PURE__ */ import_react4.default.createElement(StackItemContext.Provider, {
619
+ value: {
620
+ selfDragHandleRef,
621
+ size,
622
+ setSize,
623
+ state: dragState,
624
+ setState: setDragState
625
+ }
626
+ }, /* @__PURE__ */ import_react4.default.createElement(Root, {
627
+ ...props,
628
+ tabIndex: 0,
629
+ ...focusableGroupAttrs,
630
+ className: (0, import_react_ui_theme2.mx)("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"), classNames),
631
+ "data-dx-stack-item": true,
632
+ ...import_react_ui_dnd.resizeAttributes,
633
+ style: {
634
+ ...(0, import_react_ui_dnd.sizeStyle)(size, orientation),
635
+ ...Number.isFinite(order) && {
636
+ [orientation === "horizontal" ? "gridColumn" : "gridRow"]: `${order}`
637
+ },
638
+ ...style
515
639
  },
516
- ...style
517
- },
518
- ref: composedItemRef
519
- }, children, closestEdge && /* @__PURE__ */ import_react4.default.createElement(import_react_ui2.ListItem.DropIndicator, {
520
- lineInset: 8,
521
- terminalInset: -8,
522
- edge: closestEdge
523
- })));
640
+ ref: composedItemRef
641
+ }, children, shouldShowDropIndicator() && closestEdge && /* @__PURE__ */ import_react4.default.createElement(import_react_ui2.ListItem.DropIndicator, {
642
+ lineInset: 8,
643
+ terminalInset: -8,
644
+ edge: closestEdge
645
+ })));
646
+ } finally {
647
+ _effect.f();
648
+ }
524
649
  });
650
+ var StackItemDragPreview = ({ children }) => {
651
+ const { state } = useStackItem();
652
+ return state?.type === "preview" ? /* @__PURE__ */ (0, import_react_dom.createPortal)(children({
653
+ item: state.item
654
+ }), state.container) : null;
655
+ };
525
656
  var StackItem = {
526
657
  Root: StackItemRoot,
527
658
  Content: StackItemContent,
@@ -530,7 +661,8 @@ var StackItem = {
530
661
  ResizeHandle: StackItemResizeHandle,
531
662
  DragHandle: StackItemDragHandle,
532
663
  Sigil: StackItemSigil,
533
- SigilButton: StackItemSigilButton
664
+ SigilButton: StackItemSigilButton,
665
+ DragPreview: StackItemDragPreview
534
666
  };
535
667
  // Annotate the CommonJS export names for ESM import in node:
536
668
  0 && (module.exports = {
@@ -540,6 +672,7 @@ var StackItem = {
540
672
  Stack,
541
673
  StackContext,
542
674
  StackItem,
675
+ StackItemDragPreview,
543
676
  autoScrollRootAttributes,
544
677
  railGridHorizontal,
545
678
  railGridHorizontalContainFitContent,