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