@dxos/plugin-stack 0.6.14-staging.77003c1 → 0.6.14-staging.7b35391
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/StackMain-Z2DSTC42.mjs +390 -0
- package/dist/lib/browser/StackMain-Z2DSTC42.mjs.map +7 -0
- package/dist/lib/browser/{chunk-ONAKM24Z.mjs → chunk-DS5KGEJG.mjs} +5 -2
- package/dist/lib/browser/chunk-DS5KGEJG.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +18 -8
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/meta.mjs +1 -1
- package/dist/lib/node/StackMain-YK5QQBXA.cjs +402 -0
- package/dist/lib/node/StackMain-YK5QQBXA.cjs.map +7 -0
- package/dist/lib/node/{chunk-O5SQVKNW.cjs → chunk-PA5PRDM6.cjs} +8 -5
- package/dist/lib/node/chunk-PA5PRDM6.cjs.map +7 -0
- package/dist/lib/node/index.cjs +29 -19
- package/dist/lib/node/index.cjs.map +3 -3
- package/dist/lib/node/meta.cjs +4 -4
- package/dist/lib/node/meta.cjs.map +1 -1
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node-esm/StackMain-GCZYK7GH.mjs +391 -0
- package/dist/lib/node-esm/StackMain-GCZYK7GH.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-J57BXQJY.mjs → chunk-JEQMG2E2.mjs} +5 -2
- package/dist/lib/node-esm/chunk-JEQMG2E2.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +18 -8
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/meta.mjs +1 -1
- package/dist/types/src/StackPlugin.d.ts.map +1 -1
- package/dist/types/src/components/AddSectionDialog.d.ts +1 -1
- package/dist/types/src/components/AddSectionDialog.d.ts.map +1 -1
- package/dist/types/src/components/CaretDownUp.d.ts +3 -0
- package/dist/types/src/components/CaretDownUp.d.ts.map +1 -0
- package/dist/types/src/components/StackContext.d.ts +10 -0
- package/dist/types/src/components/StackContext.d.ts.map +1 -0
- package/dist/types/src/components/StackMain.d.ts +1 -2
- package/dist/types/src/components/StackMain.d.ts.map +1 -1
- package/dist/types/src/components/StackSection.d.ts +4 -0
- package/dist/types/src/components/StackSection.d.ts.map +1 -0
- package/dist/types/src/components/index.d.ts +1 -2
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +2 -0
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +17 -8
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/types.d.ts +24 -0
- package/dist/types/src/types/types.d.ts.map +1 -1
- package/package.json +24 -23
- package/src/StackPlugin.tsx +3 -11
- package/src/components/AddSectionDialog.tsx +1 -2
- package/src/components/CaretDownUp.tsx +30 -0
- package/src/components/StackContext.tsx +23 -0
- package/src/components/StackMain.tsx +49 -111
- package/src/components/StackSection.tsx +118 -0
- package/src/meta.ts +3 -0
- package/src/translations.ts +9 -0
- package/src/types/types.ts +30 -0
- package/dist/lib/browser/StackMain-KKC3XIAY.mjs +0 -277
- package/dist/lib/browser/StackMain-KKC3XIAY.mjs.map +0 -7
- package/dist/lib/browser/chunk-ONAKM24Z.mjs.map +0 -7
- package/dist/lib/node/StackMain-ME6LYFGI.cjs +0 -296
- package/dist/lib/node/StackMain-ME6LYFGI.cjs.map +0 -7
- package/dist/lib/node/chunk-O5SQVKNW.cjs.map +0 -7
- package/dist/lib/node-esm/StackMain-D3P3PIMI.mjs +0 -278
- package/dist/lib/node-esm/StackMain-D3P3PIMI.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-J57BXQJY.mjs.map +0 -7
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2024 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { createContext, useContext } from 'react';
|
|
6
|
+
|
|
7
|
+
import { type AddSectionPosition } from '../types';
|
|
8
|
+
|
|
9
|
+
export type StackContextValue = {
|
|
10
|
+
onCollapse: (id: string, collapsed: boolean) => void;
|
|
11
|
+
onNavigate: (id: string) => Promise<void>;
|
|
12
|
+
onDelete: (id: string) => Promise<void>;
|
|
13
|
+
onAdd: (id: string, position: AddSectionPosition) => void;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const StackContext = createContext<StackContextValue>({
|
|
17
|
+
onCollapse: () => {},
|
|
18
|
+
onNavigate: async () => {},
|
|
19
|
+
onDelete: async () => {},
|
|
20
|
+
onAdd: () => {},
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
export const useStack = () => useContext(StackContext);
|
|
@@ -8,43 +8,38 @@ import React, { useEffect, useMemo, useState } from 'react';
|
|
|
8
8
|
import {
|
|
9
9
|
LayoutAction,
|
|
10
10
|
NavigationAction,
|
|
11
|
-
Surface,
|
|
12
11
|
parseMetadataResolverPlugin,
|
|
13
12
|
useIntentDispatcher,
|
|
14
13
|
useResolvePlugin,
|
|
15
14
|
} from '@dxos/app-framework';
|
|
16
|
-
import { create, getType, fullyQualifiedId
|
|
15
|
+
import { create, getType, fullyQualifiedId } from '@dxos/client/echo';
|
|
17
16
|
import { useGraph } from '@dxos/plugin-graph';
|
|
18
17
|
import { SpaceAction } from '@dxos/plugin-space';
|
|
19
18
|
import { type CollectionType } from '@dxos/plugin-space/types';
|
|
20
19
|
import { Button, toLocalizedString, useTranslation } from '@dxos/react-ui';
|
|
21
20
|
import { AttentionProvider } from '@dxos/react-ui-attention';
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
type AddSectionPosition,
|
|
25
|
-
type CollapsedSections,
|
|
26
|
-
Stack,
|
|
27
|
-
type StackProps,
|
|
28
|
-
type StackSectionItem,
|
|
29
|
-
} from '@dxos/react-ui-stack';
|
|
21
|
+
import { Stack } from '@dxos/react-ui-stack';
|
|
30
22
|
import { nonNullable } from '@dxos/util';
|
|
31
23
|
|
|
32
24
|
import { AddSection } from './AddSection';
|
|
33
|
-
import {
|
|
34
|
-
import {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
25
|
+
import { StackContext } from './StackContext';
|
|
26
|
+
import { StackSection } from './StackSection';
|
|
27
|
+
import { STACK_PLUGIN } from '../meta';
|
|
28
|
+
import {
|
|
29
|
+
StackViewType,
|
|
30
|
+
type CollapsedSections,
|
|
31
|
+
type StackSectionMetadata,
|
|
32
|
+
type StackSectionView,
|
|
33
|
+
type StackSectionItem,
|
|
34
|
+
type AddSectionPosition,
|
|
35
|
+
} from '../types';
|
|
40
36
|
|
|
41
37
|
type StackMainProps = {
|
|
42
38
|
id: string;
|
|
43
39
|
collection: CollectionType;
|
|
44
|
-
separation?: boolean;
|
|
45
40
|
};
|
|
46
41
|
|
|
47
|
-
const StackMain = ({ id, collection
|
|
42
|
+
const StackMain = ({ id, collection }: StackMainProps) => {
|
|
48
43
|
const dispatch = useIntentDispatcher();
|
|
49
44
|
const { graph } = useGraph();
|
|
50
45
|
const { t } = useTranslation(STACK_PLUGIN);
|
|
@@ -67,72 +62,22 @@ const StackMain = ({ id, collection, separation }: StackMainProps) => {
|
|
|
67
62
|
.map((object) => {
|
|
68
63
|
const metadata = metadataPlugin?.provides.metadata.resolver(
|
|
69
64
|
getType(object)?.objectId ?? 'never',
|
|
70
|
-
) as
|
|
65
|
+
) as StackSectionMetadata;
|
|
71
66
|
const view = {
|
|
72
67
|
...stack.sections[object.id],
|
|
73
68
|
collapsed: collapsedSections[fullyQualifiedId(object)],
|
|
74
69
|
title:
|
|
75
70
|
(object as any)?.title ?? toLocalizedString(graph.findNode(fullyQualifiedId(object))?.properties.label, t),
|
|
76
|
-
} as
|
|
77
|
-
return { id: fullyQualifiedId(object), object, metadata, view };
|
|
71
|
+
} as StackSectionView;
|
|
72
|
+
return { id: fullyQualifiedId(object), object, metadata, view } satisfies StackSectionItem;
|
|
78
73
|
}) ?? [];
|
|
79
74
|
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
if (active.type !== SECTION_IDENTIFIER) {
|
|
83
|
-
return 'reject';
|
|
84
|
-
}
|
|
85
|
-
if (Path.parent(active.path) === Path.parent(over.path)) {
|
|
86
|
-
return 'rearrange';
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const parseData = metadataPlugin?.provides.metadata.resolver(active.type)?.parse;
|
|
90
|
-
const data = parseData ? parseData(active.item, 'object') : active.item;
|
|
91
|
-
|
|
92
|
-
// TODO(wittjosiah): Prevent dropping items which don't have a section renderer?
|
|
93
|
-
// Perhaps stack plugin should just provide a fallback section renderer.
|
|
94
|
-
if (!isReactiveObject(data)) {
|
|
95
|
-
return 'reject';
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
const exists = items.findIndex(({ id }) => id === active.item.id) >= 0;
|
|
99
|
-
if (!exists) {
|
|
100
|
-
return 'transfer';
|
|
101
|
-
} else {
|
|
102
|
-
return 'reject';
|
|
103
|
-
}
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
const handleDrop = ({ operation, active, over }: MosaicDropEvent<number>) => {
|
|
107
|
-
if (
|
|
108
|
-
(active.path === Path.create(id, active.item.id) || active.path === id) &&
|
|
109
|
-
(operation !== 'copy' || over.path === Path.create(id, over.item.id) || over.path === id)
|
|
110
|
-
) {
|
|
111
|
-
collection.objects.splice(active.position!, 1);
|
|
112
|
-
delete stack.sections[active.item.id];
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
const parseData = metadataPlugin?.provides.metadata.resolver(active.type)?.parse;
|
|
116
|
-
const object = parseData?.(active.item, 'object');
|
|
117
|
-
if (object && over.path === Path.create(id, over.item.id)) {
|
|
118
|
-
collection.objects.splice(over.position!, 0, object);
|
|
119
|
-
} else if (object && over.path === id) {
|
|
120
|
-
collection.objects.push(object);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
if (!stack.sections[object.id]) {
|
|
124
|
-
stack.sections[object.id] = {};
|
|
125
|
-
}
|
|
126
|
-
};
|
|
127
|
-
|
|
128
|
-
const handleDelete = async (path: string) => {
|
|
129
|
-
const index = collection.objects
|
|
130
|
-
.filter(nonNullable)
|
|
131
|
-
.findIndex((section) => fullyQualifiedId(section) === Path.last(path));
|
|
75
|
+
const handleDelete = async (id: string) => {
|
|
76
|
+
const index = collection.objects.filter(nonNullable).findIndex((section) => fullyQualifiedId(section) === id);
|
|
132
77
|
if (index >= 0) {
|
|
133
78
|
await dispatch({
|
|
134
|
-
action: SpaceAction.
|
|
135
|
-
data: {
|
|
79
|
+
action: SpaceAction.REMOVE_OBJECTS,
|
|
80
|
+
data: { objects: [collection.objects[index]], collection },
|
|
136
81
|
});
|
|
137
82
|
|
|
138
83
|
// TODO(wittjosiah): The section should also be removed, but needs to be restored if the action is undone.
|
|
@@ -140,56 +85,49 @@ const StackMain = ({ id, collection, separation }: StackMainProps) => {
|
|
|
140
85
|
}
|
|
141
86
|
};
|
|
142
87
|
|
|
143
|
-
|
|
88
|
+
const handleAdd = (id: string, position: AddSectionPosition) => {
|
|
89
|
+
void dispatch?.({
|
|
90
|
+
action: LayoutAction.SET_LAYOUT,
|
|
91
|
+
data: {
|
|
92
|
+
element: 'dialog',
|
|
93
|
+
component: `${STACK_PLUGIN}/AddSectionDialog`,
|
|
94
|
+
subject: { path: id, position, collection },
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
};
|
|
144
98
|
|
|
145
|
-
const handleNavigate = async (
|
|
146
|
-
const toId = fullyQualifiedId(object);
|
|
99
|
+
const handleNavigate = async (id: string) => {
|
|
147
100
|
await dispatch([
|
|
148
101
|
{
|
|
149
102
|
action: NavigationAction.OPEN,
|
|
150
|
-
data: { activeParts: { main: [
|
|
103
|
+
data: { activeParts: { main: [id] } },
|
|
151
104
|
},
|
|
152
105
|
{
|
|
153
106
|
action: LayoutAction.SCROLL_INTO_VIEW,
|
|
154
|
-
data: { id
|
|
107
|
+
data: { id },
|
|
155
108
|
},
|
|
156
109
|
]);
|
|
157
110
|
};
|
|
158
111
|
|
|
159
|
-
const
|
|
160
|
-
void dispatch?.({
|
|
161
|
-
action: LayoutAction.SET_LAYOUT,
|
|
162
|
-
data: {
|
|
163
|
-
element: 'dialog',
|
|
164
|
-
component: `${STACK_PLUGIN}/AddSectionDialog`,
|
|
165
|
-
subject: { path, position, collection },
|
|
166
|
-
},
|
|
167
|
-
});
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
const handleCollapseSection = (id: string, collapsed: boolean) => {
|
|
112
|
+
const handleCollapse = (id: string, collapsed: boolean) => {
|
|
171
113
|
setCollapsedSections((prev) => ({ ...prev, [id]: collapsed }));
|
|
172
114
|
};
|
|
173
115
|
|
|
174
116
|
return (
|
|
175
117
|
<AttentionProvider id={id}>
|
|
176
|
-
<
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
onNavigateToSection={handleNavigate}
|
|
190
|
-
onAddSection={handleAddSection}
|
|
191
|
-
onCollapseSection={handleCollapseSection}
|
|
192
|
-
/>
|
|
118
|
+
<StackContext.Provider
|
|
119
|
+
value={{
|
|
120
|
+
onCollapse: handleCollapse,
|
|
121
|
+
onNavigate: handleNavigate,
|
|
122
|
+
onDelete: handleDelete,
|
|
123
|
+
onAdd: handleAdd,
|
|
124
|
+
}}
|
|
125
|
+
>
|
|
126
|
+
<Stack orientation='vertical' size='intrinsic' id={id} data-testid='main.stack' classNames='divide-y-reverse'>
|
|
127
|
+
{items.map((item) => (
|
|
128
|
+
<StackSection key={item.id} {...item} />
|
|
129
|
+
))}
|
|
130
|
+
</Stack>
|
|
193
131
|
|
|
194
132
|
{items.length === 0 ? (
|
|
195
133
|
<AddSection collection={collection} />
|
|
@@ -214,7 +152,7 @@ const StackMain = ({ id, collection, separation }: StackMainProps) => {
|
|
|
214
152
|
</Button>
|
|
215
153
|
</div>
|
|
216
154
|
)}
|
|
217
|
-
</
|
|
155
|
+
</StackContext.Provider>
|
|
218
156
|
</AttentionProvider>
|
|
219
157
|
);
|
|
220
158
|
};
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2024 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as CollapsiblePrimitive from '@radix-ui/react-collapsible';
|
|
6
|
+
import React, { useState } from 'react';
|
|
7
|
+
|
|
8
|
+
import { Surface } from '@dxos/app-framework';
|
|
9
|
+
import { DropdownMenu, Icon, useTranslation, IconButton } from '@dxos/react-ui';
|
|
10
|
+
import { useAttendableAttributes } from '@dxos/react-ui-attention';
|
|
11
|
+
import { StackItem } from '@dxos/react-ui-stack';
|
|
12
|
+
import { mx, getSize, textBlockWidth } from '@dxos/react-ui-theme';
|
|
13
|
+
|
|
14
|
+
import { CaretDownUp } from './CaretDownUp';
|
|
15
|
+
import { useStack } from './StackContext';
|
|
16
|
+
import { STACK_PLUGIN } from '../meta';
|
|
17
|
+
import { type StackSectionItem } from '../types';
|
|
18
|
+
|
|
19
|
+
const sectionActionDimensions = 'm-1 p-1 shrink-0 min-bs-0 is-[--rail-action] bs-min';
|
|
20
|
+
|
|
21
|
+
export const StackSection = ({
|
|
22
|
+
id,
|
|
23
|
+
view,
|
|
24
|
+
object,
|
|
25
|
+
metadata: { icon = 'ph--placeholder--regular' },
|
|
26
|
+
}: StackSectionItem) => {
|
|
27
|
+
const { t } = useTranslation(STACK_PLUGIN);
|
|
28
|
+
const { onNavigate, onAdd, onCollapse, onDelete } = useStack();
|
|
29
|
+
const [optionsMenuOpen, setOptionsMenuOpen] = useState(false);
|
|
30
|
+
const attendableAttrs = useAttendableAttributes(id);
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<CollapsiblePrimitive.Root asChild open={!view.collapsed} onOpenChange={(nextOpen) => onCollapse?.(id, !nextOpen)}>
|
|
34
|
+
<StackItem.Root item={{ id }} role='section' {...attendableAttrs}>
|
|
35
|
+
<StackItem.Heading classNames='attention-surface'>
|
|
36
|
+
<span className='sr-only'>{view.title}</span>
|
|
37
|
+
<div role='none' className='sticky -block-start-px bg-[--sticky-bg]'>
|
|
38
|
+
<DropdownMenu.Root
|
|
39
|
+
{...{
|
|
40
|
+
open: optionsMenuOpen,
|
|
41
|
+
onOpenChange: setOptionsMenuOpen,
|
|
42
|
+
}}
|
|
43
|
+
>
|
|
44
|
+
<DropdownMenu.Trigger asChild>
|
|
45
|
+
<StackItem.SigilButton>
|
|
46
|
+
<Icon icon={icon} size={5} classNames='transition-opacity' />
|
|
47
|
+
</StackItem.SigilButton>
|
|
48
|
+
</DropdownMenu.Trigger>
|
|
49
|
+
<DropdownMenu.Portal>
|
|
50
|
+
<DropdownMenu.Content style={{ zIndex: 70 }}>
|
|
51
|
+
<DropdownMenu.Viewport>
|
|
52
|
+
{view.collapsed ? (
|
|
53
|
+
<DropdownMenu.Item onClick={() => onNavigate(id)} data-testid='section.navigate-to'>
|
|
54
|
+
<Icon icon='ph--arrow-square-out--regular' size={5} />
|
|
55
|
+
<span className='mis-2 grow'>{t('navigate to section label')}</span>
|
|
56
|
+
</DropdownMenu.Item>
|
|
57
|
+
) : (
|
|
58
|
+
<CollapsiblePrimitive.Trigger asChild>
|
|
59
|
+
<DropdownMenu.Item>
|
|
60
|
+
<CaretDownUp className={getSize(5)} />
|
|
61
|
+
<span className='mis-2 grow'>{t('collapse label')}</span>
|
|
62
|
+
</DropdownMenu.Item>
|
|
63
|
+
</CollapsiblePrimitive.Trigger>
|
|
64
|
+
)}
|
|
65
|
+
<DropdownMenu.Item onClick={() => onAdd(id, 'before')} data-testid='section.add-before'>
|
|
66
|
+
<Icon icon='ph--arrow-line-up--regular' size={5} />
|
|
67
|
+
<span className='mis-2 grow'>{t('add section before label')}</span>
|
|
68
|
+
</DropdownMenu.Item>
|
|
69
|
+
<DropdownMenu.Item onClick={() => onAdd(id, 'after')} data-testid='section.add-after'>
|
|
70
|
+
<Icon icon='ph--arrow-line-down--regular' size={5} />
|
|
71
|
+
<span className='mis-2 grow'>{t('add section after label')}</span>
|
|
72
|
+
</DropdownMenu.Item>
|
|
73
|
+
<DropdownMenu.Item onClick={() => onDelete(id)} data-testid='section.remove'>
|
|
74
|
+
<Icon icon='ph--trash--regular' size={5} />
|
|
75
|
+
<span className='mis-2 grow'>{t('remove section label')}</span>
|
|
76
|
+
</DropdownMenu.Item>
|
|
77
|
+
</DropdownMenu.Viewport>
|
|
78
|
+
<DropdownMenu.Arrow />
|
|
79
|
+
</DropdownMenu.Content>
|
|
80
|
+
</DropdownMenu.Portal>
|
|
81
|
+
</DropdownMenu.Root>
|
|
82
|
+
{view.collapsed ? (
|
|
83
|
+
<CollapsiblePrimitive.Trigger asChild>
|
|
84
|
+
<IconButton
|
|
85
|
+
iconOnly
|
|
86
|
+
tooltipZIndex='70'
|
|
87
|
+
variant='ghost'
|
|
88
|
+
label={t('expand label')}
|
|
89
|
+
icon='ph--caret-up-down--regular'
|
|
90
|
+
classNames={sectionActionDimensions}
|
|
91
|
+
/>
|
|
92
|
+
</CollapsiblePrimitive.Trigger>
|
|
93
|
+
) : (
|
|
94
|
+
<IconButton
|
|
95
|
+
iconOnly
|
|
96
|
+
tooltipZIndex='70'
|
|
97
|
+
variant='ghost'
|
|
98
|
+
onClick={() => onNavigate(id)}
|
|
99
|
+
label={t('navigate to section label')}
|
|
100
|
+
icon='ph--arrow-square-out--regular'
|
|
101
|
+
data-testid='section.navigate-to'
|
|
102
|
+
classNames={sectionActionDimensions}
|
|
103
|
+
/>
|
|
104
|
+
)}
|
|
105
|
+
</div>
|
|
106
|
+
</StackItem.Heading>
|
|
107
|
+
<CollapsiblePrimitive.Content>
|
|
108
|
+
<Surface role='section' data={{ object }} limit={1} placeholder={<></>} />
|
|
109
|
+
</CollapsiblePrimitive.Content>
|
|
110
|
+
{view.collapsed && (
|
|
111
|
+
<StackItem.Content toolbar={false} classNames='attention-surface'>
|
|
112
|
+
<h2 className={mx('flex items-center p-4 font-medium is-full', textBlockWidth)}>{view.title}</h2>
|
|
113
|
+
</StackItem.Content>
|
|
114
|
+
)}
|
|
115
|
+
</StackItem.Root>
|
|
116
|
+
</CollapsiblePrimitive.Root>
|
|
117
|
+
);
|
|
118
|
+
};
|
package/src/meta.ts
CHANGED
|
@@ -10,6 +10,9 @@ export const SECTION_IDENTIFIER = 'dxos.org/type/StackSection';
|
|
|
10
10
|
export default {
|
|
11
11
|
id: STACK_PLUGIN,
|
|
12
12
|
// TODO(wittjosiah): Prevents "stacks" language from being exposed to users in settings panel.
|
|
13
|
+
// Conside renaming this to the collection plugin and trying to factor more collections logic from the space plugin.
|
|
13
14
|
name: 'Collections',
|
|
15
|
+
description: 'View collections of objects within the deck.',
|
|
14
16
|
icon: 'ph--stack-simple--regular',
|
|
17
|
+
source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-stack',
|
|
15
18
|
} satisfies PluginMeta;
|
package/src/translations.ts
CHANGED
|
@@ -19,6 +19,15 @@ export default [
|
|
|
19
19
|
'add section input placeholder': 'Find the type of section to add',
|
|
20
20
|
'upload file label': 'Add file',
|
|
21
21
|
'add section label': 'Add section',
|
|
22
|
+
'empty stack message': 'Drag items into the stack.',
|
|
23
|
+
'remove section label': 'Delete',
|
|
24
|
+
'navigate to section label': 'Navigate to item',
|
|
25
|
+
'untitled section title': 'Untitled section',
|
|
26
|
+
'add section before label': 'Add before',
|
|
27
|
+
'add section after label': 'Add after',
|
|
28
|
+
'expand label': 'Expand',
|
|
29
|
+
'collapse label': 'Collapse',
|
|
30
|
+
'drag handle label': 'Press space or enter to begin dragging this item.',
|
|
22
31
|
},
|
|
23
32
|
},
|
|
24
33
|
},
|
package/src/types/types.ts
CHANGED
|
@@ -13,6 +13,23 @@ import type {
|
|
|
13
13
|
TranslationsProvides,
|
|
14
14
|
} from '@dxos/app-framework';
|
|
15
15
|
import { type SchemaProvides } from '@dxos/plugin-client';
|
|
16
|
+
import { type CollectionType } from '@dxos/plugin-space/types';
|
|
17
|
+
import { type Label } from '@dxos/react-ui';
|
|
18
|
+
import { type StackItemSize } from '@dxos/react-ui-stack';
|
|
19
|
+
|
|
20
|
+
export type AddSectionPosition = 'before' | 'after' | 'beforeAll' | 'afterAll';
|
|
21
|
+
|
|
22
|
+
export type CollapsedSections = Record<string, boolean>;
|
|
23
|
+
|
|
24
|
+
export type CollectionItem = CollectionType['objects'][number];
|
|
25
|
+
|
|
26
|
+
export type StackSectionView = {
|
|
27
|
+
title?: string;
|
|
28
|
+
size?: StackItemSize;
|
|
29
|
+
height?: number;
|
|
30
|
+
collapsed?: boolean;
|
|
31
|
+
custom?: Record<string, any>;
|
|
32
|
+
};
|
|
16
33
|
|
|
17
34
|
// TODO(wittjosiah): Creators/choosers likely aren't stack-specific.
|
|
18
35
|
// Also distinct from graph actions though, output should be inserted into current view rather than navigated to.
|
|
@@ -24,6 +41,19 @@ type StackSectionAction = {
|
|
|
24
41
|
icon: FC<IconProps>;
|
|
25
42
|
};
|
|
26
43
|
|
|
44
|
+
export type StackSectionMetadata = {
|
|
45
|
+
icon?: string;
|
|
46
|
+
placeholder?: Label;
|
|
47
|
+
viewActions?: (item: CollectionItem) => StackSectionAction;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export type StackSectionItem = {
|
|
51
|
+
id: string;
|
|
52
|
+
object: CollectionType['objects'][number];
|
|
53
|
+
view: StackSectionView;
|
|
54
|
+
metadata: StackSectionMetadata;
|
|
55
|
+
};
|
|
56
|
+
|
|
27
57
|
export type StackSectionCreator = StackSectionAction & {
|
|
28
58
|
intent: Intent | Intent[];
|
|
29
59
|
};
|