@dxos/react-ui-stack 0.8.4-main.f9ba587 → 0.8.4-main.fcc0d83b33

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 (107) hide show
  1. package/dist/lib/browser/index.mjs +535 -1013
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/browser/{testing → playwright}/index.mjs +5 -1
  5. package/dist/lib/browser/{testing → playwright}/index.mjs.map +3 -3
  6. package/dist/lib/browser/translations.mjs +23 -0
  7. package/dist/lib/browser/translations.mjs.map +7 -0
  8. package/dist/lib/node-esm/index.mjs +535 -1013
  9. package/dist/lib/node-esm/index.mjs.map +4 -4
  10. package/dist/lib/node-esm/meta.json +1 -1
  11. package/dist/lib/node-esm/{testing → playwright}/index.mjs +5 -1
  12. package/dist/lib/node-esm/{testing → playwright}/index.mjs.map +3 -3
  13. package/dist/lib/node-esm/translations.mjs +25 -0
  14. package/dist/lib/node-esm/translations.mjs.map +7 -0
  15. package/dist/types/src/components/Stack/Stack.d.ts +13 -10
  16. package/dist/types/src/components/Stack/Stack.d.ts.map +1 -1
  17. package/dist/types/src/components/Stack/Stack.stories.d.ts +12 -3
  18. package/dist/types/src/components/Stack/Stack.stories.d.ts.map +1 -1
  19. package/dist/types/src/components/StackContext.d.ts +2 -1
  20. package/dist/types/src/components/StackContext.d.ts.map +1 -1
  21. package/dist/types/src/components/StackItem/MenuSignifier.d.ts.map +1 -1
  22. package/dist/types/src/components/StackItem/StackItem.d.ts +14 -17
  23. package/dist/types/src/components/StackItem/StackItem.d.ts.map +1 -1
  24. package/dist/types/src/components/StackItem/StackItem.stories.d.ts +13 -5
  25. package/dist/types/src/components/StackItem/StackItem.stories.d.ts.map +1 -1
  26. package/dist/types/src/components/StackItem/StackItemContent.d.ts +4 -37
  27. package/dist/types/src/components/StackItem/StackItemContent.d.ts.map +1 -1
  28. package/dist/types/src/components/StackItem/StackItemDragHandle.d.ts.map +1 -1
  29. package/dist/types/src/components/StackItem/StackItemHeading.d.ts +2 -2
  30. package/dist/types/src/components/StackItem/StackItemHeading.d.ts.map +1 -1
  31. package/dist/types/src/components/StackItem/StackItemResizeHandle.d.ts +1 -1
  32. package/dist/types/src/components/StackItem/StackItemResizeHandle.d.ts.map +1 -1
  33. package/dist/types/src/components/StackItem/StackItemSigil.d.ts +2 -2
  34. package/dist/types/src/components/StackItem/StackItemSigil.d.ts.map +1 -1
  35. package/dist/types/src/components/index.d.ts +1 -1
  36. package/dist/types/src/components/index.d.ts.map +1 -1
  37. package/dist/types/src/components/{defs.d.ts → types.d.ts} +1 -1
  38. package/dist/types/src/components/types.d.ts.map +1 -0
  39. package/dist/types/src/hooks/useStackDropForElements.d.ts +9 -7
  40. package/dist/types/src/hooks/useStackDropForElements.d.ts.map +1 -1
  41. package/dist/types/src/index.d.ts +0 -2
  42. package/dist/types/src/index.d.ts.map +1 -1
  43. package/dist/types/src/playwright/index.d.ts.map +1 -0
  44. package/dist/types/src/playwright/playwright.config.d.ts.map +1 -1
  45. package/dist/types/src/playwright/stack-manager.d.ts.map +1 -0
  46. package/dist/types/src/translations.d.ts +10 -10
  47. package/dist/types/src/translations.d.ts.map +1 -1
  48. package/dist/types/tsconfig.tsbuildinfo +1 -1
  49. package/package.json +54 -46
  50. package/src/components/Stack/Stack.stories.tsx +15 -18
  51. package/src/components/Stack/Stack.tsx +239 -53
  52. package/src/components/StackContext.tsx +2 -1
  53. package/src/components/StackItem/MenuSignifier.tsx +2 -9
  54. package/src/components/StackItem/StackItem.stories.tsx +22 -18
  55. package/src/components/StackItem/StackItem.tsx +61 -43
  56. package/src/components/StackItem/StackItemContent.tsx +25 -44
  57. package/src/components/StackItem/StackItemDragHandle.tsx +4 -3
  58. package/src/components/StackItem/StackItemHeading.tsx +17 -20
  59. package/src/components/StackItem/StackItemResizeHandle.tsx +2 -2
  60. package/src/components/StackItem/StackItemSigil.tsx +11 -7
  61. package/src/components/index.ts +2 -1
  62. package/src/hooks/useStackDropForElements.ts +61 -47
  63. package/src/index.ts +0 -4
  64. package/src/{testing → playwright}/index.ts +1 -1
  65. package/src/playwright/playwright.config.ts +1 -1
  66. package/src/playwright/smoke.spec.ts +1 -1
  67. package/src/translations.ts +9 -9
  68. package/dist/types/src/components/defs.d.ts.map +0 -1
  69. package/dist/types/src/components/deprecated/LayoutControls.d.ts +0 -19
  70. package/dist/types/src/components/deprecated/LayoutControls.d.ts.map +0 -1
  71. package/dist/types/src/exemplars/Card/Card.d.ts +0 -57
  72. package/dist/types/src/exemplars/Card/Card.d.ts.map +0 -1
  73. package/dist/types/src/exemplars/Card/Card.stories.d.ts +0 -13
  74. package/dist/types/src/exemplars/Card/Card.stories.d.ts.map +0 -1
  75. package/dist/types/src/exemplars/Card/CardDragPreview.d.ts +0 -6
  76. package/dist/types/src/exemplars/Card/CardDragPreview.d.ts.map +0 -1
  77. package/dist/types/src/exemplars/Card/fragments.d.ts +0 -12
  78. package/dist/types/src/exemplars/Card/fragments.d.ts.map +0 -1
  79. package/dist/types/src/exemplars/Card/index.d.ts +0 -4
  80. package/dist/types/src/exemplars/Card/index.d.ts.map +0 -1
  81. package/dist/types/src/exemplars/CardStack/CardStack.d.ts +0 -40
  82. package/dist/types/src/exemplars/CardStack/CardStack.d.ts.map +0 -1
  83. package/dist/types/src/exemplars/CardStack/CardStack.stories.d.ts +0 -9
  84. package/dist/types/src/exemplars/CardStack/CardStack.stories.d.ts.map +0 -1
  85. package/dist/types/src/exemplars/CardStack/CardStackDragPreview.d.ts +0 -9
  86. package/dist/types/src/exemplars/CardStack/CardStackDragPreview.d.ts.map +0 -1
  87. package/dist/types/src/exemplars/CardStack/index.d.ts +0 -3
  88. package/dist/types/src/exemplars/CardStack/index.d.ts.map +0 -1
  89. package/dist/types/src/exemplars/index.d.ts +0 -3
  90. package/dist/types/src/exemplars/index.d.ts.map +0 -1
  91. package/dist/types/src/testing/index.d.ts.map +0 -1
  92. package/dist/types/src/testing/stack-manager.d.ts.map +0 -1
  93. package/src/components/deprecated/LayoutControls.tsx +0 -109
  94. package/src/exemplars/Card/Card.stories.tsx +0 -78
  95. package/src/exemplars/Card/Card.tsx +0 -167
  96. package/src/exemplars/Card/CardDragPreview.tsx +0 -22
  97. package/src/exemplars/Card/fragments.ts +0 -23
  98. package/src/exemplars/Card/index.ts +0 -7
  99. package/src/exemplars/CardStack/CardStack.stories.tsx +0 -172
  100. package/src/exemplars/CardStack/CardStack.tsx +0 -136
  101. package/src/exemplars/CardStack/CardStackDragPreview.tsx +0 -61
  102. package/src/exemplars/CardStack/index.ts +0 -6
  103. package/src/exemplars/index.ts +0 -6
  104. /package/dist/types/src/{testing → playwright}/index.d.ts +0 -0
  105. /package/dist/types/src/{testing → playwright}/stack-manager.d.ts +0 -0
  106. /package/src/components/{defs.ts → types.ts} +0 -0
  107. /package/src/{testing → playwright}/stack-manager.ts +0 -0
@@ -2,45 +2,49 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import '@dxos-theme';
6
-
7
5
  import { type Meta, type StoryObj } from '@storybook/react-vite';
8
6
  import React from 'react';
9
7
 
10
- import { Icon, DropdownMenu } from '@dxos/react-ui';
11
- import { withTheme } from '@dxos/storybook-utils';
8
+ import { DropdownMenu, Icon } from '@dxos/react-ui';
9
+ import { withTheme } from '@dxos/react-ui/testing';
12
10
 
13
- import { StackItem } from './StackItem';
11
+ import { StackItem, type StackItemRootProps } from './StackItem';
14
12
 
15
- const meta: Meta<typeof StackItem.Root> = {
16
- title: 'ui/react-ui-stack/StackItem',
17
- component: StackItem.Root,
18
- render: (args) => (
19
- <StackItem.Root role='section' {...args} classNames='w-[20rem] border border-separator'>
20
- <StackItem.Heading>
13
+ const DefaultStory = (props: StackItemRootProps) => {
14
+ return (
15
+ <StackItem.Root role='section' {...props} classNames='w-[20rem] border border-separator'>
16
+ <StackItem.Heading classNames='w-full border-b border-separator'>
21
17
  <span className='sr-only'>Title</span>
22
- <div role='none' className='sticky -block-start-px bg-[--sticky-bg] p-1 is-full'>
18
+ <div role='none' className='sticky -top-px bg-(--sticky-bg) p-1 w-full'>
23
19
  <DropdownMenu.Root>
24
20
  <DropdownMenu.Trigger asChild>
25
21
  <StackItem.SigilButton>
26
- <Icon icon='ph--dots-three--regular' size={5} />
22
+ <Icon icon='ph--dots-three--regular' />
27
23
  </StackItem.SigilButton>
28
24
  </DropdownMenu.Trigger>
29
25
  </DropdownMenu.Root>
30
26
  </div>
31
27
  </StackItem.Heading>
32
- <StackItem.Content classNames='p-2'>Content</StackItem.Content>
28
+ <StackItem.Content>
29
+ <div className='p-4 text-center'>Content</div>
30
+ </StackItem.Content>
33
31
  </StackItem.Root>
34
- ),
35
- decorators: [withTheme],
32
+ );
33
+ };
34
+
35
+ const meta = {
36
+ title: 'ui/react-ui-stack/StackItem',
37
+ component: StackItem.Root as any,
38
+ render: DefaultStory,
39
+ decorators: [withTheme()],
36
40
  parameters: {
37
41
  layout: 'centered',
38
42
  },
39
- };
43
+ } satisfies Meta<typeof DefaultStory>;
40
44
 
41
45
  export default meta;
42
46
 
43
- type Story = StoryObj<typeof StackItem.Root>;
47
+ type Story = StoryObj<typeof meta>;
44
48
 
45
49
  export const Default: Story = {
46
50
  args: {
@@ -2,82 +2,85 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';
6
- import { draggable, dropTargetForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
7
- import { preserveOffsetOnSource } from '@atlaskit/pragmatic-drag-and-drop/element/preserve-offset-on-source';
8
- import { setCustomNativeDragPreview } from '@atlaskit/pragmatic-drag-and-drop/element/set-custom-native-drag-preview';
9
5
  import {
6
+ type Edge,
10
7
  attachClosestEdge,
11
8
  extractClosestEdge,
12
- type Edge,
13
9
  } from '@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge';
10
+ import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';
11
+ import { draggable, dropTargetForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
12
+ import { preserveOffsetOnSource } from '@atlaskit/pragmatic-drag-and-drop/element/preserve-offset-on-source';
13
+ import { setCustomNativeDragPreview } from '@atlaskit/pragmatic-drag-and-drop/element/set-custom-native-drag-preview';
14
14
  import { useFocusableGroup } from '@fluentui/react-tabster';
15
15
  import { composeRefs } from '@radix-ui/react-compose-refs';
16
16
  import React, {
17
- forwardRef,
18
- useLayoutEffect,
19
- useState,
20
17
  type ComponentPropsWithRef,
21
- useCallback,
22
18
  type ReactNode,
19
+ forwardRef,
20
+ useCallback,
21
+ useLayoutEffect,
23
22
  useMemo,
23
+ useState,
24
24
  } from 'react';
25
25
  import { createPortal } from 'react-dom';
26
26
 
27
- import { type ThemedClassName, ListItem } from '@dxos/react-ui';
27
+ import { ListItem, type ThemedClassName } from '@dxos/react-ui';
28
28
  import { resizeAttributes, sizeStyle } from '@dxos/react-ui-dnd';
29
- import { mx } from '@dxos/react-ui-theme';
29
+ import { mx } from '@dxos/ui-theme';
30
30
 
31
+ import { type ItemDragState, StackItemContext, idle, useStack, useStackItem } from '../StackContext';
32
+ import { type StackItemData, type StackItemSize } from '../types';
31
33
  import { StackItemContent, type StackItemContentProps } from './StackItemContent';
32
34
  import { StackItemDragHandle, type StackItemDragHandleProps } from './StackItemDragHandle';
33
35
  import {
34
36
  StackItemHeading,
35
37
  StackItemHeadingLabel,
36
- type StackItemHeadingProps,
37
38
  type StackItemHeadingLabelProps,
39
+ type StackItemHeadingProps,
38
40
  StackItemHeadingStickyContent,
39
41
  } from './StackItemHeading';
40
42
  import { StackItemResizeHandle, type StackItemResizeHandleProps } from './StackItemResizeHandle';
41
43
  import {
42
44
  StackItemSigil,
43
- type StackItemSigilProps,
44
45
  type StackItemSigilAction,
45
- type StackItemSigilButtonProps,
46
46
  StackItemSigilButton,
47
+ type StackItemSigilButtonProps,
48
+ type StackItemSigilProps,
47
49
  } from './StackItemSigil';
48
- import { useStack, StackItemContext, idle, type ItemDragState, useStackItem } from '../StackContext';
49
- import { type StackItemSize, type StackItemData } from '../defs';
50
50
 
51
- // NOTE: 48rem fills the screen on a MacbookPro with the sidebars closed.
52
- export const DEFAULT_HORIZONTAL_SIZE = 48 satisfies StackItemSize;
53
51
  export const DEFAULT_VERTICAL_SIZE = 'min-content' satisfies StackItemSize;
52
+ export const DEFAULT_HORIZONTAL_SIZE = 50 satisfies StackItemSize;
54
53
  export const DEFAULT_EXTRINSIC_SIZE = DEFAULT_HORIZONTAL_SIZE satisfies StackItemSize;
55
54
 
55
+ //
56
+ // StackItemRoot
57
+ //
58
+
56
59
  type StackItemRootProps = ThemedClassName<ComponentPropsWithRef<'div'>> & {
60
+ role?: 'article' | 'section';
57
61
  item: Omit<StackItemData, 'type'>;
58
62
  order?: number;
59
63
  prevSiblingId?: string;
60
64
  nextSiblingId?: string;
61
65
  size?: StackItemSize;
62
66
  onSizeChange?: (nextSize: StackItemSize) => void;
63
- role?: 'article' | 'section';
64
67
  disableRearrange?: boolean;
65
- focusIndicatorVariant?: 'over-all' | 'group';
68
+ focusIndicatorVariant?: 'over-all' | 'group' | 'over-all-always' | 'group-always';
66
69
  };
67
70
 
68
71
  const StackItemRoot = forwardRef<HTMLDivElement, StackItemRootProps>(
69
72
  (
70
73
  {
71
- item,
72
- children,
73
74
  classNames,
74
- size: propsSize,
75
- onSizeChange,
75
+ children,
76
+ style,
76
77
  role,
78
+ item,
77
79
  order,
78
80
  prevSiblingId,
79
81
  nextSiblingId,
80
- style,
82
+ size: sizeProp,
83
+ onSizeChange,
81
84
  disableRearrange,
82
85
  focusIndicatorVariant = 'over-all',
83
86
  ...props
@@ -85,18 +88,17 @@ const StackItemRoot = forwardRef<HTMLDivElement, StackItemRootProps>(
85
88
  forwardedRef,
86
89
  ) => {
87
90
  const [itemElement, itemRef] = useState<HTMLDivElement | null>(null);
91
+ const composedItemRef = composeRefs<HTMLDivElement>(itemRef, forwardedRef);
88
92
  const [selfDragHandleElement, selfDragHandleRef] = useState<HTMLDivElement | null>(null);
89
93
  const [closestEdge, setEdge] = useState<Edge | null>(null);
90
94
  const [sourceId, setSourceId] = useState<string | null>(null);
91
95
  const [dragState, setDragState] = useState<ItemDragState>(idle);
92
- const { orientation, rail, onRearrange } = useStack();
96
+ const { orientation, rail, onRearrange, size: stackSize, stackId } = useStack();
93
97
  const [size = orientation === 'horizontal' ? DEFAULT_HORIZONTAL_SIZE : DEFAULT_VERTICAL_SIZE, setInternalSize] =
94
- useState(propsSize);
98
+ useState(sizeProp);
95
99
 
96
100
  const Root = role ?? 'div';
97
101
 
98
- const composedItemRef = composeRefs<HTMLDivElement>(itemRef, forwardedRef);
99
-
100
102
  const setSize = useCallback(
101
103
  (nextSize: StackItemSize, commit?: boolean) => {
102
104
  setInternalSize(nextSize);
@@ -109,6 +111,7 @@ const StackItemRoot = forwardRef<HTMLDivElement, StackItemRootProps>(
109
111
 
110
112
  const type = orientation === 'horizontal' ? 'column' : 'card';
111
113
 
114
+ // TODO(burdon): Factor out?
112
115
  useLayoutEffect(() => {
113
116
  if (!itemElement || !onRearrange || disableRearrange) {
114
117
  return;
@@ -182,18 +185,18 @@ const StackItemRoot = forwardRef<HTMLDivElement, StackItemRootProps>(
182
185
 
183
186
  const focusableGroupAttrs = useFocusableGroup({ tabBehavior: 'limited' });
184
187
 
185
- // Determine if the drop would result in any changes
188
+ // Determine if the drop would result in any changes.
186
189
  const shouldShowDropIndicator = () => {
187
190
  if (!closestEdge || !sourceId) {
188
191
  return false;
189
192
  }
190
193
 
191
- // Don't show indicator when dragged item is over itself
194
+ // Don't show indicator when dragged item is over itself.
192
195
  if (sourceId === item.id) {
193
196
  return false;
194
197
  }
195
198
 
196
- // Don't show indicator when dragged item is over the trailing edge of its previous sibling
199
+ // Don't show indicator when dragged item is over the trailing edge of its previous sibling.
197
200
  const isTrailingEdgeOfPrevSibling =
198
201
  prevSiblingId !== undefined &&
199
202
  sourceId === prevSiblingId &&
@@ -231,18 +234,25 @@ const StackItemRoot = forwardRef<HTMLDivElement, StackItemRootProps>(
231
234
  'group/stack-item grid relative',
232
235
  focusIndicatorVariant === 'over-all'
233
236
  ? 'dx-focus-ring-inset-over-all'
234
- : orientation === 'horizontal'
235
- ? 'dx-focus-ring-group-x'
236
- : 'dx-focus-ring-group-y',
237
+ : focusIndicatorVariant === 'over-all-always'
238
+ ? 'dx-focus-ring-inset-over-all-always'
239
+ : orientation === 'horizontal'
240
+ ? focusIndicatorVariant === 'group-always'
241
+ ? 'dx-focus-ring-group-x-always'
242
+ : 'dx-focus-ring-group-x'
243
+ : focusIndicatorVariant === 'group-always'
244
+ ? 'dx-focus-ring-group-y-always'
245
+ : 'dx-focus-ring-group-y',
237
246
  orientation === 'horizontal' ? 'grid-rows-subgrid' : 'grid-cols-subgrid',
238
247
  rail && (orientation === 'horizontal' ? 'row-span-2' : 'col-span-2'),
239
- role === 'section' && orientation !== 'horizontal' && 'border-be border-subduedSeparator',
248
+ role === 'section' && orientation !== 'horizontal' && 'border-b border-subdued-separator',
240
249
  classNames,
241
250
  )}
242
- data-dx-stack-item
251
+ data-dx-stack-item={stackId}
252
+ data-dx-item-id={item.id}
243
253
  {...resizeAttributes}
244
254
  style={{
245
- ...sizeStyle(size, orientation),
255
+ ...(stackSize !== 'split' && sizeStyle(size, orientation)),
246
256
  ...(Number.isFinite(order) && {
247
257
  [orientation === 'horizontal' ? 'gridColumn' : 'gridRow']: `${order}`,
248
258
  }),
@@ -260,37 +270,45 @@ const StackItemRoot = forwardRef<HTMLDivElement, StackItemRootProps>(
260
270
  },
261
271
  );
262
272
 
273
+ //
274
+ // StackItemDragPreview
275
+ //
276
+
263
277
  type StackItemDragPreviewProps = {
264
278
  children: ({ item }: { item: any }) => ReactNode;
265
279
  };
266
280
 
267
- export const StackItemDragPreview = ({ children }: StackItemDragPreviewProps) => {
281
+ const StackItemDragPreview = ({ children }: StackItemDragPreviewProps) => {
268
282
  const { state } = useStackItem();
269
283
  return state?.type === 'preview' ? createPortal(children({ item: state.item }), state.container) : null;
270
284
  };
271
285
 
286
+ //
287
+ // StackItem
288
+ //
289
+
272
290
  export const StackItem = {
273
291
  Root: StackItemRoot,
274
292
  Content: StackItemContent,
293
+ DragHandle: StackItemDragHandle,
294
+ DragPreview: StackItemDragPreview,
275
295
  Heading: StackItemHeading,
276
296
  HeadingLabel: StackItemHeadingLabel,
277
297
  HeadingStickyContent: StackItemHeadingStickyContent,
278
298
  ResizeHandle: StackItemResizeHandle,
279
- DragHandle: StackItemDragHandle,
280
299
  Sigil: StackItemSigil,
281
300
  SigilButton: StackItemSigilButton,
282
- DragPreview: StackItemDragPreview,
283
301
  };
284
302
 
285
303
  export type {
286
304
  StackItemRootProps,
287
305
  StackItemContentProps,
306
+ StackItemDragHandleProps,
307
+ StackItemDragPreviewProps,
288
308
  StackItemHeadingProps,
289
309
  StackItemHeadingLabelProps,
290
310
  StackItemResizeHandleProps,
291
- StackItemDragHandleProps,
292
311
  StackItemSigilProps,
293
312
  StackItemSigilButtonProps,
294
313
  StackItemSigilAction,
295
- StackItemDragPreviewProps,
296
314
  };
@@ -5,70 +5,49 @@
5
5
  import React, { type ComponentPropsWithoutRef, forwardRef, useMemo } from 'react';
6
6
 
7
7
  import { type ThemedClassName } from '@dxos/react-ui';
8
- import { mx } from '@dxos/react-ui-theme';
8
+ import { mx } from '@dxos/ui-theme';
9
9
 
10
10
  import { useStack, useStackItem } from '../StackContext';
11
11
 
12
- export type StackItemContentProps = ThemedClassName<ComponentPropsWithoutRef<'div'>> & {
13
- /**
14
- * This flag is required in order to clarify a developer experience that seemed like it needed extra boilerplate
15
- * (`row-span-2`) or was buggy. See the description of the StackItem.Content component itself for more information.
16
- */
12
+ export type StackItemContentProps = ThemedClassName<Omit<ComponentPropsWithoutRef<'div'>, 'role' | 'scrollable'>> & {
17
13
  toolbar?: boolean;
18
-
19
- /**
20
- * Whether to provide for the layout of a statusbar after the content.
21
- */
22
14
  statusbar?: boolean;
23
-
24
- /**
25
- * Whether the consumer intends to do something custom and typical affordances should not apply
26
- */
27
- layoutManaged?: boolean;
28
-
29
- /**
30
- * Whether to set a certain aspect ratio on the content, including the toolbar and statusbar. This is provided for
31
- * convenience and consistency; it can instead be specified by the `classNames` or `style` props as needed.
32
- */
33
- size?: 'intrinsic' | 'video' | 'square';
34
15
  };
35
16
 
36
17
  /**
37
- * This component should be used by plugins for rendering content within a stack item, a.k.a. a “plank” or “section”.
38
- * The `toolbar` flag must be provided since this component provides for the layout of content with the toolbar.
18
+ * This component should be used by plugins for rendering content within a stack item (i.e., a “plank” or “section”).
39
19
  */
40
20
  export const StackItemContent = forwardRef<HTMLDivElement, StackItemContentProps>(
41
- ({ children, toolbar, statusbar, layoutManaged, classNames, size = 'intrinsic', ...props }, forwardedRef) => {
21
+ ({ classNames, children, toolbar, statusbar, ...props }, forwardedRef) => {
42
22
  const { size: stackItemSize } = useStack();
43
23
  const { role } = useStackItem();
44
24
  const style = useMemo(
45
- () =>
46
- layoutManaged
47
- ? {}
48
- : {
49
- gridTemplateRows: [
50
- ...(toolbar ? [role === 'section' ? 'calc(var(--toolbar-size) - 1px)' : 'var(--toolbar-size)'] : []),
51
- '1fr',
52
- ...(statusbar ? ['var(--statusbar-size)'] : []),
53
- ].join(' '),
54
- },
55
- [toolbar, statusbar, layoutManaged],
25
+ () => ({
26
+ gridTemplateRows: [
27
+ toolbar && role === 'section' ? 'calc(var(--dx-toolbar-size) - 1px)' : 'var(--dx-toolbar-size)',
28
+ '1fr',
29
+ statusbar && 'var(--dx-statusbar-size)',
30
+ ]
31
+ .filter(Boolean)
32
+ .join(' '),
33
+ }),
34
+ [toolbar, statusbar],
56
35
  );
36
+
57
37
  return (
58
38
  <div
59
- role='none'
60
39
  {...props}
40
+ role='none'
41
+ style={style}
61
42
  className={mx(
62
- 'group grid grid-cols-[100%]',
63
- stackItemSize === 'contain' && 'min-bs-0 overflow-hidden',
64
- size === 'video' ? 'aspect-video' : size === 'square' && 'aspect-square',
65
- toolbar && '[&_.dx-toolbar]:relative [&_.dx-toolbar]:border-be [&_.dx-toolbar]:border-subduedSeparator',
66
- role === 'section' &&
67
- toolbar &&
68
- '[&_.dx-toolbar]:sticky [&_.dx-toolbar]:z-[1] [&_.dx-toolbar]:block-start-0 [&_.dx-toolbar]:-mbe-px [&_.dx-toolbar]:min-is-0',
43
+ 'group grid grid-cols-[100%] dx-density-coarse',
44
+ stackItemSize === 'contain' && 'min-h-0 overflow-hidden',
45
+ toolbar &&
46
+ role === 'section' &&
47
+ '[&_.dx-toolbar]:sticky [&_.dx-toolbar]:z-[1] [&_.dx-toolbar]:top-0 [&_.dx-toolbar]:-mb-px [&_.dx-toolbar]:min-w-0',
48
+ toolbar && '[&>.dx-toolbar]:relative [&>.dx-toolbar]:border-b [&>.dx-toolbar]:border-subdued-separator',
69
49
  classNames,
70
50
  )}
71
- style={style}
72
51
  data-popover-collision-boundary={true}
73
52
  ref={forwardedRef}
74
53
  >
@@ -77,3 +56,5 @@ export const StackItemContent = forwardRef<HTMLDivElement, StackItemContentProps
77
56
  );
78
57
  },
79
58
  );
59
+
60
+ StackItemContent.displayName = 'StackItemContent';
@@ -2,6 +2,7 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
+ import { Primitive } from '@radix-ui/react-primitive';
5
6
  import { Slot } from '@radix-ui/react-slot';
6
7
  import React, { type ComponentPropsWithoutRef } from 'react';
7
8
 
@@ -12,11 +13,11 @@ export type StackItemDragHandleProps = ComponentPropsWithoutRef<'button'> & { as
12
13
  export const StackItemDragHandle = ({ asChild, children }: StackItemDragHandleProps) => {
13
14
  const { selfDragHandleRef } = useStackItem();
14
15
 
15
- const Root = asChild ? Slot : 'div';
16
+ const Comp = asChild ? Slot : Primitive.div;
16
17
 
17
18
  return (
18
- <Root ref={selfDragHandleRef} role='button'>
19
+ <Comp ref={selfDragHandleRef} role='button'>
19
20
  {children}
20
- </Root>
21
+ </Comp>
21
22
  );
22
23
  };
@@ -2,18 +2,18 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import { useFocusableGroup } from '@fluentui/react-tabster';
5
+ import { Primitive } from '@radix-ui/react-primitive';
6
6
  import { Slot } from '@radix-ui/react-slot';
7
7
  import React, {
8
- type ComponentPropsWithoutRef,
9
8
  type ComponentPropsWithRef,
10
- forwardRef,
9
+ type ComponentPropsWithoutRef,
11
10
  type PropsWithChildren,
11
+ forwardRef,
12
12
  } from 'react';
13
13
 
14
14
  import { type ThemedClassName } from '@dxos/react-ui';
15
- import { useAttention, type AttendableId, type Related } from '@dxos/react-ui-attention';
16
- import { mx } from '@dxos/react-ui-theme';
15
+ import { type AttendableId, type Related, useAttention } from '@dxos/react-ui-attention';
16
+ import { mx } from '@dxos/ui-theme';
17
17
 
18
18
  import { useStack } from '../StackContext';
19
19
 
@@ -27,37 +27,34 @@ export const StackItemHeading = ({
27
27
  classNames,
28
28
  asChild,
29
29
  separateOnScroll,
30
+ role,
30
31
  ...props
31
32
  }: StackItemHeadingProps) => {
32
33
  const { orientation } = useStack();
33
- const focusableGroupAttrs = useFocusableGroup({ tabBehavior: 'limited' });
34
-
35
- const Root = asChild ? Slot : 'div';
34
+ const Comp = asChild ? Slot : Primitive.div;
36
35
 
37
36
  return (
38
- <Root
39
- role='heading'
37
+ <Comp
40
38
  {...props}
41
- tabIndex={0}
42
- {...focusableGroupAttrs}
39
+ role={role ?? 'heading'}
43
40
  className={mx(
44
- 'flex items-center dx-focus-ring-inset-over-all relative !border-is-0 bg-headerSurface',
41
+ 'flex items-center border-x-0! bg-header-surface',
45
42
  separateOnScroll
46
- ? 'border-transparent [[data-scroll-separator="true"]_&]:border-subduedSeparator'
47
- : 'border-subduedSeparator',
48
- orientation === 'horizontal' ? 'bs-[--rail-size]' : 'is-[--rail-size] flex-col',
49
- orientation === 'horizontal' ? 'border-be' : 'border-ie',
43
+ ? 'border-transparent [[data-scroll-separator="true"]_&]:border-subdued-separator'
44
+ : 'border-subdued-separator',
45
+ orientation === 'horizontal' ? 'h-(--dx-rail-size)' : 'w-(--dx-rail-size) flex-col',
46
+ orientation === 'horizontal' ? 'border-b' : 'border-e',
50
47
  classNames,
51
48
  )}
52
49
  >
53
50
  {children}
54
- </Root>
51
+ </Comp>
55
52
  );
56
53
  };
57
54
 
58
55
  export const StackItemHeadingStickyContent = ({ children }: PropsWithChildren<{}>) => {
59
56
  return (
60
- <div role='none' className='sticky block-start-0 bg-[--sticky-bg] p-1 is-full'>
57
+ <div role='none' className='sticky top-0 bg-(--sticky-bg) p-1 w-full'>
61
58
  {children}
62
59
  </div>
63
60
  );
@@ -74,7 +71,7 @@ export const StackItemHeadingLabel = forwardRef<HTMLHeadingElement, StackItemHea
74
71
  {...props}
75
72
  data-attention={((related && isRelated) || hasAttention || isAncestor).toString()}
76
73
  className={mx(
77
- 'pli-1 min-is-0 is-0 grow truncate font-medium text-baseText data-[attention=true]:text-accentText self-center',
74
+ 'px-1 min-w-0 w-0 grow truncate font-medium text-base-surface-text data-[attention=true]:text-accent-text self-center',
78
75
  classNames,
79
76
  )}
80
77
  ref={forwardedRef}
@@ -6,15 +6,15 @@ import React from 'react';
6
6
 
7
7
  import { ResizeHandle } from '@dxos/react-ui-dnd';
8
8
 
9
- import { DEFAULT_EXTRINSIC_SIZE } from './StackItem';
10
9
  import { useStack, useStackItem } from '../StackContext';
10
+ import { DEFAULT_EXTRINSIC_SIZE } from './StackItem';
11
11
 
12
12
  const MIN_WIDTH = 20;
13
13
  const MIN_HEIGHT = 3;
14
14
 
15
15
  export type StackItemResizeHandleProps = {};
16
16
 
17
- export const StackItemResizeHandle = () => {
17
+ export const StackItemResizeHandle = (_: StackItemResizeHandleProps) => {
18
18
  const { orientation } = useStack();
19
19
  const { setSize, size } = useStackItem();
20
20
 
@@ -4,15 +4,16 @@
4
4
 
5
5
  import React, { Fragment, type PropsWithChildren, forwardRef, useState } from 'react';
6
6
 
7
- import { type ActionLike } from '@dxos/app-graph';
7
+ import { type Node } from '@dxos/app-graph';
8
8
  import { keySymbols } from '@dxos/keyboard';
9
9
  import { Button, type ButtonProps, DropdownMenu, Icon, toLocalizedString, useTranslation } from '@dxos/react-ui';
10
10
  import { type AttendableId, type Related, useAttention } from '@dxos/react-ui-attention';
11
- import { descriptionText, mx } from '@dxos/react-ui-theme';
11
+ import { mx } from '@dxos/ui-theme';
12
12
  import { getHostPlatform } from '@dxos/util';
13
13
 
14
+ import { translationKey } from '#translations';
15
+
14
16
  import { MenuSignifierHorizontal } from './MenuSignifier';
15
- import { translationKey } from '../../translations';
16
17
 
17
18
  export type KeyBinding = {
18
19
  windows?: string;
@@ -22,7 +23,7 @@ export type KeyBinding = {
22
23
  unknown?: string;
23
24
  };
24
25
 
25
- export type StackItemSigilAction = Pick<ActionLike, 'id' | 'properties' | 'data'>;
26
+ export type StackItemSigilAction = Pick<Node.ActionLike, 'id' | 'properties' | 'data'>;
26
27
 
27
28
  export type StackItemSigilButtonProps = Omit<ButtonProps, 'variant'> &
28
29
  AttendableId &
@@ -39,7 +40,10 @@ export const StackItemSigilButton = forwardRef<HTMLButtonElement, StackItemSigil
39
40
  <Button
40
41
  {...props}
41
42
  variant={variant}
42
- classNames={['shrink-0 pli-0 min-bs-0 is-[--rail-action] bs-[--rail-action] relative app-no-drag', classNames]}
43
+ classNames={[
44
+ 'shrink-0 px-0 min-h-0 w-(--dx-rail-action) h-(--dx-rail-action) relative dx-app-no-drag',
45
+ classNames,
46
+ ]}
43
47
  ref={forwardedRef}
44
48
  >
45
49
  {isMenu && <MenuSignifierHorizontal />}
@@ -77,7 +81,7 @@ export const StackItemSigil = forwardRef<HTMLButtonElement, StackItemSigilProps>
77
81
  classNames={!hasActions && 'cursor-default'}
78
82
  >
79
83
  <span className='sr-only'>{triggerLabel}</span>
80
- <Icon icon={icon} size={5} />
84
+ <Icon icon={icon} />
81
85
  </StackItemSigilButton>
82
86
  );
83
87
 
@@ -132,7 +136,7 @@ export const StackItemSigil = forwardRef<HTMLButtonElement, StackItemSigilProps>
132
136
  </DropdownMenu.ItemIndicator>
133
137
  )}
134
138
  {shortcut && (
135
- <span className={mx('shrink-0', descriptionText)}>{keySymbols(shortcut).join('')}</span>
139
+ <span className={mx('shrink-0', 'text-description')}>{keySymbols(shortcut).join('')}</span>
136
140
  )}
137
141
  </Root>
138
142
  );
@@ -2,7 +2,8 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- export * from './defs';
5
+ export type * from './types';
6
6
 
7
7
  export * from './Stack';
8
+
8
9
  export * from './StackItem';