@cratis/scene.react 3.7.0 → 4.1.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/core/CoreButton.tsx +2 -2
- package/dist/cjs/SceneElementView.js +2 -0
- package/dist/cjs/SceneElementView.js.map +1 -1
- package/dist/cjs/core/CoreButton.js +2 -1
- package/dist/cjs/core/CoreButton.js.map +1 -1
- package/dist/cjs/index.js +18 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/interactions/ConfirmHost.js +71 -0
- package/dist/cjs/interactions/ConfirmHost.js.map +1 -0
- package/dist/cjs/interactions/InteractionScope.js +74 -0
- package/dist/cjs/interactions/InteractionScope.js.map +1 -0
- package/dist/cjs/interactions/NotificationHost.js +73 -0
- package/dist/cjs/interactions/NotificationHost.js.map +1 -0
- package/dist/cjs/interactions/UnresolvedActionHost.js +53 -0
- package/dist/cjs/interactions/UnresolvedActionHost.js.map +1 -0
- package/dist/cjs/interactions/createBrowserDispatcher.js +102 -0
- package/dist/cjs/interactions/createBrowserDispatcher.js.map +1 -0
- package/dist/cjs/interactions/useInteractionHosts.js +109 -0
- package/dist/cjs/interactions/useInteractionHosts.js.map +1 -0
- package/dist/cjs/interactions/useInteractions.js +122 -0
- package/dist/cjs/interactions/useInteractions.js.map +1 -0
- package/dist/cjs/renderer/InteractiveComponent.js +26 -0
- package/dist/cjs/renderer/InteractiveComponent.js.map +1 -0
- package/dist/cjs/renderer/createReactRenderer.js +3 -1
- package/dist/cjs/renderer/createReactRenderer.js.map +1 -1
- package/dist/esm/SceneElementView.js +2 -0
- package/dist/esm/SceneElementView.js.map +1 -1
- package/dist/esm/core/CoreButton.d.ts +1 -1
- package/dist/esm/core/CoreButton.d.ts.map +1 -1
- package/dist/esm/core/CoreButton.js +2 -1
- package/dist/esm/core/CoreButton.js.map +1 -1
- package/dist/esm/for_useInteractionHosts/when_a_document_asks_the_user_something.d.ts +2 -0
- package/dist/esm/for_useInteractionHosts/when_a_document_asks_the_user_something.d.ts.map +1 -0
- package/dist/esm/for_useInteractionHosts/when_a_document_asks_the_user_something.js +73 -0
- package/dist/esm/for_useInteractionHosts/when_a_document_asks_the_user_something.js.map +1 -0
- package/dist/esm/for_useInteractionHosts/when_the_host_cannot_do_what_was_asked.d.ts +2 -0
- package/dist/esm/for_useInteractionHosts/when_the_host_cannot_do_what_was_asked.d.ts.map +1 -0
- package/dist/esm/for_useInteractionHosts/when_the_host_cannot_do_what_was_asked.js +43 -0
- package/dist/esm/for_useInteractionHosts/when_the_host_cannot_do_what_was_asked.js.map +1 -0
- package/dist/esm/for_useInteractions/when_clicking_an_element_that_executes_a_command.d.ts +2 -0
- package/dist/esm/for_useInteractions/when_clicking_an_element_that_executes_a_command.d.ts.map +1 -0
- package/dist/esm/for_useInteractions/when_clicking_an_element_that_executes_a_command.js +94 -0
- package/dist/esm/for_useInteractions/when_clicking_an_element_that_executes_a_command.js.map +1 -0
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +8 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/interactions/ConfirmHost.d.ts +8 -0
- package/dist/esm/interactions/ConfirmHost.d.ts.map +1 -0
- package/dist/esm/interactions/ConfirmHost.js +69 -0
- package/dist/esm/interactions/ConfirmHost.js.map +1 -0
- package/dist/esm/interactions/ConfirmRequest.d.ts +5 -0
- package/dist/esm/interactions/ConfirmRequest.d.ts.map +1 -0
- package/dist/esm/interactions/ConfirmRequest.js +2 -0
- package/dist/esm/interactions/ConfirmRequest.js.map +1 -0
- package/dist/esm/interactions/InteractionScope.d.ts +17 -0
- package/dist/esm/interactions/InteractionScope.d.ts.map +1 -0
- package/dist/esm/interactions/InteractionScope.js +70 -0
- package/dist/esm/interactions/InteractionScope.js.map +1 -0
- package/dist/esm/interactions/NotificationHost.d.ts +7 -0
- package/dist/esm/interactions/NotificationHost.d.ts.map +1 -0
- package/dist/esm/interactions/NotificationHost.js +71 -0
- package/dist/esm/interactions/NotificationHost.js.map +1 -0
- package/dist/esm/interactions/SceneNotification.d.ts +7 -0
- package/dist/esm/interactions/SceneNotification.d.ts.map +1 -0
- package/dist/esm/interactions/SceneNotification.js +2 -0
- package/dist/esm/interactions/SceneNotification.js.map +1 -0
- package/dist/esm/interactions/UnresolvedAction.d.ts +5 -0
- package/dist/esm/interactions/UnresolvedAction.d.ts.map +1 -0
- package/dist/esm/interactions/UnresolvedAction.js +2 -0
- package/dist/esm/interactions/UnresolvedAction.js.map +1 -0
- package/dist/esm/interactions/UnresolvedActionHost.d.ts +6 -0
- package/dist/esm/interactions/UnresolvedActionHost.d.ts.map +1 -0
- package/dist/esm/interactions/UnresolvedActionHost.js +51 -0
- package/dist/esm/interactions/UnresolvedActionHost.js.map +1 -0
- package/dist/esm/interactions/createBrowserDispatcher.d.ts +17 -0
- package/dist/esm/interactions/createBrowserDispatcher.d.ts.map +1 -0
- package/dist/esm/interactions/createBrowserDispatcher.js +100 -0
- package/dist/esm/interactions/createBrowserDispatcher.js.map +1 -0
- package/dist/esm/interactions/index.d.ts +11 -0
- package/dist/esm/interactions/index.d.ts.map +1 -0
- package/dist/esm/interactions/index.js +11 -0
- package/dist/esm/interactions/index.js.map +1 -0
- package/dist/esm/interactions/useInteractionHosts.d.ts +11 -0
- package/dist/esm/interactions/useInteractionHosts.d.ts.map +1 -0
- package/dist/esm/interactions/useInteractionHosts.js +107 -0
- package/dist/esm/interactions/useInteractionHosts.js.map +1 -0
- package/dist/esm/interactions/useInteractions.d.ts +16 -0
- package/dist/esm/interactions/useInteractions.d.ts.map +1 -0
- package/dist/esm/interactions/useInteractions.js +120 -0
- package/dist/esm/interactions/useInteractions.js.map +1 -0
- package/dist/esm/renderer/ComponentRegistry.d.ts +2 -0
- package/dist/esm/renderer/ComponentRegistry.d.ts.map +1 -1
- package/dist/esm/renderer/InteractiveComponent.d.ts +10 -0
- package/dist/esm/renderer/InteractiveComponent.d.ts.map +1 -0
- package/dist/esm/renderer/InteractiveComponent.js +24 -0
- package/dist/esm/renderer/InteractiveComponent.js.map +1 -0
- package/dist/esm/renderer/createReactRenderer.d.ts.map +1 -1
- package/dist/esm/renderer/createReactRenderer.js +3 -1
- package/dist/esm/renderer/createReactRenderer.js.map +1 -1
- package/dist/esm/renderer/index.d.ts +1 -0
- package/dist/esm/renderer/index.d.ts.map +1 -1
- package/dist/esm/renderer/index.js +1 -0
- package/dist/esm/renderer/index.js.map +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/for_useInteractionHosts/when_a_document_asks_the_user_something.tsx +106 -0
- package/for_useInteractionHosts/when_the_host_cannot_do_what_was_asked.tsx +66 -0
- package/for_useInteractions/when_clicking_an_element_that_executes_a_command.tsx +141 -0
- package/index.ts +1 -0
- package/interactions/ConfirmHost.tsx +42 -0
- package/interactions/ConfirmRequest.ts +19 -0
- package/interactions/InteractionScope.tsx +94 -0
- package/interactions/NotificationHost.tsx +48 -0
- package/interactions/SceneNotification.ts +18 -0
- package/interactions/UnresolvedAction.ts +17 -0
- package/interactions/UnresolvedActionHost.tsx +33 -0
- package/interactions/createBrowserDispatcher.ts +160 -0
- package/interactions/index.ts +13 -0
- package/interactions/useInteractionHosts.tsx +101 -0
- package/interactions/useInteractions.ts +116 -0
- package/package.json +5 -5
- package/renderer/ComponentRegistry.ts +11 -0
- package/renderer/InteractiveComponent.tsx +25 -0
- package/renderer/createReactRenderer.tsx +2 -1
- package/renderer/index.ts +1 -0
package/core/CoreButton.tsx
CHANGED
|
@@ -6,10 +6,10 @@ import { RegisteredComponentProps } from '../renderer';
|
|
|
6
6
|
/**
|
|
7
7
|
* The `core:button` component - part of the minimum vocabulary a `ui profile` can always fall back to.
|
|
8
8
|
*/
|
|
9
|
-
export function CoreButton({ element, slots }: RegisteredComponentProps) {
|
|
9
|
+
export function CoreButton({ element, slots, interactions }: RegisteredComponentProps) {
|
|
10
10
|
const label = typeof element.properties.label === 'string' ? element.properties.label : '';
|
|
11
11
|
return (
|
|
12
|
-
<button type="button" data-scene-id={element.id}>
|
|
12
|
+
<button type="button" data-scene-id={element.id} {...interactions}>
|
|
13
13
|
{label}
|
|
14
14
|
{slots.content}
|
|
15
15
|
</button>
|
|
@@ -4,6 +4,8 @@ var jsxRuntime = require('react/jsx-runtime');
|
|
|
4
4
|
var react = require('react');
|
|
5
5
|
var scene_engine = require('@cratis/scene.engine');
|
|
6
6
|
var createReactRenderer = require('./renderer/createReactRenderer.js');
|
|
7
|
+
require('./interactions/useInteractions.js');
|
|
8
|
+
require('./interactions/NotificationHost.js');
|
|
7
9
|
|
|
8
10
|
/**
|
|
9
11
|
* Renders a Scene element tree with the real `Scene.React` renderer - the WYSIWYG building block Studio's
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SceneElementView.js","sources":["../../SceneElementView.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 { useMemo } from 'react';\nimport { renderElement, BindingResolver } from '@cratis/scene.engine';\nimport { SceneElement } from '@cratis/scene.model';\nimport { ComponentRegistry, createReactRenderer } from './renderer';\n\nexport interface SceneElementViewProps {\n element: SceneElement;\n registry: ComponentRegistry;\n resolveBinding: BindingResolver;\n}\n\n/**\n * Renders a Scene element tree with the real `Scene.React` renderer - the WYSIWYG building block Studio's\n * preview surface and Stage's shipped web bundle both consume unmodified.\n */\nexport function SceneElementView({ element, registry, resolveBinding }: SceneElementViewProps) {\n const renderer = useMemo(() => createReactRenderer(registry), [registry]);\n return <>{renderElement(element, renderer, resolveBinding)}</>;\n}\n"],"names":["SceneElementView","element","registry","resolveBinding","renderer","useMemo","createReactRenderer","_jsx","_Fragment","renderElement"],"mappings":"
|
|
1
|
+
{"version":3,"file":"SceneElementView.js","sources":["../../SceneElementView.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 { useMemo } from 'react';\nimport { renderElement, BindingResolver } from '@cratis/scene.engine';\nimport { SceneElement } from '@cratis/scene.model';\nimport { ComponentRegistry, createReactRenderer } from './renderer';\n\nexport interface SceneElementViewProps {\n element: SceneElement;\n registry: ComponentRegistry;\n resolveBinding: BindingResolver;\n}\n\n/**\n * Renders a Scene element tree with the real `Scene.React` renderer - the WYSIWYG building block Studio's\n * preview surface and Stage's shipped web bundle both consume unmodified.\n */\nexport function SceneElementView({ element, registry, resolveBinding }: SceneElementViewProps) {\n const renderer = useMemo(() => createReactRenderer(registry), [registry]);\n return <>{renderElement(element, renderer, resolveBinding)}</>;\n}\n"],"names":["SceneElementView","element","registry","resolveBinding","renderer","useMemo","createReactRenderer","_jsx","_Fragment","renderElement"],"mappings":";;;;;;;;;AAcA;;;IAIO,SAASA,gBAAAA,CAAiB,EAAEC,OAAO,EAAEC,QAAQ,EAAEC,cAAc,EAAyB,EAAA;AACzF,IAAA,MAAMC,QAAAA,GAAWC,aAAAA,CAAQ,IAAMC,uCAAAA,CAAoBJ,QAAAA,CAAAA,EAAW;AAACA,QAAAA;AAAS,KAAA,CAAA;IACxE,qBAAOK,cAAA,CAAAC,mBAAA,EAAA;AAAGC,QAAAA,QAAAA,EAAAA,0BAAAA,CAAcR,SAASG,QAAAA,EAAUD,cAAAA;;AAC/C;;"}
|
|
@@ -6,11 +6,12 @@ var jsxRuntime = require('react/jsx-runtime');
|
|
|
6
6
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
7
7
|
/**
|
|
8
8
|
* The `core:button` component - part of the minimum vocabulary a `ui profile` can always fall back to.
|
|
9
|
-
*/ function CoreButton({ element, slots }) {
|
|
9
|
+
*/ function CoreButton({ element, slots, interactions }) {
|
|
10
10
|
const label = typeof element.properties.label === 'string' ? element.properties.label : '';
|
|
11
11
|
return /*#__PURE__*/ jsxRuntime.jsxs("button", {
|
|
12
12
|
type: "button",
|
|
13
13
|
"data-scene-id": element.id,
|
|
14
|
+
...interactions,
|
|
14
15
|
children: [
|
|
15
16
|
label,
|
|
16
17
|
slots.content
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CoreButton.js","sources":["../../../core/CoreButton.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 { RegisteredComponentProps } from '../renderer';\n\n/**\n * The `core:button` component - part of the minimum vocabulary a `ui profile` can always fall back to.\n */\nexport function CoreButton({ element, slots }: RegisteredComponentProps) {\n const label = typeof element.properties.label === 'string' ? element.properties.label : '';\n return (\n <button type=\"button\" data-scene-id={element.id}>\n {label}\n {slots.content}\n </button>\n );\n}\n"],"names":["CoreButton","element","slots","label","properties","_jsxs","button","type","data-scene-id","id","content"],"mappings":";;;;AAAA;AACA;AAIA;;
|
|
1
|
+
{"version":3,"file":"CoreButton.js","sources":["../../../core/CoreButton.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 { RegisteredComponentProps } from '../renderer';\n\n/**\n * The `core:button` component - part of the minimum vocabulary a `ui profile` can always fall back to.\n */\nexport function CoreButton({ element, slots, interactions }: RegisteredComponentProps) {\n const label = typeof element.properties.label === 'string' ? element.properties.label : '';\n return (\n <button type=\"button\" data-scene-id={element.id} {...interactions}>\n {label}\n {slots.content}\n </button>\n );\n}\n"],"names":["CoreButton","element","slots","interactions","label","properties","_jsxs","button","type","data-scene-id","id","content"],"mappings":";;;;AAAA;AACA;AAIA;;IAGO,SAASA,UAAAA,CAAW,EAAEC,OAAO,EAAEC,KAAK,EAAEC,YAAY,EAA4B,EAAA;AACjF,IAAA,MAAMC,KAAAA,GAAQ,OAAOH,OAAAA,CAAQI,UAAU,CAACD,KAAK,KAAK,QAAA,GAAWH,OAAAA,CAAQI,UAAU,CAACD,KAAK,GAAG,EAAA;AACxF,IAAA,qBACIE,eAAA,CAACC,QAAAA,EAAAA;QAAOC,IAAAA,EAAK,QAAA;AAASC,QAAAA,eAAAA,EAAeR,QAAQS,EAAE;AAAG,QAAA,GAAGP,YAAY;;AAC5DC,YAAAA,KAAAA;AACAF,YAAAA,KAAAA,CAAMS;;;AAGnB;;"}
|
package/dist/cjs/index.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
var SceneElementView = require('./SceneElementView.js');
|
|
4
4
|
var UnresolvedComponent = require('./renderer/UnresolvedComponent.js');
|
|
5
5
|
var createReactRenderer = require('./renderer/createReactRenderer.js');
|
|
6
|
+
var InteractiveComponent = require('./renderer/InteractiveComponent.js');
|
|
6
7
|
var CoreText = require('./core/CoreText.js');
|
|
7
8
|
var CoreButton = require('./core/CoreButton.js');
|
|
8
9
|
var CoreCard = require('./core/CoreCard.js');
|
|
@@ -14,12 +15,20 @@ var extractNavigationItem = require('./NavBar/extractNavigationItem.js');
|
|
|
14
15
|
var ScenePackageBundle = require('./packages/ScenePackageBundle.js');
|
|
15
16
|
var themeTokens = require('./theme/themeTokens.js');
|
|
16
17
|
var SceneThemeProvider = require('./theme/SceneThemeProvider.js');
|
|
18
|
+
var InteractionScope = require('./interactions/InteractionScope.js');
|
|
19
|
+
var useInteractions = require('./interactions/useInteractions.js');
|
|
20
|
+
var createBrowserDispatcher = require('./interactions/createBrowserDispatcher.js');
|
|
21
|
+
var ConfirmHost = require('./interactions/ConfirmHost.js');
|
|
22
|
+
var NotificationHost = require('./interactions/NotificationHost.js');
|
|
23
|
+
var UnresolvedActionHost = require('./interactions/UnresolvedActionHost.js');
|
|
24
|
+
var useInteractionHosts = require('./interactions/useInteractionHosts.js');
|
|
17
25
|
|
|
18
26
|
|
|
19
27
|
|
|
20
28
|
exports.SceneElementView = SceneElementView.SceneElementView;
|
|
21
29
|
exports.UnresolvedComponent = UnresolvedComponent.UnresolvedComponent;
|
|
22
30
|
exports.createReactRenderer = createReactRenderer.createReactRenderer;
|
|
31
|
+
exports.InteractiveComponent = InteractiveComponent.InteractiveComponent;
|
|
23
32
|
exports.CoreText = CoreText.CoreText;
|
|
24
33
|
exports.CoreButton = CoreButton.CoreButton;
|
|
25
34
|
exports.CoreCard = CoreCard.CoreCard;
|
|
@@ -47,4 +56,13 @@ exports.themeTokenPrefix = themeTokens.themeTokenPrefix;
|
|
|
47
56
|
exports.themeTokenProperty = themeTokens.themeTokenProperty;
|
|
48
57
|
exports.SceneThemeProvider = SceneThemeProvider.SceneThemeProvider;
|
|
49
58
|
exports.useSceneTheme = SceneThemeProvider.useSceneTheme;
|
|
59
|
+
exports.InteractionScope = InteractionScope.InteractionScope;
|
|
60
|
+
exports.attachmentFor = InteractionScope.attachmentFor;
|
|
61
|
+
exports.useInteractionScope = InteractionScope.useInteractionScope;
|
|
62
|
+
exports.useInteractions = useInteractions.useInteractions;
|
|
63
|
+
exports.createBrowserDispatcher = createBrowserDispatcher.createBrowserDispatcher;
|
|
64
|
+
exports.ConfirmHost = ConfirmHost.ConfirmHost;
|
|
65
|
+
exports.NotificationHost = NotificationHost.NotificationHost;
|
|
66
|
+
exports.UnresolvedActionHost = UnresolvedActionHost.UnresolvedActionHost;
|
|
67
|
+
exports.useInteractionHosts = useInteractionHosts.useInteractionHosts;
|
|
50
68
|
//# sourceMappingURL=index.js.map
|
package/dist/cjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
|
|
5
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
6
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
7
|
+
/**
|
|
8
|
+
* Asks what a document's `confirm` asked, in the page rather than in a browser prompt.
|
|
9
|
+
*
|
|
10
|
+
* The browser's own prompt blocks the event loop and cannot be styled or tested, which is why it is the
|
|
11
|
+
* fallback and not this. Declining is the default action, so dismissing the question stops the sequence - a
|
|
12
|
+
* confirm exists to gate what follows it, and a gate that opens when ignored is not one.
|
|
13
|
+
* @param props The {@link ConfirmHostProps}.
|
|
14
|
+
*/ function ConfirmHost({ request, confirmLabel = 'OK', cancelLabel = 'Cancel' }) {
|
|
15
|
+
if (!request) return null;
|
|
16
|
+
return /*#__PURE__*/ jsxRuntime.jsx("div", {
|
|
17
|
+
"data-scene-confirm": true,
|
|
18
|
+
style: {
|
|
19
|
+
position: 'fixed',
|
|
20
|
+
inset: 0,
|
|
21
|
+
display: 'flex',
|
|
22
|
+
alignItems: 'center',
|
|
23
|
+
justifyContent: 'center',
|
|
24
|
+
background: 'rgba(0,0,0,0.35)',
|
|
25
|
+
zIndex: 1100
|
|
26
|
+
},
|
|
27
|
+
children: /*#__PURE__*/ jsxRuntime.jsxs("div", {
|
|
28
|
+
role: "alertdialog",
|
|
29
|
+
"aria-modal": "true",
|
|
30
|
+
"aria-label": request.message,
|
|
31
|
+
style: {
|
|
32
|
+
minWidth: '18rem',
|
|
33
|
+
maxWidth: '28rem',
|
|
34
|
+
padding: '1rem',
|
|
35
|
+
borderRadius: 4,
|
|
36
|
+
background: '#fff',
|
|
37
|
+
color: '#1a1a1a'
|
|
38
|
+
},
|
|
39
|
+
children: [
|
|
40
|
+
/*#__PURE__*/ jsxRuntime.jsx("p", {
|
|
41
|
+
style: {
|
|
42
|
+
margin: '0 0 1rem'
|
|
43
|
+
},
|
|
44
|
+
children: request.message
|
|
45
|
+
}),
|
|
46
|
+
/*#__PURE__*/ jsxRuntime.jsxs("div", {
|
|
47
|
+
style: {
|
|
48
|
+
display: 'flex',
|
|
49
|
+
justifyContent: 'flex-end',
|
|
50
|
+
gap: '0.5rem'
|
|
51
|
+
},
|
|
52
|
+
children: [
|
|
53
|
+
/*#__PURE__*/ jsxRuntime.jsx("button", {
|
|
54
|
+
type: "button",
|
|
55
|
+
onClick: ()=>request.answer(false),
|
|
56
|
+
children: cancelLabel
|
|
57
|
+
}),
|
|
58
|
+
/*#__PURE__*/ jsxRuntime.jsx("button", {
|
|
59
|
+
type: "button",
|
|
60
|
+
onClick: ()=>request.answer(true),
|
|
61
|
+
children: confirmLabel
|
|
62
|
+
})
|
|
63
|
+
]
|
|
64
|
+
})
|
|
65
|
+
]
|
|
66
|
+
})
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
exports.ConfirmHost = ConfirmHost;
|
|
71
|
+
//# sourceMappingURL=ConfirmHost.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConfirmHost.js","sources":["../../../interactions/ConfirmHost.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 { ConfirmRequest } from './ConfirmRequest';\n\n/**\n * The properties of {@link ConfirmHost}.\n */\nexport interface ConfirmHostProps {\n /** The question waiting on an answer, or `undefined` when nothing is being asked. */\n readonly request?: ConfirmRequest;\n\n /** The label on the agreeing choice. */\n readonly confirmLabel?: string;\n\n /** The label on the declining choice. */\n readonly cancelLabel?: string;\n}\n\n/**\n * Asks what a document's `confirm` asked, in the page rather than in a browser prompt.\n *\n * The browser's own prompt blocks the event loop and cannot be styled or tested, which is why it is the\n * fallback and not this. Declining is the default action, so dismissing the question stops the sequence - a\n * confirm exists to gate what follows it, and a gate that opens when ignored is not one.\n * @param props The {@link ConfirmHostProps}.\n */\nexport function ConfirmHost({ request, confirmLabel = 'OK', cancelLabel = 'Cancel' }: ConfirmHostProps) {\n if (!request) return null;\n\n return (\n <div data-scene-confirm style={{ position: 'fixed', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'rgba(0,0,0,0.35)', zIndex: 1100 }}>\n <div role=\"alertdialog\" aria-modal=\"true\" aria-label={request.message} style={{ minWidth: '18rem', maxWidth: '28rem', padding: '1rem', borderRadius: 4, background: '#fff', color: '#1a1a1a' }}>\n <p style={{ margin: '0 0 1rem' }}>{request.message}</p>\n <div style={{ display: 'flex', justifyContent: 'flex-end', gap: '0.5rem' }}>\n <button type=\"button\" onClick={() => request.answer(false)}>{cancelLabel}</button>\n <button type=\"button\" onClick={() => request.answer(true)}>{confirmLabel}</button>\n </div>\n </div>\n </div>\n );\n}\n"],"names":["ConfirmHost","request","confirmLabel","cancelLabel","_jsx","div","data-scene-confirm","style","position","inset","display","alignItems","justifyContent","background","zIndex","_jsxs","role","aria-modal","aria-label","message","minWidth","maxWidth","padding","borderRadius","color","p","margin","gap","button","type","onClick","answer"],"mappings":";;;;AAAA;AACA;AAkBA;;;;;;;IAQO,SAASA,WAAAA,CAAY,EAAEC,OAAO,EAAEC,YAAAA,GAAe,IAAI,EAAEC,WAAAA,GAAc,QAAQ,EAAoB,EAAA;IAClG,IAAI,CAACF,SAAS,OAAO,IAAA;AAErB,IAAA,qBACIG,cAAA,CAACC,KAAAA,EAAAA;QAAIC,oBAAkB,EAAA,IAAA;QAACC,KAAAA,EAAO;YAAEC,QAAAA,EAAU,OAAA;YAASC,KAAAA,EAAO,CAAA;YAAGC,OAAAA,EAAS,MAAA;YAAQC,UAAAA,EAAY,QAAA;YAAUC,cAAAA,EAAgB,QAAA;YAAUC,UAAAA,EAAY,kBAAA;YAAoBC,MAAAA,EAAQ;AAAK,SAAA;AACxK,QAAA,QAAA,gBAAAC,eAAA,CAACV,KAAAA,EAAAA;YAAIW,IAAAA,EAAK,aAAA;YAAcC,YAAAA,EAAW,MAAA;AAAOC,YAAAA,YAAAA,EAAYjB,QAAQkB,OAAO;YAAEZ,KAAAA,EAAO;gBAAEa,QAAAA,EAAU,OAAA;gBAASC,QAAAA,EAAU,OAAA;gBAASC,OAAAA,EAAS,MAAA;gBAAQC,YAAAA,EAAc,CAAA;gBAAGV,UAAAA,EAAY,MAAA;gBAAQW,KAAAA,EAAO;AAAU,aAAA;;8BACzLpB,cAAA,CAACqB,GAAAA,EAAAA;oBAAElB,KAAAA,EAAO;wBAAEmB,MAAAA,EAAQ;AAAW,qBAAA;AAAIzB,oBAAAA,QAAAA,EAAAA,OAAAA,CAAQkB;;8BAC3CJ,eAAA,CAACV,KAAAA,EAAAA;oBAAIE,KAAAA,EAAO;wBAAEG,OAAAA,EAAS,MAAA;wBAAQE,cAAAA,EAAgB,UAAA;wBAAYe,GAAAA,EAAK;AAAS,qBAAA;;sCACrEvB,cAAA,CAACwB,QAAAA,EAAAA;4BAAOC,IAAAA,EAAK,QAAA;4BAASC,OAAAA,EAAS,IAAM7B,OAAAA,CAAQ8B,MAAM,CAAC,KAAA,CAAA;AAAS5B,4BAAAA,QAAAA,EAAAA;;sCAC7DC,cAAA,CAACwB,QAAAA,EAAAA;4BAAOC,IAAAA,EAAK,QAAA;4BAASC,OAAAA,EAAS,IAAM7B,OAAAA,CAAQ8B,MAAM,CAAC,IAAA,CAAA;AAAQ7B,4BAAAA,QAAAA,EAAAA;;;;;;;AAKhF;;"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var react = require('react');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The context a scope uses when it was given none.
|
|
8
|
+
*
|
|
9
|
+
* A document whose messages are literal text and whose actions take no arguments resolves nothing, and that is
|
|
10
|
+
* an ordinary document rather than a degenerate one. Requiring a context anyway would make every host invent
|
|
11
|
+
* an empty resolver, and an invented one is a place for a mistake to hide.
|
|
12
|
+
*/ const resolvesNothing = {
|
|
13
|
+
resolve: ()=>undefined
|
|
14
|
+
};
|
|
15
|
+
const Scope = /*#__PURE__*/ react.createContext(undefined);
|
|
16
|
+
/**
|
|
17
|
+
* Provides the dispatcher, the resolution context and the enclosing attachments to everything beneath it.
|
|
18
|
+
*
|
|
19
|
+
* Attachments nest: a scope inside another scope appends to it rather than replacing it, so an element's
|
|
20
|
+
* enclosing chain is assembled by the tree rather than reconstructed at each leaf. That is what keeps the
|
|
21
|
+
* additive rule true in a renderer - a module's behavior is still in scope at a button six levels down,
|
|
22
|
+
* without the button knowing the module exists.
|
|
23
|
+
*/ function InteractionScope({ children, dispatcher, context = resolvesNothing, attachments, onFindings }) {
|
|
24
|
+
const enclosing = react.useContext(Scope);
|
|
25
|
+
const value = react.useMemo(()=>({
|
|
26
|
+
dispatcher,
|
|
27
|
+
context,
|
|
28
|
+
attachments: [
|
|
29
|
+
...enclosing?.attachments ?? [],
|
|
30
|
+
...attachments
|
|
31
|
+
],
|
|
32
|
+
onFindings: onFindings ?? enclosing?.onFindings
|
|
33
|
+
}), [
|
|
34
|
+
dispatcher,
|
|
35
|
+
context,
|
|
36
|
+
attachments,
|
|
37
|
+
onFindings,
|
|
38
|
+
enclosing
|
|
39
|
+
]);
|
|
40
|
+
return /*#__PURE__*/ jsxRuntime.jsx(Scope.Provider, {
|
|
41
|
+
value: value,
|
|
42
|
+
children: children
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Reads the enclosing interaction scope.
|
|
47
|
+
*
|
|
48
|
+
* @returns The scope, or `undefined` when the tree is rendered without one.
|
|
49
|
+
* @remarks
|
|
50
|
+
* Rendering without a scope is legitimate - a preview surface showing what a screen looks like has nothing to
|
|
51
|
+
* dispatch to - so this answers `undefined` rather than throwing. What must not happen is an element silently
|
|
52
|
+
* appearing interactive when nothing can run; {@link useInteractions} is where that is decided.
|
|
53
|
+
*/ function useInteractionScope() {
|
|
54
|
+
return react.useContext(Scope);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Builds the attachment list for one element, so a caller does not have to know the shape.
|
|
58
|
+
*
|
|
59
|
+
* @param level What is being attached to, used when reporting.
|
|
60
|
+
* @param behaviors The behaviors attached there.
|
|
61
|
+
* @returns The attachment, or an empty list when there are none.
|
|
62
|
+
*/ function attachmentFor(level, behaviors) {
|
|
63
|
+
return behaviors && behaviors.length > 0 ? [
|
|
64
|
+
{
|
|
65
|
+
level,
|
|
66
|
+
behaviors
|
|
67
|
+
}
|
|
68
|
+
] : [];
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
exports.InteractionScope = InteractionScope;
|
|
72
|
+
exports.attachmentFor = attachmentFor;
|
|
73
|
+
exports.useInteractionScope = useInteractionScope;
|
|
74
|
+
//# sourceMappingURL=InteractionScope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InteractionScope.js","sources":["../../../interactions/InteractionScope.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, createContext, useContext, useMemo } from 'react';\nimport { ActionDispatcher, BehaviorAttachment, InteractionContext, InteractionFinding } from '@cratis/scene.engine';\nimport { Behavior } from '@cratis/scene.model';\n\n/**\n * What the elements beneath a scope need in order to run an interaction.\n */\nexport interface InteractionScopeValue {\n /** The seam that performs the effects. */\n dispatcher: ActionDispatcher;\n\n /** How bindings and localization resolve. */\n context: InteractionContext;\n\n /** The attachments enclosing this point, outermost first. */\n attachments: BehaviorAttachment[];\n\n /** Where a finding goes. Absent means nothing is listening, which is itself worth knowing. */\n onFindings?: (findings: InteractionFinding[]) => void;\n}\n\n/**\n * The context a scope uses when it was given none.\n *\n * A document whose messages are literal text and whose actions take no arguments resolves nothing, and that is\n * an ordinary document rather than a degenerate one. Requiring a context anyway would make every host invent\n * an empty resolver, and an invented one is a place for a mistake to hide.\n */\nconst resolvesNothing: InteractionContext = { resolve: () => undefined };\n\nconst Scope = createContext<InteractionScopeValue | undefined>(undefined);\n\n/**\n * The properties of {@link InteractionScope}.\n *\n * The context is the one thing an author may leave out, because a document whose messages are literal text and\n * whose actions take no arguments resolves nothing. Everything beneath a scope still reads a context that is\n * definitely there, so only the author is spared, not the code doing the work.\n */\nexport interface InteractionScopeProps extends Omit<InteractionScopeValue, 'context'> {\n /** How bindings and localization resolve. Omitted means nothing resolves. */\n context?: InteractionContext;\n\n /** What the scope encloses. */\n children: ReactNode;\n}\n\n/**\n * Provides the dispatcher, the resolution context and the enclosing attachments to everything beneath it.\n *\n * Attachments nest: a scope inside another scope appends to it rather than replacing it, so an element's\n * enclosing chain is assembled by the tree rather than reconstructed at each leaf. That is what keeps the\n * additive rule true in a renderer - a module's behavior is still in scope at a button six levels down,\n * without the button knowing the module exists.\n */\nexport function InteractionScope({ children, dispatcher, context = resolvesNothing, attachments, onFindings }: InteractionScopeProps) {\n const enclosing = useContext(Scope);\n\n const value = useMemo<InteractionScopeValue>(() => ({\n dispatcher,\n context,\n attachments: [...(enclosing?.attachments ?? []), ...attachments],\n onFindings: onFindings ?? enclosing?.onFindings,\n }), [dispatcher, context, attachments, onFindings, enclosing]);\n\n return <Scope.Provider value={value}>{children}</Scope.Provider>;\n}\n\n/**\n * Reads the enclosing interaction scope.\n *\n * @returns The scope, or `undefined` when the tree is rendered without one.\n * @remarks\n * Rendering without a scope is legitimate - a preview surface showing what a screen looks like has nothing to\n * dispatch to - so this answers `undefined` rather than throwing. What must not happen is an element silently\n * appearing interactive when nothing can run; {@link useInteractions} is where that is decided.\n */\nexport function useInteractionScope(): InteractionScopeValue | undefined {\n return useContext(Scope);\n}\n\n/**\n * Builds the attachment list for one element, so a caller does not have to know the shape.\n *\n * @param level What is being attached to, used when reporting.\n * @param behaviors The behaviors attached there.\n * @returns The attachment, or an empty list when there are none.\n */\nexport function attachmentFor(level: string, behaviors?: Behavior[]): BehaviorAttachment[] {\n return behaviors && behaviors.length > 0 ? [{ level, behaviors }] : [];\n}\n"],"names":["resolvesNothing","resolve","undefined","Scope","createContext","InteractionScope","children","dispatcher","context","attachments","onFindings","enclosing","useContext","value","useMemo","_jsx","Provider","useInteractionScope","attachmentFor","level","behaviors","length"],"mappings":";;;;;AAwBA;;;;;;AAMC,IACD,MAAMA,eAAAA,GAAsC;AAAEC,IAAAA,OAAAA,EAAS,IAAMC;AAAU,CAAA;AAEvE,MAAMC,sBAAQC,mBAAAA,CAAiDF,SAAAA,CAAAA;AAiB/D;;;;;;;AAOC,IACM,SAASG,gBAAAA,CAAiB,EAAEC,QAAQ,EAAEC,UAAU,EAAEC,OAAAA,GAAUR,eAAe,EAAES,WAAW,EAAEC,UAAU,EAAyB,EAAA;AAChI,IAAA,MAAMC,YAAYC,gBAAAA,CAAWT,KAAAA,CAAAA;IAE7B,MAAMU,KAAAA,GAAQC,aAAAA,CAA+B,KAAO;AAChDP,YAAAA,UAAAA;AACAC,YAAAA,OAAAA;YACAC,WAAAA,EAAa;AAAKE,gBAAAA,GAAAA,SAAAA,EAAWF,eAAe,EAAE;AAAMA,gBAAAA,GAAAA;AAAY,aAAA;AAChEC,YAAAA,UAAAA,EAAYA,cAAcC,SAAAA,EAAWD;AACzC,SAAA,CAAA,EAAI;AAACH,QAAAA,UAAAA;AAAYC,QAAAA,OAAAA;AAASC,QAAAA,WAAAA;AAAaC,QAAAA,UAAAA;AAAYC,QAAAA;AAAU,KAAA,CAAA;IAE7D,qBAAOI,cAAA,CAACZ,MAAMa,QAAQ,EAAA;QAACH,KAAAA,EAAOA,KAAAA;AAAQP,QAAAA,QAAAA,EAAAA;;AAC1C;AAEA;;;;;;;;AAQC,IACM,SAASW,mBAAAA,GAAAA;AACZ,IAAA,OAAOL,gBAAAA,CAAWT,KAAAA,CAAAA;AACtB;AAEA;;;;;;AAMC,IACM,SAASe,aAAAA,CAAcC,KAAa,EAAEC,SAAsB,EAAA;AAC/D,IAAA,OAAOA,SAAAA,IAAaA,SAAAA,CAAUC,MAAM,GAAG,CAAA,GAAI;AAAC,QAAA;AAAEF,YAAAA,KAAAA;AAAOC,YAAAA;AAAU;AAAE,KAAA,GAAG,EAAE;AAC1E;;;;"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var scene_model = require('@cratis/scene.model');
|
|
5
|
+
|
|
6
|
+
const colours = {
|
|
7
|
+
[scene_model.NotificationLevel.Info]: '#1e6fbf',
|
|
8
|
+
[scene_model.NotificationLevel.Warning]: '#b8860b',
|
|
9
|
+
[scene_model.NotificationLevel.Error]: '#c0392b'
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Shows what a document's `notify` asked to say.
|
|
13
|
+
*
|
|
14
|
+
* Deliberately plain. An application with a design system of its own passes its own `notify` to the dispatcher
|
|
15
|
+
* and never renders this; what this exists for is that the default is *something* rather than a console line
|
|
16
|
+
* nobody is looking at.
|
|
17
|
+
* @param props The {@link NotificationHostProps}.
|
|
18
|
+
*/ function NotificationHost({ notifications, onDismiss }) {
|
|
19
|
+
if (notifications.length === 0) return null;
|
|
20
|
+
return /*#__PURE__*/ jsxRuntime.jsx("div", {
|
|
21
|
+
role: "log",
|
|
22
|
+
"aria-live": "polite",
|
|
23
|
+
"data-scene-notifications": true,
|
|
24
|
+
style: {
|
|
25
|
+
position: 'fixed',
|
|
26
|
+
top: '1rem',
|
|
27
|
+
right: '1rem',
|
|
28
|
+
display: 'flex',
|
|
29
|
+
flexDirection: 'column',
|
|
30
|
+
gap: '0.5rem',
|
|
31
|
+
zIndex: 1000
|
|
32
|
+
},
|
|
33
|
+
children: notifications.map((notification)=>/*#__PURE__*/ jsxRuntime.jsxs("div", {
|
|
34
|
+
"data-scene-notification": notification.level,
|
|
35
|
+
style: {
|
|
36
|
+
display: 'flex',
|
|
37
|
+
alignItems: 'center',
|
|
38
|
+
gap: '0.75rem',
|
|
39
|
+
maxWidth: '24rem',
|
|
40
|
+
padding: '0.625rem 0.75rem',
|
|
41
|
+
borderRadius: 4,
|
|
42
|
+
border: `1px solid ${colours[notification.level]}`,
|
|
43
|
+
borderLeftWidth: 4,
|
|
44
|
+
background: '#fff',
|
|
45
|
+
color: '#1a1a1a'
|
|
46
|
+
},
|
|
47
|
+
children: [
|
|
48
|
+
/*#__PURE__*/ jsxRuntime.jsx("span", {
|
|
49
|
+
style: {
|
|
50
|
+
flex: 1
|
|
51
|
+
},
|
|
52
|
+
children: notification.message
|
|
53
|
+
}),
|
|
54
|
+
/*#__PURE__*/ jsxRuntime.jsx("button", {
|
|
55
|
+
type: "button",
|
|
56
|
+
"aria-label": "Dismiss",
|
|
57
|
+
onClick: ()=>onDismiss(notification.id),
|
|
58
|
+
style: {
|
|
59
|
+
border: 'none',
|
|
60
|
+
background: 'none',
|
|
61
|
+
cursor: 'pointer',
|
|
62
|
+
fontSize: '1rem',
|
|
63
|
+
lineHeight: 1
|
|
64
|
+
},
|
|
65
|
+
children: "x"
|
|
66
|
+
})
|
|
67
|
+
]
|
|
68
|
+
}, notification.id))
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
exports.NotificationHost = NotificationHost;
|
|
73
|
+
//# sourceMappingURL=NotificationHost.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NotificationHost.js","sources":["../../../interactions/NotificationHost.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 { NotificationLevel } from '@cratis/scene.model';\nimport { SceneNotification } from './SceneNotification';\n\n/**\n * The properties of {@link NotificationHost}.\n */\nexport interface NotificationHostProps {\n /** What is currently being said, oldest first. */\n readonly notifications: readonly SceneNotification[];\n\n /** Called when one is dismissed. */\n readonly onDismiss: (id: number) => void;\n}\n\nconst colours: Record<NotificationLevel, string> = {\n [NotificationLevel.Info]: '#1e6fbf',\n [NotificationLevel.Warning]: '#b8860b',\n [NotificationLevel.Error]: '#c0392b',\n};\n\n/**\n * Shows what a document's `notify` asked to say.\n *\n * Deliberately plain. An application with a design system of its own passes its own `notify` to the dispatcher\n * and never renders this; what this exists for is that the default is *something* rather than a console line\n * nobody is looking at.\n * @param props The {@link NotificationHostProps}.\n */\nexport function NotificationHost({ notifications, onDismiss }: NotificationHostProps) {\n if (notifications.length === 0) return null;\n\n return (\n <div role=\"log\" aria-live=\"polite\" data-scene-notifications style={{ position: 'fixed', top: '1rem', right: '1rem', display: 'flex', flexDirection: 'column', gap: '0.5rem', zIndex: 1000 }}>\n {notifications.map(notification => (\n <div\n key={notification.id}\n data-scene-notification={notification.level}\n style={{ display: 'flex', alignItems: 'center', gap: '0.75rem', maxWidth: '24rem', padding: '0.625rem 0.75rem', borderRadius: 4, border: `1px solid ${colours[notification.level]}`, borderLeftWidth: 4, background: '#fff', color: '#1a1a1a' }}>\n <span style={{ flex: 1 }}>{notification.message}</span>\n <button type=\"button\" aria-label=\"Dismiss\" onClick={() => onDismiss(notification.id)} style={{ border: 'none', background: 'none', cursor: 'pointer', fontSize: '1rem', lineHeight: 1 }}>x</button>\n </div>\n ))}\n </div>\n );\n}\n"],"names":["colours","NotificationLevel","Info","Warning","Error","NotificationHost","notifications","onDismiss","length","_jsx","div","role","aria-live","data-scene-notifications","style","position","top","right","display","flexDirection","gap","zIndex","map","notification","_jsxs","data-scene-notification","level","alignItems","maxWidth","padding","borderRadius","border","borderLeftWidth","background","color","span","flex","message","button","type","aria-label","onClick","id","cursor","fontSize","lineHeight"],"mappings":";;;;;AAiBA,MAAMA,OAAAA,GAA6C;IAC/C,CAACC,6BAAAA,CAAkBC,IAAI,GAAG,SAAA;IAC1B,CAACD,6BAAAA,CAAkBE,OAAO,GAAG,SAAA;IAC7B,CAACF,6BAAAA,CAAkBG,KAAK,GAAG;AAC/B,CAAA;AAEA;;;;;;;AAOC,IACM,SAASC,gBAAAA,CAAiB,EAAEC,aAAa,EAAEC,SAAS,EAAyB,EAAA;AAChF,IAAA,IAAID,aAAAA,CAAcE,MAAM,KAAK,CAAA,EAAG,OAAO,IAAA;AAEvC,IAAA,qBACIC,cAAA,CAACC,KAAAA,EAAAA;QAAIC,IAAAA,EAAK,KAAA;QAAMC,WAAAA,EAAU,QAAA;QAASC,0BAAwB,EAAA,IAAA;QAACC,KAAAA,EAAO;YAAEC,QAAAA,EAAU,OAAA;YAASC,GAAAA,EAAK,MAAA;YAAQC,KAAAA,EAAO,MAAA;YAAQC,OAAAA,EAAS,MAAA;YAAQC,aAAAA,EAAe,QAAA;YAAUC,GAAAA,EAAK,QAAA;YAAUC,MAAAA,EAAQ;AAAK,SAAA;AACrLf,QAAAA,QAAAA,EAAAA,aAAAA,CAAcgB,GAAG,CAACC,CAAAA,YAAAA,iBACfC,eAAA,CAACd,KAAAA,EAAAA;AAEGe,gBAAAA,yBAAAA,EAAyBF,aAAaG,KAAK;gBAC3CZ,KAAAA,EAAO;oBAAEI,OAAAA,EAAS,MAAA;oBAAQS,UAAAA,EAAY,QAAA;oBAAUP,GAAAA,EAAK,SAAA;oBAAWQ,QAAAA,EAAU,OAAA;oBAASC,OAAAA,EAAS,kBAAA;oBAAoBC,YAAAA,EAAc,CAAA;oBAAGC,MAAAA,EAAQ,CAAC,UAAU,EAAE/B,OAAO,CAACuB,YAAAA,CAAaG,KAAK,CAAC,CAAA,CAAE;oBAAEM,eAAAA,EAAiB,CAAA;oBAAGC,UAAAA,EAAY,MAAA;oBAAQC,KAAAA,EAAO;AAAU,iBAAA;;kCAC9OzB,cAAA,CAAC0B,MAAAA,EAAAA;wBAAKrB,KAAAA,EAAO;4BAAEsB,IAAAA,EAAM;AAAE,yBAAA;AAAIb,wBAAAA,QAAAA,EAAAA,YAAAA,CAAac;;kCACxC5B,cAAA,CAAC6B,QAAAA,EAAAA;wBAAOC,IAAAA,EAAK,QAAA;wBAASC,YAAAA,EAAW,SAAA;wBAAUC,OAAAA,EAAS,IAAMlC,SAAAA,CAAUgB,YAAAA,CAAamB,EAAE,CAAA;wBAAG5B,KAAAA,EAAO;4BAAEiB,MAAAA,EAAQ,MAAA;4BAAQE,UAAAA,EAAY,MAAA;4BAAQU,MAAAA,EAAQ,SAAA;4BAAWC,QAAAA,EAAU,MAAA;4BAAQC,UAAAA,EAAY;AAAE,yBAAA;AAAG,wBAAA,QAAA,EAAA;;;AAJpLtB,aAAAA,EAAAA,YAAAA,CAAamB,EAAE,CAAA;;AASxC;;"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
|
|
5
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
6
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
7
|
+
/**
|
|
8
|
+
* Shows what a document asked for that this host cannot do.
|
|
9
|
+
*
|
|
10
|
+
* Only useful while an application is being built, which is why an application that has wired everything will
|
|
11
|
+
* never see it. It is rendered rather than logged because the person who would fix it is usually looking at
|
|
12
|
+
* the screen and not at the console.
|
|
13
|
+
* @param props The {@link UnresolvedActionHostProps}.
|
|
14
|
+
*/ function UnresolvedActionHost({ unresolved }) {
|
|
15
|
+
if (unresolved.length === 0) return null;
|
|
16
|
+
return /*#__PURE__*/ jsxRuntime.jsxs("div", {
|
|
17
|
+
role: "status",
|
|
18
|
+
"data-scene-unresolved": true,
|
|
19
|
+
style: {
|
|
20
|
+
position: 'fixed',
|
|
21
|
+
bottom: '1rem',
|
|
22
|
+
left: '1rem',
|
|
23
|
+
maxWidth: '28rem',
|
|
24
|
+
padding: '0.625rem 0.75rem',
|
|
25
|
+
borderRadius: 4,
|
|
26
|
+
border: '1px solid #c0392b',
|
|
27
|
+
background: '#fff',
|
|
28
|
+
color: '#1a1a1a',
|
|
29
|
+
zIndex: 1000
|
|
30
|
+
},
|
|
31
|
+
children: [
|
|
32
|
+
/*#__PURE__*/ jsxRuntime.jsx("strong", {
|
|
33
|
+
style: {
|
|
34
|
+
display: 'block',
|
|
35
|
+
marginBottom: '0.25rem'
|
|
36
|
+
},
|
|
37
|
+
children: "This surface cannot do what the document asked"
|
|
38
|
+
}),
|
|
39
|
+
/*#__PURE__*/ jsxRuntime.jsx("ul", {
|
|
40
|
+
style: {
|
|
41
|
+
margin: 0,
|
|
42
|
+
paddingLeft: '1.25rem'
|
|
43
|
+
},
|
|
44
|
+
children: unresolved.map((action)=>/*#__PURE__*/ jsxRuntime.jsx("li", {
|
|
45
|
+
children: action.action
|
|
46
|
+
}, action.id))
|
|
47
|
+
})
|
|
48
|
+
]
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
exports.UnresolvedActionHost = UnresolvedActionHost;
|
|
53
|
+
//# sourceMappingURL=UnresolvedActionHost.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UnresolvedActionHost.js","sources":["../../../interactions/UnresolvedActionHost.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 { UnresolvedAction } from './UnresolvedAction';\n\n/**\n * The properties of {@link UnresolvedActionHost}.\n */\nexport interface UnresolvedActionHostProps {\n /** What has been asked for and could not be done. */\n readonly unresolved: readonly UnresolvedAction[];\n}\n\n/**\n * Shows what a document asked for that this host cannot do.\n *\n * Only useful while an application is being built, which is why an application that has wired everything will\n * never see it. It is rendered rather than logged because the person who would fix it is usually looking at\n * the screen and not at the console.\n * @param props The {@link UnresolvedActionHostProps}.\n */\nexport function UnresolvedActionHost({ unresolved }: UnresolvedActionHostProps) {\n if (unresolved.length === 0) return null;\n\n return (\n <div role=\"status\" data-scene-unresolved style={{ position: 'fixed', bottom: '1rem', left: '1rem', maxWidth: '28rem', padding: '0.625rem 0.75rem', borderRadius: 4, border: '1px solid #c0392b', background: '#fff', color: '#1a1a1a', zIndex: 1000 }}>\n <strong style={{ display: 'block', marginBottom: '0.25rem' }}>This surface cannot do what the document asked</strong>\n <ul style={{ margin: 0, paddingLeft: '1.25rem' }}>\n {unresolved.map(action => <li key={action.id}>{action.action}</li>)}\n </ul>\n </div>\n );\n}\n"],"names":["UnresolvedActionHost","unresolved","length","_jsxs","div","role","data-scene-unresolved","style","position","bottom","left","maxWidth","padding","borderRadius","border","background","color","zIndex","_jsx","strong","display","marginBottom","ul","margin","paddingLeft","map","action","li","id"],"mappings":";;;;AAAA;AACA;AAYA;;;;;;;AAOC,IACM,SAASA,oBAAAA,CAAqB,EAAEC,UAAU,EAA6B,EAAA;AAC1E,IAAA,IAAIA,UAAAA,CAAWC,MAAM,KAAK,CAAA,EAAG,OAAO,IAAA;AAEpC,IAAA,qBACIC,eAAA,CAACC,KAAAA,EAAAA;QAAIC,IAAAA,EAAK,QAAA;QAASC,uBAAqB,EAAA,IAAA;QAACC,KAAAA,EAAO;YAAEC,QAAAA,EAAU,OAAA;YAASC,MAAAA,EAAQ,MAAA;YAAQC,IAAAA,EAAM,MAAA;YAAQC,QAAAA,EAAU,OAAA;YAASC,OAAAA,EAAS,kBAAA;YAAoBC,YAAAA,EAAc,CAAA;YAAGC,MAAAA,EAAQ,mBAAA;YAAqBC,UAAAA,EAAY,MAAA;YAAQC,KAAAA,EAAO,SAAA;YAAWC,MAAAA,EAAQ;AAAK,SAAA;;0BAChPC,cAAA,CAACC,QAAAA,EAAAA;gBAAOZ,KAAAA,EAAO;oBAAEa,OAAAA,EAAS,OAAA;oBAASC,YAAAA,EAAc;AAAU,iBAAA;AAAG,gBAAA,QAAA,EAAA;;0BAC9DH,cAAA,CAACI,IAAAA,EAAAA;gBAAGf,KAAAA,EAAO;oBAAEgB,MAAAA,EAAQ,CAAA;oBAAGC,WAAAA,EAAa;AAAU,iBAAA;AAC1CvB,gBAAAA,QAAAA,EAAAA,UAAAA,CAAWwB,GAAG,CAACC,CAAAA,MAAAA,iBAAUR,cAAA,CAACS,IAAAA,EAAAA;AAAoBD,wBAAAA,QAAAA,EAAAA,MAAAA,CAAOA;AAAnBA,qBAAAA,EAAAA,MAAAA,CAAOE,EAAE,CAAA;;;;AAI5D;;"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
4
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
5
|
+
/**
|
|
6
|
+
* Creates the dispatcher a browser host uses.
|
|
7
|
+
*
|
|
8
|
+
* This is the only place in Scene.React that knows an action has to *happen*. Everything about which actions
|
|
9
|
+
* run and in what order is the engine's, which is why this file is a list of one-line delegations and holds no
|
|
10
|
+
* rules of its own.
|
|
11
|
+
*
|
|
12
|
+
* @param host What the surrounding application can actually do.
|
|
13
|
+
* @returns The {@link ActionDispatcher}.
|
|
14
|
+
*/ function createBrowserDispatcher(host = {}) {
|
|
15
|
+
const unsupported = (action)=>{
|
|
16
|
+
host.onUnsupported?.(action);
|
|
17
|
+
console.warn(`[scene] The host cannot '${action}', so the interaction stopped there.`);
|
|
18
|
+
};
|
|
19
|
+
return {
|
|
20
|
+
async executeCommand (command, args) {
|
|
21
|
+
if (!host.executeCommand) {
|
|
22
|
+
unsupported(`execute ${command}`);
|
|
23
|
+
// Reported as a failure, so the document's own `on failure` runs. Answering success would
|
|
24
|
+
// make a command that never reached a backend look like one that worked.
|
|
25
|
+
return {
|
|
26
|
+
isSuccess: false,
|
|
27
|
+
validationErrors: []
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
return host.executeCommand(command, args);
|
|
31
|
+
},
|
|
32
|
+
navigate (screen, args) {
|
|
33
|
+
if (host.navigate) {
|
|
34
|
+
host.navigate(screen, args);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
unsupported(`navigate to ${screen}`);
|
|
38
|
+
},
|
|
39
|
+
navigateBack () {
|
|
40
|
+
if (host.navigateBack) {
|
|
41
|
+
host.navigateBack();
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
unsupported('navigate back');
|
|
45
|
+
},
|
|
46
|
+
async openDialog (dialogTemplate, args) {
|
|
47
|
+
if (!host.openDialog) {
|
|
48
|
+
unsupported(`open dialog ${dialogTemplate}`);
|
|
49
|
+
return {
|
|
50
|
+
isConfirmed: false
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
return host.openDialog(dialogTemplate, args);
|
|
54
|
+
},
|
|
55
|
+
closeDialog () {
|
|
56
|
+
if (host.closeDialog) {
|
|
57
|
+
host.closeDialog();
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
unsupported('close dialog');
|
|
61
|
+
},
|
|
62
|
+
async refreshQuery (query) {
|
|
63
|
+
if (host.refreshQuery) {
|
|
64
|
+
await host.refreshQuery(query);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
unsupported(`refresh ${query}`);
|
|
68
|
+
},
|
|
69
|
+
setState (target, value) {
|
|
70
|
+
if (host.setState) {
|
|
71
|
+
host.setState(target, value);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
unsupported(`set ${target}`);
|
|
75
|
+
},
|
|
76
|
+
notify (level, message) {
|
|
77
|
+
if (host.notify) {
|
|
78
|
+
host.notify(level, message);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
// The console is a poor notification, but it is a real one - and a host that has not wired
|
|
82
|
+
// notifications yet should still see what the document wanted to say.
|
|
83
|
+
console.log(`[scene:${level}] ${message}`);
|
|
84
|
+
},
|
|
85
|
+
async confirm (message) {
|
|
86
|
+
if (host.confirm) return host.confirm(message);
|
|
87
|
+
// The browser's own prompt is the honest default: a confirm exists to gate what follows, so
|
|
88
|
+
// answering `true` without asking anyone would remove the gate rather than approximate it.
|
|
89
|
+
return typeof globalThis.confirm === 'function' ? globalThis.confirm(message) : false;
|
|
90
|
+
},
|
|
91
|
+
async raise (trigger, args) {
|
|
92
|
+
if (host.raise) {
|
|
93
|
+
await host.raise(trigger, args);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
unsupported(`raise ${trigger}`);
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
exports.createBrowserDispatcher = createBrowserDispatcher;
|
|
102
|
+
//# sourceMappingURL=createBrowserDispatcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createBrowserDispatcher.js","sources":["../../../interactions/createBrowserDispatcher.ts"],"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 { ActionDispatcher, CommandOutcome, DialogOutcome } from '@cratis/scene.engine';\nimport { NotificationLevel } from '@cratis/scene.model';\n\n/**\n * What a host has to supply for an interaction to reach anything real.\n *\n * Every member is optional and every one that is missing is *reported* rather than quietly ignored. A host\n * that cannot execute commands is a legitimate state - a preview surface, a design tool - but a button that\n * appears to work and does nothing is not.\n */\nexport interface BrowserDispatcherHost {\n /** Submits a command. The transport belongs to the host: Scene does not know what a backend is. */\n executeCommand?: (command: string, args: Record<string, unknown>) => Promise<CommandOutcome>;\n\n /** Navigates to a screen. The URL belongs to the host, which is why no route is constructed here. */\n navigate?: (screen: string, args: Record<string, unknown>) => void;\n\n /** Goes back. */\n navigateBack?: () => void;\n\n /** Opens a dialog and answers with what the user did. */\n openDialog?: (dialogTemplate: string, args: Record<string, unknown>) => Promise<DialogOutcome>;\n\n /** Closes the open dialog. */\n closeDialog?: () => void;\n\n /** Re-runs a query. */\n refreshQuery?: (query: string) => Promise<void>;\n\n /** Writes screen state. */\n setState?: (target: string, value: unknown) => void;\n\n /** Surfaces a message. Falls back to the console rather than to nothing. */\n notify?: (level: NotificationLevel, message: string) => void;\n\n /** Asks the user to confirm. Falls back to the browser's own prompt. */\n confirm?: (message: string) => Promise<boolean>;\n\n /** Raises an application trigger. */\n raise?: (trigger: string, args: Record<string, unknown>) => Promise<void>;\n\n /** Where an unsupported action is reported. */\n onUnsupported?: (action: string) => void;\n}\n\n/**\n * Creates the dispatcher a browser host uses.\n *\n * This is the only place in Scene.React that knows an action has to *happen*. Everything about which actions\n * run and in what order is the engine's, which is why this file is a list of one-line delegations and holds no\n * rules of its own.\n *\n * @param host What the surrounding application can actually do.\n * @returns The {@link ActionDispatcher}.\n */\nexport function createBrowserDispatcher(host: BrowserDispatcherHost = {}): ActionDispatcher {\n const unsupported = (action: string) => {\n host.onUnsupported?.(action);\n console.warn(`[scene] The host cannot '${action}', so the interaction stopped there.`);\n };\n\n return {\n async executeCommand(command, args) {\n if (!host.executeCommand) {\n unsupported(`execute ${command}`);\n\n // Reported as a failure, so the document's own `on failure` runs. Answering success would\n // make a command that never reached a backend look like one that worked.\n return { isSuccess: false, validationErrors: [] };\n }\n\n return host.executeCommand(command, args);\n },\n\n navigate(screen, args) {\n if (host.navigate) {\n host.navigate(screen, args);\n return;\n }\n\n unsupported(`navigate to ${screen}`);\n },\n\n navigateBack() {\n if (host.navigateBack) {\n host.navigateBack();\n return;\n }\n\n unsupported('navigate back');\n },\n\n async openDialog(dialogTemplate, args) {\n if (!host.openDialog) {\n unsupported(`open dialog ${dialogTemplate}`);\n return { isConfirmed: false };\n }\n\n return host.openDialog(dialogTemplate, args);\n },\n\n closeDialog() {\n if (host.closeDialog) {\n host.closeDialog();\n return;\n }\n\n unsupported('close dialog');\n },\n\n async refreshQuery(query) {\n if (host.refreshQuery) {\n await host.refreshQuery(query);\n return;\n }\n\n unsupported(`refresh ${query}`);\n },\n\n setState(target, value) {\n if (host.setState) {\n host.setState(target, value);\n return;\n }\n\n unsupported(`set ${target}`);\n },\n\n notify(level, message) {\n if (host.notify) {\n host.notify(level, message);\n return;\n }\n\n // The console is a poor notification, but it is a real one - and a host that has not wired\n // notifications yet should still see what the document wanted to say.\n console.log(`[scene:${level}] ${message}`);\n },\n\n async confirm(message) {\n if (host.confirm) return host.confirm(message);\n\n // The browser's own prompt is the honest default: a confirm exists to gate what follows, so\n // answering `true` without asking anyone would remove the gate rather than approximate it.\n return typeof globalThis.confirm === 'function' ? globalThis.confirm(message) : false;\n },\n\n async raise(trigger, args) {\n if (host.raise) {\n await host.raise(trigger, args);\n return;\n }\n\n unsupported(`raise ${trigger}`);\n },\n };\n}\n"],"names":["createBrowserDispatcher","host","unsupported","action","onUnsupported","console","warn","executeCommand","command","args","isSuccess","validationErrors","navigate","screen","navigateBack","openDialog","dialogTemplate","isConfirmed","closeDialog","refreshQuery","query","setState","target","value","notify","level","message","log","confirm","globalThis","raise","trigger"],"mappings":"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"}
|