@dxos/react-ui-stack 0.8.3 → 0.8.4-main.1068cf700f
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.
- package/dist/lib/browser/index.mjs +767 -1016
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/{testing → playwright}/index.mjs +5 -1
- package/dist/lib/browser/{testing → playwright}/index.mjs.map +3 -3
- package/dist/lib/node-esm/index.mjs +767 -1016
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/{testing → playwright}/index.mjs +5 -1
- package/dist/lib/node-esm/{testing → playwright}/index.mjs.map +3 -3
- package/dist/types/src/{exemplars → components}/CardStack/CardStack.d.ts +24 -11
- package/dist/types/src/components/CardStack/CardStack.d.ts.map +1 -0
- package/dist/types/src/components/CardStack/CardStack.stories.d.ts +15 -0
- package/dist/types/src/components/CardStack/CardStack.stories.d.ts.map +1 -0
- package/dist/types/src/{exemplars → components}/CardStack/CardStackDragPreview.d.ts +4 -1
- package/dist/types/src/components/CardStack/CardStackDragPreview.d.ts.map +1 -0
- package/dist/types/src/components/CardStack/index.d.ts.map +1 -0
- package/dist/types/src/components/Stack/Stack.d.ts +15 -7
- package/dist/types/src/components/Stack/Stack.d.ts.map +1 -1
- package/dist/types/src/components/Stack/Stack.stories.d.ts +12 -3
- package/dist/types/src/components/Stack/Stack.stories.d.ts.map +1 -1
- package/dist/types/src/components/StackContext.d.ts +2 -1
- package/dist/types/src/components/StackContext.d.ts.map +1 -1
- package/dist/types/src/components/StackItem/StackItem.d.ts +9 -12
- package/dist/types/src/components/StackItem/StackItem.d.ts.map +1 -1
- package/dist/types/src/components/StackItem/StackItem.stories.d.ts +13 -5
- package/dist/types/src/components/StackItem/StackItem.stories.d.ts.map +1 -1
- package/dist/types/src/components/StackItem/StackItemContent.d.ts +4 -37
- package/dist/types/src/components/StackItem/StackItemContent.d.ts.map +1 -1
- package/dist/types/src/components/StackItem/StackItemHeading.d.ts +1 -1
- package/dist/types/src/components/StackItem/StackItemHeading.d.ts.map +1 -1
- package/dist/types/src/components/StackItem/StackItemResizeHandle.d.ts.map +1 -1
- package/dist/types/src/components/StackItem/StackItemSigil.d.ts +2 -2
- package/dist/types/src/components/StackItem/StackItemSigil.d.ts.map +1 -1
- package/dist/types/src/components/deprecated/LayoutControls.d.ts +3 -0
- package/dist/types/src/components/deprecated/LayoutControls.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +2 -1
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/components/{defs.d.ts → types.d.ts} +1 -1
- package/dist/types/src/components/types.d.ts.map +1 -0
- package/dist/types/src/hooks/useStackDropForElements.d.ts +9 -7
- package/dist/types/src/hooks/useStackDropForElements.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -2
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/playwright/index.d.ts.map +1 -0
- package/dist/types/src/playwright/playwright.config.d.ts +3 -0
- package/dist/types/src/playwright/playwright.config.d.ts.map +1 -0
- package/dist/types/src/playwright/stack-manager.d.ts.map +1 -0
- package/dist/types/src/translations.d.ts +13 -14
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +48 -41
- package/src/components/CardStack/CardStack.stories.tsx +173 -0
- package/src/{exemplars → components}/CardStack/CardStack.tsx +115 -39
- package/src/{exemplars → components}/CardStack/CardStackDragPreview.tsx +12 -9
- package/src/components/Stack/Stack.stories.tsx +9 -10
- package/src/components/Stack/Stack.tsx +225 -26
- package/src/components/StackContext.tsx +2 -1
- package/src/components/StackItem/StackItem.stories.tsx +21 -17
- package/src/components/StackItem/StackItem.tsx +49 -29
- package/src/components/StackItem/StackItemContent.tsx +23 -42
- package/src/components/StackItem/StackItemHeading.tsx +5 -9
- package/src/components/StackItem/StackItemResizeHandle.tsx +2 -1
- package/src/components/StackItem/StackItemSigil.tsx +5 -4
- package/src/components/deprecated/LayoutControls.tsx +3 -0
- package/src/components/index.ts +2 -1
- package/src/hooks/useStackDropForElements.ts +59 -42
- package/src/index.ts +1 -5
- package/src/{testing → playwright}/index.ts +1 -1
- package/src/playwright/playwright.config.ts +17 -0
- package/src/playwright/smoke.spec.ts +7 -5
- package/src/translations.ts +5 -3
- package/dist/lib/node/index.cjs +0 -1220
- package/dist/lib/node/index.cjs.map +0 -7
- package/dist/lib/node/meta.json +0 -1
- package/dist/lib/node/testing/index.cjs +0 -81
- package/dist/lib/node/testing/index.cjs.map +0 -7
- package/dist/types/src/components/defs.d.ts.map +0 -1
- package/dist/types/src/exemplars/Card/Card.d.ts +0 -62
- package/dist/types/src/exemplars/Card/Card.d.ts.map +0 -1
- package/dist/types/src/exemplars/Card/Card.stories-todo.d.ts +0 -1
- package/dist/types/src/exemplars/Card/Card.stories-todo.d.ts.map +0 -1
- package/dist/types/src/exemplars/Card/CardDragPreview.d.ts +0 -6
- package/dist/types/src/exemplars/Card/CardDragPreview.d.ts.map +0 -1
- package/dist/types/src/exemplars/Card/fragments.d.ts +0 -13
- package/dist/types/src/exemplars/Card/fragments.d.ts.map +0 -1
- package/dist/types/src/exemplars/Card/index.d.ts +0 -4
- package/dist/types/src/exemplars/Card/index.d.ts.map +0 -1
- package/dist/types/src/exemplars/CardStack/CardStack.d.ts.map +0 -1
- package/dist/types/src/exemplars/CardStack/CardStack.stories-todo.d.ts +0 -1
- package/dist/types/src/exemplars/CardStack/CardStack.stories-todo.d.ts.map +0 -1
- package/dist/types/src/exemplars/CardStack/CardStackDragPreview.d.ts.map +0 -1
- package/dist/types/src/exemplars/CardStack/index.d.ts.map +0 -1
- package/dist/types/src/exemplars/index.d.ts +0 -3
- package/dist/types/src/exemplars/index.d.ts.map +0 -1
- package/dist/types/src/testing/index.d.ts.map +0 -1
- package/dist/types/src/testing/stack-manager.d.ts.map +0 -1
- package/src/exemplars/Card/Card.stories-todo.tsx +0 -135
- package/src/exemplars/Card/Card.tsx +0 -182
- package/src/exemplars/Card/CardDragPreview.tsx +0 -22
- package/src/exemplars/Card/fragments.ts +0 -25
- package/src/exemplars/Card/index.ts +0 -7
- package/src/exemplars/CardStack/CardStack.stories-todo.tsx +0 -80
- package/src/exemplars/index.ts +0 -6
- package/src/playwright/playwright.config.cts +0 -18
- /package/dist/types/src/{exemplars → components}/CardStack/index.d.ts +0 -0
- /package/dist/types/src/{testing → playwright}/index.d.ts +0 -0
- /package/dist/types/src/{testing → playwright}/stack-manager.d.ts +0 -0
- /package/src/{exemplars → components}/CardStack/index.ts +0 -0
- /package/src/components/{defs.ts → types.ts} +0 -0
- /package/src/{testing → playwright}/stack-manager.ts +0 -0
package/package.json
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/react-ui-stack",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.4-main.1068cf700f",
|
|
4
4
|
"description": "A stack component.",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/dxos/dxos"
|
|
10
|
+
},
|
|
7
11
|
"license": "MIT",
|
|
8
12
|
"author": "DXOS.org",
|
|
9
|
-
"sideEffects":
|
|
13
|
+
"sideEffects": false,
|
|
10
14
|
"type": "module",
|
|
11
15
|
"exports": {
|
|
12
16
|
".": {
|
|
@@ -14,18 +18,18 @@
|
|
|
14
18
|
"browser": "./dist/lib/browser/index.mjs",
|
|
15
19
|
"node": "./dist/lib/node-esm/index.mjs"
|
|
16
20
|
},
|
|
17
|
-
"./
|
|
18
|
-
"types": "./dist/types/src/
|
|
19
|
-
"browser": "./dist/lib/browser/
|
|
20
|
-
"node":
|
|
21
|
-
"require": "./dist/lib/node/testing/index.cjs",
|
|
22
|
-
"default": "./dist/lib/node-esm/testing/index.mjs"
|
|
23
|
-
}
|
|
21
|
+
"./playwright": {
|
|
22
|
+
"types": "./dist/types/src/playwright/index.d.ts",
|
|
23
|
+
"browser": "./dist/lib/browser/playwright/index.mjs",
|
|
24
|
+
"node": "./dist/lib/node-esm/playwright/index.mjs"
|
|
24
25
|
}
|
|
25
26
|
},
|
|
26
27
|
"types": "dist/types/src/index.d.ts",
|
|
27
28
|
"typesVersions": {
|
|
28
29
|
"*": {
|
|
30
|
+
"playwright": [
|
|
31
|
+
"dist/types/src/playwright/index.d.ts"
|
|
32
|
+
],
|
|
29
33
|
"testing": [
|
|
30
34
|
"dist/types/src/testing/index.d.ts"
|
|
31
35
|
]
|
|
@@ -36,11 +40,11 @@
|
|
|
36
40
|
"src"
|
|
37
41
|
],
|
|
38
42
|
"dependencies": {
|
|
39
|
-
"@atlaskit/pragmatic-drag-and-drop": "
|
|
40
|
-
"@atlaskit/pragmatic-drag-and-drop-auto-scroll": "^2.1.
|
|
41
|
-
"@atlaskit/pragmatic-drag-and-drop-hitbox": "
|
|
42
|
-
"@
|
|
43
|
-
"@
|
|
43
|
+
"@atlaskit/pragmatic-drag-and-drop": "1.7.7",
|
|
44
|
+
"@atlaskit/pragmatic-drag-and-drop-auto-scroll": "^2.1.2",
|
|
45
|
+
"@atlaskit/pragmatic-drag-and-drop-hitbox": "1.1.0",
|
|
46
|
+
"@atlaskit/pragmatic-drag-and-drop-react-drop-indicator": "3.2.10",
|
|
47
|
+
"@fluentui/react-tabster": "9.26.11",
|
|
44
48
|
"@radix-ui/primitive": "1.1.1",
|
|
45
49
|
"@radix-ui/react-compose-refs": "1.1.1",
|
|
46
50
|
"@radix-ui/react-context": "1.1.1",
|
|
@@ -49,37 +53,40 @@
|
|
|
49
53
|
"@radix-ui/react-slot": "1.1.2",
|
|
50
54
|
"@radix-ui/react-use-controllable-state": "1.1.0",
|
|
51
55
|
"react-resize-detector": "^11.0.1",
|
|
52
|
-
"@dxos/echo
|
|
53
|
-
"@dxos/keyboard": "0.8.
|
|
54
|
-
"@dxos/react-ui-
|
|
55
|
-
"@dxos/
|
|
56
|
-
"@dxos/
|
|
57
|
-
"@dxos/
|
|
56
|
+
"@dxos/echo": "0.8.4-main.1068cf700f",
|
|
57
|
+
"@dxos/keyboard": "0.8.4-main.1068cf700f",
|
|
58
|
+
"@dxos/react-ui-dnd": "0.8.4-main.1068cf700f",
|
|
59
|
+
"@dxos/react-ui-mosaic": "0.8.4-main.1068cf700f",
|
|
60
|
+
"@dxos/util": "0.8.4-main.1068cf700f",
|
|
61
|
+
"@dxos/react-ui-attention": "0.8.4-main.1068cf700f"
|
|
58
62
|
},
|
|
59
63
|
"devDependencies": {
|
|
60
|
-
"@
|
|
61
|
-
"@types/react": "~
|
|
62
|
-
"
|
|
63
|
-
"react": "~
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"@dxos/app-graph": "0.8.
|
|
67
|
-
"@dxos/client": "0.8.
|
|
68
|
-
"@dxos/
|
|
69
|
-
"@dxos/
|
|
70
|
-
"@dxos/
|
|
71
|
-
"@dxos/react-
|
|
72
|
-
"@dxos/
|
|
73
|
-
"@dxos/
|
|
64
|
+
"@types/react": "~19.2.7",
|
|
65
|
+
"@types/react-dom": "~19.2.3",
|
|
66
|
+
"react": "~19.2.3",
|
|
67
|
+
"react-dom": "~19.2.3",
|
|
68
|
+
"vite": "7.1.9",
|
|
69
|
+
"@dxos/app-framework": "0.8.4-main.1068cf700f",
|
|
70
|
+
"@dxos/app-graph": "0.8.4-main.1068cf700f",
|
|
71
|
+
"@dxos/client": "0.8.4-main.1068cf700f",
|
|
72
|
+
"@dxos/random": "0.8.4-main.1068cf700f",
|
|
73
|
+
"@dxos/echo-db": "0.8.4-main.1068cf700f",
|
|
74
|
+
"@dxos/echo": "0.8.4-main.1068cf700f",
|
|
75
|
+
"@dxos/react-client": "0.8.4-main.1068cf700f",
|
|
76
|
+
"@dxos/react-ui": "0.8.4-main.1068cf700f",
|
|
77
|
+
"@dxos/schema": "0.8.4-main.1068cf700f",
|
|
78
|
+
"@dxos/storybook-utils": "0.8.4-main.1068cf700f",
|
|
79
|
+
"@dxos/test-utils": "0.8.4-main.1068cf700f",
|
|
80
|
+
"@dxos/types": "0.8.4-main.1068cf700f",
|
|
81
|
+
"@dxos/ui-theme": "0.8.4-main.1068cf700f"
|
|
74
82
|
},
|
|
75
83
|
"peerDependencies": {
|
|
76
|
-
"
|
|
77
|
-
"react": "~
|
|
78
|
-
"
|
|
79
|
-
"@dxos/
|
|
80
|
-
"@dxos/
|
|
81
|
-
"@dxos/
|
|
82
|
-
"@dxos/react-ui": "0.8.3"
|
|
84
|
+
"react": "~19.2.3",
|
|
85
|
+
"react-dom": "~19.2.3",
|
|
86
|
+
"@dxos/client": "0.8.4-main.1068cf700f",
|
|
87
|
+
"@dxos/random": "0.8.4-main.1068cf700f",
|
|
88
|
+
"@dxos/react-ui": "0.8.4-main.1068cf700f",
|
|
89
|
+
"@dxos/ui-theme": "0.8.4-main.1068cf700f"
|
|
83
90
|
},
|
|
84
91
|
"publishConfig": {
|
|
85
92
|
"access": "public"
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type Edge } from '@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge';
|
|
6
|
+
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
7
|
+
import React, { useCallback, useState } from 'react';
|
|
8
|
+
|
|
9
|
+
import { faker } from '@dxos/random';
|
|
10
|
+
import { IconButton } from '@dxos/react-ui';
|
|
11
|
+
import { withTheme } from '@dxos/react-ui/testing';
|
|
12
|
+
import { Card, CardDragPreview } from '@dxos/react-ui-mosaic';
|
|
13
|
+
|
|
14
|
+
import { StackItem } from '../StackItem';
|
|
15
|
+
|
|
16
|
+
import { CardStack } from './CardStack';
|
|
17
|
+
|
|
18
|
+
faker.seed(0);
|
|
19
|
+
|
|
20
|
+
type CardItem = {
|
|
21
|
+
id: string;
|
|
22
|
+
title: string;
|
|
23
|
+
description: string;
|
|
24
|
+
image: string;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
type StackItemData = {
|
|
28
|
+
id: string;
|
|
29
|
+
type?: 'column' | 'card';
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const CardStackStory = () => {
|
|
33
|
+
const [column, setColumn] = useState<CardItem[]>(
|
|
34
|
+
faker.helpers.multiple(
|
|
35
|
+
() => ({
|
|
36
|
+
id: faker.string.uuid(),
|
|
37
|
+
title: faker.commerce.productName(),
|
|
38
|
+
description: faker.lorem.paragraph(),
|
|
39
|
+
image: faker.image.url(),
|
|
40
|
+
}),
|
|
41
|
+
{ count: 12 },
|
|
42
|
+
),
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
const handleRearrange = useCallback((source: StackItemData, target: StackItemData, closestEdge: Edge | null) => {
|
|
46
|
+
setColumn((prevColumn) => {
|
|
47
|
+
const newColumns = [...prevColumn];
|
|
48
|
+
// Reordering cards within a column
|
|
49
|
+
const sourceCardIndex = prevColumn.findIndex((card) => card.id === source.id);
|
|
50
|
+
const targetCardIndex = prevColumn.findIndex((card) => card.id === target.id);
|
|
51
|
+
|
|
52
|
+
if (typeof sourceCardIndex === 'number' && typeof targetCardIndex === 'number') {
|
|
53
|
+
const [movedCard] = newColumns.splice(sourceCardIndex, 1);
|
|
54
|
+
|
|
55
|
+
let insertIndex;
|
|
56
|
+
if (sourceCardIndex < targetCardIndex) {
|
|
57
|
+
insertIndex = closestEdge === 'bottom' ? targetCardIndex : targetCardIndex - 1;
|
|
58
|
+
} else {
|
|
59
|
+
insertIndex = closestEdge === 'bottom' ? targetCardIndex + 1 : targetCardIndex;
|
|
60
|
+
}
|
|
61
|
+
newColumns.splice(insertIndex, 0, movedCard);
|
|
62
|
+
}
|
|
63
|
+
return newColumns;
|
|
64
|
+
});
|
|
65
|
+
}, []);
|
|
66
|
+
|
|
67
|
+
const handleAddCard = useCallback(() => {
|
|
68
|
+
setColumn((prevColumn) => {
|
|
69
|
+
const newColumn = [...prevColumn];
|
|
70
|
+
const newCard = {
|
|
71
|
+
id: faker.string.uuid(),
|
|
72
|
+
title: faker.commerce.productName(),
|
|
73
|
+
description: faker.lorem.paragraph(),
|
|
74
|
+
image: faker.image.url(),
|
|
75
|
+
} satisfies CardItem;
|
|
76
|
+
newColumn.push(newCard);
|
|
77
|
+
console.log('[add card]', prevColumn.length, newColumn.length);
|
|
78
|
+
return newColumn;
|
|
79
|
+
});
|
|
80
|
+
}, []);
|
|
81
|
+
|
|
82
|
+
const handleRemoveCard = useCallback((cardId: string) => {
|
|
83
|
+
setColumn((prevColumn) => {
|
|
84
|
+
const newColumn = [...prevColumn];
|
|
85
|
+
|
|
86
|
+
const cardIndex = prevColumn.findIndex((card) => card.id === cardId);
|
|
87
|
+
if (cardIndex !== -1) {
|
|
88
|
+
newColumn.splice(cardIndex, 1);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return newColumn;
|
|
92
|
+
});
|
|
93
|
+
}, []);
|
|
94
|
+
|
|
95
|
+
return (
|
|
96
|
+
<CardStack.Root classNames='is-96'>
|
|
97
|
+
<CardStack.Content footer>
|
|
98
|
+
<CardStack.Stack id='story column' onRearrange={handleRearrange} itemsCount={column.length}>
|
|
99
|
+
{column.map((card, cardIndex, cardsArray) => {
|
|
100
|
+
const cardItem = { id: card.id, type: 'card' as const };
|
|
101
|
+
const prevCardId = cardIndex > 0 ? cardsArray[cardIndex - 1].id : undefined;
|
|
102
|
+
const nextCardId = cardIndex < cardsArray.length - 1 ? cardsArray[cardIndex + 1].id : undefined;
|
|
103
|
+
|
|
104
|
+
return (
|
|
105
|
+
<CardStack.Item asChild key={card.id}>
|
|
106
|
+
<StackItem.Root
|
|
107
|
+
item={cardItem}
|
|
108
|
+
focusIndicatorVariant='group'
|
|
109
|
+
prevSiblingId={prevCardId}
|
|
110
|
+
nextSiblingId={nextCardId}
|
|
111
|
+
>
|
|
112
|
+
<Card.Root>
|
|
113
|
+
<Card.Toolbar>
|
|
114
|
+
<StackItem.DragHandle asChild>
|
|
115
|
+
<Card.DragHandle />
|
|
116
|
+
</StackItem.DragHandle>
|
|
117
|
+
<Card.ToolbarSeparator variant='gap' />
|
|
118
|
+
<Card.ToolbarIconButton
|
|
119
|
+
iconOnly
|
|
120
|
+
variant='ghost'
|
|
121
|
+
icon='ph--x--regular'
|
|
122
|
+
label='Remove card'
|
|
123
|
+
onClick={() => handleRemoveCard(card.id)}
|
|
124
|
+
/>
|
|
125
|
+
</Card.Toolbar>
|
|
126
|
+
<Card.Poster alt={card.title} image={card.image} />
|
|
127
|
+
<Card.Heading>{card.title}</Card.Heading>
|
|
128
|
+
<Card.Text variant='description'>{card.description}</Card.Text>
|
|
129
|
+
</Card.Root>
|
|
130
|
+
<StackItem.DragPreview>
|
|
131
|
+
{() => (
|
|
132
|
+
<CardDragPreview.Root>
|
|
133
|
+
<CardDragPreview.Content>
|
|
134
|
+
<Card.Toolbar>
|
|
135
|
+
<Card.DragHandle />
|
|
136
|
+
</Card.Toolbar>
|
|
137
|
+
<Card.Poster alt={card.title} image={card.image} />
|
|
138
|
+
<Card.Heading>{card.title}</Card.Heading>
|
|
139
|
+
<Card.Text variant='description'>{card.description}</Card.Text>
|
|
140
|
+
</CardDragPreview.Content>
|
|
141
|
+
</CardDragPreview.Root>
|
|
142
|
+
)}
|
|
143
|
+
</StackItem.DragPreview>
|
|
144
|
+
</StackItem.Root>
|
|
145
|
+
</CardStack.Item>
|
|
146
|
+
);
|
|
147
|
+
})}
|
|
148
|
+
</CardStack.Stack>
|
|
149
|
+
|
|
150
|
+
<CardStack.Footer>
|
|
151
|
+
<IconButton icon='ph--plus--regular' label='Add card' onClick={handleAddCard} classNames='is-full' />
|
|
152
|
+
</CardStack.Footer>
|
|
153
|
+
|
|
154
|
+
<CardStack.Heading>{faker.company.name()}</CardStack.Heading>
|
|
155
|
+
</CardStack.Content>
|
|
156
|
+
</CardStack.Root>
|
|
157
|
+
);
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
const meta = {
|
|
161
|
+
title: 'ui/react-ui-stack/CardStack',
|
|
162
|
+
component: CardStackStory,
|
|
163
|
+
decorators: [withTheme()],
|
|
164
|
+
parameters: {
|
|
165
|
+
layout: 'fullscreen',
|
|
166
|
+
},
|
|
167
|
+
} satisfies Meta<typeof CardStackStory>;
|
|
168
|
+
|
|
169
|
+
export default meta;
|
|
170
|
+
|
|
171
|
+
type Story = StoryObj<typeof CardStackStory>;
|
|
172
|
+
|
|
173
|
+
export const Default: Story = {};
|
|
@@ -6,17 +6,78 @@ import { Slot } from '@radix-ui/react-slot';
|
|
|
6
6
|
import React, { type ComponentPropsWithoutRef, forwardRef } from 'react';
|
|
7
7
|
|
|
8
8
|
import type { ThemedClassName } from '@dxos/react-ui';
|
|
9
|
-
import {
|
|
9
|
+
import { Card } from '@dxos/react-ui-mosaic';
|
|
10
|
+
import { cardDefaultInlineSize, mx } from '@dxos/ui-theme';
|
|
10
11
|
|
|
11
|
-
import {
|
|
12
|
-
import { Card } from '../Card';
|
|
12
|
+
import { Stack, type StackProps, railGridHorizontalContainFitContent } from '../Stack';
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
/**
|
|
15
|
+
* This is `cardDefaultInlineSize` plus 2 times the sum of the inner and outer spacing applied by CardStack on the inline axis.
|
|
16
|
+
*/
|
|
17
|
+
const cardStackDefaultInlineSizeRem = cardDefaultInlineSize + 2.125;
|
|
18
|
+
|
|
19
|
+
//
|
|
20
|
+
// Root
|
|
21
|
+
//
|
|
22
|
+
|
|
23
|
+
const cardStackRoot = 'flex flex-col';
|
|
24
|
+
|
|
25
|
+
const CardStackRoot = forwardRef<HTMLDivElement, SharedCardStackProps>(
|
|
26
|
+
({ children, classNames, asChild, role = 'none', ...props }, forwardedRef) => {
|
|
27
|
+
const Root = asChild ? Slot : 'div';
|
|
28
|
+
const rootProps = asChild
|
|
29
|
+
? { classNames: [cardStackRoot, classNames] }
|
|
30
|
+
: { className: mx(cardStackRoot, classNames), role };
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<Root {...props} {...rootProps} ref={forwardedRef}>
|
|
34
|
+
{children}
|
|
35
|
+
</Root>
|
|
36
|
+
);
|
|
37
|
+
},
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
//
|
|
41
|
+
// Content
|
|
42
|
+
// TODO(burdon): Rename Viewport (should be the component that scrolls).
|
|
43
|
+
//
|
|
44
|
+
|
|
45
|
+
const cardStackContent = 'shrink min-bs-0 grid dx-focus-ring-group-x-indicator bg-baseSurface';
|
|
46
|
+
|
|
47
|
+
type CardStackContentProps = SharedCardStackProps & {
|
|
48
|
+
footer?: boolean;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const CardStackContent = forwardRef<HTMLDivElement, CardStackContentProps>(
|
|
52
|
+
({ children, classNames, asChild, role = 'none', footer, ...props }, forwardedRef) => {
|
|
53
|
+
const Root = asChild ? Slot : 'div';
|
|
54
|
+
const baseClassNames = footer ? [cardStackContent, railGridHorizontalContainFitContent] : [cardStackContent];
|
|
55
|
+
const rootProps = asChild
|
|
56
|
+
? { classNames: [...baseClassNames, classNames] }
|
|
57
|
+
: { className: mx(...baseClassNames, classNames), role };
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
<Root {...props} {...rootProps} data-scroll-separator='false' ref={forwardedRef}>
|
|
61
|
+
{children}
|
|
62
|
+
</Root>
|
|
63
|
+
);
|
|
64
|
+
},
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
//
|
|
68
|
+
// Stack
|
|
69
|
+
// TODO(burdon): Rename Content.
|
|
70
|
+
//
|
|
71
|
+
|
|
72
|
+
type SharedCardStackProps = ThemedClassName<ComponentPropsWithoutRef<'div'>> & {
|
|
73
|
+
asChild?: boolean;
|
|
74
|
+
};
|
|
15
75
|
|
|
16
76
|
const CardStackStack = forwardRef<
|
|
17
77
|
HTMLDivElement,
|
|
18
78
|
Omit<StackProps, 'orientation' | 'size' | 'rail' | 'separatorOnScroll'>
|
|
19
79
|
>(({ children, classNames, itemsCount = 0, ...props }, forwardedRef) => {
|
|
80
|
+
// NOTE: Should not have horizontal padding since separatorOnScroll should be full width.
|
|
20
81
|
return (
|
|
21
82
|
<Stack
|
|
22
83
|
orientation='vertical'
|
|
@@ -24,7 +85,7 @@ const CardStackStack = forwardRef<
|
|
|
24
85
|
rail={false}
|
|
25
86
|
classNames={
|
|
26
87
|
/* NOTE(thure): Do not let this element have zero intrinsic size, otherwise the drop indicator will not display. See #9035. */
|
|
27
|
-
['plb-
|
|
88
|
+
['plb-2', classNames]
|
|
28
89
|
}
|
|
29
90
|
itemsCount={itemsCount}
|
|
30
91
|
separatorOnScroll={9}
|
|
@@ -37,7 +98,30 @@ const CardStackStack = forwardRef<
|
|
|
37
98
|
);
|
|
38
99
|
});
|
|
39
100
|
|
|
40
|
-
|
|
101
|
+
//
|
|
102
|
+
// Item
|
|
103
|
+
//
|
|
104
|
+
|
|
105
|
+
const cardStackItem = 'contain-layout pli-2 plb-1 first-of-type:pbs-0 last-of-type:pbe-0';
|
|
106
|
+
|
|
107
|
+
const CardStackItem = forwardRef<HTMLDivElement, SharedCardStackProps>(
|
|
108
|
+
({ children, classNames, asChild, role = 'none', ...props }, forwardedRef) => {
|
|
109
|
+
const Root = asChild ? Slot : 'div';
|
|
110
|
+
const rootProps = asChild
|
|
111
|
+
? { classNames: [cardStackItem, classNames] }
|
|
112
|
+
: { className: mx(cardStackItem, classNames), role };
|
|
113
|
+
|
|
114
|
+
return (
|
|
115
|
+
<Root {...props} {...rootProps} ref={forwardedRef}>
|
|
116
|
+
{children}
|
|
117
|
+
</Root>
|
|
118
|
+
);
|
|
119
|
+
},
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
//
|
|
123
|
+
// Heading
|
|
124
|
+
//
|
|
41
125
|
|
|
42
126
|
const cardStackHeading = 'mli-2 order-first bg-transparent rounded-bs-md flex items-center';
|
|
43
127
|
|
|
@@ -47,6 +131,7 @@ const CardStackHeading = forwardRef<HTMLDivElement, SharedCardStackProps>(
|
|
|
47
131
|
const rootProps = asChild
|
|
48
132
|
? { classNames: [cardStackHeading, classNames] }
|
|
49
133
|
: { className: mx(cardStackHeading, classNames), role };
|
|
134
|
+
|
|
50
135
|
return (
|
|
51
136
|
<Root {...props} {...rootProps} ref={forwardedRef}>
|
|
52
137
|
{children}
|
|
@@ -55,6 +140,10 @@ const CardStackHeading = forwardRef<HTMLDivElement, SharedCardStackProps>(
|
|
|
55
140
|
},
|
|
56
141
|
);
|
|
57
142
|
|
|
143
|
+
//
|
|
144
|
+
// Footer
|
|
145
|
+
//
|
|
146
|
+
|
|
58
147
|
const cardStackFooter =
|
|
59
148
|
'plb-2 mli-2 border-bs border-transparent [[data-scroll-separator-end="true"]_&]:border-subduedSeparator';
|
|
60
149
|
|
|
@@ -64,6 +153,7 @@ const CardStackFooter = forwardRef<HTMLDivElement, SharedCardStackProps>(
|
|
|
64
153
|
const rootProps = asChild
|
|
65
154
|
? { classNames: [cardStackFooter, classNames] }
|
|
66
155
|
: { className: mx(cardStackFooter, classNames), role };
|
|
156
|
+
|
|
67
157
|
return (
|
|
68
158
|
<Root {...props} {...rootProps} ref={forwardedRef}>
|
|
69
159
|
{children}
|
|
@@ -72,41 +162,19 @@ const CardStackFooter = forwardRef<HTMLDivElement, SharedCardStackProps>(
|
|
|
72
162
|
},
|
|
73
163
|
);
|
|
74
164
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
];
|
|
79
|
-
|
|
80
|
-
const CardStackContent = forwardRef<HTMLDivElement, SharedCardStackProps>(
|
|
81
|
-
({ children, classNames, asChild, role = 'none', ...props }, forwardedRef) => {
|
|
82
|
-
const Root = asChild ? Slot : 'div';
|
|
83
|
-
const rootProps = asChild
|
|
84
|
-
? { classNames: [...cardStackContent, classNames] }
|
|
85
|
-
: { className: mx(...cardStackContent, classNames), role };
|
|
86
|
-
return (
|
|
87
|
-
<Root {...props} {...rootProps} data-scroll-separator='false' ref={forwardedRef}>
|
|
88
|
-
{children}
|
|
89
|
-
</Root>
|
|
90
|
-
);
|
|
91
|
-
},
|
|
92
|
-
);
|
|
165
|
+
//
|
|
166
|
+
// DragHandle
|
|
167
|
+
//
|
|
93
168
|
|
|
94
|
-
const
|
|
169
|
+
const CardStackDragHandle = Card.DragHandle;
|
|
95
170
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
const rootProps = asChild
|
|
100
|
-
? { classNames: [cardStackRoot, classNames] }
|
|
101
|
-
: { className: mx(cardStackRoot, classNames), role };
|
|
102
|
-
return (
|
|
103
|
-
<Root {...props} {...rootProps} ref={forwardedRef}>
|
|
104
|
-
{children}
|
|
105
|
-
</Root>
|
|
106
|
-
);
|
|
107
|
-
},
|
|
108
|
-
);
|
|
171
|
+
//
|
|
172
|
+
// CardStack
|
|
173
|
+
//
|
|
109
174
|
|
|
175
|
+
/**
|
|
176
|
+
* @deprecated Replace with Mosaic.Stack.
|
|
177
|
+
*/
|
|
110
178
|
export const CardStack = {
|
|
111
179
|
Root: CardStackRoot,
|
|
112
180
|
Content: CardStackContent,
|
|
@@ -114,6 +182,14 @@ export const CardStack = {
|
|
|
114
182
|
Heading: CardStackHeading,
|
|
115
183
|
Footer: CardStackFooter,
|
|
116
184
|
DragHandle: CardStackDragHandle,
|
|
185
|
+
Item: CardStackItem,
|
|
117
186
|
};
|
|
118
187
|
|
|
119
|
-
export {
|
|
188
|
+
export {
|
|
189
|
+
cardStackRoot,
|
|
190
|
+
cardStackFooter,
|
|
191
|
+
cardStackHeading,
|
|
192
|
+
cardStackContent,
|
|
193
|
+
cardStackItem,
|
|
194
|
+
cardStackDefaultInlineSizeRem,
|
|
195
|
+
};
|
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
|
|
5
5
|
import React, { type PropsWithChildren } from 'react';
|
|
6
6
|
|
|
7
|
-
import { IconButton, useTranslation } from '@dxos/react-ui';
|
|
8
|
-
import { mx } from '@dxos/
|
|
7
|
+
import { IconButton, ScrollArea, useTranslation } from '@dxos/react-ui';
|
|
8
|
+
import { mx } from '@dxos/ui-theme';
|
|
9
9
|
|
|
10
|
-
import { type StackProps } from '../../components';
|
|
11
10
|
import { translationKey } from '../../translations';
|
|
11
|
+
import { type StackProps } from '../Stack';
|
|
12
12
|
|
|
13
13
|
const CardStackDragPreviewRoot = ({ children }: PropsWithChildren<{}>) => {
|
|
14
14
|
return (
|
|
@@ -41,18 +41,21 @@ const CardStackDragPreviewContent = ({
|
|
|
41
41
|
itemsCount = 0,
|
|
42
42
|
}: PropsWithChildren<Pick<StackProps, 'itemsCount'>>) => {
|
|
43
43
|
return (
|
|
44
|
-
<
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
</
|
|
44
|
+
<ScrollArea.Root orientation='vertical'>
|
|
45
|
+
<ScrollArea.Viewport classNames={mx('pli-2 plb-1 gap-2', itemsCount > 0 ? 'plb-2' : 'plb-1')}>
|
|
46
|
+
{children}
|
|
47
|
+
</ScrollArea.Viewport>
|
|
48
|
+
</ScrollArea.Root>
|
|
49
49
|
);
|
|
50
50
|
};
|
|
51
51
|
|
|
52
52
|
const CardStackDragPreviewFooter = ({ children }: PropsWithChildren<{}>) => {
|
|
53
|
-
return <div className='p-2 border-
|
|
53
|
+
return <div className='p-2 border-bs border-separator'>{children}</div>;
|
|
54
54
|
};
|
|
55
55
|
|
|
56
|
+
/**
|
|
57
|
+
* @deprecated
|
|
58
|
+
*/
|
|
56
59
|
export const CardStackDragPreview = {
|
|
57
60
|
Root: CardStackDragPreviewRoot,
|
|
58
61
|
Heading: CardStackDragPreviewHeading,
|
|
@@ -2,18 +2,17 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import '@dxos-theme';
|
|
6
|
-
|
|
7
5
|
import { type Edge } from '@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge';
|
|
8
|
-
import { type Meta, type StoryObj } from '@storybook/react';
|
|
9
|
-
import React, {
|
|
6
|
+
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
7
|
+
import React, { useCallback, useState } from 'react';
|
|
10
8
|
|
|
11
9
|
import { faker } from '@dxos/random';
|
|
12
|
-
import { withTheme } from '@dxos/
|
|
10
|
+
import { withTheme } from '@dxos/react-ui/testing';
|
|
13
11
|
|
|
14
|
-
import { Stack } from './Stack';
|
|
15
12
|
import { StackItem } from '../StackItem';
|
|
16
|
-
import { type StackItemData } from '../
|
|
13
|
+
import { type StackItemData } from '../types';
|
|
14
|
+
|
|
15
|
+
import { Stack } from './Stack';
|
|
17
16
|
|
|
18
17
|
type StoryStackItem = {
|
|
19
18
|
id: string;
|
|
@@ -129,12 +128,12 @@ const DefaultStory = () => {
|
|
|
129
128
|
);
|
|
130
129
|
};
|
|
131
130
|
|
|
132
|
-
const meta
|
|
131
|
+
const meta = {
|
|
133
132
|
title: 'ui/react-ui-stack/Stack',
|
|
134
133
|
component: DefaultStory,
|
|
135
|
-
decorators: [withTheme],
|
|
136
134
|
argTypes: { orientation: { control: 'radio', options: ['horizontal', 'vertical'] } },
|
|
137
|
-
|
|
135
|
+
decorators: [withTheme()],
|
|
136
|
+
} satisfies Meta<typeof DefaultStory>;
|
|
138
137
|
|
|
139
138
|
export default meta;
|
|
140
139
|
|