@copilotkit/a2ui-renderer 1.51.4 → 1.51.5-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/A2UIMessageRenderer.cjs +135 -0
- package/dist/A2UIMessageRenderer.cjs.map +1 -0
- package/dist/A2UIMessageRenderer.d.cts +11 -0
- package/dist/A2UIMessageRenderer.d.cts.map +1 -0
- package/dist/A2UIMessageRenderer.d.mts +11 -0
- package/dist/A2UIMessageRenderer.d.mts.map +1 -0
- package/dist/A2UIMessageRenderer.mjs +134 -0
- package/dist/A2UIMessageRenderer.mjs.map +1 -0
- package/dist/A2UIViewer.cjs +154 -0
- package/dist/A2UIViewer.cjs.map +1 -0
- package/dist/A2UIViewer.d.cts +39 -0
- package/dist/A2UIViewer.d.cts.map +1 -0
- package/dist/A2UIViewer.d.mts +39 -0
- package/dist/A2UIViewer.d.mts.map +1 -0
- package/dist/A2UIViewer.mjs +152 -0
- package/dist/A2UIViewer.mjs.map +1 -0
- package/dist/_virtual/_rolldown/runtime.cjs +29 -0
- package/dist/index.cjs +8 -0
- package/dist/index.d.cts +15 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +15 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +5 -0
- package/dist/index.umd.js +3070 -2
- package/dist/index.umd.js.map +1 -1
- package/dist/react-renderer/components/content/AudioPlayer.cjs +34 -0
- package/dist/react-renderer/components/content/AudioPlayer.cjs.map +1 -0
- package/dist/react-renderer/components/content/AudioPlayer.mjs +33 -0
- package/dist/react-renderer/components/content/AudioPlayer.mjs.map +1 -0
- package/dist/react-renderer/components/content/Divider.cjs +31 -0
- package/dist/react-renderer/components/content/Divider.cjs.map +1 -0
- package/dist/react-renderer/components/content/Divider.mjs +30 -0
- package/dist/react-renderer/components/content/Divider.mjs.map +1 -0
- package/dist/react-renderer/components/content/Icon.cjs +50 -0
- package/dist/react-renderer/components/content/Icon.cjs.map +1 -0
- package/dist/react-renderer/components/content/Icon.mjs +49 -0
- package/dist/react-renderer/components/content/Icon.mjs.map +1 -0
- package/dist/react-renderer/components/content/Image.cjs +43 -0
- package/dist/react-renderer/components/content/Image.cjs.map +1 -0
- package/dist/react-renderer/components/content/Image.mjs +42 -0
- package/dist/react-renderer/components/content/Image.mjs.map +1 -0
- package/dist/react-renderer/components/content/Text.cjs +131 -0
- package/dist/react-renderer/components/content/Text.cjs.map +1 -0
- package/dist/react-renderer/components/content/Text.mjs +129 -0
- package/dist/react-renderer/components/content/Text.mjs.map +1 -0
- package/dist/react-renderer/components/content/Video.cjs +56 -0
- package/dist/react-renderer/components/content/Video.cjs.map +1 -0
- package/dist/react-renderer/components/content/Video.mjs +55 -0
- package/dist/react-renderer/components/content/Video.mjs.map +1 -0
- package/dist/react-renderer/components/interactive/Button.cjs +39 -0
- package/dist/react-renderer/components/interactive/Button.cjs.map +1 -0
- package/dist/react-renderer/components/interactive/Button.mjs +38 -0
- package/dist/react-renderer/components/interactive/Button.mjs.map +1 -0
- package/dist/react-renderer/components/interactive/CheckBox.cjs +58 -0
- package/dist/react-renderer/components/interactive/CheckBox.cjs.map +1 -0
- package/dist/react-renderer/components/interactive/CheckBox.mjs +57 -0
- package/dist/react-renderer/components/interactive/CheckBox.mjs.map +1 -0
- package/dist/react-renderer/components/interactive/DateTimeInput.cjs +65 -0
- package/dist/react-renderer/components/interactive/DateTimeInput.cjs.map +1 -0
- package/dist/react-renderer/components/interactive/DateTimeInput.mjs +64 -0
- package/dist/react-renderer/components/interactive/DateTimeInput.mjs.map +1 -0
- package/dist/react-renderer/components/interactive/MultipleChoice.cjs +54 -0
- package/dist/react-renderer/components/interactive/MultipleChoice.cjs.map +1 -0
- package/dist/react-renderer/components/interactive/MultipleChoice.mjs +53 -0
- package/dist/react-renderer/components/interactive/MultipleChoice.mjs.map +1 -0
- package/dist/react-renderer/components/interactive/Slider.cjs +72 -0
- package/dist/react-renderer/components/interactive/Slider.cjs.map +1 -0
- package/dist/react-renderer/components/interactive/Slider.mjs +71 -0
- package/dist/react-renderer/components/interactive/Slider.mjs.map +1 -0
- package/dist/react-renderer/components/interactive/TextField.cjs +74 -0
- package/dist/react-renderer/components/interactive/TextField.cjs.map +1 -0
- package/dist/react-renderer/components/interactive/TextField.mjs +73 -0
- package/dist/react-renderer/components/interactive/TextField.mjs.map +1 -0
- package/dist/react-renderer/components/layout/Card.cjs +46 -0
- package/dist/react-renderer/components/layout/Card.cjs.map +1 -0
- package/dist/react-renderer/components/layout/Card.mjs +45 -0
- package/dist/react-renderer/components/layout/Card.mjs.map +1 -0
- package/dist/react-renderer/components/layout/Column.cjs +43 -0
- package/dist/react-renderer/components/layout/Column.cjs.map +1 -0
- package/dist/react-renderer/components/layout/Column.mjs +42 -0
- package/dist/react-renderer/components/layout/Column.mjs.map +1 -0
- package/dist/react-renderer/components/layout/List.cjs +41 -0
- package/dist/react-renderer/components/layout/List.cjs.map +1 -0
- package/dist/react-renderer/components/layout/List.mjs +40 -0
- package/dist/react-renderer/components/layout/List.mjs.map +1 -0
- package/dist/react-renderer/components/layout/Modal.cjs +92 -0
- package/dist/react-renderer/components/layout/Modal.cjs.map +1 -0
- package/dist/react-renderer/components/layout/Modal.mjs +91 -0
- package/dist/react-renderer/components/layout/Modal.mjs.map +1 -0
- package/dist/react-renderer/components/layout/Row.cjs +43 -0
- package/dist/react-renderer/components/layout/Row.cjs.map +1 -0
- package/dist/react-renderer/components/layout/Row.mjs +42 -0
- package/dist/react-renderer/components/layout/Row.mjs.map +1 -0
- package/dist/react-renderer/components/layout/Tabs.cjs +47 -0
- package/dist/react-renderer/components/layout/Tabs.cjs.map +1 -0
- package/dist/react-renderer/components/layout/Tabs.mjs +46 -0
- package/dist/react-renderer/components/layout/Tabs.mjs.map +1 -0
- package/dist/react-renderer/core/A2UIProvider.cjs +123 -0
- package/dist/react-renderer/core/A2UIProvider.cjs.map +1 -0
- package/dist/react-renderer/core/A2UIProvider.mjs +120 -0
- package/dist/react-renderer/core/A2UIProvider.mjs.map +1 -0
- package/dist/react-renderer/core/A2UIRenderer.cjs +93 -0
- package/dist/react-renderer/core/A2UIRenderer.cjs.map +1 -0
- package/dist/react-renderer/core/A2UIRenderer.mjs +92 -0
- package/dist/react-renderer/core/A2UIRenderer.mjs.map +1 -0
- package/dist/react-renderer/core/ComponentNode.cjs +53 -0
- package/dist/react-renderer/core/ComponentNode.cjs.map +1 -0
- package/dist/react-renderer/core/ComponentNode.mjs +52 -0
- package/dist/react-renderer/core/ComponentNode.mjs.map +1 -0
- package/dist/react-renderer/hooks/useA2UI.cjs +46 -0
- package/dist/react-renderer/hooks/useA2UI.cjs.map +1 -0
- package/dist/react-renderer/hooks/useA2UI.mjs +46 -0
- package/dist/react-renderer/hooks/useA2UI.mjs.map +1 -0
- package/dist/react-renderer/hooks/useA2UIComponent.cjs +173 -0
- package/dist/react-renderer/hooks/useA2UIComponent.cjs.map +1 -0
- package/dist/react-renderer/hooks/useA2UIComponent.mjs +172 -0
- package/dist/react-renderer/hooks/useA2UIComponent.mjs.map +1 -0
- package/dist/react-renderer/lib/utils.cjs +39 -0
- package/dist/react-renderer/lib/utils.cjs.map +1 -0
- package/dist/react-renderer/lib/utils.mjs +37 -0
- package/dist/react-renderer/lib/utils.mjs.map +1 -0
- package/dist/react-renderer/registry/ComponentRegistry.cjs +114 -0
- package/dist/react-renderer/registry/ComponentRegistry.cjs.map +1 -0
- package/dist/react-renderer/registry/ComponentRegistry.mjs +113 -0
- package/dist/react-renderer/registry/ComponentRegistry.mjs.map +1 -0
- package/dist/react-renderer/registry/defaultCatalog.cjs +57 -0
- package/dist/react-renderer/registry/defaultCatalog.cjs.map +1 -0
- package/dist/react-renderer/registry/defaultCatalog.mjs +57 -0
- package/dist/react-renderer/registry/defaultCatalog.mjs.map +1 -0
- package/dist/react-renderer/styles/index.cjs +458 -0
- package/dist/react-renderer/styles/index.cjs.map +1 -0
- package/dist/react-renderer/styles/{index.js → index.mjs} +47 -64
- package/dist/react-renderer/styles/index.mjs.map +1 -0
- package/dist/react-renderer/styles/reset.cjs +29 -0
- package/dist/react-renderer/styles/reset.cjs.map +1 -0
- package/dist/react-renderer/styles/reset.mjs +28 -0
- package/dist/react-renderer/styles/reset.mjs.map +1 -0
- package/dist/react-renderer/theme/ThemeContext.cjs +35 -0
- package/dist/react-renderer/theme/ThemeContext.cjs.map +1 -0
- package/dist/react-renderer/theme/ThemeContext.mjs +33 -0
- package/dist/react-renderer/theme/ThemeContext.mjs.map +1 -0
- package/dist/react-renderer/theme/litTheme.cjs +368 -0
- package/dist/react-renderer/theme/litTheme.cjs.map +1 -0
- package/dist/react-renderer/theme/litTheme.mjs +367 -0
- package/dist/react-renderer/theme/litTheme.mjs.map +1 -0
- package/dist/react-renderer/theme/utils.cjs +41 -0
- package/dist/react-renderer/theme/utils.cjs.map +1 -0
- package/dist/react-renderer/theme/utils.mjs +39 -0
- package/dist/react-renderer/theme/utils.mjs.map +1 -0
- package/dist/theme/viewer-theme.cjs +366 -0
- package/dist/theme/viewer-theme.cjs.map +1 -0
- package/dist/theme/viewer-theme.d.cts +7 -0
- package/dist/theme/viewer-theme.d.cts.map +1 -0
- package/dist/theme/viewer-theme.d.mts +7 -0
- package/dist/theme/viewer-theme.d.mts.map +1 -0
- package/dist/theme/viewer-theme.mjs +365 -0
- package/dist/theme/viewer-theme.mjs.map +1 -0
- package/package.json +14 -9
- package/dist/.tsbuildinfo +0 -1
- package/dist/A2UIMessageRenderer.d.ts +0 -7
- package/dist/A2UIMessageRenderer.d.ts.map +0 -1
- package/dist/A2UIMessageRenderer.js +0 -126
- package/dist/A2UIMessageRenderer.js.map +0 -1
- package/dist/A2UIViewer.d.ts +0 -32
- package/dist/A2UIViewer.d.ts.map +0 -1
- package/dist/A2UIViewer.js +0 -121
- package/dist/A2UIViewer.js.map +0 -1
- package/dist/__tests__/A2UIMessageRenderer.test.d.ts +0 -2
- package/dist/__tests__/A2UIMessageRenderer.test.d.ts.map +0 -1
- package/dist/__tests__/A2UIMessageRenderer.test.js +0 -229
- package/dist/__tests__/A2UIMessageRenderer.test.js.map +0 -1
- package/dist/__tests__/clsx-shim.d.ts +0 -8
- package/dist/__tests__/clsx-shim.d.ts.map +0 -1
- package/dist/__tests__/clsx-shim.js +0 -24
- package/dist/__tests__/clsx-shim.js.map +0 -1
- package/dist/__tests__/setup.d.ts +0 -2
- package/dist/__tests__/setup.d.ts.map +0 -1
- package/dist/__tests__/setup.js +0 -29
- package/dist/__tests__/setup.js.map +0 -1
- package/dist/index.d.ts +0 -13
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -19
- package/dist/index.js.map +0 -1
- package/dist/react-renderer/components/content/AudioPlayer.d.ts +0 -8
- package/dist/react-renderer/components/content/AudioPlayer.d.ts.map +0 -1
- package/dist/react-renderer/components/content/AudioPlayer.js +0 -23
- package/dist/react-renderer/components/content/AudioPlayer.js.map +0 -1
- package/dist/react-renderer/components/content/Divider.d.ts +0 -13
- package/dist/react-renderer/components/content/Divider.d.ts.map +0 -1
- package/dist/react-renderer/components/content/Divider.js +0 -22
- package/dist/react-renderer/components/content/Divider.js.map +0 -1
- package/dist/react-renderer/components/content/Icon.d.ts +0 -16
- package/dist/react-renderer/components/content/Icon.d.ts.map +0 -1
- package/dist/react-renderer/components/content/Icon.js +0 -40
- package/dist/react-renderer/components/content/Icon.js.map +0 -1
- package/dist/react-renderer/components/content/Image.d.ts +0 -11
- package/dist/react-renderer/components/content/Image.d.ts.map +0 -1
- package/dist/react-renderer/components/content/Image.js +0 -34
- package/dist/react-renderer/components/content/Image.js.map +0 -1
- package/dist/react-renderer/components/content/Text.d.ts +0 -28
- package/dist/react-renderer/components/content/Text.d.ts.map +0 -1
- package/dist/react-renderer/components/content/Text.js +0 -134
- package/dist/react-renderer/components/content/Text.js.map +0 -1
- package/dist/react-renderer/components/content/Video.d.ts +0 -10
- package/dist/react-renderer/components/content/Video.d.ts.map +0 -1
- package/dist/react-renderer/components/content/Video.js +0 -41
- package/dist/react-renderer/components/content/Video.js.map +0 -1
- package/dist/react-renderer/components/content/index.d.ts +0 -7
- package/dist/react-renderer/components/content/index.d.ts.map +0 -1
- package/dist/react-renderer/components/content/index.js +0 -7
- package/dist/react-renderer/components/content/index.js.map +0 -1
- package/dist/react-renderer/components/interactive/Button.d.ts +0 -11
- package/dist/react-renderer/components/interactive/Button.d.ts.map +0 -1
- package/dist/react-renderer/components/interactive/Button.js +0 -27
- package/dist/react-renderer/components/interactive/Button.js.map +0 -1
- package/dist/react-renderer/components/interactive/CheckBox.d.ts +0 -10
- package/dist/react-renderer/components/interactive/CheckBox.d.ts.map +0 -1
- package/dist/react-renderer/components/interactive/CheckBox.js +0 -55
- package/dist/react-renderer/components/interactive/CheckBox.js.map +0 -1
- package/dist/react-renderer/components/interactive/DateTimeInput.d.ts +0 -10
- package/dist/react-renderer/components/interactive/DateTimeInput.d.ts.map +0 -1
- package/dist/react-renderer/components/interactive/DateTimeInput.js +0 -68
- package/dist/react-renderer/components/interactive/DateTimeInput.js.map +0 -1
- package/dist/react-renderer/components/interactive/MultipleChoice.d.ts +0 -11
- package/dist/react-renderer/components/interactive/MultipleChoice.d.ts.map +0 -1
- package/dist/react-renderer/components/interactive/MultipleChoice.js +0 -43
- package/dist/react-renderer/components/interactive/MultipleChoice.js.map +0 -1
- package/dist/react-renderer/components/interactive/Slider.d.ts +0 -10
- package/dist/react-renderer/components/interactive/Slider.d.ts.map +0 -1
- package/dist/react-renderer/components/interactive/Slider.js +0 -62
- package/dist/react-renderer/components/interactive/Slider.js.map +0 -1
- package/dist/react-renderer/components/interactive/TextField.d.ts +0 -10
- package/dist/react-renderer/components/interactive/TextField.d.ts.map +0 -1
- package/dist/react-renderer/components/interactive/TextField.js +0 -59
- package/dist/react-renderer/components/interactive/TextField.js.map +0 -1
- package/dist/react-renderer/components/interactive/index.d.ts +0 -7
- package/dist/react-renderer/components/interactive/index.d.ts.map +0 -1
- package/dist/react-renderer/components/interactive/index.js +0 -7
- package/dist/react-renderer/components/interactive/index.js.map +0 -1
- package/dist/react-renderer/components/layout/Card.d.ts +0 -17
- package/dist/react-renderer/components/layout/Card.d.ts.map +0 -1
- package/dist/react-renderer/components/layout/Card.js +0 -39
- package/dist/react-renderer/components/layout/Card.js.map +0 -1
- package/dist/react-renderer/components/layout/Column.d.ts +0 -10
- package/dist/react-renderer/components/layout/Column.d.ts.map +0 -1
- package/dist/react-renderer/components/layout/Column.js +0 -33
- package/dist/react-renderer/components/layout/Column.js.map +0 -1
- package/dist/react-renderer/components/layout/List.d.ts +0 -10
- package/dist/react-renderer/components/layout/List.d.ts.map +0 -1
- package/dist/react-renderer/components/layout/List.js +0 -32
- package/dist/react-renderer/components/layout/List.js.map +0 -1
- package/dist/react-renderer/components/layout/Modal.d.ts +0 -15
- package/dist/react-renderer/components/layout/Modal.d.ts.map +0 -1
- package/dist/react-renderer/components/layout/Modal.js +0 -65
- package/dist/react-renderer/components/layout/Modal.js.map +0 -1
- package/dist/react-renderer/components/layout/Row.d.ts +0 -10
- package/dist/react-renderer/components/layout/Row.d.ts.map +0 -1
- package/dist/react-renderer/components/layout/Row.js +0 -33
- package/dist/react-renderer/components/layout/Row.js.map +0 -1
- package/dist/react-renderer/components/layout/Tabs.d.ts +0 -8
- package/dist/react-renderer/components/layout/Tabs.d.ts.map +0 -1
- package/dist/react-renderer/components/layout/Tabs.js +0 -29
- package/dist/react-renderer/components/layout/Tabs.js.map +0 -1
- package/dist/react-renderer/components/layout/index.d.ts +0 -7
- package/dist/react-renderer/components/layout/index.d.ts.map +0 -1
- package/dist/react-renderer/components/layout/index.js +0 -7
- package/dist/react-renderer/components/layout/index.js.map +0 -1
- package/dist/react-renderer/core/A2UIProvider.d.ts +0 -82
- package/dist/react-renderer/core/A2UIProvider.d.ts.map +0 -1
- package/dist/react-renderer/core/A2UIProvider.js +0 -156
- package/dist/react-renderer/core/A2UIProvider.js.map +0 -1
- package/dist/react-renderer/core/A2UIRenderer.d.ts +0 -36
- package/dist/react-renderer/core/A2UIRenderer.d.ts.map +0 -1
- package/dist/react-renderer/core/A2UIRenderer.js +0 -83
- package/dist/react-renderer/core/A2UIRenderer.js.map +0 -1
- package/dist/react-renderer/core/A2UIViewer.d.ts +0 -56
- package/dist/react-renderer/core/A2UIViewer.d.ts.map +0 -1
- package/dist/react-renderer/core/A2UIViewer.js +0 -135
- package/dist/react-renderer/core/A2UIViewer.js.map +0 -1
- package/dist/react-renderer/core/ComponentNode.d.ts +0 -25
- package/dist/react-renderer/core/ComponentNode.d.ts.map +0 -1
- package/dist/react-renderer/core/ComponentNode.js +0 -43
- package/dist/react-renderer/core/ComponentNode.js.map +0 -1
- package/dist/react-renderer/core/store.d.ts +0 -37
- package/dist/react-renderer/core/store.d.ts.map +0 -1
- package/dist/react-renderer/core/store.js +0 -2
- package/dist/react-renderer/core/store.js.map +0 -1
- package/dist/react-renderer/hooks/useA2UI.d.ts +0 -46
- package/dist/react-renderer/hooks/useA2UI.d.ts.map +0 -1
- package/dist/react-renderer/hooks/useA2UI.js +0 -41
- package/dist/react-renderer/hooks/useA2UI.js.map +0 -1
- package/dist/react-renderer/hooks/useA2UIComponent.d.ts +0 -52
- package/dist/react-renderer/hooks/useA2UIComponent.d.ts.map +0 -1
- package/dist/react-renderer/hooks/useA2UIComponent.js +0 -175
- package/dist/react-renderer/hooks/useA2UIComponent.js.map +0 -1
- package/dist/react-renderer/index.d.ts +0 -37
- package/dist/react-renderer/index.d.ts.map +0 -1
- package/dist/react-renderer/index.js +0 -40
- package/dist/react-renderer/index.js.map +0 -1
- package/dist/react-renderer/lib/utils.d.ts +0 -32
- package/dist/react-renderer/lib/utils.d.ts.map +0 -1
- package/dist/react-renderer/lib/utils.js +0 -41
- package/dist/react-renderer/lib/utils.js.map +0 -1
- package/dist/react-renderer/registry/ComponentRegistry.d.ts +0 -78
- package/dist/react-renderer/registry/ComponentRegistry.d.ts.map +0 -1
- package/dist/react-renderer/registry/ComponentRegistry.js +0 -113
- package/dist/react-renderer/registry/ComponentRegistry.js.map +0 -1
- package/dist/react-renderer/registry/defaultCatalog.d.ts +0 -13
- package/dist/react-renderer/registry/defaultCatalog.d.ts.map +0 -1
- package/dist/react-renderer/registry/defaultCatalog.js +0 -59
- package/dist/react-renderer/registry/defaultCatalog.js.map +0 -1
- package/dist/react-renderer/styles/index.d.ts +0 -41
- package/dist/react-renderer/styles/index.d.ts.map +0 -1
- package/dist/react-renderer/styles/index.js.map +0 -1
- package/dist/react-renderer/styles/reset.d.ts +0 -18
- package/dist/react-renderer/styles/reset.d.ts.map +0 -1
- package/dist/react-renderer/styles/reset.js +0 -24
- package/dist/react-renderer/styles/reset.js.map +0 -1
- package/dist/react-renderer/theme/ThemeContext.d.ts +0 -29
- package/dist/react-renderer/theme/ThemeContext.d.ts.map +0 -1
- package/dist/react-renderer/theme/ThemeContext.js +0 -35
- package/dist/react-renderer/theme/ThemeContext.js.map +0 -1
- package/dist/react-renderer/theme/litTheme.d.ts +0 -8
- package/dist/react-renderer/theme/litTheme.d.ts.map +0 -1
- package/dist/react-renderer/theme/litTheme.js +0 -401
- package/dist/react-renderer/theme/litTheme.js.map +0 -1
- package/dist/react-renderer/theme/utils.d.ts +0 -23
- package/dist/react-renderer/theme/utils.d.ts.map +0 -1
- package/dist/react-renderer/theme/utils.js +0 -46
- package/dist/react-renderer/theme/utils.js.map +0 -1
- package/dist/react-renderer/types.d.ts +0 -53
- package/dist/react-renderer/types.d.ts.map +0 -1
- package/dist/react-renderer/types.js +0 -2
- package/dist/react-renderer/types.js.map +0 -1
- package/dist/theme/viewer-theme.d.ts +0 -3
- package/dist/theme/viewer-theme.d.ts.map +0 -1
- package/dist/theme/viewer-theme.js +0 -391
- package/dist/theme/viewer-theme.js.map +0 -1
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { ComponentRegistry } from "../registry/ComponentRegistry.mjs";
|
|
2
|
+
import { Suspense, memo, useMemo } from "react";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
|
|
5
|
+
//#region src/react-renderer/core/ComponentNode.tsx
|
|
6
|
+
/** Memoized loading fallback to avoid recreating on each render */
|
|
7
|
+
const LoadingFallback = memo(function LoadingFallback() {
|
|
8
|
+
return /* @__PURE__ */ jsx("div", {
|
|
9
|
+
className: "a2ui-loading",
|
|
10
|
+
style: {
|
|
11
|
+
padding: "8px",
|
|
12
|
+
opacity: .5
|
|
13
|
+
},
|
|
14
|
+
children: "Loading..."
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
/**
|
|
18
|
+
* ComponentNode - dynamically renders an A2UI component based on its type.
|
|
19
|
+
*
|
|
20
|
+
* Looks up the component in the registry and renders it with the appropriate props.
|
|
21
|
+
* Supports lazy-loaded components via React.Suspense.
|
|
22
|
+
*
|
|
23
|
+
* No wrapper div is rendered - the component's root div (e.g., .a2ui-image) is the
|
|
24
|
+
* direct flex child, exactly matching Lit's structure where the :host element IS
|
|
25
|
+
* the flex item. Each component handles --weight CSS variable on its root div.
|
|
26
|
+
*
|
|
27
|
+
* Memoized to prevent unnecessary re-renders when parent updates but node hasn't changed.
|
|
28
|
+
*/
|
|
29
|
+
const ComponentNode = memo(function ComponentNode({ node, surfaceId, registry }) {
|
|
30
|
+
const actualRegistry = registry ?? ComponentRegistry.getInstance();
|
|
31
|
+
const nodeType = node && typeof node === "object" && "type" in node ? node.type : null;
|
|
32
|
+
const Component = useMemo(() => nodeType ? actualRegistry.get(nodeType) : null, [actualRegistry, nodeType]);
|
|
33
|
+
if (!nodeType) {
|
|
34
|
+
if (node) console.warn("[A2UI] Invalid component node (not resolved?):", node);
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
if (!Component) {
|
|
38
|
+
console.warn(`[A2UI] Unknown component type: ${nodeType}`);
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
return /* @__PURE__ */ jsx(Suspense, {
|
|
42
|
+
fallback: /* @__PURE__ */ jsx(LoadingFallback, {}),
|
|
43
|
+
children: /* @__PURE__ */ jsx(Component, {
|
|
44
|
+
node,
|
|
45
|
+
surfaceId
|
|
46
|
+
})
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
//#endregion
|
|
51
|
+
export { ComponentNode as default };
|
|
52
|
+
//# sourceMappingURL=ComponentNode.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ComponentNode.mjs","names":[],"sources":["../../../src/react-renderer/core/ComponentNode.tsx"],"sourcesContent":["import { Suspense, useMemo, memo } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport { ComponentRegistry } from \"../registry/ComponentRegistry\";\n\n/** Memoized loading fallback to avoid recreating on each render */\nconst LoadingFallback = memo(function LoadingFallback() {\n return (\n <div className=\"a2ui-loading\" style={{ padding: \"8px\", opacity: 0.5 }}>\n Loading...\n </div>\n );\n});\n\ninterface ComponentNodeProps {\n /** The component node to render (can be null/undefined for safety) */\n node: Types.AnyComponentNode | null | undefined;\n /** The surface ID this component belongs to */\n surfaceId: string;\n /** Optional custom registry. Falls back to singleton. */\n registry?: ComponentRegistry;\n}\n\n/**\n * ComponentNode - dynamically renders an A2UI component based on its type.\n *\n * Looks up the component in the registry and renders it with the appropriate props.\n * Supports lazy-loaded components via React.Suspense.\n *\n * No wrapper div is rendered - the component's root div (e.g., .a2ui-image) is the\n * direct flex child, exactly matching Lit's structure where the :host element IS\n * the flex item. Each component handles --weight CSS variable on its root div.\n *\n * Memoized to prevent unnecessary re-renders when parent updates but node hasn't changed.\n */\nexport const ComponentNode = memo(function ComponentNode({\n node,\n surfaceId,\n registry,\n}: ComponentNodeProps) {\n const actualRegistry = registry ?? ComponentRegistry.getInstance();\n\n // useMemo must be called unconditionally (Rules of Hooks)\n // We handle invalid nodes by returning null component type\n const nodeType =\n node && typeof node === \"object\" && \"type\" in node ? node.type : null;\n\n const Component = useMemo(\n () => (nodeType ? actualRegistry.get(nodeType) : null),\n [actualRegistry, nodeType],\n );\n\n // Handle null/undefined/invalid nodes gracefully\n if (!nodeType) {\n if (node) {\n console.warn(\"[A2UI] Invalid component node (not resolved?):\", node);\n }\n return null;\n }\n\n if (!Component) {\n console.warn(`[A2UI] Unknown component type: ${nodeType}`);\n return null;\n }\n\n // No wrapper div - component's root div is the :host equivalent\n // Suspense doesn't add DOM elements, preserving the correct hierarchy\n // Type assertion is safe: we've already validated node is valid (nodeType check above)\n return (\n <Suspense fallback={<LoadingFallback />}>\n <Component node={node as Types.AnyComponentNode} surfaceId={surfaceId} />\n </Suspense>\n );\n});\n\nexport default ComponentNode;\n"],"mappings":";;;;;;AAKA,MAAM,kBAAkB,KAAK,SAAS,kBAAkB;AACtD,QACE,oBAAC;EAAI,WAAU;EAAe,OAAO;GAAE,SAAS;GAAO,SAAS;GAAK;YAAE;GAEjE;EAER;;;;;;;;;;;;;AAuBF,MAAa,gBAAgB,KAAK,SAAS,cAAc,EACvD,MACA,WACA,YACqB;CACrB,MAAM,iBAAiB,YAAY,kBAAkB,aAAa;CAIlE,MAAM,WACJ,QAAQ,OAAO,SAAS,YAAY,UAAU,OAAO,KAAK,OAAO;CAEnE,MAAM,YAAY,cACT,WAAW,eAAe,IAAI,SAAS,GAAG,MACjD,CAAC,gBAAgB,SAAS,CAC3B;AAGD,KAAI,CAAC,UAAU;AACb,MAAI,KACF,SAAQ,KAAK,kDAAkD,KAAK;AAEtE,SAAO;;AAGT,KAAI,CAAC,WAAW;AACd,UAAQ,KAAK,kCAAkC,WAAW;AAC1D,SAAO;;AAMT,QACE,oBAAC;EAAS,UAAU,oBAAC,oBAAkB;YACrC,oBAAC;GAAgB;GAA2C;IAAa;GAChE;EAEb"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
const require_A2UIProvider = require('../core/A2UIProvider.cjs');
|
|
2
|
+
|
|
3
|
+
//#region src/react-renderer/hooks/useA2UI.ts
|
|
4
|
+
/**
|
|
5
|
+
* Main API hook for A2UI. Provides methods to process messages
|
|
6
|
+
* and access surface state.
|
|
7
|
+
*
|
|
8
|
+
* Note: This hook subscribes to state changes. Components using this
|
|
9
|
+
* will re-render when the A2UI state changes. For action-only usage
|
|
10
|
+
* (no re-renders), use useA2UIActions() instead.
|
|
11
|
+
*
|
|
12
|
+
* @returns Object with message processing and surface access methods
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```tsx
|
|
16
|
+
* function ChatApp() {
|
|
17
|
+
* const { processMessages, getSurface } = useA2UI();
|
|
18
|
+
*
|
|
19
|
+
* useEffect(() => {
|
|
20
|
+
* const ws = new WebSocket('wss://agent.example.com');
|
|
21
|
+
* ws.onmessage = (event) => {
|
|
22
|
+
* const messages = JSON.parse(event.data);
|
|
23
|
+
* processMessages(messages);
|
|
24
|
+
* };
|
|
25
|
+
* return () => ws.close();
|
|
26
|
+
* }, [processMessages]);
|
|
27
|
+
*
|
|
28
|
+
* return <A2UIRenderer surfaceId="main" />;
|
|
29
|
+
* }
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
function useA2UI() {
|
|
33
|
+
const actions = require_A2UIProvider.useA2UIActions();
|
|
34
|
+
const state = require_A2UIProvider.useA2UIState();
|
|
35
|
+
return {
|
|
36
|
+
processMessages: actions.processMessages,
|
|
37
|
+
getSurface: actions.getSurface,
|
|
38
|
+
getSurfaces: actions.getSurfaces,
|
|
39
|
+
clearSurfaces: actions.clearSurfaces,
|
|
40
|
+
version: state.version
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
//#endregion
|
|
45
|
+
exports.useA2UI = useA2UI;
|
|
46
|
+
//# sourceMappingURL=useA2UI.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useA2UI.cjs","names":["useA2UIActions","useA2UIState"],"sources":["../../../src/react-renderer/hooks/useA2UI.ts"],"sourcesContent":["import type { Types } from \"@a2ui/lit/0.8\";\nimport { useA2UIActions, useA2UIState } from \"../core/A2UIProvider\";\n\n/**\n * Result returned by the useA2UI hook.\n */\nexport interface UseA2UIResult {\n /** Process incoming server messages */\n processMessages: (messages: Types.ServerToClientMessage[]) => void;\n\n /** Get a surface by ID */\n getSurface: (surfaceId: string) => Types.Surface | undefined;\n\n /** Get all surfaces */\n getSurfaces: () => ReadonlyMap<string, Types.Surface>;\n\n /** Clear all surfaces */\n clearSurfaces: () => void;\n\n /** The current version number (increments on state changes) */\n version: number;\n}\n\n/**\n * Main API hook for A2UI. Provides methods to process messages\n * and access surface state.\n *\n * Note: This hook subscribes to state changes. Components using this\n * will re-render when the A2UI state changes. For action-only usage\n * (no re-renders), use useA2UIActions() instead.\n *\n * @returns Object with message processing and surface access methods\n *\n * @example\n * ```tsx\n * function ChatApp() {\n * const { processMessages, getSurface } = useA2UI();\n *\n * useEffect(() => {\n * const ws = new WebSocket('wss://agent.example.com');\n * ws.onmessage = (event) => {\n * const messages = JSON.parse(event.data);\n * processMessages(messages);\n * };\n * return () => ws.close();\n * }, [processMessages]);\n *\n * return <A2UIRenderer surfaceId=\"main\" />;\n * }\n * ```\n */\nexport function useA2UI(): UseA2UIResult {\n const actions = useA2UIActions();\n const state = useA2UIState();\n\n return {\n processMessages: actions.processMessages,\n getSurface: actions.getSurface,\n getSurfaces: actions.getSurfaces,\n clearSurfaces: actions.clearSurfaces,\n version: state.version,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmDA,SAAgB,UAAyB;CACvC,MAAM,UAAUA,qCAAgB;CAChC,MAAM,QAAQC,mCAAc;AAE5B,QAAO;EACL,iBAAiB,QAAQ;EACzB,YAAY,QAAQ;EACpB,aAAa,QAAQ;EACrB,eAAe,QAAQ;EACvB,SAAS,MAAM;EAChB"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { useA2UIActions, useA2UIState } from "../core/A2UIProvider.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/react-renderer/hooks/useA2UI.ts
|
|
4
|
+
/**
|
|
5
|
+
* Main API hook for A2UI. Provides methods to process messages
|
|
6
|
+
* and access surface state.
|
|
7
|
+
*
|
|
8
|
+
* Note: This hook subscribes to state changes. Components using this
|
|
9
|
+
* will re-render when the A2UI state changes. For action-only usage
|
|
10
|
+
* (no re-renders), use useA2UIActions() instead.
|
|
11
|
+
*
|
|
12
|
+
* @returns Object with message processing and surface access methods
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```tsx
|
|
16
|
+
* function ChatApp() {
|
|
17
|
+
* const { processMessages, getSurface } = useA2UI();
|
|
18
|
+
*
|
|
19
|
+
* useEffect(() => {
|
|
20
|
+
* const ws = new WebSocket('wss://agent.example.com');
|
|
21
|
+
* ws.onmessage = (event) => {
|
|
22
|
+
* const messages = JSON.parse(event.data);
|
|
23
|
+
* processMessages(messages);
|
|
24
|
+
* };
|
|
25
|
+
* return () => ws.close();
|
|
26
|
+
* }, [processMessages]);
|
|
27
|
+
*
|
|
28
|
+
* return <A2UIRenderer surfaceId="main" />;
|
|
29
|
+
* }
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
function useA2UI() {
|
|
33
|
+
const actions = useA2UIActions();
|
|
34
|
+
const state = useA2UIState();
|
|
35
|
+
return {
|
|
36
|
+
processMessages: actions.processMessages,
|
|
37
|
+
getSurface: actions.getSurface,
|
|
38
|
+
getSurfaces: actions.getSurfaces,
|
|
39
|
+
clearSurfaces: actions.clearSurfaces,
|
|
40
|
+
version: state.version
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
//#endregion
|
|
45
|
+
export { useA2UI };
|
|
46
|
+
//# sourceMappingURL=useA2UI.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useA2UI.mjs","names":[],"sources":["../../../src/react-renderer/hooks/useA2UI.ts"],"sourcesContent":["import type { Types } from \"@a2ui/lit/0.8\";\nimport { useA2UIActions, useA2UIState } from \"../core/A2UIProvider\";\n\n/**\n * Result returned by the useA2UI hook.\n */\nexport interface UseA2UIResult {\n /** Process incoming server messages */\n processMessages: (messages: Types.ServerToClientMessage[]) => void;\n\n /** Get a surface by ID */\n getSurface: (surfaceId: string) => Types.Surface | undefined;\n\n /** Get all surfaces */\n getSurfaces: () => ReadonlyMap<string, Types.Surface>;\n\n /** Clear all surfaces */\n clearSurfaces: () => void;\n\n /** The current version number (increments on state changes) */\n version: number;\n}\n\n/**\n * Main API hook for A2UI. Provides methods to process messages\n * and access surface state.\n *\n * Note: This hook subscribes to state changes. Components using this\n * will re-render when the A2UI state changes. For action-only usage\n * (no re-renders), use useA2UIActions() instead.\n *\n * @returns Object with message processing and surface access methods\n *\n * @example\n * ```tsx\n * function ChatApp() {\n * const { processMessages, getSurface } = useA2UI();\n *\n * useEffect(() => {\n * const ws = new WebSocket('wss://agent.example.com');\n * ws.onmessage = (event) => {\n * const messages = JSON.parse(event.data);\n * processMessages(messages);\n * };\n * return () => ws.close();\n * }, [processMessages]);\n *\n * return <A2UIRenderer surfaceId=\"main\" />;\n * }\n * ```\n */\nexport function useA2UI(): UseA2UIResult {\n const actions = useA2UIActions();\n const state = useA2UIState();\n\n return {\n processMessages: actions.processMessages,\n getSurface: actions.getSurface,\n getSurfaces: actions.getSurfaces,\n clearSurfaces: actions.clearSurfaces,\n version: state.version,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmDA,SAAgB,UAAyB;CACvC,MAAM,UAAU,gBAAgB;CAChC,MAAM,QAAQ,cAAc;AAE5B,QAAO;EACL,iBAAiB,QAAQ;EACzB,YAAY,QAAQ;EACpB,aAAa,QAAQ;EACrB,eAAe,QAAQ;EACvB,SAAS,MAAM;EAChB"}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
const require_runtime = require('../../_virtual/_rolldown/runtime.cjs');
|
|
2
|
+
const require_ThemeContext = require('../theme/ThemeContext.cjs');
|
|
3
|
+
const require_A2UIProvider = require('../core/A2UIProvider.cjs');
|
|
4
|
+
let react = require("react");
|
|
5
|
+
|
|
6
|
+
//#region src/react-renderer/hooks/useA2UIComponent.ts
|
|
7
|
+
/**
|
|
8
|
+
* Base hook for A2UI components. Provides data binding, theme access,
|
|
9
|
+
* and action dispatching.
|
|
10
|
+
*
|
|
11
|
+
* @param node - The component node from the A2UI message processor
|
|
12
|
+
* @param surfaceId - The surface ID this component belongs to
|
|
13
|
+
* @returns Object with theme, data binding helpers, and action dispatcher
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```tsx
|
|
17
|
+
* function TextField({ node, surfaceId }: A2UIComponentProps<Types.TextFieldNode>) {
|
|
18
|
+
* const { theme, resolveString, setValue } = useA2UIComponent(node, surfaceId);
|
|
19
|
+
*
|
|
20
|
+
* const label = resolveString(node.properties.label);
|
|
21
|
+
* const value = resolveString(node.properties.text) ?? '';
|
|
22
|
+
*
|
|
23
|
+
* return (
|
|
24
|
+
* <div className={classMapToString(theme.components.TextField.container)}>
|
|
25
|
+
* <label>{label}</label>
|
|
26
|
+
* <input
|
|
27
|
+
* value={value}
|
|
28
|
+
* onChange={(e) => setValue(node.properties.text?.path!, e.target.value)}
|
|
29
|
+
* />
|
|
30
|
+
* </div>
|
|
31
|
+
* );
|
|
32
|
+
* }
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
function useA2UIComponent(node, surfaceId) {
|
|
36
|
+
const actions = require_A2UIProvider.useA2UIActions();
|
|
37
|
+
const theme = require_ThemeContext.useTheme();
|
|
38
|
+
const baseId = (0, react.useId)();
|
|
39
|
+
require_A2UIProvider.useA2UIState();
|
|
40
|
+
/**
|
|
41
|
+
* Resolve a StringValue to its actual string value.
|
|
42
|
+
* Checks literalString, literal, then path in that order.
|
|
43
|
+
* Note: This reads from data model via stable actions reference.
|
|
44
|
+
*/
|
|
45
|
+
const resolveString = (0, react.useCallback)((value) => {
|
|
46
|
+
if (!value) return null;
|
|
47
|
+
if (typeof value !== "object") return null;
|
|
48
|
+
if (value.literalString !== void 0) return value.literalString;
|
|
49
|
+
if (value.literal !== void 0) return String(value.literal);
|
|
50
|
+
if (value.path) {
|
|
51
|
+
const data = actions.getData(node, value.path, surfaceId);
|
|
52
|
+
return data !== null ? String(data) : null;
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
}, [
|
|
56
|
+
actions,
|
|
57
|
+
node,
|
|
58
|
+
surfaceId
|
|
59
|
+
]);
|
|
60
|
+
/**
|
|
61
|
+
* Resolve a NumberValue to its actual number value.
|
|
62
|
+
*/
|
|
63
|
+
const resolveNumber = (0, react.useCallback)((value) => {
|
|
64
|
+
if (!value) return null;
|
|
65
|
+
if (typeof value !== "object") return null;
|
|
66
|
+
if (value.literalNumber !== void 0) return value.literalNumber;
|
|
67
|
+
if (value.literal !== void 0) return Number(value.literal);
|
|
68
|
+
if (value.path) {
|
|
69
|
+
const data = actions.getData(node, value.path, surfaceId);
|
|
70
|
+
return data !== null ? Number(data) : null;
|
|
71
|
+
}
|
|
72
|
+
return null;
|
|
73
|
+
}, [
|
|
74
|
+
actions,
|
|
75
|
+
node,
|
|
76
|
+
surfaceId
|
|
77
|
+
]);
|
|
78
|
+
/**
|
|
79
|
+
* Resolve a BooleanValue to its actual boolean value.
|
|
80
|
+
*/
|
|
81
|
+
const resolveBoolean = (0, react.useCallback)((value) => {
|
|
82
|
+
if (!value) return null;
|
|
83
|
+
if (typeof value !== "object") return null;
|
|
84
|
+
if (value.literalBoolean !== void 0) return value.literalBoolean;
|
|
85
|
+
if (value.literal !== void 0) return Boolean(value.literal);
|
|
86
|
+
if (value.path) {
|
|
87
|
+
const data = actions.getData(node, value.path, surfaceId);
|
|
88
|
+
return data !== null ? Boolean(data) : null;
|
|
89
|
+
}
|
|
90
|
+
return null;
|
|
91
|
+
}, [
|
|
92
|
+
actions,
|
|
93
|
+
node,
|
|
94
|
+
surfaceId
|
|
95
|
+
]);
|
|
96
|
+
/**
|
|
97
|
+
* Set a value in the data model for two-way binding.
|
|
98
|
+
*/
|
|
99
|
+
const setValue = (0, react.useCallback)((path, value) => {
|
|
100
|
+
actions.setData(node, path, value, surfaceId);
|
|
101
|
+
}, [
|
|
102
|
+
actions,
|
|
103
|
+
node,
|
|
104
|
+
surfaceId
|
|
105
|
+
]);
|
|
106
|
+
/**
|
|
107
|
+
* Get a value from the data model.
|
|
108
|
+
*/
|
|
109
|
+
const getValue = (0, react.useCallback)((path) => {
|
|
110
|
+
return actions.getData(node, path, surfaceId);
|
|
111
|
+
}, [
|
|
112
|
+
actions,
|
|
113
|
+
node,
|
|
114
|
+
surfaceId
|
|
115
|
+
]);
|
|
116
|
+
/**
|
|
117
|
+
* Dispatch a user action to the server.
|
|
118
|
+
* Resolves all context bindings before dispatching.
|
|
119
|
+
*/
|
|
120
|
+
const sendAction = (0, react.useCallback)((action) => {
|
|
121
|
+
const actionContext = {};
|
|
122
|
+
if (action.context) {
|
|
123
|
+
for (const item of action.context) if (item.value.literalString !== void 0) actionContext[item.key] = item.value.literalString;
|
|
124
|
+
else if (item.value.literalNumber !== void 0) actionContext[item.key] = item.value.literalNumber;
|
|
125
|
+
else if (item.value.literalBoolean !== void 0) actionContext[item.key] = item.value.literalBoolean;
|
|
126
|
+
else if (item.value.path) {
|
|
127
|
+
const resolvedPath = actions.resolvePath(item.value.path, node.dataContextPath);
|
|
128
|
+
actionContext[item.key] = actions.getData(node, resolvedPath, surfaceId);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
actions.dispatch({ userAction: {
|
|
132
|
+
name: action.name,
|
|
133
|
+
sourceComponentId: node.id,
|
|
134
|
+
surfaceId,
|
|
135
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
136
|
+
context: actionContext
|
|
137
|
+
} });
|
|
138
|
+
}, [
|
|
139
|
+
actions,
|
|
140
|
+
node,
|
|
141
|
+
surfaceId
|
|
142
|
+
]);
|
|
143
|
+
/**
|
|
144
|
+
* Generate a unique ID for accessibility purposes.
|
|
145
|
+
* Uses React's useId() for SSR and Concurrent Mode compatibility.
|
|
146
|
+
*/
|
|
147
|
+
const getUniqueId = (0, react.useCallback)((prefix) => {
|
|
148
|
+
return `${prefix}${baseId}`;
|
|
149
|
+
}, [baseId]);
|
|
150
|
+
return (0, react.useMemo)(() => ({
|
|
151
|
+
theme,
|
|
152
|
+
resolveString,
|
|
153
|
+
resolveNumber,
|
|
154
|
+
resolveBoolean,
|
|
155
|
+
setValue,
|
|
156
|
+
getValue,
|
|
157
|
+
sendAction,
|
|
158
|
+
getUniqueId
|
|
159
|
+
}), [
|
|
160
|
+
theme,
|
|
161
|
+
resolveString,
|
|
162
|
+
resolveNumber,
|
|
163
|
+
resolveBoolean,
|
|
164
|
+
setValue,
|
|
165
|
+
getValue,
|
|
166
|
+
sendAction,
|
|
167
|
+
getUniqueId
|
|
168
|
+
]);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
//#endregion
|
|
172
|
+
exports.useA2UIComponent = useA2UIComponent;
|
|
173
|
+
//# sourceMappingURL=useA2UIComponent.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useA2UIComponent.cjs","names":["useA2UIActions","useTheme"],"sources":["../../../src/react-renderer/hooks/useA2UIComponent.ts"],"sourcesContent":["import { useCallback, useId, useMemo } from \"react\";\nimport type { Types, Primitives } from \"@a2ui/lit/0.8\";\nimport { useA2UIActions, useA2UIState } from \"../core/A2UIProvider\";\nimport { useTheme } from \"../theme/ThemeContext\";\n\n/**\n * Result returned by the useA2UIComponent hook.\n */\nexport interface UseA2UIComponentResult {\n /** The current theme */\n theme: Types.Theme;\n\n /** Resolve a StringValue to its actual string value */\n resolveString: (\n value: Primitives.StringValue | null | undefined,\n ) => string | null;\n\n /** Resolve a NumberValue to its actual number value */\n resolveNumber: (\n value: Primitives.NumberValue | null | undefined,\n ) => number | null;\n\n /** Resolve a BooleanValue to its actual boolean value */\n resolveBoolean: (\n value: Primitives.BooleanValue | null | undefined,\n ) => boolean | null;\n\n /** Set a value in the data model (for two-way binding) */\n setValue: (path: string, value: Types.DataValue) => void;\n\n /** Get a value from the data model */\n getValue: (path: string) => Types.DataValue | null;\n\n /** Dispatch a user action */\n sendAction: (action: Types.Action) => void;\n\n /** Generate a unique ID for accessibility */\n getUniqueId: (prefix: string) => string;\n}\n\n/**\n * Base hook for A2UI components. Provides data binding, theme access,\n * and action dispatching.\n *\n * @param node - The component node from the A2UI message processor\n * @param surfaceId - The surface ID this component belongs to\n * @returns Object with theme, data binding helpers, and action dispatcher\n *\n * @example\n * ```tsx\n * function TextField({ node, surfaceId }: A2UIComponentProps<Types.TextFieldNode>) {\n * const { theme, resolveString, setValue } = useA2UIComponent(node, surfaceId);\n *\n * const label = resolveString(node.properties.label);\n * const value = resolveString(node.properties.text) ?? '';\n *\n * return (\n * <div className={classMapToString(theme.components.TextField.container)}>\n * <label>{label}</label>\n * <input\n * value={value}\n * onChange={(e) => setValue(node.properties.text?.path!, e.target.value)}\n * />\n * </div>\n * );\n * }\n * ```\n */\nexport function useA2UIComponent<T extends Types.AnyComponentNode>(\n node: T,\n surfaceId: string,\n): UseA2UIComponentResult {\n // Use stable actions - won't cause re-renders when version changes\n const actions = useA2UIActions();\n const theme = useTheme();\n const baseId = useId();\n\n // Subscribe to data model version - triggers re-render when data changes via setData.\n // This ensures components with path bindings see updated values.\n // memo() doesn't block context-triggered re-renders.\n useA2UIState();\n\n /**\n * Resolve a StringValue to its actual string value.\n * Checks literalString, literal, then path in that order.\n * Note: This reads from data model via stable actions reference.\n */\n const resolveString = useCallback(\n (value: Primitives.StringValue | null | undefined): string | null => {\n if (!value) return null;\n if (typeof value !== \"object\") return null;\n\n if (value.literalString !== undefined) {\n return value.literalString;\n }\n if (value.literal !== undefined) {\n return String(value.literal);\n }\n if (value.path) {\n const data = actions.getData(node, value.path, surfaceId);\n return data !== null ? String(data) : null;\n }\n return null;\n },\n [actions, node, surfaceId],\n );\n\n /**\n * Resolve a NumberValue to its actual number value.\n */\n const resolveNumber = useCallback(\n (value: Primitives.NumberValue | null | undefined): number | null => {\n if (!value) return null;\n if (typeof value !== \"object\") return null;\n\n if (value.literalNumber !== undefined) {\n return value.literalNumber;\n }\n if (value.literal !== undefined) {\n return Number(value.literal);\n }\n if (value.path) {\n const data = actions.getData(node, value.path, surfaceId);\n return data !== null ? Number(data) : null;\n }\n return null;\n },\n [actions, node, surfaceId],\n );\n\n /**\n * Resolve a BooleanValue to its actual boolean value.\n */\n const resolveBoolean = useCallback(\n (value: Primitives.BooleanValue | null | undefined): boolean | null => {\n if (!value) return null;\n if (typeof value !== \"object\") return null;\n\n if (value.literalBoolean !== undefined) {\n return value.literalBoolean;\n }\n if (value.literal !== undefined) {\n return Boolean(value.literal);\n }\n if (value.path) {\n const data = actions.getData(node, value.path, surfaceId);\n return data !== null ? Boolean(data) : null;\n }\n return null;\n },\n [actions, node, surfaceId],\n );\n\n /**\n * Set a value in the data model for two-way binding.\n */\n const setValue = useCallback(\n (path: string, value: Types.DataValue) => {\n actions.setData(node, path, value, surfaceId);\n },\n [actions, node, surfaceId],\n );\n\n /**\n * Get a value from the data model.\n */\n const getValue = useCallback(\n (path: string): Types.DataValue | null => {\n return actions.getData(node, path, surfaceId);\n },\n [actions, node, surfaceId],\n );\n\n /**\n * Dispatch a user action to the server.\n * Resolves all context bindings before dispatching.\n */\n const sendAction = useCallback(\n (action: Types.Action) => {\n const actionContext: Record<string, unknown> = {};\n\n if (action.context) {\n for (const item of action.context) {\n if (item.value.literalString !== undefined) {\n actionContext[item.key] = item.value.literalString;\n } else if (item.value.literalNumber !== undefined) {\n actionContext[item.key] = item.value.literalNumber;\n } else if (item.value.literalBoolean !== undefined) {\n actionContext[item.key] = item.value.literalBoolean;\n } else if (item.value.path) {\n const resolvedPath = actions.resolvePath(\n item.value.path,\n node.dataContextPath,\n );\n actionContext[item.key] = actions.getData(\n node,\n resolvedPath,\n surfaceId,\n );\n }\n }\n }\n\n actions.dispatch({\n userAction: {\n name: action.name,\n sourceComponentId: node.id,\n surfaceId,\n timestamp: new Date().toISOString(),\n context: actionContext,\n },\n });\n },\n [actions, node, surfaceId],\n );\n\n /**\n * Generate a unique ID for accessibility purposes.\n * Uses React's useId() for SSR and Concurrent Mode compatibility.\n */\n const getUniqueId = useCallback(\n (prefix: string) => {\n return `${prefix}${baseId}`;\n },\n [baseId],\n );\n\n return useMemo(\n () => ({\n theme,\n resolveString,\n resolveNumber,\n resolveBoolean,\n setValue,\n getValue,\n sendAction,\n getUniqueId,\n }),\n [\n theme,\n resolveString,\n resolveNumber,\n resolveBoolean,\n setValue,\n getValue,\n sendAction,\n getUniqueId,\n ],\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoEA,SAAgB,iBACd,MACA,WACwB;CAExB,MAAM,UAAUA,qCAAgB;CAChC,MAAM,QAAQC,+BAAU;CACxB,MAAM,2BAAgB;AAKtB,oCAAc;;;;;;CAOd,MAAM,wCACH,UAAoE;AACnE,MAAI,CAAC,MAAO,QAAO;AACnB,MAAI,OAAO,UAAU,SAAU,QAAO;AAEtC,MAAI,MAAM,kBAAkB,OAC1B,QAAO,MAAM;AAEf,MAAI,MAAM,YAAY,OACpB,QAAO,OAAO,MAAM,QAAQ;AAE9B,MAAI,MAAM,MAAM;GACd,MAAM,OAAO,QAAQ,QAAQ,MAAM,MAAM,MAAM,UAAU;AACzD,UAAO,SAAS,OAAO,OAAO,KAAK,GAAG;;AAExC,SAAO;IAET;EAAC;EAAS;EAAM;EAAU,CAC3B;;;;CAKD,MAAM,wCACH,UAAoE;AACnE,MAAI,CAAC,MAAO,QAAO;AACnB,MAAI,OAAO,UAAU,SAAU,QAAO;AAEtC,MAAI,MAAM,kBAAkB,OAC1B,QAAO,MAAM;AAEf,MAAI,MAAM,YAAY,OACpB,QAAO,OAAO,MAAM,QAAQ;AAE9B,MAAI,MAAM,MAAM;GACd,MAAM,OAAO,QAAQ,QAAQ,MAAM,MAAM,MAAM,UAAU;AACzD,UAAO,SAAS,OAAO,OAAO,KAAK,GAAG;;AAExC,SAAO;IAET;EAAC;EAAS;EAAM;EAAU,CAC3B;;;;CAKD,MAAM,yCACH,UAAsE;AACrE,MAAI,CAAC,MAAO,QAAO;AACnB,MAAI,OAAO,UAAU,SAAU,QAAO;AAEtC,MAAI,MAAM,mBAAmB,OAC3B,QAAO,MAAM;AAEf,MAAI,MAAM,YAAY,OACpB,QAAO,QAAQ,MAAM,QAAQ;AAE/B,MAAI,MAAM,MAAM;GACd,MAAM,OAAO,QAAQ,QAAQ,MAAM,MAAM,MAAM,UAAU;AACzD,UAAO,SAAS,OAAO,QAAQ,KAAK,GAAG;;AAEzC,SAAO;IAET;EAAC;EAAS;EAAM;EAAU,CAC3B;;;;CAKD,MAAM,mCACH,MAAc,UAA2B;AACxC,UAAQ,QAAQ,MAAM,MAAM,OAAO,UAAU;IAE/C;EAAC;EAAS;EAAM;EAAU,CAC3B;;;;CAKD,MAAM,mCACH,SAAyC;AACxC,SAAO,QAAQ,QAAQ,MAAM,MAAM,UAAU;IAE/C;EAAC;EAAS;EAAM;EAAU,CAC3B;;;;;CAMD,MAAM,qCACH,WAAyB;EACxB,MAAM,gBAAyC,EAAE;AAEjD,MAAI,OAAO,SACT;QAAK,MAAM,QAAQ,OAAO,QACxB,KAAI,KAAK,MAAM,kBAAkB,OAC/B,eAAc,KAAK,OAAO,KAAK,MAAM;YAC5B,KAAK,MAAM,kBAAkB,OACtC,eAAc,KAAK,OAAO,KAAK,MAAM;YAC5B,KAAK,MAAM,mBAAmB,OACvC,eAAc,KAAK,OAAO,KAAK,MAAM;YAC5B,KAAK,MAAM,MAAM;IAC1B,MAAM,eAAe,QAAQ,YAC3B,KAAK,MAAM,MACX,KAAK,gBACN;AACD,kBAAc,KAAK,OAAO,QAAQ,QAChC,MACA,cACA,UACD;;;AAKP,UAAQ,SAAS,EACf,YAAY;GACV,MAAM,OAAO;GACb,mBAAmB,KAAK;GACxB;GACA,4BAAW,IAAI,MAAM,EAAC,aAAa;GACnC,SAAS;GACV,EACF,CAAC;IAEJ;EAAC;EAAS;EAAM;EAAU,CAC3B;;;;;CAMD,MAAM,sCACH,WAAmB;AAClB,SAAO,GAAG,SAAS;IAErB,CAAC,OAAO,CACT;AAED,kCACS;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,GACD;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CACF"}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { useTheme } from "../theme/ThemeContext.mjs";
|
|
2
|
+
import { useA2UIActions, useA2UIState } from "../core/A2UIProvider.mjs";
|
|
3
|
+
import { useCallback, useId, useMemo } from "react";
|
|
4
|
+
|
|
5
|
+
//#region src/react-renderer/hooks/useA2UIComponent.ts
|
|
6
|
+
/**
|
|
7
|
+
* Base hook for A2UI components. Provides data binding, theme access,
|
|
8
|
+
* and action dispatching.
|
|
9
|
+
*
|
|
10
|
+
* @param node - The component node from the A2UI message processor
|
|
11
|
+
* @param surfaceId - The surface ID this component belongs to
|
|
12
|
+
* @returns Object with theme, data binding helpers, and action dispatcher
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```tsx
|
|
16
|
+
* function TextField({ node, surfaceId }: A2UIComponentProps<Types.TextFieldNode>) {
|
|
17
|
+
* const { theme, resolveString, setValue } = useA2UIComponent(node, surfaceId);
|
|
18
|
+
*
|
|
19
|
+
* const label = resolveString(node.properties.label);
|
|
20
|
+
* const value = resolveString(node.properties.text) ?? '';
|
|
21
|
+
*
|
|
22
|
+
* return (
|
|
23
|
+
* <div className={classMapToString(theme.components.TextField.container)}>
|
|
24
|
+
* <label>{label}</label>
|
|
25
|
+
* <input
|
|
26
|
+
* value={value}
|
|
27
|
+
* onChange={(e) => setValue(node.properties.text?.path!, e.target.value)}
|
|
28
|
+
* />
|
|
29
|
+
* </div>
|
|
30
|
+
* );
|
|
31
|
+
* }
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
function useA2UIComponent(node, surfaceId) {
|
|
35
|
+
const actions = useA2UIActions();
|
|
36
|
+
const theme = useTheme();
|
|
37
|
+
const baseId = useId();
|
|
38
|
+
useA2UIState();
|
|
39
|
+
/**
|
|
40
|
+
* Resolve a StringValue to its actual string value.
|
|
41
|
+
* Checks literalString, literal, then path in that order.
|
|
42
|
+
* Note: This reads from data model via stable actions reference.
|
|
43
|
+
*/
|
|
44
|
+
const resolveString = useCallback((value) => {
|
|
45
|
+
if (!value) return null;
|
|
46
|
+
if (typeof value !== "object") return null;
|
|
47
|
+
if (value.literalString !== void 0) return value.literalString;
|
|
48
|
+
if (value.literal !== void 0) return String(value.literal);
|
|
49
|
+
if (value.path) {
|
|
50
|
+
const data = actions.getData(node, value.path, surfaceId);
|
|
51
|
+
return data !== null ? String(data) : null;
|
|
52
|
+
}
|
|
53
|
+
return null;
|
|
54
|
+
}, [
|
|
55
|
+
actions,
|
|
56
|
+
node,
|
|
57
|
+
surfaceId
|
|
58
|
+
]);
|
|
59
|
+
/**
|
|
60
|
+
* Resolve a NumberValue to its actual number value.
|
|
61
|
+
*/
|
|
62
|
+
const resolveNumber = useCallback((value) => {
|
|
63
|
+
if (!value) return null;
|
|
64
|
+
if (typeof value !== "object") return null;
|
|
65
|
+
if (value.literalNumber !== void 0) return value.literalNumber;
|
|
66
|
+
if (value.literal !== void 0) return Number(value.literal);
|
|
67
|
+
if (value.path) {
|
|
68
|
+
const data = actions.getData(node, value.path, surfaceId);
|
|
69
|
+
return data !== null ? Number(data) : null;
|
|
70
|
+
}
|
|
71
|
+
return null;
|
|
72
|
+
}, [
|
|
73
|
+
actions,
|
|
74
|
+
node,
|
|
75
|
+
surfaceId
|
|
76
|
+
]);
|
|
77
|
+
/**
|
|
78
|
+
* Resolve a BooleanValue to its actual boolean value.
|
|
79
|
+
*/
|
|
80
|
+
const resolveBoolean = useCallback((value) => {
|
|
81
|
+
if (!value) return null;
|
|
82
|
+
if (typeof value !== "object") return null;
|
|
83
|
+
if (value.literalBoolean !== void 0) return value.literalBoolean;
|
|
84
|
+
if (value.literal !== void 0) return Boolean(value.literal);
|
|
85
|
+
if (value.path) {
|
|
86
|
+
const data = actions.getData(node, value.path, surfaceId);
|
|
87
|
+
return data !== null ? Boolean(data) : null;
|
|
88
|
+
}
|
|
89
|
+
return null;
|
|
90
|
+
}, [
|
|
91
|
+
actions,
|
|
92
|
+
node,
|
|
93
|
+
surfaceId
|
|
94
|
+
]);
|
|
95
|
+
/**
|
|
96
|
+
* Set a value in the data model for two-way binding.
|
|
97
|
+
*/
|
|
98
|
+
const setValue = useCallback((path, value) => {
|
|
99
|
+
actions.setData(node, path, value, surfaceId);
|
|
100
|
+
}, [
|
|
101
|
+
actions,
|
|
102
|
+
node,
|
|
103
|
+
surfaceId
|
|
104
|
+
]);
|
|
105
|
+
/**
|
|
106
|
+
* Get a value from the data model.
|
|
107
|
+
*/
|
|
108
|
+
const getValue = useCallback((path) => {
|
|
109
|
+
return actions.getData(node, path, surfaceId);
|
|
110
|
+
}, [
|
|
111
|
+
actions,
|
|
112
|
+
node,
|
|
113
|
+
surfaceId
|
|
114
|
+
]);
|
|
115
|
+
/**
|
|
116
|
+
* Dispatch a user action to the server.
|
|
117
|
+
* Resolves all context bindings before dispatching.
|
|
118
|
+
*/
|
|
119
|
+
const sendAction = useCallback((action) => {
|
|
120
|
+
const actionContext = {};
|
|
121
|
+
if (action.context) {
|
|
122
|
+
for (const item of action.context) if (item.value.literalString !== void 0) actionContext[item.key] = item.value.literalString;
|
|
123
|
+
else if (item.value.literalNumber !== void 0) actionContext[item.key] = item.value.literalNumber;
|
|
124
|
+
else if (item.value.literalBoolean !== void 0) actionContext[item.key] = item.value.literalBoolean;
|
|
125
|
+
else if (item.value.path) {
|
|
126
|
+
const resolvedPath = actions.resolvePath(item.value.path, node.dataContextPath);
|
|
127
|
+
actionContext[item.key] = actions.getData(node, resolvedPath, surfaceId);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
actions.dispatch({ userAction: {
|
|
131
|
+
name: action.name,
|
|
132
|
+
sourceComponentId: node.id,
|
|
133
|
+
surfaceId,
|
|
134
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
135
|
+
context: actionContext
|
|
136
|
+
} });
|
|
137
|
+
}, [
|
|
138
|
+
actions,
|
|
139
|
+
node,
|
|
140
|
+
surfaceId
|
|
141
|
+
]);
|
|
142
|
+
/**
|
|
143
|
+
* Generate a unique ID for accessibility purposes.
|
|
144
|
+
* Uses React's useId() for SSR and Concurrent Mode compatibility.
|
|
145
|
+
*/
|
|
146
|
+
const getUniqueId = useCallback((prefix) => {
|
|
147
|
+
return `${prefix}${baseId}`;
|
|
148
|
+
}, [baseId]);
|
|
149
|
+
return useMemo(() => ({
|
|
150
|
+
theme,
|
|
151
|
+
resolveString,
|
|
152
|
+
resolveNumber,
|
|
153
|
+
resolveBoolean,
|
|
154
|
+
setValue,
|
|
155
|
+
getValue,
|
|
156
|
+
sendAction,
|
|
157
|
+
getUniqueId
|
|
158
|
+
}), [
|
|
159
|
+
theme,
|
|
160
|
+
resolveString,
|
|
161
|
+
resolveNumber,
|
|
162
|
+
resolveBoolean,
|
|
163
|
+
setValue,
|
|
164
|
+
getValue,
|
|
165
|
+
sendAction,
|
|
166
|
+
getUniqueId
|
|
167
|
+
]);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
//#endregion
|
|
171
|
+
export { useA2UIComponent };
|
|
172
|
+
//# sourceMappingURL=useA2UIComponent.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useA2UIComponent.mjs","names":[],"sources":["../../../src/react-renderer/hooks/useA2UIComponent.ts"],"sourcesContent":["import { useCallback, useId, useMemo } from \"react\";\nimport type { Types, Primitives } from \"@a2ui/lit/0.8\";\nimport { useA2UIActions, useA2UIState } from \"../core/A2UIProvider\";\nimport { useTheme } from \"../theme/ThemeContext\";\n\n/**\n * Result returned by the useA2UIComponent hook.\n */\nexport interface UseA2UIComponentResult {\n /** The current theme */\n theme: Types.Theme;\n\n /** Resolve a StringValue to its actual string value */\n resolveString: (\n value: Primitives.StringValue | null | undefined,\n ) => string | null;\n\n /** Resolve a NumberValue to its actual number value */\n resolveNumber: (\n value: Primitives.NumberValue | null | undefined,\n ) => number | null;\n\n /** Resolve a BooleanValue to its actual boolean value */\n resolveBoolean: (\n value: Primitives.BooleanValue | null | undefined,\n ) => boolean | null;\n\n /** Set a value in the data model (for two-way binding) */\n setValue: (path: string, value: Types.DataValue) => void;\n\n /** Get a value from the data model */\n getValue: (path: string) => Types.DataValue | null;\n\n /** Dispatch a user action */\n sendAction: (action: Types.Action) => void;\n\n /** Generate a unique ID for accessibility */\n getUniqueId: (prefix: string) => string;\n}\n\n/**\n * Base hook for A2UI components. Provides data binding, theme access,\n * and action dispatching.\n *\n * @param node - The component node from the A2UI message processor\n * @param surfaceId - The surface ID this component belongs to\n * @returns Object with theme, data binding helpers, and action dispatcher\n *\n * @example\n * ```tsx\n * function TextField({ node, surfaceId }: A2UIComponentProps<Types.TextFieldNode>) {\n * const { theme, resolveString, setValue } = useA2UIComponent(node, surfaceId);\n *\n * const label = resolveString(node.properties.label);\n * const value = resolveString(node.properties.text) ?? '';\n *\n * return (\n * <div className={classMapToString(theme.components.TextField.container)}>\n * <label>{label}</label>\n * <input\n * value={value}\n * onChange={(e) => setValue(node.properties.text?.path!, e.target.value)}\n * />\n * </div>\n * );\n * }\n * ```\n */\nexport function useA2UIComponent<T extends Types.AnyComponentNode>(\n node: T,\n surfaceId: string,\n): UseA2UIComponentResult {\n // Use stable actions - won't cause re-renders when version changes\n const actions = useA2UIActions();\n const theme = useTheme();\n const baseId = useId();\n\n // Subscribe to data model version - triggers re-render when data changes via setData.\n // This ensures components with path bindings see updated values.\n // memo() doesn't block context-triggered re-renders.\n useA2UIState();\n\n /**\n * Resolve a StringValue to its actual string value.\n * Checks literalString, literal, then path in that order.\n * Note: This reads from data model via stable actions reference.\n */\n const resolveString = useCallback(\n (value: Primitives.StringValue | null | undefined): string | null => {\n if (!value) return null;\n if (typeof value !== \"object\") return null;\n\n if (value.literalString !== undefined) {\n return value.literalString;\n }\n if (value.literal !== undefined) {\n return String(value.literal);\n }\n if (value.path) {\n const data = actions.getData(node, value.path, surfaceId);\n return data !== null ? String(data) : null;\n }\n return null;\n },\n [actions, node, surfaceId],\n );\n\n /**\n * Resolve a NumberValue to its actual number value.\n */\n const resolveNumber = useCallback(\n (value: Primitives.NumberValue | null | undefined): number | null => {\n if (!value) return null;\n if (typeof value !== \"object\") return null;\n\n if (value.literalNumber !== undefined) {\n return value.literalNumber;\n }\n if (value.literal !== undefined) {\n return Number(value.literal);\n }\n if (value.path) {\n const data = actions.getData(node, value.path, surfaceId);\n return data !== null ? Number(data) : null;\n }\n return null;\n },\n [actions, node, surfaceId],\n );\n\n /**\n * Resolve a BooleanValue to its actual boolean value.\n */\n const resolveBoolean = useCallback(\n (value: Primitives.BooleanValue | null | undefined): boolean | null => {\n if (!value) return null;\n if (typeof value !== \"object\") return null;\n\n if (value.literalBoolean !== undefined) {\n return value.literalBoolean;\n }\n if (value.literal !== undefined) {\n return Boolean(value.literal);\n }\n if (value.path) {\n const data = actions.getData(node, value.path, surfaceId);\n return data !== null ? Boolean(data) : null;\n }\n return null;\n },\n [actions, node, surfaceId],\n );\n\n /**\n * Set a value in the data model for two-way binding.\n */\n const setValue = useCallback(\n (path: string, value: Types.DataValue) => {\n actions.setData(node, path, value, surfaceId);\n },\n [actions, node, surfaceId],\n );\n\n /**\n * Get a value from the data model.\n */\n const getValue = useCallback(\n (path: string): Types.DataValue | null => {\n return actions.getData(node, path, surfaceId);\n },\n [actions, node, surfaceId],\n );\n\n /**\n * Dispatch a user action to the server.\n * Resolves all context bindings before dispatching.\n */\n const sendAction = useCallback(\n (action: Types.Action) => {\n const actionContext: Record<string, unknown> = {};\n\n if (action.context) {\n for (const item of action.context) {\n if (item.value.literalString !== undefined) {\n actionContext[item.key] = item.value.literalString;\n } else if (item.value.literalNumber !== undefined) {\n actionContext[item.key] = item.value.literalNumber;\n } else if (item.value.literalBoolean !== undefined) {\n actionContext[item.key] = item.value.literalBoolean;\n } else if (item.value.path) {\n const resolvedPath = actions.resolvePath(\n item.value.path,\n node.dataContextPath,\n );\n actionContext[item.key] = actions.getData(\n node,\n resolvedPath,\n surfaceId,\n );\n }\n }\n }\n\n actions.dispatch({\n userAction: {\n name: action.name,\n sourceComponentId: node.id,\n surfaceId,\n timestamp: new Date().toISOString(),\n context: actionContext,\n },\n });\n },\n [actions, node, surfaceId],\n );\n\n /**\n * Generate a unique ID for accessibility purposes.\n * Uses React's useId() for SSR and Concurrent Mode compatibility.\n */\n const getUniqueId = useCallback(\n (prefix: string) => {\n return `${prefix}${baseId}`;\n },\n [baseId],\n );\n\n return useMemo(\n () => ({\n theme,\n resolveString,\n resolveNumber,\n resolveBoolean,\n setValue,\n getValue,\n sendAction,\n getUniqueId,\n }),\n [\n theme,\n resolveString,\n resolveNumber,\n resolveBoolean,\n setValue,\n getValue,\n sendAction,\n getUniqueId,\n ],\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoEA,SAAgB,iBACd,MACA,WACwB;CAExB,MAAM,UAAU,gBAAgB;CAChC,MAAM,QAAQ,UAAU;CACxB,MAAM,SAAS,OAAO;AAKtB,eAAc;;;;;;CAOd,MAAM,gBAAgB,aACnB,UAAoE;AACnE,MAAI,CAAC,MAAO,QAAO;AACnB,MAAI,OAAO,UAAU,SAAU,QAAO;AAEtC,MAAI,MAAM,kBAAkB,OAC1B,QAAO,MAAM;AAEf,MAAI,MAAM,YAAY,OACpB,QAAO,OAAO,MAAM,QAAQ;AAE9B,MAAI,MAAM,MAAM;GACd,MAAM,OAAO,QAAQ,QAAQ,MAAM,MAAM,MAAM,UAAU;AACzD,UAAO,SAAS,OAAO,OAAO,KAAK,GAAG;;AAExC,SAAO;IAET;EAAC;EAAS;EAAM;EAAU,CAC3B;;;;CAKD,MAAM,gBAAgB,aACnB,UAAoE;AACnE,MAAI,CAAC,MAAO,QAAO;AACnB,MAAI,OAAO,UAAU,SAAU,QAAO;AAEtC,MAAI,MAAM,kBAAkB,OAC1B,QAAO,MAAM;AAEf,MAAI,MAAM,YAAY,OACpB,QAAO,OAAO,MAAM,QAAQ;AAE9B,MAAI,MAAM,MAAM;GACd,MAAM,OAAO,QAAQ,QAAQ,MAAM,MAAM,MAAM,UAAU;AACzD,UAAO,SAAS,OAAO,OAAO,KAAK,GAAG;;AAExC,SAAO;IAET;EAAC;EAAS;EAAM;EAAU,CAC3B;;;;CAKD,MAAM,iBAAiB,aACpB,UAAsE;AACrE,MAAI,CAAC,MAAO,QAAO;AACnB,MAAI,OAAO,UAAU,SAAU,QAAO;AAEtC,MAAI,MAAM,mBAAmB,OAC3B,QAAO,MAAM;AAEf,MAAI,MAAM,YAAY,OACpB,QAAO,QAAQ,MAAM,QAAQ;AAE/B,MAAI,MAAM,MAAM;GACd,MAAM,OAAO,QAAQ,QAAQ,MAAM,MAAM,MAAM,UAAU;AACzD,UAAO,SAAS,OAAO,QAAQ,KAAK,GAAG;;AAEzC,SAAO;IAET;EAAC;EAAS;EAAM;EAAU,CAC3B;;;;CAKD,MAAM,WAAW,aACd,MAAc,UAA2B;AACxC,UAAQ,QAAQ,MAAM,MAAM,OAAO,UAAU;IAE/C;EAAC;EAAS;EAAM;EAAU,CAC3B;;;;CAKD,MAAM,WAAW,aACd,SAAyC;AACxC,SAAO,QAAQ,QAAQ,MAAM,MAAM,UAAU;IAE/C;EAAC;EAAS;EAAM;EAAU,CAC3B;;;;;CAMD,MAAM,aAAa,aAChB,WAAyB;EACxB,MAAM,gBAAyC,EAAE;AAEjD,MAAI,OAAO,SACT;QAAK,MAAM,QAAQ,OAAO,QACxB,KAAI,KAAK,MAAM,kBAAkB,OAC/B,eAAc,KAAK,OAAO,KAAK,MAAM;YAC5B,KAAK,MAAM,kBAAkB,OACtC,eAAc,KAAK,OAAO,KAAK,MAAM;YAC5B,KAAK,MAAM,mBAAmB,OACvC,eAAc,KAAK,OAAO,KAAK,MAAM;YAC5B,KAAK,MAAM,MAAM;IAC1B,MAAM,eAAe,QAAQ,YAC3B,KAAK,MAAM,MACX,KAAK,gBACN;AACD,kBAAc,KAAK,OAAO,QAAQ,QAChC,MACA,cACA,UACD;;;AAKP,UAAQ,SAAS,EACf,YAAY;GACV,MAAM,OAAO;GACb,mBAAmB,KAAK;GACxB;GACA,4BAAW,IAAI,MAAM,EAAC,aAAa;GACnC,SAAS;GACV,EACF,CAAC;IAEJ;EAAC;EAAS;EAAM;EAAU,CAC3B;;;;;CAMD,MAAM,cAAc,aACjB,WAAmB;AAClB,SAAO,GAAG,SAAS;IAErB,CAAC,OAAO,CACT;AAED,QAAO,eACE;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,GACD;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CACF"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const require_runtime = require('../../_virtual/_rolldown/runtime.cjs');
|
|
2
|
+
const require_utils = require('../theme/utils.cjs');
|
|
3
|
+
let _a2ui_lit_0_8 = require("@a2ui/lit/0.8");
|
|
4
|
+
let clsx = require("clsx");
|
|
5
|
+
|
|
6
|
+
//#region src/react-renderer/lib/utils.ts
|
|
7
|
+
/**
|
|
8
|
+
* Utility function to merge class names.
|
|
9
|
+
* Combines clsx for conditional classes.
|
|
10
|
+
*
|
|
11
|
+
* @param inputs - Class values to merge
|
|
12
|
+
* @returns Merged class name string
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* cn('base-class', condition && 'conditional-class', { 'object-class': true })
|
|
16
|
+
*/
|
|
17
|
+
function cn(...inputs) {
|
|
18
|
+
return (0, clsx.clsx)(inputs);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Merges multiple class maps into a single class map.
|
|
22
|
+
* Uses Lit's Styles.merge() function directly for consistency.
|
|
23
|
+
*
|
|
24
|
+
* Lit's merge handles prefix conflicts: if you have 'layout-p-2' and 'layout-p-4',
|
|
25
|
+
* only the latter is kept (same prefix 'layout-p-' means they conflict).
|
|
26
|
+
*
|
|
27
|
+
* @param maps - Class maps to merge
|
|
28
|
+
* @returns A merged class map
|
|
29
|
+
*/
|
|
30
|
+
function mergeClassMaps(...maps) {
|
|
31
|
+
const validMaps = maps.filter((m) => m !== void 0);
|
|
32
|
+
if (validMaps.length === 0) return {};
|
|
33
|
+
return _a2ui_lit_0_8.Styles.merge(...validMaps);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
//#endregion
|
|
37
|
+
exports.cn = cn;
|
|
38
|
+
exports.mergeClassMaps = mergeClassMaps;
|
|
39
|
+
//# sourceMappingURL=utils.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.cjs","names":["Styles"],"sources":["../../../src/react-renderer/lib/utils.ts"],"sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { Styles } from \"@a2ui/lit/0.8\";\n\n/**\n * Utility function to merge class names.\n * Combines clsx for conditional classes.\n *\n * @param inputs - Class values to merge\n * @returns Merged class name string\n *\n * @example\n * cn('base-class', condition && 'conditional-class', { 'object-class': true })\n */\nexport function cn(...inputs: ClassValue[]): string {\n return clsx(inputs);\n}\n\n/**\n * Converts a theme class map (Record<string, boolean>) to a className string.\n * Re-exported from theme/utils for convenience.\n *\n * @param classMap - An object where keys are class names and values are booleans\n * @returns A space-separated string of class names where the value is true\n */\nexport { classMapToString, stylesToObject } from \"../theme/utils\";\n\n/**\n * Merges multiple class maps into a single class map.\n * Uses Lit's Styles.merge() function directly for consistency.\n *\n * Lit's merge handles prefix conflicts: if you have 'layout-p-2' and 'layout-p-4',\n * only the latter is kept (same prefix 'layout-p-' means they conflict).\n *\n * @param maps - Class maps to merge\n * @returns A merged class map\n */\nexport function mergeClassMaps(\n ...maps: (Record<string, boolean> | undefined)[]\n): Record<string, boolean> {\n // Filter out undefined maps and use Lit's merge function\n const validMaps = maps.filter(\n (m): m is Record<string, boolean> => m !== undefined,\n );\n if (validMaps.length === 0) return {};\n return Styles.merge(...validMaps);\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAaA,SAAgB,GAAG,GAAG,QAA8B;AAClD,uBAAY,OAAO;;;;;;;;;;;;AAsBrB,SAAgB,eACd,GAAG,MACsB;CAEzB,MAAM,YAAY,KAAK,QACpB,MAAoC,MAAM,OAC5C;AACD,KAAI,UAAU,WAAW,EAAG,QAAO,EAAE;AACrC,QAAOA,qBAAO,MAAM,GAAG,UAAU"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { classMapToString, stylesToObject } from "../theme/utils.mjs";
|
|
2
|
+
import { Styles } from "@a2ui/lit/0.8";
|
|
3
|
+
import { clsx } from "clsx";
|
|
4
|
+
|
|
5
|
+
//#region src/react-renderer/lib/utils.ts
|
|
6
|
+
/**
|
|
7
|
+
* Utility function to merge class names.
|
|
8
|
+
* Combines clsx for conditional classes.
|
|
9
|
+
*
|
|
10
|
+
* @param inputs - Class values to merge
|
|
11
|
+
* @returns Merged class name string
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* cn('base-class', condition && 'conditional-class', { 'object-class': true })
|
|
15
|
+
*/
|
|
16
|
+
function cn(...inputs) {
|
|
17
|
+
return clsx(inputs);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Merges multiple class maps into a single class map.
|
|
21
|
+
* Uses Lit's Styles.merge() function directly for consistency.
|
|
22
|
+
*
|
|
23
|
+
* Lit's merge handles prefix conflicts: if you have 'layout-p-2' and 'layout-p-4',
|
|
24
|
+
* only the latter is kept (same prefix 'layout-p-' means they conflict).
|
|
25
|
+
*
|
|
26
|
+
* @param maps - Class maps to merge
|
|
27
|
+
* @returns A merged class map
|
|
28
|
+
*/
|
|
29
|
+
function mergeClassMaps(...maps) {
|
|
30
|
+
const validMaps = maps.filter((m) => m !== void 0);
|
|
31
|
+
if (validMaps.length === 0) return {};
|
|
32
|
+
return Styles.merge(...validMaps);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
//#endregion
|
|
36
|
+
export { cn, mergeClassMaps };
|
|
37
|
+
//# sourceMappingURL=utils.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.mjs","names":[],"sources":["../../../src/react-renderer/lib/utils.ts"],"sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { Styles } from \"@a2ui/lit/0.8\";\n\n/**\n * Utility function to merge class names.\n * Combines clsx for conditional classes.\n *\n * @param inputs - Class values to merge\n * @returns Merged class name string\n *\n * @example\n * cn('base-class', condition && 'conditional-class', { 'object-class': true })\n */\nexport function cn(...inputs: ClassValue[]): string {\n return clsx(inputs);\n}\n\n/**\n * Converts a theme class map (Record<string, boolean>) to a className string.\n * Re-exported from theme/utils for convenience.\n *\n * @param classMap - An object where keys are class names and values are booleans\n * @returns A space-separated string of class names where the value is true\n */\nexport { classMapToString, stylesToObject } from \"../theme/utils\";\n\n/**\n * Merges multiple class maps into a single class map.\n * Uses Lit's Styles.merge() function directly for consistency.\n *\n * Lit's merge handles prefix conflicts: if you have 'layout-p-2' and 'layout-p-4',\n * only the latter is kept (same prefix 'layout-p-' means they conflict).\n *\n * @param maps - Class maps to merge\n * @returns A merged class map\n */\nexport function mergeClassMaps(\n ...maps: (Record<string, boolean> | undefined)[]\n): Record<string, boolean> {\n // Filter out undefined maps and use Lit's merge function\n const validMaps = maps.filter(\n (m): m is Record<string, boolean> => m !== undefined,\n );\n if (validMaps.length === 0) return {};\n return Styles.merge(...validMaps);\n}\n"],"mappings":";;;;;;;;;;;;;;;AAaA,SAAgB,GAAG,GAAG,QAA8B;AAClD,QAAO,KAAK,OAAO;;;;;;;;;;;;AAsBrB,SAAgB,eACd,GAAG,MACsB;CAEzB,MAAM,YAAY,KAAK,QACpB,MAAoC,MAAM,OAC5C;AACD,KAAI,UAAU,WAAW,EAAG,QAAO,EAAE;AACrC,QAAO,OAAO,MAAM,GAAG,UAAU"}
|