@dxos/react-ui-stack 0.8.4-main.e098934 → 0.8.4-main.ead640a

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 (52) hide show
  1. package/dist/lib/browser/{chunk-3V2YUQK5.mjs → chunk-T4ZCIFCF.mjs} +156 -83
  2. package/dist/lib/browser/chunk-T4ZCIFCF.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +5 -1
  4. package/dist/lib/browser/meta.json +1 -1
  5. package/dist/lib/browser/testing/index.mjs +1 -1
  6. package/dist/lib/node-esm/{chunk-HE3BRF7A.mjs → chunk-G2QYUH52.mjs} +156 -83
  7. package/dist/lib/node-esm/chunk-G2QYUH52.mjs.map +7 -0
  8. package/dist/lib/node-esm/index.mjs +5 -1
  9. package/dist/lib/node-esm/meta.json +1 -1
  10. package/dist/lib/node-esm/testing/index.mjs +1 -1
  11. package/dist/types/src/components/Image/Image.d.ts +5 -2
  12. package/dist/types/src/components/Image/Image.d.ts.map +1 -1
  13. package/dist/types/src/components/Image/Image.stories.d.ts +2 -1
  14. package/dist/types/src/components/Image/Image.stories.d.ts.map +1 -1
  15. package/dist/types/src/components/Stack/Stack.d.ts +1 -0
  16. package/dist/types/src/components/Stack/Stack.d.ts.map +1 -1
  17. package/dist/types/src/components/Stack/Stack.stories.d.ts +1 -2
  18. package/dist/types/src/components/Stack/Stack.stories.d.ts.map +1 -1
  19. package/dist/types/src/components/StackItem/StackItem.d.ts +4 -3
  20. package/dist/types/src/components/StackItem/StackItem.d.ts.map +1 -1
  21. package/dist/types/src/components/StackItem/StackItem.stories.d.ts +0 -1
  22. package/dist/types/src/components/StackItem/StackItem.stories.d.ts.map +1 -1
  23. package/dist/types/src/components/StackItem/StackItemContent.d.ts +20 -10
  24. package/dist/types/src/components/StackItem/StackItemContent.d.ts.map +1 -1
  25. package/dist/types/src/components/StackItem/StackItemHeading.d.ts.map +1 -1
  26. package/dist/types/src/exemplars/Card/Card.d.ts +15 -7
  27. package/dist/types/src/exemplars/Card/Card.d.ts.map +1 -1
  28. package/dist/types/src/exemplars/Card/Card.stories.d.ts +0 -23
  29. package/dist/types/src/exemplars/Card/Card.stories.d.ts.map +1 -1
  30. package/dist/types/src/exemplars/Card/fragments.d.ts +1 -1
  31. package/dist/types/src/exemplars/Card/fragments.d.ts.map +1 -1
  32. package/dist/types/src/exemplars/CardStack/CardStack.d.ts +3 -1
  33. package/dist/types/src/exemplars/CardStack/CardStack.d.ts.map +1 -1
  34. package/dist/types/src/exemplars/CardStack/CardStack.stories.d.ts +3 -1
  35. package/dist/types/src/exemplars/CardStack/CardStack.stories.d.ts.map +1 -1
  36. package/dist/types/tsconfig.tsbuildinfo +1 -1
  37. package/package.json +27 -27
  38. package/src/components/Image/Image.stories.tsx +26 -6
  39. package/src/components/Image/Image.tsx +121 -66
  40. package/src/components/Stack/Stack.stories.tsx +2 -4
  41. package/src/components/Stack/Stack.tsx +81 -26
  42. package/src/components/StackItem/StackItem.stories.tsx +2 -4
  43. package/src/components/StackItem/StackItem.tsx +11 -4
  44. package/src/components/StackItem/StackItemContent.tsx +19 -8
  45. package/src/components/StackItem/StackItemHeading.tsx +1 -5
  46. package/src/exemplars/Card/Card.stories.tsx +1 -25
  47. package/src/exemplars/Card/Card.tsx +20 -2
  48. package/src/exemplars/Card/fragments.ts +1 -1
  49. package/src/exemplars/CardStack/CardStack.stories.tsx +5 -4
  50. package/src/exemplars/CardStack/CardStack.tsx +11 -8
  51. package/dist/lib/browser/chunk-3V2YUQK5.mjs.map +0 -7
  52. package/dist/lib/node-esm/chunk-HE3BRF7A.mjs.map +0 -7
@@ -11,56 +11,25 @@ var Image = ({ classNames, src, alt = "", crossOrigin = "anonymous", sampleSize
11
11
  const [dominantColor, setDominantColor] = useState(void 0);
12
12
  const [imageLoaded, setImageLoaded] = useState(false);
13
13
  const canvasRef = useRef(null);
14
- const extractDominantColor = (img) => {
15
- const canvas = canvasRef.current;
16
- const ctx = canvas?.getContext("2d");
17
- if (!canvas || !ctx) {
14
+ const handleImageError = () => {
15
+ setCrossOriginState(void 0);
16
+ };
17
+ const handleImageLoad = ({ target }) => {
18
+ const img = target;
19
+ if (!canvasRef.current) {
18
20
  return;
19
21
  }
20
- canvas.width = sampleSize;
21
- canvas.height = sampleSize;
22
- ctx.drawImage(img, 0, 0, sampleSize, sampleSize);
23
22
  try {
24
- const imageData = ctx.getImageData(0, 0, sampleSize, sampleSize);
25
- const pixels = imageData.data;
26
- let r = 0;
27
- let g = 0;
28
- let b = 0;
29
- let totalWeight = 0;
30
- for (let i = 0; i < pixels.length; i += 4) {
31
- const red = pixels[i];
32
- const green = pixels[i + 1];
33
- const blue = pixels[i + 2];
34
- const alpha = pixels[i + 3];
35
- if (alpha === 0) continue;
36
- const max = Math.max(red, green, blue);
37
- const min = Math.min(red, green, blue);
38
- const saturation = max === 0 ? 0 : (max - min) / max;
39
- const weight = 1 + saturation * 2;
40
- r += red * weight;
41
- g += green * weight;
42
- b += blue * weight;
43
- totalWeight += weight;
44
- }
45
- if (totalWeight > 0) {
46
- r = Math.round(r / totalWeight);
47
- g = Math.round(g / totalWeight);
48
- b = Math.round(b / totalWeight);
49
- r = Math.round(r * contrast);
50
- g = Math.round(g * contrast);
51
- b = Math.round(b * contrast);
52
- setDominantColor(`rgb(${r}, ${g}, ${b})`);
23
+ const color = extractDominantColor(canvasRef.current, img, {
24
+ sampleSize,
25
+ contrast
26
+ });
27
+ if (color) {
28
+ setDominantColor(`rgb(${color[0]}, ${color[1]}, ${color[2]})`);
53
29
  }
54
30
  } catch {
55
31
  setCrossOriginState(void 0);
56
32
  }
57
- };
58
- const handleImageError = () => {
59
- setCrossOriginState(void 0);
60
- };
61
- const handleImageLoad = (ev) => {
62
- const img = ev.target;
63
- extractDominantColor(img);
64
33
  setImageLoaded(true);
65
34
  };
66
35
  return /* @__PURE__ */ React.createElement("div", {
@@ -96,6 +65,67 @@ var Image = ({ classNames, src, alt = "", crossOrigin = "anonymous", sampleSize
96
65
  _effect.f();
97
66
  }
98
67
  };
68
+ var extractDominantColor = (canvas, img, { sampleSize = 64, contrast = 0.95 }) => {
69
+ const ctx = canvas.getContext("2d");
70
+ if (!ctx) {
71
+ return null;
72
+ }
73
+ canvas.width = sampleSize;
74
+ canvas.height = sampleSize;
75
+ ctx.drawImage(img, 0, 0, sampleSize, sampleSize);
76
+ const imageData = ctx.getImageData(0, 0, sampleSize, sampleSize);
77
+ const pixels = imageData.data;
78
+ if (isTransparent(pixels, sampleSize)) {
79
+ return null;
80
+ }
81
+ let r = 0;
82
+ let g = 0;
83
+ let b = 0;
84
+ let totalWeight = 0;
85
+ for (let i = 0; i < pixels.length; i += 4) {
86
+ const red = pixels[i];
87
+ const green = pixels[i + 1];
88
+ const blue = pixels[i + 2];
89
+ const alpha = pixels[i + 3];
90
+ if (alpha === 0) continue;
91
+ const max = Math.max(red, green, blue);
92
+ const min = Math.min(red, green, blue);
93
+ const saturation = max === 0 ? 0 : (max - min) / max;
94
+ const weight = 1 + saturation * 2;
95
+ r += red * weight;
96
+ g += green * weight;
97
+ b += blue * weight;
98
+ totalWeight += weight;
99
+ }
100
+ if (totalWeight > 0) {
101
+ r = Math.round(Math.round(r / totalWeight) * contrast);
102
+ g = Math.round(Math.round(g / totalWeight) * contrast);
103
+ b = Math.round(Math.round(b / totalWeight) * contrast);
104
+ return [
105
+ r,
106
+ g,
107
+ b
108
+ ];
109
+ }
110
+ return null;
111
+ };
112
+ var isTransparent = (pixels, sampleSize, threshold = 0.5) => {
113
+ let edgeTransparentPixels = 0;
114
+ const edgePixels = sampleSize * 4 - 4;
115
+ for (let x = 0; x < sampleSize; x++) {
116
+ const topIndex = x * 4;
117
+ if (pixels[topIndex + 3] === 0) edgeTransparentPixels++;
118
+ const bottomIndex = ((sampleSize - 1) * sampleSize + x) * 4;
119
+ if (pixels[bottomIndex + 3] === 0) edgeTransparentPixels++;
120
+ }
121
+ for (let y = 1; y < sampleSize - 1; y++) {
122
+ const leftIndex = y * sampleSize * 4;
123
+ if (pixels[leftIndex + 3] === 0) edgeTransparentPixels++;
124
+ const rightIndex = (y * sampleSize + sampleSize - 1) * 4;
125
+ if (pixels[rightIndex + 3] === 0) edgeTransparentPixels++;
126
+ }
127
+ return edgeTransparentPixels / edgePixels > threshold;
128
+ };
99
129
 
100
130
  // src/components/StackContext.tsx
101
131
  import { createContext, useContext } from "react";
@@ -206,11 +236,12 @@ var scrollIntoViewAndFocus = (el, orientation) => {
206
236
  });
207
237
  return el.focus();
208
238
  };
209
- var Stack = /* @__PURE__ */ forwardRef(({ children, classNames, style, orientation = "vertical", rail = true, size = "intrinsic", onRearrange, itemsCount = Children.count(children), getDropElement, separatorOnScroll, ...props }, forwardedRef) => {
239
+ var Stack = /* @__PURE__ */ forwardRef(({ children, classNames, style, orientation = "vertical", rail = true, size = "intrinsic", onRearrange, itemsCount = Children.count(children), getDropElement, separatorOnScroll, circularFocus, ...props }, forwardedRef) => {
210
240
  var _effect = _useSignals2();
211
241
  try {
212
242
  const stackId = useId("stack", props.id);
213
243
  const [stackElement, stackRef] = useState3(null);
244
+ const [lastFocusedItem, setLastFocusedItem] = useState3();
214
245
  const composedItemRef = composeRefs(stackRef, forwardedRef);
215
246
  const styles = {
216
247
  [orientation === "horizontal" ? "gridTemplateColumns" : "gridTemplateRows"]: size === "split" ? `repeat(${itemsCount}, 1fr)` : `repeat(${itemsCount}, min-content) [tabster-dummies] 0`,
@@ -241,6 +272,19 @@ var Stack = /* @__PURE__ */ forwardRef(({ children, classNames, style, orientati
241
272
  separatorOnScroll,
242
273
  orientation
243
274
  ]);
275
+ const handleBlur = useCallback((event) => {
276
+ if (event.target) {
277
+ const target = event.target;
278
+ const closestStackItem = target.closest(`[data-dx-item-id]`);
279
+ if (closestStackItem?.closest(`[data-dx-stack="${stackId}"]`)) {
280
+ setLastFocusedItem(closestStackItem?.getAttribute("data-dx-item-id") ?? void 0);
281
+ }
282
+ }
283
+ props.onBlur?.(event);
284
+ }, [
285
+ stackId,
286
+ props.onBlur
287
+ ]);
244
288
  const handleKeyDown = useCallback((event) => {
245
289
  const target = event.target;
246
290
  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)}"]`)) {
@@ -254,7 +298,16 @@ var Stack = /* @__PURE__ */ forwardRef(({ children, classNames, style, orientati
254
298
  const parallelDelta = (closestStackOrientation === "vertical" ? event.key === "ArrowUp" : event.key === "ArrowLeft") ? -1 : (closestStackOrientation === "vertical" ? event.key === "ArrowDown" : event.key === "ArrowRight") ? 1 : 0;
255
299
  const perpendicularDelta = (closestStackOrientation === "vertical" ? event.key === "ArrowLeft" : event.key === "ArrowUp") ? -1 : (closestStackOrientation === "vertical" ? event.key === "ArrowRight" : event.key === "ArrowDown") ? 1 : 0;
256
300
  if (parallelDelta !== 0) {
257
- const adjacentItem = closestStackItems[(closestStackItems.indexOf(closestOwnedItem) + parallelDelta + closestStackItems.length) % closestStackItems.length];
301
+ const currentIndex = closestStackItems.indexOf(closestOwnedItem);
302
+ const nextIndex = currentIndex + parallelDelta;
303
+ let adjacentItem;
304
+ if (circularFocus) {
305
+ adjacentItem = closestStackItems[(nextIndex + closestStackItems.length) % closestStackItems.length];
306
+ } else {
307
+ if (nextIndex >= 0 && nextIndex < closestStackItems.length) {
308
+ adjacentItem = closestStackItems[nextIndex];
309
+ }
310
+ }
258
311
  if (adjacentItem) {
259
312
  event.preventDefault();
260
313
  scrollIntoViewAndFocus(adjacentItem, closestStackOrientation);
@@ -263,24 +316,38 @@ var Stack = /* @__PURE__ */ forwardRef(({ children, classNames, style, orientati
263
316
  if (perpendicularDelta !== 0) {
264
317
  if (ancestorStack && ancestorOrientation !== closestStackOrientation) {
265
318
  const siblingStacks = Array.from(ancestorStack.querySelectorAll(`[data-dx-stack-item="${ancestorStack.getAttribute("data-dx-stack")}"] [data-dx-stack]`));
266
- const adjacentStack = siblingStacks[(siblingStacks.indexOf(closestStack) + perpendicularDelta + siblingStacks.length) % siblingStacks.length];
319
+ const currentStackIndex = siblingStacks.indexOf(closestStack);
320
+ const nextStackIndex = currentStackIndex + perpendicularDelta;
321
+ let adjacentStack;
322
+ if (ancestorStack.getAttribute("data-dx-stack-circular-focus") === "true") {
323
+ adjacentStack = siblingStacks[(nextStackIndex + siblingStacks.length) % siblingStacks.length];
324
+ } else {
325
+ if (nextStackIndex >= 0 && nextStackIndex < siblingStacks.length) {
326
+ adjacentStack = siblingStacks[nextStackIndex];
327
+ }
328
+ }
267
329
  const adjacentStackSelfItem = adjacentStack?.closest(`[data-dx-stack-item=${ancestorStack.getAttribute("data-dx-stack")}]`);
268
330
  const adjacentStackItems = adjacentStack ? Array.from(adjacentStack.querySelectorAll(`[data-dx-stack-item="${adjacentStack.getAttribute("data-dx-stack")}"]`)) : [];
269
- if (adjacentStackItems.length > 0) {
270
- const ownedItemRect = closestOwnedItem.getBoundingClientRect();
271
- const targetPosition = closestStackOrientation === "vertical" ? ownedItemRect.top : ownedItemRect.left;
331
+ if (adjacentStack && adjacentStackItems.length > 0) {
272
332
  let closestItem = adjacentStackItems[0];
273
- let closestDistance = Infinity;
274
- for (const item of adjacentStackItems) {
275
- const itemRect = item.getBoundingClientRect();
276
- const itemPosition = closestStackOrientation === "vertical" ? itemRect.top : itemRect.left;
277
- const distance = Math.abs(itemPosition - targetPosition);
278
- if (distance < closestDistance) {
279
- closestDistance = distance;
280
- closestItem = item;
281
- }
282
- if (closestDistance <= PERPENDICULAR_FOCUS_THRESHHOLD) {
283
- break;
333
+ const lastFocusedItem2 = adjacentStack.querySelector(`[data-dx-item-id="${adjacentStack.getAttribute("data-dx-last-focused-item") ?? "never"}"]`);
334
+ if (lastFocusedItem2) {
335
+ closestItem = lastFocusedItem2;
336
+ } else {
337
+ const ownedItemRect = closestOwnedItem.getBoundingClientRect();
338
+ const targetPosition = closestStackOrientation === "vertical" ? ownedItemRect.top : ownedItemRect.left;
339
+ let closestDistance = Infinity;
340
+ for (const item of adjacentStackItems) {
341
+ const itemRect = item.getBoundingClientRect();
342
+ const itemPosition = closestStackOrientation === "vertical" ? itemRect.top : itemRect.left;
343
+ const distance = Math.abs(itemPosition - targetPosition);
344
+ if (distance < closestDistance) {
345
+ closestDistance = distance;
346
+ closestItem = item;
347
+ }
348
+ if (closestDistance <= PERPENDICULAR_FOCUS_THRESHHOLD) {
349
+ break;
350
+ }
284
351
  }
285
352
  }
286
353
  event.preventDefault();
@@ -306,7 +373,8 @@ var Stack = /* @__PURE__ */ forwardRef(({ children, classNames, style, orientati
306
373
  props.onKeyDown?.(event);
307
374
  }, [
308
375
  props.onKeyDown,
309
- stackId
376
+ stackId,
377
+ circularFocus
310
378
  ]);
311
379
  const gridClasses = useMemo(() => {
312
380
  if (!rail) {
@@ -352,7 +420,10 @@ var Stack = /* @__PURE__ */ forwardRef(({ children, classNames, style, orientati
352
420
  ...props,
353
421
  className: mx2("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),
354
422
  onKeyDown: handleKeyDown,
423
+ onBlur: handleBlur,
355
424
  "data-dx-stack": stackId,
425
+ "data-dx-stack-circular-focus": circularFocus,
426
+ "data-dx-last-focused-item": lastFocusedItem,
356
427
  "data-rail": rail,
357
428
  "aria-orientation": orientation,
358
429
  style: styles,
@@ -397,7 +468,7 @@ import { draggable, dropTargetForElements as dropTargetForElements2 } from "@atl
397
468
  import { preserveOffsetOnSource } from "@atlaskit/pragmatic-drag-and-drop/element/preserve-offset-on-source";
398
469
  import { setCustomNativeDragPreview } from "@atlaskit/pragmatic-drag-and-drop/element/set-custom-native-drag-preview";
399
470
  import { attachClosestEdge as attachClosestEdge2, extractClosestEdge as extractClosestEdge2 } from "@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge";
400
- import { useFocusableGroup as useFocusableGroup2 } from "@fluentui/react-tabster";
471
+ import { useFocusableGroup } from "@fluentui/react-tabster";
401
472
  import { composeRefs as composeRefs2 } from "@radix-ui/react-compose-refs";
402
473
  import React9, { forwardRef as forwardRef5, useCallback as useCallback2, useLayoutEffect as useLayoutEffect2, useMemo as useMemo3, useState as useState5 } from "react";
403
474
  import { createPortal } from "react-dom";
@@ -409,7 +480,7 @@ import { mx as mx6 } from "@dxos/react-ui-theme";
409
480
  import { useSignals as _useSignals3 } from "@preact-signals/safe-react/tracking";
410
481
  import React3, { forwardRef as forwardRef2, useMemo as useMemo2 } from "react";
411
482
  import { mx as mx3 } from "@dxos/react-ui-theme";
412
- var StackItemContent = /* @__PURE__ */ forwardRef2(({ children, toolbar, statusbar, layoutManaged, classNames, size = "intrinsic", ...props }, forwardedRef) => {
483
+ var StackItemContent = /* @__PURE__ */ forwardRef2(({ children, toolbar, statusbar, layoutManaged, classNames, size = "intrinsic", scrollable, ...props }, forwardedRef) => {
413
484
  var _effect = _useSignals3();
414
485
  try {
415
486
  const { size: stackItemSize } = useStack();
@@ -432,7 +503,7 @@ var StackItemContent = /* @__PURE__ */ forwardRef2(({ children, toolbar, statusb
432
503
  return /* @__PURE__ */ React3.createElement("div", {
433
504
  role: "none",
434
505
  ...props,
435
- className: mx3("group grid grid-cols-[100%] density-coarse", 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),
506
+ className: mx3("group grid grid-cols-[100%] density-coarse", size === "video" ? "aspect-video" : size === "square" && "aspect-square", stackItemSize === "contain" && "min-bs-0 overflow-hidden", scrollable ? "min-bs-0 overflow-y-auto scrollbar-thin contain-layout" : "overflow-hidden", role === "section" && toolbar && "[&_.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),
436
507
  style,
437
508
  "data-popover-collision-boundary": true,
438
509
  ref: forwardedRef
@@ -462,7 +533,6 @@ var StackItemDragHandle = ({ asChild, children }) => {
462
533
 
463
534
  // src/components/StackItem/StackItemHeading.tsx
464
535
  import { useSignals as _useSignals5 } from "@preact-signals/safe-react/tracking";
465
- import { useFocusableGroup } from "@fluentui/react-tabster";
466
536
  import { Slot as Slot2 } from "@radix-ui/react-slot";
467
537
  import React5, { forwardRef as forwardRef3 } from "react";
468
538
  import { useAttention } from "@dxos/react-ui-attention";
@@ -471,16 +541,11 @@ var StackItemHeading = ({ children, classNames, asChild, separateOnScroll, ...pr
471
541
  var _effect = _useSignals5();
472
542
  try {
473
543
  const { orientation } = useStack();
474
- const focusableGroupAttrs = useFocusableGroup({
475
- tabBehavior: "limited"
476
- });
477
544
  const Root = asChild ? Slot2 : "div";
478
545
  return /* @__PURE__ */ React5.createElement(Root, {
479
546
  role: "heading",
480
547
  ...props,
481
- tabIndex: 0,
482
- ...focusableGroupAttrs,
483
- className: mx4("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)
548
+ className: mx4("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)
484
549
  }, children);
485
550
  } finally {
486
551
  _effect.f();
@@ -790,7 +855,7 @@ var StackItemRoot = /* @__PURE__ */ forwardRef5(({ item, children, classNames, s
790
855
  selfDragHandleElement,
791
856
  itemElement
792
857
  ]);
793
- const focusableGroupAttrs = useFocusableGroup2({
858
+ const focusableGroupAttrs = useFocusableGroup({
794
859
  tabBehavior: "limited"
795
860
  });
796
861
  const shouldShowDropIndicator = () => {
@@ -831,8 +896,9 @@ var StackItemRoot = /* @__PURE__ */ forwardRef5(({ item, children, classNames, s
831
896
  ...props,
832
897
  tabIndex: 0,
833
898
  ...focusableGroupAttrs,
834
- className: mx6("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),
899
+ className: mx6("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),
835
900
  "data-dx-stack-item": stackId,
901
+ "data-dx-item-id": item.id,
836
902
  ...resizeAttributes,
837
903
  style: {
838
904
  ...stackSize !== "split" && sizeStyle(size, orientation),
@@ -882,7 +948,7 @@ var cardDialogPaddedOverflow = `${cardDialogOverflow} plb-cardSpacingBlock`;
882
948
  var cardDialogSearchListRoot = "pli-cardSpacingInline pbs-cardSpacingBlock [&>input]:mbe-0 min-bs-0 flex-1 flex flex-col";
883
949
  var cardText = cardSpacing;
884
950
  var cardHeading = "text-lg font-medium line-clamp-2 grow";
885
- var cardChrome = "pli-[--dx-cardSpacingChrome] mlb-[--dx-cardSpacingChrome] [&_.dx-button]:text-start [&_.dx-button]:is-full";
951
+ var cardChrome = "pli-[--dx-cardSpacingChrome] mlb-[--dx-cardSpacingChrome] [&_.dx-button]:text-start [&_.dx-button]:is-full [&_.dx-button]:pis-[calc(var(--dx-cardSpacingInline)-var(--dx-cardSpacingChrome))]";
886
952
 
887
953
  // src/exemplars/Card/Card.tsx
888
954
  import { useSignals as _useSignals10 } from "@preact-signals/safe-react/tracking";
@@ -891,6 +957,8 @@ import { Slot as Slot3 } from "@radix-ui/react-slot";
891
957
  import React10, { forwardRef as forwardRef6 } from "react";
892
958
  import { Icon as Icon2, IconButton, Toolbar, useTranslation as useTranslation2 } from "@dxos/react-ui";
893
959
  import { hoverableControls, mx as mx7 } from "@dxos/react-ui-theme";
960
+ var cardDefaultInlineSize = 18;
961
+ var cardStackDefaultInlineSizeRem = cardDefaultInlineSize + 2.125;
894
962
  var CardStaticRoot = /* @__PURE__ */ forwardRef6(({ children, classNames, asChild, role = "group", ...props }, forwardedRef) => {
895
963
  var _effect = _useSignals10();
896
964
  try {
@@ -1006,7 +1074,7 @@ var CardPoster = (props) => {
1006
1074
  if (props.image) {
1007
1075
  return /* @__PURE__ */ React10.createElement(Image, {
1008
1076
  classNames: [
1009
- `dx-card__poster is-full __bs-auto`,
1077
+ `dx-card__poster is-full`,
1010
1078
  aspect
1011
1079
  ],
1012
1080
  src: props.image,
@@ -1192,21 +1260,24 @@ var CardStackFooter = /* @__PURE__ */ forwardRef7(({ children, classNames, asChi
1192
1260
  _effect.f();
1193
1261
  }
1194
1262
  });
1195
- var cardStackContent = [
1196
- "shrink min-bs-0 bg-baseSurface border border-separator rounded-md grid dx-focus-ring-group-x-indicator kanban-drop",
1197
- railGridHorizontalContainFitContent
1198
- ];
1199
- var CardStackContent = /* @__PURE__ */ forwardRef7(({ children, classNames, asChild, role = "none", ...props }, forwardedRef) => {
1263
+ var cardStackContent = "shrink min-bs-0 bg-baseSurface border border-separator rounded-md grid dx-focus-ring-group-x-indicator kanban-drop";
1264
+ var CardStackContent = /* @__PURE__ */ forwardRef7(({ children, classNames, asChild, role = "none", footer = true, ...props }, forwardedRef) => {
1200
1265
  var _effect = _useSignals12();
1201
1266
  try {
1202
1267
  const Root = asChild ? Slot4 : "div";
1268
+ const baseClassNames = footer ? [
1269
+ cardStackContent,
1270
+ railGridHorizontalContainFitContent
1271
+ ] : [
1272
+ cardStackContent
1273
+ ];
1203
1274
  const rootProps = asChild ? {
1204
1275
  classNames: [
1205
- ...cardStackContent,
1276
+ ...baseClassNames,
1206
1277
  classNames
1207
1278
  ]
1208
1279
  } : {
1209
- className: mx9(...cardStackContent, classNames),
1280
+ className: mx9(...baseClassNames, classNames),
1210
1281
  role
1211
1282
  };
1212
1283
  return /* @__PURE__ */ React12.createElement(Root, {
@@ -1364,6 +1435,8 @@ export {
1364
1435
  cardText,
1365
1436
  cardHeading,
1366
1437
  cardChrome,
1438
+ cardDefaultInlineSize,
1439
+ cardStackDefaultInlineSizeRem,
1367
1440
  Card,
1368
1441
  CardDragPreview2 as CardDragPreview,
1369
1442
  cardStackHeading,
@@ -1374,4 +1447,4 @@ export {
1374
1447
  CardStack,
1375
1448
  CardStackDragPreview
1376
1449
  };
1377
- //# sourceMappingURL=chunk-HE3BRF7A.mjs.map
1450
+ //# sourceMappingURL=chunk-G2QYUH52.mjs.map