@lynx-js/genui 0.0.1-rc.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/LICENSE +202 -0
- package/README.md +170 -0
- package/a2ui/README.md +140 -0
- package/a2ui/dist/catalog/Button/catalog.json +156 -0
- package/a2ui/dist/catalog/Button/index.d.ts +35 -0
- package/a2ui/dist/catalog/Button/index.js +35 -0
- package/a2ui/dist/catalog/Button/index.js.map +1 -0
- package/a2ui/dist/catalog/Card/catalog.json +24 -0
- package/a2ui/dist/catalog/Card/index.d.ts +11 -0
- package/a2ui/dist/catalog/Card/index.js +19 -0
- package/a2ui/dist/catalog/Card/index.js.map +1 -0
- package/a2ui/dist/catalog/CheckBox/catalog.json +170 -0
- package/a2ui/dist/catalog/CheckBox/index.d.ts +32 -0
- package/a2ui/dist/catalog/CheckBox/index.js +24 -0
- package/a2ui/dist/catalog/CheckBox/index.js.map +1 -0
- package/a2ui/dist/catalog/Column/catalog.json +57 -0
- package/a2ui/dist/catalog/Column/index.d.ts +15 -0
- package/a2ui/dist/catalog/Column/index.js +55 -0
- package/a2ui/dist/catalog/Column/index.js.map +1 -0
- package/a2ui/dist/catalog/Divider/catalog.json +14 -0
- package/a2ui/dist/catalog/Divider/index.d.ts +9 -0
- package/a2ui/dist/catalog/Divider/index.js +8 -0
- package/a2ui/dist/catalog/Divider/index.js.map +1 -0
- package/a2ui/dist/catalog/Icon/catalog.json +45 -0
- package/a2ui/dist/catalog/Icon/index.d.ts +14 -0
- package/a2ui/dist/catalog/Icon/index.js +11 -0
- package/a2ui/dist/catalog/Icon/index.js.map +1 -0
- package/a2ui/dist/catalog/Image/catalog.json +62 -0
- package/a2ui/dist/catalog/Image/index.d.ts +16 -0
- package/a2ui/dist/catalog/Image/index.js +30 -0
- package/a2ui/dist/catalog/Image/index.js.map +1 -0
- package/a2ui/dist/catalog/LineChart/catalog.json +98 -0
- package/a2ui/dist/catalog/LineChart/index.d.ts +31 -0
- package/a2ui/dist/catalog/LineChart/index.js +195 -0
- package/a2ui/dist/catalog/LineChart/index.js.map +1 -0
- package/a2ui/dist/catalog/List/catalog.json +52 -0
- package/a2ui/dist/catalog/List/index.d.ts +15 -0
- package/a2ui/dist/catalog/List/index.js +53 -0
- package/a2ui/dist/catalog/List/index.js.map +1 -0
- package/a2ui/dist/catalog/Modal/catalog.json +18 -0
- package/a2ui/dist/catalog/Modal/index.d.ts +12 -0
- package/a2ui/dist/catalog/Modal/index.js +33 -0
- package/a2ui/dist/catalog/Modal/index.js.map +1 -0
- package/a2ui/dist/catalog/PieChart/catalog.json +87 -0
- package/a2ui/dist/catalog/PieChart/index.d.ts +37 -0
- package/a2ui/dist/catalog/PieChart/index.js +131 -0
- package/a2ui/dist/catalog/PieChart/index.js.map +1 -0
- package/a2ui/dist/catalog/RadioGroup/catalog.json +184 -0
- package/a2ui/dist/catalog/RadioGroup/index.d.ts +36 -0
- package/a2ui/dist/catalog/RadioGroup/index.js +36 -0
- package/a2ui/dist/catalog/RadioGroup/index.js.map +1 -0
- package/a2ui/dist/catalog/Row/catalog.json +57 -0
- package/a2ui/dist/catalog/Row/index.d.ts +15 -0
- package/a2ui/dist/catalog/Row/index.js +28 -0
- package/a2ui/dist/catalog/Row/index.js.map +1 -0
- package/a2ui/dist/catalog/Slider/catalog.json +183 -0
- package/a2ui/dist/catalog/Slider/index.d.ts +41 -0
- package/a2ui/dist/catalog/Slider/index.js +39 -0
- package/a2ui/dist/catalog/Slider/index.js.map +1 -0
- package/a2ui/dist/catalog/Slider/utils.d.ts +11 -0
- package/a2ui/dist/catalog/Slider/utils.js +58 -0
- package/a2ui/dist/catalog/Slider/utils.js.map +1 -0
- package/a2ui/dist/catalog/Tabs/catalog.json +28 -0
- package/a2ui/dist/catalog/Tabs/index.d.ts +12 -0
- package/a2ui/dist/catalog/Tabs/index.js +32 -0
- package/a2ui/dist/catalog/Tabs/index.js.map +1 -0
- package/a2ui/dist/catalog/Text/catalog.json +74 -0
- package/a2ui/dist/catalog/Text/index.d.ts +18 -0
- package/a2ui/dist/catalog/Text/index.js +27 -0
- package/a2ui/dist/catalog/Text/index.js.map +1 -0
- package/a2ui/dist/catalog/TextField/catalog.json +147 -0
- package/a2ui/dist/catalog/TextField/index.d.ts +35 -0
- package/a2ui/dist/catalog/TextField/index.js +43 -0
- package/a2ui/dist/catalog/TextField/index.js.map +1 -0
- package/a2ui/dist/catalog/TextField/utils.d.ts +7 -0
- package/a2ui/dist/catalog/TextField/utils.js +51 -0
- package/a2ui/dist/catalog/TextField/utils.js.map +1 -0
- package/a2ui/dist/catalog/defineCatalog.d.ts +119 -0
- package/a2ui/dist/catalog/defineCatalog.js +196 -0
- package/a2ui/dist/catalog/defineCatalog.js.map +1 -0
- package/a2ui/dist/catalog/index.d.ts +20 -0
- package/a2ui/dist/catalog/index.js +26 -0
- package/a2ui/dist/catalog/index.js.map +1 -0
- package/a2ui/dist/catalog/utils/chart.d.ts +3 -0
- package/a2ui/dist/catalog/utils/chart.js +28 -0
- package/a2ui/dist/catalog/utils/chart.js.map +1 -0
- package/a2ui/dist/functions/index.d.ts +19 -0
- package/a2ui/dist/functions/index.js +87 -0
- package/a2ui/dist/functions/index.js.map +1 -0
- package/a2ui/dist/index.d.ts +11 -0
- package/a2ui/dist/index.js +35 -0
- package/a2ui/dist/index.js.map +1 -0
- package/a2ui/dist/react/A2UI.d.ts +77 -0
- package/a2ui/dist/react/A2UI.js +159 -0
- package/a2ui/dist/react/A2UI.js.map +1 -0
- package/a2ui/dist/react/A2UIProvider.d.ts +25 -0
- package/a2ui/dist/react/A2UIProvider.js +20 -0
- package/a2ui/dist/react/A2UIProvider.js.map +1 -0
- package/a2ui/dist/react/A2UIRenderer.d.ts +34 -0
- package/a2ui/dist/react/A2UIRenderer.js +161 -0
- package/a2ui/dist/react/A2UIRenderer.js.map +1 -0
- package/a2ui/dist/react/FormContext.d.ts +10 -0
- package/a2ui/dist/react/FormContext.js +12 -0
- package/a2ui/dist/react/FormContext.js.map +1 -0
- package/a2ui/dist/react/index.d.ts +8 -0
- package/a2ui/dist/react/index.js +23 -0
- package/a2ui/dist/react/index.js.map +1 -0
- package/a2ui/dist/react/useA2UIContext.d.ts +7 -0
- package/a2ui/dist/react/useA2UIContext.js +19 -0
- package/a2ui/dist/react/useA2UIContext.js.map +1 -0
- package/a2ui/dist/react/useAction.d.ts +9 -0
- package/a2ui/dist/react/useAction.js +38 -0
- package/a2ui/dist/react/useAction.js.map +1 -0
- package/a2ui/dist/react/useCatalog.d.ts +7 -0
- package/a2ui/dist/react/useCatalog.js +13 -0
- package/a2ui/dist/react/useCatalog.js.map +1 -0
- package/a2ui/dist/react/useChecks.d.ts +27 -0
- package/a2ui/dist/react/useChecks.js +76 -0
- package/a2ui/dist/react/useChecks.js.map +1 -0
- package/a2ui/dist/react/useDataBinding.d.ts +10 -0
- package/a2ui/dist/react/useDataBinding.js +175 -0
- package/a2ui/dist/react/useDataBinding.js.map +1 -0
- package/a2ui/dist/store/FormController.d.ts +23 -0
- package/a2ui/dist/store/FormController.js +40 -0
- package/a2ui/dist/store/FormController.js.map +1 -0
- package/a2ui/dist/store/FunctionRegistry.d.ts +47 -0
- package/a2ui/dist/store/FunctionRegistry.js +23 -0
- package/a2ui/dist/store/FunctionRegistry.js.map +1 -0
- package/a2ui/dist/store/MessageProcessor.d.ts +28 -0
- package/a2ui/dist/store/MessageProcessor.js +408 -0
- package/a2ui/dist/store/MessageProcessor.js.map +1 -0
- package/a2ui/dist/store/MessageStore.d.ts +38 -0
- package/a2ui/dist/store/MessageStore.js +37 -0
- package/a2ui/dist/store/MessageStore.js.map +1 -0
- package/a2ui/dist/store/Resource.d.ts +45 -0
- package/a2ui/dist/store/Resource.js +80 -0
- package/a2ui/dist/store/Resource.js.map +1 -0
- package/a2ui/dist/store/SignalStore.d.ts +10 -0
- package/a2ui/dist/store/SignalStore.js +29 -0
- package/a2ui/dist/store/SignalStore.js.map +1 -0
- package/a2ui/dist/store/index.d.ts +14 -0
- package/a2ui/dist/store/index.js +15 -0
- package/a2ui/dist/store/index.js.map +1 -0
- package/a2ui/dist/store/payloadNormalizer.d.ts +27 -0
- package/a2ui/dist/store/payloadNormalizer.js +179 -0
- package/a2ui/dist/store/payloadNormalizer.js.map +1 -0
- package/a2ui/dist/store/resolveFunctionCall.d.ts +18 -0
- package/a2ui/dist/store/resolveFunctionCall.js +131 -0
- package/a2ui/dist/store/resolveFunctionCall.js.map +1 -0
- package/a2ui/dist/store/types.d.ts +68 -0
- package/a2ui/dist/store/types.js +2 -0
- package/a2ui/dist/store/types.js.map +1 -0
- package/a2ui/dist/tsconfig.build.tsbuildinfo +1 -0
- package/a2ui/styles/catalog/Button.css +83 -0
- package/a2ui/styles/catalog/Card.css +49 -0
- package/a2ui/styles/catalog/CheckBox.css +46 -0
- package/a2ui/styles/catalog/Column.css +89 -0
- package/a2ui/styles/catalog/Divider.css +20 -0
- package/a2ui/styles/catalog/Icon.css +39 -0
- package/a2ui/styles/catalog/Image.css +54 -0
- package/a2ui/styles/catalog/LineChart.css +116 -0
- package/a2ui/styles/catalog/List.css +38 -0
- package/a2ui/styles/catalog/Modal.css +60 -0
- package/a2ui/styles/catalog/PieChart.css +109 -0
- package/a2ui/styles/catalog/RadioGroup.css +123 -0
- package/a2ui/styles/catalog/Row.css +83 -0
- package/a2ui/styles/catalog/Slider.css +96 -0
- package/a2ui/styles/catalog/Tabs.css +46 -0
- package/a2ui/styles/catalog/Text.css +121 -0
- package/a2ui/styles/catalog/TextField.css +48 -0
- package/a2ui/styles/theme.css +62 -0
- package/a2ui-catalog-extractor/README.md +605 -0
- package/a2ui-catalog-extractor/bin/a2ui-catalog-extractor.js +6 -0
- package/a2ui-catalog-extractor/dist/cli.d.ts +12 -0
- package/a2ui-catalog-extractor/dist/cli.js +171 -0
- package/a2ui-catalog-extractor/dist/cli.js.map +1 -0
- package/a2ui-catalog-extractor/dist/index.d.ts +140 -0
- package/a2ui-catalog-extractor/dist/index.js +755 -0
- package/a2ui-catalog-extractor/dist/index.js.map +1 -0
- package/a2ui-catalog-extractor/dist/tsconfig.build.tsbuildinfo +1 -0
- package/a2ui-catalog-extractor/skills/a2ui-catalog-extractor/SKILL.md +30 -0
- package/a2ui-prompt/README.md +65 -0
- package/a2ui-prompt/dist/index.d.ts +91 -0
- package/a2ui-prompt/dist/index.js +767 -0
- package/cli/README.md +88 -0
- package/cli/bin/cli.js +271 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/index.ts +114 -0
- package/openui/README.md +211 -0
- package/openui/dist/catalog/Action/index.d.ts +20 -0
- package/openui/dist/catalog/Action/index.js +23 -0
- package/openui/dist/catalog/Action/index.js.map +1 -0
- package/openui/dist/catalog/Button/index.d.ts +64 -0
- package/openui/dist/catalog/Button/index.js +75 -0
- package/openui/dist/catalog/Button/index.js.map +1 -0
- package/openui/dist/catalog/Card/index.d.ts +34 -0
- package/openui/dist/catalog/Card/index.js +69 -0
- package/openui/dist/catalog/Card/index.js.map +1 -0
- package/openui/dist/catalog/CardHeader/index.d.ts +5 -0
- package/openui/dist/catalog/CardHeader/index.js +18 -0
- package/openui/dist/catalog/CardHeader/index.js.map +1 -0
- package/openui/dist/catalog/Separator/index.d.ts +2 -0
- package/openui/dist/catalog/Separator/index.js +13 -0
- package/openui/dist/catalog/Separator/index.js.map +1 -0
- package/openui/dist/catalog/Stack/index.d.ts +29 -0
- package/openui/dist/catalog/Stack/index.js +61 -0
- package/openui/dist/catalog/Stack/index.js.map +1 -0
- package/openui/dist/catalog/Tag/index.d.ts +4 -0
- package/openui/dist/catalog/Tag/index.js +15 -0
- package/openui/dist/catalog/Tag/index.js.map +1 -0
- package/openui/dist/catalog/TextContent/index.d.ts +11 -0
- package/openui/dist/catalog/TextContent/index.js +33 -0
- package/openui/dist/catalog/TextContent/index.js.map +1 -0
- package/openui/dist/catalog/index.d.ts +7 -0
- package/openui/dist/catalog/index.js +11 -0
- package/openui/dist/catalog/index.js.map +1 -0
- package/openui/dist/catalog/utils.d.ts +2 -0
- package/openui/dist/catalog/utils.js +17 -0
- package/openui/dist/catalog/utils.js.map +1 -0
- package/openui/dist/core/context.d.ts +112 -0
- package/openui/dist/core/context.js +99 -0
- package/openui/dist/core/context.js.map +1 -0
- package/openui/dist/core/createLibrary.d.ts +10 -0
- package/openui/dist/core/createLibrary.js +36 -0
- package/openui/dist/core/createLibrary.js.map +1 -0
- package/openui/dist/core/hooks/index.d.ts +4 -0
- package/openui/dist/core/hooks/index.js +6 -0
- package/openui/dist/core/hooks/index.js.map +1 -0
- package/openui/dist/core/hooks/useFormValidation.d.ts +13 -0
- package/openui/dist/core/hooks/useFormValidation.js +76 -0
- package/openui/dist/core/hooks/useFormValidation.js.map +1 -0
- package/openui/dist/core/hooks/useOpenUIState.d.ts +33 -0
- package/openui/dist/core/hooks/useOpenUIState.js +413 -0
- package/openui/dist/core/hooks/useOpenUIState.js.map +1 -0
- package/openui/dist/core/hooks/useStateField.d.ts +2 -0
- package/openui/dist/core/hooks/useStateField.js +11 -0
- package/openui/dist/core/hooks/useStateField.js.map +1 -0
- package/openui/dist/core/index.d.ts +7 -0
- package/openui/dist/core/index.js +8 -0
- package/openui/dist/core/index.js.map +1 -0
- package/openui/dist/core/library.d.ts +20 -0
- package/openui/dist/core/library.js +13 -0
- package/openui/dist/core/library.js.map +1 -0
- package/openui/dist/core/renderer.css +271 -0
- package/openui/dist/core/renderer.d.ts +9 -0
- package/openui/dist/core/renderer.js +139 -0
- package/openui/dist/core/renderer.js.map +1 -0
- package/openui/dist/core/utils.d.ts +1 -0
- package/openui/dist/core/utils.js +76 -0
- package/openui/dist/core/utils.js.map +1 -0
- package/package.json +120 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "@lynx-js/react/jsx-runtime";
|
|
2
|
+
// Copyright 2026 The Lynx Authors. All rights reserved.
|
|
3
|
+
// Licensed under the Apache License Version 2.0 that can be found in the
|
|
4
|
+
// LICENSE file in the root directory of this source tree.
|
|
5
|
+
import { memo, useEffect, useMemo, useSyncExternalStore } from '@lynx-js/react';
|
|
6
|
+
import { useA2UIContext } from './useA2UIContext.js';
|
|
7
|
+
import { useAction } from './useAction.js';
|
|
8
|
+
import { useCatalog } from './useCatalog.js';
|
|
9
|
+
import { splitUnsupportedProps, useResolvedProps } from './useDataBinding.js';
|
|
10
|
+
const noop = () => {
|
|
11
|
+
/* no-op subscribe disposer */
|
|
12
|
+
};
|
|
13
|
+
const noopSubscribe = () => noop;
|
|
14
|
+
const emptySnapshot = {
|
|
15
|
+
status: 'pending',
|
|
16
|
+
value: undefined,
|
|
17
|
+
error: undefined,
|
|
18
|
+
};
|
|
19
|
+
const returnEmptySnapshot = () => emptySnapshot;
|
|
20
|
+
const warnedTags = new Set();
|
|
21
|
+
function DefaultLoading(props) {
|
|
22
|
+
const content = `loading ${props.id}...`;
|
|
23
|
+
return (_jsx("view", { style: {
|
|
24
|
+
width: '100%',
|
|
25
|
+
minHeight: '20px',
|
|
26
|
+
padding: '10px',
|
|
27
|
+
border: '1px solid var(--a2ui-color-border)',
|
|
28
|
+
borderRadius: '4px',
|
|
29
|
+
backgroundColor: 'var(--a2ui-color-surface-muted)',
|
|
30
|
+
color: 'var(--a2ui-color-text-muted)',
|
|
31
|
+
}, children: _jsx("text", { style: { color: 'inherit' }, children: content }) }));
|
|
32
|
+
}
|
|
33
|
+
function DefaultUnsupportedNotice(props) {
|
|
34
|
+
return (_jsx("view", { style: {
|
|
35
|
+
width: '100%',
|
|
36
|
+
minHeight: '20px',
|
|
37
|
+
marginBottom: '8px',
|
|
38
|
+
padding: '6px',
|
|
39
|
+
borderRadius: '6px',
|
|
40
|
+
border: '1px dashed var(--a2ui-color-border)',
|
|
41
|
+
backgroundColor: 'var(--a2ui-color-surface-muted)',
|
|
42
|
+
color: 'var(--a2ui-color-text-muted)',
|
|
43
|
+
}, children: _jsxs("text", { style: { color: 'inherit', fontSize: '10px', lineHeight: '12px' }, children: ["Unsupported ", props.kind, " in ", props.id] }) }));
|
|
44
|
+
}
|
|
45
|
+
function buildNodeRecursive(component, surface, catalog, renderUnsupported, props, setValue, sendAction) {
|
|
46
|
+
const tag = component.component;
|
|
47
|
+
const Component = catalog.get(tag);
|
|
48
|
+
const renderUnsupportedNotice = (info) => {
|
|
49
|
+
if (typeof renderUnsupported === 'function') {
|
|
50
|
+
return renderUnsupported(info);
|
|
51
|
+
}
|
|
52
|
+
return _jsx(DefaultUnsupportedNotice, { ...info });
|
|
53
|
+
};
|
|
54
|
+
if (!Component) {
|
|
55
|
+
return renderUnsupportedNotice({
|
|
56
|
+
id: component.id ?? '',
|
|
57
|
+
tag,
|
|
58
|
+
kind: 'component',
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
const { unsupportedFields, displayProps } = splitUnsupportedProps(props);
|
|
62
|
+
return (_jsxs(_Fragment, { children: [unsupportedFields.length > 0
|
|
63
|
+
? (renderUnsupportedNotice({
|
|
64
|
+
id: component.id ?? '',
|
|
65
|
+
tag,
|
|
66
|
+
kind: 'syntax',
|
|
67
|
+
fields: unsupportedFields,
|
|
68
|
+
}))
|
|
69
|
+
: null, _jsx(Component, { ...displayProps, id: component.id ?? '', surface: surface, setValue: setValue, sendAction: (a) => {
|
|
70
|
+
void sendAction?.(a);
|
|
71
|
+
}, dataContextPath: component.dataContextPath }, component.id)] }));
|
|
72
|
+
}
|
|
73
|
+
function A2UIRendererImpl(props) {
|
|
74
|
+
const { resource, renderUnsupported, wrapSurface, renderFallback, renderError, className: surfaceClassName = 'surface-root', } = props;
|
|
75
|
+
// Eagerly read context so the renderer fails clearly outside <A2UIProvider>.
|
|
76
|
+
useCatalog();
|
|
77
|
+
const snapshot = useSyncExternalStore(resource.subscribe, resource.getSnapshot, resource.getSnapshot);
|
|
78
|
+
const data = snapshot.value;
|
|
79
|
+
const status = snapshot.status;
|
|
80
|
+
const error = snapshot.error;
|
|
81
|
+
if (status === 'pending' && data === undefined) {
|
|
82
|
+
// Use a ternary instead of `??` so consumers can return `null` from
|
|
83
|
+
// the override callback to suppress the built-in placeholder.
|
|
84
|
+
return renderFallback
|
|
85
|
+
? renderFallback()
|
|
86
|
+
: _jsx(DefaultLoading, { id: resource.id });
|
|
87
|
+
}
|
|
88
|
+
if (status === 'error') {
|
|
89
|
+
return renderError
|
|
90
|
+
? renderError(error)
|
|
91
|
+
: _jsxs("text", { children: ["Error: ", String(error)] });
|
|
92
|
+
}
|
|
93
|
+
if (!data)
|
|
94
|
+
return null;
|
|
95
|
+
const dataObj = data;
|
|
96
|
+
const type = dataObj['type'];
|
|
97
|
+
const surfaceId = dataObj['surfaceId'];
|
|
98
|
+
const surface = dataObj['surface'];
|
|
99
|
+
const component = dataObj['component'];
|
|
100
|
+
if (type === 'beginRendering') {
|
|
101
|
+
const id = surface.rootComponentId;
|
|
102
|
+
const childResource = surface.resources.get(id);
|
|
103
|
+
if (!childResource)
|
|
104
|
+
return null;
|
|
105
|
+
const childProps = { resource: childResource };
|
|
106
|
+
if (wrapSurface)
|
|
107
|
+
childProps.wrapSurface = wrapSurface;
|
|
108
|
+
if (renderFallback)
|
|
109
|
+
childProps.renderFallback = renderFallback;
|
|
110
|
+
if (renderError)
|
|
111
|
+
childProps.renderError = renderError;
|
|
112
|
+
if (renderUnsupported)
|
|
113
|
+
childProps.renderUnsupported = renderUnsupported;
|
|
114
|
+
const inner = (_jsx("view", { id: `surface-${surfaceId}`, className: surfaceClassName, children: _jsx(A2UIRenderer, { ...childProps }) }));
|
|
115
|
+
return wrapSurface ? wrapSurface(inner, { surfaceId }) : inner;
|
|
116
|
+
}
|
|
117
|
+
if (type === 'surfaceUpdate' && component) {
|
|
118
|
+
return (_jsx(NodeRenderer, { component: component, surface: surface, renderUnsupported: renderUnsupported }));
|
|
119
|
+
}
|
|
120
|
+
if (type === 'deleteSurface') {
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
export const A2UIRenderer = memo(A2UIRendererImpl);
|
|
126
|
+
function NodeRendererImpl(props) {
|
|
127
|
+
const { component: initialComponent, surface, renderUnsupported, } = props;
|
|
128
|
+
const { catalog: activeCatalog, processor } = useA2UIContext();
|
|
129
|
+
const catalog = useCatalog();
|
|
130
|
+
const resource = surface.resources.get(initialComponent.id);
|
|
131
|
+
const latest = useSyncExternalStore(resource ? resource.subscribe : noopSubscribe, resource ? resource.getSnapshot : returnEmptySnapshot, resource ? resource.getSnapshot : returnEmptySnapshot);
|
|
132
|
+
const component = latest.value?.component
|
|
133
|
+
?? initialComponent;
|
|
134
|
+
const effectiveComponent = initialComponent.dataContextPath !== undefined
|
|
135
|
+
&& component.dataContextPath !== initialComponent.dataContextPath
|
|
136
|
+
? { ...component, dataContextPath: initialComponent.dataContextPath }
|
|
137
|
+
: component;
|
|
138
|
+
useEffect(() => {
|
|
139
|
+
const tag = effectiveComponent.component;
|
|
140
|
+
if (!catalog.has(tag) && !warnedTags.has(tag)) {
|
|
141
|
+
warnedTags.add(tag);
|
|
142
|
+
console.warn(`[a2ui] Component "${tag}" is not in the active catalog.`);
|
|
143
|
+
}
|
|
144
|
+
}, [effectiveComponent.component, catalog]);
|
|
145
|
+
const [resolvedProps, setValue] = useResolvedProps(effectiveComponent, surface, effectiveComponent.dataContextPath, processor, activeCatalog.functions);
|
|
146
|
+
const actionProps = useMemo(() => ({
|
|
147
|
+
id: effectiveComponent.id,
|
|
148
|
+
surfaceId: surface.surfaceId,
|
|
149
|
+
dataContext: effectiveComponent.dataContextPath,
|
|
150
|
+
}), [
|
|
151
|
+
effectiveComponent.id,
|
|
152
|
+
surface.surfaceId,
|
|
153
|
+
effectiveComponent.dataContextPath,
|
|
154
|
+
]);
|
|
155
|
+
const { sendAction } = useAction(actionProps);
|
|
156
|
+
return (buildNodeRecursive(effectiveComponent, surface, catalog, renderUnsupported, resolvedProps, setValue, (a) => {
|
|
157
|
+
void sendAction(a);
|
|
158
|
+
}));
|
|
159
|
+
}
|
|
160
|
+
export const NodeRenderer = NodeRendererImpl;
|
|
161
|
+
//# sourceMappingURL=A2UIRenderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"A2UIRenderer.js","sourceRoot":"","sources":["../../src/react/A2UIRenderer.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { createContext } from '@lynx-js/react';
|
|
2
|
+
import type { FormController } from '../store/FormController.js';
|
|
3
|
+
export type { CheckFailure, CheckOutcome, FormController, } from '../store/FormController.js';
|
|
4
|
+
export { createFormController } from '../store/FormController.js';
|
|
5
|
+
/**
|
|
6
|
+
* React context exposing the nearest enclosing form controller, if any.
|
|
7
|
+
* Inputs use it to broadcast their check outcomes; Buttons use it to read
|
|
8
|
+
* `isValid` and disable themselves until every input passes.
|
|
9
|
+
*/
|
|
10
|
+
export declare const FormContext: ReturnType<typeof createContext<FormController | null>>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// Copyright 2026 The Lynx Authors. All rights reserved.
|
|
2
|
+
// Licensed under the Apache License Version 2.0 that can be found in the
|
|
3
|
+
// LICENSE file in the root directory of this source tree.
|
|
4
|
+
import { createContext } from '@lynx-js/react';
|
|
5
|
+
export { createFormController } from '../store/FormController.js';
|
|
6
|
+
/**
|
|
7
|
+
* React context exposing the nearest enclosing form controller, if any.
|
|
8
|
+
* Inputs use it to broadcast their check outcomes; Buttons use it to read
|
|
9
|
+
* `isValid` and disable themselves until every input passes.
|
|
10
|
+
*/
|
|
11
|
+
export const FormContext = createContext(null);
|
|
12
|
+
//# sourceMappingURL=FormContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormContext.js","sourceRoot":"","sources":["../../src/react/FormContext.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,yEAAyE;AACzE,0DAA0D;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAS/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAElE;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAEpB,aAAa,CAAwB,IAAI,CAAC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { A2UI } from './A2UI.js';
|
|
2
|
+
export type { A2UIProps } from './A2UI.js';
|
|
3
|
+
export { NodeRenderer } from './A2UIRenderer.js';
|
|
4
|
+
export { useAction } from './useAction.js';
|
|
5
|
+
export type { ActionProps } from './useAction.js';
|
|
6
|
+
export { useDataBinding, useResolvedProps } from './useDataBinding.js';
|
|
7
|
+
export { useChecks } from './useChecks.js';
|
|
8
|
+
export type { CheckLike } from './useChecks.js';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Copyright 2026 The Lynx Authors. All rights reserved.
|
|
2
|
+
// Licensed under the Apache License Version 2.0 that can be found in the
|
|
3
|
+
// LICENSE file in the root directory of this source tree.
|
|
4
|
+
//
|
|
5
|
+
// Public React surface. `<A2UI>` is the all-in-one component for
|
|
6
|
+
// developers without protocol knowledge. The hooks + `NodeRenderer` are
|
|
7
|
+
// the contract that custom catalog components plug into.
|
|
8
|
+
//
|
|
9
|
+
// `A2UIProvider`, `A2UIRenderer`, `A2UIContext`, `useA2UIContext`, and
|
|
10
|
+
// `useCatalog` are intentionally NOT exported — they're internal details
|
|
11
|
+
// of how `<A2UI>` mounts itself. Custom components don't need them.
|
|
12
|
+
//
|
|
13
|
+
// `FormContext` and `FormController` are also internal. `useChecks` reads
|
|
14
|
+
// from `FormContext` so a follow-up PR can introduce a `<Form>` component
|
|
15
|
+
// that aggregates input validity — exporting the context now would
|
|
16
|
+
// pre-commit the package to a Provider-based API before there's a real
|
|
17
|
+
// consumer to validate it.
|
|
18
|
+
export { A2UI } from './A2UI.js';
|
|
19
|
+
export { NodeRenderer } from './A2UIRenderer.js';
|
|
20
|
+
export { useAction } from './useAction.js';
|
|
21
|
+
export { useDataBinding, useResolvedProps } from './useDataBinding.js';
|
|
22
|
+
export { useChecks } from './useChecks.js';
|
|
23
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,yEAAyE;AACzE,0DAA0D;AAC1D,EAAE;AACF,iEAAiE;AACjE,wEAAwE;AACxE,yDAAyD;AACzD,EAAE;AACF,uEAAuE;AACvE,yEAAyE;AACzE,oEAAoE;AACpE,EAAE;AACF,0EAA0E;AAC1E,0EAA0E;AAC1E,mEAAmE;AACnE,uEAAuE;AACvE,2BAA2B;AAC3B,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { A2UIInternalContext } from './A2UIProvider.js';
|
|
2
|
+
/**
|
|
3
|
+
* Internal helper used by catalog-component hooks (`useAction`, the
|
|
4
|
+
* renderer, …) to reach the `<A2UI>`-owned context. NOT exported from
|
|
5
|
+
* the package.
|
|
6
|
+
*/
|
|
7
|
+
export declare function useA2UIContext(): A2UIInternalContext;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Copyright 2026 The Lynx Authors. All rights reserved.
|
|
2
|
+
// Licensed under the Apache License Version 2.0 that can be found in the
|
|
3
|
+
// LICENSE file in the root directory of this source tree.
|
|
4
|
+
import { useContext } from '@lynx-js/react';
|
|
5
|
+
import { A2UIContext } from './A2UIProvider.js';
|
|
6
|
+
/**
|
|
7
|
+
* Internal helper used by catalog-component hooks (`useAction`, the
|
|
8
|
+
* renderer, …) to reach the `<A2UI>`-owned context. NOT exported from
|
|
9
|
+
* the package.
|
|
10
|
+
*/
|
|
11
|
+
export function useA2UIContext() {
|
|
12
|
+
const ctx = useContext(A2UIContext);
|
|
13
|
+
if (!ctx) {
|
|
14
|
+
throw new Error('[a2ui] Catalog-component hooks must be used inside a tree rendered '
|
|
15
|
+
+ 'by `<A2UI>`.');
|
|
16
|
+
}
|
|
17
|
+
return ctx;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=useA2UIContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useA2UIContext.js","sourceRoot":"","sources":["../../src/react/useA2UIContext.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,yEAAyE;AACzE,0DAA0D;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAE5C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD;;;;GAIG;AACH,MAAM,UAAU,cAAc;IAC5B,MAAM,GAAG,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IACpC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CACb,qEAAqE;cACjE,cAAc,CACnB,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type * as v0_9 from '@a2ui/web_core/v0_9';
|
|
2
|
+
export interface ActionProps {
|
|
3
|
+
id: string;
|
|
4
|
+
surfaceId: string;
|
|
5
|
+
dataContext?: string | undefined;
|
|
6
|
+
}
|
|
7
|
+
export declare function useAction(props: ActionProps): {
|
|
8
|
+
sendAction: (action: v0_9.Action) => Promise<unknown>;
|
|
9
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { useCallback } from '@lynx-js/react';
|
|
2
|
+
import { useA2UIContext } from './useA2UIContext.js';
|
|
3
|
+
import { executeFunctionCall, resolveDynamicValue, } from '../store/resolveFunctionCall.js';
|
|
4
|
+
export function useAction(props) {
|
|
5
|
+
const { id, surfaceId, dataContext } = props;
|
|
6
|
+
const { catalog, processor } = useA2UIContext();
|
|
7
|
+
const sendAction = useCallback((action) => {
|
|
8
|
+
if ('functionCall' in action && action.functionCall) {
|
|
9
|
+
return Promise.resolve(executeFunctionCall(processor, action.functionCall, surfaceId, dataContext, { functions: catalog.functions }));
|
|
10
|
+
}
|
|
11
|
+
let name = 'unknownAction';
|
|
12
|
+
let context = {};
|
|
13
|
+
if ('event' in action && action.event) {
|
|
14
|
+
name = action.event.name;
|
|
15
|
+
const ctx = action.event.context;
|
|
16
|
+
if (ctx) {
|
|
17
|
+
const resolvedContext = {};
|
|
18
|
+
for (const [key, value] of Object.entries(ctx)) {
|
|
19
|
+
resolvedContext[key] = resolveDynamicValue(processor, value, surfaceId, dataContext, { functions: catalog.functions });
|
|
20
|
+
}
|
|
21
|
+
context = resolvedContext;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
const userAction = {
|
|
25
|
+
name,
|
|
26
|
+
surfaceId,
|
|
27
|
+
sourceComponentId: id,
|
|
28
|
+
timestamp: new Date().toISOString(),
|
|
29
|
+
context,
|
|
30
|
+
};
|
|
31
|
+
// Dispatch through the processor — `<A2UI>` listens via
|
|
32
|
+
// `processor.onEvent` and forwards the action to its `onAction`
|
|
33
|
+
// prop, which the developer wires to their agent.
|
|
34
|
+
return processor.dispatch({ userAction });
|
|
35
|
+
}, [id, surfaceId, dataContext, processor, catalog.functions]);
|
|
36
|
+
return { sendAction };
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=useAction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAction.js","sourceRoot":"","sources":["../../src/react/useAction.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EACL,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,iCAAiC,CAAC;AASzC,MAAM,UAAU,SAAS,CACvB,KAAkB;IAElB,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,WAAW,EAAE,GAAG,KAAK,CAAC;IAC7C,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,cAAc,EAAE,CAAC;IAEhD,MAAM,UAAU,GAAG,WAAW,CAC5B,CAAC,MAAmB,EAAE,EAAE;QACtB,IAAI,cAAc,IAAI,MAAM,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;YACpD,OAAO,OAAO,CAAC,OAAO,CAAC,mBAAmB,CACxC,SAAS,EACT,MAAM,CAAC,YAAY,EACnB,SAAS,EACT,WAAW,EACX,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CACjC,CAAC,CAAC;QACL,CAAC;QAED,IAAI,IAAI,GAAG,eAAe,CAAC;QAC3B,IAAI,OAAO,GAA4B,EAAE,CAAC;QAE1C,IAAI,OAAO,IAAI,MAAM,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YACtC,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC;YACzB,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,OAA8C,CAAC;YACxE,IAAI,GAAG,EAAE,CAAC;gBACR,MAAM,eAAe,GAA4B,EAAE,CAAC;gBACpD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC/C,eAAe,CAAC,GAAG,CAAC,GAAG,mBAAmB,CACxC,SAAS,EACT,KAAK,EACL,SAAS,EACT,WAAW,EACX,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CACjC,CAAC;gBACJ,CAAC;gBACD,OAAO,GAAG,eAAe,CAAC;YAC5B,CAAC;QACH,CAAC;QAED,MAAM,UAAU,GAAsB;YACpC,IAAI;YACJ,SAAS;YACT,iBAAiB,EAAE,EAAE;YACrB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,OAAO;SACR,CAAC;QAEF,wDAAwD;QACxD,gEAAgE;QAChE,kDAAkD;QAClD,OAAO,SAAS,CAAC,QAAQ,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC;IAC5C,CAAC,EACD,CAAC,EAAE,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,CAAC,CAC3D,CAAC;IAEF,OAAO,EAAE,UAAU,EAAE,CAAC;AACxB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { CatalogComponent } from '../catalog/defineCatalog.js';
|
|
2
|
+
/**
|
|
3
|
+
* Internal hook — returns the resolved name → component map. Used by the
|
|
4
|
+
* renderer and exposed for advanced custom components that want to peek
|
|
5
|
+
* at the active catalog.
|
|
6
|
+
*/
|
|
7
|
+
export declare function useCatalog(): ReadonlyMap<string, CatalogComponent>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Copyright 2026 The Lynx Authors. All rights reserved.
|
|
2
|
+
// Licensed under the Apache License Version 2.0 that can be found in the
|
|
3
|
+
// LICENSE file in the root directory of this source tree.
|
|
4
|
+
import { useA2UIContext } from './useA2UIContext.js';
|
|
5
|
+
/**
|
|
6
|
+
* Internal hook — returns the resolved name → component map. Used by the
|
|
7
|
+
* renderer and exposed for advanced custom components that want to peek
|
|
8
|
+
* at the active catalog.
|
|
9
|
+
*/
|
|
10
|
+
export function useCatalog() {
|
|
11
|
+
return useA2UIContext().catalogMap;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=useCatalog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useCatalog.js","sourceRoot":"","sources":["../../src/react/useCatalog.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,yEAAyE;AACzE,0DAA0D;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAGrD;;;;GAIG;AACH,MAAM,UAAU,UAAU;IACxB,OAAO,cAAc,EAAE,CAAC,UAAU,CAAC;AACrC,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { CheckOutcome } from '../store/FormController.js';
|
|
2
|
+
import type { Surface } from '../store/types.js';
|
|
3
|
+
/**
|
|
4
|
+
* A v0.9 `CheckRule` is `{ condition, message }` where `condition` is a
|
|
5
|
+
* boolean, a `DataBinding`, or a `FunctionCall`. We accept the loose
|
|
6
|
+
* `unknown` shape so component props don't have to import the v0_9
|
|
7
|
+
* types just to pass them through.
|
|
8
|
+
*/
|
|
9
|
+
export interface CheckLike {
|
|
10
|
+
condition: unknown;
|
|
11
|
+
message: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Evaluate an input component's `checks` array reactively. Returns the
|
|
15
|
+
* current outcome plus the first failure message (handy for inline error
|
|
16
|
+
* rendering). When an enclosing `<FormContext.Provider>` exists, the input
|
|
17
|
+
* is also registered with it so Buttons in the same form can react to
|
|
18
|
+
* `isValid`.
|
|
19
|
+
*/
|
|
20
|
+
export declare function useChecks(options: {
|
|
21
|
+
checks: CheckLike[] | undefined;
|
|
22
|
+
componentId: string;
|
|
23
|
+
surface: Surface | undefined;
|
|
24
|
+
dataContextPath?: string | undefined;
|
|
25
|
+
}): CheckOutcome & {
|
|
26
|
+
firstFailureMessage: string | undefined;
|
|
27
|
+
};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// Copyright 2026 The Lynx Authors. All rights reserved.
|
|
2
|
+
// Licensed under the Apache License Version 2.0 that can be found in the
|
|
3
|
+
// LICENSE file in the root directory of this source tree.
|
|
4
|
+
import { effect } from '@preact/signals';
|
|
5
|
+
import { useContext, useEffect, useState } from '@lynx-js/react';
|
|
6
|
+
import { FormContext } from './FormContext.js';
|
|
7
|
+
import { useA2UIContext } from './useA2UIContext.js';
|
|
8
|
+
import { executeFunctionCall, isDataBinding, isFunctionCall, resolveDynamicValue, } from '../store/resolveFunctionCall.js';
|
|
9
|
+
function evaluateCondition(processor, condition, surfaceId, dataContextPath, functions) {
|
|
10
|
+
if (typeof condition === 'boolean')
|
|
11
|
+
return condition;
|
|
12
|
+
if (isFunctionCall(condition)) {
|
|
13
|
+
const result = executeFunctionCall(processor, condition, surfaceId, dataContextPath, { functions });
|
|
14
|
+
return Boolean(result);
|
|
15
|
+
}
|
|
16
|
+
if (isDataBinding(condition)) {
|
|
17
|
+
return Boolean(resolveDynamicValue(processor, condition, surfaceId, dataContextPath));
|
|
18
|
+
}
|
|
19
|
+
// Unknown shape — treat as passing rather than blocking the user.
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
function evaluateChecks(processor, checks, surface, dataContextPath, functions) {
|
|
23
|
+
if (!surface || !Array.isArray(checks) || checks.length === 0) {
|
|
24
|
+
return { ok: true, failures: [] };
|
|
25
|
+
}
|
|
26
|
+
const failures = [];
|
|
27
|
+
for (const rule of checks) {
|
|
28
|
+
const ok = evaluateCondition(processor, rule.condition, surface.surfaceId, dataContextPath, functions);
|
|
29
|
+
if (!ok) {
|
|
30
|
+
failures.push({
|
|
31
|
+
call: isFunctionCall(rule.condition)
|
|
32
|
+
? rule.condition.call
|
|
33
|
+
: 'condition',
|
|
34
|
+
message: rule.message,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return { ok: failures.length === 0, failures };
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Evaluate an input component's `checks` array reactively. Returns the
|
|
42
|
+
* current outcome plus the first failure message (handy for inline error
|
|
43
|
+
* rendering). When an enclosing `<FormContext.Provider>` exists, the input
|
|
44
|
+
* is also registered with it so Buttons in the same form can react to
|
|
45
|
+
* `isValid`.
|
|
46
|
+
*/
|
|
47
|
+
export function useChecks(options) {
|
|
48
|
+
const { checks, componentId, surface, dataContextPath } = options;
|
|
49
|
+
const { catalog, processor } = useA2UIContext();
|
|
50
|
+
const form = useContext(FormContext);
|
|
51
|
+
const [outcome, setOutcome] = useState(() => evaluateChecks(processor, checks, surface, dataContextPath, catalog.functions));
|
|
52
|
+
useEffect(() => {
|
|
53
|
+
if (!surface) {
|
|
54
|
+
setOutcome({ ok: true, failures: [] });
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const dispose = effect(() => {
|
|
58
|
+
const next = evaluateChecks(processor, checks, surface, dataContextPath, catalog.functions);
|
|
59
|
+
setOutcome(next);
|
|
60
|
+
});
|
|
61
|
+
return dispose;
|
|
62
|
+
}, [processor, checks, surface, dataContextPath, catalog.functions]);
|
|
63
|
+
useEffect(() => {
|
|
64
|
+
// Skip registration when no componentId is available — otherwise every
|
|
65
|
+
// unnamed input collides under the same '' key in the form controller.
|
|
66
|
+
if (!form || !componentId)
|
|
67
|
+
return;
|
|
68
|
+
return form.setOutcome(componentId, outcome);
|
|
69
|
+
}, [form, componentId, outcome]);
|
|
70
|
+
return {
|
|
71
|
+
ok: outcome.ok,
|
|
72
|
+
failures: outcome.failures,
|
|
73
|
+
firstFailureMessage: outcome.failures[0]?.message,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=useChecks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useChecks.js","sourceRoot":"","sources":["../../src/react/useChecks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { CatalogFunctionEntry } from '../catalog/defineCatalog.js';
|
|
2
|
+
import type { MessageProcessor } from '../store/MessageProcessor.js';
|
|
3
|
+
import type { Surface } from '../store/types.js';
|
|
4
|
+
export declare function useDataBinding<T = unknown>(dynamicValue: unknown, surface: Surface | undefined, dataContextPath?: string, fallbackValue?: T): [T | undefined, (newValue: T) => void, string | undefined];
|
|
5
|
+
export declare function splitUnsupportedProps(properties: Record<string, unknown> | undefined): {
|
|
6
|
+
unsupportedFields: string[];
|
|
7
|
+
displayProps: Record<string, unknown> | undefined;
|
|
8
|
+
};
|
|
9
|
+
export declare function resolveProperties(properties: Record<string, unknown>, surface: Surface | undefined, dataContextPath?: string, processor?: MessageProcessor, functions?: readonly CatalogFunctionEntry[]): Record<string, unknown>;
|
|
10
|
+
export declare function useResolvedProps(properties: Record<string, unknown>, surface: Surface | undefined, dataContextPath?: string, processor?: MessageProcessor, functions?: readonly CatalogFunctionEntry[]): readonly [Record<string, unknown>, (key: string, value: unknown) => void];
|