@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
@@ -1,9 +1,10 @@
1
1
  import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
2
 
3
3
  // packages/ui/react-ui-stack/src/components/Stack/Stack.tsx
4
+ import { useSignals as _useSignals } from "@preact-signals/safe-react/tracking";
4
5
  import { useArrowNavigationGroup } from "@fluentui/react-tabster";
5
6
  import { composeRefs } from "@radix-ui/react-compose-refs";
6
- import React, { Children, forwardRef, useState as useState2, useMemo } from "react";
7
+ import React, { Children, forwardRef, useState as useState2, useMemo, useCallback } from "react";
7
8
  import { ListItem } from "@dxos/react-ui";
8
9
  import { mx } from "@dxos/react-ui-theme";
9
10
 
@@ -77,11 +78,17 @@ var StackContext = /* @__PURE__ */ createContext({
77
78
  size: "intrinsic"
78
79
  });
79
80
  var useStack = () => useContext(StackContext);
81
+ var idle = {
82
+ type: "idle"
83
+ };
80
84
  var StackItemContext = /* @__PURE__ */ createContext({
81
85
  selfDragHandleRef: () => {
82
86
  },
83
87
  size: "min-content",
84
88
  setSize: () => {
89
+ },
90
+ state: idle,
91
+ setState: () => {
85
92
  }
86
93
  });
87
94
  var useStackItem = () => useContext(StackItemContext);
@@ -94,158 +101,214 @@ var railGridVerticalContainFitContent = "grid-cols-[[rail-start]_var(--rail-size
94
101
  var autoScrollRootAttributes = {
95
102
  "data-drag-autoscroll": "idle"
96
103
  };
97
- var Stack = /* @__PURE__ */ forwardRef(({ children, classNames, style, orientation = "vertical", rail = true, size = "intrinsic", onRearrange, itemsCount = Children.count(children), ...props }, forwardedRef) => {
98
- const [stackElement, stackRef] = useState2(null);
99
- const composedItemRef = composeRefs(stackRef, forwardedRef);
100
- const arrowNavigationAttrs = useArrowNavigationGroup({
101
- axis: orientation
102
- });
103
- const styles = {
104
- [orientation === "horizontal" ? "gridTemplateColumns" : "gridTemplateRows"]: `repeat(${itemsCount}, min-content) [tabster-dummies] 0`,
105
- ...style
106
- };
107
- const selfDroppable = !!(itemsCount < 1 && onRearrange && props.id);
108
- const { dropping } = useStackDropForElements({
109
- id: props.id,
110
- element: stackElement,
111
- selfDroppable,
112
- orientation,
113
- onRearrange
114
- });
115
- const gridClasses = useMemo(() => {
116
- if (!rail) {
117
- return orientation === "horizontal" ? "grid-rows-1 pli-1" : "grid-cols-1 plb-1";
118
- }
119
- if (orientation === "horizontal") {
120
- return size === "contain-fit-content" ? railGridHorizontalContainFitContent : railGridHorizontal;
121
- } else {
122
- return size === "contain-fit-content" ? railGridVerticalContainFitContent : railGridVertical;
123
- }
124
- }, [
125
- rail,
126
- orientation,
127
- size
128
- ]);
129
- return /* @__PURE__ */ React.createElement(StackContext.Provider, {
130
- value: {
104
+ var Stack = /* @__PURE__ */ forwardRef(({ children, classNames, style, orientation = "vertical", rail = true, size = "intrinsic", onRearrange, itemsCount = Children.count(children), getDropElement, separatorOnScroll, ...props }, forwardedRef) => {
105
+ var _effect = _useSignals();
106
+ try {
107
+ const [stackElement, stackRef] = useState2(null);
108
+ const composedItemRef = composeRefs(stackRef, forwardedRef);
109
+ const arrowNavigationAttrs = useArrowNavigationGroup({
110
+ axis: orientation
111
+ });
112
+ const styles = {
113
+ [orientation === "horizontal" ? "gridTemplateColumns" : "gridTemplateRows"]: `repeat(${itemsCount}, min-content) [tabster-dummies] 0`,
114
+ ...style
115
+ };
116
+ const selfDroppable = !!(itemsCount < 1 && onRearrange && props.id);
117
+ const { dropping } = useStackDropForElements({
118
+ id: props.id,
119
+ element: getDropElement && stackElement ? getDropElement(stackElement) : stackElement,
120
+ selfDroppable,
131
121
  orientation,
132
- rail,
133
- size,
134
122
  onRearrange
135
- }
136
- }, /* @__PURE__ */ React.createElement("div", {
137
- ...props,
138
- ...arrowNavigationAttrs,
139
- 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),
140
- "data-rail": rail,
141
- "aria-orientation": orientation,
142
- style: styles,
143
- ref: composedItemRef
144
- }, children, selfDroppable && dropping && /* @__PURE__ */ React.createElement(ListItem.DropIndicator, {
145
- lineInset: 8,
146
- terminalInset: -8,
147
- gap: -8,
148
- edge: orientation === "horizontal" ? "left" : "top"
149
- })));
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
+ }
134
+ }
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";
143
+ }
144
+ if (orientation === "horizontal") {
145
+ return size === "contain-fit-content" ? railGridHorizontalContainFitContent : railGridHorizontal;
146
+ } else {
147
+ return size === "contain-fit-content" ? railGridVerticalContainFitContent : railGridVertical;
148
+ }
149
+ }, [
150
+ rail,
151
+ orientation,
152
+ size
153
+ ]);
154
+ return /* @__PURE__ */ React.createElement(StackContext.Provider, {
155
+ value: {
156
+ orientation,
157
+ rail,
158
+ size,
159
+ onRearrange
160
+ }
161
+ }, /* @__PURE__ */ React.createElement("div", {
162
+ ...props,
163
+ ...arrowNavigationAttrs,
164
+ 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),
165
+ "data-rail": rail,
166
+ "aria-orientation": orientation,
167
+ style: styles,
168
+ ref: composedItemRef,
169
+ ...Number.isFinite(separatorOnScroll) && {
170
+ onScroll: handleScroll
171
+ }
172
+ }, children, selfDroppable && dropping && /* @__PURE__ */ React.createElement(ListItem.DropIndicator, {
173
+ lineInset: 8,
174
+ terminalInset: -8,
175
+ gap: -8,
176
+ edge: orientation === "horizontal" ? "left" : "top"
177
+ })));
178
+ } finally {
179
+ _effect.f();
180
+ }
150
181
  });
151
182
 
152
183
  // packages/ui/react-ui-stack/src/components/StackItem/StackItem.tsx
184
+ import { useSignals as _useSignals8 } from "@preact-signals/safe-react/tracking";
153
185
  import { combine as combine2 } from "@atlaskit/pragmatic-drag-and-drop/combine";
154
186
  import { draggable, dropTargetForElements as dropTargetForElements2 } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
155
187
  import { preserveOffsetOnSource } from "@atlaskit/pragmatic-drag-and-drop/element/preserve-offset-on-source";
156
- import { scrollJustEnoughIntoView } from "@atlaskit/pragmatic-drag-and-drop/element/scroll-just-enough-into-view";
188
+ import { setCustomNativeDragPreview } from "@atlaskit/pragmatic-drag-and-drop/element/set-custom-native-drag-preview";
157
189
  import { attachClosestEdge as attachClosestEdge2, extractClosestEdge as extractClosestEdge2 } from "@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge";
158
190
  import { useFocusableGroup as useFocusableGroup2 } from "@fluentui/react-tabster";
159
191
  import { composeRefs as composeRefs2 } from "@radix-ui/react-compose-refs";
160
- import React8, { forwardRef as forwardRef5, useLayoutEffect as useLayoutEffect2, useState as useState4, useCallback } from "react";
192
+ import React8, { forwardRef as forwardRef5, useLayoutEffect as useLayoutEffect2, useState as useState4, useCallback as useCallback2 } from "react";
193
+ import { createPortal } from "react-dom";
161
194
  import { ListItem as ListItem2 } from "@dxos/react-ui";
162
195
  import { resizeAttributes, sizeStyle } from "@dxos/react-ui-dnd";
163
196
  import { mx as mx5 } from "@dxos/react-ui-theme";
164
197
 
165
198
  // packages/ui/react-ui-stack/src/components/StackItem/StackItemContent.tsx
199
+ import { useSignals as _useSignals2 } from "@preact-signals/safe-react/tracking";
166
200
  import React2, { forwardRef as forwardRef2 } from "react";
167
201
  import { mx as mx2 } from "@dxos/react-ui-theme";
168
202
  var StackItemContent = /* @__PURE__ */ forwardRef2(({ children, toolbar, statusbar, classNames, size = "intrinsic", ...props }, forwardedRef) => {
169
- const { size: stackItemSize } = useStack();
170
- return /* @__PURE__ */ React2.createElement("div", {
171
- role: "none",
172
- ...props,
173
- className: mx2("group grid grid-cols-[100%]", stackItemSize === "contain" && "min-bs-0 overflow-hidden", size === "video" ? "aspect-video" : size === "square" && "aspect-square", classNames),
174
- style: {
175
- gridTemplateRows: [
176
- ...toolbar ? [
177
- "var(--rail-action)"
178
- ] : [],
179
- "1fr",
180
- ...statusbar ? [
181
- "var(--statusbar-size)"
182
- ] : []
183
- ].join(" ")
184
- },
185
- "data-popover-collision-boundary": true,
186
- ref: forwardedRef
187
- }, children);
203
+ var _effect = _useSignals2();
204
+ try {
205
+ const { size: stackItemSize } = useStack();
206
+ return /* @__PURE__ */ React2.createElement("div", {
207
+ role: "none",
208
+ ...props,
209
+ className: mx2("group grid grid-cols-[100%]", stackItemSize === "contain" && "min-bs-0 overflow-hidden", size === "video" ? "aspect-video" : size === "square" && "aspect-square", classNames),
210
+ style: {
211
+ gridTemplateRows: [
212
+ ...toolbar ? [
213
+ "var(--rail-action)"
214
+ ] : [],
215
+ "1fr",
216
+ ...statusbar ? [
217
+ "var(--statusbar-size)"
218
+ ] : []
219
+ ].join(" ")
220
+ },
221
+ "data-popover-collision-boundary": true,
222
+ ref: forwardedRef
223
+ }, children);
224
+ } finally {
225
+ _effect.f();
226
+ }
188
227
  });
189
228
 
190
229
  // packages/ui/react-ui-stack/src/components/StackItem/StackItemDragHandle.tsx
230
+ import { useSignals as _useSignals3 } from "@preact-signals/safe-react/tracking";
191
231
  import { Slot } from "@radix-ui/react-slot";
192
232
  import React3 from "react";
193
233
  var StackItemDragHandle = ({ asChild, children }) => {
194
- const { selfDragHandleRef } = useStackItem();
195
- const Root = asChild ? Slot : "div";
196
- return /* @__PURE__ */ React3.createElement(Root, {
197
- ref: selfDragHandleRef,
198
- role: "button"
199
- }, children);
234
+ var _effect = _useSignals3();
235
+ try {
236
+ const { selfDragHandleRef } = useStackItem();
237
+ const Root = asChild ? Slot : "div";
238
+ return /* @__PURE__ */ React3.createElement(Root, {
239
+ ref: selfDragHandleRef,
240
+ role: "button"
241
+ }, children);
242
+ } finally {
243
+ _effect.f();
244
+ }
200
245
  };
201
246
 
202
247
  // packages/ui/react-ui-stack/src/components/StackItem/StackItemHeading.tsx
248
+ import { useSignals as _useSignals4 } from "@preact-signals/safe-react/tracking";
203
249
  import { useFocusableGroup } from "@fluentui/react-tabster";
204
250
  import React4, { forwardRef as forwardRef3 } from "react";
205
251
  import { useAttention } from "@dxos/react-ui-attention";
206
252
  import { mx as mx3 } from "@dxos/react-ui-theme";
207
253
  var StackItemHeading = ({ children, classNames, ...props }) => {
208
- const { orientation } = useStack();
209
- const focusableGroupAttrs = useFocusableGroup({
210
- tabBehavior: "limited"
211
- });
212
- return /* @__PURE__ */ React4.createElement("div", {
213
- role: "heading",
214
- ...props,
215
- tabIndex: 0,
216
- ...focusableGroupAttrs,
217
- className: mx3("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)
218
- }, children);
254
+ var _effect = _useSignals4();
255
+ try {
256
+ const { orientation } = useStack();
257
+ const focusableGroupAttrs = useFocusableGroup({
258
+ tabBehavior: "limited"
259
+ });
260
+ return /* @__PURE__ */ React4.createElement("div", {
261
+ role: "heading",
262
+ ...props,
263
+ tabIndex: 0,
264
+ ...focusableGroupAttrs,
265
+ className: mx3('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)
266
+ }, children);
267
+ } finally {
268
+ _effect.f();
269
+ }
219
270
  };
220
271
  var StackItemHeadingLabel = /* @__PURE__ */ forwardRef3(({ attendableId, related, classNames, ...props }, forwardedRef) => {
221
- const { hasAttention, isAncestor, isRelated } = useAttention(attendableId);
222
- return /* @__PURE__ */ React4.createElement("h1", {
223
- ...props,
224
- "data-attention": (related && isRelated || hasAttention || isAncestor).toString(),
225
- className: mx3("pli-1 min-is-0 is-0 grow truncate font-medium text-baseText data-[attention=true]:text-accentText self-center", classNames),
226
- ref: forwardedRef
227
- });
272
+ var _effect = _useSignals4();
273
+ try {
274
+ const { hasAttention, isAncestor, isRelated } = useAttention(attendableId);
275
+ return /* @__PURE__ */ React4.createElement("h1", {
276
+ ...props,
277
+ "data-attention": (related && isRelated || hasAttention || isAncestor).toString(),
278
+ className: mx3("pli-1 min-is-0 is-0 grow truncate font-medium text-baseText data-[attention=true]:text-accentText self-center", classNames),
279
+ ref: forwardedRef
280
+ });
281
+ } finally {
282
+ _effect.f();
283
+ }
228
284
  });
229
285
 
230
286
  // packages/ui/react-ui-stack/src/components/StackItem/StackItemResizeHandle.tsx
287
+ import { useSignals as _useSignals5 } from "@preact-signals/safe-react/tracking";
231
288
  import React5 from "react";
232
289
  import { ResizeHandle } from "@dxos/react-ui-dnd";
233
290
  var MIN_WIDTH = 20;
234
291
  var MIN_HEIGHT = 3;
235
292
  var StackItemResizeHandle = () => {
236
- const { orientation } = useStack();
237
- const { setSize, size } = useStackItem();
238
- return /* @__PURE__ */ React5.createElement(ResizeHandle, {
239
- side: orientation === "horizontal" ? "inline-end" : "block-end",
240
- fallbackSize: DEFAULT_EXTRINSIC_SIZE,
241
- minSize: orientation === "horizontal" ? MIN_WIDTH : MIN_HEIGHT,
242
- size,
243
- onSizeChange: setSize
244
- });
293
+ var _effect = _useSignals5();
294
+ try {
295
+ const { orientation } = useStack();
296
+ const { setSize, size } = useStackItem();
297
+ return /* @__PURE__ */ React5.createElement(ResizeHandle, {
298
+ side: orientation === "horizontal" ? "inline-end" : "block-end",
299
+ fallbackSize: DEFAULT_EXTRINSIC_SIZE,
300
+ minSize: orientation === "horizontal" ? MIN_WIDTH : MIN_HEIGHT,
301
+ size,
302
+ onSizeChange: setSize
303
+ });
304
+ } finally {
305
+ _effect.f();
306
+ }
245
307
  };
246
308
 
247
309
  // packages/ui/react-ui-stack/src/components/StackItem/StackItemSigil.tsx
248
- import React7, { Fragment, forwardRef as forwardRef4, useRef, useState as useState3 } from "react";
310
+ import { useSignals as _useSignals7 } from "@preact-signals/safe-react/tracking";
311
+ import React7, { Fragment, forwardRef as forwardRef4, useState as useState3 } from "react";
249
312
  import { keySymbols } from "@dxos/keyboard";
250
313
  import { Button, DropdownMenu, Icon, toLocalizedString, useTranslation } from "@dxos/react-ui";
251
314
  import { useAttention as useAttention2 } from "@dxos/react-ui-attention";
@@ -253,24 +316,32 @@ import { descriptionText, mx as mx4 } from "@dxos/react-ui-theme";
253
316
  import { getHostPlatform } from "@dxos/util";
254
317
 
255
318
  // packages/ui/react-ui-stack/src/components/StackItem/MenuSignifier.tsx
319
+ import { useSignals as _useSignals6 } from "@preact-signals/safe-react/tracking";
256
320
  import React6 from "react";
257
- var MenuSignifierHorizontal = () => /* @__PURE__ */ React6.createElement("svg", {
258
- className: "absolute block-end-[7px]",
259
- width: 20,
260
- height: 2,
261
- viewBox: "0 0 20 2",
262
- stroke: "currentColor",
263
- opacity: 0.5
264
- }, /* @__PURE__ */ React6.createElement("line", {
265
- x1: 0.5,
266
- y1: 0.75,
267
- x2: 19,
268
- y2: 0.75,
269
- strokeWidth: 1.25,
270
- strokeLinecap: "round",
271
- strokeDasharray: "6 20",
272
- strokeDashoffset: "-6.5"
273
- }));
321
+ var MenuSignifierHorizontal = () => {
322
+ var _effect = _useSignals6();
323
+ try {
324
+ return /* @__PURE__ */ React6.createElement("svg", {
325
+ className: "absolute block-end-[7px]",
326
+ width: 20,
327
+ height: 2,
328
+ viewBox: "0 0 20 2",
329
+ stroke: "currentColor",
330
+ opacity: 0.5
331
+ }, /* @__PURE__ */ React6.createElement("line", {
332
+ x1: 0.5,
333
+ y1: 0.75,
334
+ x2: 19,
335
+ y2: 0.75,
336
+ strokeWidth: 1.25,
337
+ strokeLinecap: "round",
338
+ strokeDasharray: "6 20",
339
+ strokeDashoffset: "-6.5"
340
+ }));
341
+ } finally {
342
+ _effect.f();
343
+ }
344
+ };
274
345
 
275
346
  // packages/ui/react-ui-stack/src/translations.ts
276
347
  var translationKey = "stack";
@@ -292,221 +363,280 @@ var translations_default = [
292
363
 
293
364
  // packages/ui/react-ui-stack/src/components/StackItem/StackItemSigil.tsx
294
365
  var StackItemSigilButton = /* @__PURE__ */ forwardRef4(({ attendableId, classNames, related, isMenu = true, children, ...props }, forwardedRef) => {
295
- const { hasAttention, isAncestor, isRelated } = useAttention2(attendableId);
296
- const variant = related && isRelated || hasAttention || isAncestor ? "primary" : "ghost";
297
- return /* @__PURE__ */ React7.createElement(Button, {
298
- ...props,
299
- variant,
300
- classNames: [
301
- "shrink-0 pli-0 min-bs-0 is-[--rail-action] bs-[--rail-action] relative app-no-drag",
302
- classNames
303
- ],
304
- ref: forwardedRef
305
- }, isMenu && /* @__PURE__ */ React7.createElement(MenuSignifierHorizontal, null), children);
366
+ var _effect = _useSignals7();
367
+ try {
368
+ const { hasAttention, isAncestor, isRelated } = useAttention2(attendableId);
369
+ const variant = related && isRelated || hasAttention || isAncestor ? "primary" : "ghost";
370
+ return /* @__PURE__ */ React7.createElement(Button, {
371
+ ...props,
372
+ variant,
373
+ classNames: [
374
+ "shrink-0 pli-0 min-bs-0 is-[--rail-action] bs-[--rail-action] relative app-no-drag",
375
+ classNames
376
+ ],
377
+ ref: forwardedRef
378
+ }, isMenu && /* @__PURE__ */ React7.createElement(MenuSignifierHorizontal, null), children);
379
+ } finally {
380
+ _effect.f();
381
+ }
306
382
  });
307
383
  var StackItemSigil = /* @__PURE__ */ forwardRef4(({ actions: actionGroups, onAction, triggerLabel, attendableId, icon, related, children }, forwardedRef) => {
308
- const { t } = useTranslation(translationKey);
309
- const suppressNextTooltip = useRef(false);
310
- const [optionsMenuOpen, setOptionsMenuOpen] = useState3(false);
311
- const hasActions = actionGroups && actionGroups.length > 0;
312
- const button = /* @__PURE__ */ React7.createElement(StackItemSigilButton, {
313
- attendableId,
314
- related,
315
- isMenu: hasActions,
316
- // TODO(wittjosiah): Better disabling of interactive styles when no action are available.
317
- // Remove underscore icon when no actions are available?
318
- classNames: !hasActions && "cursor-default"
319
- }, /* @__PURE__ */ React7.createElement("span", {
320
- className: "sr-only"
321
- }, triggerLabel), /* @__PURE__ */ React7.createElement(Icon, {
322
- icon,
323
- size: 5
324
- }));
325
- if (!hasActions) {
326
- return button;
327
- }
328
- return /* @__PURE__ */ React7.createElement(DropdownMenu.Root, {
329
- open: optionsMenuOpen,
330
- onOpenChange: (nextOpen) => {
331
- if (!nextOpen) {
332
- suppressNextTooltip.current = true;
333
- }
334
- return setOptionsMenuOpen(nextOpen);
384
+ var _effect = _useSignals7();
385
+ try {
386
+ const { t } = useTranslation(translationKey);
387
+ const [optionsMenuOpen, setOptionsMenuOpen] = useState3(false);
388
+ const hasActions = actionGroups && actionGroups.length > 0;
389
+ const button = /* @__PURE__ */ React7.createElement(StackItemSigilButton, {
390
+ attendableId,
391
+ related,
392
+ isMenu: hasActions,
393
+ // TODO(wittjosiah): Better disabling of interactive styles when no action are available.
394
+ // Remove underscore icon when no actions are available?
395
+ classNames: !hasActions && "cursor-default"
396
+ }, /* @__PURE__ */ React7.createElement("span", {
397
+ className: "sr-only"
398
+ }, triggerLabel), /* @__PURE__ */ React7.createElement(Icon, {
399
+ icon,
400
+ size: 5
401
+ }));
402
+ if (!hasActions) {
403
+ return button;
335
404
  }
336
- }, /* @__PURE__ */ React7.createElement(DropdownMenu.Trigger, {
337
- asChild: true,
338
- ref: forwardedRef
339
- }, button), /* @__PURE__ */ React7.createElement(DropdownMenu.Portal, null, /* @__PURE__ */ React7.createElement(DropdownMenu.Content, {
340
- classNames: "z-[31]"
341
- }, /* @__PURE__ */ React7.createElement(DropdownMenu.Viewport, null, actionGroups?.map((actions, index) => {
342
- const separator = index > 0 ? /* @__PURE__ */ React7.createElement(DropdownMenu.Separator, null) : null;
343
- return /* @__PURE__ */ React7.createElement(Fragment, {
344
- key: index
345
- }, separator, actions.map((action) => {
346
- const shortcut = typeof action.properties.keyBinding === "string" ? action.properties.keyBinding : action.properties.keyBinding?.[getHostPlatform()];
347
- const menuItemType = action.properties.menuItemType;
348
- const Root = menuItemType === "toggle" ? DropdownMenu.CheckboxItem : DropdownMenu.Item;
349
- return /* @__PURE__ */ React7.createElement(Root, {
350
- key: action.id,
351
- onClick: (event) => {
352
- if (action.properties.disabled) {
353
- return;
405
+ return /* @__PURE__ */ React7.createElement(DropdownMenu.Root, {
406
+ open: optionsMenuOpen,
407
+ onOpenChange: setOptionsMenuOpen
408
+ }, /* @__PURE__ */ React7.createElement(DropdownMenu.Trigger, {
409
+ asChild: true,
410
+ ref: forwardedRef
411
+ }, button), /* @__PURE__ */ React7.createElement(DropdownMenu.Portal, null, /* @__PURE__ */ React7.createElement(DropdownMenu.Content, {
412
+ classNames: "z-[31]"
413
+ }, /* @__PURE__ */ React7.createElement(DropdownMenu.Viewport, null, actionGroups?.map((actions, index) => {
414
+ const separator = index > 0 ? /* @__PURE__ */ React7.createElement(DropdownMenu.Separator, null) : null;
415
+ return /* @__PURE__ */ React7.createElement(Fragment, {
416
+ key: index
417
+ }, separator, actions.map((action) => {
418
+ const shortcut = typeof action.properties.keyBinding === "string" ? action.properties.keyBinding : action.properties.keyBinding?.[getHostPlatform()];
419
+ const menuItemType = action.properties.menuItemType;
420
+ const Root = menuItemType === "toggle" ? DropdownMenu.CheckboxItem : DropdownMenu.Item;
421
+ return /* @__PURE__ */ React7.createElement(Root, {
422
+ key: action.id,
423
+ onClick: (event) => {
424
+ if (action.properties.disabled) {
425
+ return;
426
+ }
427
+ event.stopPropagation();
428
+ setOptionsMenuOpen(false);
429
+ onAction?.(action);
430
+ },
431
+ classNames: "gap-2",
432
+ disabled: action.properties.disabled,
433
+ checked: menuItemType === "toggle" ? action.properties.isChecked : void 0,
434
+ ...action.properties?.testId && {
435
+ "data-testid": action.properties.testId
354
436
  }
355
- event.stopPropagation();
356
- suppressNextTooltip.current = true;
357
- setOptionsMenuOpen(false);
358
- onAction?.(action);
359
- },
360
- classNames: "gap-2",
361
- disabled: action.properties.disabled,
362
- checked: menuItemType === "toggle" ? action.properties.isChecked : void 0,
363
- ...action.properties?.testId && {
364
- "data-testid": action.properties.testId
365
- }
366
- }, /* @__PURE__ */ React7.createElement(Icon, {
367
- icon: action.properties.icon ?? "ph--placeholder--regular",
368
- size: 4
369
- }), /* @__PURE__ */ React7.createElement("span", {
370
- className: "grow truncate"
371
- }, toLocalizedString(action.properties.label ?? "", t)), menuItemType === "toggle" && /* @__PURE__ */ React7.createElement(DropdownMenu.ItemIndicator, {
372
- asChild: true
373
- }, /* @__PURE__ */ React7.createElement(Icon, {
374
- icon: "ph--check--regular",
375
- size: 4
376
- })), shortcut && /* @__PURE__ */ React7.createElement("span", {
377
- className: mx4("shrink-0", descriptionText)
378
- }, keySymbols(shortcut).join("")));
379
- }));
380
- }), children), /* @__PURE__ */ React7.createElement(DropdownMenu.Arrow, null))));
437
+ }, /* @__PURE__ */ React7.createElement(Icon, {
438
+ icon: action.properties.icon ?? "ph--placeholder--regular",
439
+ size: 4
440
+ }), /* @__PURE__ */ React7.createElement("span", {
441
+ className: "grow truncate"
442
+ }, toLocalizedString(action.properties.label ?? "", t)), menuItemType === "toggle" && /* @__PURE__ */ React7.createElement(DropdownMenu.ItemIndicator, {
443
+ asChild: true
444
+ }, /* @__PURE__ */ React7.createElement(Icon, {
445
+ icon: "ph--check--regular",
446
+ size: 4
447
+ })), shortcut && /* @__PURE__ */ React7.createElement("span", {
448
+ className: mx4("shrink-0", descriptionText)
449
+ }, keySymbols(shortcut).join("")));
450
+ }));
451
+ }), children), /* @__PURE__ */ React7.createElement(DropdownMenu.Arrow, null))));
452
+ } finally {
453
+ _effect.f();
454
+ }
381
455
  });
382
456
 
383
457
  // packages/ui/react-ui-stack/src/components/StackItem/StackItem.tsx
384
458
  var DEFAULT_HORIZONTAL_SIZE = 48;
385
459
  var DEFAULT_VERTICAL_SIZE = "min-content";
386
460
  var DEFAULT_EXTRINSIC_SIZE = DEFAULT_HORIZONTAL_SIZE;
387
- var StackItemRoot = /* @__PURE__ */ forwardRef5(({ item, children, classNames, size: propsSize, onSizeChange, role, order, style, disableRearrange, focusIndicatorVariant = "over-all", ...props }, forwardedRef) => {
388
- const [itemElement, itemRef] = useState4(null);
389
- const [selfDragHandleElement, selfDragHandleRef] = useState4(null);
390
- const [closestEdge, setEdge] = useState4(null);
391
- const { orientation, rail, onRearrange } = useStack();
392
- const [size = orientation === "horizontal" ? DEFAULT_HORIZONTAL_SIZE : DEFAULT_VERTICAL_SIZE, setInternalSize] = useState4(propsSize);
393
- const Root = role ?? "div";
394
- const composedItemRef = composeRefs2(itemRef, forwardedRef);
395
- const setSize = useCallback((nextSize, commit) => {
396
- setInternalSize(nextSize);
397
- if (commit) {
398
- onSizeChange?.(nextSize);
399
- }
400
- }, [
401
- onSizeChange
402
- ]);
403
- const type = orientation === "horizontal" ? "column" : "card";
404
- useLayoutEffect2(() => {
405
- if (!itemElement || !onRearrange || disableRearrange) {
406
- return;
407
- }
408
- return combine2(draggable({
409
- element: itemElement,
410
- ...selfDragHandleElement && {
411
- dragHandle: selfDragHandleElement
412
- },
413
- getInitialData: () => ({
414
- id: item.id,
415
- type
416
- }),
417
- onGenerateDragPreview: ({ nativeSetDragImage, source, location }) => {
418
- document.body.setAttribute("data-drag-preview", "true");
419
- scrollJustEnoughIntoView({
420
- element: source.element
421
- });
422
- const { x, y } = preserveOffsetOnSource({
423
- element: source.element,
424
- input: location.current.input
425
- })({
426
- container: source.element.offsetParent ?? document.body
427
- });
428
- nativeSetDragImage?.(source.element, x, y);
429
- },
430
- onDragStart: () => {
431
- document.body.removeAttribute("data-drag-preview");
432
- itemElement?.closest("[data-drag-autoscroll]")?.setAttribute("data-drag-autoscroll", "active");
433
- },
434
- onDrop: () => {
435
- itemElement?.closest("[data-drag-autoscroll]")?.setAttribute("data-drag-autoscroll", "idle");
461
+ var StackItemRoot = /* @__PURE__ */ forwardRef5(({ item, children, classNames, size: propsSize, onSizeChange, role, order, prevSiblingId, nextSiblingId, style, disableRearrange, focusIndicatorVariant = "over-all", ...props }, forwardedRef) => {
462
+ var _effect = _useSignals8();
463
+ try {
464
+ const [itemElement, itemRef] = useState4(null);
465
+ const [selfDragHandleElement, selfDragHandleRef] = useState4(null);
466
+ const [closestEdge, setEdge] = useState4(null);
467
+ const [sourceId, setSourceId] = useState4(null);
468
+ const [dragState, setDragState] = useState4(idle);
469
+ const { orientation, rail, onRearrange } = useStack();
470
+ const [size = orientation === "horizontal" ? DEFAULT_HORIZONTAL_SIZE : DEFAULT_VERTICAL_SIZE, setInternalSize] = useState4(propsSize);
471
+ const Root = role ?? "div";
472
+ const composedItemRef = composeRefs2(itemRef, forwardedRef);
473
+ const setSize = useCallback2((nextSize, commit) => {
474
+ setInternalSize(nextSize);
475
+ if (commit) {
476
+ onSizeChange?.(nextSize);
477
+ }
478
+ }, [
479
+ onSizeChange
480
+ ]);
481
+ const type = orientation === "horizontal" ? "column" : "card";
482
+ useLayoutEffect2(() => {
483
+ if (!itemElement || !onRearrange || disableRearrange) {
484
+ return;
436
485
  }
437
- }), dropTargetForElements2({
438
- element: itemElement,
439
- getData: ({ input, element }) => {
440
- return attachClosestEdge2({
486
+ return combine2(draggable({
487
+ element: itemElement,
488
+ ...selfDragHandleElement && {
489
+ dragHandle: selfDragHandleElement
490
+ },
491
+ getInitialData: () => ({
441
492
  id: item.id,
442
493
  type
443
- }, {
444
- input,
445
- element,
446
- allowedEdges: orientation === "horizontal" ? [
447
- "left",
448
- "right"
449
- ] : [
450
- "top",
451
- "bottom"
452
- ]
453
- });
454
- },
455
- onDragEnter: ({ self, source }) => {
456
- if (source.data.type === self.data.type) {
457
- setEdge(extractClosestEdge2(self.data));
458
- }
459
- },
460
- onDrag: ({ self, source }) => {
461
- if (source.data.type === self.data.type) {
462
- setEdge(extractClosestEdge2(self.data));
494
+ }),
495
+ onGenerateDragPreview: ({ nativeSetDragImage, source, location }) => {
496
+ document.body.setAttribute("data-drag-preview", "true");
497
+ const offsetFn = preserveOffsetOnSource({
498
+ element: source.element,
499
+ input: location.current.input
500
+ });
501
+ const rect = source.element.getBoundingClientRect();
502
+ setCustomNativeDragPreview({
503
+ nativeSetDragImage,
504
+ getOffset: ({ container }) => {
505
+ return offsetFn({
506
+ container
507
+ });
508
+ },
509
+ render: ({ container }) => {
510
+ container.style.width = rect.width + "px";
511
+ setDragState({
512
+ type: "preview",
513
+ container,
514
+ item
515
+ });
516
+ return () => {
517
+ };
518
+ }
519
+ });
520
+ },
521
+ onDragStart: () => {
522
+ document.body.removeAttribute("data-drag-preview");
523
+ itemElement?.closest("[data-drag-autoscroll]")?.setAttribute("data-drag-autoscroll", "active");
524
+ setDragState({
525
+ type: "is-dragging",
526
+ item
527
+ });
528
+ },
529
+ onDrop: () => {
530
+ itemElement?.closest("[data-drag-autoscroll]")?.setAttribute("data-drag-autoscroll", "idle");
531
+ setDragState(idle);
463
532
  }
464
- },
465
- onDragLeave: () => setEdge(null),
466
- onDrop: ({ self, source }) => {
467
- setEdge(null);
468
- if (source.data.type === self.data.type) {
469
- onRearrange(source.data, self.data, extractClosestEdge2(self.data));
533
+ }), dropTargetForElements2({
534
+ element: itemElement,
535
+ getData: ({ input, element }) => {
536
+ return attachClosestEdge2({
537
+ id: item.id,
538
+ type
539
+ }, {
540
+ input,
541
+ element,
542
+ allowedEdges: orientation === "horizontal" ? [
543
+ "left",
544
+ "right"
545
+ ] : [
546
+ "top",
547
+ "bottom"
548
+ ]
549
+ });
550
+ },
551
+ onDragEnter: ({ self, source }) => {
552
+ if (source.data.type === self.data.type) {
553
+ setEdge(extractClosestEdge2(self.data));
554
+ setSourceId(source.data.id);
555
+ }
556
+ },
557
+ onDrag: ({ self, source }) => {
558
+ if (source.data.type === self.data.type) {
559
+ setEdge(extractClosestEdge2(self.data));
560
+ setSourceId(source.data.id);
561
+ }
562
+ },
563
+ onDragLeave: () => {
564
+ setEdge(null);
565
+ setSourceId(null);
566
+ },
567
+ onDrop: ({ self, source }) => {
568
+ setEdge(null);
569
+ setSourceId(null);
570
+ if (source.data.type === self.data.type) {
571
+ onRearrange(source.data, self.data, extractClosestEdge2(self.data));
572
+ }
470
573
  }
574
+ }));
575
+ }, [
576
+ orientation,
577
+ item,
578
+ onRearrange,
579
+ selfDragHandleElement,
580
+ itemElement
581
+ ]);
582
+ const focusableGroupAttrs = useFocusableGroup2({
583
+ tabBehavior: "limited"
584
+ });
585
+ const shouldShowDropIndicator = () => {
586
+ if (!closestEdge || !sourceId) {
587
+ return false;
471
588
  }
472
- }));
473
- }, [
474
- orientation,
475
- item,
476
- onRearrange,
477
- selfDragHandleElement,
478
- itemElement
479
- ]);
480
- const focusableGroupAttrs = useFocusableGroup2({
481
- tabBehavior: "limited"
482
- });
483
- return /* @__PURE__ */ React8.createElement(StackItemContext.Provider, {
484
- value: {
485
- selfDragHandleRef,
486
- size,
487
- setSize
488
- }
489
- }, /* @__PURE__ */ React8.createElement(Root, {
490
- ...props,
491
- tabIndex: 0,
492
- ...focusableGroupAttrs,
493
- 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"), classNames),
494
- "data-dx-stack-item": true,
495
- ...resizeAttributes,
496
- style: {
497
- ...sizeStyle(size, orientation),
498
- ...Number.isFinite(order) && {
499
- [orientation === "horizontal" ? "gridColumn" : "gridRow"]: `${order}`
589
+ if (sourceId === item.id) {
590
+ return false;
591
+ }
592
+ const isTrailingEdgeOfPrevSibling = prevSiblingId !== void 0 && sourceId === prevSiblingId && (orientation === "horizontal" && closestEdge === "left" || orientation === "vertical" && closestEdge === "top");
593
+ if (isTrailingEdgeOfPrevSibling) {
594
+ return false;
595
+ }
596
+ const isLeadingEdgeOfNextSibling = nextSiblingId !== void 0 && sourceId === nextSiblingId && (orientation === "horizontal" && closestEdge === "right" || orientation === "vertical" && closestEdge === "bottom");
597
+ if (isLeadingEdgeOfNextSibling) {
598
+ return false;
599
+ }
600
+ return true;
601
+ };
602
+ return /* @__PURE__ */ React8.createElement(StackItemContext.Provider, {
603
+ value: {
604
+ selfDragHandleRef,
605
+ size,
606
+ setSize,
607
+ state: dragState,
608
+ setState: setDragState
609
+ }
610
+ }, /* @__PURE__ */ React8.createElement(Root, {
611
+ ...props,
612
+ tabIndex: 0,
613
+ ...focusableGroupAttrs,
614
+ 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"), classNames),
615
+ "data-dx-stack-item": true,
616
+ ...resizeAttributes,
617
+ style: {
618
+ ...sizeStyle(size, orientation),
619
+ ...Number.isFinite(order) && {
620
+ [orientation === "horizontal" ? "gridColumn" : "gridRow"]: `${order}`
621
+ },
622
+ ...style
500
623
  },
501
- ...style
502
- },
503
- ref: composedItemRef
504
- }, children, closestEdge && /* @__PURE__ */ React8.createElement(ListItem2.DropIndicator, {
505
- lineInset: 8,
506
- terminalInset: -8,
507
- edge: closestEdge
508
- })));
624
+ ref: composedItemRef
625
+ }, children, shouldShowDropIndicator() && closestEdge && /* @__PURE__ */ React8.createElement(ListItem2.DropIndicator, {
626
+ lineInset: 8,
627
+ terminalInset: -8,
628
+ edge: closestEdge
629
+ })));
630
+ } finally {
631
+ _effect.f();
632
+ }
509
633
  });
634
+ var StackItemDragPreview = ({ children }) => {
635
+ const { state } = useStackItem();
636
+ return state?.type === "preview" ? /* @__PURE__ */ createPortal(children({
637
+ item: state.item
638
+ }), state.container) : null;
639
+ };
510
640
  var StackItem = {
511
641
  Root: StackItemRoot,
512
642
  Content: StackItemContent,
@@ -515,7 +645,8 @@ var StackItem = {
515
645
  ResizeHandle: StackItemResizeHandle,
516
646
  DragHandle: StackItemDragHandle,
517
647
  Sigil: StackItemSigil,
518
- SigilButton: StackItemSigilButton
648
+ SigilButton: StackItemSigilButton,
649
+ DragPreview: StackItemDragPreview
519
650
  };
520
651
  export {
521
652
  DEFAULT_EXTRINSIC_SIZE,
@@ -524,6 +655,7 @@ export {
524
655
  Stack,
525
656
  StackContext,
526
657
  StackItem,
658
+ StackItemDragPreview,
527
659
  autoScrollRootAttributes,
528
660
  railGridHorizontal,
529
661
  railGridHorizontalContainFitContent,