@dxos/plugin-testing 0.12.0-next-73daef452f1464b62efdbca75fb0067c1066f264 → 0.13.0
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/StorybookCapabilities.mjs.map +1 -1
- package/dist/lib/capabilities.browser.mjs +16 -0
- package/dist/lib/capabilities.browser.mjs.map +1 -0
- package/dist/lib/capabilities.mjs.map +1 -1
- package/dist/lib/capabilities.node.mjs.map +1 -1
- package/dist/lib/capabilities.tauri.mjs +16 -0
- package/dist/lib/capabilities.tauri.mjs.map +1 -0
- package/dist/lib/capabilities.workerd.mjs.map +1 -1
- package/dist/lib/chunk-add-toast.mjs.map +1 -1
- package/dist/lib/chunk-state.mjs +1 -1
- package/dist/lib/chunk-state.mjs.map +1 -1
- package/dist/lib/chunk-switch-workspace.mjs.map +1 -1
- package/dist/lib/chunk-update-complementary.mjs.map +1 -1
- package/dist/lib/chunk-update-dialog.mjs.map +1 -1
- package/dist/lib/chunk-update-popover.mjs.map +1 -1
- package/dist/lib/chunk-update-sidebar.mjs.map +1 -1
- package/dist/lib/components.mjs +62 -55
- package/dist/lib/components.mjs.map +1 -1
- package/dist/lib/core.mjs +4 -4
- package/dist/lib/core.mjs.map +1 -1
- package/dist/lib/harness.mjs +7 -5
- package/dist/lib/harness.mjs.map +1 -1
- package/dist/lib/index.mjs +4 -214
- package/dist/lib/meta.mjs.map +1 -1
- package/dist/lib/ns/CorePlugins.mjs +8 -0
- package/dist/lib/ns/CorePlugins.mjs.map +1 -0
- package/dist/lib/ns/Corpus.mjs +216 -0
- package/dist/lib/ns/Corpus.mjs.map +1 -0
- package/dist/lib/operations.mjs.map +1 -1
- package/dist/types/src/CorePlugins.d.ts +2 -0
- package/dist/types/src/CorePlugins.d.ts.map +1 -0
- package/dist/types/src/Corpus.d.ts +2 -0
- package/dist/types/src/Corpus.d.ts.map +1 -0
- package/dist/types/src/{harness.d.ts → Harness.d.ts} +1 -1
- package/dist/types/src/{harness.d.ts.map → Harness.d.ts.map} +1 -1
- package/dist/types/src/capabilities/gen/browser.d.ts +8 -0
- package/dist/types/src/capabilities/gen/browser.d.ts.map +1 -0
- package/dist/types/src/capabilities/gen/node.d.ts.map +1 -1
- package/dist/types/src/capabilities/gen/tauri.d.ts +8 -0
- package/dist/types/src/capabilities/gen/tauri.d.ts.map +1 -0
- package/dist/types/src/capabilities/gen/workerd.d.ts.map +1 -1
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/components/Layout/Layout.d.ts.map +1 -1
- package/dist/types/src/components/Layout/index.d.ts +1 -1
- package/dist/types/src/components/Layout/index.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +1 -1
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/core.d.ts.map +1 -1
- package/dist/types/src/corpus/index.d.ts +1 -1
- package/dist/types/src/corpus/index.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +4 -4
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/operations/update-state.d.ts +1 -1
- package/dist/types/src/operations/update-state.d.ts.map +1 -1
- package/dist/types/src/types/StorybookCapabilities.d.ts +3 -3
- package/dist/types/src/types/StorybookCapabilities.d.ts.map +1 -1
- package/dist/types/src/types/index.d.ts +1 -1
- package/dist/types/src/types/index.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +37 -25
- package/src/CorePlugins.ts +7 -0
- package/src/Corpus.ts +7 -0
- package/src/{harness.ts → Harness.ts} +5 -3
- package/src/capabilities/gen/browser.ts +23 -0
- package/src/capabilities/gen/node.ts +2 -2
- package/src/capabilities/gen/tauri.ts +23 -0
- package/src/capabilities/gen/workerd.ts +2 -2
- package/src/capabilities/index.ts +3 -3
- package/src/capabilities/state.tsx +1 -1
- package/src/components/Layout/Layout.tsx +101 -96
- package/src/components/Layout/index.ts +1 -1
- package/src/components/index.ts +1 -1
- package/src/core.ts +4 -4
- package/src/corpus/index.ts +1 -1
- package/src/corpus/sample-messages.test.ts +1 -1
- package/src/index.ts +4 -4
- package/src/meta.ts +1 -1
- package/src/operations/add-toast.ts +1 -1
- package/src/operations/index.ts +9 -9
- package/src/operations/switch-workspace.ts +1 -1
- package/src/operations/update-complementary.ts +1 -1
- package/src/operations/update-dialog.ts +1 -1
- package/src/operations/update-popover.ts +1 -1
- package/src/operations/update-sidebar.ts +1 -1
- package/src/types/StorybookCapabilities.ts +3 -3
- package/src/types/index.ts +1 -1
- package/dist/lib/index.mjs.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/plugin-testing",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "Plugin testing utils",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -10,19 +10,21 @@
|
|
|
10
10
|
},
|
|
11
11
|
"license": "FSL-1.1-Apache-2.0",
|
|
12
12
|
"author": "DXOS.org",
|
|
13
|
-
"sideEffects":
|
|
13
|
+
"sideEffects": false,
|
|
14
14
|
"type": "module",
|
|
15
15
|
"imports": {
|
|
16
16
|
"#capabilities": {
|
|
17
17
|
"source": {
|
|
18
18
|
"workerd": "./src/capabilities/gen/workerd.ts",
|
|
19
19
|
"node": "./src/capabilities/gen/node.ts",
|
|
20
|
-
"
|
|
20
|
+
"tauri": "./src/capabilities/gen/tauri.ts",
|
|
21
|
+
"browser": "./src/capabilities/gen/browser.ts"
|
|
21
22
|
},
|
|
22
23
|
"types": "./dist/types/src/capabilities/index.d.ts",
|
|
23
24
|
"workerd": "./dist/lib/capabilities.workerd.mjs",
|
|
24
25
|
"node": "./dist/lib/capabilities.node.mjs",
|
|
25
|
-
"
|
|
26
|
+
"tauri": "./dist/lib/capabilities.tauri.mjs",
|
|
27
|
+
"browser": "./dist/lib/capabilities.browser.mjs"
|
|
26
28
|
},
|
|
27
29
|
"#components": {
|
|
28
30
|
"source": "./src/components/index.ts",
|
|
@@ -56,9 +58,19 @@
|
|
|
56
58
|
"types": "./dist/types/src/index.d.ts",
|
|
57
59
|
"import": "./dist/lib/index.mjs"
|
|
58
60
|
},
|
|
59
|
-
"./
|
|
60
|
-
"source": "./src/
|
|
61
|
-
"types": "./dist/types/src/
|
|
61
|
+
"./CorePlugins": {
|
|
62
|
+
"source": "./src/CorePlugins.ts",
|
|
63
|
+
"types": "./dist/types/src/CorePlugins.d.ts",
|
|
64
|
+
"import": "./dist/lib/ns/CorePlugins.mjs"
|
|
65
|
+
},
|
|
66
|
+
"./Corpus": {
|
|
67
|
+
"source": "./src/Corpus.ts",
|
|
68
|
+
"types": "./dist/types/src/Corpus.d.ts",
|
|
69
|
+
"import": "./dist/lib/ns/Corpus.mjs"
|
|
70
|
+
},
|
|
71
|
+
"./Harness": {
|
|
72
|
+
"source": "./src/Harness.ts",
|
|
73
|
+
"types": "./dist/types/src/Harness.d.ts",
|
|
62
74
|
"import": "./dist/lib/harness.mjs"
|
|
63
75
|
},
|
|
64
76
|
"./package.json": "./package.json",
|
|
@@ -87,34 +99,34 @@
|
|
|
87
99
|
"src"
|
|
88
100
|
],
|
|
89
101
|
"dependencies": {
|
|
90
|
-
"@effect/atom-react": "4.0.0
|
|
91
|
-
"@dxos/app-framework": "0.
|
|
92
|
-
"@dxos/app-toolkit": "0.
|
|
93
|
-
"@dxos/
|
|
94
|
-
"@dxos/
|
|
95
|
-
"@dxos/plugin-
|
|
96
|
-
"@dxos/plugin-
|
|
97
|
-
"@dxos/plugin-settings": "0.
|
|
98
|
-
"@dxos/plugin-theme": "0.
|
|
99
|
-
"@dxos/react-ui-dnd": "0.
|
|
100
|
-
"@dxos/util": "0.
|
|
102
|
+
"@effect/atom-react": "4.0.0",
|
|
103
|
+
"@dxos/app-framework": "0.13.0",
|
|
104
|
+
"@dxos/app-toolkit": "0.13.0",
|
|
105
|
+
"@dxos/compute": "0.13.0",
|
|
106
|
+
"@dxos/log": "0.13.0",
|
|
107
|
+
"@dxos/plugin-graph": "0.13.0",
|
|
108
|
+
"@dxos/plugin-attention": "0.13.0",
|
|
109
|
+
"@dxos/plugin-settings": "0.13.0",
|
|
110
|
+
"@dxos/plugin-theme": "0.13.0",
|
|
111
|
+
"@dxos/react-ui-dnd": "0.13.0",
|
|
112
|
+
"@dxos/util": "0.13.0"
|
|
101
113
|
},
|
|
102
114
|
"devDependencies": {
|
|
103
115
|
"@types/react": "~19.2.17",
|
|
104
116
|
"@types/react-dom": "~19.2.3",
|
|
105
|
-
"effect": "4.0.0
|
|
117
|
+
"effect": "4.0.0",
|
|
106
118
|
"react": "~19.2.7",
|
|
107
119
|
"react-dom": "~19.2.7",
|
|
108
|
-
"vite": "^8.2.
|
|
109
|
-
"@dxos/react-ui": "0.
|
|
110
|
-
"@dxos/ui-theme": "0.
|
|
120
|
+
"vite": "^8.2.2",
|
|
121
|
+
"@dxos/react-ui": "0.13.0",
|
|
122
|
+
"@dxos/ui-theme": "0.13.0"
|
|
111
123
|
},
|
|
112
124
|
"peerDependencies": {
|
|
113
|
-
"effect": "4.0.0
|
|
125
|
+
"effect": "4.0.0",
|
|
114
126
|
"react": "~19.2.7",
|
|
115
127
|
"react-dom": "~19.2.7",
|
|
116
|
-
"@dxos/react-ui": "^0.
|
|
117
|
-
"@dxos/ui-theme": "^0.
|
|
128
|
+
"@dxos/react-ui": "^0.13.0",
|
|
129
|
+
"@dxos/ui-theme": "^0.13.0"
|
|
118
130
|
},
|
|
119
131
|
"publishConfig": {
|
|
120
132
|
"access": "public"
|
package/src/Corpus.ts
ADDED
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
// Copyright 2026 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
// @import-as-namespace
|
|
6
|
+
|
|
6
7
|
import type * as Plugin from '@dxos/app-framework/Plugin';
|
|
8
|
+
import * as ProcessManagerPlugin from '@dxos/app-framework/ProcessManagerPlugin';
|
|
7
9
|
import { type TestAppOptions, type TestHarness, createTestApp } from '@dxos/app-framework/testing';
|
|
8
10
|
import { AttentionPlugin } from '@dxos/plugin-attention/testing';
|
|
9
11
|
import { GraphPlugin } from '@dxos/plugin-graph/testing';
|
|
@@ -27,7 +29,7 @@ export type ComposerTestAppOptions = Omit<TestAppOptions, 'plugins'> & {
|
|
|
27
29
|
const headlessCorePlugins = (): Plugin.Plugin[] => [
|
|
28
30
|
AttentionPlugin.make(),
|
|
29
31
|
GraphPlugin.make(),
|
|
30
|
-
ProcessManagerPlugin(),
|
|
32
|
+
ProcessManagerPlugin.make(),
|
|
31
33
|
SettingsPlugin.make(),
|
|
32
34
|
];
|
|
33
35
|
|
|
@@ -48,7 +50,7 @@ export const createComposerTestApp = async (opts: ComposerTestAppOptions = {}):
|
|
|
48
50
|
const core = headlessCorePlugins();
|
|
49
51
|
if (theme) {
|
|
50
52
|
const { ThemePlugin } = await import('@dxos/plugin-theme/testing');
|
|
51
|
-
const { defaultTx } = await import('@dxos/react-ui');
|
|
53
|
+
const { defaultTx } = await import('@dxos/react-ui/Theme');
|
|
52
54
|
core.push(ThemePlugin.make({ tx: defaultTx }));
|
|
53
55
|
}
|
|
54
56
|
return createTestApp({
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
// GENERATED by dx-plugin — do not edit. Sliced from ../index.ts for the 'browser' condition.
|
|
6
|
+
|
|
7
|
+
import * as ActivationEvents from '@dxos/app-framework/ActivationEvents';
|
|
8
|
+
import * as Capability from '@dxos/app-framework/Capability';
|
|
9
|
+
import * as AppCapabilities from '@dxos/app-toolkit/AppCapabilities';
|
|
10
|
+
import * as AppCapability from '@dxos/app-toolkit/AppCapability';
|
|
11
|
+
|
|
12
|
+
import { StorybookCapabilities } from '#types';
|
|
13
|
+
|
|
14
|
+
export const OperationHandler = AppCapability.operationHandler(() => import('../operation-handler.ts'));
|
|
15
|
+
|
|
16
|
+
export const ReactContext = AppCapability.reactContext(() => import('../react-context.tsx'));
|
|
17
|
+
|
|
18
|
+
export const State = Capability.lazyModule(
|
|
19
|
+
'State',
|
|
20
|
+
// Shell state read by `Layout` on its first render — same class as the deck's `DeckState`.
|
|
21
|
+
{ activatesOn: ActivationEvents.Startup, provides: [StorybookCapabilities.LayoutState, AppCapabilities.Layout] },
|
|
22
|
+
() => import('../state.tsx'),
|
|
23
|
+
);
|
|
@@ -11,13 +11,13 @@ import * as AppCapability from '@dxos/app-toolkit/AppCapability';
|
|
|
11
11
|
|
|
12
12
|
import { StorybookCapabilities } from '#types';
|
|
13
13
|
|
|
14
|
-
export const OperationHandler = AppCapability.operationHandler(() => import('../operation-handler'));
|
|
14
|
+
export const OperationHandler = AppCapability.operationHandler(() => import('../operation-handler.ts'));
|
|
15
15
|
|
|
16
16
|
export const State = Capability.lazyModule(
|
|
17
17
|
'State',
|
|
18
18
|
// Shell state read by `Layout` on its first render — same class as the deck's `DeckState`.
|
|
19
19
|
{ activatesOn: ActivationEvents.Startup, provides: [StorybookCapabilities.LayoutState, AppCapabilities.Layout] },
|
|
20
|
-
() => import('../state'),
|
|
20
|
+
() => import('../state.tsx'),
|
|
21
21
|
);
|
|
22
22
|
|
|
23
23
|
export const ReactContext = undefined;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
// GENERATED by dx-plugin — do not edit. Sliced from ../index.ts for the 'tauri' condition.
|
|
6
|
+
|
|
7
|
+
import * as ActivationEvents from '@dxos/app-framework/ActivationEvents';
|
|
8
|
+
import * as Capability from '@dxos/app-framework/Capability';
|
|
9
|
+
import * as AppCapabilities from '@dxos/app-toolkit/AppCapabilities';
|
|
10
|
+
import * as AppCapability from '@dxos/app-toolkit/AppCapability';
|
|
11
|
+
|
|
12
|
+
import { StorybookCapabilities } from '#types';
|
|
13
|
+
|
|
14
|
+
export const OperationHandler = AppCapability.operationHandler(() => import('../operation-handler.ts'));
|
|
15
|
+
|
|
16
|
+
export const ReactContext = AppCapability.reactContext(() => import('../react-context.tsx'));
|
|
17
|
+
|
|
18
|
+
export const State = Capability.lazyModule(
|
|
19
|
+
'State',
|
|
20
|
+
// Shell state read by `Layout` on its first render — same class as the deck's `DeckState`.
|
|
21
|
+
{ activatesOn: ActivationEvents.Startup, provides: [StorybookCapabilities.LayoutState, AppCapabilities.Layout] },
|
|
22
|
+
() => import('../state.tsx'),
|
|
23
|
+
);
|
|
@@ -11,13 +11,13 @@ import * as AppCapability from '@dxos/app-toolkit/AppCapability';
|
|
|
11
11
|
|
|
12
12
|
import { StorybookCapabilities } from '#types';
|
|
13
13
|
|
|
14
|
-
export const OperationHandler = AppCapability.operationHandler(() => import('../operation-handler'));
|
|
14
|
+
export const OperationHandler = AppCapability.operationHandler(() => import('../operation-handler.ts'));
|
|
15
15
|
|
|
16
16
|
export const State = Capability.lazyModule(
|
|
17
17
|
'State',
|
|
18
18
|
// Shell state read by `Layout` on its first render — same class as the deck's `DeckState`.
|
|
19
19
|
{ activatesOn: ActivationEvents.Startup, provides: [StorybookCapabilities.LayoutState, AppCapabilities.Layout] },
|
|
20
|
-
() => import('../state'),
|
|
20
|
+
() => import('../state.tsx'),
|
|
21
21
|
);
|
|
22
22
|
|
|
23
23
|
export const ReactContext = undefined;
|
|
@@ -9,11 +9,11 @@ import * as AppCapability from '@dxos/app-toolkit/AppCapability';
|
|
|
9
9
|
|
|
10
10
|
import { StorybookCapabilities } from '#types';
|
|
11
11
|
|
|
12
|
-
export const OperationHandler = AppCapability.operationHandler(() => import('./operation-handler'));
|
|
13
|
-
export const ReactContext = AppCapability.reactContext(() => import('./react-context'));
|
|
12
|
+
export const OperationHandler = AppCapability.operationHandler(() => import('./operation-handler.ts'));
|
|
13
|
+
export const ReactContext = AppCapability.reactContext(() => import('./react-context.tsx'));
|
|
14
14
|
export const State = Capability.lazyModule(
|
|
15
15
|
'State',
|
|
16
16
|
// Shell state read by `Layout` on its first render — same class as the deck's `DeckState`.
|
|
17
17
|
{ activatesOn: ActivationEvents.Startup, provides: [StorybookCapabilities.LayoutState, AppCapabilities.Layout] },
|
|
18
|
-
() => import('./state'),
|
|
18
|
+
() => import('./state.tsx'),
|
|
19
19
|
);
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import * as Effect from 'effect/Effect';
|
|
6
|
-
import * as Atom from 'effect/
|
|
6
|
+
import * as Atom from 'effect/reactivity/Atom';
|
|
7
7
|
|
|
8
8
|
import * as Capability from '@dxos/app-framework/Capability';
|
|
9
9
|
import * as AppCapabilities from '@dxos/app-toolkit/AppCapabilities';
|
|
@@ -4,24 +4,31 @@
|
|
|
4
4
|
|
|
5
5
|
import { useAtomValue } from '@effect/atom-react/Hooks';
|
|
6
6
|
import { RegistryContext } from '@effect/atom-react/RegistryContext';
|
|
7
|
-
import React, {
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
import React, {
|
|
8
|
+
type ComponentProps,
|
|
9
|
+
type PropsWithChildren,
|
|
10
|
+
useCallback,
|
|
11
|
+
useContext,
|
|
12
|
+
useEffect,
|
|
13
|
+
useRef,
|
|
14
|
+
useState,
|
|
15
|
+
} from 'react';
|
|
16
|
+
|
|
17
|
+
import * as Hooks from '@dxos/app-framework/Hooks';
|
|
18
|
+
import * as Surface from '@dxos/app-framework/Surface';
|
|
19
|
+
import * as AppSurface from '@dxos/app-toolkit/AppSurface';
|
|
10
20
|
import type * as LayoutOperation from '@dxos/app-toolkit/LayoutOperation';
|
|
11
|
-
import { AppSurface } from '@dxos/app-toolkit/ui';
|
|
12
|
-
import {
|
|
13
|
-
AlertDialog,
|
|
14
|
-
Button,
|
|
15
|
-
Dialog,
|
|
16
|
-
Main,
|
|
17
|
-
Popover,
|
|
18
|
-
type PopoverContentInteractOutsideEvent,
|
|
19
|
-
Toast,
|
|
20
|
-
toLocalizedString,
|
|
21
|
-
useTranslation,
|
|
22
|
-
} from '@dxos/react-ui';
|
|
23
|
-
import { Card } from '@dxos/react-ui';
|
|
24
21
|
import { Dnd } from '@dxos/react-ui-dnd';
|
|
22
|
+
import * as AlertDialog from '@dxos/react-ui/AlertDialog';
|
|
23
|
+
import * as Card from '@dxos/react-ui/Card';
|
|
24
|
+
import * as Dialog from '@dxos/react-ui/Dialog';
|
|
25
|
+
import * as DragHandle from '@dxos/react-ui/DragHandle';
|
|
26
|
+
import * as UiHooks from '@dxos/react-ui/Hooks';
|
|
27
|
+
import * as Main from '@dxos/react-ui/Main';
|
|
28
|
+
import * as Popover from '@dxos/react-ui/Popover';
|
|
29
|
+
import * as Theme from '@dxos/react-ui/Theme';
|
|
30
|
+
import * as Toast from '@dxos/react-ui/Toast';
|
|
31
|
+
import * as VirtualAnchor from '@dxos/react-ui/VirtualAnchor';
|
|
25
32
|
import { descriptionMessage, mx } from '@dxos/ui-theme';
|
|
26
33
|
|
|
27
34
|
import { meta } from '#meta';
|
|
@@ -29,8 +36,10 @@ import { StorybookCapabilities } from '#types';
|
|
|
29
36
|
|
|
30
37
|
const debounce_delay = 100;
|
|
31
38
|
|
|
39
|
+
type FocusOutsideEvent = Parameters<NonNullable<ComponentProps<typeof Popover.Root>['onFocusOutside']>>[0];
|
|
40
|
+
|
|
32
41
|
const StoryToast = ({ toast, onDismiss }: { toast: LayoutOperation.Toast; onDismiss: (id: string) => void }) => {
|
|
33
|
-
const { t } = useTranslation(meta.profile.key);
|
|
42
|
+
const { t } = UiHooks.useTranslation(meta.profile.key);
|
|
34
43
|
return (
|
|
35
44
|
<Toast.Root
|
|
36
45
|
data-testid={toast.id}
|
|
@@ -42,28 +51,26 @@ const StoryToast = ({ toast, onDismiss }: { toast: LayoutOperation.Toast; onDism
|
|
|
42
51
|
}
|
|
43
52
|
}}
|
|
44
53
|
>
|
|
45
|
-
<Toast.
|
|
46
|
-
{toast.title &&
|
|
47
|
-
</Toast.
|
|
48
|
-
{toast.description && <Toast.Description>{toLocalizedString(toast.description, t)}</Toast.Description>}
|
|
54
|
+
<Toast.Header icon={toast.icon} closable={!!toast.closeLabel}>
|
|
55
|
+
{toast.title && Theme.toLocalizedString(toast.title, t)}
|
|
56
|
+
</Toast.Header>
|
|
57
|
+
{toast.description && <Toast.Description>{Theme.toLocalizedString(toast.description, t)}</Toast.Description>}
|
|
49
58
|
{toast.onAction && toast.actionAlt && toast.actionLabel && (
|
|
50
|
-
<Toast.
|
|
51
|
-
<Toast.
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
</Toast.Action>
|
|
56
|
-
</Toast.Actions>
|
|
59
|
+
<Toast.Footer>
|
|
60
|
+
<Toast.ActionTrigger variant='primary' onClick={() => toast.onAction?.()}>
|
|
61
|
+
{Theme.toLocalizedString(toast.actionLabel, t)}
|
|
62
|
+
</Toast.ActionTrigger>
|
|
63
|
+
</Toast.Footer>
|
|
57
64
|
)}
|
|
58
65
|
</Toast.Root>
|
|
59
66
|
);
|
|
60
67
|
};
|
|
61
68
|
|
|
62
69
|
export const Layout = ({ children }: PropsWithChildren<{}>) => {
|
|
63
|
-
const { t } = useTranslation(meta.profile.key);
|
|
70
|
+
const { t } = UiHooks.useTranslation(meta.profile.key);
|
|
64
71
|
const trigger = useRef<HTMLButtonElement | null>(null);
|
|
65
72
|
const registry = useContext(RegistryContext);
|
|
66
|
-
const stateAtom = useCapability(StorybookCapabilities.LayoutState);
|
|
73
|
+
const stateAtom = Hooks.useCapability(StorybookCapabilities.LayoutState);
|
|
67
74
|
const layout = useAtomValue(stateAtom);
|
|
68
75
|
const [iter, setIter] = useState(0);
|
|
69
76
|
const [open, setOpen] = useState(false);
|
|
@@ -100,13 +107,11 @@ export const Layout = ({ children }: PropsWithChildren<{}>) => {
|
|
|
100
107
|
});
|
|
101
108
|
}, [updateState]);
|
|
102
109
|
|
|
103
|
-
const
|
|
104
|
-
(event:
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
(event.currentTarget as HTMLElement | undefined)?.classList.contains('cm-content')
|
|
109
|
-
) {
|
|
110
|
+
const handleFocusOutside = useCallback(
|
|
111
|
+
(event: FocusOutsideEvent) => {
|
|
112
|
+
// TODO(thure): CodeMirror should not focus itself when it updates.
|
|
113
|
+
const target = event.detail.originalEvent.target;
|
|
114
|
+
if (target instanceof HTMLElement && target.classList.contains('cm-content')) {
|
|
110
115
|
event.preventDefault();
|
|
111
116
|
} else {
|
|
112
117
|
handleClose();
|
|
@@ -123,13 +128,27 @@ export const Layout = ({ children }: PropsWithChildren<{}>) => {
|
|
|
123
128
|
);
|
|
124
129
|
|
|
125
130
|
const DialogRoot = layout.dialogType === 'alert' ? AlertDialog.Root : Dialog.Root;
|
|
126
|
-
const DialogOverlay = layout.dialogType === 'alert' ? AlertDialog.Overlay : Dialog.Overlay;
|
|
127
131
|
|
|
128
132
|
return (
|
|
129
133
|
<Toast.Provider>
|
|
134
|
+
{/* The plugin `ReactContext` capabilities — the theme plugin's `Tooltip.Provider` among them —
|
|
135
|
+
wrap `children` only, so the dialog and popover portals rendered as its siblings below sit
|
|
136
|
+
outside them. Any `IconButton` there renders a `Tooltip.Trigger`, which throws rather than
|
|
137
|
+
degrades when it finds no provider, taking the whole surface down with it. */}
|
|
130
138
|
<div className='fixed inset-0 flex overflow-hidden'>
|
|
131
139
|
<Dnd.Root>
|
|
132
|
-
<Popover.Root
|
|
140
|
+
<Popover.Root
|
|
141
|
+
open={open}
|
|
142
|
+
positioning={{
|
|
143
|
+
...VirtualAnchor.virtualAnchor(trigger),
|
|
144
|
+
placement: layout.popoverSide,
|
|
145
|
+
hideWhenDetached: true,
|
|
146
|
+
}}
|
|
147
|
+
autoFocus={false}
|
|
148
|
+
onFocusOutside={handleFocusOutside}
|
|
149
|
+
onPointerDownOutside={handleClose}
|
|
150
|
+
onEscapeKeyDown={handleClose}
|
|
151
|
+
>
|
|
133
152
|
<Main.Root
|
|
134
153
|
navigationSidebarState={layout.sidebarState}
|
|
135
154
|
complementarySidebarState={layout.complementarySidebarState}
|
|
@@ -142,78 +161,64 @@ export const Layout = ({ children }: PropsWithChildren<{}>) => {
|
|
|
142
161
|
<DialogRoot
|
|
143
162
|
modal={layout.dialogBlockAlign !== 'end'}
|
|
144
163
|
open={layout.dialogOpen}
|
|
145
|
-
onOpenChange={(nextOpen) => updateState({ dialogOpen: nextOpen })}
|
|
164
|
+
onOpenChange={({ open: nextOpen }) => updateState({ dialogOpen: nextOpen })}
|
|
146
165
|
>
|
|
147
|
-
{
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
) : (
|
|
156
|
-
<DialogOverlay
|
|
157
|
-
blockAlign={layout.dialogBlockAlign}
|
|
158
|
-
classNames={layout.dialogOverlayClasses}
|
|
159
|
-
style={layout.dialogOverlayStyle}
|
|
160
|
-
>
|
|
161
|
-
<Surface.Surface
|
|
162
|
-
type={AppSurface.Dialog}
|
|
163
|
-
data={layout.dialogContent}
|
|
164
|
-
limit={1}
|
|
165
|
-
fallback={ErrorFallback}
|
|
166
|
-
/>
|
|
167
|
-
</DialogOverlay>
|
|
168
|
-
)}
|
|
166
|
+
{/* The dialog surface renders its own Content, which carries the placement and scrim. */}
|
|
167
|
+
<Surface.Surface
|
|
168
|
+
type={AppSurface.Dialog}
|
|
169
|
+
data={layout.dialogContent}
|
|
170
|
+
limit={1}
|
|
171
|
+
fallback={ErrorFallback}
|
|
172
|
+
placeholder={<div />}
|
|
173
|
+
/>
|
|
169
174
|
</DialogRoot>
|
|
170
175
|
|
|
171
|
-
<Popover.
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
<Card.Title>{toLocalizedString(layout.popoverTitle, t)}</Card.Title>
|
|
189
|
-
) : (
|
|
190
|
-
<span />
|
|
191
|
-
)}
|
|
192
|
-
<Card.ActionIconButton action='close' onClick={handleClose} />
|
|
193
|
-
</Card.Header>
|
|
176
|
+
<Popover.Content>
|
|
177
|
+
<Popover.Body>
|
|
178
|
+
{/* `border={false}`: the popover content already draws the surface and its border,
|
|
179
|
+
so a bordered card inside it reads as a second frame. Matches the deck's popover. */}
|
|
180
|
+
{layout.popoverKind === 'card' && (
|
|
181
|
+
<Card.Root grid border={false} classNames='dx-card-popover rounded-md'>
|
|
182
|
+
<Card.Header>
|
|
183
|
+
{/* Disabled drag handle keeps the toolbar slot layout consistent with regular cards. */}
|
|
184
|
+
<DragHandle.DragHandle />
|
|
185
|
+
{layout.popoverTitle ? (
|
|
186
|
+
<Card.Title>{Theme.toLocalizedString(layout.popoverTitle, t)}</Card.Title>
|
|
187
|
+
) : (
|
|
188
|
+
<span />
|
|
189
|
+
)}
|
|
190
|
+
<Card.Action system='close' onClick={handleClose} />
|
|
191
|
+
</Card.Header>
|
|
192
|
+
{layout.popoverContent ? (
|
|
194
193
|
<Surface.Surface type={AppSurface.CardContent} data={layout.popoverContent} limit={1} />
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
194
|
+
) : (
|
|
195
|
+
// Matches the deck's popover, which opens a card with no subject for a link that did not resolve.
|
|
196
|
+
<Card.Body classNames='min-h-8'>
|
|
197
|
+
<Card.Row>
|
|
198
|
+
<Card.Text variant='muted'>No preview available.</Card.Text>
|
|
199
|
+
</Card.Row>
|
|
200
|
+
</Card.Body>
|
|
201
|
+
)}
|
|
202
|
+
</Card.Root>
|
|
203
|
+
)}
|
|
204
|
+
{(layout.popoverKind === 'base' || layout.popoverKind === 'rename') && (
|
|
205
|
+
<Surface.Surface type={AppSurface.Popover} data={layout.popoverContent} limit={1} />
|
|
206
|
+
)}
|
|
207
|
+
</Popover.Body>
|
|
208
|
+
</Popover.Content>
|
|
204
209
|
</Popover.Root>
|
|
205
210
|
</Dnd.Root>
|
|
206
211
|
{layout.toasts.map((toast) => (
|
|
207
212
|
<StoryToast key={toast.id} toast={toast} onDismiss={handleDismissToast} />
|
|
208
213
|
))}
|
|
209
|
-
<Toast.
|
|
214
|
+
<Toast.Toaster />
|
|
210
215
|
</div>
|
|
211
216
|
</Toast.Provider>
|
|
212
217
|
);
|
|
213
218
|
};
|
|
214
219
|
|
|
215
220
|
export const ErrorFallback = ({ error }: { error?: Error }) => {
|
|
216
|
-
const { t } = useTranslation(meta.profile.key);
|
|
221
|
+
const { t } = UiHooks.useTranslation(meta.profile.key);
|
|
217
222
|
const errorString = error?.toString() ?? '';
|
|
218
223
|
return (
|
|
219
224
|
<div
|
package/src/components/index.ts
CHANGED
package/src/core.ts
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { ProcessManagerPlugin } from '@dxos/app-framework';
|
|
6
5
|
import type * as Plugin from '@dxos/app-framework/Plugin';
|
|
6
|
+
import * as ProcessManagerPlugin from '@dxos/app-framework/ProcessManagerPlugin';
|
|
7
7
|
// `/testing` entrypoints re-export the plugin eagerly (without `Plugin.lazy`).
|
|
8
8
|
// The default `.` and `/plugin` exports wrap each plugin in a lazy stub
|
|
9
9
|
// (`() => import('./XPlugin')`), which webkit cannot reliably resolve under
|
|
@@ -21,7 +21,7 @@ import { AttentionPlugin } from '@dxos/plugin-attention/testing';
|
|
|
21
21
|
import { GraphPlugin } from '@dxos/plugin-graph/testing';
|
|
22
22
|
import { SettingsPlugin } from '@dxos/plugin-settings/testing';
|
|
23
23
|
import { ThemePlugin } from '@dxos/plugin-theme/testing';
|
|
24
|
-
import
|
|
24
|
+
import * as Theme from '@dxos/react-ui/Theme';
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
27
|
* Core plugins for testing/storybook environments.
|
|
@@ -31,7 +31,7 @@ import { defaultTx } from '@dxos/react-ui';
|
|
|
31
31
|
export const corePlugins = (): Plugin.Plugin[] => [
|
|
32
32
|
AttentionPlugin.make(),
|
|
33
33
|
GraphPlugin.make(),
|
|
34
|
-
ProcessManagerPlugin(),
|
|
34
|
+
ProcessManagerPlugin.make(),
|
|
35
35
|
SettingsPlugin.make(),
|
|
36
|
-
ThemePlugin.make({ tx: defaultTx }),
|
|
36
|
+
ThemePlugin.make({ tx: Theme.defaultTx }),
|
|
37
37
|
];
|
package/src/corpus/index.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { describe, expect, test } from 'vitest';
|
|
6
6
|
|
|
7
|
-
import { SAMPLE_MESSAGES, type SampleMessage } from './sample-messages';
|
|
7
|
+
import { SAMPLE_MESSAGES, type SampleMessage } from './sample-messages.ts';
|
|
8
8
|
|
|
9
9
|
const TOPICS: SampleMessage['topic'][] = ['project', 'finance', 'scheduling', 'hiring', 'ops'];
|
|
10
10
|
|
package/src/index.ts
CHANGED
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
// Storybook on webkit + vite-dev cannot reliably resolve the lazy form's
|
|
8
8
|
// dynamic `import()` — see `./core.ts` for the underlying chunk-init issue
|
|
9
9
|
// — and there is no production code-splitting benefit to recover here.
|
|
10
|
-
export * as StorybookPlugin from './StorybookPlugin';
|
|
11
|
-
export * from './core';
|
|
12
|
-
export * from './corpus';
|
|
13
|
-
export * from '#meta';
|
|
10
|
+
export * as StorybookPlugin from './StorybookPlugin.ts';
|
|
14
11
|
export * from '#types';
|
|
12
|
+
export * as CorePlugins from './CorePlugins.ts';
|
|
13
|
+
export * as Corpus from './Corpus.ts';
|
|
14
|
+
export * as Harness from './Harness.ts';
|
package/src/meta.ts
CHANGED
|
@@ -7,7 +7,7 @@ import * as Effect from 'effect/Effect';
|
|
|
7
7
|
import * as LayoutOperation from '@dxos/app-toolkit/LayoutOperation';
|
|
8
8
|
import * as Operation from '@dxos/compute/Operation';
|
|
9
9
|
|
|
10
|
-
import { updateState } from './update-state';
|
|
10
|
+
import { updateState } from './update-state.ts';
|
|
11
11
|
|
|
12
12
|
const handler: Operation.WithHandler<typeof LayoutOperation.AddToast> = LayoutOperation.AddToast.pipe(
|
|
13
13
|
Operation.withHandler(
|