@dxos/plugin-simple-layout 0.8.4-main.2244d791bb → 0.8.4-main.4a85c3132b
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/{chunk-U632CHRU.mjs → chunk-TMZNLVT2.mjs} +130 -127
- package/dist/lib/browser/chunk-TMZNLVT2.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +2 -2
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/{react-root-ZQTWLJYR.mjs → react-root-MMB575WY.mjs} +2 -2
- package/dist/lib/browser/{react-surface-IOYDLMNR.mjs → react-surface-M6CURANW.mjs} +2 -2
- package/dist/lib/node-esm/{chunk-UXFYLQJA.mjs → chunk-FLOYBAHE.mjs} +130 -127
- package/dist/lib/node-esm/chunk-FLOYBAHE.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +2 -2
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/{react-root-FMAUHDJI.mjs → react-root-ENZKVSY4.mjs} +2 -2
- package/dist/lib/node-esm/{react-surface-ZAZRIKZQ.mjs → react-surface-ITVNQYLG.mjs} +2 -2
- package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts +1 -1
- package/dist/types/src/capabilities/react-root/react-root.d.ts +1 -1
- package/dist/types/src/capabilities/react-surface/react-surface.d.ts +1 -1
- package/dist/types/src/capabilities/spotlight-dismiss/index.d.ts +1 -1
- package/dist/types/src/capabilities/spotlight-dismiss/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/spotlight-dismiss/spotlight-dismiss.d.ts +1 -1
- package/dist/types/src/capabilities/state/index.d.ts +1 -1
- package/dist/types/src/capabilities/state/state.d.ts +1 -1
- package/dist/types/src/capabilities/url-handler/url-handler.d.ts +1 -1
- package/dist/types/src/components/ContentError.stories.d.ts +1 -3
- package/dist/types/src/components/ContentError.stories.d.ts.map +1 -1
- package/dist/types/src/components/Home/Home.d.ts.map +1 -1
- package/dist/types/src/components/MobileLayout/MobileLayout.stories.d.ts.map +1 -1
- package/dist/types/src/components/Popover/Popover.d.ts.map +1 -1
- package/dist/types/src/components/SimpleLayout/AppBar.d.ts.map +1 -1
- package/dist/types/src/components/SimpleLayout/Drawer.d.ts.map +1 -1
- package/dist/types/src/components/SimpleLayout/Main.d.ts.map +1 -1
- package/dist/types/src/components/SimpleLayout/NavBar.d.ts.map +1 -1
- package/dist/types/src/components/Workspace/Workspace.d.ts.map +1 -1
- package/dist/types/src/hooks/useAppBarProps.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +29 -28
- package/src/components/ContentError.stories.tsx +7 -6
- package/src/components/ContentLoading.stories.tsx +1 -1
- package/src/components/ContentLoading.tsx +1 -1
- package/src/components/Dialog/Dialog.tsx +3 -3
- package/src/components/Home/Home.tsx +25 -20
- package/src/components/MobileLayout/MobileLayout.stories.tsx +23 -19
- package/src/components/MobileLayout/MobileLayout.tsx +2 -2
- package/src/components/Popover/Popover.tsx +14 -4
- package/src/components/SimpleLayout/AppBar.stories.tsx +2 -2
- package/src/components/SimpleLayout/AppBar.tsx +17 -20
- package/src/components/SimpleLayout/Drawer.tsx +12 -9
- package/src/components/SimpleLayout/Main.tsx +8 -6
- package/src/components/SimpleLayout/NavBar.stories.tsx +8 -8
- package/src/components/SimpleLayout/NavBar.tsx +4 -10
- package/src/components/SimpleLayout/SimpleLayout.stories.tsx +2 -2
- package/src/components/SimpleLayout/SimpleLayout.tsx +1 -1
- package/src/components/Workspace/Workspace.tsx +25 -20
- package/src/components/hooks.ts +3 -3
- package/src/hooks/actions.ts +2 -2
- package/src/hooks/useAppBarProps.ts +7 -3
- package/src/hooks/useCompanions.ts +1 -1
- package/src/hooks/useDrawerActions.ts +2 -2
- package/src/hooks/useNavbarActions.ts +5 -5
- package/dist/lib/browser/chunk-U632CHRU.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-UXFYLQJA.mjs.map +0 -7
- package/dist/types/src/components/ContentError.d.ts +0 -5
- package/dist/types/src/components/ContentError.d.ts.map +0 -1
- package/src/components/ContentError.tsx +0 -23
- /package/dist/lib/browser/{react-root-ZQTWLJYR.mjs.map → react-root-MMB575WY.mjs.map} +0 -0
- /package/dist/lib/browser/{react-surface-IOYDLMNR.mjs.map → react-surface-M6CURANW.mjs.map} +0 -0
- /package/dist/lib/node-esm/{react-root-FMAUHDJI.mjs.map → react-root-ENZKVSY4.mjs.map} +0 -0
- /package/dist/lib/node-esm/{react-surface-ZAZRIKZQ.mjs.map → react-surface-ITVNQYLG.mjs.map} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/plugin-simple-layout",
|
|
3
|
-
"version": "0.8.4-main.
|
|
3
|
+
"version": "0.8.4-main.4a85c3132b",
|
|
4
4
|
"description": "Simple layout plugin for minimal UI contexts like popover windows.",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -14,9 +14,9 @@
|
|
|
14
14
|
"type": "module",
|
|
15
15
|
"exports": {
|
|
16
16
|
".": {
|
|
17
|
+
"source": "./src/index.ts",
|
|
17
18
|
"browser": "./dist/lib/browser/index.mjs",
|
|
18
19
|
"node": "./dist/lib/node-esm/index.mjs",
|
|
19
|
-
"source": "./src/index.ts",
|
|
20
20
|
"types": "./dist/types/src/index.d.ts"
|
|
21
21
|
}
|
|
22
22
|
},
|
|
@@ -31,19 +31,20 @@
|
|
|
31
31
|
"@radix-ui/react-context": "1.1.1",
|
|
32
32
|
"@tauri-apps/plugin-deep-link": "^2.2.0",
|
|
33
33
|
"@tauri-apps/plugin-haptics": "^2.3.2",
|
|
34
|
-
"@dxos/app-framework": "0.8.4-main.
|
|
35
|
-
"@dxos/
|
|
36
|
-
"@dxos/
|
|
37
|
-
"@dxos/
|
|
38
|
-
"@dxos/
|
|
39
|
-
"@dxos/
|
|
40
|
-
"@dxos/react-ui-
|
|
41
|
-
"@dxos/react-ui-
|
|
42
|
-
"@dxos/react-ui-mosaic": "0.8.4-main.
|
|
43
|
-
"@dxos/react-ui-searchlist": "0.8.4-main.
|
|
44
|
-
"@dxos/react-ui-stack": "0.8.4-main.
|
|
45
|
-
"@dxos/schema": "0.8.4-main.
|
|
46
|
-
"@dxos/util": "0.8.4-main.
|
|
34
|
+
"@dxos/app-framework": "0.8.4-main.4a85c3132b",
|
|
35
|
+
"@dxos/echo": "0.8.4-main.4a85c3132b",
|
|
36
|
+
"@dxos/async": "0.8.4-main.4a85c3132b",
|
|
37
|
+
"@dxos/app-toolkit": "0.8.4-main.4a85c3132b",
|
|
38
|
+
"@dxos/log": "0.8.4-main.4a85c3132b",
|
|
39
|
+
"@dxos/operation": "0.8.4-main.4a85c3132b",
|
|
40
|
+
"@dxos/react-ui-menu": "0.8.4-main.4a85c3132b",
|
|
41
|
+
"@dxos/react-ui-attention": "0.8.4-main.4a85c3132b",
|
|
42
|
+
"@dxos/react-ui-mosaic": "0.8.4-main.4a85c3132b",
|
|
43
|
+
"@dxos/react-ui-searchlist": "0.8.4-main.4a85c3132b",
|
|
44
|
+
"@dxos/react-ui-stack": "0.8.4-main.4a85c3132b",
|
|
45
|
+
"@dxos/schema": "0.8.4-main.4a85c3132b",
|
|
46
|
+
"@dxos/util": "0.8.4-main.4a85c3132b",
|
|
47
|
+
"@dxos/plugin-graph": "0.8.4-main.4a85c3132b"
|
|
47
48
|
},
|
|
48
49
|
"devDependencies": {
|
|
49
50
|
"@types/react": "~19.2.7",
|
|
@@ -51,24 +52,24 @@
|
|
|
51
52
|
"effect": "3.19.16",
|
|
52
53
|
"react": "~19.2.3",
|
|
53
54
|
"react-dom": "~19.2.3",
|
|
54
|
-
"vite": "7.1.
|
|
55
|
-
"@dxos/
|
|
56
|
-
"@dxos/plugin-
|
|
57
|
-
"@dxos/
|
|
58
|
-
"@dxos/plugin-
|
|
59
|
-
"@dxos/plugin-
|
|
60
|
-
"@dxos/react-ui": "0.8.4-main.
|
|
61
|
-
"@dxos/
|
|
62
|
-
"@dxos/storybook-utils": "0.8.4-main.
|
|
63
|
-
"@dxos/
|
|
64
|
-
"@dxos/ui-theme": "0.8.4-main.
|
|
55
|
+
"vite": "^7.1.11",
|
|
56
|
+
"@dxos/plugin-preview": "0.8.4-main.4a85c3132b",
|
|
57
|
+
"@dxos/plugin-client": "0.8.4-main.4a85c3132b",
|
|
58
|
+
"@dxos/app-graph": "0.8.4-main.4a85c3132b",
|
|
59
|
+
"@dxos/plugin-space": "0.8.4-main.4a85c3132b",
|
|
60
|
+
"@dxos/plugin-search": "0.8.4-main.4a85c3132b",
|
|
61
|
+
"@dxos/react-ui": "0.8.4-main.4a85c3132b",
|
|
62
|
+
"@dxos/schema": "0.8.4-main.4a85c3132b",
|
|
63
|
+
"@dxos/storybook-utils": "0.8.4-main.4a85c3132b",
|
|
64
|
+
"@dxos/plugin-testing": "0.8.4-main.4a85c3132b",
|
|
65
|
+
"@dxos/ui-theme": "0.8.4-main.4a85c3132b"
|
|
65
66
|
},
|
|
66
67
|
"peerDependencies": {
|
|
67
68
|
"effect": "3.19.16",
|
|
68
69
|
"react": "~19.2.3",
|
|
69
70
|
"react-dom": "~19.2.3",
|
|
70
|
-
"@dxos/react-ui": "0.8.4-main.
|
|
71
|
-
"@dxos/ui-theme": "0.8.4-main.
|
|
71
|
+
"@dxos/react-ui": "0.8.4-main.4a85c3132b",
|
|
72
|
+
"@dxos/ui-theme": "0.8.4-main.4a85c3132b"
|
|
72
73
|
},
|
|
73
74
|
"publishConfig": {
|
|
74
75
|
"access": "public"
|
|
@@ -4,28 +4,29 @@
|
|
|
4
4
|
|
|
5
5
|
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
6
6
|
|
|
7
|
+
import { ErrorFallback } from '@dxos/react-ui';
|
|
7
8
|
import { withTheme } from '@dxos/react-ui/testing';
|
|
8
9
|
|
|
9
10
|
import { translations } from '../translations';
|
|
10
11
|
|
|
11
|
-
import { ContentError } from './ContentError';
|
|
12
|
-
|
|
13
12
|
const meta = {
|
|
14
|
-
title: 'plugins/plugin-simple-layout/
|
|
15
|
-
component:
|
|
13
|
+
title: 'plugins/plugin-simple-layout/components/ErrorFallback',
|
|
14
|
+
component: ErrorFallback,
|
|
16
15
|
decorators: [withTheme()],
|
|
17
16
|
parameters: {
|
|
18
17
|
layout: 'centered',
|
|
19
18
|
translations,
|
|
20
19
|
},
|
|
21
|
-
} satisfies Meta<typeof
|
|
20
|
+
} satisfies Meta<typeof ErrorFallback>;
|
|
22
21
|
|
|
23
22
|
export default meta;
|
|
24
23
|
|
|
25
24
|
type Story = StoryObj<typeof meta>;
|
|
26
25
|
|
|
27
26
|
export const Default: Story = {
|
|
28
|
-
args: {
|
|
27
|
+
args: {
|
|
28
|
+
error: new Error('An unexpected error occurred'),
|
|
29
|
+
},
|
|
29
30
|
};
|
|
30
31
|
|
|
31
32
|
export const WithError: Story = {
|
|
@@ -9,7 +9,7 @@ import { withTheme } from '@dxos/react-ui/testing';
|
|
|
9
9
|
import { ContentLoading } from './ContentLoading';
|
|
10
10
|
|
|
11
11
|
const meta = {
|
|
12
|
-
title: 'plugins/plugin-simple-layout/ContentLoading',
|
|
12
|
+
title: 'plugins/plugin-simple-layout/components/ContentLoading',
|
|
13
13
|
component: ContentLoading,
|
|
14
14
|
decorators: [withTheme()],
|
|
15
15
|
parameters: {
|
|
@@ -6,5 +6,5 @@ import React from 'react';
|
|
|
6
6
|
|
|
7
7
|
// TODO(burdon): Show skeleton: https://github.com/dxos/dxos/issues/8259
|
|
8
8
|
export const ContentLoading = () => {
|
|
9
|
-
return <div role='none' className='grid place-items-center attention-surface' />;
|
|
9
|
+
return <div role='none' className='grid place-items-center dx-attention-surface' />;
|
|
10
10
|
};
|
|
@@ -6,9 +6,9 @@ import React from 'react';
|
|
|
6
6
|
|
|
7
7
|
import { Surface } from '@dxos/app-framework/ui';
|
|
8
8
|
import { AlertDialog, Dialog as NaturalDialog } from '@dxos/react-ui';
|
|
9
|
+
import { ErrorFallback } from '@dxos/react-ui';
|
|
9
10
|
|
|
10
11
|
import { useSimpleLayoutState } from '../../hooks';
|
|
11
|
-
import { ContentError } from '../ContentError';
|
|
12
12
|
|
|
13
13
|
export const Dialog = () => {
|
|
14
14
|
const { state, updateState } = useSimpleLayoutState();
|
|
@@ -23,14 +23,14 @@ export const Dialog = () => {
|
|
|
23
23
|
onOpenChange={(nextOpen) => updateState((state) => ({ ...state, dialogOpen: nextOpen }))}
|
|
24
24
|
>
|
|
25
25
|
{state.dialogBlockAlign === 'end' ? (
|
|
26
|
-
<Surface.Surface role='dialog' data={state.dialogContent} limit={1} fallback={
|
|
26
|
+
<Surface.Surface role='dialog' data={state.dialogContent} limit={1} fallback={ErrorFallback} />
|
|
27
27
|
) : (
|
|
28
28
|
<DialogOverlay
|
|
29
29
|
blockAlign={state.dialogBlockAlign}
|
|
30
30
|
classNames={state.dialogOverlayClasses}
|
|
31
31
|
style={state.dialogOverlayStyle}
|
|
32
32
|
>
|
|
33
|
-
<Surface.Surface role='dialog' data={state.dialogContent} limit={1} fallback={
|
|
33
|
+
<Surface.Surface role='dialog' data={state.dialogContent} limit={1} fallback={ErrorFallback} />
|
|
34
34
|
</DialogOverlay>
|
|
35
35
|
)}
|
|
36
36
|
</DialogRoot>
|
|
@@ -8,8 +8,9 @@ import { useOperationInvoker } from '@dxos/app-framework/ui';
|
|
|
8
8
|
import { LayoutOperation } from '@dxos/app-toolkit';
|
|
9
9
|
import { useAppGraph } from '@dxos/app-toolkit/ui';
|
|
10
10
|
import { Node, useConnections } from '@dxos/plugin-graph';
|
|
11
|
-
import { Avatar, Icon,
|
|
12
|
-
import { Card
|
|
11
|
+
import { Avatar, Icon, Panel, ScrollArea, Toolbar, toLocalizedString, useTranslation } from '@dxos/react-ui';
|
|
12
|
+
import { Card } from '@dxos/react-ui';
|
|
13
|
+
import { Mosaic, type MosaicStackTileComponent } from '@dxos/react-ui-mosaic';
|
|
13
14
|
import { SearchList, useSearchListItem, useSearchListResults } from '@dxos/react-ui-searchlist';
|
|
14
15
|
import { mx } from '@dxos/ui-theme';
|
|
15
16
|
import { byPosition } from '@dxos/util';
|
|
@@ -40,22 +41,26 @@ export const Home = (_: HomeProps) => {
|
|
|
40
41
|
});
|
|
41
42
|
|
|
42
43
|
return (
|
|
43
|
-
<
|
|
44
|
-
<
|
|
45
|
-
<Toolbar
|
|
46
|
-
<
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
44
|
+
<SearchList.Root onSearch={handleSearch}>
|
|
45
|
+
<Panel.Root>
|
|
46
|
+
<Panel.Toolbar asChild>
|
|
47
|
+
<Toolbar.Root>
|
|
48
|
+
<SearchList.Input placeholder={t('search placeholder')} autoFocus />
|
|
49
|
+
</Toolbar.Root>
|
|
50
|
+
</Panel.Toolbar>
|
|
51
|
+
<Panel.Content asChild>
|
|
52
|
+
<SearchList.Content>
|
|
53
|
+
<Mosaic.Container asChild>
|
|
54
|
+
<ScrollArea.Root orientation='vertical'>
|
|
55
|
+
<ScrollArea.Viewport classNames='p-2'>
|
|
56
|
+
<Mosaic.Stack items={results} getId={(node) => node.id} Tile={WorkspaceTile} />
|
|
57
|
+
</ScrollArea.Viewport>
|
|
58
|
+
</ScrollArea.Root>
|
|
59
|
+
</Mosaic.Container>
|
|
60
|
+
</SearchList.Content>
|
|
61
|
+
</Panel.Content>
|
|
62
|
+
</Panel.Root>
|
|
63
|
+
</SearchList.Root>
|
|
59
64
|
);
|
|
60
65
|
};
|
|
61
66
|
|
|
@@ -97,7 +102,7 @@ const WorkspaceTile: MosaicStackTileComponent<Node.Node> = (props) => {
|
|
|
97
102
|
fullWidth
|
|
98
103
|
tabIndex={-1} // TODO(burdon): Use Mosaic.Focus.
|
|
99
104
|
data-selected={isSelected}
|
|
100
|
-
classNames={mx('dx-focus-ring', isSelected && 'bg-
|
|
105
|
+
classNames={mx('dx-focus-ring', isSelected && 'bg-hover-overlay')}
|
|
101
106
|
onClick={handleSelect}
|
|
102
107
|
ref={cardRef}
|
|
103
108
|
>
|
|
@@ -127,7 +132,7 @@ const filterItems = (node: Node.Node, disposition: string) => {
|
|
|
127
132
|
/** Returns root-level items filtered by disposition. */
|
|
128
133
|
const useItemsByDisposition = (disposition: string, sort = false) => {
|
|
129
134
|
const { graph } = useAppGraph();
|
|
130
|
-
const connections = useConnections(graph, Node.RootId);
|
|
135
|
+
const connections = useConnections(graph, Node.RootId, 'child');
|
|
131
136
|
const filtered = connections.filter((node) => filterItems(node, disposition));
|
|
132
137
|
return sort ? filtered.toSorted((a, b) => byPosition(a.properties, b.properties)) : filtered;
|
|
133
138
|
};
|
|
@@ -6,7 +6,7 @@ import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
|
6
6
|
import React, { type PropsWithChildren, useEffect, useState } from 'react';
|
|
7
7
|
|
|
8
8
|
import { addEventListener, combine } from '@dxos/async';
|
|
9
|
-
import { Flex, Input,
|
|
9
|
+
import { Flex, Input, Panel, Splitter, type SplitterMode, Toolbar } from '@dxos/react-ui';
|
|
10
10
|
import { withLayout, withTheme } from '@dxos/react-ui/testing';
|
|
11
11
|
|
|
12
12
|
import { MobileLayout, type MobileLayoutRootProps } from './MobileLayout';
|
|
@@ -54,20 +54,24 @@ const WithKeyboard = ({ children }: PropsWithChildren) => {
|
|
|
54
54
|
return <div className='h-screen relative'>{children}</div>;
|
|
55
55
|
};
|
|
56
56
|
|
|
57
|
-
const
|
|
57
|
+
const StoryPanel = ({ children, label }: PropsWithChildren<{ label: string }>) => {
|
|
58
58
|
return (
|
|
59
|
-
<
|
|
60
|
-
<Toolbar
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
59
|
+
<Panel.Root>
|
|
60
|
+
<Panel.Toolbar asChild>
|
|
61
|
+
<Toolbar.Root>
|
|
62
|
+
{label}
|
|
63
|
+
<Toolbar.Separator />
|
|
64
|
+
{children}
|
|
65
|
+
</Toolbar.Root>
|
|
66
|
+
</Panel.Toolbar>
|
|
67
|
+
<Panel.Content asChild>
|
|
68
|
+
<Flex column classNames='p-1'>
|
|
69
|
+
<Input.Root>
|
|
70
|
+
<Input.TextInput />
|
|
71
|
+
</Input.Root>
|
|
72
|
+
</Flex>
|
|
73
|
+
</Panel.Content>
|
|
74
|
+
</Panel.Root>
|
|
71
75
|
);
|
|
72
76
|
};
|
|
73
77
|
|
|
@@ -85,21 +89,21 @@ const DefaultStory = () => {
|
|
|
85
89
|
<MobileLayout.Panel safe={{ top: true, bottom: splitterMode === 'upper' }}>
|
|
86
90
|
<Splitter.Root mode={splitterMode} ratio={0.5}>
|
|
87
91
|
<Splitter.Panel position='upper'>
|
|
88
|
-
<
|
|
92
|
+
<StoryPanel label='Main'>
|
|
89
93
|
{splitterMode === 'upper' && (
|
|
90
94
|
<Toolbar.IconButton icon='ph--plus--regular' label='Open' onClick={() => setSplitterMode('both')} />
|
|
91
95
|
)}
|
|
92
|
-
</
|
|
96
|
+
</StoryPanel>
|
|
93
97
|
</Splitter.Panel>
|
|
94
98
|
<Splitter.Panel position='lower'>
|
|
95
|
-
<
|
|
99
|
+
<StoryPanel label='Drawer'>
|
|
96
100
|
<Toolbar.IconButton
|
|
97
101
|
icon={splitterMode === 'lower' ? 'ph--arrow-down--regular' : 'ph--arrow-up--regular'}
|
|
98
102
|
label={splitterMode === 'lower' ? 'Collapse' : 'Expand'}
|
|
99
103
|
onClick={() => setSplitterMode((splitterMode) => (splitterMode === 'both' ? 'lower' : 'both'))}
|
|
100
104
|
/>
|
|
101
105
|
<Toolbar.IconButton icon='ph--x--regular' label='Close' onClick={() => setSplitterMode('upper')} />
|
|
102
|
-
</
|
|
106
|
+
</StoryPanel>
|
|
103
107
|
</Splitter.Panel>
|
|
104
108
|
</Splitter.Root>
|
|
105
109
|
</MobileLayout.Panel>
|
|
@@ -109,7 +113,7 @@ const DefaultStory = () => {
|
|
|
109
113
|
};
|
|
110
114
|
|
|
111
115
|
const meta: Meta<MobileLayoutRootProps> = {
|
|
112
|
-
title: 'plugins/plugin-simple-layout/MobileLayout',
|
|
116
|
+
title: 'plugins/plugin-simple-layout/components/MobileLayout',
|
|
113
117
|
component: MobileLayout.Root,
|
|
114
118
|
render: DefaultStory,
|
|
115
119
|
decorators: [withTheme(), withLayout({ layout: 'column', classNames: 'relative' })],
|
|
@@ -54,7 +54,7 @@ const MobileLayoutRoot = forwardRef<HTMLDivElement, MobileLayoutRootProps>(
|
|
|
54
54
|
{...props}
|
|
55
55
|
role='none'
|
|
56
56
|
style={{
|
|
57
|
-
transition: `
|
|
57
|
+
transition: `h-size ${transition}ms ease-out`,
|
|
58
58
|
blockSize: 'calc(100vh - var(--kb-height, 0px))',
|
|
59
59
|
}}
|
|
60
60
|
className={mx('absolute top-0 left-0 right-0 flex flex-col', classNames)}
|
|
@@ -95,7 +95,7 @@ const MobileLayoutPanel = forwardRef<HTMLDivElement, MobileLayoutPanelProps>(
|
|
|
95
95
|
paddingTop: safe?.top ? 'env(safe-area-inset-top)' : undefined,
|
|
96
96
|
paddingBottom: safe?.bottom ? `calc((1 - var(--kb-open, 0)) * env(safe-area-inset-bottom))` : undefined,
|
|
97
97
|
}}
|
|
98
|
-
className={mx('relative
|
|
98
|
+
className={mx('relative h-full flex flex-col overflow-hidden', classNames)}
|
|
99
99
|
ref={forwardedRef}
|
|
100
100
|
>
|
|
101
101
|
{children}
|
|
@@ -6,8 +6,9 @@ import { createContext } from '@radix-ui/react-context';
|
|
|
6
6
|
import React, { type PropsWithChildren, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
7
7
|
|
|
8
8
|
import { Surface } from '@dxos/app-framework/ui';
|
|
9
|
+
import { useObjectNavigate } from '@dxos/app-toolkit/ui';
|
|
9
10
|
import { Popover, type PopoverContentInteractOutsideEvent, toLocalizedString, useTranslation } from '@dxos/react-ui';
|
|
10
|
-
import { Card } from '@dxos/react-ui
|
|
11
|
+
import { Card } from '@dxos/react-ui';
|
|
11
12
|
|
|
12
13
|
import { useSimpleLayoutState } from '../../hooks';
|
|
13
14
|
import { meta } from '../../meta';
|
|
@@ -53,10 +54,15 @@ export const PopoverRoot = ({ children }: PropsWithChildren) => {
|
|
|
53
54
|
);
|
|
54
55
|
};
|
|
55
56
|
|
|
57
|
+
// Extracts the subject from popover content if it has one, otherwise returns the content as-is.
|
|
58
|
+
const getPopoverSubject = (content: unknown): unknown =>
|
|
59
|
+
content && typeof content === 'object' && 'subject' in content ? (content as { subject: unknown }).subject : content;
|
|
60
|
+
|
|
56
61
|
export const PopoverContent = () => {
|
|
57
62
|
const { t } = useTranslation(meta.id);
|
|
58
63
|
const { state, updateState } = useSimpleLayoutState();
|
|
59
64
|
const { setOpen } = useLayoutPopoverContext('PopoverContent');
|
|
65
|
+
const handleNavigate = useObjectNavigate(getPopoverSubject(state.popoverContent));
|
|
60
66
|
|
|
61
67
|
const handleClose = useCallback(() => {
|
|
62
68
|
setOpen(false);
|
|
@@ -102,12 +108,16 @@ export const PopoverContent = () => {
|
|
|
102
108
|
<Popover.Viewport>
|
|
103
109
|
{state.popoverKind === 'base' && <Surface.Surface role='popover' data={state.popoverContent} limit={1} />}
|
|
104
110
|
{state.popoverKind === 'card' && (
|
|
105
|
-
<Card.Root border={false} classNames='
|
|
111
|
+
<Card.Root border={false} classNames='dx-card-popover'>
|
|
106
112
|
<Card.Toolbar>
|
|
107
113
|
{/* TODO(wittjosiah): Cleaner way to handle no drag handle in toolbar? */}
|
|
108
114
|
<span />
|
|
109
|
-
{state.popoverTitle ?
|
|
110
|
-
|
|
115
|
+
{state.popoverTitle ? (
|
|
116
|
+
<Card.Title onClick={handleNavigate}>{toLocalizedString(state.popoverTitle, t)}</Card.Title>
|
|
117
|
+
) : (
|
|
118
|
+
<span />
|
|
119
|
+
)}
|
|
120
|
+
<Card.CloseIconButton onClick={handleClose} />
|
|
111
121
|
</Card.Toolbar>
|
|
112
122
|
<Surface.Surface role='card--content' data={state.popoverContent} limit={1} />
|
|
113
123
|
</Card.Root>
|
|
@@ -35,7 +35,7 @@ const buildDefaultActions = (): ActionGraphProps => {
|
|
|
35
35
|
}),
|
|
36
36
|
];
|
|
37
37
|
result.nodes.push(...actions);
|
|
38
|
-
result.edges.push(...actions.map((a) => ({ source: 'root', target: a.id })));
|
|
38
|
+
result.edges.push(...actions.map((a) => ({ source: 'root', target: a.id, relation: 'child' })));
|
|
39
39
|
return result;
|
|
40
40
|
};
|
|
41
41
|
|
|
@@ -53,7 +53,7 @@ const DefaultStory = ({ actions: actionsProp, ...props }: StoryProps) => {
|
|
|
53
53
|
};
|
|
54
54
|
|
|
55
55
|
const meta = {
|
|
56
|
-
title: 'plugins/plugin-simple-layout/AppBar',
|
|
56
|
+
title: 'plugins/plugin-simple-layout/components/AppBar',
|
|
57
57
|
render: DefaultStory,
|
|
58
58
|
decorators: [
|
|
59
59
|
withTheme(),
|
|
@@ -6,13 +6,7 @@ import { type Atom, useAtomValue } from '@effect-atom/atom-react';
|
|
|
6
6
|
import React, { Fragment } from 'react';
|
|
7
7
|
|
|
8
8
|
import { IconButton, Popover, type ThemedClassName, Toolbar, useTranslation } from '@dxos/react-ui';
|
|
9
|
-
import {
|
|
10
|
-
type ActionExecutor,
|
|
11
|
-
type ActionGraphProps,
|
|
12
|
-
DropdownMenu,
|
|
13
|
-
MenuProvider,
|
|
14
|
-
useMenuActions,
|
|
15
|
-
} from '@dxos/react-ui-menu';
|
|
9
|
+
import { type ActionExecutor, type ActionGraphProps, Menu, useMenuActions } from '@dxos/react-ui-menu';
|
|
16
10
|
import { mx, osTranslations } from '@dxos/ui-theme';
|
|
17
11
|
|
|
18
12
|
import { meta } from '../../meta';
|
|
@@ -62,7 +56,11 @@ export const AppBar = ({
|
|
|
62
56
|
return (
|
|
63
57
|
<Toolbar.Root
|
|
64
58
|
role='banner'
|
|
65
|
-
classNames={mx(
|
|
59
|
+
classNames={mx(
|
|
60
|
+
'grid grid-cols-[var(--dx-rail-size)_1fr_var(--dx-rail-size)] items-center',
|
|
61
|
+
'dx-density-fine',
|
|
62
|
+
classNames,
|
|
63
|
+
)}
|
|
66
64
|
>
|
|
67
65
|
{keyboardOpen ? (
|
|
68
66
|
<IconButton variant='ghost' icon='ph--x--regular' iconOnly label={t('done label')} />
|
|
@@ -74,18 +72,17 @@ export const AppBar = ({
|
|
|
74
72
|
<h1 className='text-center truncate font-thin uppercase'>{displayTitle}</h1>
|
|
75
73
|
{hasActions ? (
|
|
76
74
|
<AnchorRoot>
|
|
77
|
-
<
|
|
78
|
-
<
|
|
79
|
-
<
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
</MenuProvider>
|
|
75
|
+
<Menu.Root {...menu} caller={meta.id} onAction={onAction}>
|
|
76
|
+
<Menu.Trigger asChild>
|
|
77
|
+
<IconButton
|
|
78
|
+
variant='ghost'
|
|
79
|
+
icon='ph--dots-three-vertical--regular'
|
|
80
|
+
iconOnly
|
|
81
|
+
label={t('actions menu label')}
|
|
82
|
+
/>
|
|
83
|
+
</Menu.Trigger>
|
|
84
|
+
<Menu.Content />
|
|
85
|
+
</Menu.Root>
|
|
89
86
|
</AnchorRoot>
|
|
90
87
|
) : (
|
|
91
88
|
<span />
|
|
@@ -7,12 +7,11 @@ import React, { useMemo } from 'react';
|
|
|
7
7
|
import { Surface } from '@dxos/app-framework/ui';
|
|
8
8
|
import { useAppGraph } from '@dxos/app-toolkit/ui';
|
|
9
9
|
import { type Node, useNode } from '@dxos/plugin-graph';
|
|
10
|
-
import {
|
|
10
|
+
import { ErrorFallback, Panel } from '@dxos/react-ui';
|
|
11
11
|
import { ATTENDABLE_PATH_SEPARATOR } from '@dxos/react-ui-attention';
|
|
12
|
-
import {
|
|
12
|
+
import { Menu, useMenuActions } from '@dxos/react-ui-menu';
|
|
13
13
|
|
|
14
14
|
import { useCompanions, useDrawerActions, useSimpleLayoutState } from '../../hooks';
|
|
15
|
-
import { ContentError } from '../ContentError';
|
|
16
15
|
import { ContentLoading } from '../ContentLoading';
|
|
17
16
|
|
|
18
17
|
const DRAWER_NAME = 'SimpleLayout.Drawer';
|
|
@@ -53,12 +52,16 @@ export const Drawer = () => {
|
|
|
53
52
|
const menu = useMenuActions(actions);
|
|
54
53
|
|
|
55
54
|
return (
|
|
56
|
-
<
|
|
57
|
-
<
|
|
58
|
-
<
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
55
|
+
<Panel.Root>
|
|
56
|
+
<Panel.Toolbar>
|
|
57
|
+
<Menu.Root {...menu} alwaysActive onAction={onAction}>
|
|
58
|
+
<Menu.Toolbar density='coarse' />
|
|
59
|
+
</Menu.Root>
|
|
60
|
+
</Panel.Toolbar>
|
|
61
|
+
<Panel.Content asChild>
|
|
62
|
+
<Surface.Surface role='article' data={data} limit={1} fallback={ErrorFallback} placeholder={placeholder} />
|
|
63
|
+
</Panel.Content>
|
|
64
|
+
</Panel.Root>
|
|
62
65
|
);
|
|
63
66
|
};
|
|
64
67
|
|
|
@@ -7,11 +7,11 @@ import React, { useMemo } from 'react';
|
|
|
7
7
|
import { Surface } from '@dxos/app-framework/ui';
|
|
8
8
|
import { useAppGraph } from '@dxos/app-toolkit/ui';
|
|
9
9
|
import { useNode } from '@dxos/plugin-graph';
|
|
10
|
+
import { ErrorFallback } from '@dxos/react-ui';
|
|
10
11
|
import { useAttentionAttributes } from '@dxos/react-ui-attention';
|
|
11
12
|
import { mx } from '@dxos/ui-theme';
|
|
12
13
|
|
|
13
14
|
import { useAppBarProps, useNavbarActions, useSimpleLayoutState } from '../../hooks';
|
|
14
|
-
import { ContentError } from '../ContentError';
|
|
15
15
|
import { ContentLoading } from '../ContentLoading';
|
|
16
16
|
import { useLoadDescendents } from '../hooks';
|
|
17
17
|
import { useMobileLayout } from '../MobileLayout/MobileLayout';
|
|
@@ -57,23 +57,25 @@ export const Main = () => {
|
|
|
57
57
|
<div
|
|
58
58
|
role='none'
|
|
59
59
|
className={mx(
|
|
60
|
-
'
|
|
61
|
-
showNavBar
|
|
60
|
+
'h-full grid overflow-hidden bg-toolbar-surface',
|
|
61
|
+
showNavBar
|
|
62
|
+
? 'grid-rows-[var(--dx-rail-action)_1fr_var(--dx-toolbar-size)]'
|
|
63
|
+
: 'grid-rows-[var(--dx-rail-action)_1fr]',
|
|
62
64
|
)}
|
|
63
65
|
{...attentionAttrs}
|
|
64
66
|
>
|
|
65
67
|
<AppBar {...appBarProps} />
|
|
66
|
-
<article className='
|
|
68
|
+
<article className='h-full overflow-hidden bg-base-surface'>
|
|
67
69
|
<Surface.Surface
|
|
68
70
|
key={id}
|
|
69
71
|
role='article'
|
|
70
72
|
data={data}
|
|
71
73
|
limit={1}
|
|
72
|
-
fallback={
|
|
74
|
+
fallback={ErrorFallback}
|
|
73
75
|
placeholder={placeholder}
|
|
74
76
|
/>
|
|
75
77
|
</article>
|
|
76
|
-
{showNavBar && <NavBar classNames='border-
|
|
78
|
+
{showNavBar && <NavBar classNames='border-y border-subdued-separator' actions={actions} onAction={onAction} />}
|
|
77
79
|
</div>
|
|
78
80
|
);
|
|
79
81
|
};
|
|
@@ -7,7 +7,7 @@ import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
|
7
7
|
import React, { useMemo } from 'react';
|
|
8
8
|
import { type Mock, expect, fn, screen, userEvent, within } from 'storybook/test';
|
|
9
9
|
|
|
10
|
-
import { withTheme } from '@dxos/react-ui/testing';
|
|
10
|
+
import { withLayout, withTheme } from '@dxos/react-ui/testing';
|
|
11
11
|
import { type ActionGraphProps, createGapSeparator, createMenuAction, createMenuItemGroup } from '@dxos/react-ui-menu';
|
|
12
12
|
import { withRegistry } from '@dxos/storybook-utils';
|
|
13
13
|
|
|
@@ -39,7 +39,7 @@ const buildCompanionOnlyActions = (): ActionGraphProps => {
|
|
|
39
39
|
}),
|
|
40
40
|
];
|
|
41
41
|
result.nodes.push(...companions);
|
|
42
|
-
result.edges.push(...companions.map((c) => ({ source: 'root', target: c.id })));
|
|
42
|
+
result.edges.push(...companions.map((c) => ({ source: 'root', target: c.id, relation: 'child' })));
|
|
43
43
|
return result;
|
|
44
44
|
};
|
|
45
45
|
|
|
@@ -81,18 +81,18 @@ const buildDefaultActions = (): ActionGraphProps => {
|
|
|
81
81
|
];
|
|
82
82
|
result.nodes.push(...companions, ...gapSeparator.nodes, mainMenuGroup, ...menuActions);
|
|
83
83
|
result.edges.push(
|
|
84
|
-
...companions.map((c) => ({ source: 'root', target: c.id })),
|
|
84
|
+
...companions.map((c) => ({ source: 'root', target: c.id, relation: 'child' })),
|
|
85
85
|
...gapSeparator.edges,
|
|
86
|
-
{ source: 'root', target: mainMenuGroup.id },
|
|
87
|
-
...menuActions.map((action) => ({ source: MAIN_MENU_GROUP_ID, target: action.id })),
|
|
86
|
+
{ source: 'root', target: mainMenuGroup.id, relation: 'child' },
|
|
87
|
+
...menuActions.map((action) => ({ source: MAIN_MENU_GROUP_ID, target: action.id, relation: 'child' })),
|
|
88
88
|
);
|
|
89
89
|
return result;
|
|
90
90
|
};
|
|
91
91
|
|
|
92
92
|
const meta = {
|
|
93
|
-
title: 'plugins/plugin-simple-layout/NavBar',
|
|
93
|
+
title: 'plugins/plugin-simple-layout/components/NavBar',
|
|
94
94
|
component: NavBar,
|
|
95
|
-
decorators: [withTheme(), withRegistry],
|
|
95
|
+
decorators: [withTheme(), withLayout({ layout: 'fullscreen' }), withRegistry],
|
|
96
96
|
parameters: {
|
|
97
97
|
layout: 'fullscreen',
|
|
98
98
|
translations,
|
|
@@ -106,7 +106,7 @@ type Story = StoryObj<typeof meta>;
|
|
|
106
106
|
const DefaultStory = ({ onAction }: { onAction: (action: { id: string }) => void }) => {
|
|
107
107
|
const actions = useMemo(() => Atom.make(buildDefaultActions()).pipe(Atom.keepAlive), []);
|
|
108
108
|
|
|
109
|
-
return <NavBar classNames='border-
|
|
109
|
+
return <NavBar classNames='border-y border-separator' actions={actions} onAction={onAction} />;
|
|
110
110
|
};
|
|
111
111
|
|
|
112
112
|
export const Default: Story = {
|
|
@@ -6,13 +6,7 @@ import { type Atom } from '@effect-atom/atom-react';
|
|
|
6
6
|
import React from 'react';
|
|
7
7
|
|
|
8
8
|
import { type ThemedClassName } from '@dxos/react-ui';
|
|
9
|
-
import {
|
|
10
|
-
type ActionExecutor,
|
|
11
|
-
type ActionGraphProps,
|
|
12
|
-
MenuProvider,
|
|
13
|
-
ToolbarMenu,
|
|
14
|
-
useMenuActions,
|
|
15
|
-
} from '@dxos/react-ui-menu';
|
|
9
|
+
import { type ActionExecutor, type ActionGraphProps, Menu, useMenuActions } from '@dxos/react-ui-menu';
|
|
16
10
|
import { mx } from '@dxos/ui-theme';
|
|
17
11
|
|
|
18
12
|
const NAVBAR_NAME = 'SimpleLayout.NavBar';
|
|
@@ -31,9 +25,9 @@ export const NavBar = ({ classNames, actions, onAction }: NavBarProps) => {
|
|
|
31
25
|
const menu = useMenuActions(actions);
|
|
32
26
|
|
|
33
27
|
return (
|
|
34
|
-
<
|
|
35
|
-
<
|
|
36
|
-
</
|
|
28
|
+
<Menu.Root {...menu} alwaysActive onAction={onAction}>
|
|
29
|
+
<Menu.Toolbar density='coarse' classNames={mx(classNames)} />
|
|
30
|
+
</Menu.Root>
|
|
37
31
|
);
|
|
38
32
|
};
|
|
39
33
|
|