@cratis/scene.blueprint.default 4.34.0 → 4.35.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/cjs/preview-host/ApplicationHost.js +48 -27
- package/dist/cjs/preview-host/ApplicationHost.js.map +1 -1
- package/dist/esm/preview-host/ApplicationHost.d.ts +5 -2
- package/dist/esm/preview-host/ApplicationHost.d.ts.map +1 -1
- package/dist/esm/preview-host/ApplicationHost.js +50 -29
- package/dist/esm/preview-host/ApplicationHost.js.map +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/package.json +8 -8
- package/preview-host/ApplicationHost.tsx +57 -16
|
@@ -13,7 +13,7 @@ var composeApplication = require('./composeApplication.js');
|
|
|
13
13
|
* topbar and sidebar regions, every destination the document and the navigation lead to routed, and the dialog a toolbar slice
|
|
14
14
|
* button or a dialog destination opened shown over it - one place for all of it (spec PRV9), so a behaviour that differs between
|
|
15
15
|
* the two hosts is a bug in the host, not a second implementation.
|
|
16
|
-
*/ function ApplicationHost({ application, composition = {}, navigationModel, registry: hostRegistry, initialScreen, history, resolveBinding, queryResults, renderScreen, renderDialog, children }) {
|
|
16
|
+
*/ function ApplicationHost({ application, composition = {}, navigationModel, registry: hostRegistry, initialScreen, history, resolveBinding, queryResults, renderScreen, renderDialog, renderDialogTemplate, scope, layoutConfigStorage = null, children }) {
|
|
17
17
|
const [memoryHistory] = react.useState(()=>scene_react.createMemorySceneHistory());
|
|
18
18
|
const registry = react.useMemo(()=>({
|
|
19
19
|
...PreviewTemplate.previewComponents,
|
|
@@ -67,13 +67,46 @@ var composeApplication = require('./composeApplication.js');
|
|
|
67
67
|
const dialogTemplate = navigation.currentDialog ? application.dialogTemplates?.find((candidate)=>candidate.name === navigation.currentDialog) : undefined;
|
|
68
68
|
const sliceDialog = !dialogTemplate && navigation.currentDialog && scene_react.sliceDialogParameters(navigation.currentDialogParameters) !== undefined;
|
|
69
69
|
const dialogName = scene_react.sliceDialogParameters(navigation.currentDialogParameters)?.title ?? navigation.currentDialog;
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
70
|
+
const dialogContent = dialogTemplate ? composeApplication.composeDialog(application, dialogTemplate, composition) : undefined;
|
|
71
|
+
const body = /*#__PURE__*/ jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
72
|
+
children: [
|
|
73
|
+
/*#__PURE__*/ jsxRuntime.jsx("div", {
|
|
74
|
+
"data-scene-outlet": "primary",
|
|
75
|
+
"data-scene-url": navigation.currentUrl,
|
|
76
|
+
"data-scene-screen": navigation.primaryScreen,
|
|
77
|
+
children: composed && /*#__PURE__*/ jsxRuntime.jsx(Drawn, {
|
|
78
|
+
children: renderScreen ? ()=>renderScreen(composed.element, composed.configuration, navigation) : ()=>/*#__PURE__*/ jsxRuntime.jsx(scene_react.SceneElementView, {
|
|
79
|
+
element: composed.element,
|
|
80
|
+
registry: registry,
|
|
81
|
+
resolveBinding: resolveBinding,
|
|
82
|
+
queryResults: queryResults,
|
|
83
|
+
configuration: composed.configuration
|
|
84
|
+
})
|
|
85
|
+
})
|
|
86
|
+
}),
|
|
87
|
+
dialogTemplate && dialogContent && (renderDialogTemplate ? /*#__PURE__*/ jsxRuntime.jsx(Drawn, {
|
|
88
|
+
children: ()=>renderDialogTemplate(dialogTemplate, dialogContent, navigation)
|
|
89
|
+
}) : /*#__PURE__*/ jsxRuntime.jsx("div", {
|
|
90
|
+
role: "dialog",
|
|
91
|
+
"aria-modal": "true",
|
|
92
|
+
"aria-label": dialogName,
|
|
93
|
+
"data-scene-dialog": navigation.currentDialog,
|
|
94
|
+
children: /*#__PURE__*/ jsxRuntime.jsx(scene_react.SceneElementView, {
|
|
95
|
+
element: dialogContent,
|
|
96
|
+
registry: registry,
|
|
97
|
+
resolveBinding: resolveBinding,
|
|
98
|
+
queryResults: queryResults
|
|
99
|
+
})
|
|
100
|
+
})),
|
|
101
|
+
sliceDialog && /*#__PURE__*/ jsxRuntime.jsx("div", {
|
|
102
|
+
role: "dialog",
|
|
103
|
+
"aria-modal": "true",
|
|
104
|
+
"aria-label": dialogName,
|
|
105
|
+
"data-scene-dialog": navigation.currentDialog,
|
|
106
|
+
children: renderDialog?.(navigation) ?? /*#__PURE__*/ jsxRuntime.jsx(scene_react.SliceDialogView, {})
|
|
107
|
+
})
|
|
108
|
+
]
|
|
109
|
+
});
|
|
77
110
|
return /*#__PURE__*/ jsxRuntime.jsx(scene_react.SceneNavigationProvider, {
|
|
78
111
|
value: navigation,
|
|
79
112
|
children: /*#__PURE__*/ jsxRuntime.jsx(scene_react.SceneOutletContext.Provider, {
|
|
@@ -81,26 +114,9 @@ var composeApplication = require('./composeApplication.js');
|
|
|
81
114
|
children: /*#__PURE__*/ jsxRuntime.jsx(scene_react.SceneNavigationModelProvider, {
|
|
82
115
|
model: navigationModel,
|
|
83
116
|
children: /*#__PURE__*/ jsxRuntime.jsxs(LayoutConfigProvider.LayoutConfigProvider, {
|
|
84
|
-
storage:
|
|
117
|
+
storage: layoutConfigStorage,
|
|
85
118
|
children: [
|
|
86
|
-
|
|
87
|
-
"data-scene-outlet": "primary",
|
|
88
|
-
"data-scene-url": navigation.currentUrl,
|
|
89
|
-
"data-scene-screen": navigation.primaryScreen,
|
|
90
|
-
children: drawn
|
|
91
|
-
}),
|
|
92
|
-
(dialogTemplate || sliceDialog) && /*#__PURE__*/ jsxRuntime.jsx("div", {
|
|
93
|
-
role: "dialog",
|
|
94
|
-
"aria-modal": "true",
|
|
95
|
-
"aria-label": dialogName,
|
|
96
|
-
"data-scene-dialog": navigation.currentDialog,
|
|
97
|
-
children: dialogTemplate ? /*#__PURE__*/ jsxRuntime.jsx(scene_react.SceneElementView, {
|
|
98
|
-
element: composeApplication.composeDialog(application, dialogTemplate, composition),
|
|
99
|
-
registry: registry,
|
|
100
|
-
resolveBinding: resolveBinding,
|
|
101
|
-
queryResults: queryResults
|
|
102
|
-
}) : renderDialog?.(navigation) ?? /*#__PURE__*/ jsxRuntime.jsx(scene_react.SliceDialogView, {})
|
|
103
|
-
}),
|
|
119
|
+
scope ? scope(navigation, body) : body,
|
|
104
120
|
children
|
|
105
121
|
]
|
|
106
122
|
})
|
|
@@ -108,6 +124,11 @@ var composeApplication = require('./composeApplication.js');
|
|
|
108
124
|
})
|
|
109
125
|
});
|
|
110
126
|
}
|
|
127
|
+
/** Calls what a host draws as part of this component, so a hook it uses runs under the providers the host put in scope. */ function Drawn({ children }) {
|
|
128
|
+
return /*#__PURE__*/ jsxRuntime.jsx(jsxRuntime.Fragment, {
|
|
129
|
+
children: children()
|
|
130
|
+
});
|
|
131
|
+
}
|
|
111
132
|
|
|
112
133
|
exports.ApplicationHost = ApplicationHost;
|
|
113
134
|
//# sourceMappingURL=ApplicationHost.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ApplicationHost.js","sources":["../../../preview-host/ApplicationHost.tsx"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { ReactNode, useMemo, useState } from 'react';\nimport { SceneElement, type EffectiveConfiguration } from '@cratis/scene.model';\nimport { BindingResolver, BindingScope } from '@cratis/scene.engine';\nimport {\n ComponentRegistry, SceneElementView, SceneHistory, SceneNavigationContextValue, SceneNavigationModel, SceneNavigationModelProvider,\n SceneNavigationProvider, SceneOutletContext, SliceDialogView, collectOutletOwners, createMemorySceneHistory, navigationDestinations,\n sceneRoutesFrom, sliceDialogParameters, useSceneHistoryNavigation,\n} from '@cratis/scene.react';\nimport { LayoutConfigProvider } from '../configuration';\nimport { ApplicationDocument } from './ApplicationDocument';\nimport { previewComponents } from './PreviewTemplate';\nimport { CompositionOptions, collectDestinations, composeApplicationScreen, composeDialog, composeOutletScreen } from './composeApplication';\n\nexport interface ApplicationHostProps {\n /** The document the application is composed from. */\n application: ApplicationDocument;\n\n /** What the host decides about composition; Stage and the preview host differ only here. */\n composition?: CompositionOptions;\n\n /** The structure and navigation the shell's regions show and the items' destinations resolve against. */\n navigationModel: SceneNavigationModel;\n\n registry: ComponentRegistry;\n\n /** The screen shown first. */\n initialScreen: string;\n\n /** Where entries are recorded: the address bar for Stage, an in-memory history for a preview, which never touches the host's URL (PRV4). */\n history?: SceneHistory;\n\n /** What the screens' bindings resolve against. */\n resolveBinding?: BindingResolver;\n queryResults?: Record<string, unknown>;\n\n /**\n * Draws the composed screen. The default renders it with `SceneElementView`; Stage wraps it with its data and command scope.\n * @param element The composed screen.\n * @param configuration What the screen's templates were configured with.\n * @param navigation Where the user is.\n */\n renderScreen?(element: SceneElement, configuration: EffectiveConfiguration | undefined, navigation: SceneNavigationContextValue): ReactNode;\n\n /**\n * Draws what the open dialog shows when the document has no dialog template of that name - a toolbar slice button's task\n * dialog by default.\n */\n renderDialog?(navigation: SceneNavigationContextValue): ReactNode;\n\n /** Rendered inside the host's providers, after the application. */\n children?: ReactNode;\n}\n\n/**\n * The application as both Stage and the preview host run it: the shell composed for the screen on the page\n * (`composeApplicationScreen`), nested outlets holding the screens placed in them, the navigation model in scope for the shell's\n * topbar and sidebar regions, every destination the document and the navigation lead to routed, and the dialog a toolbar slice\n * button or a dialog destination opened shown over it - one place for all of it (spec PRV9), so a behaviour that differs between\n * the two hosts is a bug in the host, not a second implementation.\n */\nexport function ApplicationHost({ application, composition = {}, navigationModel, registry: hostRegistry, initialScreen, history, resolveBinding, queryResults, renderScreen, renderDialog, children }: ApplicationHostProps) {\n const [memoryHistory] = useState(() => createMemorySceneHistory());\n const registry = useMemo(() => ({ ...previewComponents, ...hostRegistry }), [hostRegistry]);\n const hostHistory = history ?? memoryHistory;\n const screens = application.screens;\n\n const outletScreens = useMemo(\n () => Object.fromEntries(screens.map(candidate => [candidate.name, composeOutletScreen(application, candidate, composition)])),\n [application, composition, screens]);\n const owners = useMemo(() => collectOutletOwners(outletScreens), [outletScreens]);\n const destinations = useMemo(\n () => [...collectDestinations(application), ...navigationDestinations(navigationModel.structure, navigationModel.navigation, navigationModel.screenFor)],\n [application, navigationModel]);\n const routes = useMemo(() => sceneRoutesFrom(screens.map(candidate => candidate.name), destinations), [destinations, screens]);\n const bindingScope = useMemo<BindingScope>(() => ({ queryResults }), [queryResults]);\n const navigation = useSceneHistoryNavigation(hostHistory, routes, initialScreen, bindingScope, owners, destinations);\n\n const screen = screens.find(candidate => candidate.name === navigation.primaryScreen) ?? screens.find(candidate => candidate.name === initialScreen) ?? screens[0];\n const composed = useMemo(() => screen ? composeApplicationScreen(application, screen, composition) : undefined, [application, composition, screen]);\n const outletContext = useMemo(() => ({ screens: outletScreens, registry }), [outletScreens, registry]);\n\n const dialogTemplate = navigation.currentDialog ? application.dialogTemplates?.find(candidate => candidate.name === navigation.currentDialog) : undefined;\n const sliceDialog = !dialogTemplate && navigation.currentDialog && sliceDialogParameters(navigation.currentDialogParameters) !== undefined;\n const dialogName = sliceDialogParameters(navigation.currentDialogParameters)?.title ?? navigation.currentDialog;\n\n const drawn = composed\n ? renderScreen?.(composed.element, composed.configuration, navigation)\n ?? <SceneElementView element={composed.element} registry={registry} resolveBinding={resolveBinding} queryResults={queryResults} configuration={composed.configuration} />\n : null;\n\n return (\n <SceneNavigationProvider value={navigation}>\n <SceneOutletContext.Provider value={outletContext}>\n <SceneNavigationModelProvider model={navigationModel}>\n {/* The shell reads its layout configuration from a provider; nothing is saved from a hosted application's own. */}\n <LayoutConfigProvider storage={null}>\n <div data-scene-outlet='primary' data-scene-url={navigation.currentUrl} data-scene-screen={navigation.primaryScreen}>{drawn}</div>\n {(dialogTemplate || sliceDialog) && (\n <div role='dialog' aria-modal='true' aria-label={dialogName} data-scene-dialog={navigation.currentDialog}>\n {dialogTemplate\n ? <SceneElementView element={composeDialog(application, dialogTemplate, composition)} registry={registry} resolveBinding={resolveBinding} queryResults={queryResults} />\n : renderDialog?.(navigation) ?? <SliceDialogView />}\n </div>\n )}\n {children}\n </LayoutConfigProvider>\n </SceneNavigationModelProvider>\n </SceneOutletContext.Provider>\n </SceneNavigationProvider>\n );\n}\n"],"names":["ApplicationHost","application","composition","navigationModel","registry","hostRegistry","initialScreen","history","resolveBinding","queryResults","renderScreen","renderDialog","children","memoryHistory","useState","createMemorySceneHistory","useMemo","previewComponents","hostHistory","screens","outletScreens","Object","fromEntries","map","candidate","name","composeOutletScreen","owners","collectOutletOwners","destinations","collectDestinations","navigationDestinations","structure","navigation","screenFor","routes","sceneRoutesFrom","bindingScope","useSceneHistoryNavigation","screen","find","primaryScreen","composed","composeApplicationScreen","undefined","outletContext","dialogTemplate","currentDialog","dialogTemplates","sliceDialog","sliceDialogParameters","currentDialogParameters","dialogName","title","drawn","element","configuration","_jsx","SceneElementView","SceneNavigationProvider","value","SceneOutletContext","Provider","SceneNavigationModelProvider","model","_jsxs","LayoutConfigProvider","storage","div","data-scene-outlet","data-scene-url","currentUrl","data-scene-screen","role","aria-modal","aria-label","data-scene-dialog","composeDialog","SliceDialogView"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ApplicationHost.js","sources":["../../../preview-host/ApplicationHost.tsx"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { ReactNode, useMemo, useState } from 'react';\nimport { DialogTemplate, SceneElement, type EffectiveConfiguration } from '@cratis/scene.model';\nimport { BindingResolver, BindingScope } from '@cratis/scene.engine';\nimport {\n ComponentRegistry, SceneElementView, SceneHistory, SceneNavigationContextValue, SceneNavigationModel, SceneNavigationModelProvider,\n SceneNavigationProvider, SceneOutletContext, SliceDialogView, collectOutletOwners, createMemorySceneHistory, navigationDestinations,\n sceneRoutesFrom, sliceDialogParameters, useSceneHistoryNavigation,\n} from '@cratis/scene.react';\nimport { LayoutConfigProvider } from '../configuration';\nimport { ApplicationDocument } from './ApplicationDocument';\nimport { previewComponents } from './PreviewTemplate';\nimport { CompositionOptions, collectDestinations, composeApplicationScreen, composeDialog, composeOutletScreen } from './composeApplication';\n\nexport interface ApplicationHostProps {\n /** The document the application is composed from. */\n application: ApplicationDocument;\n\n /** What the host decides about composition; Stage and the preview host differ only here. */\n composition?: CompositionOptions;\n\n /** The structure and navigation the shell's regions show and the items' destinations resolve against. */\n navigationModel: SceneNavigationModel;\n\n registry: ComponentRegistry;\n\n /** The screen shown first. */\n initialScreen: string;\n\n /** Where entries are recorded: the address bar for Stage, an in-memory history for a preview, which never touches the host's URL (PRV4). */\n history?: SceneHistory;\n\n /** What the screens' bindings resolve against. */\n resolveBinding?: BindingResolver;\n queryResults?: Record<string, unknown>;\n\n /**\n * Draws the composed screen. The default renders it with `SceneElementView`; Stage wraps it with its data and command scope.\n * @param element The composed screen.\n * @param configuration What the screen's templates were configured with.\n * @param navigation Where the user is.\n */\n renderScreen?(element: SceneElement, configuration: EffectiveConfiguration | undefined, navigation: SceneNavigationContextValue): ReactNode;\n\n /**\n * Draws what the open dialog shows when the document has no dialog template of that name - a toolbar slice button's task\n * dialog by default.\n */\n renderDialog?(navigation: SceneNavigationContextValue): ReactNode;\n\n /**\n * Draws a dialog the document declares, in place of the host's plain one - a host that wants its own backdrop, a close button\n * and keyboard handling around the template's content. Called inside {@link scope}.\n * @param template The dialog template that is open.\n * @param content The template's composed content.\n * @param navigation Where the user is.\n */\n renderDialogTemplate?(template: DialogTemplate, content: SceneElement, navigation: SceneNavigationContextValue): ReactNode;\n\n /**\n * What a host provides around everything that renders - the screen on the page and the dialog over it: its data, its command\n * dispatcher, its chrome state. Inside the navigation providers, so it can read where the user is. Stage puts its data and\n * interaction scope here, so the screen, a dialog template and a slice dialog all share them.\n * @param navigation Where the user is.\n * @param children The screen and the dialog.\n */\n scope?(navigation: SceneNavigationContextValue, children: ReactNode): ReactNode;\n\n /**\n * Where the shell keeps its layout configuration - the sidebar's state, the chosen theme. A preview keeps none (null, the default);\n * a running application passes its storage so what a user chose is still chosen on the next visit.\n */\n layoutConfigStorage?: Storage | null;\n\n /** Rendered inside the host's providers, after the application. */\n children?: ReactNode;\n}\n\n/**\n * The application as both Stage and the preview host run it: the shell composed for the screen on the page\n * (`composeApplicationScreen`), nested outlets holding the screens placed in them, the navigation model in scope for the shell's\n * topbar and sidebar regions, every destination the document and the navigation lead to routed, and the dialog a toolbar slice\n * button or a dialog destination opened shown over it - one place for all of it (spec PRV9), so a behaviour that differs between\n * the two hosts is a bug in the host, not a second implementation.\n */\nexport function ApplicationHost({ application, composition = {}, navigationModel, registry: hostRegistry, initialScreen, history, resolveBinding, queryResults, renderScreen, renderDialog, renderDialogTemplate, scope, layoutConfigStorage = null, children }: ApplicationHostProps) {\n const [memoryHistory] = useState(() => createMemorySceneHistory());\n const registry = useMemo(() => ({ ...previewComponents, ...hostRegistry }), [hostRegistry]);\n const hostHistory = history ?? memoryHistory;\n const screens = application.screens;\n\n const outletScreens = useMemo(\n () => Object.fromEntries(screens.map(candidate => [candidate.name, composeOutletScreen(application, candidate, composition)])),\n [application, composition, screens]);\n const owners = useMemo(() => collectOutletOwners(outletScreens), [outletScreens]);\n const destinations = useMemo(\n () => [...collectDestinations(application), ...navigationDestinations(navigationModel.structure, navigationModel.navigation, navigationModel.screenFor)],\n [application, navigationModel]);\n const routes = useMemo(() => sceneRoutesFrom(screens.map(candidate => candidate.name), destinations), [destinations, screens]);\n const bindingScope = useMemo<BindingScope>(() => ({ queryResults }), [queryResults]);\n const navigation = useSceneHistoryNavigation(hostHistory, routes, initialScreen, bindingScope, owners, destinations);\n\n const screen = screens.find(candidate => candidate.name === navigation.primaryScreen) ?? screens.find(candidate => candidate.name === initialScreen) ?? screens[0];\n const composed = useMemo(() => screen ? composeApplicationScreen(application, screen, composition) : undefined, [application, composition, screen]);\n const outletContext = useMemo(() => ({ screens: outletScreens, registry }), [outletScreens, registry]);\n\n const dialogTemplate = navigation.currentDialog ? application.dialogTemplates?.find(candidate => candidate.name === navigation.currentDialog) : undefined;\n const sliceDialog = !dialogTemplate && navigation.currentDialog && sliceDialogParameters(navigation.currentDialogParameters) !== undefined;\n const dialogName = sliceDialogParameters(navigation.currentDialogParameters)?.title ?? navigation.currentDialog;\n\n const dialogContent = dialogTemplate ? composeDialog(application, dialogTemplate, composition) : undefined;\n\n const body = (\n <>\n <div data-scene-outlet='primary' data-scene-url={navigation.currentUrl} data-scene-screen={navigation.primaryScreen}>\n {composed && <Drawn>{renderScreen\n ? () => renderScreen(composed.element, composed.configuration, navigation)\n : () => <SceneElementView element={composed.element} registry={registry} resolveBinding={resolveBinding} queryResults={queryResults} configuration={composed.configuration} />}</Drawn>}\n </div>\n {dialogTemplate && dialogContent && (renderDialogTemplate\n ? <Drawn>{() => renderDialogTemplate(dialogTemplate, dialogContent, navigation)}</Drawn>\n : (\n <div role='dialog' aria-modal='true' aria-label={dialogName} data-scene-dialog={navigation.currentDialog}>\n <SceneElementView element={dialogContent} registry={registry} resolveBinding={resolveBinding} queryResults={queryResults} />\n </div>\n ))}\n {sliceDialog && (\n <div role='dialog' aria-modal='true' aria-label={dialogName} data-scene-dialog={navigation.currentDialog}>\n {renderDialog?.(navigation) ?? <SliceDialogView />}\n </div>\n )}\n </>\n );\n\n return (\n <SceneNavigationProvider value={navigation}>\n <SceneOutletContext.Provider value={outletContext}>\n <SceneNavigationModelProvider model={navigationModel}>\n {/* The shell reads its layout configuration from a provider; nothing is saved unless the host gives it somewhere to. */}\n <LayoutConfigProvider storage={layoutConfigStorage}>\n {scope ? scope(navigation, body) : body}\n {children}\n </LayoutConfigProvider>\n </SceneNavigationModelProvider>\n </SceneOutletContext.Provider>\n </SceneNavigationProvider>\n );\n}\n\n/** Calls what a host draws as part of this component, so a hook it uses runs under the providers the host put in scope. */\nfunction Drawn({ children }: { children(): ReactNode }) {\n return <>{children()}</>;\n}\n"],"names":["ApplicationHost","application","composition","navigationModel","registry","hostRegistry","initialScreen","history","resolveBinding","queryResults","renderScreen","renderDialog","renderDialogTemplate","scope","layoutConfigStorage","children","memoryHistory","useState","createMemorySceneHistory","useMemo","previewComponents","hostHistory","screens","outletScreens","Object","fromEntries","map","candidate","name","composeOutletScreen","owners","collectOutletOwners","destinations","collectDestinations","navigationDestinations","structure","navigation","screenFor","routes","sceneRoutesFrom","bindingScope","useSceneHistoryNavigation","screen","find","primaryScreen","composed","composeApplicationScreen","undefined","outletContext","dialogTemplate","currentDialog","dialogTemplates","sliceDialog","sliceDialogParameters","currentDialogParameters","dialogName","title","dialogContent","composeDialog","body","_jsxs","_Fragment","_jsx","div","data-scene-outlet","data-scene-url","currentUrl","data-scene-screen","Drawn","element","configuration","SceneElementView","role","aria-modal","aria-label","data-scene-dialog","SliceDialogView","SceneNavigationProvider","value","SceneOutletContext","Provider","SceneNavigationModelProvider","model","LayoutConfigProvider","storage"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
|
-
import { SceneElement, type EffectiveConfiguration } from '@cratis/scene.model';
|
|
2
|
+
import { DialogTemplate, SceneElement, type EffectiveConfiguration } from '@cratis/scene.model';
|
|
3
3
|
import { BindingResolver } from '@cratis/scene.engine';
|
|
4
4
|
import { ComponentRegistry, SceneHistory, SceneNavigationContextValue, SceneNavigationModel } from '@cratis/scene.react';
|
|
5
5
|
import { ApplicationDocument } from './ApplicationDocument';
|
|
@@ -15,7 +15,10 @@ export interface ApplicationHostProps {
|
|
|
15
15
|
queryResults?: Record<string, unknown>;
|
|
16
16
|
renderScreen?(element: SceneElement, configuration: EffectiveConfiguration | undefined, navigation: SceneNavigationContextValue): ReactNode;
|
|
17
17
|
renderDialog?(navigation: SceneNavigationContextValue): ReactNode;
|
|
18
|
+
renderDialogTemplate?(template: DialogTemplate, content: SceneElement, navigation: SceneNavigationContextValue): ReactNode;
|
|
19
|
+
scope?(navigation: SceneNavigationContextValue, children: ReactNode): ReactNode;
|
|
20
|
+
layoutConfigStorage?: Storage | null;
|
|
18
21
|
children?: ReactNode;
|
|
19
22
|
}
|
|
20
|
-
export declare function ApplicationHost({ application, composition, navigationModel, registry: hostRegistry, initialScreen, history, resolveBinding, queryResults, renderScreen, renderDialog, children }: ApplicationHostProps): import("react").JSX.Element;
|
|
23
|
+
export declare function ApplicationHost({ application, composition, navigationModel, registry: hostRegistry, initialScreen, history, resolveBinding, queryResults, renderScreen, renderDialog, renderDialogTemplate, scope, layoutConfigStorage, children }: ApplicationHostProps): import("react").JSX.Element;
|
|
21
24
|
//# sourceMappingURL=ApplicationHost.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ApplicationHost.d.ts","sourceRoot":"","sources":["../../../preview-host/ApplicationHost.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAqB,MAAM,OAAO,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,KAAK,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"ApplicationHost.d.ts","sourceRoot":"","sources":["../../../preview-host/ApplicationHost.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAqB,MAAM,OAAO,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,KAAK,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAChG,OAAO,EAAE,eAAe,EAAgB,MAAM,sBAAsB,CAAC;AACrE,OAAO,EACH,iBAAiB,EAAoB,YAAY,EAAE,2BAA2B,EAAE,oBAAoB,EAGvG,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,EAAE,kBAAkB,EAAqF,MAAM,sBAAsB,CAAC;AAE7I,MAAM,WAAW,oBAAoB;IAEjC,WAAW,EAAE,mBAAmB,CAAC;IAGjC,WAAW,CAAC,EAAE,kBAAkB,CAAC;IAGjC,eAAe,EAAE,oBAAoB,CAAC;IAEtC,QAAQ,EAAE,iBAAiB,CAAC;IAG5B,aAAa,EAAE,MAAM,CAAC;IAGtB,OAAO,CAAC,EAAE,YAAY,CAAC;IAGvB,cAAc,CAAC,EAAE,eAAe,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAQvC,YAAY,CAAC,CAAC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,sBAAsB,GAAG,SAAS,EAAE,UAAU,EAAE,2BAA2B,GAAG,SAAS,CAAC;IAM5I,YAAY,CAAC,CAAC,UAAU,EAAE,2BAA2B,GAAG,SAAS,CAAC;IASlE,oBAAoB,CAAC,CAAC,QAAQ,EAAE,cAAc,EAAE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,2BAA2B,GAAG,SAAS,CAAC;IAS3H,KAAK,CAAC,CAAC,UAAU,EAAE,2BAA2B,EAAE,QAAQ,EAAE,SAAS,GAAG,SAAS,CAAC;IAMhF,mBAAmB,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAGrC,QAAQ,CAAC,EAAE,SAAS,CAAC;CACxB;AASD,wBAAgB,eAAe,CAAC,EAAE,WAAW,EAAE,WAAgB,EAAE,eAAe,EAAE,QAAQ,EAAE,YAAY,EAAE,aAAa,EAAE,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,oBAAoB,EAAE,KAAK,EAAE,mBAA0B,EAAE,QAAQ,EAAE,EAAE,oBAAoB,+BA8DpR"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
2
2
|
import { useState, useMemo } from 'react';
|
|
3
|
-
import { createMemorySceneHistory, collectOutletOwners, navigationDestinations, sceneRoutesFrom, useSceneHistoryNavigation, sliceDialogParameters, SceneElementView, SceneNavigationProvider, SceneOutletContext, SceneNavigationModelProvider
|
|
3
|
+
import { createMemorySceneHistory, collectOutletOwners, navigationDestinations, sceneRoutesFrom, useSceneHistoryNavigation, sliceDialogParameters, SceneElementView, SliceDialogView, SceneNavigationProvider, SceneOutletContext, SceneNavigationModelProvider } from '@cratis/scene.react';
|
|
4
4
|
import { LayoutConfigProvider } from '../configuration/LayoutConfigProvider.js';
|
|
5
5
|
import { previewComponents } from './PreviewTemplate.js';
|
|
6
6
|
import { composeOutletScreen, collectDestinations, composeApplicationScreen, composeDialog } from './composeApplication.js';
|
|
@@ -11,7 +11,7 @@ import { composeOutletScreen, collectDestinations, composeApplicationScreen, com
|
|
|
11
11
|
* topbar and sidebar regions, every destination the document and the navigation lead to routed, and the dialog a toolbar slice
|
|
12
12
|
* button or a dialog destination opened shown over it - one place for all of it (spec PRV9), so a behaviour that differs between
|
|
13
13
|
* the two hosts is a bug in the host, not a second implementation.
|
|
14
|
-
*/ function ApplicationHost({ application, composition = {}, navigationModel, registry: hostRegistry, initialScreen, history, resolveBinding, queryResults, renderScreen, renderDialog, children }) {
|
|
14
|
+
*/ function ApplicationHost({ application, composition = {}, navigationModel, registry: hostRegistry, initialScreen, history, resolveBinding, queryResults, renderScreen, renderDialog, renderDialogTemplate, scope, layoutConfigStorage = null, children }) {
|
|
15
15
|
const [memoryHistory] = useState(()=>createMemorySceneHistory());
|
|
16
16
|
const registry = useMemo(()=>({
|
|
17
17
|
...previewComponents,
|
|
@@ -65,13 +65,46 @@ import { composeOutletScreen, collectDestinations, composeApplicationScreen, com
|
|
|
65
65
|
const dialogTemplate = navigation.currentDialog ? application.dialogTemplates?.find((candidate)=>candidate.name === navigation.currentDialog) : undefined;
|
|
66
66
|
const sliceDialog = !dialogTemplate && navigation.currentDialog && sliceDialogParameters(navigation.currentDialogParameters) !== undefined;
|
|
67
67
|
const dialogName = sliceDialogParameters(navigation.currentDialogParameters)?.title ?? navigation.currentDialog;
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
68
|
+
const dialogContent = dialogTemplate ? composeDialog(application, dialogTemplate, composition) : undefined;
|
|
69
|
+
const body = /*#__PURE__*/ jsxs(Fragment, {
|
|
70
|
+
children: [
|
|
71
|
+
/*#__PURE__*/ jsx("div", {
|
|
72
|
+
"data-scene-outlet": "primary",
|
|
73
|
+
"data-scene-url": navigation.currentUrl,
|
|
74
|
+
"data-scene-screen": navigation.primaryScreen,
|
|
75
|
+
children: composed && /*#__PURE__*/ jsx(Drawn, {
|
|
76
|
+
children: renderScreen ? ()=>renderScreen(composed.element, composed.configuration, navigation) : ()=>/*#__PURE__*/ jsx(SceneElementView, {
|
|
77
|
+
element: composed.element,
|
|
78
|
+
registry: registry,
|
|
79
|
+
resolveBinding: resolveBinding,
|
|
80
|
+
queryResults: queryResults,
|
|
81
|
+
configuration: composed.configuration
|
|
82
|
+
})
|
|
83
|
+
})
|
|
84
|
+
}),
|
|
85
|
+
dialogTemplate && dialogContent && (renderDialogTemplate ? /*#__PURE__*/ jsx(Drawn, {
|
|
86
|
+
children: ()=>renderDialogTemplate(dialogTemplate, dialogContent, navigation)
|
|
87
|
+
}) : /*#__PURE__*/ jsx("div", {
|
|
88
|
+
role: "dialog",
|
|
89
|
+
"aria-modal": "true",
|
|
90
|
+
"aria-label": dialogName,
|
|
91
|
+
"data-scene-dialog": navigation.currentDialog,
|
|
92
|
+
children: /*#__PURE__*/ jsx(SceneElementView, {
|
|
93
|
+
element: dialogContent,
|
|
94
|
+
registry: registry,
|
|
95
|
+
resolveBinding: resolveBinding,
|
|
96
|
+
queryResults: queryResults
|
|
97
|
+
})
|
|
98
|
+
})),
|
|
99
|
+
sliceDialog && /*#__PURE__*/ jsx("div", {
|
|
100
|
+
role: "dialog",
|
|
101
|
+
"aria-modal": "true",
|
|
102
|
+
"aria-label": dialogName,
|
|
103
|
+
"data-scene-dialog": navigation.currentDialog,
|
|
104
|
+
children: renderDialog?.(navigation) ?? /*#__PURE__*/ jsx(SliceDialogView, {})
|
|
105
|
+
})
|
|
106
|
+
]
|
|
107
|
+
});
|
|
75
108
|
return /*#__PURE__*/ jsx(SceneNavigationProvider, {
|
|
76
109
|
value: navigation,
|
|
77
110
|
children: /*#__PURE__*/ jsx(SceneOutletContext.Provider, {
|
|
@@ -79,26 +112,9 @@ import { composeOutletScreen, collectDestinations, composeApplicationScreen, com
|
|
|
79
112
|
children: /*#__PURE__*/ jsx(SceneNavigationModelProvider, {
|
|
80
113
|
model: navigationModel,
|
|
81
114
|
children: /*#__PURE__*/ jsxs(LayoutConfigProvider, {
|
|
82
|
-
storage:
|
|
115
|
+
storage: layoutConfigStorage,
|
|
83
116
|
children: [
|
|
84
|
-
|
|
85
|
-
"data-scene-outlet": "primary",
|
|
86
|
-
"data-scene-url": navigation.currentUrl,
|
|
87
|
-
"data-scene-screen": navigation.primaryScreen,
|
|
88
|
-
children: drawn
|
|
89
|
-
}),
|
|
90
|
-
(dialogTemplate || sliceDialog) && /*#__PURE__*/ jsx("div", {
|
|
91
|
-
role: "dialog",
|
|
92
|
-
"aria-modal": "true",
|
|
93
|
-
"aria-label": dialogName,
|
|
94
|
-
"data-scene-dialog": navigation.currentDialog,
|
|
95
|
-
children: dialogTemplate ? /*#__PURE__*/ jsx(SceneElementView, {
|
|
96
|
-
element: composeDialog(application, dialogTemplate, composition),
|
|
97
|
-
registry: registry,
|
|
98
|
-
resolveBinding: resolveBinding,
|
|
99
|
-
queryResults: queryResults
|
|
100
|
-
}) : renderDialog?.(navigation) ?? /*#__PURE__*/ jsx(SliceDialogView, {})
|
|
101
|
-
}),
|
|
117
|
+
scope ? scope(navigation, body) : body,
|
|
102
118
|
children
|
|
103
119
|
]
|
|
104
120
|
})
|
|
@@ -106,6 +122,11 @@ import { composeOutletScreen, collectDestinations, composeApplicationScreen, com
|
|
|
106
122
|
})
|
|
107
123
|
});
|
|
108
124
|
}
|
|
125
|
+
/** Calls what a host draws as part of this component, so a hook it uses runs under the providers the host put in scope. */ function Drawn({ children }) {
|
|
126
|
+
return /*#__PURE__*/ jsx(Fragment, {
|
|
127
|
+
children: children()
|
|
128
|
+
});
|
|
129
|
+
}
|
|
109
130
|
|
|
110
131
|
export { ApplicationHost };
|
|
111
132
|
//# sourceMappingURL=ApplicationHost.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ApplicationHost.js","sources":["../../../preview-host/ApplicationHost.tsx"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { ReactNode, useMemo, useState } from 'react';\nimport { SceneElement, type EffectiveConfiguration } from '@cratis/scene.model';\nimport { BindingResolver, BindingScope } from '@cratis/scene.engine';\nimport {\n ComponentRegistry, SceneElementView, SceneHistory, SceneNavigationContextValue, SceneNavigationModel, SceneNavigationModelProvider,\n SceneNavigationProvider, SceneOutletContext, SliceDialogView, collectOutletOwners, createMemorySceneHistory, navigationDestinations,\n sceneRoutesFrom, sliceDialogParameters, useSceneHistoryNavigation,\n} from '@cratis/scene.react';\nimport { LayoutConfigProvider } from '../configuration';\nimport { ApplicationDocument } from './ApplicationDocument';\nimport { previewComponents } from './PreviewTemplate';\nimport { CompositionOptions, collectDestinations, composeApplicationScreen, composeDialog, composeOutletScreen } from './composeApplication';\n\nexport interface ApplicationHostProps {\n /** The document the application is composed from. */\n application: ApplicationDocument;\n\n /** What the host decides about composition; Stage and the preview host differ only here. */\n composition?: CompositionOptions;\n\n /** The structure and navigation the shell's regions show and the items' destinations resolve against. */\n navigationModel: SceneNavigationModel;\n\n registry: ComponentRegistry;\n\n /** The screen shown first. */\n initialScreen: string;\n\n /** Where entries are recorded: the address bar for Stage, an in-memory history for a preview, which never touches the host's URL (PRV4). */\n history?: SceneHistory;\n\n /** What the screens' bindings resolve against. */\n resolveBinding?: BindingResolver;\n queryResults?: Record<string, unknown>;\n\n /**\n * Draws the composed screen. The default renders it with `SceneElementView`; Stage wraps it with its data and command scope.\n * @param element The composed screen.\n * @param configuration What the screen's templates were configured with.\n * @param navigation Where the user is.\n */\n renderScreen?(element: SceneElement, configuration: EffectiveConfiguration | undefined, navigation: SceneNavigationContextValue): ReactNode;\n\n /**\n * Draws what the open dialog shows when the document has no dialog template of that name - a toolbar slice button's task\n * dialog by default.\n */\n renderDialog?(navigation: SceneNavigationContextValue): ReactNode;\n\n /** Rendered inside the host's providers, after the application. */\n children?: ReactNode;\n}\n\n/**\n * The application as both Stage and the preview host run it: the shell composed for the screen on the page\n * (`composeApplicationScreen`), nested outlets holding the screens placed in them, the navigation model in scope for the shell's\n * topbar and sidebar regions, every destination the document and the navigation lead to routed, and the dialog a toolbar slice\n * button or a dialog destination opened shown over it - one place for all of it (spec PRV9), so a behaviour that differs between\n * the two hosts is a bug in the host, not a second implementation.\n */\nexport function ApplicationHost({ application, composition = {}, navigationModel, registry: hostRegistry, initialScreen, history, resolveBinding, queryResults, renderScreen, renderDialog, children }: ApplicationHostProps) {\n const [memoryHistory] = useState(() => createMemorySceneHistory());\n const registry = useMemo(() => ({ ...previewComponents, ...hostRegistry }), [hostRegistry]);\n const hostHistory = history ?? memoryHistory;\n const screens = application.screens;\n\n const outletScreens = useMemo(\n () => Object.fromEntries(screens.map(candidate => [candidate.name, composeOutletScreen(application, candidate, composition)])),\n [application, composition, screens]);\n const owners = useMemo(() => collectOutletOwners(outletScreens), [outletScreens]);\n const destinations = useMemo(\n () => [...collectDestinations(application), ...navigationDestinations(navigationModel.structure, navigationModel.navigation, navigationModel.screenFor)],\n [application, navigationModel]);\n const routes = useMemo(() => sceneRoutesFrom(screens.map(candidate => candidate.name), destinations), [destinations, screens]);\n const bindingScope = useMemo<BindingScope>(() => ({ queryResults }), [queryResults]);\n const navigation = useSceneHistoryNavigation(hostHistory, routes, initialScreen, bindingScope, owners, destinations);\n\n const screen = screens.find(candidate => candidate.name === navigation.primaryScreen) ?? screens.find(candidate => candidate.name === initialScreen) ?? screens[0];\n const composed = useMemo(() => screen ? composeApplicationScreen(application, screen, composition) : undefined, [application, composition, screen]);\n const outletContext = useMemo(() => ({ screens: outletScreens, registry }), [outletScreens, registry]);\n\n const dialogTemplate = navigation.currentDialog ? application.dialogTemplates?.find(candidate => candidate.name === navigation.currentDialog) : undefined;\n const sliceDialog = !dialogTemplate && navigation.currentDialog && sliceDialogParameters(navigation.currentDialogParameters) !== undefined;\n const dialogName = sliceDialogParameters(navigation.currentDialogParameters)?.title ?? navigation.currentDialog;\n\n const drawn = composed\n ? renderScreen?.(composed.element, composed.configuration, navigation)\n ?? <SceneElementView element={composed.element} registry={registry} resolveBinding={resolveBinding} queryResults={queryResults} configuration={composed.configuration} />\n : null;\n\n return (\n <SceneNavigationProvider value={navigation}>\n <SceneOutletContext.Provider value={outletContext}>\n <SceneNavigationModelProvider model={navigationModel}>\n {/* The shell reads its layout configuration from a provider; nothing is saved from a hosted application's own. */}\n <LayoutConfigProvider storage={null}>\n <div data-scene-outlet='primary' data-scene-url={navigation.currentUrl} data-scene-screen={navigation.primaryScreen}>{drawn}</div>\n {(dialogTemplate || sliceDialog) && (\n <div role='dialog' aria-modal='true' aria-label={dialogName} data-scene-dialog={navigation.currentDialog}>\n {dialogTemplate\n ? <SceneElementView element={composeDialog(application, dialogTemplate, composition)} registry={registry} resolveBinding={resolveBinding} queryResults={queryResults} />\n : renderDialog?.(navigation) ?? <SliceDialogView />}\n </div>\n )}\n {children}\n </LayoutConfigProvider>\n </SceneNavigationModelProvider>\n </SceneOutletContext.Provider>\n </SceneNavigationProvider>\n );\n}\n"],"names":["ApplicationHost","application","composition","navigationModel","registry","hostRegistry","initialScreen","history","resolveBinding","queryResults","renderScreen","renderDialog","children","memoryHistory","useState","createMemorySceneHistory","useMemo","previewComponents","hostHistory","screens","outletScreens","Object","fromEntries","map","candidate","name","composeOutletScreen","owners","collectOutletOwners","destinations","collectDestinations","navigationDestinations","structure","navigation","screenFor","routes","sceneRoutesFrom","bindingScope","useSceneHistoryNavigation","screen","find","primaryScreen","composed","composeApplicationScreen","undefined","outletContext","dialogTemplate","currentDialog","dialogTemplates","sliceDialog","sliceDialogParameters","currentDialogParameters","dialogName","title","drawn","element","configuration","_jsx","SceneElementView","SceneNavigationProvider","value","SceneOutletContext","Provider","SceneNavigationModelProvider","model","_jsxs","LayoutConfigProvider","storage","div","data-scene-outlet","data-scene-url","currentUrl","data-scene-screen","role","aria-modal","aria-label","data-scene-dialog","composeDialog","SliceDialogView"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ApplicationHost.js","sources":["../../../preview-host/ApplicationHost.tsx"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { ReactNode, useMemo, useState } from 'react';\nimport { DialogTemplate, SceneElement, type EffectiveConfiguration } from '@cratis/scene.model';\nimport { BindingResolver, BindingScope } from '@cratis/scene.engine';\nimport {\n ComponentRegistry, SceneElementView, SceneHistory, SceneNavigationContextValue, SceneNavigationModel, SceneNavigationModelProvider,\n SceneNavigationProvider, SceneOutletContext, SliceDialogView, collectOutletOwners, createMemorySceneHistory, navigationDestinations,\n sceneRoutesFrom, sliceDialogParameters, useSceneHistoryNavigation,\n} from '@cratis/scene.react';\nimport { LayoutConfigProvider } from '../configuration';\nimport { ApplicationDocument } from './ApplicationDocument';\nimport { previewComponents } from './PreviewTemplate';\nimport { CompositionOptions, collectDestinations, composeApplicationScreen, composeDialog, composeOutletScreen } from './composeApplication';\n\nexport interface ApplicationHostProps {\n /** The document the application is composed from. */\n application: ApplicationDocument;\n\n /** What the host decides about composition; Stage and the preview host differ only here. */\n composition?: CompositionOptions;\n\n /** The structure and navigation the shell's regions show and the items' destinations resolve against. */\n navigationModel: SceneNavigationModel;\n\n registry: ComponentRegistry;\n\n /** The screen shown first. */\n initialScreen: string;\n\n /** Where entries are recorded: the address bar for Stage, an in-memory history for a preview, which never touches the host's URL (PRV4). */\n history?: SceneHistory;\n\n /** What the screens' bindings resolve against. */\n resolveBinding?: BindingResolver;\n queryResults?: Record<string, unknown>;\n\n /**\n * Draws the composed screen. The default renders it with `SceneElementView`; Stage wraps it with its data and command scope.\n * @param element The composed screen.\n * @param configuration What the screen's templates were configured with.\n * @param navigation Where the user is.\n */\n renderScreen?(element: SceneElement, configuration: EffectiveConfiguration | undefined, navigation: SceneNavigationContextValue): ReactNode;\n\n /**\n * Draws what the open dialog shows when the document has no dialog template of that name - a toolbar slice button's task\n * dialog by default.\n */\n renderDialog?(navigation: SceneNavigationContextValue): ReactNode;\n\n /**\n * Draws a dialog the document declares, in place of the host's plain one - a host that wants its own backdrop, a close button\n * and keyboard handling around the template's content. Called inside {@link scope}.\n * @param template The dialog template that is open.\n * @param content The template's composed content.\n * @param navigation Where the user is.\n */\n renderDialogTemplate?(template: DialogTemplate, content: SceneElement, navigation: SceneNavigationContextValue): ReactNode;\n\n /**\n * What a host provides around everything that renders - the screen on the page and the dialog over it: its data, its command\n * dispatcher, its chrome state. Inside the navigation providers, so it can read where the user is. Stage puts its data and\n * interaction scope here, so the screen, a dialog template and a slice dialog all share them.\n * @param navigation Where the user is.\n * @param children The screen and the dialog.\n */\n scope?(navigation: SceneNavigationContextValue, children: ReactNode): ReactNode;\n\n /**\n * Where the shell keeps its layout configuration - the sidebar's state, the chosen theme. A preview keeps none (null, the default);\n * a running application passes its storage so what a user chose is still chosen on the next visit.\n */\n layoutConfigStorage?: Storage | null;\n\n /** Rendered inside the host's providers, after the application. */\n children?: ReactNode;\n}\n\n/**\n * The application as both Stage and the preview host run it: the shell composed for the screen on the page\n * (`composeApplicationScreen`), nested outlets holding the screens placed in them, the navigation model in scope for the shell's\n * topbar and sidebar regions, every destination the document and the navigation lead to routed, and the dialog a toolbar slice\n * button or a dialog destination opened shown over it - one place for all of it (spec PRV9), so a behaviour that differs between\n * the two hosts is a bug in the host, not a second implementation.\n */\nexport function ApplicationHost({ application, composition = {}, navigationModel, registry: hostRegistry, initialScreen, history, resolveBinding, queryResults, renderScreen, renderDialog, renderDialogTemplate, scope, layoutConfigStorage = null, children }: ApplicationHostProps) {\n const [memoryHistory] = useState(() => createMemorySceneHistory());\n const registry = useMemo(() => ({ ...previewComponents, ...hostRegistry }), [hostRegistry]);\n const hostHistory = history ?? memoryHistory;\n const screens = application.screens;\n\n const outletScreens = useMemo(\n () => Object.fromEntries(screens.map(candidate => [candidate.name, composeOutletScreen(application, candidate, composition)])),\n [application, composition, screens]);\n const owners = useMemo(() => collectOutletOwners(outletScreens), [outletScreens]);\n const destinations = useMemo(\n () => [...collectDestinations(application), ...navigationDestinations(navigationModel.structure, navigationModel.navigation, navigationModel.screenFor)],\n [application, navigationModel]);\n const routes = useMemo(() => sceneRoutesFrom(screens.map(candidate => candidate.name), destinations), [destinations, screens]);\n const bindingScope = useMemo<BindingScope>(() => ({ queryResults }), [queryResults]);\n const navigation = useSceneHistoryNavigation(hostHistory, routes, initialScreen, bindingScope, owners, destinations);\n\n const screen = screens.find(candidate => candidate.name === navigation.primaryScreen) ?? screens.find(candidate => candidate.name === initialScreen) ?? screens[0];\n const composed = useMemo(() => screen ? composeApplicationScreen(application, screen, composition) : undefined, [application, composition, screen]);\n const outletContext = useMemo(() => ({ screens: outletScreens, registry }), [outletScreens, registry]);\n\n const dialogTemplate = navigation.currentDialog ? application.dialogTemplates?.find(candidate => candidate.name === navigation.currentDialog) : undefined;\n const sliceDialog = !dialogTemplate && navigation.currentDialog && sliceDialogParameters(navigation.currentDialogParameters) !== undefined;\n const dialogName = sliceDialogParameters(navigation.currentDialogParameters)?.title ?? navigation.currentDialog;\n\n const dialogContent = dialogTemplate ? composeDialog(application, dialogTemplate, composition) : undefined;\n\n const body = (\n <>\n <div data-scene-outlet='primary' data-scene-url={navigation.currentUrl} data-scene-screen={navigation.primaryScreen}>\n {composed && <Drawn>{renderScreen\n ? () => renderScreen(composed.element, composed.configuration, navigation)\n : () => <SceneElementView element={composed.element} registry={registry} resolveBinding={resolveBinding} queryResults={queryResults} configuration={composed.configuration} />}</Drawn>}\n </div>\n {dialogTemplate && dialogContent && (renderDialogTemplate\n ? <Drawn>{() => renderDialogTemplate(dialogTemplate, dialogContent, navigation)}</Drawn>\n : (\n <div role='dialog' aria-modal='true' aria-label={dialogName} data-scene-dialog={navigation.currentDialog}>\n <SceneElementView element={dialogContent} registry={registry} resolveBinding={resolveBinding} queryResults={queryResults} />\n </div>\n ))}\n {sliceDialog && (\n <div role='dialog' aria-modal='true' aria-label={dialogName} data-scene-dialog={navigation.currentDialog}>\n {renderDialog?.(navigation) ?? <SliceDialogView />}\n </div>\n )}\n </>\n );\n\n return (\n <SceneNavigationProvider value={navigation}>\n <SceneOutletContext.Provider value={outletContext}>\n <SceneNavigationModelProvider model={navigationModel}>\n {/* The shell reads its layout configuration from a provider; nothing is saved unless the host gives it somewhere to. */}\n <LayoutConfigProvider storage={layoutConfigStorage}>\n {scope ? scope(navigation, body) : body}\n {children}\n </LayoutConfigProvider>\n </SceneNavigationModelProvider>\n </SceneOutletContext.Provider>\n </SceneNavigationProvider>\n );\n}\n\n/** Calls what a host draws as part of this component, so a hook it uses runs under the providers the host put in scope. */\nfunction Drawn({ children }: { children(): ReactNode }) {\n return <>{children()}</>;\n}\n"],"names":["ApplicationHost","application","composition","navigationModel","registry","hostRegistry","initialScreen","history","resolveBinding","queryResults","renderScreen","renderDialog","renderDialogTemplate","scope","layoutConfigStorage","children","memoryHistory","useState","createMemorySceneHistory","useMemo","previewComponents","hostHistory","screens","outletScreens","Object","fromEntries","map","candidate","name","composeOutletScreen","owners","collectOutletOwners","destinations","collectDestinations","navigationDestinations","structure","navigation","screenFor","routes","sceneRoutesFrom","bindingScope","useSceneHistoryNavigation","screen","find","primaryScreen","composed","composeApplicationScreen","undefined","outletContext","dialogTemplate","currentDialog","dialogTemplates","sliceDialog","sliceDialogParameters","currentDialogParameters","dialogName","title","dialogContent","composeDialog","body","_jsxs","_Fragment","_jsx","div","data-scene-outlet","data-scene-url","currentUrl","data-scene-screen","Drawn","element","configuration","SceneElementView","role","aria-modal","aria-label","data-scene-dialog","SliceDialogView","SceneNavigationProvider","value","SceneOutletContext","Provider","SceneNavigationModelProvider","model","LayoutConfigProvider","storage"],"mappings":"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"}
|