@a2ui-sdk/react 0.2.1 → 0.3.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/README.md +201 -18
- package/dist/0.8/components/layout/ColumnComponent.js +33 -40
- package/dist/0.8/components/layout/ListComponent.js +31 -38
- package/dist/0.8/components/layout/RowComponent.js +33 -40
- package/dist/0.8/components/layout/TemplateRenderer.d.ts +22 -0
- package/dist/0.8/components/layout/TemplateRenderer.js +30 -0
- package/dist/0.8/contexts/ActionContext.d.ts +1 -1
- package/dist/0.8/contexts/ActionContext.js +21 -17
- package/dist/0.8/contexts/ScopeContext.d.ts +53 -0
- package/dist/0.8/contexts/ScopeContext.js +22 -0
- package/dist/0.8/hooks/useDataBinding.js +22 -18
- package/dist/0.8/hooks/useDispatchAction.d.ts +1 -0
- package/dist/0.8/hooks/useDispatchAction.js +12 -5
- package/dist/0.8/index.d.ts +1 -0
- package/dist/0.8/index.js +11 -8
- package/dist/0.9/index.d.ts +1 -0
- package/dist/0.9/index.js +16 -13
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -15,7 +15,129 @@ npm install @a2ui-sdk/react
|
|
|
15
15
|
|
|
16
16
|
## Usage
|
|
17
17
|
|
|
18
|
-
###
|
|
18
|
+
### v0.8
|
|
19
|
+
|
|
20
|
+
#### Basic Usage
|
|
21
|
+
|
|
22
|
+
```tsx
|
|
23
|
+
import {
|
|
24
|
+
A2UIProvider,
|
|
25
|
+
A2UIRenderer,
|
|
26
|
+
type A2UIMessage,
|
|
27
|
+
type A2UIAction,
|
|
28
|
+
} from '@a2ui-sdk/react/0.8'
|
|
29
|
+
|
|
30
|
+
function App() {
|
|
31
|
+
const messages: A2UIMessage[] = [
|
|
32
|
+
// A2UI messages from your backend
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
const handleAction = (action: A2UIAction) => {
|
|
36
|
+
console.log('Action received:', action)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<A2UIProvider messages={messages}>
|
|
41
|
+
<A2UIRenderer onAction={handleAction} />
|
|
42
|
+
</A2UIProvider>
|
|
43
|
+
)
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
#### Custom Components
|
|
48
|
+
|
|
49
|
+
You can override default components or add new custom components via the `catalog` prop on `A2UIProvider`. Use `standardCatalog` as a base and extend it with your custom components.
|
|
50
|
+
|
|
51
|
+
```tsx
|
|
52
|
+
import {
|
|
53
|
+
A2UIProvider,
|
|
54
|
+
A2UIRenderer,
|
|
55
|
+
standardCatalog,
|
|
56
|
+
type A2UIMessage,
|
|
57
|
+
type A2UIAction,
|
|
58
|
+
} from '@a2ui-sdk/react/0.8'
|
|
59
|
+
|
|
60
|
+
// Extend standard catalog with custom components
|
|
61
|
+
const customCatalog = {
|
|
62
|
+
...standardCatalog,
|
|
63
|
+
components: {
|
|
64
|
+
...standardCatalog.components,
|
|
65
|
+
// Override default Button component with a custom one
|
|
66
|
+
Button: CustomButtonComponent,
|
|
67
|
+
// Add a new custom Switch component
|
|
68
|
+
Switch: CustomSwitchComponent,
|
|
69
|
+
},
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function App() {
|
|
73
|
+
return (
|
|
74
|
+
<A2UIProvider catalog={customCatalog} messages={messages}>
|
|
75
|
+
<A2UIRenderer onAction={handleAction} />
|
|
76
|
+
</A2UIProvider>
|
|
77
|
+
)
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Implementing a custom button component with action dispatch:
|
|
82
|
+
|
|
83
|
+
```tsx
|
|
84
|
+
import {
|
|
85
|
+
useDispatchAction,
|
|
86
|
+
ComponentRenderer,
|
|
87
|
+
type ButtonComponentProps,
|
|
88
|
+
} from '@a2ui-sdk/react/0.8'
|
|
89
|
+
|
|
90
|
+
export function CustomButtonComponent({
|
|
91
|
+
surfaceId,
|
|
92
|
+
componentId,
|
|
93
|
+
child,
|
|
94
|
+
action,
|
|
95
|
+
}: ButtonComponentProps) {
|
|
96
|
+
const dispatchAction = useDispatchAction()
|
|
97
|
+
|
|
98
|
+
const handleClick = () => {
|
|
99
|
+
if (action) {
|
|
100
|
+
dispatchAction(surfaceId, componentId, action)
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return (
|
|
105
|
+
<button onClick={handleClick}>
|
|
106
|
+
<ComponentRenderer surfaceId={surfaceId} componentId={child} />
|
|
107
|
+
</button>
|
|
108
|
+
)
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Implementing a custom switch component with data binding:
|
|
113
|
+
|
|
114
|
+
```tsx
|
|
115
|
+
import { useDataBinding, useFormBinding } from '@a2ui-sdk/react/0.8'
|
|
116
|
+
|
|
117
|
+
export function CustomSwitchComponent({
|
|
118
|
+
surfaceId,
|
|
119
|
+
componentId,
|
|
120
|
+
label,
|
|
121
|
+
value,
|
|
122
|
+
}: SwitchComponentProps) {
|
|
123
|
+
const labelText = useDataBinding<string>(surfaceId, label, '')
|
|
124
|
+
const [checked, setChecked] = useFormBinding<boolean>(surfaceId, value, false)
|
|
125
|
+
|
|
126
|
+
const handleChange = (newChecked: boolean) => {
|
|
127
|
+
setChecked(newChecked)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return (
|
|
131
|
+
<Switch checked={checked} onChange={handleChange}>
|
|
132
|
+
{labelText}
|
|
133
|
+
</Switch>
|
|
134
|
+
)
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### v0.9
|
|
139
|
+
|
|
140
|
+
#### Basic Usage
|
|
19
141
|
|
|
20
142
|
```tsx
|
|
21
143
|
import {
|
|
@@ -35,36 +157,40 @@ function App() {
|
|
|
35
157
|
}
|
|
36
158
|
|
|
37
159
|
return (
|
|
38
|
-
<A2UIProvider messages={messages}
|
|
39
|
-
<A2UIRenderer />
|
|
160
|
+
<A2UIProvider messages={messages}>
|
|
161
|
+
<A2UIRenderer onAction={handleAction} />
|
|
40
162
|
</A2UIProvider>
|
|
41
163
|
)
|
|
42
164
|
}
|
|
43
165
|
```
|
|
44
166
|
|
|
45
|
-
|
|
167
|
+
#### Custom Components
|
|
46
168
|
|
|
47
|
-
|
|
169
|
+
Override or extend the standard catalog the same way as in v0.8:
|
|
48
170
|
|
|
49
171
|
```tsx
|
|
50
|
-
import {
|
|
172
|
+
import {
|
|
173
|
+
A2UIProvider,
|
|
174
|
+
A2UIRenderer,
|
|
175
|
+
standardCatalog,
|
|
176
|
+
type A2UIMessage,
|
|
177
|
+
type A2UIAction,
|
|
178
|
+
} from '@a2ui-sdk/react/0.9'
|
|
51
179
|
|
|
52
|
-
//
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
180
|
+
// Extend standard catalog with custom components
|
|
181
|
+
const customCatalog = {
|
|
182
|
+
...standardCatalog,
|
|
183
|
+
components: {
|
|
184
|
+
...standardCatalog.components,
|
|
185
|
+
// Override default components or add new ones
|
|
186
|
+
Button: CustomButtonComponent,
|
|
187
|
+
},
|
|
56
188
|
}
|
|
57
189
|
|
|
58
190
|
function App() {
|
|
59
|
-
const components = new Map([['Text', MyCustomText]])
|
|
60
|
-
|
|
61
191
|
return (
|
|
62
|
-
<A2UIProvider
|
|
63
|
-
|
|
64
|
-
onAction={handleAction}
|
|
65
|
-
components={components}
|
|
66
|
-
>
|
|
67
|
-
<A2UIRenderer />
|
|
192
|
+
<A2UIProvider catalog={customCatalog} messages={messages}>
|
|
193
|
+
<A2UIRenderer onAction={handleAction} />
|
|
68
194
|
</A2UIProvider>
|
|
69
195
|
)
|
|
70
196
|
}
|
|
@@ -81,6 +207,9 @@ import {
|
|
|
81
207
|
A2UIRenderer,
|
|
82
208
|
ComponentRenderer,
|
|
83
209
|
|
|
210
|
+
// Catalog
|
|
211
|
+
standardCatalog,
|
|
212
|
+
|
|
84
213
|
// Hooks
|
|
85
214
|
useDispatchAction,
|
|
86
215
|
useDataBinding,
|
|
@@ -92,6 +221,10 @@ import {
|
|
|
92
221
|
useScope,
|
|
93
222
|
useScopeBasePath,
|
|
94
223
|
|
|
224
|
+
// Context Providers & Hooks
|
|
225
|
+
ActionProvider,
|
|
226
|
+
useActionContext,
|
|
227
|
+
|
|
95
228
|
// Types
|
|
96
229
|
type A2UIMessage,
|
|
97
230
|
type A2UIAction,
|
|
@@ -124,12 +257,21 @@ import {
|
|
|
124
257
|
A2UIRenderer,
|
|
125
258
|
ComponentRenderer,
|
|
126
259
|
|
|
260
|
+
// Catalog
|
|
261
|
+
standardCatalog,
|
|
262
|
+
|
|
127
263
|
// Hooks
|
|
128
264
|
useDispatchAction,
|
|
129
265
|
useDataBinding,
|
|
130
266
|
useFormBinding,
|
|
131
267
|
useSurfaceContext,
|
|
132
268
|
useDataModelContext,
|
|
269
|
+
useScope,
|
|
270
|
+
useScopeBasePath,
|
|
271
|
+
|
|
272
|
+
// Context Providers & Hooks
|
|
273
|
+
ActionProvider,
|
|
274
|
+
useActionContext,
|
|
133
275
|
|
|
134
276
|
// Types
|
|
135
277
|
type A2UIMessage,
|
|
@@ -139,6 +281,7 @@ import {
|
|
|
139
281
|
type ComponentsMap,
|
|
140
282
|
type Action,
|
|
141
283
|
type ValueSource,
|
|
284
|
+
type ScopeValue,
|
|
142
285
|
} from '@a2ui-sdk/react/0.8'
|
|
143
286
|
```
|
|
144
287
|
|
|
@@ -197,6 +340,46 @@ const { valid, errors } = useValidation(checks)
|
|
|
197
340
|
// errors: string[] - list of failed validation messages
|
|
198
341
|
```
|
|
199
342
|
|
|
343
|
+
### ActionProvider & useActionContext
|
|
344
|
+
|
|
345
|
+
For advanced use cases, you can create custom action handling middleware by using `ActionProvider` and `useActionContext` directly. This is useful when you need to intercept, transform, or augment actions before they reach your action handler.
|
|
346
|
+
|
|
347
|
+
```tsx
|
|
348
|
+
import {
|
|
349
|
+
A2UIProvider,
|
|
350
|
+
A2UIRenderer,
|
|
351
|
+
ActionProvider,
|
|
352
|
+
useActionContext,
|
|
353
|
+
} from '@a2ui-sdk/react/0.9'
|
|
354
|
+
|
|
355
|
+
function ActionLogger({ children }: { children: React.ReactNode }) {
|
|
356
|
+
const { onAction } = useActionContext()
|
|
357
|
+
|
|
358
|
+
// You can access the action handler here
|
|
359
|
+
// and potentially wrap it with logging or other middleware logic
|
|
360
|
+
|
|
361
|
+
return <>{children}</>
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
function App() {
|
|
365
|
+
const handleAction = (action: A2UIAction) => {
|
|
366
|
+
console.log('Action:', action)
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
return (
|
|
370
|
+
<A2UIProvider messages={messages}>
|
|
371
|
+
<ActionProvider onAction={handleAction}>
|
|
372
|
+
<ActionLogger>
|
|
373
|
+
<A2UIRenderer />
|
|
374
|
+
</ActionLogger>
|
|
375
|
+
</ActionProvider>
|
|
376
|
+
</A2UIProvider>
|
|
377
|
+
)
|
|
378
|
+
}
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
**Note:** In most cases, you don't need to use `ActionProvider` directly as `A2UIProvider` already includes it. Use this only for advanced customization scenarios.
|
|
382
|
+
|
|
200
383
|
## License
|
|
201
384
|
|
|
202
385
|
Apache-2.0
|
|
@@ -1,58 +1,51 @@
|
|
|
1
1
|
import { jsx as t } from "react/jsx-runtime";
|
|
2
|
-
import { memo as
|
|
3
|
-
import { useDataModel as
|
|
4
|
-
import { cn as
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
2
|
+
import { memo as a } from "react";
|
|
3
|
+
import { useDataModel as c } from "../../hooks/useDataBinding.js";
|
|
4
|
+
import { cn as l } from "../../../lib/utils.js";
|
|
5
|
+
import { ComponentRenderer as f } from "../ComponentRenderer.js";
|
|
6
|
+
import { TemplateRenderer as u } from "./TemplateRenderer.js";
|
|
7
|
+
import { useScope as d } from "../../contexts/ScopeContext.js";
|
|
8
|
+
const y = {
|
|
8
9
|
start: "justify-start",
|
|
9
10
|
center: "justify-center",
|
|
10
11
|
end: "justify-end",
|
|
11
12
|
spaceBetween: "justify-between",
|
|
12
13
|
spaceAround: "justify-around",
|
|
13
14
|
spaceEvenly: "justify-evenly"
|
|
14
|
-
},
|
|
15
|
+
}, j = {
|
|
15
16
|
start: "items-start",
|
|
16
17
|
center: "items-center",
|
|
17
18
|
end: "items-end",
|
|
18
19
|
stretch: "items-stretch"
|
|
19
|
-
},
|
|
20
|
-
surfaceId:
|
|
20
|
+
}, x = a(function({
|
|
21
|
+
surfaceId: n,
|
|
21
22
|
children: e,
|
|
22
|
-
distribution:
|
|
23
|
-
alignment:
|
|
23
|
+
distribution: s = "start",
|
|
24
|
+
alignment: m = "stretch"
|
|
24
25
|
}) {
|
|
25
|
-
const c = d(
|
|
26
|
+
const i = c(n), { basePath: p } = d(), o = l(
|
|
26
27
|
"flex flex-col gap-4",
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
y[s],
|
|
29
|
+
j[m]
|
|
29
30
|
);
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
{
|
|
47
|
-
surfaceId: s,
|
|
48
|
-
componentId: o
|
|
49
|
-
},
|
|
50
|
-
f
|
|
51
|
-
)) });
|
|
52
|
-
}
|
|
53
|
-
return /* @__PURE__ */ t("div", { className: n });
|
|
31
|
+
return e?.explicitList ? /* @__PURE__ */ t("div", { className: o, children: e.explicitList.map((r) => /* @__PURE__ */ t(
|
|
32
|
+
f,
|
|
33
|
+
{
|
|
34
|
+
surfaceId: n,
|
|
35
|
+
componentId: r
|
|
36
|
+
},
|
|
37
|
+
r
|
|
38
|
+
)) }) : e?.template ? /* @__PURE__ */ t("div", { className: o, children: /* @__PURE__ */ t(
|
|
39
|
+
u,
|
|
40
|
+
{
|
|
41
|
+
surfaceId: n,
|
|
42
|
+
template: e.template,
|
|
43
|
+
dataModel: i,
|
|
44
|
+
basePath: p
|
|
45
|
+
}
|
|
46
|
+
) }) : /* @__PURE__ */ t("div", { className: o });
|
|
54
47
|
});
|
|
55
|
-
|
|
48
|
+
x.displayName = "A2UI.Column";
|
|
56
49
|
export {
|
|
57
|
-
|
|
50
|
+
x as ColumnComponent
|
|
58
51
|
};
|
|
@@ -1,51 +1,44 @@
|
|
|
1
1
|
import { jsx as t } from "react/jsx-runtime";
|
|
2
|
-
import { memo as
|
|
3
|
-
import { useDataModel as
|
|
4
|
-
import { cn as
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
2
|
+
import { memo as a } from "react";
|
|
3
|
+
import { useDataModel as l } from "../../hooks/useDataBinding.js";
|
|
4
|
+
import { cn as c } from "../../../lib/utils.js";
|
|
5
|
+
import { ComponentRenderer as f } from "../ComponentRenderer.js";
|
|
6
|
+
import { TemplateRenderer as d } from "./TemplateRenderer.js";
|
|
7
|
+
import { useScope as x } from "../../contexts/ScopeContext.js";
|
|
7
8
|
const L = {
|
|
8
9
|
start: "items-start",
|
|
9
10
|
center: "items-center",
|
|
10
11
|
end: "items-end",
|
|
11
12
|
stretch: "items-stretch"
|
|
12
|
-
},
|
|
13
|
-
surfaceId:
|
|
13
|
+
}, u = a(function({
|
|
14
|
+
surfaceId: o,
|
|
14
15
|
children: e,
|
|
15
|
-
direction:
|
|
16
|
-
alignment:
|
|
16
|
+
direction: i = "vertical",
|
|
17
|
+
alignment: n = "stretch"
|
|
17
18
|
}) {
|
|
18
|
-
const p = x(
|
|
19
|
+
const s = l(o), { basePath: p } = x(), m = c(
|
|
19
20
|
"flex gap-3",
|
|
20
|
-
|
|
21
|
-
L[
|
|
21
|
+
i === "horizontal" ? "flex-row" : "flex-col",
|
|
22
|
+
L[n]
|
|
22
23
|
);
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
{
|
|
40
|
-
surfaceId: n,
|
|
41
|
-
componentId: i
|
|
42
|
-
},
|
|
43
|
-
f
|
|
44
|
-
)) });
|
|
45
|
-
}
|
|
46
|
-
return /* @__PURE__ */ t("div", { className: o });
|
|
24
|
+
return e?.explicitList ? /* @__PURE__ */ t("div", { className: m, children: e.explicitList.map((r) => /* @__PURE__ */ t(
|
|
25
|
+
f,
|
|
26
|
+
{
|
|
27
|
+
surfaceId: o,
|
|
28
|
+
componentId: r
|
|
29
|
+
},
|
|
30
|
+
r
|
|
31
|
+
)) }) : e?.template ? /* @__PURE__ */ t("div", { className: m, children: /* @__PURE__ */ t(
|
|
32
|
+
d,
|
|
33
|
+
{
|
|
34
|
+
surfaceId: o,
|
|
35
|
+
template: e.template,
|
|
36
|
+
dataModel: s,
|
|
37
|
+
basePath: p
|
|
38
|
+
}
|
|
39
|
+
) }) : /* @__PURE__ */ t("div", { className: m });
|
|
47
40
|
});
|
|
48
|
-
|
|
41
|
+
u.displayName = "A2UI.List";
|
|
49
42
|
export {
|
|
50
|
-
|
|
43
|
+
u as ListComponent
|
|
51
44
|
};
|
|
@@ -1,58 +1,51 @@
|
|
|
1
1
|
import { jsx as t } from "react/jsx-runtime";
|
|
2
|
-
import { memo as
|
|
3
|
-
import { useDataModel as
|
|
4
|
-
import { cn as
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
2
|
+
import { memo as a } from "react";
|
|
3
|
+
import { useDataModel as c } from "../../hooks/useDataBinding.js";
|
|
4
|
+
import { cn as f } from "../../../lib/utils.js";
|
|
5
|
+
import { ComponentRenderer as l } from "../ComponentRenderer.js";
|
|
6
|
+
import { TemplateRenderer as u } from "./TemplateRenderer.js";
|
|
7
|
+
import { useScope as d } from "../../contexts/ScopeContext.js";
|
|
8
|
+
const y = {
|
|
8
9
|
start: "justify-start",
|
|
9
10
|
center: "justify-center",
|
|
10
11
|
end: "justify-end",
|
|
11
12
|
spaceBetween: "justify-between",
|
|
12
13
|
spaceAround: "justify-around",
|
|
13
14
|
spaceEvenly: "justify-evenly"
|
|
14
|
-
},
|
|
15
|
+
}, j = {
|
|
15
16
|
start: "items-start",
|
|
16
17
|
center: "items-center",
|
|
17
18
|
end: "items-end",
|
|
18
19
|
stretch: "items-stretch"
|
|
19
|
-
},
|
|
20
|
-
surfaceId:
|
|
20
|
+
}, w = a(function({
|
|
21
|
+
surfaceId: o,
|
|
21
22
|
children: e,
|
|
22
|
-
distribution:
|
|
23
|
-
alignment:
|
|
23
|
+
distribution: s = "start",
|
|
24
|
+
alignment: i = "stretch"
|
|
24
25
|
}) {
|
|
25
|
-
const p =
|
|
26
|
+
const m = c(o), { basePath: p } = d(), n = f(
|
|
26
27
|
"flex flex-row gap-3",
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
y[s],
|
|
29
|
+
j[i]
|
|
29
30
|
);
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
{
|
|
47
|
-
surfaceId: s,
|
|
48
|
-
componentId: o
|
|
49
|
-
},
|
|
50
|
-
d
|
|
51
|
-
)) });
|
|
52
|
-
}
|
|
53
|
-
return /* @__PURE__ */ t("div", { className: n });
|
|
31
|
+
return e?.explicitList ? /* @__PURE__ */ t("div", { className: n, children: e.explicitList.map((r) => /* @__PURE__ */ t(
|
|
32
|
+
l,
|
|
33
|
+
{
|
|
34
|
+
surfaceId: o,
|
|
35
|
+
componentId: r
|
|
36
|
+
},
|
|
37
|
+
r
|
|
38
|
+
)) }) : e?.template ? /* @__PURE__ */ t("div", { className: n, children: /* @__PURE__ */ t(
|
|
39
|
+
u,
|
|
40
|
+
{
|
|
41
|
+
surfaceId: o,
|
|
42
|
+
template: e.template,
|
|
43
|
+
dataModel: m,
|
|
44
|
+
basePath: p
|
|
45
|
+
}
|
|
46
|
+
) }) : /* @__PURE__ */ t("div", { className: n });
|
|
54
47
|
});
|
|
55
|
-
|
|
48
|
+
w.displayName = "A2UI.Row";
|
|
56
49
|
export {
|
|
57
|
-
|
|
50
|
+
w as RowComponent
|
|
58
51
|
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { TemplateBinding, DataModel } from '@a2ui-sdk/types/0.8';
|
|
2
|
+
export interface TemplateRendererProps {
|
|
3
|
+
surfaceId: string;
|
|
4
|
+
template: TemplateBinding;
|
|
5
|
+
dataModel: DataModel;
|
|
6
|
+
basePath: string | null;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Renders template-bound children with scoped data context.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```tsx
|
|
13
|
+
* <TemplateRenderer
|
|
14
|
+
* surfaceId="main"
|
|
15
|
+
* template={{ componentId: "item-card", dataBinding: "/items" }}
|
|
16
|
+
* dataModel={{ items: { 0: { name: "Alice" }, 1: { name: "Bob" } } }}
|
|
17
|
+
* basePath={null}
|
|
18
|
+
* />
|
|
19
|
+
* // Renders two item-card components, each with scoped access to its data
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export declare const TemplateRenderer: import('react').NamedExoticComponent<TemplateRendererProps>;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { jsx as t, Fragment as l } from "react/jsx-runtime";
|
|
2
|
+
import { memo as f } from "react";
|
|
3
|
+
import { resolvePath as h, getValueByPath as u } from "@a2ui-sdk/utils/0.8";
|
|
4
|
+
import { ScopeProvider as P } from "../../contexts/ScopeContext.js";
|
|
5
|
+
import { ComponentRenderer as R } from "../ComponentRenderer.js";
|
|
6
|
+
const $ = f(function({
|
|
7
|
+
surfaceId: m,
|
|
8
|
+
template: a,
|
|
9
|
+
dataModel: i,
|
|
10
|
+
basePath: p
|
|
11
|
+
}) {
|
|
12
|
+
const { componentId: r, dataBinding: s } = a, o = h(s, p), e = u(i, o);
|
|
13
|
+
if (!e || typeof e != "object")
|
|
14
|
+
return null;
|
|
15
|
+
const c = Object.entries(e);
|
|
16
|
+
return /* @__PURE__ */ t(l, { children: c.map(([n]) => {
|
|
17
|
+
const d = `${o}/${n}`;
|
|
18
|
+
return /* @__PURE__ */ t(P, { basePath: d, children: /* @__PURE__ */ t(
|
|
19
|
+
R,
|
|
20
|
+
{
|
|
21
|
+
surfaceId: m,
|
|
22
|
+
componentId: r
|
|
23
|
+
}
|
|
24
|
+
) }, `${r}-${n}`);
|
|
25
|
+
}) });
|
|
26
|
+
});
|
|
27
|
+
$.displayName = "A2UI.TemplateRenderer";
|
|
28
|
+
export {
|
|
29
|
+
$ as TemplateRenderer
|
|
30
|
+
};
|
|
@@ -5,7 +5,7 @@ import { Action, ActionHandler } from '@a2ui-sdk/types/0.8';
|
|
|
5
5
|
*/
|
|
6
6
|
export interface ActionContextValue {
|
|
7
7
|
/** Dispatches an action with resolved context */
|
|
8
|
-
dispatchAction: (surfaceId: string, componentId: string, action: Action) => void;
|
|
8
|
+
dispatchAction: (surfaceId: string, componentId: string, action: Action, basePath: string | null) => void;
|
|
9
9
|
/** The action handler callback (if set) */
|
|
10
10
|
onAction: ActionHandler | null;
|
|
11
11
|
}
|
|
@@ -1,41 +1,45 @@
|
|
|
1
|
-
import { jsx as
|
|
2
|
-
import { useCallback as
|
|
3
|
-
import { useDataModelContext as
|
|
4
|
-
import { resolveActionContext as
|
|
5
|
-
const s =
|
|
6
|
-
function
|
|
7
|
-
const { getDataModel: o } =
|
|
8
|
-
(n, a, r) => {
|
|
1
|
+
import { jsx as x } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback as C, useMemo as p, createContext as f, useContext as v } from "react";
|
|
3
|
+
import { useDataModelContext as A } from "./DataModelContext.js";
|
|
4
|
+
import { resolveActionContext as h } from "@a2ui-sdk/utils/0.8";
|
|
5
|
+
const s = f(null);
|
|
6
|
+
function g({ onAction: t, children: c }) {
|
|
7
|
+
const { getDataModel: o } = A(), e = C(
|
|
8
|
+
(n, a, r, u) => {
|
|
9
9
|
if (!t) {
|
|
10
10
|
console.warn("A2UI: Action dispatched but no handler is registered");
|
|
11
11
|
return;
|
|
12
12
|
}
|
|
13
|
-
const
|
|
13
|
+
const d = o(n), l = h(
|
|
14
|
+
r.context,
|
|
15
|
+
d,
|
|
16
|
+
u
|
|
17
|
+
), m = {
|
|
14
18
|
surfaceId: n,
|
|
15
19
|
name: r.name,
|
|
16
|
-
context:
|
|
20
|
+
context: l,
|
|
17
21
|
sourceComponentId: a
|
|
18
22
|
};
|
|
19
|
-
t(
|
|
23
|
+
t(m);
|
|
20
24
|
},
|
|
21
25
|
[t, o]
|
|
22
|
-
), i =
|
|
26
|
+
), i = p(
|
|
23
27
|
() => ({
|
|
24
28
|
dispatchAction: e,
|
|
25
29
|
onAction: t ?? null
|
|
26
30
|
}),
|
|
27
31
|
[e, t]
|
|
28
32
|
);
|
|
29
|
-
return /* @__PURE__ */
|
|
33
|
+
return /* @__PURE__ */ x(s.Provider, { value: i, children: c });
|
|
30
34
|
}
|
|
31
|
-
function
|
|
32
|
-
const t =
|
|
35
|
+
function D() {
|
|
36
|
+
const t = v(s);
|
|
33
37
|
if (!t)
|
|
34
38
|
throw new Error("useActionContext must be used within an ActionProvider");
|
|
35
39
|
return t;
|
|
36
40
|
}
|
|
37
41
|
export {
|
|
38
42
|
s as ActionContext,
|
|
39
|
-
|
|
40
|
-
|
|
43
|
+
g as ActionProvider,
|
|
44
|
+
D as useActionContext
|
|
41
45
|
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { ScopeValue } from '@a2ui-sdk/types/0.8';
|
|
3
|
+
/**
|
|
4
|
+
* Context for tracking collection scopes.
|
|
5
|
+
*
|
|
6
|
+
* When rendering children from template binding (e.g., List with `{"componentId": "item", "dataBinding": "/items"}`),
|
|
7
|
+
* each item gets its own scope with a base path like "/items/0", "/items/1", etc.
|
|
8
|
+
*
|
|
9
|
+
* Components use this context to resolve relative paths within their scope.
|
|
10
|
+
*/
|
|
11
|
+
export declare const ScopeContext: import('react').Context<ScopeValue>;
|
|
12
|
+
/**
|
|
13
|
+
* Props for ScopeProvider.
|
|
14
|
+
*/
|
|
15
|
+
export interface ScopeProviderProps {
|
|
16
|
+
/** The base path for this scope (e.g., "/items/0") */
|
|
17
|
+
basePath: string;
|
|
18
|
+
children: ReactNode;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Provider for creating a new scope.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```tsx
|
|
25
|
+
* // In ListComponent when rendering template children:
|
|
26
|
+
* {items.map(([key]) => (
|
|
27
|
+
* <ScopeProvider key={key} basePath={`${dataPath}/${key}`}>
|
|
28
|
+
* <ComponentRenderer surfaceId={surfaceId} componentId={templateComponentId} />
|
|
29
|
+
* </ScopeProvider>
|
|
30
|
+
* ))}
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare function ScopeProvider({ basePath, children }: ScopeProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
34
|
+
/**
|
|
35
|
+
* Hook to access the current scope.
|
|
36
|
+
*
|
|
37
|
+
* @returns The current scope value
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```tsx
|
|
41
|
+
* function MyComponent() {
|
|
42
|
+
* const { basePath } = useScope()
|
|
43
|
+
* // basePath is null for root scope, or something like "/items/0" for item scope
|
|
44
|
+
* }
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export declare function useScope(): ScopeValue;
|
|
48
|
+
/**
|
|
49
|
+
* Hook to get the base path for the current scope.
|
|
50
|
+
*
|
|
51
|
+
* @returns The base path (null for root scope, string for nested scope)
|
|
52
|
+
*/
|
|
53
|
+
export declare function useScopeBasePath(): string | null;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { jsx as r } from "react/jsx-runtime";
|
|
2
|
+
import { useContext as c, createContext as u } from "react";
|
|
3
|
+
const s = {
|
|
4
|
+
basePath: null
|
|
5
|
+
}, t = u(s);
|
|
6
|
+
function f({ basePath: e, children: o }) {
|
|
7
|
+
const n = { basePath: e };
|
|
8
|
+
return /* @__PURE__ */ r(t.Provider, { value: n, children: o });
|
|
9
|
+
}
|
|
10
|
+
function a() {
|
|
11
|
+
return c(t);
|
|
12
|
+
}
|
|
13
|
+
function l() {
|
|
14
|
+
const { basePath: e } = a();
|
|
15
|
+
return e;
|
|
16
|
+
}
|
|
17
|
+
export {
|
|
18
|
+
t as ScopeContext,
|
|
19
|
+
f as ScopeProvider,
|
|
20
|
+
a as useScope,
|
|
21
|
+
l as useScopeBasePath
|
|
22
|
+
};
|
|
@@ -1,28 +1,32 @@
|
|
|
1
1
|
import { useMemo as i } from "react";
|
|
2
2
|
import { useDataModelContext as l } from "../contexts/DataModelContext.js";
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
import { useScope as m } from "../contexts/ScopeContext.js";
|
|
4
|
+
import { resolveValue as p, resolvePath as d } from "@a2ui-sdk/utils/0.8";
|
|
5
|
+
function c(o, t, e) {
|
|
6
|
+
const { getDataModel: a } = l(), { basePath: r } = m();
|
|
6
7
|
return i(() => {
|
|
7
|
-
const
|
|
8
|
-
return
|
|
9
|
-
}, [
|
|
8
|
+
const n = a(o);
|
|
9
|
+
return p(t, n, r, e);
|
|
10
|
+
}, [a, o, t, r, e]);
|
|
10
11
|
}
|
|
11
|
-
function
|
|
12
|
+
function b(o) {
|
|
12
13
|
const { getDataModel: t } = l();
|
|
13
|
-
return i(() => t(
|
|
14
|
+
return i(() => t(o), [t, o]);
|
|
14
15
|
}
|
|
15
|
-
function
|
|
16
|
-
const { getDataModel:
|
|
17
|
-
const
|
|
18
|
-
return
|
|
19
|
-
}, [
|
|
20
|
-
t && "path" in t
|
|
21
|
-
|
|
16
|
+
function x(o, t, e) {
|
|
17
|
+
const { getDataModel: a, setDataValue: r } = l(), { basePath: n } = m(), M = i(() => {
|
|
18
|
+
const s = a(o);
|
|
19
|
+
return p(t, s, n, e);
|
|
20
|
+
}, [a, o, t, n, e]), D = i(() => (s) => {
|
|
21
|
+
if (t && "path" in t) {
|
|
22
|
+
const h = d(t.path, n);
|
|
23
|
+
r(o, h, s);
|
|
24
|
+
}
|
|
25
|
+
}, [r, o, t, n]);
|
|
22
26
|
return [M, D];
|
|
23
27
|
}
|
|
24
28
|
export {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
29
|
+
c as useDataBinding,
|
|
30
|
+
b as useDataModel,
|
|
31
|
+
x as useFormBinding
|
|
28
32
|
};
|
|
@@ -1,8 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { useCallback as i } from "react";
|
|
2
|
+
import { useActionContext as n } from "../contexts/ActionContext.js";
|
|
3
|
+
import { useScopeBasePath as r } from "../contexts/ScopeContext.js";
|
|
4
|
+
function u() {
|
|
5
|
+
const { dispatchAction: t } = n(), o = r();
|
|
6
|
+
return i(
|
|
7
|
+
(c, e, s) => {
|
|
8
|
+
t(c, e, s, o);
|
|
9
|
+
},
|
|
10
|
+
[t, o]
|
|
11
|
+
);
|
|
5
12
|
}
|
|
6
13
|
export {
|
|
7
|
-
|
|
14
|
+
u as useDispatchAction
|
|
8
15
|
};
|
package/dist/0.8/index.d.ts
CHANGED
|
@@ -44,3 +44,4 @@ export { useDispatchAction } from './hooks/useDispatchAction';
|
|
|
44
44
|
export { useDataBinding, useFormBinding } from './hooks/useDataBinding';
|
|
45
45
|
export { useSurfaceContext } from './contexts/SurfaceContext';
|
|
46
46
|
export { useDataModelContext } from './contexts/DataModelContext';
|
|
47
|
+
export { ActionProvider, useActionContext } from './contexts/ActionContext';
|
package/dist/0.8/index.js
CHANGED
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
import { A2UIProvider as r } from "./contexts/A2UIProvider.js";
|
|
2
2
|
import { A2UIRenderer as n } from "./A2UIRenderer.js";
|
|
3
3
|
import { ComponentRenderer as m } from "./components/ComponentRenderer.js";
|
|
4
|
-
import { standardCatalog as
|
|
5
|
-
import { useDispatchAction as
|
|
4
|
+
import { standardCatalog as a } from "./standard-catalog/index.js";
|
|
5
|
+
import { useDispatchAction as i } from "./hooks/useDispatchAction.js";
|
|
6
6
|
import { useDataBinding as s, useFormBinding as u } from "./hooks/useDataBinding.js";
|
|
7
|
-
import { useSurfaceContext as
|
|
8
|
-
import { useDataModelContext as
|
|
7
|
+
import { useSurfaceContext as A } from "./contexts/SurfaceContext.js";
|
|
8
|
+
import { useDataModelContext as g } from "./contexts/DataModelContext.js";
|
|
9
|
+
import { ActionProvider as l, useActionContext as v } from "./contexts/ActionContext.js";
|
|
9
10
|
export {
|
|
10
11
|
r as A2UIProvider,
|
|
11
12
|
n as A2UIRenderer,
|
|
13
|
+
l as ActionProvider,
|
|
12
14
|
m as ComponentRenderer,
|
|
13
|
-
|
|
15
|
+
a as standardCatalog,
|
|
16
|
+
v as useActionContext,
|
|
14
17
|
s as useDataBinding,
|
|
15
|
-
|
|
16
|
-
|
|
18
|
+
g as useDataModelContext,
|
|
19
|
+
i as useDispatchAction,
|
|
17
20
|
u as useFormBinding,
|
|
18
|
-
|
|
21
|
+
A as useSurfaceContext
|
|
19
22
|
};
|
package/dist/0.9/index.d.ts
CHANGED
|
@@ -34,3 +34,4 @@ export { useDataBinding, useFormBinding, useStringBinding, useDataModel, } from
|
|
|
34
34
|
export { useValidation } from './hooks/useValidation';
|
|
35
35
|
export { useSurfaceContext } from './contexts/SurfaceContext';
|
|
36
36
|
export { useScope, useScopeBasePath } from './contexts/ScopeContext';
|
|
37
|
+
export { ActionProvider, useActionContext } from './contexts/ActionContext';
|
package/dist/0.9/index.js
CHANGED
|
@@ -1,24 +1,27 @@
|
|
|
1
1
|
import { A2UIProvider as r } from "./contexts/A2UIProvider.js";
|
|
2
2
|
import { A2UIRenderer as n } from "./A2UIRenderer.js";
|
|
3
|
-
import { ComponentRenderer as
|
|
3
|
+
import { ComponentRenderer as a } from "./components/ComponentRenderer.js";
|
|
4
4
|
import { standardCatalog as s } from "./standard-catalog/index.js";
|
|
5
|
-
import { useDispatchAction as
|
|
6
|
-
import { useDataBinding as
|
|
7
|
-
import { useValidation as
|
|
8
|
-
import { useSurfaceContext as
|
|
9
|
-
import { useScope as D, useScopeBasePath as
|
|
5
|
+
import { useDispatchAction as x } from "./hooks/useDispatchAction.js";
|
|
6
|
+
import { useDataBinding as f, useDataModel as u, useFormBinding as c, useStringBinding as g } from "./hooks/useDataBinding.js";
|
|
7
|
+
import { useValidation as B } from "./hooks/useValidation.js";
|
|
8
|
+
import { useSurfaceContext as S } from "./contexts/SurfaceContext.js";
|
|
9
|
+
import { useScope as D, useScopeBasePath as P } from "./contexts/ScopeContext.js";
|
|
10
|
+
import { ActionProvider as v, useActionContext as I } from "./contexts/ActionContext.js";
|
|
10
11
|
export {
|
|
11
12
|
r as A2UIProvider,
|
|
12
13
|
n as A2UIRenderer,
|
|
13
|
-
|
|
14
|
+
v as ActionProvider,
|
|
15
|
+
a as ComponentRenderer,
|
|
14
16
|
s as standardCatalog,
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
I as useActionContext,
|
|
18
|
+
f as useDataBinding,
|
|
19
|
+
u as useDataModel,
|
|
20
|
+
x as useDispatchAction,
|
|
18
21
|
c as useFormBinding,
|
|
19
22
|
D as useScope,
|
|
20
|
-
|
|
23
|
+
P as useScopeBasePath,
|
|
21
24
|
g as useStringBinding,
|
|
22
|
-
|
|
23
|
-
|
|
25
|
+
S as useSurfaceContext,
|
|
26
|
+
B as useValidation
|
|
24
27
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@a2ui-sdk/react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "A2UI SDK for React",
|
|
5
5
|
"homepage": "https://a2ui-sdk.js.org/",
|
|
6
6
|
"repository": {
|
|
@@ -66,8 +66,8 @@
|
|
|
66
66
|
"vitest": "^4.0.16"
|
|
67
67
|
},
|
|
68
68
|
"dependencies": {
|
|
69
|
-
"@a2ui-sdk/types": "0.
|
|
70
|
-
"@a2ui-sdk/utils": "0.
|
|
69
|
+
"@a2ui-sdk/types": "0.3.0",
|
|
70
|
+
"@a2ui-sdk/utils": "0.3.0",
|
|
71
71
|
"@radix-ui/react-checkbox": "^1.3.3",
|
|
72
72
|
"@radix-ui/react-dialog": "^1.1.15",
|
|
73
73
|
"@radix-ui/react-label": "^2.1.8",
|