@copilotkit/a2ui-renderer 1.52.2-next.1 → 1.52.2-next.3

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/index.umd.js CHANGED
@@ -1185,7 +1185,8 @@ markdown_it = __toESM(markdown_it);
1185
1185
  var _ref, _theme$additionalStyl;
1186
1186
  const { theme, resolveString } = useA2UIComponent(node, surfaceId);
1187
1187
  const props = node.properties;
1188
- const url = resolveString(props.url);
1188
+ const rawUrl = resolveString(props.url);
1189
+ const url = rawUrl === null || rawUrl === void 0 ? void 0 : rawUrl.replace("//via.placeholder.com/", "//placehold.co/");
1189
1190
  const usageHint = props.usageHint;
1190
1191
  const fit = (_ref = props.fit) !== null && _ref !== void 0 ? _ref : "fill";
1191
1192
  const classes = mergeClassMaps(theme.components.Image.all, usageHint ? theme.components.Image[usageHint] : {});
@@ -1 +1 @@
1
- {"version":3,"file":"index.umd.js","names":["Data","Suspense","Styles","Suspense","MarkdownIt","Styles","initialized","ensureInitialized","z","v0_8","v0_8","viewerTheme"],"sources":["../src/react-renderer/theme/litTheme.ts","../src/react-renderer/theme/ThemeContext.tsx","../src/react-renderer/core/A2UIProvider.tsx","../src/react-renderer/hooks/useA2UI.ts","../src/react-renderer/registry/ComponentRegistry.ts","../src/react-renderer/core/ComponentNode.tsx","../src/react-renderer/theme/utils.ts","../src/react-renderer/lib/utils.ts","../src/react-renderer/core/A2UIRenderer.tsx","../src/react-renderer/hooks/useA2UIComponent.ts","../src/react-renderer/components/content/Text.tsx","../src/react-renderer/components/content/Image.tsx","../src/react-renderer/components/content/Icon.tsx","../src/react-renderer/components/content/Divider.tsx","../src/react-renderer/components/content/Video.tsx","../src/react-renderer/components/content/AudioPlayer.tsx","../src/react-renderer/components/layout/Row.tsx","../src/react-renderer/components/layout/Column.tsx","../src/react-renderer/components/layout/List.tsx","../src/react-renderer/components/layout/Card.tsx","../src/react-renderer/components/layout/Tabs.tsx","../src/react-renderer/components/layout/Modal.tsx","../src/react-renderer/components/interactive/Button.tsx","../src/react-renderer/components/interactive/TextField.tsx","../src/react-renderer/components/interactive/CheckBox.tsx","../src/react-renderer/components/interactive/Slider.tsx","../src/react-renderer/components/interactive/DateTimeInput.tsx","../src/react-renderer/components/interactive/MultipleChoice.tsx","../src/react-renderer/registry/defaultCatalog.ts","../src/react-renderer/styles/reset.ts","../src/react-renderer/styles/index.ts","../src/A2UIMessageRenderer.tsx","../src/theme/viewer-theme.ts","../src/A2UIViewer.tsx"],"sourcesContent":["import type { Types } from \"@a2ui/lit/0.8\";\n\n/**\n * Default theme for A2UI React components.\n *\n * This theme uses the same CSS class conventions as the Lit renderer,\n * ensuring visual consistency between React and Lit implementations.\n *\n * IMPORTANT: This theme must be kept in sync with the Lit renderer's internal\n * styling. If Lit components change their class maps, this file must be updated\n * to match. Ideally, Lit would export its default theme for direct import.\n *\n * Requires the structural styles to be injected:\n * @example\n * ```tsx\n * import { A2UIProvider } from '@a2ui/react';\n * import { injectStyles } from '@a2ui/react/styles';\n *\n * // Inject structural CSS at app startup\n * injectStyles();\n *\n * function App() {\n * return (\n * <A2UIProvider>\n * <A2UIRenderer surfaceId=\"main\" />\n * </A2UIProvider>\n * );\n * }\n * ```\n */\n\n// =============================================================================\n// Element Styles (used for markdown rendering and form elements)\n// =============================================================================\n\nconst elementA = {\n \"typography-f-sf\": true,\n \"typography-fs-n\": true,\n \"typography-w-500\": true,\n \"layout-as-n\": true,\n \"layout-dis-iflx\": true,\n \"layout-al-c\": true,\n \"typography-td-none\": true,\n \"color-c-p40\": true,\n};\n\nconst elementAudio = {\n \"layout-w-100\": true,\n};\n\nconst elementBody = {\n \"typography-f-s\": true,\n \"typography-fs-n\": true,\n \"typography-w-400\": true,\n \"layout-mt-0\": true,\n \"layout-mb-2\": true,\n \"typography-sz-bm\": true,\n \"color-c-n10\": true,\n};\n\nconst elementButton = {\n \"typography-f-sf\": true,\n \"typography-fs-n\": true,\n \"typography-w-500\": true,\n \"layout-pt-3\": true,\n \"layout-pb-3\": true,\n \"layout-pl-5\": true,\n \"layout-pr-5\": true,\n \"layout-mb-1\": true,\n \"border-br-16\": true,\n \"border-bw-0\": true,\n \"border-c-n70\": true,\n \"border-bs-s\": true,\n \"color-bgc-s30\": true,\n \"behavior-ho-80\": true,\n};\n\nconst elementHeading = {\n \"typography-f-sf\": true,\n \"typography-fs-n\": true,\n \"typography-w-500\": true,\n \"layout-mt-0\": true,\n \"layout-mb-2\": true,\n};\n\nconst elementIframe = {\n \"behavior-sw-n\": true,\n};\n\nconst elementInput = {\n \"typography-f-sf\": true,\n \"typography-fs-n\": true,\n \"typography-w-400\": true,\n \"layout-pl-4\": true,\n \"layout-pr-4\": true,\n \"layout-pt-2\": true,\n \"layout-pb-2\": true,\n \"border-br-6\": true,\n \"border-bw-1\": true,\n \"color-bc-s70\": true,\n \"border-bs-s\": true,\n \"layout-as-n\": true,\n \"color-c-n10\": true,\n};\n\nconst elementP = {\n \"typography-f-s\": true,\n \"typography-fs-n\": true,\n \"typography-w-400\": true,\n \"layout-m-0\": true,\n \"typography-sz-bm\": true,\n \"layout-as-n\": true,\n \"color-c-n10\": true,\n};\n\nconst elementList = {\n \"typography-f-s\": true,\n \"typography-fs-n\": true,\n \"typography-w-400\": true,\n \"layout-m-0\": true,\n \"typography-sz-bm\": true,\n \"layout-as-n\": true,\n \"color-c-n10\": true,\n};\n\nconst elementPre = {\n \"typography-f-c\": true,\n \"typography-fs-n\": true,\n \"typography-w-400\": true,\n \"typography-sz-bm\": true,\n \"typography-ws-p\": true,\n \"layout-as-n\": true,\n};\n\nconst elementTextarea = {\n ...elementInput,\n \"layout-r-none\": true,\n \"layout-fs-c\": true,\n};\n\nconst elementVideo = {\n \"layout-el-cv\": true,\n};\n\n// =============================================================================\n// Theme Export\n// =============================================================================\n\nexport const litTheme: Types.Theme = {\n // ===========================================================================\n // Additional Styles (inline CSS properties)\n // ===========================================================================\n\n // additionalStyles is optional - only define if custom styling is needed\n // The default Lit theme does not apply any additional inline styles\n\n components: {\n // =========================================================================\n // Content Components\n // =========================================================================\n\n AudioPlayer: {},\n\n Divider: {},\n\n Icon: {},\n\n Image: {\n all: {\n \"border-br-5\": true,\n \"layout-el-cv\": true,\n \"layout-w-100\": true,\n \"layout-h-100\": true,\n },\n avatar: { \"is-avatar\": true },\n header: {},\n icon: {},\n largeFeature: {},\n mediumFeature: {},\n smallFeature: {},\n },\n\n Text: {\n all: {\n \"layout-w-100\": true,\n \"layout-g-2\": true,\n },\n h1: {\n \"typography-f-sf\": true,\n \"typography-v-r\": true,\n \"typography-w-400\": true,\n \"layout-m-0\": true,\n \"layout-p-0\": true,\n \"typography-sz-hs\": true,\n },\n h2: {\n \"typography-f-sf\": true,\n \"typography-v-r\": true,\n \"typography-w-400\": true,\n \"layout-m-0\": true,\n \"layout-p-0\": true,\n \"typography-sz-tl\": true,\n },\n h3: {\n \"typography-f-sf\": true,\n \"typography-v-r\": true,\n \"typography-w-400\": true,\n \"layout-m-0\": true,\n \"layout-p-0\": true,\n \"typography-sz-tl\": true,\n },\n h4: {\n \"typography-f-sf\": true,\n \"typography-v-r\": true,\n \"typography-w-400\": true,\n \"layout-m-0\": true,\n \"layout-p-0\": true,\n \"typography-sz-bl\": true,\n },\n h5: {\n \"typography-f-sf\": true,\n \"typography-v-r\": true,\n \"typography-w-400\": true,\n \"layout-m-0\": true,\n \"layout-p-0\": true,\n \"typography-sz-bm\": true,\n },\n body: {},\n caption: {},\n },\n\n Video: {\n \"border-br-5\": true,\n \"layout-el-cv\": true,\n },\n\n // =========================================================================\n // Layout Components\n // =========================================================================\n\n Card: {\n \"border-br-9\": true,\n \"layout-p-4\": true,\n \"color-bgc-n100\": true,\n },\n\n Column: {\n \"layout-g-2\": true,\n },\n\n List: {\n \"layout-g-4\": true,\n \"layout-p-2\": true,\n },\n\n Modal: {\n backdrop: {\n \"color-bbgc-p60_20\": true,\n },\n element: {\n \"border-br-2\": true,\n \"color-bgc-p100\": true,\n \"layout-p-4\": true,\n \"border-bw-1\": true,\n \"border-bs-s\": true,\n \"color-bc-p80\": true,\n },\n },\n\n Row: {\n \"layout-g-4\": true,\n },\n\n Tabs: {\n container: {},\n controls: {\n all: {},\n selected: {},\n },\n element: {},\n },\n\n // =========================================================================\n // Interactive Components\n // =========================================================================\n\n Button: {\n \"layout-pt-2\": true,\n \"layout-pb-2\": true,\n \"layout-pl-3\": true,\n \"layout-pr-3\": true,\n \"border-br-12\": true,\n \"border-bw-0\": true,\n \"border-bs-s\": true,\n \"color-bgc-p30\": true,\n \"color-c-p100\": true, // White text on dark purple background\n \"behavior-ho-70\": true,\n \"typography-w-400\": true,\n },\n\n CheckBox: {\n container: {\n \"layout-dsp-iflex\": true,\n \"layout-al-c\": true,\n },\n element: {\n \"layout-m-0\": true,\n \"layout-mr-2\": true,\n \"layout-p-2\": true,\n \"border-br-12\": true,\n \"border-bw-1\": true,\n \"border-bs-s\": true,\n \"color-bgc-p100\": true,\n \"color-bc-p60\": true,\n \"color-c-n30\": true,\n \"color-c-p30\": true,\n },\n label: {\n \"color-c-p30\": true,\n \"typography-f-sf\": true,\n \"typography-v-r\": true,\n \"typography-w-400\": true,\n \"layout-flx-1\": true,\n \"typography-sz-ll\": true,\n },\n },\n\n DateTimeInput: {\n container: {\n \"typography-sz-bm\": true,\n \"layout-w-100\": true,\n \"layout-g-2\": true,\n \"layout-dsp-flexhor\": true,\n \"layout-al-c\": true,\n \"typography-ws-nw\": true,\n },\n label: {\n \"color-c-p30\": true,\n \"typography-sz-bm\": true,\n },\n element: {\n \"layout-pt-2\": true,\n \"layout-pb-2\": true,\n \"layout-pl-3\": true,\n \"layout-pr-3\": true,\n \"border-br-2\": true,\n \"border-bw-1\": true,\n \"border-bs-s\": true,\n \"color-bgc-p100\": true,\n \"color-bc-p60\": true,\n \"color-c-n30\": true,\n \"color-c-p30\": true,\n },\n },\n\n MultipleChoice: {\n container: {},\n label: {},\n element: {},\n },\n\n Slider: {\n container: {},\n label: {},\n element: {},\n },\n\n TextField: {\n container: {\n \"typography-sz-bm\": true,\n \"layout-w-100\": true,\n \"layout-g-2\": true,\n \"layout-dsp-flexhor\": true,\n \"layout-al-c\": true,\n \"typography-ws-nw\": true,\n },\n label: {\n \"layout-flx-0\": true,\n \"color-c-p30\": true,\n },\n element: {\n \"typography-sz-bm\": true,\n \"layout-pt-2\": true,\n \"layout-pb-2\": true,\n \"layout-pl-3\": true,\n \"layout-pr-3\": true,\n \"border-br-2\": true,\n \"border-bw-1\": true,\n \"border-bs-s\": true,\n \"color-bgc-p100\": true,\n \"color-bc-p60\": true,\n \"color-c-n30\": true,\n \"color-c-p30\": true,\n },\n },\n },\n\n // ===========================================================================\n // HTML Elements (used for markdown rendering and raw HTML)\n // ===========================================================================\n\n elements: {\n a: elementA,\n audio: elementAudio,\n body: elementBody,\n button: elementButton,\n h1: elementHeading,\n h2: elementHeading,\n h3: elementHeading,\n h4: elementHeading,\n h5: elementHeading,\n iframe: elementIframe,\n input: elementInput,\n p: elementP,\n pre: elementPre,\n textarea: elementTextarea,\n video: elementVideo,\n },\n\n // ===========================================================================\n // Markdown (class arrays for markdown-it renderer)\n // ===========================================================================\n\n markdown: {\n p: Object.keys(elementP),\n h1: Object.keys(elementHeading),\n h2: Object.keys(elementHeading),\n h3: Object.keys(elementHeading),\n h4: Object.keys(elementHeading),\n h5: Object.keys(elementHeading),\n ul: Object.keys(elementList),\n ol: Object.keys(elementList),\n li: Object.keys(elementList),\n a: Object.keys(elementA),\n strong: [],\n em: [],\n },\n};\n\n/**\n * Alias for litTheme - the default theme for A2UI React components.\n * @see litTheme\n */\nexport const defaultTheme = litTheme;\n","import { createContext, useContext, type ReactNode } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport { defaultTheme } from \"./litTheme\";\n\n/**\n * React context for the A2UI theme.\n */\nconst ThemeContext = createContext<Types.Theme | undefined>(undefined);\n\n/**\n * Props for the ThemeProvider component.\n */\nexport interface ThemeProviderProps {\n /** The theme to provide. Falls back to defaultTheme if not specified. */\n theme?: Types.Theme;\n /** Child components that will have access to the theme */\n children: ReactNode;\n}\n\n/**\n * Provider component that makes the A2UI theme available to descendant components.\n */\nexport function ThemeProvider({ theme, children }: ThemeProviderProps) {\n return (\n <ThemeContext.Provider value={theme ?? defaultTheme}>\n {children}\n </ThemeContext.Provider>\n );\n}\n\n/**\n * Hook to access the current A2UI theme.\n *\n * @returns The current theme\n * @throws If used outside of a ThemeProvider\n */\nexport function useTheme(): Types.Theme {\n const theme = useContext(ThemeContext);\n if (!theme) {\n throw new Error(\n \"useTheme must be used within a ThemeProvider or A2UIProvider\",\n );\n }\n return theme;\n}\n\n/**\n * Hook to optionally access the current A2UI theme.\n *\n * @returns The current theme, or undefined if not within a provider\n */\nexport function useThemeOptional(): Types.Theme | undefined {\n return useContext(ThemeContext);\n}\n","import {\n createContext,\n useContext,\n useRef,\n useState,\n useMemo,\n type ReactNode,\n} from \"react\";\nimport { Data, type Types } from \"@a2ui/lit/0.8\";\nimport type { A2UIContextValue, A2UIActions } from \"./store\";\nimport { ThemeProvider } from \"../theme/ThemeContext\";\nimport type { OnActionCallback } from \"../types\";\n\n/**\n * Context for stable actions (never changes reference, prevents re-renders).\n * Components that only need to dispatch actions or read data won't re-render.\n */\nconst A2UIActionsContext = createContext<A2UIActions | null>(null);\n\n/**\n * Context for reactive state (changes trigger re-renders).\n * Only components that need to react to state changes subscribe to this.\n */\nconst A2UIStateContext = createContext<{ version: number } | null>(null);\n\n/**\n * Props for the A2UIProvider component.\n */\nexport interface A2UIProviderProps {\n /** Callback invoked when a user action is dispatched (button click, etc.) */\n onAction?: OnActionCallback;\n /** Theme configuration. Falls back to default theme if not provided. */\n theme?: Types.Theme;\n /** Child components */\n children: ReactNode;\n}\n\n/**\n * Provider component that sets up the A2UI context for descendant components.\n *\n * This provider uses a two-context architecture for performance:\n * - A2UIActionsContext: Stable actions that never change (no re-renders)\n * - A2UIStateContext: Reactive state that triggers re-renders when needed\n *\n * @example\n * ```tsx\n * function App() {\n * const handleAction = async (message) => {\n * const response = await fetch('/api/a2ui', {\n * method: 'POST',\n * body: JSON.stringify(message)\n * });\n * const newMessages = await response.json();\n * };\n *\n * return (\n * <A2UIProvider onAction={handleAction}>\n * <A2UIRenderer surfaceId=\"main\" />\n * </A2UIProvider>\n * );\n * }\n * ```\n */\nexport function A2UIProvider({ onAction, theme, children }: A2UIProviderProps) {\n // Create message processor only once using ref\n const processorRef = useRef<Types.MessageProcessor | null>(null);\n if (!processorRef.current) {\n processorRef.current = Data.createSignalA2uiMessageProcessor();\n }\n const processor = processorRef.current;\n\n // Version counter for triggering re-renders\n const [version, setVersion] = useState(0);\n\n // Store onAction in a ref so callbacks always have the latest value\n const onActionRef = useRef<OnActionCallback | null>(onAction ?? null);\n onActionRef.current = onAction ?? null;\n\n // Create stable actions object once - stored in ref, never changes\n const actionsRef = useRef<A2UIActions | null>(null);\n if (!actionsRef.current) {\n actionsRef.current = {\n processMessages: (messages: Types.ServerToClientMessage[]) => {\n processor.processMessages(messages);\n setVersion((v) => v + 1);\n },\n\n setData: (\n node: Types.AnyComponentNode | null,\n path: string,\n value: Types.DataValue,\n surfaceId: string,\n ) => {\n processor.setData(node, path, value, surfaceId);\n setVersion((v) => v + 1);\n },\n\n dispatch: (message: Types.A2UIClientEventMessage) => {\n if (onActionRef.current) {\n onActionRef.current(message);\n }\n },\n\n clearSurfaces: () => {\n processor.clearSurfaces();\n setVersion((v) => v + 1);\n },\n\n getSurface: (surfaceId: string) => {\n return processor.getSurfaces().get(surfaceId);\n },\n\n getSurfaces: () => {\n return processor.getSurfaces();\n },\n\n getData: (\n node: Types.AnyComponentNode,\n path: string,\n surfaceId: string,\n ) => {\n return processor.getData(node, path, surfaceId);\n },\n\n resolvePath: (path: string, dataContextPath?: string) => {\n return processor.resolvePath(path, dataContextPath);\n },\n };\n }\n const actions = actionsRef.current;\n\n // State context value - only changes when version changes\n const stateValue = useMemo(() => ({ version }), [version]);\n\n return (\n <A2UIActionsContext.Provider value={actions}>\n <A2UIStateContext.Provider value={stateValue}>\n <ThemeProvider theme={theme}>{children}</ThemeProvider>\n </A2UIStateContext.Provider>\n </A2UIActionsContext.Provider>\n );\n}\n\n/**\n * Hook to access stable A2UI actions (won't cause re-renders).\n * Use this when you only need to dispatch actions or read data.\n *\n * @returns Stable actions object\n * @throws If used outside of an A2UIProvider\n */\nexport function useA2UIActions(): A2UIActions {\n const actions = useContext(A2UIActionsContext);\n if (!actions) {\n throw new Error(\"useA2UIActions must be used within an A2UIProvider\");\n }\n return actions;\n}\n\n/**\n * Hook to subscribe to A2UI state changes.\n * Components using this will re-render when state changes.\n *\n * @returns Current version number\n * @throws If used outside of an A2UIProvider\n */\nexport function useA2UIState(): { version: number } {\n const state = useContext(A2UIStateContext);\n if (!state) {\n throw new Error(\"useA2UIState must be used within an A2UIProvider\");\n }\n return state;\n}\n\n/**\n * Hook to access the full A2UI context (actions + state).\n * Components using this will re-render when state changes.\n *\n * @returns The A2UI context value\n * @throws If used outside of an A2UIProvider\n */\nexport function useA2UIContext(): A2UIContextValue {\n const actions = useA2UIActions();\n const state = useA2UIState();\n\n // Memoize combined value - only changes when state changes\n // Actions are stable, so this only re-creates when version changes\n return useMemo(\n () => ({\n ...actions,\n processor: null as unknown as Types.MessageProcessor, // Not exposed directly\n version: state.version,\n onAction: null, // Use dispatch instead\n }),\n [actions, state.version],\n );\n}\n\n/**\n * @deprecated Use useA2UIContext instead. This alias exists for backward compatibility only.\n */\nexport const useA2UIStore = useA2UIContext;\n\n/**\n * @deprecated This selector pattern does not provide performance benefits with React Context.\n * Components will re-render on any context change regardless of what you select.\n * Use useA2UIContext() or useA2UI() directly instead.\n *\n * @param selector - Function to select a slice of state\n * @returns The selected state\n */\nexport function useA2UIStoreSelector<T>(\n selector: (state: A2UIContextValue) => T,\n): T {\n const context = useA2UIContext();\n return selector(context);\n}\n","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","import { lazy, type ComponentType } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport type {\n A2UIComponentProps,\n ComponentLoader,\n ComponentRegistration,\n} from \"../types\";\n\n/**\n * Registry for A2UI components. Allows registration of custom components\n * and supports lazy loading for code splitting.\n *\n * @example\n * ```tsx\n * const registry = new ComponentRegistry();\n *\n * // Register a component directly\n * registry.register('Text', { component: Text });\n *\n * // Register with lazy loading\n * registry.register('Modal', {\n * component: () => import('./components/Modal'),\n * lazy: true\n * });\n *\n * // Use with A2UIRenderer\n * <A2UIRenderer surfaceId=\"main\" registry={registry} />\n * ```\n */\nexport class ComponentRegistry {\n private static _instance: ComponentRegistry | null = null;\n private registry = new Map<string, ComponentRegistration>();\n private lazyCache = new Map<string, ComponentType<A2UIComponentProps>>();\n\n /**\n * Get the singleton instance of the registry.\n * Use this for the default global registry.\n */\n static getInstance(): ComponentRegistry {\n if (!ComponentRegistry._instance) {\n ComponentRegistry._instance = new ComponentRegistry();\n }\n return ComponentRegistry._instance;\n }\n\n /**\n * Reset the singleton instance.\n * Useful for testing.\n */\n static resetInstance(): void {\n ComponentRegistry._instance = null;\n }\n\n /**\n * Register a component type.\n *\n * @param type - The A2UI component type name (e.g., 'Text', 'Button')\n * @param registration - The component registration\n */\n register<T extends Types.AnyComponentNode>(\n type: string,\n registration: ComponentRegistration<T>,\n ): void {\n this.registry.set(type, registration as unknown as ComponentRegistration);\n }\n\n /**\n * Unregister a component type.\n *\n * @param type - The component type to unregister\n */\n unregister(type: string): void {\n this.registry.delete(type);\n this.lazyCache.delete(type);\n }\n\n /**\n * Check if a component type is registered.\n *\n * @param type - The component type to check\n * @returns True if the component is registered\n */\n has(type: string): boolean {\n return this.registry.has(type);\n }\n\n /**\n * Get a component by type. If the component is registered with lazy loading,\n * returns a React.lazy wrapped component.\n *\n * @param type - The component type to get\n * @returns The React component, or null if not found\n */\n get(type: string): ComponentType<A2UIComponentProps> | null {\n const registration = this.registry.get(type);\n if (!registration) return null;\n\n // If lazy loading is enabled and the component is a loader function\n if (registration.lazy && typeof registration.component === \"function\") {\n // Check cache first\n const cached = this.lazyCache.get(type);\n if (cached) return cached;\n\n // Create lazy component and cache it\n const lazyComponent = lazy(registration.component as ComponentLoader);\n this.lazyCache.set(type, lazyComponent);\n return lazyComponent;\n }\n\n return registration.component as ComponentType<A2UIComponentProps>;\n }\n\n /**\n * Get all registered component types.\n *\n * @returns Array of registered type names\n */\n getRegisteredTypes(): string[] {\n return Array.from(this.registry.keys());\n }\n\n /**\n * Clear all registrations.\n */\n clear(): void {\n this.registry.clear();\n this.lazyCache.clear();\n }\n}\n","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","/**\n * Converts a theme class map (Record<string, boolean>) to a className string.\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 *\n * @example\n * classMapToString({ 'a2ui-button': true, 'a2ui-button--primary': true, 'disabled': false })\n * // Returns: 'a2ui-button a2ui-button--primary'\n */\nexport function classMapToString(\n classMap: Record<string, boolean> | undefined,\n): string {\n if (!classMap) return \"\";\n return Object.entries(classMap)\n .filter(([, enabled]) => enabled)\n .map(([className]) => className)\n .join(\" \");\n}\n\n/**\n * Converts an additional styles object (Record<string, string>) to a React style object.\n *\n * @param styles - An object with CSS property names as keys and values as strings\n * @returns A React-compatible style object, or undefined if no styles\n *\n * @example\n * stylesToObject({ 'background-color': 'red', 'font-size': '16px', '--custom-var': 'blue' })\n * // Returns: { backgroundColor: 'red', fontSize: '16px', '--custom-var': 'blue' }\n */\nexport function stylesToObject(\n styles: Record<string, string> | undefined,\n): React.CSSProperties | undefined {\n if (!styles || Object.keys(styles).length === 0) return undefined;\n\n const result: Record<string, string> = {};\n for (const [key, value] of Object.entries(styles)) {\n // Preserve CSS custom properties (--var-name) as-is\n if (key.startsWith(\"--\")) {\n result[key] = value;\n } else {\n // Convert kebab-case to camelCase for React\n const camelKey = key.replace(/-([a-z])/g, (_, letter) =>\n letter.toUpperCase(),\n );\n result[camelKey] = value;\n }\n }\n return result as React.CSSProperties;\n}\n","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","import { Suspense, useMemo, memo, type ReactNode } from \"react\";\nimport { useA2UI } from \"../hooks/useA2UI\";\nimport { ComponentNode } from \"./ComponentNode\";\nimport { type ComponentRegistry } from \"../registry/ComponentRegistry\";\nimport { cn } from \"../lib/utils\";\n\n/** Default loading fallback - memoized to prevent recreation */\nconst DefaultLoadingFallback = memo(function DefaultLoadingFallback() {\n return (\n <div className=\"a2ui-loading\" style={{ padding: \"16px\", opacity: 0.5 }}>\n Loading...\n </div>\n );\n});\n\nexport interface A2UIRendererProps {\n /** The surface ID to render */\n surfaceId: string;\n /** Additional CSS classes for the surface container */\n className?: string;\n /** Fallback content when surface is not yet available */\n fallback?: ReactNode;\n /** Loading fallback for lazy-loaded components */\n loadingFallback?: ReactNode;\n /** Optional custom component registry */\n registry?: ComponentRegistry;\n}\n\n/**\n * A2UIRenderer - renders an A2UI surface.\n *\n * This is the main entry point for rendering A2UI content in your React app.\n * It reads the surface state from the A2UI store and renders the component tree.\n *\n * Memoized to prevent unnecessary re-renders when props haven't changed.\n *\n * @example\n * ```tsx\n * function App() {\n * return (\n * <A2UIProvider onAction={handleAction}>\n * <A2UIRenderer surfaceId=\"main\" />\n * </A2UIProvider>\n * );\n * }\n * ```\n */\nexport const A2UIRenderer = memo(function A2UIRenderer({\n surfaceId,\n className,\n fallback = null,\n loadingFallback,\n registry,\n}: A2UIRendererProps) {\n const { getSurface, version } = useA2UI();\n\n // Get surface - this will re-render when version changes\n const surface = getSurface(surfaceId);\n\n // Memoize surface styles to prevent object recreation\n // Matches Lit renderer's transformation logic in surface.ts\n const surfaceStyles = useMemo<React.CSSProperties>(() => {\n if (!surface?.styles) return {};\n\n const styles: React.CSSProperties & Record<string, string> = {};\n\n for (const [key, value] of Object.entries(surface.styles)) {\n switch (key) {\n // Generate a color palette from the primary color.\n // Values range from 0-100 where 0=black, 100=white, 50=primary color.\n // Uses color-mix to create intermediate values.\n case \"primaryColor\": {\n styles[\"--p-100\"] = \"#ffffff\";\n styles[\"--p-99\"] = `color-mix(in srgb, ${value} 2%, white 98%)`;\n styles[\"--p-98\"] = `color-mix(in srgb, ${value} 4%, white 96%)`;\n styles[\"--p-95\"] = `color-mix(in srgb, ${value} 10%, white 90%)`;\n styles[\"--p-90\"] = `color-mix(in srgb, ${value} 20%, white 80%)`;\n styles[\"--p-80\"] = `color-mix(in srgb, ${value} 40%, white 60%)`;\n styles[\"--p-70\"] = `color-mix(in srgb, ${value} 60%, white 40%)`;\n styles[\"--p-60\"] = `color-mix(in srgb, ${value} 80%, white 20%)`;\n styles[\"--p-50\"] = String(value);\n styles[\"--p-40\"] = `color-mix(in srgb, ${value} 80%, black 20%)`;\n styles[\"--p-35\"] = `color-mix(in srgb, ${value} 70%, black 30%)`;\n styles[\"--p-30\"] = `color-mix(in srgb, ${value} 60%, black 40%)`;\n styles[\"--p-25\"] = `color-mix(in srgb, ${value} 50%, black 50%)`;\n styles[\"--p-20\"] = `color-mix(in srgb, ${value} 40%, black 60%)`;\n styles[\"--p-15\"] = `color-mix(in srgb, ${value} 30%, black 70%)`;\n styles[\"--p-10\"] = `color-mix(in srgb, ${value} 20%, black 80%)`;\n styles[\"--p-5\"] = `color-mix(in srgb, ${value} 10%, black 90%)`;\n styles[\"--p-0\"] = \"#000000\";\n break;\n }\n\n case \"font\": {\n styles[\"--font-family\"] = String(value);\n styles[\"--font-family-flex\"] = String(value);\n break;\n }\n }\n }\n return styles;\n }, [surface?.styles]);\n\n // No surface yet\n if (!surface || !surface.componentTree) {\n return <>{fallback}</>;\n }\n\n // Use provided fallback or default memoized component\n const actualLoadingFallback = loadingFallback ?? <DefaultLoadingFallback />;\n\n return (\n <div\n className={cn(\"a2ui-surface\", className)}\n style={surfaceStyles}\n data-surface-id={surfaceId}\n data-version={version}\n >\n <Suspense fallback={actualLoadingFallback}>\n <ComponentNode\n node={surface.componentTree}\n surfaceId={surfaceId}\n registry={registry}\n />\n </Suspense>\n </div>\n );\n});\n\nexport default A2UIRenderer;\n","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","import { useMemo, memo } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport type { A2UIComponentProps } from \"../../types\";\nimport { useA2UIComponent } from \"../../hooks/useA2UIComponent\";\nimport {\n classMapToString,\n stylesToObject,\n mergeClassMaps,\n} from \"../../lib/utils\";\nimport MarkdownIt from \"markdown-it\";\n\ntype UsageHint = \"h1\" | \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"caption\" | \"body\";\n\ninterface HintedStyles {\n h1: Record<string, string>;\n h2: Record<string, string>;\n h3: Record<string, string>;\n h4: Record<string, string>;\n h5: Record<string, string>;\n body: Record<string, string>;\n caption: Record<string, string>;\n}\n\nfunction isHintedStyles(styles: unknown): styles is HintedStyles {\n if (typeof styles !== \"object\" || !styles || Array.isArray(styles))\n return false;\n const expected = [\"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"caption\", \"body\"];\n return expected.some((v) => v in styles);\n}\n\n/**\n * Markdown-it instance for rendering markdown text.\n * Uses synchronous import to ensure availability at first render (matches Lit renderer).\n *\n * Configuration matches Lit's markdown directive (uses MarkdownIt defaults):\n * - html: false (default) - Security: disable raw HTML\n * - linkify: false (default) - Don't auto-convert URLs/emails to links\n * - breaks: false (default) - Don't convert \\n to <br>\n * - typographer: false (default) - Don't use smart quotes/dashes\n */\nconst markdownRenderer = new MarkdownIt();\n\n/**\n * Apply theme classes to markdown HTML elements.\n * Replaces default element tags with themed versions.\n */\nfunction applyMarkdownTheme(\n html: string,\n markdownTheme: Types.Theme[\"markdown\"],\n): string {\n if (!markdownTheme) return html;\n\n // Map of element -> classes\n const replacements: Array<[RegExp, string]> = [];\n\n for (const [element, classes] of Object.entries(markdownTheme)) {\n if (!classes || (Array.isArray(classes) && classes.length === 0)) continue;\n\n const classString = Array.isArray(classes)\n ? classes.join(\" \")\n : classMapToString(classes);\n if (!classString) continue;\n\n // Create regex to match opening tags (handles self-closing and regular)\n const tagRegex = new RegExp(`<${element}(?=\\\\s|>|/>)`, \"gi\");\n replacements.push([tagRegex, `<${element} class=\"${classString}\"`]);\n }\n\n let result = html;\n for (const [regex, replacement] of replacements) {\n result = result.replace(regex, replacement);\n }\n\n return result;\n}\n\n/**\n * Text component - renders text content with markdown support.\n *\n * Structure mirrors Lit's Text component:\n * <div class=\"a2ui-text\"> ← :host equivalent\n * <section class=\"...\"> ← theme classes\n * <h2>...</h2> ← rendered markdown content\n * </section>\n * </div>\n *\n * Text is parsed as markdown and rendered as HTML (matches Lit renderer behavior).\n * Supports usageHint values: h1, h2, h3, h4, h5, caption, body\n *\n * Markdown features supported:\n * - **Bold** and *italic* text\n * - Lists (ordered and unordered)\n * - `inline code` and code blocks\n * - [Links](url) (auto-linkified URLs too)\n * - Blockquotes\n * - Horizontal rules\n *\n * Note: Raw HTML is disabled for security.\n */\nexport const Text = memo(function Text({\n node,\n surfaceId,\n}: A2UIComponentProps<Types.TextNode>) {\n const { theme, resolveString } = useA2UIComponent(node, surfaceId);\n const props = node.properties;\n\n const textValue = resolveString(props.text);\n const usageHint = props.usageHint as UsageHint | undefined;\n\n // Get merged classes (matches Lit's Styles.merge)\n const classes = mergeClassMaps(\n theme.components.Text.all,\n usageHint ? theme.components.Text[usageHint] : {},\n );\n\n // Get additional styles based on usage hint\n const additionalStyles = useMemo(() => {\n const textStyles = theme.additionalStyles?.Text;\n if (!textStyles) return undefined;\n\n if (isHintedStyles(textStyles)) {\n const hint = usageHint ?? \"body\";\n return stylesToObject(textStyles[hint]);\n }\n return stylesToObject(textStyles as Record<string, string>);\n }, [theme.additionalStyles?.Text, usageHint]);\n\n // Render markdown content (matches Lit behavior - always uses markdown)\n const renderedContent = useMemo(() => {\n if (textValue === null || textValue === undefined) {\n return null;\n }\n\n // Add markdown prefix based on usageHint (matches Lit behavior)\n let markdownText = textValue;\n switch (usageHint) {\n case \"h1\":\n markdownText = `# ${markdownText}`;\n break;\n case \"h2\":\n markdownText = `## ${markdownText}`;\n break;\n case \"h3\":\n markdownText = `### ${markdownText}`;\n break;\n case \"h4\":\n markdownText = `#### ${markdownText}`;\n break;\n case \"h5\":\n markdownText = `##### ${markdownText}`;\n break;\n case \"caption\":\n markdownText = `*${markdownText}*`;\n break;\n default:\n break; // Body - no prefix\n }\n\n const rawHtml = markdownRenderer.render(markdownText);\n const themedHtml = applyMarkdownTheme(rawHtml, theme.markdown);\n return { __html: themedHtml };\n }, [textValue, theme.markdown, usageHint]);\n\n if (!renderedContent) {\n return null;\n }\n\n // Apply --weight CSS variable on root div (:host equivalent) for flex layouts\n const hostStyle: React.CSSProperties =\n node.weight !== undefined\n ? ({ \"--weight\": node.weight } as React.CSSProperties)\n : {};\n\n return (\n <div className=\"a2ui-text\" style={hostStyle}>\n <section\n className={classMapToString(classes)}\n style={additionalStyles}\n dangerouslySetInnerHTML={renderedContent}\n />\n </div>\n );\n});\n\nexport default Text;\n","import { memo } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport type { A2UIComponentProps } from \"../../types\";\nimport { useA2UIComponent } from \"../../hooks/useA2UIComponent\";\nimport {\n classMapToString,\n stylesToObject,\n mergeClassMaps,\n} from \"../../lib/utils\";\n\ntype UsageHint =\n | \"icon\"\n | \"avatar\"\n | \"smallFeature\"\n | \"mediumFeature\"\n | \"largeFeature\"\n | \"header\";\ntype FitMode = \"contain\" | \"cover\" | \"fill\" | \"none\" | \"scale-down\";\n\n/**\n * Image component - renders an image from a URL with optional sizing and fit modes.\n *\n * Supports usageHint values: icon, avatar, smallFeature, mediumFeature, largeFeature, header\n * Supports fit values: contain, cover, fill, none, scale-down (maps to object-fit via CSS variable)\n */\nexport const Image = memo(function Image({\n node,\n surfaceId,\n}: A2UIComponentProps<Types.ImageNode>) {\n const { theme, resolveString } = useA2UIComponent(node, surfaceId);\n const props = node.properties;\n\n const url = resolveString(props.url);\n const usageHint = props.usageHint as UsageHint | undefined;\n const fit = (props.fit as FitMode) ?? \"fill\";\n\n // Get merged classes for section (matches Lit's Styles.merge)\n const classes = mergeClassMaps(\n theme.components.Image.all,\n usageHint ? theme.components.Image[usageHint] : {},\n );\n\n // Build style object with object-fit as CSS variable (matches Lit)\n const style: React.CSSProperties = {\n ...stylesToObject(theme.additionalStyles?.Image),\n \"--object-fit\": fit,\n } as React.CSSProperties;\n\n if (!url) {\n return null;\n }\n\n // Apply --weight CSS variable on root div (:host equivalent) for flex layouts\n const hostStyle: React.CSSProperties =\n node.weight !== undefined\n ? ({ \"--weight\": node.weight } as React.CSSProperties)\n : {};\n\n return (\n <div className=\"a2ui-image\" style={hostStyle}>\n <section className={classMapToString(classes)} style={style}>\n <img src={url} alt=\"\" />\n </section>\n </div>\n );\n});\n\nexport default Image;\n","import { memo } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport type { A2UIComponentProps } from \"../../types\";\nimport { useA2UIComponent } from \"../../hooks/useA2UIComponent\";\nimport { classMapToString, stylesToObject } from \"../../lib/utils\";\n\n/**\n * Convert camelCase to snake_case for Material Symbols font.\n * e.g., \"shoppingCart\" -> \"shopping_cart\"\n * This matches the Lit renderer's approach.\n */\nfunction toSnakeCase(str: string): string {\n return str.replace(/([A-Z])/g, \"_$1\").toLowerCase();\n}\n\n/**\n * Icon component - renders an icon using Material Symbols Outlined font.\n *\n * This matches the Lit renderer's approach using the g-icon class with\n * Material Symbols Outlined font.\n *\n * @example Add Material Symbols font to your HTML:\n * ```html\n * <link href=\"https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined\" rel=\"stylesheet\">\n * ```\n */\nexport const Icon = memo(function Icon({\n node,\n surfaceId,\n}: A2UIComponentProps<Types.IconNode>) {\n const { theme, resolveString } = useA2UIComponent(node, surfaceId);\n const props = node.properties;\n\n const iconName = resolveString(props.name);\n\n if (!iconName) {\n return null;\n }\n\n // Convert camelCase to snake_case for Material Symbols\n const snakeCaseName = toSnakeCase(iconName);\n\n // Apply --weight CSS variable on root div (:host equivalent) for flex layouts\n const hostStyle: React.CSSProperties =\n node.weight !== undefined\n ? ({ \"--weight\": node.weight } as React.CSSProperties)\n : {};\n\n return (\n <div className=\"a2ui-icon\" style={hostStyle}>\n <section\n className={classMapToString(theme.components.Icon)}\n style={stylesToObject(theme.additionalStyles?.Icon)}\n >\n <span className=\"g-icon\">{snakeCaseName}</span>\n </section>\n </div>\n );\n});\n\nexport default Icon;\n","import { memo } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport type { A2UIComponentProps } from \"../../types\";\nimport { useA2UIComponent } from \"../../hooks/useA2UIComponent\";\nimport { classMapToString, stylesToObject } from \"../../lib/utils\";\n\n/**\n * Divider component - renders a visual separator line.\n *\n * Structure mirrors Lit's Divider component:\n * <div class=\"a2ui-divider\"> ← :host equivalent\n * <hr class=\"...\"> ← internal element\n * </div>\n */\nexport const Divider = memo(function Divider({\n node,\n surfaceId,\n}: A2UIComponentProps<Types.DividerNode>) {\n const { theme } = useA2UIComponent(node, surfaceId);\n\n // Apply --weight CSS variable on root div (:host equivalent) for flex layouts\n const hostStyle: React.CSSProperties =\n node.weight !== undefined\n ? ({ \"--weight\": node.weight } as React.CSSProperties)\n : {};\n\n return (\n <div className=\"a2ui-divider\" style={hostStyle}>\n <hr\n className={classMapToString(theme.components.Divider)}\n style={stylesToObject(theme.additionalStyles?.Divider)}\n />\n </div>\n );\n});\n\nexport default Divider;\n","import { memo } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport type { A2UIComponentProps } from \"../../types\";\nimport { useA2UIComponent } from \"../../hooks/useA2UIComponent\";\nimport { classMapToString, stylesToObject } from \"../../lib/utils\";\n\n/**\n * Check if a URL is a YouTube URL and extract the video ID.\n */\nfunction getYouTubeVideoId(url: string): string | null {\n const patterns = [\n /(?:youtube\\.com\\/watch\\?v=|youtu\\.be\\/|youtube\\.com\\/embed\\/)([^&\\s?]+)/,\n ];\n for (const pattern of patterns) {\n const match = url.match(pattern);\n if (match && match.length > 1) {\n // Non-null assertion is safe here since we checked match.length > 1\n\n return match[1]!;\n }\n }\n return null;\n}\n\n/**\n * Video component - renders a video player.\n *\n * Supports regular video URLs and YouTube URLs (renders as embedded iframe).\n */\nexport const Video = memo(function Video({\n node,\n surfaceId,\n}: A2UIComponentProps<Types.VideoNode>) {\n const { theme, resolveString } = useA2UIComponent(node, surfaceId);\n const props = node.properties;\n\n const url = resolveString(props.url);\n\n if (!url) {\n return null;\n }\n\n const youtubeId = getYouTubeVideoId(url);\n\n // Apply --weight CSS variable on root div (:host equivalent) for flex layouts\n const hostStyle: React.CSSProperties =\n node.weight !== undefined\n ? ({ \"--weight\": node.weight } as React.CSSProperties)\n : {};\n\n return (\n <div className=\"a2ui-video\" style={hostStyle}>\n <section\n className={classMapToString(theme.components.Video)}\n style={stylesToObject(theme.additionalStyles?.Video)}\n >\n {youtubeId ? (\n <iframe\n src={`https://www.youtube.com/embed/${youtubeId}`}\n title=\"YouTube video player\"\n allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\"\n allowFullScreen\n style={{ border: \"none\", width: \"100%\", aspectRatio: \"16/9\" }}\n />\n ) : (\n <video src={url} controls />\n )}\n </section>\n </div>\n );\n});\n\nexport default Video;\n","import { memo } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport type { A2UIComponentProps } from \"../../types\";\nimport { useA2UIComponent } from \"../../hooks/useA2UIComponent\";\nimport { classMapToString, stylesToObject } from \"../../lib/utils\";\n\n/**\n * AudioPlayer component - renders an audio player with optional description.\n */\nexport const AudioPlayer = memo(function AudioPlayer({\n node,\n surfaceId,\n}: A2UIComponentProps<Types.AudioPlayerNode>) {\n const { theme, resolveString } = useA2UIComponent(node, surfaceId);\n const props = node.properties;\n\n const url = resolveString(props.url);\n const description = resolveString(props.description ?? null);\n\n if (!url) {\n return null;\n }\n\n // Apply --weight CSS variable on root div (:host equivalent) for flex layouts\n const hostStyle: React.CSSProperties =\n node.weight !== undefined\n ? ({ \"--weight\": node.weight } as React.CSSProperties)\n : {};\n\n return (\n <div className=\"a2ui-audio\" style={hostStyle}>\n <section\n className={classMapToString(theme.components.AudioPlayer)}\n style={stylesToObject(theme.additionalStyles?.AudioPlayer)}\n >\n {description && <p>{description}</p>}\n <audio src={url} controls />\n </section>\n </div>\n );\n});\n\nexport default AudioPlayer;\n","import { memo } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport type { A2UIComponentProps } from \"../../types\";\nimport { useA2UIComponent } from \"../../hooks/useA2UIComponent\";\nimport { classMapToString, stylesToObject } from \"../../lib/utils\";\nimport { ComponentNode } from \"../../core/ComponentNode\";\n\n/**\n * Row component - arranges children horizontally using flexbox.\n *\n * Supports distribution (justify-content) and alignment (align-items) properties.\n */\nexport const Row = memo(function Row({\n node,\n surfaceId,\n}: A2UIComponentProps<Types.RowNode>) {\n const { theme } = useA2UIComponent(node, surfaceId);\n const props = node.properties;\n\n // Match Lit's default values\n const alignment = props.alignment ?? \"stretch\";\n const distribution = props.distribution ?? \"start\";\n\n const children = Array.isArray(props.children) ? props.children : [];\n\n // Apply --weight CSS variable on root div (:host equivalent) for flex layouts\n const hostStyle: React.CSSProperties =\n node.weight !== undefined\n ? ({ \"--weight\": node.weight } as React.CSSProperties)\n : {};\n\n return (\n <div\n className=\"a2ui-row\"\n data-alignment={alignment}\n data-distribution={distribution}\n style={hostStyle}\n >\n <section\n className={classMapToString(theme.components.Row)}\n style={stylesToObject(theme.additionalStyles?.Row)}\n >\n {children.map((child, index) => {\n const childId =\n typeof child === \"object\" && child !== null && \"id\" in child\n ? (child as Types.AnyComponentNode).id\n : `child-${index}`;\n const childNode =\n typeof child === \"object\" && child !== null && \"type\" in child\n ? (child as Types.AnyComponentNode)\n : null;\n return (\n <ComponentNode\n key={childId}\n node={childNode}\n surfaceId={surfaceId}\n />\n );\n })}\n </section>\n </div>\n );\n});\n\nexport default Row;\n","import { memo } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport type { A2UIComponentProps } from \"../../types\";\nimport { useA2UIComponent } from \"../../hooks/useA2UIComponent\";\nimport { classMapToString, stylesToObject } from \"../../lib/utils\";\nimport { ComponentNode } from \"../../core/ComponentNode\";\n\n/**\n * Column component - arranges children vertically using flexbox.\n *\n * Supports distribution (justify-content) and alignment (align-items) properties.\n */\nexport const Column = memo(function Column({\n node,\n surfaceId,\n}: A2UIComponentProps<Types.ColumnNode>) {\n const { theme } = useA2UIComponent(node, surfaceId);\n const props = node.properties;\n\n // Match Lit's default values\n const alignment = props.alignment ?? \"stretch\";\n const distribution = props.distribution ?? \"start\";\n\n const children = Array.isArray(props.children) ? props.children : [];\n\n // Apply --weight CSS variable on root div (:host equivalent) for flex layouts\n const hostStyle: React.CSSProperties =\n node.weight !== undefined\n ? ({ \"--weight\": node.weight } as React.CSSProperties)\n : {};\n\n return (\n <div\n className=\"a2ui-column\"\n data-alignment={alignment}\n data-distribution={distribution}\n style={hostStyle}\n >\n <section\n className={classMapToString(theme.components.Column)}\n style={stylesToObject(theme.additionalStyles?.Column)}\n >\n {children.map((child, index) => {\n const childId =\n typeof child === \"object\" && child !== null && \"id\" in child\n ? (child as Types.AnyComponentNode).id\n : `child-${index}`;\n const childNode =\n typeof child === \"object\" && child !== null && \"type\" in child\n ? (child as Types.AnyComponentNode)\n : null;\n return (\n <ComponentNode\n key={childId}\n node={childNode}\n surfaceId={surfaceId}\n />\n );\n })}\n </section>\n </div>\n );\n});\n\nexport default Column;\n","import { memo } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport type { A2UIComponentProps } from \"../../types\";\nimport { useA2UIComponent } from \"../../hooks/useA2UIComponent\";\nimport { classMapToString, stylesToObject } from \"../../lib/utils\";\nimport { ComponentNode } from \"../../core/ComponentNode\";\n\n/**\n * List component - renders a scrollable list of items.\n *\n * Supports direction (vertical/horizontal) properties.\n */\nexport const List = memo(function List({\n node,\n surfaceId,\n}: A2UIComponentProps<Types.ListNode>) {\n const { theme } = useA2UIComponent(node, surfaceId);\n const props = node.properties;\n\n // Match Lit's default value\n const direction = props.direction ?? \"vertical\";\n\n const children = Array.isArray(props.children) ? props.children : [];\n\n // Apply --weight CSS variable on root div (:host equivalent) for flex layouts\n const hostStyle: React.CSSProperties =\n node.weight !== undefined\n ? ({ \"--weight\": node.weight } as React.CSSProperties)\n : {};\n\n return (\n <div className=\"a2ui-list\" data-direction={direction} style={hostStyle}>\n <section\n className={classMapToString(theme.components.List)}\n style={stylesToObject(theme.additionalStyles?.List)}\n >\n {children.map((child, index) => {\n const childId =\n typeof child === \"object\" && child !== null && \"id\" in child\n ? (child as Types.AnyComponentNode).id\n : `child-${index}`;\n const childNode =\n typeof child === \"object\" && child !== null && \"type\" in child\n ? (child as Types.AnyComponentNode)\n : null;\n return (\n <ComponentNode\n key={childId}\n node={childNode}\n surfaceId={surfaceId}\n />\n );\n })}\n </section>\n </div>\n );\n});\n\nexport default List;\n","import { memo } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport type { A2UIComponentProps } from \"../../types\";\nimport { useA2UIComponent } from \"../../hooks/useA2UIComponent\";\nimport { classMapToString, stylesToObject } from \"../../lib/utils\";\nimport { ComponentNode } from \"../../core/ComponentNode\";\n\n/**\n * Card component - a container that visually groups content.\n *\n * Structure mirrors Lit's Card component:\n * <div class=\"a2ui-card\"> ← :host equivalent\n * <section class=\"...\"> ← theme classes (border, padding, background)\n * {children} ← ::slotted(*) equivalent\n * </section>\n * </div>\n *\n * All styles come from componentSpecificStyles CSS, no inline styles needed.\n */\nexport const Card = memo(function Card({\n node,\n surfaceId,\n}: A2UIComponentProps<Types.CardNode>) {\n const { theme } = useA2UIComponent(node, surfaceId);\n const props = node.properties;\n\n // Card can have either a single child or multiple children\n const rawChildren = props.children ?? (props.child ? [props.child] : []);\n const children = Array.isArray(rawChildren) ? rawChildren : [];\n\n // Apply --weight CSS variable on root div (:host equivalent) for flex layouts\n const hostStyle: React.CSSProperties =\n node.weight !== undefined\n ? ({ \"--weight\": node.weight } as React.CSSProperties)\n : {};\n\n return (\n <div className=\"a2ui-card\" style={hostStyle}>\n <section\n className={classMapToString(theme.components.Card)}\n style={stylesToObject(theme.additionalStyles?.Card)}\n >\n {children.map((child, index) => {\n const childId =\n typeof child === \"object\" && child !== null && \"id\" in child\n ? (child as Types.AnyComponentNode).id\n : `child-${index}`;\n const childNode =\n typeof child === \"object\" && child !== null && \"type\" in child\n ? (child as Types.AnyComponentNode)\n : null;\n return (\n <ComponentNode\n key={childId}\n node={childNode}\n surfaceId={surfaceId}\n />\n );\n })}\n </section>\n </div>\n );\n});\n\nexport default Card;\n","import { useState, memo } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport type { A2UIComponentProps } from \"../../types\";\nimport { useA2UIComponent } from \"../../hooks/useA2UIComponent\";\nimport {\n classMapToString,\n stylesToObject,\n mergeClassMaps,\n} from \"../../lib/utils\";\nimport { ComponentNode } from \"../../core/ComponentNode\";\n\n/**\n * Tabs component - displays content in switchable tabs.\n */\nexport const Tabs = memo(function Tabs({\n node,\n surfaceId,\n}: A2UIComponentProps<Types.TabsNode>) {\n const { theme, resolveString } = useA2UIComponent(node, surfaceId);\n const props = node.properties;\n\n const [selectedIndex, setSelectedIndex] = useState(0);\n\n const tabItems = props.tabItems ?? [];\n\n // Apply --weight CSS variable on root div (:host equivalent) for flex layouts\n const hostStyle: React.CSSProperties =\n node.weight !== undefined\n ? ({ \"--weight\": node.weight } as React.CSSProperties)\n : {};\n\n return (\n <div className=\"a2ui-tabs\" style={hostStyle}>\n <section\n className={classMapToString(theme.components.Tabs.container)}\n style={stylesToObject(theme.additionalStyles?.Tabs)}\n >\n {/* Tab buttons - uses Tabs.element for the container */}\n <div\n id=\"buttons\"\n className={classMapToString(theme.components.Tabs.element)}\n >\n {tabItems.map((tab, index) => {\n const title = resolveString(tab.title);\n const isSelected = index === selectedIndex;\n\n // Lit merges all + selected classes when selected\n const classes = isSelected\n ? mergeClassMaps(\n theme.components.Tabs.controls.all,\n theme.components.Tabs.controls.selected,\n )\n : theme.components.Tabs.controls.all;\n\n return (\n <button\n key={index}\n disabled={isSelected}\n className={classMapToString(classes)}\n onClick={() => setSelectedIndex(index)}\n >\n {title}\n </button>\n );\n })}\n </div>\n\n {/* Tab content */}\n {tabItems[selectedIndex] && (\n <ComponentNode\n node={tabItems[selectedIndex].child}\n surfaceId={surfaceId}\n />\n )}\n </section>\n </div>\n );\n});\n\nexport default Tabs;\n","import { useState, useCallback, useRef, useEffect, memo } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport type { A2UIComponentProps } from \"../../types\";\nimport { useA2UIComponent } from \"../../hooks/useA2UIComponent\";\nimport { classMapToString, stylesToObject } from \"../../lib/utils\";\nimport { ComponentNode } from \"../../core/ComponentNode\";\n\n/**\n * Modal component - displays content in a dialog overlay.\n *\n * Matches Lit's rendering approach:\n * - When closed: renders section with entry point child\n * - When open: renders dialog with content child (entry point is replaced)\n *\n * The dialog is rendered in place (no portal) so it stays inside .a2ui-surface\n * and CSS selectors work correctly. showModal() handles the top-layer overlay.\n */\nexport const Modal = memo(function Modal({\n node,\n surfaceId,\n}: A2UIComponentProps<Types.ModalNode>) {\n const { theme } = useA2UIComponent(node, surfaceId);\n const props = node.properties;\n\n const [isOpen, setIsOpen] = useState(false);\n const dialogRef = useRef<HTMLDialogElement>(null);\n\n const openModal = useCallback(() => {\n setIsOpen(true);\n }, []);\n\n const closeModal = useCallback(() => {\n setIsOpen(false);\n }, []);\n\n // Show dialog when isOpen becomes true, and sync state when dialog closes (e.g., via Escape)\n useEffect(() => {\n const dialog = dialogRef.current;\n if (!dialog) return;\n\n if (isOpen && !dialog.open) {\n dialog.showModal();\n }\n\n // Listen for native close event (triggered by Escape key)\n const handleClose = () => {\n setIsOpen(false);\n };\n dialog.addEventListener(\"close\", handleClose);\n return () => dialog.removeEventListener(\"close\", handleClose);\n }, [isOpen]);\n\n // Handle backdrop clicks (only close if clicking directly on dialog, not its content)\n const handleBackdropClick = useCallback(\n (e: React.MouseEvent<HTMLDialogElement>) => {\n if (e.target === e.currentTarget) {\n closeModal();\n }\n },\n [closeModal],\n );\n\n // Handle Escape key (for jsdom test compatibility - real browsers use native dialog behavior)\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLDialogElement>) => {\n if (e.key === \"Escape\") {\n closeModal();\n }\n },\n [closeModal],\n );\n\n // Apply --weight CSS variable on root div (:host equivalent) for flex layouts\n const hostStyle: React.CSSProperties =\n node.weight !== undefined\n ? ({ \"--weight\": node.weight } as React.CSSProperties)\n : {};\n\n // Match Lit's render approach: closed shows section with entry, open shows dialog\n if (!isOpen) {\n return (\n <div className=\"a2ui-modal\" style={hostStyle}>\n <section onClick={openModal} style={{ cursor: \"pointer\" }}>\n <ComponentNode node={props.entryPointChild} surfaceId={surfaceId} />\n </section>\n </div>\n );\n }\n\n return (\n <div className=\"a2ui-modal\" style={hostStyle}>\n <dialog\n ref={dialogRef}\n className={classMapToString(theme.components.Modal.backdrop)}\n onClick={handleBackdropClick}\n onKeyDown={handleKeyDown}\n >\n <section\n className={classMapToString(theme.components.Modal.element)}\n style={stylesToObject(theme.additionalStyles?.Modal)}\n >\n <div id=\"controls\">\n <button onClick={closeModal} aria-label=\"Close modal\">\n <span className=\"g-icon\">close</span>\n </button>\n </div>\n <ComponentNode node={props.contentChild} surfaceId={surfaceId} />\n </section>\n </dialog>\n </div>\n );\n});\n\nexport default Modal;\n","import { useCallback, memo } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport type { A2UIComponentProps } from \"../../types\";\nimport { useA2UIComponent } from \"../../hooks/useA2UIComponent\";\nimport { classMapToString, stylesToObject } from \"../../lib/utils\";\nimport { ComponentNode } from \"../../core/ComponentNode\";\n\n/**\n * Button component - a clickable element that triggers an action.\n *\n * Contains a child component (usually Text or Icon) and dispatches\n * a user action when clicked.\n */\nexport const Button = memo(function Button({\n node,\n surfaceId,\n}: A2UIComponentProps<Types.ButtonNode>) {\n const { theme, sendAction } = useA2UIComponent(node, surfaceId);\n const props = node.properties;\n\n const handleClick = useCallback(() => {\n if (props.action) {\n sendAction(props.action);\n }\n }, [props.action, sendAction]);\n\n // Apply --weight CSS variable on root div (:host equivalent) for flex layouts\n const hostStyle: React.CSSProperties =\n node.weight !== undefined\n ? ({ \"--weight\": node.weight } as React.CSSProperties)\n : {};\n\n return (\n <div className=\"a2ui-button\" style={hostStyle}>\n <button\n className={classMapToString(theme.components.Button)}\n style={stylesToObject(theme.additionalStyles?.Button)}\n onClick={handleClick}\n >\n <ComponentNode node={props.child} surfaceId={surfaceId} />\n </button>\n </div>\n );\n});\n\nexport default Button;\n","import { useState, useCallback, useEffect, useId, memo } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport type { A2UIComponentProps } from \"../../types\";\nimport { useA2UIComponent } from \"../../hooks/useA2UIComponent\";\nimport { classMapToString, stylesToObject } from \"../../lib/utils\";\n\ntype TextFieldType = \"shortText\" | \"longText\" | \"number\" | \"date\";\n\n/**\n * TextField component - an input field for text entry.\n *\n * Supports various input types and two-way data binding.\n */\nexport const TextField = memo(function TextField({\n node,\n surfaceId,\n}: A2UIComponentProps<Types.TextFieldNode>) {\n const { theme, resolveString, setValue, getValue } = useA2UIComponent(\n node,\n surfaceId,\n );\n const props = node.properties;\n const id = useId();\n\n const label = resolveString(props.label);\n const textPath = props.text?.path;\n const initialValue = resolveString(props.text) ?? \"\";\n const fieldType = props.type as TextFieldType | undefined;\n const validationRegexp = props.validationRegexp;\n\n const [value, setLocalValue] = useState(initialValue);\n // Validation state tracked for potential future use (e.g., error styling)\n const [_isValid, setIsValid] = useState(true);\n\n // Sync with external data model changes\n useEffect(() => {\n if (textPath) {\n const externalValue = getValue(textPath);\n if (externalValue !== null && String(externalValue) !== value) {\n setLocalValue(String(externalValue));\n }\n }\n }, [textPath, getValue]); // eslint-disable-line react-hooks/exhaustive-deps\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {\n const newValue = e.target.value;\n setLocalValue(newValue);\n\n // Validate if pattern provided\n if (validationRegexp) {\n setIsValid(new RegExp(validationRegexp).test(newValue));\n }\n\n // Two-way binding: update data model\n if (textPath) {\n setValue(textPath, newValue);\n }\n },\n [validationRegexp, textPath, setValue],\n );\n\n const inputType =\n fieldType === \"number\" ? \"number\" : fieldType === \"date\" ? \"date\" : \"text\";\n const isTextArea = fieldType === \"longText\";\n\n // Structure mirrors Lit's TextField component:\n // <div class=\"a2ui-textfield\"> ← :host equivalent\n // <section class=\"...\"> ← container with theme classes\n // <label>...</label>\n // <input>...</input>\n // </section>\n // </div>\n\n // Apply --weight CSS variable on root div (:host equivalent) for flex layouts\n const hostStyle: React.CSSProperties =\n node.weight !== undefined\n ? ({ \"--weight\": node.weight } as React.CSSProperties)\n : {};\n\n return (\n <div className=\"a2ui-textfield\" style={hostStyle}>\n <section\n className={classMapToString(theme.components.TextField.container)}\n >\n {label && (\n <label\n htmlFor={id}\n className={classMapToString(theme.components.TextField.label)}\n >\n {label}\n </label>\n )}\n {isTextArea ? (\n <textarea\n id={id}\n value={value}\n onChange={handleChange}\n placeholder=\"Please enter a value\"\n className={classMapToString(theme.components.TextField.element)}\n style={stylesToObject(theme.additionalStyles?.TextField)}\n />\n ) : (\n <input\n type={inputType}\n id={id}\n value={value}\n onChange={handleChange}\n placeholder=\"Please enter a value\"\n className={classMapToString(theme.components.TextField.element)}\n style={stylesToObject(theme.additionalStyles?.TextField)}\n />\n )}\n </section>\n </div>\n );\n});\n\nexport default TextField;\n","import { useState, useCallback, useEffect, useId, memo } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport type { A2UIComponentProps } from \"../../types\";\nimport { useA2UIComponent } from \"../../hooks/useA2UIComponent\";\nimport { classMapToString, stylesToObject } from \"../../lib/utils\";\n\n/**\n * CheckBox component - a boolean toggle with a label.\n *\n * Supports two-way data binding for the checked state.\n */\nexport const CheckBox = memo(function CheckBox({\n node,\n surfaceId,\n}: A2UIComponentProps<Types.CheckboxNode>) {\n const { theme, resolveString, resolveBoolean, setValue, getValue } =\n useA2UIComponent(node, surfaceId);\n const props = node.properties;\n const id = useId();\n\n const label = resolveString(props.label);\n const valuePath = props.value?.path;\n const initialChecked = resolveBoolean(props.value) ?? false;\n\n const [checked, setChecked] = useState(initialChecked);\n\n // Sync with external data model changes (path binding)\n useEffect(() => {\n if (valuePath) {\n const externalValue = getValue(valuePath);\n if (externalValue !== null && Boolean(externalValue) !== checked) {\n setChecked(Boolean(externalValue));\n }\n }\n }, [valuePath, getValue]); // eslint-disable-line react-hooks/exhaustive-deps\n\n // Sync when literal value changes from props (server-driven updates via surfaceUpdate)\n useEffect(() => {\n if (props.value?.literalBoolean !== undefined) {\n setChecked(props.value.literalBoolean);\n }\n }, [props.value?.literalBoolean]);\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = e.target.checked;\n setChecked(newValue);\n\n // Two-way binding: update data model\n if (valuePath) {\n setValue(valuePath, newValue);\n }\n },\n [valuePath, setValue],\n );\n\n // Structure mirrors Lit's CheckBox component:\n // <div class=\"a2ui-checkbox\"> ← :host equivalent\n // <section class=\"...\"> ← internal element\n // <input>...</input>\n // <label>...</label>\n // </section>\n // </div>\n\n // Apply --weight CSS variable on root div (:host equivalent) for flex layouts\n const hostStyle: React.CSSProperties =\n node.weight !== undefined\n ? ({ \"--weight\": node.weight } as React.CSSProperties)\n : {};\n\n return (\n <div className=\"a2ui-checkbox\" style={hostStyle}>\n <section\n className={classMapToString(theme.components.CheckBox.container)}\n style={stylesToObject(theme.additionalStyles?.CheckBox)}\n >\n <input\n type=\"checkbox\"\n id={id}\n checked={checked}\n onChange={handleChange}\n className={classMapToString(theme.components.CheckBox.element)}\n />\n {label && (\n <label\n htmlFor={id}\n className={classMapToString(theme.components.CheckBox.label)}\n >\n {label}\n </label>\n )}\n </section>\n </div>\n );\n});\n\nexport default CheckBox;\n","import { useState, useCallback, useEffect, useId, memo } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport type { A2UIComponentProps } from \"../../types\";\nimport { useA2UIComponent } from \"../../hooks/useA2UIComponent\";\nimport { classMapToString, stylesToObject } from \"../../lib/utils\";\n\n/**\n * Slider component - a numeric value selector with a range.\n *\n * Supports two-way data binding for the value.\n */\nexport const Slider = memo(function Slider({\n node,\n surfaceId,\n}: A2UIComponentProps<Types.SliderNode>) {\n const { theme, resolveNumber, resolveString, setValue, getValue } =\n useA2UIComponent(node, surfaceId);\n const props = node.properties;\n const id = useId();\n\n const valuePath = props.value?.path;\n const initialValue = resolveNumber(props.value) ?? 0;\n // Match Lit's default values (minValue=0, maxValue=0)\n const minValue = props.minValue ?? 0;\n const maxValue = props.maxValue ?? 0;\n\n const [value, setLocalValue] = useState(initialValue);\n\n // Sync with external data model changes (path binding)\n useEffect(() => {\n if (valuePath) {\n const externalValue = getValue(valuePath);\n if (externalValue !== null && Number(externalValue) !== value) {\n setLocalValue(Number(externalValue));\n }\n }\n }, [valuePath, getValue]); // eslint-disable-line react-hooks/exhaustive-deps\n\n // Sync when literal value changes from props (server-driven updates via surfaceUpdate)\n useEffect(() => {\n if (props.value?.literalNumber !== undefined) {\n setLocalValue(props.value.literalNumber);\n }\n }, [props.value?.literalNumber]);\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = Number(e.target.value);\n setLocalValue(newValue);\n\n // Two-way binding: update data model\n if (valuePath) {\n setValue(valuePath, newValue);\n }\n },\n [valuePath, setValue],\n );\n\n // Access label from props if it exists (Lit component supports it but type doesn't define it)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const labelValue = (props as any).label;\n const label = labelValue ? resolveString(labelValue) : \"\";\n\n // Structure mirrors Lit's Slider component:\n // <div class=\"a2ui-slider\"> ← :host equivalent\n // <section class=\"...\"> ← internal element\n // <label>...</label>\n // <input>...</input>\n // <span>value</span>\n // </section>\n // </div>\n\n // Apply --weight CSS variable on root div (:host equivalent) for flex layouts\n const hostStyle: React.CSSProperties =\n node.weight !== undefined\n ? ({ \"--weight\": node.weight } as React.CSSProperties)\n : {};\n\n return (\n <div className=\"a2ui-slider\" style={hostStyle}>\n <section className={classMapToString(theme.components.Slider.container)}>\n <label\n htmlFor={id}\n className={classMapToString(theme.components.Slider.label)}\n >\n {label}\n </label>\n <input\n type=\"range\"\n id={id}\n name=\"data\"\n value={value}\n min={minValue}\n max={maxValue}\n onChange={handleChange}\n className={classMapToString(theme.components.Slider.element)}\n style={stylesToObject(theme.additionalStyles?.Slider)}\n />\n <span className={classMapToString(theme.components.Slider.label)}>\n {value}\n </span>\n </section>\n </div>\n );\n});\n\nexport default Slider;\n","import { useState, useCallback, useEffect, useId, memo } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport type { A2UIComponentProps } from \"../../types\";\nimport { useA2UIComponent } from \"../../hooks/useA2UIComponent\";\nimport { classMapToString, stylesToObject } from \"../../lib/utils\";\n\n/**\n * DateTimeInput component - a date and/or time picker.\n *\n * Supports enabling date, time, or both. Uses native HTML5 date/time inputs.\n */\nexport const DateTimeInput = memo(function DateTimeInput({\n node,\n surfaceId,\n}: A2UIComponentProps<Types.DateTimeInputNode>) {\n const { theme, resolveString, setValue, getValue } = useA2UIComponent(\n node,\n surfaceId,\n );\n const props = node.properties;\n const id = useId();\n\n const valuePath = props.value?.path;\n const initialValue = resolveString(props.value) ?? \"\";\n const enableDate = props.enableDate ?? true;\n const enableTime = props.enableTime ?? false;\n\n const [value, setLocalValue] = useState(initialValue);\n\n // Sync with external data model changes\n useEffect(() => {\n if (valuePath) {\n const externalValue = getValue(valuePath);\n if (externalValue !== null && String(externalValue) !== value) {\n setLocalValue(String(externalValue));\n }\n }\n }, [valuePath, getValue]); // eslint-disable-line react-hooks/exhaustive-deps\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = e.target.value;\n setLocalValue(newValue);\n\n // Two-way binding: update data model\n if (valuePath) {\n setValue(valuePath, newValue);\n }\n },\n [valuePath, setValue],\n );\n\n // Determine input type based on enableDate and enableTime\n let inputType: \"date\" | \"time\" | \"datetime-local\" = \"date\";\n if (enableDate && enableTime) {\n inputType = \"datetime-local\";\n } else if (enableTime && !enableDate) {\n inputType = \"time\";\n }\n\n // Get placeholder text to match Lit renderer\n const getPlaceholderText = () => {\n if (enableDate && enableTime) {\n return \"Date & Time\";\n } else if (enableTime) {\n return \"Time\";\n }\n return \"Date\";\n };\n\n // Structure mirrors Lit's DateTimeInput component:\n // <div class=\"a2ui-datetime-input\"> ← :host equivalent\n // <section class=\"...\"> ← container theme classes\n // <label> ← label\n // <input> ← input element\n // </section>\n // </div>\n\n // Apply --weight CSS variable on root div (:host equivalent) for flex layouts\n const hostStyle: React.CSSProperties =\n node.weight !== undefined\n ? ({ \"--weight\": node.weight } as React.CSSProperties)\n : {};\n\n return (\n <div className=\"a2ui-datetime-input\" style={hostStyle}>\n <section\n className={classMapToString(theme.components.DateTimeInput.container)}\n >\n <label\n htmlFor={id}\n className={classMapToString(theme.components.DateTimeInput.label)}\n >\n {getPlaceholderText()}\n </label>\n <input\n type={inputType}\n id={id}\n value={value}\n onChange={handleChange}\n className={classMapToString(theme.components.DateTimeInput.element)}\n style={stylesToObject(theme.additionalStyles?.DateTimeInput)}\n />\n </section>\n </div>\n );\n});\n\nexport default DateTimeInput;\n","import { useCallback, useId, memo } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport type { A2UIComponentProps } from \"../../types\";\nimport { useA2UIComponent } from \"../../hooks/useA2UIComponent\";\nimport { classMapToString, stylesToObject } from \"../../lib/utils\";\n\n/**\n * MultipleChoice component - a selection component using a dropdown.\n *\n * Renders a <select> element with options, matching the Lit renderer's behavior.\n * Supports two-way data binding for the selected value.\n */\nexport const MultipleChoice = memo(function MultipleChoice({\n node,\n surfaceId,\n}: A2UIComponentProps<Types.MultipleChoiceNode>) {\n const { theme, resolveString, setValue } = useA2UIComponent(node, surfaceId);\n const props = node.properties;\n const id = useId();\n\n const options =\n (props.options as {\n label: { literalString?: string; path?: string };\n value: string;\n }[]) ?? [];\n const selectionsPath = props.selections?.path;\n\n // Access description from props (Lit component supports it)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const description =\n resolveString((props as any).description) ?? \"Select an item\";\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLSelectElement>) => {\n // Two-way binding: update data model with array (matches Lit behavior)\n if (selectionsPath) {\n setValue(selectionsPath, [e.target.value]);\n }\n },\n [selectionsPath, setValue],\n );\n\n // Apply --weight CSS variable on root div (:host equivalent) for flex layouts\n const hostStyle: React.CSSProperties =\n node.weight !== undefined\n ? ({ \"--weight\": node.weight } as React.CSSProperties)\n : {};\n\n // Structure mirrors Lit's MultipleChoice component:\n // <div class=\"a2ui-multiplechoice\"> ← :host equivalent\n // <section class=\"...\"> ← container theme classes\n // <label>...</label> ← description label\n // <select>...</select> ← dropdown element\n // </section>\n // </div>\n return (\n <div className=\"a2ui-multiplechoice\" style={hostStyle}>\n <section\n className={classMapToString(theme.components.MultipleChoice.container)}\n >\n <label\n htmlFor={id}\n className={classMapToString(theme.components.MultipleChoice.label)}\n >\n {description}\n </label>\n <select\n name=\"data\"\n id={id}\n className={classMapToString(theme.components.MultipleChoice.element)}\n style={stylesToObject(theme.additionalStyles?.MultipleChoice)}\n onChange={handleChange}\n >\n {options.map((option) => {\n const label = resolveString(option.label);\n return (\n <option key={option.value} value={option.value}>\n {label}\n </option>\n );\n })}\n </select>\n </section>\n </div>\n );\n});\n\nexport default MultipleChoice;\n","import { ComponentRegistry } from \"./ComponentRegistry\";\n\n// Content components\nimport { Text } from \"../components/content/Text\";\nimport { Image } from \"../components/content/Image\";\nimport { Icon } from \"../components/content/Icon\";\nimport { Divider } from \"../components/content/Divider\";\nimport { Video } from \"../components/content/Video\";\nimport { AudioPlayer } from \"../components/content/AudioPlayer\";\n\n// Layout components\nimport { Row } from \"../components/layout/Row\";\nimport { Column } from \"../components/layout/Column\";\nimport { List } from \"../components/layout/List\";\nimport { Card } from \"../components/layout/Card\";\nimport { Tabs } from \"../components/layout/Tabs\";\nimport { Modal } from \"../components/layout/Modal\";\n\n// Interactive components\nimport { Button } from \"../components/interactive/Button\";\nimport { TextField } from \"../components/interactive/TextField\";\nimport { CheckBox } from \"../components/interactive/CheckBox\";\nimport { Slider } from \"../components/interactive/Slider\";\nimport { DateTimeInput } from \"../components/interactive/DateTimeInput\";\nimport { MultipleChoice } from \"../components/interactive/MultipleChoice\";\n\n/**\n * Registers all standard A2UI components in the registry.\n *\n * @param registry - The component registry to populate\n */\nexport function registerDefaultCatalog(registry: ComponentRegistry): void {\n // Content components (small, load immediately)\n registry.register(\"Text\", { component: Text });\n registry.register(\"Image\", { component: Image });\n registry.register(\"Icon\", { component: Icon });\n registry.register(\"Divider\", { component: Divider });\n registry.register(\"Video\", { component: Video });\n registry.register(\"AudioPlayer\", { component: AudioPlayer });\n\n // Layout components\n registry.register(\"Row\", { component: Row });\n registry.register(\"Column\", { component: Column });\n registry.register(\"List\", { component: List });\n registry.register(\"Card\", { component: Card });\n\n // Additional layout components\n registry.register(\"Tabs\", { component: Tabs });\n registry.register(\"Modal\", { component: Modal });\n\n // Interactive components\n registry.register(\"Button\", { component: Button });\n registry.register(\"TextField\", { component: TextField });\n registry.register(\"CheckBox\", { component: CheckBox });\n registry.register(\"Slider\", { component: Slider });\n registry.register(\"DateTimeInput\", { component: DateTimeInput });\n registry.register(\"MultipleChoice\", { component: MultipleChoice });\n}\n\n/**\n * Initialize the default catalog in the singleton registry.\n * Call this once at app startup.\n */\nexport function initializeDefaultCatalog(): void {\n registerDefaultCatalog(ComponentRegistry.getInstance());\n}\n","/**\n * Browser default reset for A2UI surfaces.\n *\n * The React renderer uses Light DOM, which means host-app CSS resets\n * (e.g. Tailwind preflight, normalize.css) can strip browser defaults\n * like heading margins, list styles, and form element appearance from\n * elements inside the renderer.\n *\n * The Lit renderer avoids this because Shadow DOM isolates its elements\n * from external stylesheets.\n *\n * This reset restores browser defaults inside `.a2ui-surface` by using\n * `all: revert` in a CSS @layer. Layered styles have the lowest author\n * priority, so every other A2UI style (utility classes, component styles,\n * theme classes, inline styles) automatically overrides the reset.\n */\nexport const resetStyles: string = `\n@layer a2ui-reset {\n :where(.a2ui-surface) :where(*) {\n all: revert;\n }\n}\n`;\n","import { Styles } from \"@a2ui/lit/0.8\";\nimport { resetStyles } from \"./reset\";\n\n/**\n * Structural CSS styles from the Lit renderer, converted for global DOM use.\n * These styles define all the utility classes (layout-*, typography-*, color-*, etc.)\n * Converts :host selectors to .a2ui-surface for scoped use outside Shadow DOM.\n */\nexport const structuralStyles: string = Styles.structuralStyles.replace(\n /:host\\s*\\{/g,\n \".a2ui-surface {\",\n);\n\n/**\n * Component-specific styles that replicate Lit's Shadow DOM scoped CSS.\n *\n * Each Lit component has `static styles` with :host, element selectors, and ::slotted().\n * Since React uses Light DOM, we transform these to global CSS scoped under .a2ui-surface.\n *\n * Transformation rules:\n * :host → .a2ui-surface .a2ui-{component}\n * section → .a2ui-surface .a2ui-{component} section\n * ::slotted(*) → .a2ui-surface .a2ui-{component} section > *\n */\nexport const componentSpecificStyles: string = `\n/* =========================================================================\n * Card (from Lit card.ts static styles)\n * ========================================================================= */\n\n/* :host { display: block; flex: var(--weight); min-height: 0; overflow: auto; } */\n.a2ui-surface .a2ui-card {\n display: block;\n flex: var(--weight);\n min-height: 0;\n overflow: auto;\n}\n\n/* section { height: 100%; width: 100%; min-height: 0; overflow: auto; } */\n/* Use > to target only Card's direct section, not nested sections (e.g., TextField's section) */\n.a2ui-surface .a2ui-card > section {\n height: 100%;\n width: 100%;\n min-height: 0;\n overflow: auto;\n}\n\n/* section ::slotted(*) { height: 100%; width: 100%; } */\n/* Use > section > to only target Card's slotted children, not deeply nested elements */\n.a2ui-surface .a2ui-card > section > * {\n height: 100%;\n width: 100%;\n}\n\n/* =========================================================================\n * Divider (from Lit divider.ts static styles)\n * ========================================================================= */\n\n/* :host { display: block; min-height: 0; overflow: auto; } */\n.a2ui-surface .a2ui-divider {\n display: block;\n min-height: 0;\n overflow: auto;\n}\n\n/* hr { height: 1px; background: #ccc; border: none; } */\n/* Use :where() for low specificity (0,0,1) so theme utility classes can override */\n/* Browser default margins apply (margin-block: 0.5em, margin-inline: auto) */\n:where(.a2ui-surface .a2ui-divider) hr {\n height: 1px;\n background: #ccc;\n border: none;\n}\n\n/* =========================================================================\n * Text (from Lit text.ts static styles)\n * ========================================================================= */\n\n/* :host { display: block; flex: var(--weight); } */\n.a2ui-surface .a2ui-text {\n display: block;\n flex: var(--weight);\n}\n\n/* h1, h2, h3, h4, h5 { line-height: inherit; font: inherit; } */\n/* Use :where() to match Lit's low specificity (0,0,0,1 - just element) */\n:where(.a2ui-surface .a2ui-text) h1,\n:where(.a2ui-surface .a2ui-text) h2,\n:where(.a2ui-surface .a2ui-text) h3,\n:where(.a2ui-surface .a2ui-text) h4,\n:where(.a2ui-surface .a2ui-text) h5 {\n line-height: inherit;\n font: inherit;\n}\n\n/* Ensure markdown paragraph margins are reset */\n.a2ui-surface .a2ui-text p {\n margin: 0;\n}\n\n/* =========================================================================\n * TextField (from Lit text-field.ts static styles)\n * ========================================================================= */\n\n/* :host { display: flex; flex: var(--weight); } */\n.a2ui-surface .a2ui-textfield {\n display: flex;\n flex: var(--weight);\n}\n\n/* input { display: block; width: 100%; } */\n:where(.a2ui-surface .a2ui-textfield) input {\n display: block;\n width: 100%;\n}\n\n/* label { display: block; margin-bottom: 4px; } */\n:where(.a2ui-surface .a2ui-textfield) label {\n display: block;\n margin-bottom: 4px;\n}\n\n/* textarea - same styling as input for multiline text fields */\n:where(.a2ui-surface .a2ui-textfield) textarea {\n display: block;\n width: 100%;\n}\n\n/* =========================================================================\n * CheckBox (from Lit checkbox.ts static styles)\n * ========================================================================= */\n\n/* :host { display: block; flex: var(--weight); min-height: 0; overflow: auto; } */\n.a2ui-surface .a2ui-checkbox {\n display: block;\n flex: var(--weight);\n min-height: 0;\n overflow: auto;\n}\n\n/* input { display: block; width: 100%; } */\n:where(.a2ui-surface .a2ui-checkbox) input {\n display: block;\n width: 100%;\n}\n\n/* =========================================================================\n * Slider (from Lit slider.ts static styles)\n * ========================================================================= */\n\n/* :host { display: block; flex: var(--weight); } */\n.a2ui-surface .a2ui-slider {\n display: block;\n flex: var(--weight);\n}\n\n/* input { display: block; width: 100%; } */\n:where(.a2ui-surface .a2ui-slider) input {\n display: block;\n width: 100%;\n}\n\n/* =========================================================================\n * Button (from Lit button.ts static styles)\n * ========================================================================= */\n\n/* :host { display: block; flex: var(--weight); min-height: 0; } */\n.a2ui-surface .a2ui-button {\n display: block;\n flex: var(--weight);\n min-height: 0;\n}\n\n/* =========================================================================\n * Icon (from Lit icon.ts static styles)\n * ========================================================================= */\n\n/* :host { display: block; flex: var(--weight); min-height: 0; overflow: auto; } */\n.a2ui-surface .a2ui-icon {\n display: block;\n flex: var(--weight);\n min-height: 0;\n overflow: auto;\n}\n\n/* =========================================================================\n * Tabs (from Lit tabs.ts static styles)\n * ========================================================================= */\n\n/* :host { display: block; flex: var(--weight); } */\n.a2ui-surface .a2ui-tabs {\n display: block;\n flex: var(--weight);\n}\n\n/* =========================================================================\n * Modal (from Lit modal.ts static styles)\n * ========================================================================= */\n\n/* :host { display: block; flex: var(--weight); } */\n.a2ui-surface .a2ui-modal {\n display: block;\n flex: var(--weight);\n}\n\n/* dialog { padding: 0; border: none; background: none; } */\n:where(.a2ui-surface .a2ui-modal) dialog {\n padding: 0;\n border: none;\n background: none;\n}\n\n/* dialog section #controls { display: flex; justify-content: end; margin-bottom: 4px; } */\n.a2ui-surface .a2ui-modal dialog section #controls {\n display: flex;\n justify-content: end;\n margin-bottom: 4px;\n}\n\n/* dialog section #controls button { padding: 0; background: none; ... } */\n.a2ui-surface .a2ui-modal dialog section #controls button {\n padding: 0;\n background: none;\n width: 20px;\n height: 20px;\n cursor: pointer;\n border: none;\n}\n\n/* =========================================================================\n * Image (from Lit image.ts static styles)\n * ========================================================================= */\n\n/* :host { display: block; flex: var(--weight); min-height: 0; overflow: auto; } */\n.a2ui-surface .a2ui-image {\n display: block;\n flex: var(--weight);\n min-height: 0;\n overflow: auto;\n}\n\n/* img { display: block; width: 100%; height: 100%; object-fit: var(--object-fit, fill); } */\n:where(.a2ui-surface .a2ui-image) img {\n display: block;\n width: 100%;\n height: 100%;\n object-fit: var(--object-fit, fill);\n}\n\n/* =========================================================================\n * Video (from Lit video.ts static styles)\n * ========================================================================= */\n\n/* :host { display: block; flex: var(--weight); min-height: 0; overflow: auto; } */\n.a2ui-surface .a2ui-video {\n display: block;\n flex: var(--weight);\n min-height: 0;\n overflow: auto;\n}\n\n/* video { display: block; width: 100%; } */\n:where(.a2ui-surface .a2ui-video) video {\n display: block;\n width: 100%;\n}\n\n/* =========================================================================\n * AudioPlayer (from Lit audio.ts static styles)\n * ========================================================================= */\n\n/* :host { display: block; flex: var(--weight); min-height: 0; overflow: auto; } */\n.a2ui-surface .a2ui-audio {\n display: block;\n flex: var(--weight);\n min-height: 0;\n overflow: auto;\n}\n\n/* audio { display: block; width: 100%; } */\n:where(.a2ui-surface .a2ui-audio) audio {\n display: block;\n width: 100%;\n}\n\n/* =========================================================================\n * MultipleChoice (from Lit multiple-choice.ts static styles)\n * ========================================================================= */\n\n/* :host { display: block; flex: var(--weight); min-height: 0; overflow: auto; } */\n.a2ui-surface .a2ui-multiplechoice {\n display: block;\n flex: var(--weight);\n min-height: 0;\n overflow: auto;\n}\n\n/* select { width: 100%; } */\n:where(.a2ui-surface .a2ui-multiplechoice) select {\n width: 100%;\n}\n\n/* =========================================================================\n * Column (from Lit column.ts static styles)\n * ========================================================================= */\n\n/* :host { display: flex; flex: var(--weight); } */\n.a2ui-surface .a2ui-column {\n display: flex;\n flex: var(--weight);\n}\n\n/* section { display: flex; flex-direction: column; min-width: 100%; height: 100%; } */\n.a2ui-surface .a2ui-column > section {\n display: flex;\n flex-direction: column;\n min-width: 100%;\n height: 100%;\n}\n\n/* :host([alignment=\"...\"]) section { align-items: ...; } */\n/* Use > section to only target Column's direct section, not nested sections (e.g., CheckBox's section) */\n.a2ui-surface .a2ui-column[data-alignment=\"start\"] > section { align-items: start; }\n.a2ui-surface .a2ui-column[data-alignment=\"center\"] > section { align-items: center; }\n.a2ui-surface .a2ui-column[data-alignment=\"end\"] > section { align-items: end; }\n.a2ui-surface .a2ui-column[data-alignment=\"stretch\"] > section { align-items: stretch; }\n\n/* :host([distribution=\"...\"]) section { justify-content: ...; } */\n.a2ui-surface .a2ui-column[data-distribution=\"start\"] > section { justify-content: start; }\n.a2ui-surface .a2ui-column[data-distribution=\"center\"] > section { justify-content: center; }\n.a2ui-surface .a2ui-column[data-distribution=\"end\"] > section { justify-content: end; }\n.a2ui-surface .a2ui-column[data-distribution=\"spaceBetween\"] > section { justify-content: space-between; }\n.a2ui-surface .a2ui-column[data-distribution=\"spaceAround\"] > section { justify-content: space-around; }\n.a2ui-surface .a2ui-column[data-distribution=\"spaceEvenly\"] > section { justify-content: space-evenly; }\n\n/* =========================================================================\n * Row (from Lit row.ts static styles)\n * ========================================================================= */\n\n/* :host { display: flex; flex: var(--weight); } */\n.a2ui-surface .a2ui-row {\n display: flex;\n flex: var(--weight);\n}\n\n/* section { display: flex; flex-direction: row; width: 100%; min-height: 100%; } */\n.a2ui-surface .a2ui-row > section {\n display: flex;\n flex-direction: row;\n width: 100%;\n min-height: 100%;\n}\n\n/* :host([alignment=\"...\"]) section { align-items: ...; } */\n/* Use > section to only target Row's direct section, not nested sections */\n.a2ui-surface .a2ui-row[data-alignment=\"start\"] > section { align-items: start; }\n.a2ui-surface .a2ui-row[data-alignment=\"center\"] > section { align-items: center; }\n.a2ui-surface .a2ui-row[data-alignment=\"end\"] > section { align-items: end; }\n.a2ui-surface .a2ui-row[data-alignment=\"stretch\"] > section { align-items: stretch; }\n\n/* :host([distribution=\"...\"]) section { justify-content: ...; } */\n.a2ui-surface .a2ui-row[data-distribution=\"start\"] > section { justify-content: start; }\n.a2ui-surface .a2ui-row[data-distribution=\"center\"] > section { justify-content: center; }\n.a2ui-surface .a2ui-row[data-distribution=\"end\"] > section { justify-content: end; }\n.a2ui-surface .a2ui-row[data-distribution=\"spaceBetween\"] > section { justify-content: space-between; }\n.a2ui-surface .a2ui-row[data-distribution=\"spaceAround\"] > section { justify-content: space-around; }\n.a2ui-surface .a2ui-row[data-distribution=\"spaceEvenly\"] > section { justify-content: space-evenly; }\n\n/* =========================================================================\n * List (from Lit list.ts static styles)\n * ========================================================================= */\n\n/* :host { display: block; flex: var(--weight); min-height: 0; overflow: auto; } */\n.a2ui-surface .a2ui-list {\n display: block;\n flex: var(--weight);\n min-height: 0;\n overflow: auto;\n}\n\n/* :host([direction=\"vertical\"]) section { display: grid; } */\n.a2ui-surface .a2ui-list[data-direction=\"vertical\"] > section {\n display: grid;\n}\n\n/* :host([direction=\"horizontal\"]) section { display: flex; max-width: 100%; overflow-x: scroll; ... } */\n.a2ui-surface .a2ui-list[data-direction=\"horizontal\"] > section {\n display: flex;\n max-width: 100%;\n overflow-x: scroll;\n overflow-y: hidden;\n scrollbar-width: none;\n}\n\n/* :host([direction=\"horizontal\"]) section > ::slotted(*) { flex: 1 0 fit-content; ... } */\n.a2ui-surface .a2ui-list[data-direction=\"horizontal\"] > section > * {\n flex: 1 0 fit-content;\n max-width: min(80%, 400px);\n}\n\n/* =========================================================================\n * DateTimeInput (from Lit datetime-input.ts static styles)\n * ========================================================================= */\n\n/* :host { display: block; flex: var(--weight); min-height: 0; overflow: auto; } */\n.a2ui-surface .a2ui-datetime-input {\n display: block;\n flex: var(--weight);\n min-height: 0;\n overflow: auto;\n}\n\n/* input { display: block; border-radius: 8px; padding: 8px; border: 1px solid #ccc; width: 100%; } */\n/* Use :where() to match Lit's low specificity (0,0,0,1) so theme utility classes can override */\n:where(.a2ui-surface .a2ui-datetime-input) input {\n display: block;\n border-radius: 8px;\n padding: 8px;\n border: 1px solid #ccc;\n width: 100%;\n}\n\n/* =========================================================================\n * Global box-sizing (matches Lit's * { box-sizing: border-box; } in components)\n * ========================================================================= */\n\n.a2ui-surface *,\n.a2ui-surface *::before,\n.a2ui-surface *::after {\n box-sizing: border-box;\n}\n`;\n\n/**\n * Injects A2UI structural styles into the document head.\n * Includes utility classes (layout-*, typography-*, color-*, etc.) and React-specific overrides.\n * Call this once at application startup.\n *\n * NOTE: CSS variables (--n-*, --p-*, etc.) must be defined by the host application on :root,\n * just like in the Lit renderer. This allows full customization of the color palette.\n *\n * @example\n * ```tsx\n * import { injectStyles } from '@a2ui/react/styles';\n *\n * // In your app entry point:\n * injectStyles();\n * ```\n */\nexport function injectStyles(): void {\n if (typeof document === \"undefined\") {\n return; // SSR safety\n }\n\n const styleId = \"a2ui-structural-styles\";\n\n // Avoid duplicate injection\n if (document.getElementById(styleId)) {\n return;\n }\n\n const styleElement = document.createElement(\"style\");\n styleElement.id = styleId;\n // Include structural (utility classes) and component-specific styles\n // Note: CSS variables (palette) must be defined by the host application on :root,\n // just like in the Lit renderer. This allows full customization.\n styleElement.textContent =\n resetStyles + \"\\n\" + structuralStyles + \"\\n\" + componentSpecificStyles;\n document.head.appendChild(styleElement);\n}\n\n/**\n * Removes injected A2UI styles from the document.\n * Useful for cleanup in tests or when unmounting.\n */\nexport function removeStyles(): void {\n if (typeof document === \"undefined\") {\n return;\n }\n\n const styleElement = document.getElementById(\"a2ui-structural-styles\");\n if (styleElement) {\n styleElement.remove();\n }\n}\n","import {\n useCopilotKit,\n type ReactActivityMessageRenderer,\n} from \"@copilotkit/react-core/v2\";\nimport { v0_8 } from \"@a2ui/lit\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { z } from \"zod\";\nimport {\n A2UIProvider,\n useA2UIActions,\n} from \"./react-renderer/core/A2UIProvider\";\nimport { A2UIRenderer } from \"./react-renderer/core/A2UIRenderer\";\nimport { initializeDefaultCatalog } from \"./react-renderer/registry/defaultCatalog\";\nimport { injectStyles } from \"./react-renderer/styles\";\nimport type { Types } from \"@a2ui/lit/0.8\";\n\n// Initialize the React renderer's component catalog and styles once\nlet initialized = false;\nfunction ensureInitialized() {\n if (!initialized) {\n initializeDefaultCatalog();\n injectStyles();\n initialized = true;\n }\n}\n\nexport type A2UIMessageRendererOptions = {\n theme: v0_8.Types.Theme;\n};\n\nexport function createA2UIMessageRenderer(\n options: A2UIMessageRendererOptions,\n): ReactActivityMessageRenderer<any> {\n const { theme } = options;\n\n return {\n activityType: \"a2ui-surface\",\n content: z.any(),\n render: ({ content, agent }) => {\n ensureInitialized();\n\n const [operations, setOperations] = useState<any[]>([]);\n const lastSignatureRef = useRef<string | null>(null);\n const { copilotkit } = useCopilotKit();\n\n useEffect(() => {\n if (!content || !Array.isArray(content.operations)) {\n lastSignatureRef.current = null;\n setOperations([]);\n return;\n }\n\n const incoming = content.operations as any[];\n const signature = stringifyOperations(incoming);\n\n if (signature && signature === lastSignatureRef.current) {\n return;\n }\n\n lastSignatureRef.current = signature;\n setOperations(incoming);\n }, [content]);\n\n // Group operations by surface ID\n const groupedOperations = useMemo(() => {\n const groups = new Map<string, any[]>();\n\n for (const operation of operations) {\n const surfaceId =\n getOperationSurfaceId(operation) ??\n v0_8.Data.A2uiMessageProcessor.DEFAULT_SURFACE_ID;\n\n if (!groups.has(surfaceId)) {\n groups.set(surfaceId, []);\n }\n groups.get(surfaceId)!.push(operation);\n }\n\n return groups;\n }, [operations]);\n\n if (!groupedOperations.size) {\n return null;\n }\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col gap-6 overflow-auto py-6\">\n {Array.from(groupedOperations.entries()).map(([surfaceId, ops]) => (\n <ReactSurfaceHost\n key={surfaceId}\n surfaceId={surfaceId}\n operations={ops}\n theme={theme}\n agent={agent}\n copilotkit={copilotkit}\n />\n ))}\n </div>\n );\n },\n };\n}\n\ntype ReactSurfaceHostProps = {\n surfaceId: string;\n operations: any[];\n theme: v0_8.Types.Theme;\n agent: any;\n copilotkit: any;\n};\n\n/**\n * Renders a single A2UI surface using the React renderer.\n * Wraps A2UIProvider + A2UIRenderer and bridges actions back to CopilotKit.\n */\nfunction ReactSurfaceHost({\n surfaceId,\n operations,\n theme,\n agent,\n copilotkit,\n}: ReactSurfaceHostProps) {\n // Bridge: when the React renderer dispatches an action, send it to CopilotKit\n const handleAction = useCallback(\n async (message: Types.A2UIClientEventMessage) => {\n if (!agent) return;\n\n try {\n console.info(\"[A2UI] Action dispatched\", message.userAction);\n\n copilotkit.setProperties({\n ...(copilotkit.properties ?? {}),\n a2uiAction: message,\n });\n\n await copilotkit.runAgent({ agent });\n } finally {\n if (copilotkit.properties) {\n const { a2uiAction, ...rest } = copilotkit.properties;\n copilotkit.setProperties(rest);\n }\n }\n },\n [agent, copilotkit],\n );\n\n return (\n <div className=\"flex w-full flex-none overflow-hidden rounded-lg bg-white/5 p-4\">\n <A2UIProvider onAction={handleAction} theme={theme}>\n <SurfaceMessageProcessor\n surfaceId={surfaceId}\n operations={operations}\n />\n <A2UIRenderer surfaceId={surfaceId} className=\"flex flex-1\" />\n </A2UIProvider>\n </div>\n );\n}\n\n/**\n * Processes A2UI operations into the provider's message processor.\n * Must be a child of A2UIProvider to access the actions context.\n */\nfunction SurfaceMessageProcessor({\n surfaceId,\n operations,\n}: {\n surfaceId: string;\n operations: any[];\n}) {\n const { processMessages } = useA2UIActions();\n const lastProcessedRef = useRef<string>(\"\");\n\n useEffect(() => {\n const key = `${surfaceId}-${JSON.stringify(operations)}`;\n if (key === lastProcessedRef.current) return;\n lastProcessedRef.current = key;\n\n processMessages(operations);\n }, [processMessages, surfaceId, operations]);\n\n return null;\n}\n\nfunction getOperationSurfaceId(operation: any): string | null {\n if (!operation || typeof operation !== \"object\") {\n return null;\n }\n\n if (typeof operation.surfaceId === \"string\") {\n return operation.surfaceId;\n }\n\n return (\n operation?.beginRendering?.surfaceId ??\n operation?.surfaceUpdate?.surfaceId ??\n operation?.dataModelUpdate?.surfaceId ??\n operation?.deleteSurface?.surfaceId ??\n null\n );\n}\n\nfunction stringifyOperations(ops: any[]): string | null {\n try {\n return JSON.stringify(ops);\n } catch (error) {\n return null;\n }\n}\n","/*\n Copyright 2025 Google LLC\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n https://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n\nimport { v0_8 } from \"@a2ui/lit\";\n\n/** Elements */\n\nconst a = {\n \"typography-f-sf\": true,\n \"typography-fs-n\": true,\n \"typography-w-500\": true,\n \"layout-as-n\": true,\n \"layout-dis-iflx\": true,\n \"layout-al-c\": true,\n};\n\nconst audio = {\n \"layout-w-100\": true,\n};\n\nconst body = {\n \"typography-f-s\": true,\n \"typography-fs-n\": true,\n \"typography-w-400\": true,\n \"layout-mt-0\": true,\n \"layout-mb-2\": true,\n \"typography-sz-bm\": true,\n \"color-c-n10\": true,\n};\n\nconst button = {\n \"typography-f-sf\": true,\n \"typography-fs-n\": true,\n \"typography-w-500\": true,\n \"layout-pt-3\": true,\n \"layout-pb-3\": true,\n \"layout-pl-5\": true,\n \"layout-pr-5\": true,\n \"layout-mb-1\": true,\n \"border-br-16\": true,\n \"border-bw-0\": true,\n \"border-c-n70\": true,\n \"border-bs-s\": true,\n \"color-bgc-s30\": true,\n \"color-c-n100\": true,\n \"behavior-ho-80\": true,\n};\n\nconst heading = {\n \"typography-f-sf\": true,\n \"typography-fs-n\": true,\n \"typography-w-500\": true,\n \"layout-mt-0\": true,\n \"layout-mb-2\": true,\n \"color-c-n10\": true,\n};\n\nconst h1 = {\n ...heading,\n \"typography-sz-tl\": true,\n};\n\nconst h2 = {\n ...heading,\n \"typography-sz-tm\": true,\n};\n\nconst h3 = {\n ...heading,\n \"typography-sz-ts\": true,\n};\n\nconst iframe = {\n \"behavior-sw-n\": true,\n};\n\nconst input = {\n \"typography-f-sf\": true,\n \"typography-fs-n\": true,\n \"typography-w-400\": true,\n \"layout-pl-4\": true,\n \"layout-pr-4\": true,\n \"layout-pt-2\": true,\n \"layout-pb-2\": true,\n \"border-br-6\": true,\n \"border-bw-1\": true,\n \"color-bc-s70\": true,\n \"border-bs-s\": true,\n \"layout-as-n\": true,\n \"color-c-n10\": true,\n};\n\nconst p = {\n \"typography-f-s\": true,\n \"typography-fs-n\": true,\n \"typography-w-400\": true,\n \"layout-m-0\": true,\n \"typography-sz-bm\": true,\n \"layout-as-n\": true,\n \"color-c-n10\": true,\n};\n\nconst orderedList = {\n \"typography-f-s\": true,\n \"typography-fs-n\": true,\n \"typography-w-400\": true,\n \"layout-m-0\": true,\n \"typography-sz-bm\": true,\n \"layout-as-n\": true,\n};\n\nconst unorderedList = {\n \"typography-f-s\": true,\n \"typography-fs-n\": true,\n \"typography-w-400\": true,\n \"layout-m-0\": true,\n \"typography-sz-bm\": true,\n \"layout-as-n\": true,\n};\n\nconst listItem = {\n \"typography-f-s\": true,\n \"typography-fs-n\": true,\n \"typography-w-400\": true,\n \"layout-m-0\": true,\n \"typography-sz-bm\": true,\n \"layout-as-n\": true,\n};\n\nconst pre = {\n \"typography-f-c\": true,\n \"typography-fs-n\": true,\n \"typography-w-400\": true,\n \"typography-sz-bm\": true,\n \"typography-ws-p\": true,\n \"layout-as-n\": true,\n};\n\nconst textarea = {\n ...input,\n \"layout-r-none\": true,\n \"layout-fs-c\": true,\n};\n\nconst video = {\n \"layout-el-cv\": true,\n};\n\nconst aLight = v0_8.Styles.merge(a, { \"color-c-n5\": true });\nconst inputLight = v0_8.Styles.merge(input, { \"color-c-n5\": true });\nconst textareaLight = v0_8.Styles.merge(textarea, { \"color-c-n5\": true });\nconst buttonLight = v0_8.Styles.merge(button, { \"color-c-n100\": true });\nconst h1Light = v0_8.Styles.merge(h1, { \"color-c-n5\": true });\nconst h2Light = v0_8.Styles.merge(h2, { \"color-c-n5\": true });\nconst h3Light = v0_8.Styles.merge(h3, { \"color-c-n5\": true });\nconst bodyLight = v0_8.Styles.merge(body, { \"color-c-n5\": true });\nconst pLight = v0_8.Styles.merge(p, { \"color-c-n35\": true });\nconst preLight = v0_8.Styles.merge(pre, { \"color-c-n35\": true });\nconst orderedListLight = v0_8.Styles.merge(orderedList, {\n \"color-c-n35\": true,\n});\nconst unorderedListLight = v0_8.Styles.merge(unorderedList, {\n \"color-c-n35\": true,\n});\nconst listItemLight = v0_8.Styles.merge(listItem, {\n \"color-c-n35\": true,\n});\n\nexport const theme: v0_8.Types.Theme = {\n additionalStyles: {\n Button: {\n \"--n-35\": \"var(--n-100)\",\n },\n Card: {\n padding: \"32px\",\n },\n },\n components: {\n AudioPlayer: {},\n Button: {\n \"layout-pt-2\": true,\n \"layout-pb-2\": true,\n \"layout-pl-3\": true,\n \"layout-pr-3\": true,\n \"border-br-12\": true,\n \"border-bw-0\": true,\n \"border-bs-s\": true,\n \"color-bgc-p30\": true,\n \"color-c-n100\": true,\n \"behavior-ho-70\": true,\n },\n Card: { \"border-br-9\": true, \"color-bgc-p100\": true },\n CheckBox: {\n element: {\n \"layout-m-0\": true,\n \"layout-mr-2\": true,\n \"layout-p-2\": true,\n \"border-br-12\": true,\n \"border-bw-1\": true,\n \"border-bs-s\": true,\n \"color-bgc-p100\": true,\n \"color-bc-p60\": true,\n \"color-c-n30\": true,\n \"color-c-p30\": true,\n },\n label: {\n \"color-c-p30\": true,\n \"typography-f-sf\": true,\n \"typography-v-r\": true,\n \"typography-w-400\": true,\n \"layout-flx-1\": true,\n \"typography-sz-ll\": true,\n },\n container: {\n \"layout-dsp-iflex\": true,\n \"layout-al-c\": true,\n },\n },\n Column: {\n \"layout-g-2\": true,\n },\n DateTimeInput: {\n container: {},\n label: {},\n element: {\n \"layout-pt-2\": true,\n \"layout-pb-2\": true,\n \"layout-pl-3\": true,\n \"layout-pr-3\": true,\n \"border-br-12\": true,\n \"border-bw-1\": true,\n \"border-bs-s\": true,\n \"color-bgc-p100\": true,\n \"color-bc-p60\": true,\n \"color-c-n30\": true,\n \"color-c-p30\": true,\n },\n },\n Divider: {},\n Image: {\n all: {\n \"border-br-5\": true,\n \"layout-el-cv\": true,\n \"layout-w-100\": true,\n \"layout-h-100\": true,\n },\n avatar: { \"is-avatar\": true },\n header: {},\n icon: {},\n largeFeature: {},\n mediumFeature: {},\n smallFeature: {},\n },\n Icon: {},\n List: {\n \"layout-g-4\": true,\n \"layout-p-2\": true,\n },\n Modal: {\n backdrop: { \"color-bbgc-p60_20\": true },\n element: {\n \"border-br-2\": true,\n \"color-bgc-p100\": true,\n \"layout-p-4\": true,\n \"border-bw-1\": true,\n \"border-bs-s\": true,\n \"color-bc-p80\": true,\n },\n },\n MultipleChoice: {\n container: {},\n label: {},\n element: {},\n },\n Row: {\n \"layout-g-4\": true,\n },\n Slider: {\n container: {},\n label: {},\n element: {},\n },\n Tabs: {\n container: {},\n controls: { all: {}, selected: {} },\n element: {},\n },\n Text: {\n all: {\n \"layout-w-100\": true,\n \"layout-g-2\": true,\n },\n h1: {\n \"typography-f-sf\": true,\n \"typography-v-r\": true,\n \"typography-w-400\": true,\n \"layout-m-0\": true,\n \"layout-p-0\": true,\n \"typography-sz-tl\": true,\n },\n h2: {\n \"typography-f-sf\": true,\n \"typography-v-r\": true,\n \"typography-w-400\": true,\n \"layout-m-0\": true,\n \"layout-p-0\": true,\n \"typography-sz-tm\": true,\n },\n h3: {\n \"typography-f-sf\": true,\n \"typography-v-r\": true,\n \"typography-w-400\": true,\n \"layout-m-0\": true,\n \"layout-p-0\": true,\n \"typography-sz-ts\": true,\n },\n h4: {\n \"typography-f-sf\": true,\n \"typography-v-r\": true,\n \"typography-w-400\": true,\n \"layout-m-0\": true,\n \"layout-p-0\": true,\n \"typography-sz-bl\": true,\n },\n h5: {\n \"typography-f-sf\": true,\n \"typography-v-r\": true,\n \"typography-w-400\": true,\n \"layout-m-0\": true,\n \"layout-p-0\": true,\n \"typography-sz-bm\": true,\n },\n body: {},\n caption: {},\n },\n TextField: {\n container: {\n \"typography-sz-bm\": true,\n \"layout-w-100\": true,\n \"layout-g-2\": true,\n \"layout-dsp-flexhor\": true,\n \"layout-al-c\": true,\n },\n label: {\n \"layout-flx-0\": true,\n },\n element: {\n \"typography-sz-bm\": true,\n \"layout-pt-2\": true,\n \"layout-pb-2\": true,\n \"layout-pl-3\": true,\n \"layout-pr-3\": true,\n \"border-br-12\": true,\n \"border-bw-1\": true,\n \"border-bs-s\": true,\n \"color-bgc-p100\": true,\n \"color-bc-p60\": true,\n \"color-c-n30\": true,\n \"color-c-p30\": true,\n },\n },\n Video: {\n \"border-br-5\": true,\n \"layout-el-cv\": true,\n },\n },\n elements: {\n a: aLight,\n audio,\n body: bodyLight,\n button: buttonLight,\n h1: h1Light,\n h2: h2Light,\n h3: h3Light,\n h4: {},\n h5: {},\n iframe,\n input: inputLight,\n p: pLight,\n pre: preLight,\n textarea: textareaLight,\n video,\n },\n markdown: {\n p: [...Object.keys(pLight)],\n h1: [...Object.keys(h1Light)],\n h2: [...Object.keys(h2Light)],\n h3: [...Object.keys(h3Light)],\n h4: [],\n h5: [],\n ul: [...Object.keys(unorderedListLight)],\n ol: [...Object.keys(orderedListLight)],\n li: [...Object.keys(listItemLight)],\n a: [...Object.keys(aLight)],\n strong: [],\n em: [],\n },\n};\n","\"use client\";\n\nimport React, { useId, useMemo, useEffect, useRef } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport { v0_8 } from \"@a2ui/lit\";\nimport {\n A2UIProvider,\n useA2UIActions,\n} from \"./react-renderer/core/A2UIProvider\";\nimport { A2UIRenderer } from \"./react-renderer/core/A2UIRenderer\";\nimport { initializeDefaultCatalog } from \"./react-renderer/registry/defaultCatalog\";\nimport { litTheme } from \"./react-renderer/theme/litTheme\";\nimport { injectStyles } from \"./react-renderer/styles\";\nimport { theme as viewerTheme } from \"./theme/viewer-theme.js\";\n\n// Re-export types that consumers may need\nexport interface ComponentInstance {\n id: string;\n component: Record<string, unknown>;\n}\n\nexport interface A2UIActionEvent {\n actionName: string;\n sourceComponentId: string;\n timestamp: string;\n context: Record<string, unknown>;\n}\n\nexport interface A2UIViewerProps {\n /** ID of the root component to render */\n root: string;\n /** Component definitions - array of ComponentInstance */\n components: v0_8.Types.ComponentInstance[];\n /** Data model - nested object, e.g. { user: { name: \"John\" }, items: [\"a\", \"b\"] } */\n data?: Record<string, unknown>;\n /** Called when user triggers an action (button click, etc.) */\n onAction?: (action: A2UIActionEvent) => void;\n /** Surface styles (primaryColor, font, logoUrl) */\n styles?: Record<string, string>;\n /** Optional className for the container */\n className?: string;\n}\n\n// Initialize the React renderer's component catalog and styles once\nlet initialized = false;\nfunction ensureInitialized() {\n if (!initialized) {\n initializeDefaultCatalog();\n injectStyles();\n initialized = true;\n }\n}\n\n/**\n * A2UIViewer renders an A2UI component tree from a JSON definition and data.\n * It re-renders cleanly when props change, discarding previous state.\n */\nexport function A2UIViewer({\n root,\n components,\n data,\n onAction,\n styles,\n className,\n}: A2UIViewerProps): React.JSX.Element {\n ensureInitialized();\n\n // Use React's useId for SSR-safe base ID\n const baseId = useId();\n\n // Generate a stable surfaceId that changes when definition changes\n const surfaceId = useMemo(() => {\n const definitionKey = `${root}-${JSON.stringify(components)}`;\n let hash = 0;\n for (let i = 0; i < definitionKey.length; i++) {\n const char = definitionKey.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash;\n }\n return `surface${baseId.replace(/:/g, \"-\")}${hash}`;\n }, [baseId, root, components]);\n\n // Convert onAction callback to internal format\n const handleAction = useMemo(() => {\n if (!onAction) return undefined;\n\n return (message: Types.A2UIClientEventMessage) => {\n const userAction = message.userAction;\n if (userAction) {\n onAction({\n actionName: userAction.name,\n sourceComponentId: userAction.sourceComponentId,\n timestamp: userAction.timestamp,\n context: userAction.context ?? {},\n });\n }\n };\n }, [onAction]);\n\n // Show placeholder if no components provided\n if (!components || components.length === 0) {\n return (\n <div\n className={className}\n style={{ padding: 16, color: \"#666\", fontFamily: \"system-ui\" }}\n >\n No content to display\n </div>\n );\n }\n\n return (\n <A2UIProvider onAction={handleAction} theme={viewerTheme}>\n <A2UIViewerInner\n surfaceId={surfaceId}\n root={root}\n components={components}\n data={data ?? {}}\n styles={styles}\n className={className}\n />\n </A2UIProvider>\n );\n}\n\n/**\n * Inner component that processes messages within the provider context.\n */\nfunction A2UIViewerInner({\n surfaceId,\n root,\n components,\n data,\n styles,\n className,\n}: {\n surfaceId: string;\n root: string;\n components: v0_8.Types.ComponentInstance[];\n data: Record<string, unknown>;\n styles?: Record<string, string>;\n className?: string;\n}) {\n const { processMessages } = useA2UIActions();\n const lastProcessedRef = useRef<string>(\"\");\n\n // Process messages when props change\n useEffect(() => {\n const key = `${surfaceId}-${JSON.stringify(components)}-${JSON.stringify(data)}`;\n if (key === lastProcessedRef.current) return;\n lastProcessedRef.current = key;\n\n const messages: Types.ServerToClientMessage[] = [\n { beginRendering: { surfaceId, root, styles: styles ?? {} } },\n { surfaceUpdate: { surfaceId, components } },\n ];\n\n // Add data model updates\n if (data && Object.keys(data).length > 0) {\n const contents = objectToValueMaps(data);\n if (contents.length > 0) {\n messages.push({\n dataModelUpdate: { surfaceId, path: \"/\", contents },\n });\n }\n }\n\n processMessages(messages);\n }, [processMessages, surfaceId, root, components, data, styles]);\n\n return (\n <div className={className}>\n <A2UIRenderer surfaceId={surfaceId} />\n </div>\n );\n}\n\n/**\n * Converts a nested JavaScript object to the ValueMap[] format\n * expected by A2UI's dataModelUpdate message.\n */\nfunction objectToValueMaps(obj: Record<string, unknown>): Types.ValueMap[] {\n return Object.entries(obj).map(([key, value]) => valueToValueMap(key, value));\n}\n\n/**\n * Converts a single key-value pair to a ValueMap.\n */\nfunction valueToValueMap(key: string, value: unknown): Types.ValueMap {\n if (typeof value === \"string\") {\n return { key, valueString: value };\n }\n if (typeof value === \"number\") {\n return { key, valueNumber: value };\n }\n if (typeof value === \"boolean\") {\n return { key, valueBoolean: value };\n }\n if (value === null || value === undefined) {\n return { key };\n }\n if (Array.isArray(value)) {\n const valueMap = value.map((item, index) =>\n valueToValueMap(String(index), item),\n );\n return { key, valueMap };\n }\n if (typeof value === \"object\") {\n const valueMap = objectToValueMaps(value as Record<string, unknown>);\n return { key, valueMap };\n }\n return { key };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.umd.js","names":["Data","Suspense","Styles","Suspense","MarkdownIt","Styles","initialized","ensureInitialized","z","v0_8","v0_8","viewerTheme"],"sources":["../src/react-renderer/theme/litTheme.ts","../src/react-renderer/theme/ThemeContext.tsx","../src/react-renderer/core/A2UIProvider.tsx","../src/react-renderer/hooks/useA2UI.ts","../src/react-renderer/registry/ComponentRegistry.ts","../src/react-renderer/core/ComponentNode.tsx","../src/react-renderer/theme/utils.ts","../src/react-renderer/lib/utils.ts","../src/react-renderer/core/A2UIRenderer.tsx","../src/react-renderer/hooks/useA2UIComponent.ts","../src/react-renderer/components/content/Text.tsx","../src/react-renderer/components/content/Image.tsx","../src/react-renderer/components/content/Icon.tsx","../src/react-renderer/components/content/Divider.tsx","../src/react-renderer/components/content/Video.tsx","../src/react-renderer/components/content/AudioPlayer.tsx","../src/react-renderer/components/layout/Row.tsx","../src/react-renderer/components/layout/Column.tsx","../src/react-renderer/components/layout/List.tsx","../src/react-renderer/components/layout/Card.tsx","../src/react-renderer/components/layout/Tabs.tsx","../src/react-renderer/components/layout/Modal.tsx","../src/react-renderer/components/interactive/Button.tsx","../src/react-renderer/components/interactive/TextField.tsx","../src/react-renderer/components/interactive/CheckBox.tsx","../src/react-renderer/components/interactive/Slider.tsx","../src/react-renderer/components/interactive/DateTimeInput.tsx","../src/react-renderer/components/interactive/MultipleChoice.tsx","../src/react-renderer/registry/defaultCatalog.ts","../src/react-renderer/styles/reset.ts","../src/react-renderer/styles/index.ts","../src/A2UIMessageRenderer.tsx","../src/theme/viewer-theme.ts","../src/A2UIViewer.tsx"],"sourcesContent":["import type { Types } from \"@a2ui/lit/0.8\";\n\n/**\n * Default theme for A2UI React components.\n *\n * This theme uses the same CSS class conventions as the Lit renderer,\n * ensuring visual consistency between React and Lit implementations.\n *\n * IMPORTANT: This theme must be kept in sync with the Lit renderer's internal\n * styling. If Lit components change their class maps, this file must be updated\n * to match. Ideally, Lit would export its default theme for direct import.\n *\n * Requires the structural styles to be injected:\n * @example\n * ```tsx\n * import { A2UIProvider } from '@a2ui/react';\n * import { injectStyles } from '@a2ui/react/styles';\n *\n * // Inject structural CSS at app startup\n * injectStyles();\n *\n * function App() {\n * return (\n * <A2UIProvider>\n * <A2UIRenderer surfaceId=\"main\" />\n * </A2UIProvider>\n * );\n * }\n * ```\n */\n\n// =============================================================================\n// Element Styles (used for markdown rendering and form elements)\n// =============================================================================\n\nconst elementA = {\n \"typography-f-sf\": true,\n \"typography-fs-n\": true,\n \"typography-w-500\": true,\n \"layout-as-n\": true,\n \"layout-dis-iflx\": true,\n \"layout-al-c\": true,\n \"typography-td-none\": true,\n \"color-c-p40\": true,\n};\n\nconst elementAudio = {\n \"layout-w-100\": true,\n};\n\nconst elementBody = {\n \"typography-f-s\": true,\n \"typography-fs-n\": true,\n \"typography-w-400\": true,\n \"layout-mt-0\": true,\n \"layout-mb-2\": true,\n \"typography-sz-bm\": true,\n \"color-c-n10\": true,\n};\n\nconst elementButton = {\n \"typography-f-sf\": true,\n \"typography-fs-n\": true,\n \"typography-w-500\": true,\n \"layout-pt-3\": true,\n \"layout-pb-3\": true,\n \"layout-pl-5\": true,\n \"layout-pr-5\": true,\n \"layout-mb-1\": true,\n \"border-br-16\": true,\n \"border-bw-0\": true,\n \"border-c-n70\": true,\n \"border-bs-s\": true,\n \"color-bgc-s30\": true,\n \"behavior-ho-80\": true,\n};\n\nconst elementHeading = {\n \"typography-f-sf\": true,\n \"typography-fs-n\": true,\n \"typography-w-500\": true,\n \"layout-mt-0\": true,\n \"layout-mb-2\": true,\n};\n\nconst elementIframe = {\n \"behavior-sw-n\": true,\n};\n\nconst elementInput = {\n \"typography-f-sf\": true,\n \"typography-fs-n\": true,\n \"typography-w-400\": true,\n \"layout-pl-4\": true,\n \"layout-pr-4\": true,\n \"layout-pt-2\": true,\n \"layout-pb-2\": true,\n \"border-br-6\": true,\n \"border-bw-1\": true,\n \"color-bc-s70\": true,\n \"border-bs-s\": true,\n \"layout-as-n\": true,\n \"color-c-n10\": true,\n};\n\nconst elementP = {\n \"typography-f-s\": true,\n \"typography-fs-n\": true,\n \"typography-w-400\": true,\n \"layout-m-0\": true,\n \"typography-sz-bm\": true,\n \"layout-as-n\": true,\n \"color-c-n10\": true,\n};\n\nconst elementList = {\n \"typography-f-s\": true,\n \"typography-fs-n\": true,\n \"typography-w-400\": true,\n \"layout-m-0\": true,\n \"typography-sz-bm\": true,\n \"layout-as-n\": true,\n \"color-c-n10\": true,\n};\n\nconst elementPre = {\n \"typography-f-c\": true,\n \"typography-fs-n\": true,\n \"typography-w-400\": true,\n \"typography-sz-bm\": true,\n \"typography-ws-p\": true,\n \"layout-as-n\": true,\n};\n\nconst elementTextarea = {\n ...elementInput,\n \"layout-r-none\": true,\n \"layout-fs-c\": true,\n};\n\nconst elementVideo = {\n \"layout-el-cv\": true,\n};\n\n// =============================================================================\n// Theme Export\n// =============================================================================\n\nexport const litTheme: Types.Theme = {\n // ===========================================================================\n // Additional Styles (inline CSS properties)\n // ===========================================================================\n\n // additionalStyles is optional - only define if custom styling is needed\n // The default Lit theme does not apply any additional inline styles\n\n components: {\n // =========================================================================\n // Content Components\n // =========================================================================\n\n AudioPlayer: {},\n\n Divider: {},\n\n Icon: {},\n\n Image: {\n all: {\n \"border-br-5\": true,\n \"layout-el-cv\": true,\n \"layout-w-100\": true,\n \"layout-h-100\": true,\n },\n avatar: { \"is-avatar\": true },\n header: {},\n icon: {},\n largeFeature: {},\n mediumFeature: {},\n smallFeature: {},\n },\n\n Text: {\n all: {\n \"layout-w-100\": true,\n \"layout-g-2\": true,\n },\n h1: {\n \"typography-f-sf\": true,\n \"typography-v-r\": true,\n \"typography-w-400\": true,\n \"layout-m-0\": true,\n \"layout-p-0\": true,\n \"typography-sz-hs\": true,\n },\n h2: {\n \"typography-f-sf\": true,\n \"typography-v-r\": true,\n \"typography-w-400\": true,\n \"layout-m-0\": true,\n \"layout-p-0\": true,\n \"typography-sz-tl\": true,\n },\n h3: {\n \"typography-f-sf\": true,\n \"typography-v-r\": true,\n \"typography-w-400\": true,\n \"layout-m-0\": true,\n \"layout-p-0\": true,\n \"typography-sz-tl\": true,\n },\n h4: {\n \"typography-f-sf\": true,\n \"typography-v-r\": true,\n \"typography-w-400\": true,\n \"layout-m-0\": true,\n \"layout-p-0\": true,\n \"typography-sz-bl\": true,\n },\n h5: {\n \"typography-f-sf\": true,\n \"typography-v-r\": true,\n \"typography-w-400\": true,\n \"layout-m-0\": true,\n \"layout-p-0\": true,\n \"typography-sz-bm\": true,\n },\n body: {},\n caption: {},\n },\n\n Video: {\n \"border-br-5\": true,\n \"layout-el-cv\": true,\n },\n\n // =========================================================================\n // Layout Components\n // =========================================================================\n\n Card: {\n \"border-br-9\": true,\n \"layout-p-4\": true,\n \"color-bgc-n100\": true,\n },\n\n Column: {\n \"layout-g-2\": true,\n },\n\n List: {\n \"layout-g-4\": true,\n \"layout-p-2\": true,\n },\n\n Modal: {\n backdrop: {\n \"color-bbgc-p60_20\": true,\n },\n element: {\n \"border-br-2\": true,\n \"color-bgc-p100\": true,\n \"layout-p-4\": true,\n \"border-bw-1\": true,\n \"border-bs-s\": true,\n \"color-bc-p80\": true,\n },\n },\n\n Row: {\n \"layout-g-4\": true,\n },\n\n Tabs: {\n container: {},\n controls: {\n all: {},\n selected: {},\n },\n element: {},\n },\n\n // =========================================================================\n // Interactive Components\n // =========================================================================\n\n Button: {\n \"layout-pt-2\": true,\n \"layout-pb-2\": true,\n \"layout-pl-3\": true,\n \"layout-pr-3\": true,\n \"border-br-12\": true,\n \"border-bw-0\": true,\n \"border-bs-s\": true,\n \"color-bgc-p30\": true,\n \"color-c-p100\": true, // White text on dark purple background\n \"behavior-ho-70\": true,\n \"typography-w-400\": true,\n },\n\n CheckBox: {\n container: {\n \"layout-dsp-iflex\": true,\n \"layout-al-c\": true,\n },\n element: {\n \"layout-m-0\": true,\n \"layout-mr-2\": true,\n \"layout-p-2\": true,\n \"border-br-12\": true,\n \"border-bw-1\": true,\n \"border-bs-s\": true,\n \"color-bgc-p100\": true,\n \"color-bc-p60\": true,\n \"color-c-n30\": true,\n \"color-c-p30\": true,\n },\n label: {\n \"color-c-p30\": true,\n \"typography-f-sf\": true,\n \"typography-v-r\": true,\n \"typography-w-400\": true,\n \"layout-flx-1\": true,\n \"typography-sz-ll\": true,\n },\n },\n\n DateTimeInput: {\n container: {\n \"typography-sz-bm\": true,\n \"layout-w-100\": true,\n \"layout-g-2\": true,\n \"layout-dsp-flexhor\": true,\n \"layout-al-c\": true,\n \"typography-ws-nw\": true,\n },\n label: {\n \"color-c-p30\": true,\n \"typography-sz-bm\": true,\n },\n element: {\n \"layout-pt-2\": true,\n \"layout-pb-2\": true,\n \"layout-pl-3\": true,\n \"layout-pr-3\": true,\n \"border-br-2\": true,\n \"border-bw-1\": true,\n \"border-bs-s\": true,\n \"color-bgc-p100\": true,\n \"color-bc-p60\": true,\n \"color-c-n30\": true,\n \"color-c-p30\": true,\n },\n },\n\n MultipleChoice: {\n container: {},\n label: {},\n element: {},\n },\n\n Slider: {\n container: {},\n label: {},\n element: {},\n },\n\n TextField: {\n container: {\n \"typography-sz-bm\": true,\n \"layout-w-100\": true,\n \"layout-g-2\": true,\n \"layout-dsp-flexhor\": true,\n \"layout-al-c\": true,\n \"typography-ws-nw\": true,\n },\n label: {\n \"layout-flx-0\": true,\n \"color-c-p30\": true,\n },\n element: {\n \"typography-sz-bm\": true,\n \"layout-pt-2\": true,\n \"layout-pb-2\": true,\n \"layout-pl-3\": true,\n \"layout-pr-3\": true,\n \"border-br-2\": true,\n \"border-bw-1\": true,\n \"border-bs-s\": true,\n \"color-bgc-p100\": true,\n \"color-bc-p60\": true,\n \"color-c-n30\": true,\n \"color-c-p30\": true,\n },\n },\n },\n\n // ===========================================================================\n // HTML Elements (used for markdown rendering and raw HTML)\n // ===========================================================================\n\n elements: {\n a: elementA,\n audio: elementAudio,\n body: elementBody,\n button: elementButton,\n h1: elementHeading,\n h2: elementHeading,\n h3: elementHeading,\n h4: elementHeading,\n h5: elementHeading,\n iframe: elementIframe,\n input: elementInput,\n p: elementP,\n pre: elementPre,\n textarea: elementTextarea,\n video: elementVideo,\n },\n\n // ===========================================================================\n // Markdown (class arrays for markdown-it renderer)\n // ===========================================================================\n\n markdown: {\n p: Object.keys(elementP),\n h1: Object.keys(elementHeading),\n h2: Object.keys(elementHeading),\n h3: Object.keys(elementHeading),\n h4: Object.keys(elementHeading),\n h5: Object.keys(elementHeading),\n ul: Object.keys(elementList),\n ol: Object.keys(elementList),\n li: Object.keys(elementList),\n a: Object.keys(elementA),\n strong: [],\n em: [],\n },\n};\n\n/**\n * Alias for litTheme - the default theme for A2UI React components.\n * @see litTheme\n */\nexport const defaultTheme = litTheme;\n","import { createContext, useContext, type ReactNode } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport { defaultTheme } from \"./litTheme\";\n\n/**\n * React context for the A2UI theme.\n */\nconst ThemeContext = createContext<Types.Theme | undefined>(undefined);\n\n/**\n * Props for the ThemeProvider component.\n */\nexport interface ThemeProviderProps {\n /** The theme to provide. Falls back to defaultTheme if not specified. */\n theme?: Types.Theme;\n /** Child components that will have access to the theme */\n children: ReactNode;\n}\n\n/**\n * Provider component that makes the A2UI theme available to descendant components.\n */\nexport function ThemeProvider({ theme, children }: ThemeProviderProps) {\n return (\n <ThemeContext.Provider value={theme ?? defaultTheme}>\n {children}\n </ThemeContext.Provider>\n );\n}\n\n/**\n * Hook to access the current A2UI theme.\n *\n * @returns The current theme\n * @throws If used outside of a ThemeProvider\n */\nexport function useTheme(): Types.Theme {\n const theme = useContext(ThemeContext);\n if (!theme) {\n throw new Error(\n \"useTheme must be used within a ThemeProvider or A2UIProvider\",\n );\n }\n return theme;\n}\n\n/**\n * Hook to optionally access the current A2UI theme.\n *\n * @returns The current theme, or undefined if not within a provider\n */\nexport function useThemeOptional(): Types.Theme | undefined {\n return useContext(ThemeContext);\n}\n","import {\n createContext,\n useContext,\n useRef,\n useState,\n useMemo,\n type ReactNode,\n} from \"react\";\nimport { Data, type Types } from \"@a2ui/lit/0.8\";\nimport type { A2UIContextValue, A2UIActions } from \"./store\";\nimport { ThemeProvider } from \"../theme/ThemeContext\";\nimport type { OnActionCallback } from \"../types\";\n\n/**\n * Context for stable actions (never changes reference, prevents re-renders).\n * Components that only need to dispatch actions or read data won't re-render.\n */\nconst A2UIActionsContext = createContext<A2UIActions | null>(null);\n\n/**\n * Context for reactive state (changes trigger re-renders).\n * Only components that need to react to state changes subscribe to this.\n */\nconst A2UIStateContext = createContext<{ version: number } | null>(null);\n\n/**\n * Props for the A2UIProvider component.\n */\nexport interface A2UIProviderProps {\n /** Callback invoked when a user action is dispatched (button click, etc.) */\n onAction?: OnActionCallback;\n /** Theme configuration. Falls back to default theme if not provided. */\n theme?: Types.Theme;\n /** Child components */\n children: ReactNode;\n}\n\n/**\n * Provider component that sets up the A2UI context for descendant components.\n *\n * This provider uses a two-context architecture for performance:\n * - A2UIActionsContext: Stable actions that never change (no re-renders)\n * - A2UIStateContext: Reactive state that triggers re-renders when needed\n *\n * @example\n * ```tsx\n * function App() {\n * const handleAction = async (message) => {\n * const response = await fetch('/api/a2ui', {\n * method: 'POST',\n * body: JSON.stringify(message)\n * });\n * const newMessages = await response.json();\n * };\n *\n * return (\n * <A2UIProvider onAction={handleAction}>\n * <A2UIRenderer surfaceId=\"main\" />\n * </A2UIProvider>\n * );\n * }\n * ```\n */\nexport function A2UIProvider({ onAction, theme, children }: A2UIProviderProps) {\n // Create message processor only once using ref\n const processorRef = useRef<Types.MessageProcessor | null>(null);\n if (!processorRef.current) {\n processorRef.current = Data.createSignalA2uiMessageProcessor();\n }\n const processor = processorRef.current;\n\n // Version counter for triggering re-renders\n const [version, setVersion] = useState(0);\n\n // Store onAction in a ref so callbacks always have the latest value\n const onActionRef = useRef<OnActionCallback | null>(onAction ?? null);\n onActionRef.current = onAction ?? null;\n\n // Create stable actions object once - stored in ref, never changes\n const actionsRef = useRef<A2UIActions | null>(null);\n if (!actionsRef.current) {\n actionsRef.current = {\n processMessages: (messages: Types.ServerToClientMessage[]) => {\n processor.processMessages(messages);\n setVersion((v) => v + 1);\n },\n\n setData: (\n node: Types.AnyComponentNode | null,\n path: string,\n value: Types.DataValue,\n surfaceId: string,\n ) => {\n processor.setData(node, path, value, surfaceId);\n setVersion((v) => v + 1);\n },\n\n dispatch: (message: Types.A2UIClientEventMessage) => {\n if (onActionRef.current) {\n onActionRef.current(message);\n }\n },\n\n clearSurfaces: () => {\n processor.clearSurfaces();\n setVersion((v) => v + 1);\n },\n\n getSurface: (surfaceId: string) => {\n return processor.getSurfaces().get(surfaceId);\n },\n\n getSurfaces: () => {\n return processor.getSurfaces();\n },\n\n getData: (\n node: Types.AnyComponentNode,\n path: string,\n surfaceId: string,\n ) => {\n return processor.getData(node, path, surfaceId);\n },\n\n resolvePath: (path: string, dataContextPath?: string) => {\n return processor.resolvePath(path, dataContextPath);\n },\n };\n }\n const actions = actionsRef.current;\n\n // State context value - only changes when version changes\n const stateValue = useMemo(() => ({ version }), [version]);\n\n return (\n <A2UIActionsContext.Provider value={actions}>\n <A2UIStateContext.Provider value={stateValue}>\n <ThemeProvider theme={theme}>{children}</ThemeProvider>\n </A2UIStateContext.Provider>\n </A2UIActionsContext.Provider>\n );\n}\n\n/**\n * Hook to access stable A2UI actions (won't cause re-renders).\n * Use this when you only need to dispatch actions or read data.\n *\n * @returns Stable actions object\n * @throws If used outside of an A2UIProvider\n */\nexport function useA2UIActions(): A2UIActions {\n const actions = useContext(A2UIActionsContext);\n if (!actions) {\n throw new Error(\"useA2UIActions must be used within an A2UIProvider\");\n }\n return actions;\n}\n\n/**\n * Hook to subscribe to A2UI state changes.\n * Components using this will re-render when state changes.\n *\n * @returns Current version number\n * @throws If used outside of an A2UIProvider\n */\nexport function useA2UIState(): { version: number } {\n const state = useContext(A2UIStateContext);\n if (!state) {\n throw new Error(\"useA2UIState must be used within an A2UIProvider\");\n }\n return state;\n}\n\n/**\n * Hook to access the full A2UI context (actions + state).\n * Components using this will re-render when state changes.\n *\n * @returns The A2UI context value\n * @throws If used outside of an A2UIProvider\n */\nexport function useA2UIContext(): A2UIContextValue {\n const actions = useA2UIActions();\n const state = useA2UIState();\n\n // Memoize combined value - only changes when state changes\n // Actions are stable, so this only re-creates when version changes\n return useMemo(\n () => ({\n ...actions,\n processor: null as unknown as Types.MessageProcessor, // Not exposed directly\n version: state.version,\n onAction: null, // Use dispatch instead\n }),\n [actions, state.version],\n );\n}\n\n/**\n * @deprecated Use useA2UIContext instead. This alias exists for backward compatibility only.\n */\nexport const useA2UIStore = useA2UIContext;\n\n/**\n * @deprecated This selector pattern does not provide performance benefits with React Context.\n * Components will re-render on any context change regardless of what you select.\n * Use useA2UIContext() or useA2UI() directly instead.\n *\n * @param selector - Function to select a slice of state\n * @returns The selected state\n */\nexport function useA2UIStoreSelector<T>(\n selector: (state: A2UIContextValue) => T,\n): T {\n const context = useA2UIContext();\n return selector(context);\n}\n","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","import { lazy, type ComponentType } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport type {\n A2UIComponentProps,\n ComponentLoader,\n ComponentRegistration,\n} from \"../types\";\n\n/**\n * Registry for A2UI components. Allows registration of custom components\n * and supports lazy loading for code splitting.\n *\n * @example\n * ```tsx\n * const registry = new ComponentRegistry();\n *\n * // Register a component directly\n * registry.register('Text', { component: Text });\n *\n * // Register with lazy loading\n * registry.register('Modal', {\n * component: () => import('./components/Modal'),\n * lazy: true\n * });\n *\n * // Use with A2UIRenderer\n * <A2UIRenderer surfaceId=\"main\" registry={registry} />\n * ```\n */\nexport class ComponentRegistry {\n private static _instance: ComponentRegistry | null = null;\n private registry = new Map<string, ComponentRegistration>();\n private lazyCache = new Map<string, ComponentType<A2UIComponentProps>>();\n\n /**\n * Get the singleton instance of the registry.\n * Use this for the default global registry.\n */\n static getInstance(): ComponentRegistry {\n if (!ComponentRegistry._instance) {\n ComponentRegistry._instance = new ComponentRegistry();\n }\n return ComponentRegistry._instance;\n }\n\n /**\n * Reset the singleton instance.\n * Useful for testing.\n */\n static resetInstance(): void {\n ComponentRegistry._instance = null;\n }\n\n /**\n * Register a component type.\n *\n * @param type - The A2UI component type name (e.g., 'Text', 'Button')\n * @param registration - The component registration\n */\n register<T extends Types.AnyComponentNode>(\n type: string,\n registration: ComponentRegistration<T>,\n ): void {\n this.registry.set(type, registration as unknown as ComponentRegistration);\n }\n\n /**\n * Unregister a component type.\n *\n * @param type - The component type to unregister\n */\n unregister(type: string): void {\n this.registry.delete(type);\n this.lazyCache.delete(type);\n }\n\n /**\n * Check if a component type is registered.\n *\n * @param type - The component type to check\n * @returns True if the component is registered\n */\n has(type: string): boolean {\n return this.registry.has(type);\n }\n\n /**\n * Get a component by type. If the component is registered with lazy loading,\n * returns a React.lazy wrapped component.\n *\n * @param type - The component type to get\n * @returns The React component, or null if not found\n */\n get(type: string): ComponentType<A2UIComponentProps> | null {\n const registration = this.registry.get(type);\n if (!registration) return null;\n\n // If lazy loading is enabled and the component is a loader function\n if (registration.lazy && typeof registration.component === \"function\") {\n // Check cache first\n const cached = this.lazyCache.get(type);\n if (cached) return cached;\n\n // Create lazy component and cache it\n const lazyComponent = lazy(registration.component as ComponentLoader);\n this.lazyCache.set(type, lazyComponent);\n return lazyComponent;\n }\n\n return registration.component as ComponentType<A2UIComponentProps>;\n }\n\n /**\n * Get all registered component types.\n *\n * @returns Array of registered type names\n */\n getRegisteredTypes(): string[] {\n return Array.from(this.registry.keys());\n }\n\n /**\n * Clear all registrations.\n */\n clear(): void {\n this.registry.clear();\n this.lazyCache.clear();\n }\n}\n","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","/**\n * Converts a theme class map (Record<string, boolean>) to a className string.\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 *\n * @example\n * classMapToString({ 'a2ui-button': true, 'a2ui-button--primary': true, 'disabled': false })\n * // Returns: 'a2ui-button a2ui-button--primary'\n */\nexport function classMapToString(\n classMap: Record<string, boolean> | undefined,\n): string {\n if (!classMap) return \"\";\n return Object.entries(classMap)\n .filter(([, enabled]) => enabled)\n .map(([className]) => className)\n .join(\" \");\n}\n\n/**\n * Converts an additional styles object (Record<string, string>) to a React style object.\n *\n * @param styles - An object with CSS property names as keys and values as strings\n * @returns A React-compatible style object, or undefined if no styles\n *\n * @example\n * stylesToObject({ 'background-color': 'red', 'font-size': '16px', '--custom-var': 'blue' })\n * // Returns: { backgroundColor: 'red', fontSize: '16px', '--custom-var': 'blue' }\n */\nexport function stylesToObject(\n styles: Record<string, string> | undefined,\n): React.CSSProperties | undefined {\n if (!styles || Object.keys(styles).length === 0) return undefined;\n\n const result: Record<string, string> = {};\n for (const [key, value] of Object.entries(styles)) {\n // Preserve CSS custom properties (--var-name) as-is\n if (key.startsWith(\"--\")) {\n result[key] = value;\n } else {\n // Convert kebab-case to camelCase for React\n const camelKey = key.replace(/-([a-z])/g, (_, letter) =>\n letter.toUpperCase(),\n );\n result[camelKey] = value;\n }\n }\n return result as React.CSSProperties;\n}\n","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","import { Suspense, useMemo, memo, type ReactNode } from \"react\";\nimport { useA2UI } from \"../hooks/useA2UI\";\nimport { ComponentNode } from \"./ComponentNode\";\nimport { type ComponentRegistry } from \"../registry/ComponentRegistry\";\nimport { cn } from \"../lib/utils\";\n\n/** Default loading fallback - memoized to prevent recreation */\nconst DefaultLoadingFallback = memo(function DefaultLoadingFallback() {\n return (\n <div className=\"a2ui-loading\" style={{ padding: \"16px\", opacity: 0.5 }}>\n Loading...\n </div>\n );\n});\n\nexport interface A2UIRendererProps {\n /** The surface ID to render */\n surfaceId: string;\n /** Additional CSS classes for the surface container */\n className?: string;\n /** Fallback content when surface is not yet available */\n fallback?: ReactNode;\n /** Loading fallback for lazy-loaded components */\n loadingFallback?: ReactNode;\n /** Optional custom component registry */\n registry?: ComponentRegistry;\n}\n\n/**\n * A2UIRenderer - renders an A2UI surface.\n *\n * This is the main entry point for rendering A2UI content in your React app.\n * It reads the surface state from the A2UI store and renders the component tree.\n *\n * Memoized to prevent unnecessary re-renders when props haven't changed.\n *\n * @example\n * ```tsx\n * function App() {\n * return (\n * <A2UIProvider onAction={handleAction}>\n * <A2UIRenderer surfaceId=\"main\" />\n * </A2UIProvider>\n * );\n * }\n * ```\n */\nexport const A2UIRenderer = memo(function A2UIRenderer({\n surfaceId,\n className,\n fallback = null,\n loadingFallback,\n registry,\n}: A2UIRendererProps) {\n const { getSurface, version } = useA2UI();\n\n // Get surface - this will re-render when version changes\n const surface = getSurface(surfaceId);\n\n // Memoize surface styles to prevent object recreation\n // Matches Lit renderer's transformation logic in surface.ts\n const surfaceStyles = useMemo<React.CSSProperties>(() => {\n if (!surface?.styles) return {};\n\n const styles: React.CSSProperties & Record<string, string> = {};\n\n for (const [key, value] of Object.entries(surface.styles)) {\n switch (key) {\n // Generate a color palette from the primary color.\n // Values range from 0-100 where 0=black, 100=white, 50=primary color.\n // Uses color-mix to create intermediate values.\n case \"primaryColor\": {\n styles[\"--p-100\"] = \"#ffffff\";\n styles[\"--p-99\"] = `color-mix(in srgb, ${value} 2%, white 98%)`;\n styles[\"--p-98\"] = `color-mix(in srgb, ${value} 4%, white 96%)`;\n styles[\"--p-95\"] = `color-mix(in srgb, ${value} 10%, white 90%)`;\n styles[\"--p-90\"] = `color-mix(in srgb, ${value} 20%, white 80%)`;\n styles[\"--p-80\"] = `color-mix(in srgb, ${value} 40%, white 60%)`;\n styles[\"--p-70\"] = `color-mix(in srgb, ${value} 60%, white 40%)`;\n styles[\"--p-60\"] = `color-mix(in srgb, ${value} 80%, white 20%)`;\n styles[\"--p-50\"] = String(value);\n styles[\"--p-40\"] = `color-mix(in srgb, ${value} 80%, black 20%)`;\n styles[\"--p-35\"] = `color-mix(in srgb, ${value} 70%, black 30%)`;\n styles[\"--p-30\"] = `color-mix(in srgb, ${value} 60%, black 40%)`;\n styles[\"--p-25\"] = `color-mix(in srgb, ${value} 50%, black 50%)`;\n styles[\"--p-20\"] = `color-mix(in srgb, ${value} 40%, black 60%)`;\n styles[\"--p-15\"] = `color-mix(in srgb, ${value} 30%, black 70%)`;\n styles[\"--p-10\"] = `color-mix(in srgb, ${value} 20%, black 80%)`;\n styles[\"--p-5\"] = `color-mix(in srgb, ${value} 10%, black 90%)`;\n styles[\"--p-0\"] = \"#000000\";\n break;\n }\n\n case \"font\": {\n styles[\"--font-family\"] = String(value);\n styles[\"--font-family-flex\"] = String(value);\n break;\n }\n }\n }\n return styles;\n }, [surface?.styles]);\n\n // No surface yet\n if (!surface || !surface.componentTree) {\n return <>{fallback}</>;\n }\n\n // Use provided fallback or default memoized component\n const actualLoadingFallback = loadingFallback ?? <DefaultLoadingFallback />;\n\n return (\n <div\n className={cn(\"a2ui-surface\", className)}\n style={surfaceStyles}\n data-surface-id={surfaceId}\n data-version={version}\n >\n <Suspense fallback={actualLoadingFallback}>\n <ComponentNode\n node={surface.componentTree}\n surfaceId={surfaceId}\n registry={registry}\n />\n </Suspense>\n </div>\n );\n});\n\nexport default A2UIRenderer;\n","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","import { useMemo, memo } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport type { A2UIComponentProps } from \"../../types\";\nimport { useA2UIComponent } from \"../../hooks/useA2UIComponent\";\nimport {\n classMapToString,\n stylesToObject,\n mergeClassMaps,\n} from \"../../lib/utils\";\nimport MarkdownIt from \"markdown-it\";\n\ntype UsageHint = \"h1\" | \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"caption\" | \"body\";\n\ninterface HintedStyles {\n h1: Record<string, string>;\n h2: Record<string, string>;\n h3: Record<string, string>;\n h4: Record<string, string>;\n h5: Record<string, string>;\n body: Record<string, string>;\n caption: Record<string, string>;\n}\n\nfunction isHintedStyles(styles: unknown): styles is HintedStyles {\n if (typeof styles !== \"object\" || !styles || Array.isArray(styles))\n return false;\n const expected = [\"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"caption\", \"body\"];\n return expected.some((v) => v in styles);\n}\n\n/**\n * Markdown-it instance for rendering markdown text.\n * Uses synchronous import to ensure availability at first render (matches Lit renderer).\n *\n * Configuration matches Lit's markdown directive (uses MarkdownIt defaults):\n * - html: false (default) - Security: disable raw HTML\n * - linkify: false (default) - Don't auto-convert URLs/emails to links\n * - breaks: false (default) - Don't convert \\n to <br>\n * - typographer: false (default) - Don't use smart quotes/dashes\n */\nconst markdownRenderer = new MarkdownIt();\n\n/**\n * Apply theme classes to markdown HTML elements.\n * Replaces default element tags with themed versions.\n */\nfunction applyMarkdownTheme(\n html: string,\n markdownTheme: Types.Theme[\"markdown\"],\n): string {\n if (!markdownTheme) return html;\n\n // Map of element -> classes\n const replacements: Array<[RegExp, string]> = [];\n\n for (const [element, classes] of Object.entries(markdownTheme)) {\n if (!classes || (Array.isArray(classes) && classes.length === 0)) continue;\n\n const classString = Array.isArray(classes)\n ? classes.join(\" \")\n : classMapToString(classes);\n if (!classString) continue;\n\n // Create regex to match opening tags (handles self-closing and regular)\n const tagRegex = new RegExp(`<${element}(?=\\\\s|>|/>)`, \"gi\");\n replacements.push([tagRegex, `<${element} class=\"${classString}\"`]);\n }\n\n let result = html;\n for (const [regex, replacement] of replacements) {\n result = result.replace(regex, replacement);\n }\n\n return result;\n}\n\n/**\n * Text component - renders text content with markdown support.\n *\n * Structure mirrors Lit's Text component:\n * <div class=\"a2ui-text\"> ← :host equivalent\n * <section class=\"...\"> ← theme classes\n * <h2>...</h2> ← rendered markdown content\n * </section>\n * </div>\n *\n * Text is parsed as markdown and rendered as HTML (matches Lit renderer behavior).\n * Supports usageHint values: h1, h2, h3, h4, h5, caption, body\n *\n * Markdown features supported:\n * - **Bold** and *italic* text\n * - Lists (ordered and unordered)\n * - `inline code` and code blocks\n * - [Links](url) (auto-linkified URLs too)\n * - Blockquotes\n * - Horizontal rules\n *\n * Note: Raw HTML is disabled for security.\n */\nexport const Text = memo(function Text({\n node,\n surfaceId,\n}: A2UIComponentProps<Types.TextNode>) {\n const { theme, resolveString } = useA2UIComponent(node, surfaceId);\n const props = node.properties;\n\n const textValue = resolveString(props.text);\n const usageHint = props.usageHint as UsageHint | undefined;\n\n // Get merged classes (matches Lit's Styles.merge)\n const classes = mergeClassMaps(\n theme.components.Text.all,\n usageHint ? theme.components.Text[usageHint] : {},\n );\n\n // Get additional styles based on usage hint\n const additionalStyles = useMemo(() => {\n const textStyles = theme.additionalStyles?.Text;\n if (!textStyles) return undefined;\n\n if (isHintedStyles(textStyles)) {\n const hint = usageHint ?? \"body\";\n return stylesToObject(textStyles[hint]);\n }\n return stylesToObject(textStyles as Record<string, string>);\n }, [theme.additionalStyles?.Text, usageHint]);\n\n // Render markdown content (matches Lit behavior - always uses markdown)\n const renderedContent = useMemo(() => {\n if (textValue === null || textValue === undefined) {\n return null;\n }\n\n // Add markdown prefix based on usageHint (matches Lit behavior)\n let markdownText = textValue;\n switch (usageHint) {\n case \"h1\":\n markdownText = `# ${markdownText}`;\n break;\n case \"h2\":\n markdownText = `## ${markdownText}`;\n break;\n case \"h3\":\n markdownText = `### ${markdownText}`;\n break;\n case \"h4\":\n markdownText = `#### ${markdownText}`;\n break;\n case \"h5\":\n markdownText = `##### ${markdownText}`;\n break;\n case \"caption\":\n markdownText = `*${markdownText}*`;\n break;\n default:\n break; // Body - no prefix\n }\n\n const rawHtml = markdownRenderer.render(markdownText);\n const themedHtml = applyMarkdownTheme(rawHtml, theme.markdown);\n return { __html: themedHtml };\n }, [textValue, theme.markdown, usageHint]);\n\n if (!renderedContent) {\n return null;\n }\n\n // Apply --weight CSS variable on root div (:host equivalent) for flex layouts\n const hostStyle: React.CSSProperties =\n node.weight !== undefined\n ? ({ \"--weight\": node.weight } as React.CSSProperties)\n : {};\n\n return (\n <div className=\"a2ui-text\" style={hostStyle}>\n <section\n className={classMapToString(classes)}\n style={additionalStyles}\n dangerouslySetInnerHTML={renderedContent}\n />\n </div>\n );\n});\n\nexport default Text;\n","import { memo } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport type { A2UIComponentProps } from \"../../types\";\nimport { useA2UIComponent } from \"../../hooks/useA2UIComponent\";\nimport {\n classMapToString,\n stylesToObject,\n mergeClassMaps,\n} from \"../../lib/utils\";\n\ntype UsageHint =\n | \"icon\"\n | \"avatar\"\n | \"smallFeature\"\n | \"mediumFeature\"\n | \"largeFeature\"\n | \"header\";\ntype FitMode = \"contain\" | \"cover\" | \"fill\" | \"none\" | \"scale-down\";\n\n/**\n * Image component - renders an image from a URL with optional sizing and fit modes.\n *\n * Supports usageHint values: icon, avatar, smallFeature, mediumFeature, largeFeature, header\n * Supports fit values: contain, cover, fill, none, scale-down (maps to object-fit via CSS variable)\n */\nexport const Image = memo(function Image({\n node,\n surfaceId,\n}: A2UIComponentProps<Types.ImageNode>) {\n const { theme, resolveString } = useA2UIComponent(node, surfaceId);\n const props = node.properties;\n\n const rawUrl = resolveString(props.url);\n // Rewrite known-dead placeholder services to working alternatives\n const url = rawUrl?.replace(\"//via.placeholder.com/\", \"//placehold.co/\");\n const usageHint = props.usageHint as UsageHint | undefined;\n const fit = (props.fit as FitMode) ?? \"fill\";\n\n // Get merged classes for section (matches Lit's Styles.merge)\n const classes = mergeClassMaps(\n theme.components.Image.all,\n usageHint ? theme.components.Image[usageHint] : {},\n );\n\n // Build style object with object-fit as CSS variable (matches Lit)\n const style: React.CSSProperties = {\n ...stylesToObject(theme.additionalStyles?.Image),\n \"--object-fit\": fit,\n } as React.CSSProperties;\n\n if (!url) {\n return null;\n }\n\n // Apply --weight CSS variable on root div (:host equivalent) for flex layouts\n const hostStyle: React.CSSProperties =\n node.weight !== undefined\n ? ({ \"--weight\": node.weight } as React.CSSProperties)\n : {};\n\n return (\n <div className=\"a2ui-image\" style={hostStyle}>\n <section className={classMapToString(classes)} style={style}>\n <img src={url} alt=\"\" />\n </section>\n </div>\n );\n});\n\nexport default Image;\n","import { memo } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport type { A2UIComponentProps } from \"../../types\";\nimport { useA2UIComponent } from \"../../hooks/useA2UIComponent\";\nimport { classMapToString, stylesToObject } from \"../../lib/utils\";\n\n/**\n * Convert camelCase to snake_case for Material Symbols font.\n * e.g., \"shoppingCart\" -> \"shopping_cart\"\n * This matches the Lit renderer's approach.\n */\nfunction toSnakeCase(str: string): string {\n return str.replace(/([A-Z])/g, \"_$1\").toLowerCase();\n}\n\n/**\n * Icon component - renders an icon using Material Symbols Outlined font.\n *\n * This matches the Lit renderer's approach using the g-icon class with\n * Material Symbols Outlined font.\n *\n * @example Add Material Symbols font to your HTML:\n * ```html\n * <link href=\"https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined\" rel=\"stylesheet\">\n * ```\n */\nexport const Icon = memo(function Icon({\n node,\n surfaceId,\n}: A2UIComponentProps<Types.IconNode>) {\n const { theme, resolveString } = useA2UIComponent(node, surfaceId);\n const props = node.properties;\n\n const iconName = resolveString(props.name);\n\n if (!iconName) {\n return null;\n }\n\n // Convert camelCase to snake_case for Material Symbols\n const snakeCaseName = toSnakeCase(iconName);\n\n // Apply --weight CSS variable on root div (:host equivalent) for flex layouts\n const hostStyle: React.CSSProperties =\n node.weight !== undefined\n ? ({ \"--weight\": node.weight } as React.CSSProperties)\n : {};\n\n return (\n <div className=\"a2ui-icon\" style={hostStyle}>\n <section\n className={classMapToString(theme.components.Icon)}\n style={stylesToObject(theme.additionalStyles?.Icon)}\n >\n <span className=\"g-icon\">{snakeCaseName}</span>\n </section>\n </div>\n );\n});\n\nexport default Icon;\n","import { memo } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport type { A2UIComponentProps } from \"../../types\";\nimport { useA2UIComponent } from \"../../hooks/useA2UIComponent\";\nimport { classMapToString, stylesToObject } from \"../../lib/utils\";\n\n/**\n * Divider component - renders a visual separator line.\n *\n * Structure mirrors Lit's Divider component:\n * <div class=\"a2ui-divider\"> ← :host equivalent\n * <hr class=\"...\"> ← internal element\n * </div>\n */\nexport const Divider = memo(function Divider({\n node,\n surfaceId,\n}: A2UIComponentProps<Types.DividerNode>) {\n const { theme } = useA2UIComponent(node, surfaceId);\n\n // Apply --weight CSS variable on root div (:host equivalent) for flex layouts\n const hostStyle: React.CSSProperties =\n node.weight !== undefined\n ? ({ \"--weight\": node.weight } as React.CSSProperties)\n : {};\n\n return (\n <div className=\"a2ui-divider\" style={hostStyle}>\n <hr\n className={classMapToString(theme.components.Divider)}\n style={stylesToObject(theme.additionalStyles?.Divider)}\n />\n </div>\n );\n});\n\nexport default Divider;\n","import { memo } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport type { A2UIComponentProps } from \"../../types\";\nimport { useA2UIComponent } from \"../../hooks/useA2UIComponent\";\nimport { classMapToString, stylesToObject } from \"../../lib/utils\";\n\n/**\n * Check if a URL is a YouTube URL and extract the video ID.\n */\nfunction getYouTubeVideoId(url: string): string | null {\n const patterns = [\n /(?:youtube\\.com\\/watch\\?v=|youtu\\.be\\/|youtube\\.com\\/embed\\/)([^&\\s?]+)/,\n ];\n for (const pattern of patterns) {\n const match = url.match(pattern);\n if (match && match.length > 1) {\n // Non-null assertion is safe here since we checked match.length > 1\n\n return match[1]!;\n }\n }\n return null;\n}\n\n/**\n * Video component - renders a video player.\n *\n * Supports regular video URLs and YouTube URLs (renders as embedded iframe).\n */\nexport const Video = memo(function Video({\n node,\n surfaceId,\n}: A2UIComponentProps<Types.VideoNode>) {\n const { theme, resolveString } = useA2UIComponent(node, surfaceId);\n const props = node.properties;\n\n const url = resolveString(props.url);\n\n if (!url) {\n return null;\n }\n\n const youtubeId = getYouTubeVideoId(url);\n\n // Apply --weight CSS variable on root div (:host equivalent) for flex layouts\n const hostStyle: React.CSSProperties =\n node.weight !== undefined\n ? ({ \"--weight\": node.weight } as React.CSSProperties)\n : {};\n\n return (\n <div className=\"a2ui-video\" style={hostStyle}>\n <section\n className={classMapToString(theme.components.Video)}\n style={stylesToObject(theme.additionalStyles?.Video)}\n >\n {youtubeId ? (\n <iframe\n src={`https://www.youtube.com/embed/${youtubeId}`}\n title=\"YouTube video player\"\n allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\"\n allowFullScreen\n style={{ border: \"none\", width: \"100%\", aspectRatio: \"16/9\" }}\n />\n ) : (\n <video src={url} controls />\n )}\n </section>\n </div>\n );\n});\n\nexport default Video;\n","import { memo } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport type { A2UIComponentProps } from \"../../types\";\nimport { useA2UIComponent } from \"../../hooks/useA2UIComponent\";\nimport { classMapToString, stylesToObject } from \"../../lib/utils\";\n\n/**\n * AudioPlayer component - renders an audio player with optional description.\n */\nexport const AudioPlayer = memo(function AudioPlayer({\n node,\n surfaceId,\n}: A2UIComponentProps<Types.AudioPlayerNode>) {\n const { theme, resolveString } = useA2UIComponent(node, surfaceId);\n const props = node.properties;\n\n const url = resolveString(props.url);\n const description = resolveString(props.description ?? null);\n\n if (!url) {\n return null;\n }\n\n // Apply --weight CSS variable on root div (:host equivalent) for flex layouts\n const hostStyle: React.CSSProperties =\n node.weight !== undefined\n ? ({ \"--weight\": node.weight } as React.CSSProperties)\n : {};\n\n return (\n <div className=\"a2ui-audio\" style={hostStyle}>\n <section\n className={classMapToString(theme.components.AudioPlayer)}\n style={stylesToObject(theme.additionalStyles?.AudioPlayer)}\n >\n {description && <p>{description}</p>}\n <audio src={url} controls />\n </section>\n </div>\n );\n});\n\nexport default AudioPlayer;\n","import { memo } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport type { A2UIComponentProps } from \"../../types\";\nimport { useA2UIComponent } from \"../../hooks/useA2UIComponent\";\nimport { classMapToString, stylesToObject } from \"../../lib/utils\";\nimport { ComponentNode } from \"../../core/ComponentNode\";\n\n/**\n * Row component - arranges children horizontally using flexbox.\n *\n * Supports distribution (justify-content) and alignment (align-items) properties.\n */\nexport const Row = memo(function Row({\n node,\n surfaceId,\n}: A2UIComponentProps<Types.RowNode>) {\n const { theme } = useA2UIComponent(node, surfaceId);\n const props = node.properties;\n\n // Match Lit's default values\n const alignment = props.alignment ?? \"stretch\";\n const distribution = props.distribution ?? \"start\";\n\n const children = Array.isArray(props.children) ? props.children : [];\n\n // Apply --weight CSS variable on root div (:host equivalent) for flex layouts\n const hostStyle: React.CSSProperties =\n node.weight !== undefined\n ? ({ \"--weight\": node.weight } as React.CSSProperties)\n : {};\n\n return (\n <div\n className=\"a2ui-row\"\n data-alignment={alignment}\n data-distribution={distribution}\n style={hostStyle}\n >\n <section\n className={classMapToString(theme.components.Row)}\n style={stylesToObject(theme.additionalStyles?.Row)}\n >\n {children.map((child, index) => {\n const childId =\n typeof child === \"object\" && child !== null && \"id\" in child\n ? (child as Types.AnyComponentNode).id\n : `child-${index}`;\n const childNode =\n typeof child === \"object\" && child !== null && \"type\" in child\n ? (child as Types.AnyComponentNode)\n : null;\n return (\n <ComponentNode\n key={childId}\n node={childNode}\n surfaceId={surfaceId}\n />\n );\n })}\n </section>\n </div>\n );\n});\n\nexport default Row;\n","import { memo } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport type { A2UIComponentProps } from \"../../types\";\nimport { useA2UIComponent } from \"../../hooks/useA2UIComponent\";\nimport { classMapToString, stylesToObject } from \"../../lib/utils\";\nimport { ComponentNode } from \"../../core/ComponentNode\";\n\n/**\n * Column component - arranges children vertically using flexbox.\n *\n * Supports distribution (justify-content) and alignment (align-items) properties.\n */\nexport const Column = memo(function Column({\n node,\n surfaceId,\n}: A2UIComponentProps<Types.ColumnNode>) {\n const { theme } = useA2UIComponent(node, surfaceId);\n const props = node.properties;\n\n // Match Lit's default values\n const alignment = props.alignment ?? \"stretch\";\n const distribution = props.distribution ?? \"start\";\n\n const children = Array.isArray(props.children) ? props.children : [];\n\n // Apply --weight CSS variable on root div (:host equivalent) for flex layouts\n const hostStyle: React.CSSProperties =\n node.weight !== undefined\n ? ({ \"--weight\": node.weight } as React.CSSProperties)\n : {};\n\n return (\n <div\n className=\"a2ui-column\"\n data-alignment={alignment}\n data-distribution={distribution}\n style={hostStyle}\n >\n <section\n className={classMapToString(theme.components.Column)}\n style={stylesToObject(theme.additionalStyles?.Column)}\n >\n {children.map((child, index) => {\n const childId =\n typeof child === \"object\" && child !== null && \"id\" in child\n ? (child as Types.AnyComponentNode).id\n : `child-${index}`;\n const childNode =\n typeof child === \"object\" && child !== null && \"type\" in child\n ? (child as Types.AnyComponentNode)\n : null;\n return (\n <ComponentNode\n key={childId}\n node={childNode}\n surfaceId={surfaceId}\n />\n );\n })}\n </section>\n </div>\n );\n});\n\nexport default Column;\n","import { memo } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport type { A2UIComponentProps } from \"../../types\";\nimport { useA2UIComponent } from \"../../hooks/useA2UIComponent\";\nimport { classMapToString, stylesToObject } from \"../../lib/utils\";\nimport { ComponentNode } from \"../../core/ComponentNode\";\n\n/**\n * List component - renders a scrollable list of items.\n *\n * Supports direction (vertical/horizontal) properties.\n */\nexport const List = memo(function List({\n node,\n surfaceId,\n}: A2UIComponentProps<Types.ListNode>) {\n const { theme } = useA2UIComponent(node, surfaceId);\n const props = node.properties;\n\n // Match Lit's default value\n const direction = props.direction ?? \"vertical\";\n\n const children = Array.isArray(props.children) ? props.children : [];\n\n // Apply --weight CSS variable on root div (:host equivalent) for flex layouts\n const hostStyle: React.CSSProperties =\n node.weight !== undefined\n ? ({ \"--weight\": node.weight } as React.CSSProperties)\n : {};\n\n return (\n <div className=\"a2ui-list\" data-direction={direction} style={hostStyle}>\n <section\n className={classMapToString(theme.components.List)}\n style={stylesToObject(theme.additionalStyles?.List)}\n >\n {children.map((child, index) => {\n const childId =\n typeof child === \"object\" && child !== null && \"id\" in child\n ? (child as Types.AnyComponentNode).id\n : `child-${index}`;\n const childNode =\n typeof child === \"object\" && child !== null && \"type\" in child\n ? (child as Types.AnyComponentNode)\n : null;\n return (\n <ComponentNode\n key={childId}\n node={childNode}\n surfaceId={surfaceId}\n />\n );\n })}\n </section>\n </div>\n );\n});\n\nexport default List;\n","import { memo } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport type { A2UIComponentProps } from \"../../types\";\nimport { useA2UIComponent } from \"../../hooks/useA2UIComponent\";\nimport { classMapToString, stylesToObject } from \"../../lib/utils\";\nimport { ComponentNode } from \"../../core/ComponentNode\";\n\n/**\n * Card component - a container that visually groups content.\n *\n * Structure mirrors Lit's Card component:\n * <div class=\"a2ui-card\"> ← :host equivalent\n * <section class=\"...\"> ← theme classes (border, padding, background)\n * {children} ← ::slotted(*) equivalent\n * </section>\n * </div>\n *\n * All styles come from componentSpecificStyles CSS, no inline styles needed.\n */\nexport const Card = memo(function Card({\n node,\n surfaceId,\n}: A2UIComponentProps<Types.CardNode>) {\n const { theme } = useA2UIComponent(node, surfaceId);\n const props = node.properties;\n\n // Card can have either a single child or multiple children\n const rawChildren = props.children ?? (props.child ? [props.child] : []);\n const children = Array.isArray(rawChildren) ? rawChildren : [];\n\n // Apply --weight CSS variable on root div (:host equivalent) for flex layouts\n const hostStyle: React.CSSProperties =\n node.weight !== undefined\n ? ({ \"--weight\": node.weight } as React.CSSProperties)\n : {};\n\n return (\n <div className=\"a2ui-card\" style={hostStyle}>\n <section\n className={classMapToString(theme.components.Card)}\n style={stylesToObject(theme.additionalStyles?.Card)}\n >\n {children.map((child, index) => {\n const childId =\n typeof child === \"object\" && child !== null && \"id\" in child\n ? (child as Types.AnyComponentNode).id\n : `child-${index}`;\n const childNode =\n typeof child === \"object\" && child !== null && \"type\" in child\n ? (child as Types.AnyComponentNode)\n : null;\n return (\n <ComponentNode\n key={childId}\n node={childNode}\n surfaceId={surfaceId}\n />\n );\n })}\n </section>\n </div>\n );\n});\n\nexport default Card;\n","import { useState, memo } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport type { A2UIComponentProps } from \"../../types\";\nimport { useA2UIComponent } from \"../../hooks/useA2UIComponent\";\nimport {\n classMapToString,\n stylesToObject,\n mergeClassMaps,\n} from \"../../lib/utils\";\nimport { ComponentNode } from \"../../core/ComponentNode\";\n\n/**\n * Tabs component - displays content in switchable tabs.\n */\nexport const Tabs = memo(function Tabs({\n node,\n surfaceId,\n}: A2UIComponentProps<Types.TabsNode>) {\n const { theme, resolveString } = useA2UIComponent(node, surfaceId);\n const props = node.properties;\n\n const [selectedIndex, setSelectedIndex] = useState(0);\n\n const tabItems = props.tabItems ?? [];\n\n // Apply --weight CSS variable on root div (:host equivalent) for flex layouts\n const hostStyle: React.CSSProperties =\n node.weight !== undefined\n ? ({ \"--weight\": node.weight } as React.CSSProperties)\n : {};\n\n return (\n <div className=\"a2ui-tabs\" style={hostStyle}>\n <section\n className={classMapToString(theme.components.Tabs.container)}\n style={stylesToObject(theme.additionalStyles?.Tabs)}\n >\n {/* Tab buttons - uses Tabs.element for the container */}\n <div\n id=\"buttons\"\n className={classMapToString(theme.components.Tabs.element)}\n >\n {tabItems.map((tab, index) => {\n const title = resolveString(tab.title);\n const isSelected = index === selectedIndex;\n\n // Lit merges all + selected classes when selected\n const classes = isSelected\n ? mergeClassMaps(\n theme.components.Tabs.controls.all,\n theme.components.Tabs.controls.selected,\n )\n : theme.components.Tabs.controls.all;\n\n return (\n <button\n key={index}\n disabled={isSelected}\n className={classMapToString(classes)}\n onClick={() => setSelectedIndex(index)}\n >\n {title}\n </button>\n );\n })}\n </div>\n\n {/* Tab content */}\n {tabItems[selectedIndex] && (\n <ComponentNode\n node={tabItems[selectedIndex].child}\n surfaceId={surfaceId}\n />\n )}\n </section>\n </div>\n );\n});\n\nexport default Tabs;\n","import { useState, useCallback, useRef, useEffect, memo } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport type { A2UIComponentProps } from \"../../types\";\nimport { useA2UIComponent } from \"../../hooks/useA2UIComponent\";\nimport { classMapToString, stylesToObject } from \"../../lib/utils\";\nimport { ComponentNode } from \"../../core/ComponentNode\";\n\n/**\n * Modal component - displays content in a dialog overlay.\n *\n * Matches Lit's rendering approach:\n * - When closed: renders section with entry point child\n * - When open: renders dialog with content child (entry point is replaced)\n *\n * The dialog is rendered in place (no portal) so it stays inside .a2ui-surface\n * and CSS selectors work correctly. showModal() handles the top-layer overlay.\n */\nexport const Modal = memo(function Modal({\n node,\n surfaceId,\n}: A2UIComponentProps<Types.ModalNode>) {\n const { theme } = useA2UIComponent(node, surfaceId);\n const props = node.properties;\n\n const [isOpen, setIsOpen] = useState(false);\n const dialogRef = useRef<HTMLDialogElement>(null);\n\n const openModal = useCallback(() => {\n setIsOpen(true);\n }, []);\n\n const closeModal = useCallback(() => {\n setIsOpen(false);\n }, []);\n\n // Show dialog when isOpen becomes true, and sync state when dialog closes (e.g., via Escape)\n useEffect(() => {\n const dialog = dialogRef.current;\n if (!dialog) return;\n\n if (isOpen && !dialog.open) {\n dialog.showModal();\n }\n\n // Listen for native close event (triggered by Escape key)\n const handleClose = () => {\n setIsOpen(false);\n };\n dialog.addEventListener(\"close\", handleClose);\n return () => dialog.removeEventListener(\"close\", handleClose);\n }, [isOpen]);\n\n // Handle backdrop clicks (only close if clicking directly on dialog, not its content)\n const handleBackdropClick = useCallback(\n (e: React.MouseEvent<HTMLDialogElement>) => {\n if (e.target === e.currentTarget) {\n closeModal();\n }\n },\n [closeModal],\n );\n\n // Handle Escape key (for jsdom test compatibility - real browsers use native dialog behavior)\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLDialogElement>) => {\n if (e.key === \"Escape\") {\n closeModal();\n }\n },\n [closeModal],\n );\n\n // Apply --weight CSS variable on root div (:host equivalent) for flex layouts\n const hostStyle: React.CSSProperties =\n node.weight !== undefined\n ? ({ \"--weight\": node.weight } as React.CSSProperties)\n : {};\n\n // Match Lit's render approach: closed shows section with entry, open shows dialog\n if (!isOpen) {\n return (\n <div className=\"a2ui-modal\" style={hostStyle}>\n <section onClick={openModal} style={{ cursor: \"pointer\" }}>\n <ComponentNode node={props.entryPointChild} surfaceId={surfaceId} />\n </section>\n </div>\n );\n }\n\n return (\n <div className=\"a2ui-modal\" style={hostStyle}>\n <dialog\n ref={dialogRef}\n className={classMapToString(theme.components.Modal.backdrop)}\n onClick={handleBackdropClick}\n onKeyDown={handleKeyDown}\n >\n <section\n className={classMapToString(theme.components.Modal.element)}\n style={stylesToObject(theme.additionalStyles?.Modal)}\n >\n <div id=\"controls\">\n <button onClick={closeModal} aria-label=\"Close modal\">\n <span className=\"g-icon\">close</span>\n </button>\n </div>\n <ComponentNode node={props.contentChild} surfaceId={surfaceId} />\n </section>\n </dialog>\n </div>\n );\n});\n\nexport default Modal;\n","import { useCallback, memo } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport type { A2UIComponentProps } from \"../../types\";\nimport { useA2UIComponent } from \"../../hooks/useA2UIComponent\";\nimport { classMapToString, stylesToObject } from \"../../lib/utils\";\nimport { ComponentNode } from \"../../core/ComponentNode\";\n\n/**\n * Button component - a clickable element that triggers an action.\n *\n * Contains a child component (usually Text or Icon) and dispatches\n * a user action when clicked.\n */\nexport const Button = memo(function Button({\n node,\n surfaceId,\n}: A2UIComponentProps<Types.ButtonNode>) {\n const { theme, sendAction } = useA2UIComponent(node, surfaceId);\n const props = node.properties;\n\n const handleClick = useCallback(() => {\n if (props.action) {\n sendAction(props.action);\n }\n }, [props.action, sendAction]);\n\n // Apply --weight CSS variable on root div (:host equivalent) for flex layouts\n const hostStyle: React.CSSProperties =\n node.weight !== undefined\n ? ({ \"--weight\": node.weight } as React.CSSProperties)\n : {};\n\n return (\n <div className=\"a2ui-button\" style={hostStyle}>\n <button\n className={classMapToString(theme.components.Button)}\n style={stylesToObject(theme.additionalStyles?.Button)}\n onClick={handleClick}\n >\n <ComponentNode node={props.child} surfaceId={surfaceId} />\n </button>\n </div>\n );\n});\n\nexport default Button;\n","import { useState, useCallback, useEffect, useId, memo } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport type { A2UIComponentProps } from \"../../types\";\nimport { useA2UIComponent } from \"../../hooks/useA2UIComponent\";\nimport { classMapToString, stylesToObject } from \"../../lib/utils\";\n\ntype TextFieldType = \"shortText\" | \"longText\" | \"number\" | \"date\";\n\n/**\n * TextField component - an input field for text entry.\n *\n * Supports various input types and two-way data binding.\n */\nexport const TextField = memo(function TextField({\n node,\n surfaceId,\n}: A2UIComponentProps<Types.TextFieldNode>) {\n const { theme, resolveString, setValue, getValue } = useA2UIComponent(\n node,\n surfaceId,\n );\n const props = node.properties;\n const id = useId();\n\n const label = resolveString(props.label);\n const textPath = props.text?.path;\n const initialValue = resolveString(props.text) ?? \"\";\n const fieldType = props.type as TextFieldType | undefined;\n const validationRegexp = props.validationRegexp;\n\n const [value, setLocalValue] = useState(initialValue);\n // Validation state tracked for potential future use (e.g., error styling)\n const [_isValid, setIsValid] = useState(true);\n\n // Sync with external data model changes\n useEffect(() => {\n if (textPath) {\n const externalValue = getValue(textPath);\n if (externalValue !== null && String(externalValue) !== value) {\n setLocalValue(String(externalValue));\n }\n }\n }, [textPath, getValue]); // eslint-disable-line react-hooks/exhaustive-deps\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {\n const newValue = e.target.value;\n setLocalValue(newValue);\n\n // Validate if pattern provided\n if (validationRegexp) {\n setIsValid(new RegExp(validationRegexp).test(newValue));\n }\n\n // Two-way binding: update data model\n if (textPath) {\n setValue(textPath, newValue);\n }\n },\n [validationRegexp, textPath, setValue],\n );\n\n const inputType =\n fieldType === \"number\" ? \"number\" : fieldType === \"date\" ? \"date\" : \"text\";\n const isTextArea = fieldType === \"longText\";\n\n // Structure mirrors Lit's TextField component:\n // <div class=\"a2ui-textfield\"> ← :host equivalent\n // <section class=\"...\"> ← container with theme classes\n // <label>...</label>\n // <input>...</input>\n // </section>\n // </div>\n\n // Apply --weight CSS variable on root div (:host equivalent) for flex layouts\n const hostStyle: React.CSSProperties =\n node.weight !== undefined\n ? ({ \"--weight\": node.weight } as React.CSSProperties)\n : {};\n\n return (\n <div className=\"a2ui-textfield\" style={hostStyle}>\n <section\n className={classMapToString(theme.components.TextField.container)}\n >\n {label && (\n <label\n htmlFor={id}\n className={classMapToString(theme.components.TextField.label)}\n >\n {label}\n </label>\n )}\n {isTextArea ? (\n <textarea\n id={id}\n value={value}\n onChange={handleChange}\n placeholder=\"Please enter a value\"\n className={classMapToString(theme.components.TextField.element)}\n style={stylesToObject(theme.additionalStyles?.TextField)}\n />\n ) : (\n <input\n type={inputType}\n id={id}\n value={value}\n onChange={handleChange}\n placeholder=\"Please enter a value\"\n className={classMapToString(theme.components.TextField.element)}\n style={stylesToObject(theme.additionalStyles?.TextField)}\n />\n )}\n </section>\n </div>\n );\n});\n\nexport default TextField;\n","import { useState, useCallback, useEffect, useId, memo } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport type { A2UIComponentProps } from \"../../types\";\nimport { useA2UIComponent } from \"../../hooks/useA2UIComponent\";\nimport { classMapToString, stylesToObject } from \"../../lib/utils\";\n\n/**\n * CheckBox component - a boolean toggle with a label.\n *\n * Supports two-way data binding for the checked state.\n */\nexport const CheckBox = memo(function CheckBox({\n node,\n surfaceId,\n}: A2UIComponentProps<Types.CheckboxNode>) {\n const { theme, resolveString, resolveBoolean, setValue, getValue } =\n useA2UIComponent(node, surfaceId);\n const props = node.properties;\n const id = useId();\n\n const label = resolveString(props.label);\n const valuePath = props.value?.path;\n const initialChecked = resolveBoolean(props.value) ?? false;\n\n const [checked, setChecked] = useState(initialChecked);\n\n // Sync with external data model changes (path binding)\n useEffect(() => {\n if (valuePath) {\n const externalValue = getValue(valuePath);\n if (externalValue !== null && Boolean(externalValue) !== checked) {\n setChecked(Boolean(externalValue));\n }\n }\n }, [valuePath, getValue]); // eslint-disable-line react-hooks/exhaustive-deps\n\n // Sync when literal value changes from props (server-driven updates via surfaceUpdate)\n useEffect(() => {\n if (props.value?.literalBoolean !== undefined) {\n setChecked(props.value.literalBoolean);\n }\n }, [props.value?.literalBoolean]);\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = e.target.checked;\n setChecked(newValue);\n\n // Two-way binding: update data model\n if (valuePath) {\n setValue(valuePath, newValue);\n }\n },\n [valuePath, setValue],\n );\n\n // Structure mirrors Lit's CheckBox component:\n // <div class=\"a2ui-checkbox\"> ← :host equivalent\n // <section class=\"...\"> ← internal element\n // <input>...</input>\n // <label>...</label>\n // </section>\n // </div>\n\n // Apply --weight CSS variable on root div (:host equivalent) for flex layouts\n const hostStyle: React.CSSProperties =\n node.weight !== undefined\n ? ({ \"--weight\": node.weight } as React.CSSProperties)\n : {};\n\n return (\n <div className=\"a2ui-checkbox\" style={hostStyle}>\n <section\n className={classMapToString(theme.components.CheckBox.container)}\n style={stylesToObject(theme.additionalStyles?.CheckBox)}\n >\n <input\n type=\"checkbox\"\n id={id}\n checked={checked}\n onChange={handleChange}\n className={classMapToString(theme.components.CheckBox.element)}\n />\n {label && (\n <label\n htmlFor={id}\n className={classMapToString(theme.components.CheckBox.label)}\n >\n {label}\n </label>\n )}\n </section>\n </div>\n );\n});\n\nexport default CheckBox;\n","import { useState, useCallback, useEffect, useId, memo } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport type { A2UIComponentProps } from \"../../types\";\nimport { useA2UIComponent } from \"../../hooks/useA2UIComponent\";\nimport { classMapToString, stylesToObject } from \"../../lib/utils\";\n\n/**\n * Slider component - a numeric value selector with a range.\n *\n * Supports two-way data binding for the value.\n */\nexport const Slider = memo(function Slider({\n node,\n surfaceId,\n}: A2UIComponentProps<Types.SliderNode>) {\n const { theme, resolveNumber, resolveString, setValue, getValue } =\n useA2UIComponent(node, surfaceId);\n const props = node.properties;\n const id = useId();\n\n const valuePath = props.value?.path;\n const initialValue = resolveNumber(props.value) ?? 0;\n // Match Lit's default values (minValue=0, maxValue=0)\n const minValue = props.minValue ?? 0;\n const maxValue = props.maxValue ?? 0;\n\n const [value, setLocalValue] = useState(initialValue);\n\n // Sync with external data model changes (path binding)\n useEffect(() => {\n if (valuePath) {\n const externalValue = getValue(valuePath);\n if (externalValue !== null && Number(externalValue) !== value) {\n setLocalValue(Number(externalValue));\n }\n }\n }, [valuePath, getValue]); // eslint-disable-line react-hooks/exhaustive-deps\n\n // Sync when literal value changes from props (server-driven updates via surfaceUpdate)\n useEffect(() => {\n if (props.value?.literalNumber !== undefined) {\n setLocalValue(props.value.literalNumber);\n }\n }, [props.value?.literalNumber]);\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = Number(e.target.value);\n setLocalValue(newValue);\n\n // Two-way binding: update data model\n if (valuePath) {\n setValue(valuePath, newValue);\n }\n },\n [valuePath, setValue],\n );\n\n // Access label from props if it exists (Lit component supports it but type doesn't define it)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const labelValue = (props as any).label;\n const label = labelValue ? resolveString(labelValue) : \"\";\n\n // Structure mirrors Lit's Slider component:\n // <div class=\"a2ui-slider\"> ← :host equivalent\n // <section class=\"...\"> ← internal element\n // <label>...</label>\n // <input>...</input>\n // <span>value</span>\n // </section>\n // </div>\n\n // Apply --weight CSS variable on root div (:host equivalent) for flex layouts\n const hostStyle: React.CSSProperties =\n node.weight !== undefined\n ? ({ \"--weight\": node.weight } as React.CSSProperties)\n : {};\n\n return (\n <div className=\"a2ui-slider\" style={hostStyle}>\n <section className={classMapToString(theme.components.Slider.container)}>\n <label\n htmlFor={id}\n className={classMapToString(theme.components.Slider.label)}\n >\n {label}\n </label>\n <input\n type=\"range\"\n id={id}\n name=\"data\"\n value={value}\n min={minValue}\n max={maxValue}\n onChange={handleChange}\n className={classMapToString(theme.components.Slider.element)}\n style={stylesToObject(theme.additionalStyles?.Slider)}\n />\n <span className={classMapToString(theme.components.Slider.label)}>\n {value}\n </span>\n </section>\n </div>\n );\n});\n\nexport default Slider;\n","import { useState, useCallback, useEffect, useId, memo } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport type { A2UIComponentProps } from \"../../types\";\nimport { useA2UIComponent } from \"../../hooks/useA2UIComponent\";\nimport { classMapToString, stylesToObject } from \"../../lib/utils\";\n\n/**\n * DateTimeInput component - a date and/or time picker.\n *\n * Supports enabling date, time, or both. Uses native HTML5 date/time inputs.\n */\nexport const DateTimeInput = memo(function DateTimeInput({\n node,\n surfaceId,\n}: A2UIComponentProps<Types.DateTimeInputNode>) {\n const { theme, resolveString, setValue, getValue } = useA2UIComponent(\n node,\n surfaceId,\n );\n const props = node.properties;\n const id = useId();\n\n const valuePath = props.value?.path;\n const initialValue = resolveString(props.value) ?? \"\";\n const enableDate = props.enableDate ?? true;\n const enableTime = props.enableTime ?? false;\n\n const [value, setLocalValue] = useState(initialValue);\n\n // Sync with external data model changes\n useEffect(() => {\n if (valuePath) {\n const externalValue = getValue(valuePath);\n if (externalValue !== null && String(externalValue) !== value) {\n setLocalValue(String(externalValue));\n }\n }\n }, [valuePath, getValue]); // eslint-disable-line react-hooks/exhaustive-deps\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = e.target.value;\n setLocalValue(newValue);\n\n // Two-way binding: update data model\n if (valuePath) {\n setValue(valuePath, newValue);\n }\n },\n [valuePath, setValue],\n );\n\n // Determine input type based on enableDate and enableTime\n let inputType: \"date\" | \"time\" | \"datetime-local\" = \"date\";\n if (enableDate && enableTime) {\n inputType = \"datetime-local\";\n } else if (enableTime && !enableDate) {\n inputType = \"time\";\n }\n\n // Get placeholder text to match Lit renderer\n const getPlaceholderText = () => {\n if (enableDate && enableTime) {\n return \"Date & Time\";\n } else if (enableTime) {\n return \"Time\";\n }\n return \"Date\";\n };\n\n // Structure mirrors Lit's DateTimeInput component:\n // <div class=\"a2ui-datetime-input\"> ← :host equivalent\n // <section class=\"...\"> ← container theme classes\n // <label> ← label\n // <input> ← input element\n // </section>\n // </div>\n\n // Apply --weight CSS variable on root div (:host equivalent) for flex layouts\n const hostStyle: React.CSSProperties =\n node.weight !== undefined\n ? ({ \"--weight\": node.weight } as React.CSSProperties)\n : {};\n\n return (\n <div className=\"a2ui-datetime-input\" style={hostStyle}>\n <section\n className={classMapToString(theme.components.DateTimeInput.container)}\n >\n <label\n htmlFor={id}\n className={classMapToString(theme.components.DateTimeInput.label)}\n >\n {getPlaceholderText()}\n </label>\n <input\n type={inputType}\n id={id}\n value={value}\n onChange={handleChange}\n className={classMapToString(theme.components.DateTimeInput.element)}\n style={stylesToObject(theme.additionalStyles?.DateTimeInput)}\n />\n </section>\n </div>\n );\n});\n\nexport default DateTimeInput;\n","import { useCallback, useId, memo } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport type { A2UIComponentProps } from \"../../types\";\nimport { useA2UIComponent } from \"../../hooks/useA2UIComponent\";\nimport { classMapToString, stylesToObject } from \"../../lib/utils\";\n\n/**\n * MultipleChoice component - a selection component using a dropdown.\n *\n * Renders a <select> element with options, matching the Lit renderer's behavior.\n * Supports two-way data binding for the selected value.\n */\nexport const MultipleChoice = memo(function MultipleChoice({\n node,\n surfaceId,\n}: A2UIComponentProps<Types.MultipleChoiceNode>) {\n const { theme, resolveString, setValue } = useA2UIComponent(node, surfaceId);\n const props = node.properties;\n const id = useId();\n\n const options =\n (props.options as {\n label: { literalString?: string; path?: string };\n value: string;\n }[]) ?? [];\n const selectionsPath = props.selections?.path;\n\n // Access description from props (Lit component supports it)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const description =\n resolveString((props as any).description) ?? \"Select an item\";\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLSelectElement>) => {\n // Two-way binding: update data model with array (matches Lit behavior)\n if (selectionsPath) {\n setValue(selectionsPath, [e.target.value]);\n }\n },\n [selectionsPath, setValue],\n );\n\n // Apply --weight CSS variable on root div (:host equivalent) for flex layouts\n const hostStyle: React.CSSProperties =\n node.weight !== undefined\n ? ({ \"--weight\": node.weight } as React.CSSProperties)\n : {};\n\n // Structure mirrors Lit's MultipleChoice component:\n // <div class=\"a2ui-multiplechoice\"> ← :host equivalent\n // <section class=\"...\"> ← container theme classes\n // <label>...</label> ← description label\n // <select>...</select> ← dropdown element\n // </section>\n // </div>\n return (\n <div className=\"a2ui-multiplechoice\" style={hostStyle}>\n <section\n className={classMapToString(theme.components.MultipleChoice.container)}\n >\n <label\n htmlFor={id}\n className={classMapToString(theme.components.MultipleChoice.label)}\n >\n {description}\n </label>\n <select\n name=\"data\"\n id={id}\n className={classMapToString(theme.components.MultipleChoice.element)}\n style={stylesToObject(theme.additionalStyles?.MultipleChoice)}\n onChange={handleChange}\n >\n {options.map((option) => {\n const label = resolveString(option.label);\n return (\n <option key={option.value} value={option.value}>\n {label}\n </option>\n );\n })}\n </select>\n </section>\n </div>\n );\n});\n\nexport default MultipleChoice;\n","import { ComponentRegistry } from \"./ComponentRegistry\";\n\n// Content components\nimport { Text } from \"../components/content/Text\";\nimport { Image } from \"../components/content/Image\";\nimport { Icon } from \"../components/content/Icon\";\nimport { Divider } from \"../components/content/Divider\";\nimport { Video } from \"../components/content/Video\";\nimport { AudioPlayer } from \"../components/content/AudioPlayer\";\n\n// Layout components\nimport { Row } from \"../components/layout/Row\";\nimport { Column } from \"../components/layout/Column\";\nimport { List } from \"../components/layout/List\";\nimport { Card } from \"../components/layout/Card\";\nimport { Tabs } from \"../components/layout/Tabs\";\nimport { Modal } from \"../components/layout/Modal\";\n\n// Interactive components\nimport { Button } from \"../components/interactive/Button\";\nimport { TextField } from \"../components/interactive/TextField\";\nimport { CheckBox } from \"../components/interactive/CheckBox\";\nimport { Slider } from \"../components/interactive/Slider\";\nimport { DateTimeInput } from \"../components/interactive/DateTimeInput\";\nimport { MultipleChoice } from \"../components/interactive/MultipleChoice\";\n\n/**\n * Registers all standard A2UI components in the registry.\n *\n * @param registry - The component registry to populate\n */\nexport function registerDefaultCatalog(registry: ComponentRegistry): void {\n // Content components (small, load immediately)\n registry.register(\"Text\", { component: Text });\n registry.register(\"Image\", { component: Image });\n registry.register(\"Icon\", { component: Icon });\n registry.register(\"Divider\", { component: Divider });\n registry.register(\"Video\", { component: Video });\n registry.register(\"AudioPlayer\", { component: AudioPlayer });\n\n // Layout components\n registry.register(\"Row\", { component: Row });\n registry.register(\"Column\", { component: Column });\n registry.register(\"List\", { component: List });\n registry.register(\"Card\", { component: Card });\n\n // Additional layout components\n registry.register(\"Tabs\", { component: Tabs });\n registry.register(\"Modal\", { component: Modal });\n\n // Interactive components\n registry.register(\"Button\", { component: Button });\n registry.register(\"TextField\", { component: TextField });\n registry.register(\"CheckBox\", { component: CheckBox });\n registry.register(\"Slider\", { component: Slider });\n registry.register(\"DateTimeInput\", { component: DateTimeInput });\n registry.register(\"MultipleChoice\", { component: MultipleChoice });\n}\n\n/**\n * Initialize the default catalog in the singleton registry.\n * Call this once at app startup.\n */\nexport function initializeDefaultCatalog(): void {\n registerDefaultCatalog(ComponentRegistry.getInstance());\n}\n","/**\n * Browser default reset for A2UI surfaces.\n *\n * The React renderer uses Light DOM, which means host-app CSS resets\n * (e.g. Tailwind preflight, normalize.css) can strip browser defaults\n * like heading margins, list styles, and form element appearance from\n * elements inside the renderer.\n *\n * The Lit renderer avoids this because Shadow DOM isolates its elements\n * from external stylesheets.\n *\n * This reset restores browser defaults inside `.a2ui-surface` by using\n * `all: revert` in a CSS @layer. Layered styles have the lowest author\n * priority, so every other A2UI style (utility classes, component styles,\n * theme classes, inline styles) automatically overrides the reset.\n */\nexport const resetStyles: string = `\n@layer a2ui-reset {\n :where(.a2ui-surface) :where(*) {\n all: revert;\n }\n}\n`;\n","import { Styles } from \"@a2ui/lit/0.8\";\nimport { resetStyles } from \"./reset\";\n\n/**\n * Structural CSS styles from the Lit renderer, converted for global DOM use.\n * These styles define all the utility classes (layout-*, typography-*, color-*, etc.)\n * Converts :host selectors to .a2ui-surface for scoped use outside Shadow DOM.\n */\nexport const structuralStyles: string = Styles.structuralStyles.replace(\n /:host\\s*\\{/g,\n \".a2ui-surface {\",\n);\n\n/**\n * Component-specific styles that replicate Lit's Shadow DOM scoped CSS.\n *\n * Each Lit component has `static styles` with :host, element selectors, and ::slotted().\n * Since React uses Light DOM, we transform these to global CSS scoped under .a2ui-surface.\n *\n * Transformation rules:\n * :host → .a2ui-surface .a2ui-{component}\n * section → .a2ui-surface .a2ui-{component} section\n * ::slotted(*) → .a2ui-surface .a2ui-{component} section > *\n */\nexport const componentSpecificStyles: string = `\n/* =========================================================================\n * Card (from Lit card.ts static styles)\n * ========================================================================= */\n\n/* :host { display: block; flex: var(--weight); min-height: 0; overflow: auto; } */\n.a2ui-surface .a2ui-card {\n display: block;\n flex: var(--weight);\n min-height: 0;\n overflow: auto;\n}\n\n/* section { height: 100%; width: 100%; min-height: 0; overflow: auto; } */\n/* Use > to target only Card's direct section, not nested sections (e.g., TextField's section) */\n.a2ui-surface .a2ui-card > section {\n height: 100%;\n width: 100%;\n min-height: 0;\n overflow: auto;\n}\n\n/* section ::slotted(*) { height: 100%; width: 100%; } */\n/* Use > section > to only target Card's slotted children, not deeply nested elements */\n.a2ui-surface .a2ui-card > section > * {\n height: 100%;\n width: 100%;\n}\n\n/* =========================================================================\n * Divider (from Lit divider.ts static styles)\n * ========================================================================= */\n\n/* :host { display: block; min-height: 0; overflow: auto; } */\n.a2ui-surface .a2ui-divider {\n display: block;\n min-height: 0;\n overflow: auto;\n}\n\n/* hr { height: 1px; background: #ccc; border: none; } */\n/* Use :where() for low specificity (0,0,1) so theme utility classes can override */\n/* Browser default margins apply (margin-block: 0.5em, margin-inline: auto) */\n:where(.a2ui-surface .a2ui-divider) hr {\n height: 1px;\n background: #ccc;\n border: none;\n}\n\n/* =========================================================================\n * Text (from Lit text.ts static styles)\n * ========================================================================= */\n\n/* :host { display: block; flex: var(--weight); } */\n.a2ui-surface .a2ui-text {\n display: block;\n flex: var(--weight);\n}\n\n/* h1, h2, h3, h4, h5 { line-height: inherit; font: inherit; } */\n/* Use :where() to match Lit's low specificity (0,0,0,1 - just element) */\n:where(.a2ui-surface .a2ui-text) h1,\n:where(.a2ui-surface .a2ui-text) h2,\n:where(.a2ui-surface .a2ui-text) h3,\n:where(.a2ui-surface .a2ui-text) h4,\n:where(.a2ui-surface .a2ui-text) h5 {\n line-height: inherit;\n font: inherit;\n}\n\n/* Ensure markdown paragraph margins are reset */\n.a2ui-surface .a2ui-text p {\n margin: 0;\n}\n\n/* =========================================================================\n * TextField (from Lit text-field.ts static styles)\n * ========================================================================= */\n\n/* :host { display: flex; flex: var(--weight); } */\n.a2ui-surface .a2ui-textfield {\n display: flex;\n flex: var(--weight);\n}\n\n/* input { display: block; width: 100%; } */\n:where(.a2ui-surface .a2ui-textfield) input {\n display: block;\n width: 100%;\n}\n\n/* label { display: block; margin-bottom: 4px; } */\n:where(.a2ui-surface .a2ui-textfield) label {\n display: block;\n margin-bottom: 4px;\n}\n\n/* textarea - same styling as input for multiline text fields */\n:where(.a2ui-surface .a2ui-textfield) textarea {\n display: block;\n width: 100%;\n}\n\n/* =========================================================================\n * CheckBox (from Lit checkbox.ts static styles)\n * ========================================================================= */\n\n/* :host { display: block; flex: var(--weight); min-height: 0; overflow: auto; } */\n.a2ui-surface .a2ui-checkbox {\n display: block;\n flex: var(--weight);\n min-height: 0;\n overflow: auto;\n}\n\n/* input { display: block; width: 100%; } */\n:where(.a2ui-surface .a2ui-checkbox) input {\n display: block;\n width: 100%;\n}\n\n/* =========================================================================\n * Slider (from Lit slider.ts static styles)\n * ========================================================================= */\n\n/* :host { display: block; flex: var(--weight); } */\n.a2ui-surface .a2ui-slider {\n display: block;\n flex: var(--weight);\n}\n\n/* input { display: block; width: 100%; } */\n:where(.a2ui-surface .a2ui-slider) input {\n display: block;\n width: 100%;\n}\n\n/* =========================================================================\n * Button (from Lit button.ts static styles)\n * ========================================================================= */\n\n/* :host { display: block; flex: var(--weight); min-height: 0; } */\n.a2ui-surface .a2ui-button {\n display: block;\n flex: var(--weight);\n min-height: 0;\n}\n\n/* =========================================================================\n * Icon (from Lit icon.ts static styles)\n * ========================================================================= */\n\n/* :host { display: block; flex: var(--weight); min-height: 0; overflow: auto; } */\n.a2ui-surface .a2ui-icon {\n display: block;\n flex: var(--weight);\n min-height: 0;\n overflow: auto;\n}\n\n/* =========================================================================\n * Tabs (from Lit tabs.ts static styles)\n * ========================================================================= */\n\n/* :host { display: block; flex: var(--weight); } */\n.a2ui-surface .a2ui-tabs {\n display: block;\n flex: var(--weight);\n}\n\n/* =========================================================================\n * Modal (from Lit modal.ts static styles)\n * ========================================================================= */\n\n/* :host { display: block; flex: var(--weight); } */\n.a2ui-surface .a2ui-modal {\n display: block;\n flex: var(--weight);\n}\n\n/* dialog { padding: 0; border: none; background: none; } */\n:where(.a2ui-surface .a2ui-modal) dialog {\n padding: 0;\n border: none;\n background: none;\n}\n\n/* dialog section #controls { display: flex; justify-content: end; margin-bottom: 4px; } */\n.a2ui-surface .a2ui-modal dialog section #controls {\n display: flex;\n justify-content: end;\n margin-bottom: 4px;\n}\n\n/* dialog section #controls button { padding: 0; background: none; ... } */\n.a2ui-surface .a2ui-modal dialog section #controls button {\n padding: 0;\n background: none;\n width: 20px;\n height: 20px;\n cursor: pointer;\n border: none;\n}\n\n/* =========================================================================\n * Image (from Lit image.ts static styles)\n * ========================================================================= */\n\n/* :host { display: block; flex: var(--weight); min-height: 0; overflow: auto; } */\n.a2ui-surface .a2ui-image {\n display: block;\n flex: var(--weight);\n min-height: 0;\n overflow: auto;\n}\n\n/* img { display: block; width: 100%; height: 100%; object-fit: var(--object-fit, fill); } */\n:where(.a2ui-surface .a2ui-image) img {\n display: block;\n width: 100%;\n height: 100%;\n object-fit: var(--object-fit, fill);\n}\n\n/* =========================================================================\n * Video (from Lit video.ts static styles)\n * ========================================================================= */\n\n/* :host { display: block; flex: var(--weight); min-height: 0; overflow: auto; } */\n.a2ui-surface .a2ui-video {\n display: block;\n flex: var(--weight);\n min-height: 0;\n overflow: auto;\n}\n\n/* video { display: block; width: 100%; } */\n:where(.a2ui-surface .a2ui-video) video {\n display: block;\n width: 100%;\n}\n\n/* =========================================================================\n * AudioPlayer (from Lit audio.ts static styles)\n * ========================================================================= */\n\n/* :host { display: block; flex: var(--weight); min-height: 0; overflow: auto; } */\n.a2ui-surface .a2ui-audio {\n display: block;\n flex: var(--weight);\n min-height: 0;\n overflow: auto;\n}\n\n/* audio { display: block; width: 100%; } */\n:where(.a2ui-surface .a2ui-audio) audio {\n display: block;\n width: 100%;\n}\n\n/* =========================================================================\n * MultipleChoice (from Lit multiple-choice.ts static styles)\n * ========================================================================= */\n\n/* :host { display: block; flex: var(--weight); min-height: 0; overflow: auto; } */\n.a2ui-surface .a2ui-multiplechoice {\n display: block;\n flex: var(--weight);\n min-height: 0;\n overflow: auto;\n}\n\n/* select { width: 100%; } */\n:where(.a2ui-surface .a2ui-multiplechoice) select {\n width: 100%;\n}\n\n/* =========================================================================\n * Column (from Lit column.ts static styles)\n * ========================================================================= */\n\n/* :host { display: flex; flex: var(--weight); } */\n.a2ui-surface .a2ui-column {\n display: flex;\n flex: var(--weight);\n}\n\n/* section { display: flex; flex-direction: column; min-width: 100%; height: 100%; } */\n.a2ui-surface .a2ui-column > section {\n display: flex;\n flex-direction: column;\n min-width: 100%;\n height: 100%;\n}\n\n/* :host([alignment=\"...\"]) section { align-items: ...; } */\n/* Use > section to only target Column's direct section, not nested sections (e.g., CheckBox's section) */\n.a2ui-surface .a2ui-column[data-alignment=\"start\"] > section { align-items: start; }\n.a2ui-surface .a2ui-column[data-alignment=\"center\"] > section { align-items: center; }\n.a2ui-surface .a2ui-column[data-alignment=\"end\"] > section { align-items: end; }\n.a2ui-surface .a2ui-column[data-alignment=\"stretch\"] > section { align-items: stretch; }\n\n/* :host([distribution=\"...\"]) section { justify-content: ...; } */\n.a2ui-surface .a2ui-column[data-distribution=\"start\"] > section { justify-content: start; }\n.a2ui-surface .a2ui-column[data-distribution=\"center\"] > section { justify-content: center; }\n.a2ui-surface .a2ui-column[data-distribution=\"end\"] > section { justify-content: end; }\n.a2ui-surface .a2ui-column[data-distribution=\"spaceBetween\"] > section { justify-content: space-between; }\n.a2ui-surface .a2ui-column[data-distribution=\"spaceAround\"] > section { justify-content: space-around; }\n.a2ui-surface .a2ui-column[data-distribution=\"spaceEvenly\"] > section { justify-content: space-evenly; }\n\n/* =========================================================================\n * Row (from Lit row.ts static styles)\n * ========================================================================= */\n\n/* :host { display: flex; flex: var(--weight); } */\n.a2ui-surface .a2ui-row {\n display: flex;\n flex: var(--weight);\n}\n\n/* section { display: flex; flex-direction: row; width: 100%; min-height: 100%; } */\n.a2ui-surface .a2ui-row > section {\n display: flex;\n flex-direction: row;\n width: 100%;\n min-height: 100%;\n}\n\n/* :host([alignment=\"...\"]) section { align-items: ...; } */\n/* Use > section to only target Row's direct section, not nested sections */\n.a2ui-surface .a2ui-row[data-alignment=\"start\"] > section { align-items: start; }\n.a2ui-surface .a2ui-row[data-alignment=\"center\"] > section { align-items: center; }\n.a2ui-surface .a2ui-row[data-alignment=\"end\"] > section { align-items: end; }\n.a2ui-surface .a2ui-row[data-alignment=\"stretch\"] > section { align-items: stretch; }\n\n/* :host([distribution=\"...\"]) section { justify-content: ...; } */\n.a2ui-surface .a2ui-row[data-distribution=\"start\"] > section { justify-content: start; }\n.a2ui-surface .a2ui-row[data-distribution=\"center\"] > section { justify-content: center; }\n.a2ui-surface .a2ui-row[data-distribution=\"end\"] > section { justify-content: end; }\n.a2ui-surface .a2ui-row[data-distribution=\"spaceBetween\"] > section { justify-content: space-between; }\n.a2ui-surface .a2ui-row[data-distribution=\"spaceAround\"] > section { justify-content: space-around; }\n.a2ui-surface .a2ui-row[data-distribution=\"spaceEvenly\"] > section { justify-content: space-evenly; }\n\n/* =========================================================================\n * List (from Lit list.ts static styles)\n * ========================================================================= */\n\n/* :host { display: block; flex: var(--weight); min-height: 0; overflow: auto; } */\n.a2ui-surface .a2ui-list {\n display: block;\n flex: var(--weight);\n min-height: 0;\n overflow: auto;\n}\n\n/* :host([direction=\"vertical\"]) section { display: grid; } */\n.a2ui-surface .a2ui-list[data-direction=\"vertical\"] > section {\n display: grid;\n}\n\n/* :host([direction=\"horizontal\"]) section { display: flex; max-width: 100%; overflow-x: scroll; ... } */\n.a2ui-surface .a2ui-list[data-direction=\"horizontal\"] > section {\n display: flex;\n max-width: 100%;\n overflow-x: scroll;\n overflow-y: hidden;\n scrollbar-width: none;\n}\n\n/* :host([direction=\"horizontal\"]) section > ::slotted(*) { flex: 1 0 fit-content; ... } */\n.a2ui-surface .a2ui-list[data-direction=\"horizontal\"] > section > * {\n flex: 1 0 fit-content;\n max-width: min(80%, 400px);\n}\n\n/* =========================================================================\n * DateTimeInput (from Lit datetime-input.ts static styles)\n * ========================================================================= */\n\n/* :host { display: block; flex: var(--weight); min-height: 0; overflow: auto; } */\n.a2ui-surface .a2ui-datetime-input {\n display: block;\n flex: var(--weight);\n min-height: 0;\n overflow: auto;\n}\n\n/* input { display: block; border-radius: 8px; padding: 8px; border: 1px solid #ccc; width: 100%; } */\n/* Use :where() to match Lit's low specificity (0,0,0,1) so theme utility classes can override */\n:where(.a2ui-surface .a2ui-datetime-input) input {\n display: block;\n border-radius: 8px;\n padding: 8px;\n border: 1px solid #ccc;\n width: 100%;\n}\n\n/* =========================================================================\n * Global box-sizing (matches Lit's * { box-sizing: border-box; } in components)\n * ========================================================================= */\n\n.a2ui-surface *,\n.a2ui-surface *::before,\n.a2ui-surface *::after {\n box-sizing: border-box;\n}\n`;\n\n/**\n * Injects A2UI structural styles into the document head.\n * Includes utility classes (layout-*, typography-*, color-*, etc.) and React-specific overrides.\n * Call this once at application startup.\n *\n * NOTE: CSS variables (--n-*, --p-*, etc.) must be defined by the host application on :root,\n * just like in the Lit renderer. This allows full customization of the color palette.\n *\n * @example\n * ```tsx\n * import { injectStyles } from '@a2ui/react/styles';\n *\n * // In your app entry point:\n * injectStyles();\n * ```\n */\nexport function injectStyles(): void {\n if (typeof document === \"undefined\") {\n return; // SSR safety\n }\n\n const styleId = \"a2ui-structural-styles\";\n\n // Avoid duplicate injection\n if (document.getElementById(styleId)) {\n return;\n }\n\n const styleElement = document.createElement(\"style\");\n styleElement.id = styleId;\n // Include structural (utility classes) and component-specific styles\n // Note: CSS variables (palette) must be defined by the host application on :root,\n // just like in the Lit renderer. This allows full customization.\n styleElement.textContent =\n resetStyles + \"\\n\" + structuralStyles + \"\\n\" + componentSpecificStyles;\n document.head.appendChild(styleElement);\n}\n\n/**\n * Removes injected A2UI styles from the document.\n * Useful for cleanup in tests or when unmounting.\n */\nexport function removeStyles(): void {\n if (typeof document === \"undefined\") {\n return;\n }\n\n const styleElement = document.getElementById(\"a2ui-structural-styles\");\n if (styleElement) {\n styleElement.remove();\n }\n}\n","import {\n useCopilotKit,\n type ReactActivityMessageRenderer,\n} from \"@copilotkit/react-core/v2\";\nimport { v0_8 } from \"@a2ui/lit\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { z } from \"zod\";\nimport {\n A2UIProvider,\n useA2UIActions,\n} from \"./react-renderer/core/A2UIProvider\";\nimport { A2UIRenderer } from \"./react-renderer/core/A2UIRenderer\";\nimport { initializeDefaultCatalog } from \"./react-renderer/registry/defaultCatalog\";\nimport { injectStyles } from \"./react-renderer/styles\";\nimport type { Types } from \"@a2ui/lit/0.8\";\n\n// Initialize the React renderer's component catalog and styles once\nlet initialized = false;\nfunction ensureInitialized() {\n if (!initialized) {\n initializeDefaultCatalog();\n injectStyles();\n initialized = true;\n }\n}\n\nexport type A2UIMessageRendererOptions = {\n theme: v0_8.Types.Theme;\n};\n\nexport function createA2UIMessageRenderer(\n options: A2UIMessageRendererOptions,\n): ReactActivityMessageRenderer<any> {\n const { theme } = options;\n\n return {\n activityType: \"a2ui-surface\",\n content: z.any(),\n render: ({ content, agent }) => {\n ensureInitialized();\n\n const [operations, setOperations] = useState<any[]>([]);\n const lastSignatureRef = useRef<string | null>(null);\n const { copilotkit } = useCopilotKit();\n\n useEffect(() => {\n if (!content || !Array.isArray(content.operations)) {\n lastSignatureRef.current = null;\n setOperations([]);\n return;\n }\n\n const incoming = content.operations as any[];\n const signature = stringifyOperations(incoming);\n\n if (signature && signature === lastSignatureRef.current) {\n return;\n }\n\n lastSignatureRef.current = signature;\n setOperations(incoming);\n }, [content]);\n\n // Group operations by surface ID\n const groupedOperations = useMemo(() => {\n const groups = new Map<string, any[]>();\n\n for (const operation of operations) {\n const surfaceId =\n getOperationSurfaceId(operation) ??\n v0_8.Data.A2uiMessageProcessor.DEFAULT_SURFACE_ID;\n\n if (!groups.has(surfaceId)) {\n groups.set(surfaceId, []);\n }\n groups.get(surfaceId)!.push(operation);\n }\n\n return groups;\n }, [operations]);\n\n if (!groupedOperations.size) {\n return null;\n }\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col gap-6 overflow-auto py-6\">\n {Array.from(groupedOperations.entries()).map(([surfaceId, ops]) => (\n <ReactSurfaceHost\n key={surfaceId}\n surfaceId={surfaceId}\n operations={ops}\n theme={theme}\n agent={agent}\n copilotkit={copilotkit}\n />\n ))}\n </div>\n );\n },\n };\n}\n\ntype ReactSurfaceHostProps = {\n surfaceId: string;\n operations: any[];\n theme: v0_8.Types.Theme;\n agent: any;\n copilotkit: any;\n};\n\n/**\n * Renders a single A2UI surface using the React renderer.\n * Wraps A2UIProvider + A2UIRenderer and bridges actions back to CopilotKit.\n */\nfunction ReactSurfaceHost({\n surfaceId,\n operations,\n theme,\n agent,\n copilotkit,\n}: ReactSurfaceHostProps) {\n // Bridge: when the React renderer dispatches an action, send it to CopilotKit\n const handleAction = useCallback(\n async (message: Types.A2UIClientEventMessage) => {\n if (!agent) return;\n\n try {\n console.info(\"[A2UI] Action dispatched\", message.userAction);\n\n copilotkit.setProperties({\n ...(copilotkit.properties ?? {}),\n a2uiAction: message,\n });\n\n await copilotkit.runAgent({ agent });\n } finally {\n if (copilotkit.properties) {\n const { a2uiAction, ...rest } = copilotkit.properties;\n copilotkit.setProperties(rest);\n }\n }\n },\n [agent, copilotkit],\n );\n\n return (\n <div className=\"flex w-full flex-none overflow-hidden rounded-lg bg-white/5 p-4\">\n <A2UIProvider onAction={handleAction} theme={theme}>\n <SurfaceMessageProcessor\n surfaceId={surfaceId}\n operations={operations}\n />\n <A2UIRenderer surfaceId={surfaceId} className=\"flex flex-1\" />\n </A2UIProvider>\n </div>\n );\n}\n\n/**\n * Processes A2UI operations into the provider's message processor.\n * Must be a child of A2UIProvider to access the actions context.\n */\nfunction SurfaceMessageProcessor({\n surfaceId,\n operations,\n}: {\n surfaceId: string;\n operations: any[];\n}) {\n const { processMessages } = useA2UIActions();\n const lastProcessedRef = useRef<string>(\"\");\n\n useEffect(() => {\n const key = `${surfaceId}-${JSON.stringify(operations)}`;\n if (key === lastProcessedRef.current) return;\n lastProcessedRef.current = key;\n\n processMessages(operations);\n }, [processMessages, surfaceId, operations]);\n\n return null;\n}\n\nfunction getOperationSurfaceId(operation: any): string | null {\n if (!operation || typeof operation !== \"object\") {\n return null;\n }\n\n if (typeof operation.surfaceId === \"string\") {\n return operation.surfaceId;\n }\n\n return (\n operation?.beginRendering?.surfaceId ??\n operation?.surfaceUpdate?.surfaceId ??\n operation?.dataModelUpdate?.surfaceId ??\n operation?.deleteSurface?.surfaceId ??\n null\n );\n}\n\nfunction stringifyOperations(ops: any[]): string | null {\n try {\n return JSON.stringify(ops);\n } catch (error) {\n return null;\n }\n}\n","/*\n Copyright 2025 Google LLC\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n https://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n\nimport { v0_8 } from \"@a2ui/lit\";\n\n/** Elements */\n\nconst a = {\n \"typography-f-sf\": true,\n \"typography-fs-n\": true,\n \"typography-w-500\": true,\n \"layout-as-n\": true,\n \"layout-dis-iflx\": true,\n \"layout-al-c\": true,\n};\n\nconst audio = {\n \"layout-w-100\": true,\n};\n\nconst body = {\n \"typography-f-s\": true,\n \"typography-fs-n\": true,\n \"typography-w-400\": true,\n \"layout-mt-0\": true,\n \"layout-mb-2\": true,\n \"typography-sz-bm\": true,\n \"color-c-n10\": true,\n};\n\nconst button = {\n \"typography-f-sf\": true,\n \"typography-fs-n\": true,\n \"typography-w-500\": true,\n \"layout-pt-3\": true,\n \"layout-pb-3\": true,\n \"layout-pl-5\": true,\n \"layout-pr-5\": true,\n \"layout-mb-1\": true,\n \"border-br-16\": true,\n \"border-bw-0\": true,\n \"border-c-n70\": true,\n \"border-bs-s\": true,\n \"color-bgc-s30\": true,\n \"color-c-n100\": true,\n \"behavior-ho-80\": true,\n};\n\nconst heading = {\n \"typography-f-sf\": true,\n \"typography-fs-n\": true,\n \"typography-w-500\": true,\n \"layout-mt-0\": true,\n \"layout-mb-2\": true,\n \"color-c-n10\": true,\n};\n\nconst h1 = {\n ...heading,\n \"typography-sz-tl\": true,\n};\n\nconst h2 = {\n ...heading,\n \"typography-sz-tm\": true,\n};\n\nconst h3 = {\n ...heading,\n \"typography-sz-ts\": true,\n};\n\nconst iframe = {\n \"behavior-sw-n\": true,\n};\n\nconst input = {\n \"typography-f-sf\": true,\n \"typography-fs-n\": true,\n \"typography-w-400\": true,\n \"layout-pl-4\": true,\n \"layout-pr-4\": true,\n \"layout-pt-2\": true,\n \"layout-pb-2\": true,\n \"border-br-6\": true,\n \"border-bw-1\": true,\n \"color-bc-s70\": true,\n \"border-bs-s\": true,\n \"layout-as-n\": true,\n \"color-c-n10\": true,\n};\n\nconst p = {\n \"typography-f-s\": true,\n \"typography-fs-n\": true,\n \"typography-w-400\": true,\n \"layout-m-0\": true,\n \"typography-sz-bm\": true,\n \"layout-as-n\": true,\n \"color-c-n10\": true,\n};\n\nconst orderedList = {\n \"typography-f-s\": true,\n \"typography-fs-n\": true,\n \"typography-w-400\": true,\n \"layout-m-0\": true,\n \"typography-sz-bm\": true,\n \"layout-as-n\": true,\n};\n\nconst unorderedList = {\n \"typography-f-s\": true,\n \"typography-fs-n\": true,\n \"typography-w-400\": true,\n \"layout-m-0\": true,\n \"typography-sz-bm\": true,\n \"layout-as-n\": true,\n};\n\nconst listItem = {\n \"typography-f-s\": true,\n \"typography-fs-n\": true,\n \"typography-w-400\": true,\n \"layout-m-0\": true,\n \"typography-sz-bm\": true,\n \"layout-as-n\": true,\n};\n\nconst pre = {\n \"typography-f-c\": true,\n \"typography-fs-n\": true,\n \"typography-w-400\": true,\n \"typography-sz-bm\": true,\n \"typography-ws-p\": true,\n \"layout-as-n\": true,\n};\n\nconst textarea = {\n ...input,\n \"layout-r-none\": true,\n \"layout-fs-c\": true,\n};\n\nconst video = {\n \"layout-el-cv\": true,\n};\n\nconst aLight = v0_8.Styles.merge(a, { \"color-c-n5\": true });\nconst inputLight = v0_8.Styles.merge(input, { \"color-c-n5\": true });\nconst textareaLight = v0_8.Styles.merge(textarea, { \"color-c-n5\": true });\nconst buttonLight = v0_8.Styles.merge(button, { \"color-c-n100\": true });\nconst h1Light = v0_8.Styles.merge(h1, { \"color-c-n5\": true });\nconst h2Light = v0_8.Styles.merge(h2, { \"color-c-n5\": true });\nconst h3Light = v0_8.Styles.merge(h3, { \"color-c-n5\": true });\nconst bodyLight = v0_8.Styles.merge(body, { \"color-c-n5\": true });\nconst pLight = v0_8.Styles.merge(p, { \"color-c-n35\": true });\nconst preLight = v0_8.Styles.merge(pre, { \"color-c-n35\": true });\nconst orderedListLight = v0_8.Styles.merge(orderedList, {\n \"color-c-n35\": true,\n});\nconst unorderedListLight = v0_8.Styles.merge(unorderedList, {\n \"color-c-n35\": true,\n});\nconst listItemLight = v0_8.Styles.merge(listItem, {\n \"color-c-n35\": true,\n});\n\nexport const theme: v0_8.Types.Theme = {\n additionalStyles: {\n Button: {\n \"--n-35\": \"var(--n-100)\",\n },\n Card: {\n padding: \"32px\",\n },\n },\n components: {\n AudioPlayer: {},\n Button: {\n \"layout-pt-2\": true,\n \"layout-pb-2\": true,\n \"layout-pl-3\": true,\n \"layout-pr-3\": true,\n \"border-br-12\": true,\n \"border-bw-0\": true,\n \"border-bs-s\": true,\n \"color-bgc-p30\": true,\n \"color-c-n100\": true,\n \"behavior-ho-70\": true,\n },\n Card: { \"border-br-9\": true, \"color-bgc-p100\": true },\n CheckBox: {\n element: {\n \"layout-m-0\": true,\n \"layout-mr-2\": true,\n \"layout-p-2\": true,\n \"border-br-12\": true,\n \"border-bw-1\": true,\n \"border-bs-s\": true,\n \"color-bgc-p100\": true,\n \"color-bc-p60\": true,\n \"color-c-n30\": true,\n \"color-c-p30\": true,\n },\n label: {\n \"color-c-p30\": true,\n \"typography-f-sf\": true,\n \"typography-v-r\": true,\n \"typography-w-400\": true,\n \"layout-flx-1\": true,\n \"typography-sz-ll\": true,\n },\n container: {\n \"layout-dsp-iflex\": true,\n \"layout-al-c\": true,\n },\n },\n Column: {\n \"layout-g-2\": true,\n },\n DateTimeInput: {\n container: {},\n label: {},\n element: {\n \"layout-pt-2\": true,\n \"layout-pb-2\": true,\n \"layout-pl-3\": true,\n \"layout-pr-3\": true,\n \"border-br-12\": true,\n \"border-bw-1\": true,\n \"border-bs-s\": true,\n \"color-bgc-p100\": true,\n \"color-bc-p60\": true,\n \"color-c-n30\": true,\n \"color-c-p30\": true,\n },\n },\n Divider: {},\n Image: {\n all: {\n \"border-br-5\": true,\n \"layout-el-cv\": true,\n \"layout-w-100\": true,\n \"layout-h-100\": true,\n },\n avatar: { \"is-avatar\": true },\n header: {},\n icon: {},\n largeFeature: {},\n mediumFeature: {},\n smallFeature: {},\n },\n Icon: {},\n List: {\n \"layout-g-4\": true,\n \"layout-p-2\": true,\n },\n Modal: {\n backdrop: { \"color-bbgc-p60_20\": true },\n element: {\n \"border-br-2\": true,\n \"color-bgc-p100\": true,\n \"layout-p-4\": true,\n \"border-bw-1\": true,\n \"border-bs-s\": true,\n \"color-bc-p80\": true,\n },\n },\n MultipleChoice: {\n container: {},\n label: {},\n element: {},\n },\n Row: {\n \"layout-g-4\": true,\n },\n Slider: {\n container: {},\n label: {},\n element: {},\n },\n Tabs: {\n container: {},\n controls: { all: {}, selected: {} },\n element: {},\n },\n Text: {\n all: {\n \"layout-w-100\": true,\n \"layout-g-2\": true,\n },\n h1: {\n \"typography-f-sf\": true,\n \"typography-v-r\": true,\n \"typography-w-400\": true,\n \"layout-m-0\": true,\n \"layout-p-0\": true,\n \"typography-sz-tl\": true,\n },\n h2: {\n \"typography-f-sf\": true,\n \"typography-v-r\": true,\n \"typography-w-400\": true,\n \"layout-m-0\": true,\n \"layout-p-0\": true,\n \"typography-sz-tm\": true,\n },\n h3: {\n \"typography-f-sf\": true,\n \"typography-v-r\": true,\n \"typography-w-400\": true,\n \"layout-m-0\": true,\n \"layout-p-0\": true,\n \"typography-sz-ts\": true,\n },\n h4: {\n \"typography-f-sf\": true,\n \"typography-v-r\": true,\n \"typography-w-400\": true,\n \"layout-m-0\": true,\n \"layout-p-0\": true,\n \"typography-sz-bl\": true,\n },\n h5: {\n \"typography-f-sf\": true,\n \"typography-v-r\": true,\n \"typography-w-400\": true,\n \"layout-m-0\": true,\n \"layout-p-0\": true,\n \"typography-sz-bm\": true,\n },\n body: {},\n caption: {},\n },\n TextField: {\n container: {\n \"typography-sz-bm\": true,\n \"layout-w-100\": true,\n \"layout-g-2\": true,\n \"layout-dsp-flexhor\": true,\n \"layout-al-c\": true,\n },\n label: {\n \"layout-flx-0\": true,\n },\n element: {\n \"typography-sz-bm\": true,\n \"layout-pt-2\": true,\n \"layout-pb-2\": true,\n \"layout-pl-3\": true,\n \"layout-pr-3\": true,\n \"border-br-12\": true,\n \"border-bw-1\": true,\n \"border-bs-s\": true,\n \"color-bgc-p100\": true,\n \"color-bc-p60\": true,\n \"color-c-n30\": true,\n \"color-c-p30\": true,\n },\n },\n Video: {\n \"border-br-5\": true,\n \"layout-el-cv\": true,\n },\n },\n elements: {\n a: aLight,\n audio,\n body: bodyLight,\n button: buttonLight,\n h1: h1Light,\n h2: h2Light,\n h3: h3Light,\n h4: {},\n h5: {},\n iframe,\n input: inputLight,\n p: pLight,\n pre: preLight,\n textarea: textareaLight,\n video,\n },\n markdown: {\n p: [...Object.keys(pLight)],\n h1: [...Object.keys(h1Light)],\n h2: [...Object.keys(h2Light)],\n h3: [...Object.keys(h3Light)],\n h4: [],\n h5: [],\n ul: [...Object.keys(unorderedListLight)],\n ol: [...Object.keys(orderedListLight)],\n li: [...Object.keys(listItemLight)],\n a: [...Object.keys(aLight)],\n strong: [],\n em: [],\n },\n};\n","\"use client\";\n\nimport React, { useId, useMemo, useEffect, useRef } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport { v0_8 } from \"@a2ui/lit\";\nimport {\n A2UIProvider,\n useA2UIActions,\n} from \"./react-renderer/core/A2UIProvider\";\nimport { A2UIRenderer } from \"./react-renderer/core/A2UIRenderer\";\nimport { initializeDefaultCatalog } from \"./react-renderer/registry/defaultCatalog\";\nimport { litTheme } from \"./react-renderer/theme/litTheme\";\nimport { injectStyles } from \"./react-renderer/styles\";\nimport { theme as viewerTheme } from \"./theme/viewer-theme.js\";\n\n// Re-export types that consumers may need\nexport interface ComponentInstance {\n id: string;\n component: Record<string, unknown>;\n}\n\nexport interface A2UIActionEvent {\n actionName: string;\n sourceComponentId: string;\n timestamp: string;\n context: Record<string, unknown>;\n}\n\nexport interface A2UIViewerProps {\n /** ID of the root component to render */\n root: string;\n /** Component definitions - array of ComponentInstance */\n components: v0_8.Types.ComponentInstance[];\n /** Data model - nested object, e.g. { user: { name: \"John\" }, items: [\"a\", \"b\"] } */\n data?: Record<string, unknown>;\n /** Called when user triggers an action (button click, etc.) */\n onAction?: (action: A2UIActionEvent) => void;\n /** Surface styles (primaryColor, font, logoUrl) */\n styles?: Record<string, string>;\n /** Optional className for the container */\n className?: string;\n}\n\n// Initialize the React renderer's component catalog and styles once\nlet initialized = false;\nfunction ensureInitialized() {\n if (!initialized) {\n initializeDefaultCatalog();\n injectStyles();\n initialized = true;\n }\n}\n\n/**\n * A2UIViewer renders an A2UI component tree from a JSON definition and data.\n * It re-renders cleanly when props change, discarding previous state.\n */\nexport function A2UIViewer({\n root,\n components,\n data,\n onAction,\n styles,\n className,\n}: A2UIViewerProps): React.JSX.Element {\n ensureInitialized();\n\n // Use React's useId for SSR-safe base ID\n const baseId = useId();\n\n // Generate a stable surfaceId that changes when definition changes\n const surfaceId = useMemo(() => {\n const definitionKey = `${root}-${JSON.stringify(components)}`;\n let hash = 0;\n for (let i = 0; i < definitionKey.length; i++) {\n const char = definitionKey.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash;\n }\n return `surface${baseId.replace(/:/g, \"-\")}${hash}`;\n }, [baseId, root, components]);\n\n // Convert onAction callback to internal format\n const handleAction = useMemo(() => {\n if (!onAction) return undefined;\n\n return (message: Types.A2UIClientEventMessage) => {\n const userAction = message.userAction;\n if (userAction) {\n onAction({\n actionName: userAction.name,\n sourceComponentId: userAction.sourceComponentId,\n timestamp: userAction.timestamp,\n context: userAction.context ?? {},\n });\n }\n };\n }, [onAction]);\n\n // Show placeholder if no components provided\n if (!components || components.length === 0) {\n return (\n <div\n className={className}\n style={{ padding: 16, color: \"#666\", fontFamily: \"system-ui\" }}\n >\n No content to display\n </div>\n );\n }\n\n return (\n <A2UIProvider onAction={handleAction} theme={viewerTheme}>\n <A2UIViewerInner\n surfaceId={surfaceId}\n root={root}\n components={components}\n data={data ?? {}}\n styles={styles}\n className={className}\n />\n </A2UIProvider>\n );\n}\n\n/**\n * Inner component that processes messages within the provider context.\n */\nfunction A2UIViewerInner({\n surfaceId,\n root,\n components,\n data,\n styles,\n className,\n}: {\n surfaceId: string;\n root: string;\n components: v0_8.Types.ComponentInstance[];\n data: Record<string, unknown>;\n styles?: Record<string, string>;\n className?: string;\n}) {\n const { processMessages } = useA2UIActions();\n const lastProcessedRef = useRef<string>(\"\");\n\n // Process messages when props change\n useEffect(() => {\n const key = `${surfaceId}-${JSON.stringify(components)}-${JSON.stringify(data)}`;\n if (key === lastProcessedRef.current) return;\n lastProcessedRef.current = key;\n\n const messages: Types.ServerToClientMessage[] = [\n { beginRendering: { surfaceId, root, styles: styles ?? {} } },\n { surfaceUpdate: { surfaceId, components } },\n ];\n\n // Add data model updates\n if (data && Object.keys(data).length > 0) {\n const contents = objectToValueMaps(data);\n if (contents.length > 0) {\n messages.push({\n dataModelUpdate: { surfaceId, path: \"/\", contents },\n });\n }\n }\n\n processMessages(messages);\n }, [processMessages, surfaceId, root, components, data, styles]);\n\n return (\n <div className={className}>\n <A2UIRenderer surfaceId={surfaceId} />\n </div>\n );\n}\n\n/**\n * Converts a nested JavaScript object to the ValueMap[] format\n * expected by A2UI's dataModelUpdate message.\n */\nfunction objectToValueMaps(obj: Record<string, unknown>): Types.ValueMap[] {\n return Object.entries(obj).map(([key, value]) => valueToValueMap(key, value));\n}\n\n/**\n * Converts a single key-value pair to a ValueMap.\n */\nfunction valueToValueMap(key: string, value: unknown): Types.ValueMap {\n if (typeof value === \"string\") {\n return { key, valueString: value };\n }\n if (typeof value === \"number\") {\n return { key, valueNumber: value };\n }\n if (typeof value === \"boolean\") {\n return { key, valueBoolean: value };\n }\n if (value === null || value === undefined) {\n return { key };\n }\n if (Array.isArray(value)) {\n const valueMap = value.map((item, index) =>\n valueToValueMap(String(index), item),\n );\n return { key, valueMap };\n }\n if (typeof value === \"object\") {\n const valueMap = objectToValueMaps(value as Record<string, unknown>);\n return { key, valueMap };\n }\n return { key };\n}\n"],"mappings":"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"}
@@ -15,7 +15,7 @@ let react_jsx_runtime = require("react/jsx-runtime");
15
15
  const Image = (0, react.memo)(function Image({ node, surfaceId }) {
16
16
  const { theme, resolveString } = require_useA2UIComponent.useA2UIComponent(node, surfaceId);
17
17
  const props = node.properties;
18
- const url = resolveString(props.url);
18
+ const url = resolveString(props.url)?.replace("//via.placeholder.com/", "//placehold.co/");
19
19
  const usageHint = props.usageHint;
20
20
  const fit = props.fit ?? "fill";
21
21
  const classes = require_utils$1.mergeClassMaps(theme.components.Image.all, usageHint ? theme.components.Image[usageHint] : {});
@@ -1 +1 @@
1
- {"version":3,"file":"Image.cjs","names":["useA2UIComponent","mergeClassMaps","stylesToObject","classMapToString"],"sources":["../../../../src/react-renderer/components/content/Image.tsx"],"sourcesContent":["import { memo } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport type { A2UIComponentProps } from \"../../types\";\nimport { useA2UIComponent } from \"../../hooks/useA2UIComponent\";\nimport {\n classMapToString,\n stylesToObject,\n mergeClassMaps,\n} from \"../../lib/utils\";\n\ntype UsageHint =\n | \"icon\"\n | \"avatar\"\n | \"smallFeature\"\n | \"mediumFeature\"\n | \"largeFeature\"\n | \"header\";\ntype FitMode = \"contain\" | \"cover\" | \"fill\" | \"none\" | \"scale-down\";\n\n/**\n * Image component - renders an image from a URL with optional sizing and fit modes.\n *\n * Supports usageHint values: icon, avatar, smallFeature, mediumFeature, largeFeature, header\n * Supports fit values: contain, cover, fill, none, scale-down (maps to object-fit via CSS variable)\n */\nexport const Image = memo(function Image({\n node,\n surfaceId,\n}: A2UIComponentProps<Types.ImageNode>) {\n const { theme, resolveString } = useA2UIComponent(node, surfaceId);\n const props = node.properties;\n\n const url = resolveString(props.url);\n const usageHint = props.usageHint as UsageHint | undefined;\n const fit = (props.fit as FitMode) ?? \"fill\";\n\n // Get merged classes for section (matches Lit's Styles.merge)\n const classes = mergeClassMaps(\n theme.components.Image.all,\n usageHint ? theme.components.Image[usageHint] : {},\n );\n\n // Build style object with object-fit as CSS variable (matches Lit)\n const style: React.CSSProperties = {\n ...stylesToObject(theme.additionalStyles?.Image),\n \"--object-fit\": fit,\n } as React.CSSProperties;\n\n if (!url) {\n return null;\n }\n\n // Apply --weight CSS variable on root div (:host equivalent) for flex layouts\n const hostStyle: React.CSSProperties =\n node.weight !== undefined\n ? ({ \"--weight\": node.weight } as React.CSSProperties)\n : {};\n\n return (\n <div className=\"a2ui-image\" style={hostStyle}>\n <section className={classMapToString(classes)} style={style}>\n <img src={url} alt=\"\" />\n </section>\n </div>\n );\n});\n\nexport default Image;\n"],"mappings":";;;;;;;;;;;;;;AAyBA,MAAa,wBAAa,SAAS,MAAM,EACvC,MACA,aACsC;CACtC,MAAM,EAAE,OAAO,kBAAkBA,0CAAiB,MAAM,UAAU;CAClE,MAAM,QAAQ,KAAK;CAEnB,MAAM,MAAM,cAAc,MAAM,IAAI;CACpC,MAAM,YAAY,MAAM;CACxB,MAAM,MAAO,MAAM,OAAmB;CAGtC,MAAM,UAAUC,+BACd,MAAM,WAAW,MAAM,KACvB,YAAY,MAAM,WAAW,MAAM,aAAa,EAAE,CACnD;CAGD,MAAM,QAA6B;EACjC,GAAGC,6BAAe,MAAM,kBAAkB,MAAM;EAChD,gBAAgB;EACjB;AAED,KAAI,CAAC,IACH,QAAO;AAST,QACE,2CAAC;EAAI,WAAU;EAAa,OAL5B,KAAK,WAAW,SACX,EAAE,YAAY,KAAK,QAAQ,GAC5B,EAAE;YAIJ,2CAAC;GAAQ,WAAWC,+BAAiB,QAAQ;GAAS;aACpD,2CAAC;IAAI,KAAK;IAAK,KAAI;KAAK;IAChB;GACN;EAER"}
1
+ {"version":3,"file":"Image.cjs","names":["useA2UIComponent","mergeClassMaps","stylesToObject","classMapToString"],"sources":["../../../../src/react-renderer/components/content/Image.tsx"],"sourcesContent":["import { memo } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport type { A2UIComponentProps } from \"../../types\";\nimport { useA2UIComponent } from \"../../hooks/useA2UIComponent\";\nimport {\n classMapToString,\n stylesToObject,\n mergeClassMaps,\n} from \"../../lib/utils\";\n\ntype UsageHint =\n | \"icon\"\n | \"avatar\"\n | \"smallFeature\"\n | \"mediumFeature\"\n | \"largeFeature\"\n | \"header\";\ntype FitMode = \"contain\" | \"cover\" | \"fill\" | \"none\" | \"scale-down\";\n\n/**\n * Image component - renders an image from a URL with optional sizing and fit modes.\n *\n * Supports usageHint values: icon, avatar, smallFeature, mediumFeature, largeFeature, header\n * Supports fit values: contain, cover, fill, none, scale-down (maps to object-fit via CSS variable)\n */\nexport const Image = memo(function Image({\n node,\n surfaceId,\n}: A2UIComponentProps<Types.ImageNode>) {\n const { theme, resolveString } = useA2UIComponent(node, surfaceId);\n const props = node.properties;\n\n const rawUrl = resolveString(props.url);\n // Rewrite known-dead placeholder services to working alternatives\n const url = rawUrl?.replace(\"//via.placeholder.com/\", \"//placehold.co/\");\n const usageHint = props.usageHint as UsageHint | undefined;\n const fit = (props.fit as FitMode) ?? \"fill\";\n\n // Get merged classes for section (matches Lit's Styles.merge)\n const classes = mergeClassMaps(\n theme.components.Image.all,\n usageHint ? theme.components.Image[usageHint] : {},\n );\n\n // Build style object with object-fit as CSS variable (matches Lit)\n const style: React.CSSProperties = {\n ...stylesToObject(theme.additionalStyles?.Image),\n \"--object-fit\": fit,\n } as React.CSSProperties;\n\n if (!url) {\n return null;\n }\n\n // Apply --weight CSS variable on root div (:host equivalent) for flex layouts\n const hostStyle: React.CSSProperties =\n node.weight !== undefined\n ? ({ \"--weight\": node.weight } as React.CSSProperties)\n : {};\n\n return (\n <div className=\"a2ui-image\" style={hostStyle}>\n <section className={classMapToString(classes)} style={style}>\n <img src={url} alt=\"\" />\n </section>\n </div>\n );\n});\n\nexport default Image;\n"],"mappings":";;;;;;;;;;;;;;AAyBA,MAAa,wBAAa,SAAS,MAAM,EACvC,MACA,aACsC;CACtC,MAAM,EAAE,OAAO,kBAAkBA,0CAAiB,MAAM,UAAU;CAClE,MAAM,QAAQ,KAAK;CAInB,MAAM,MAFS,cAAc,MAAM,IAAI,EAEnB,QAAQ,0BAA0B,kBAAkB;CACxE,MAAM,YAAY,MAAM;CACxB,MAAM,MAAO,MAAM,OAAmB;CAGtC,MAAM,UAAUC,+BACd,MAAM,WAAW,MAAM,KACvB,YAAY,MAAM,WAAW,MAAM,aAAa,EAAE,CACnD;CAGD,MAAM,QAA6B;EACjC,GAAGC,6BAAe,MAAM,kBAAkB,MAAM;EAChD,gBAAgB;EACjB;AAED,KAAI,CAAC,IACH,QAAO;AAST,QACE,2CAAC;EAAI,WAAU;EAAa,OAL5B,KAAK,WAAW,SACX,EAAE,YAAY,KAAK,QAAQ,GAC5B,EAAE;YAIJ,2CAAC;GAAQ,WAAWC,+BAAiB,QAAQ;GAAS;aACpD,2CAAC;IAAI,KAAK;IAAK,KAAI;KAAK;IAChB;GACN;EAER"}
@@ -14,7 +14,7 @@ import { jsx } from "react/jsx-runtime";
14
14
  const Image = memo(function Image({ node, surfaceId }) {
15
15
  const { theme, resolveString } = useA2UIComponent(node, surfaceId);
16
16
  const props = node.properties;
17
- const url = resolveString(props.url);
17
+ const url = resolveString(props.url)?.replace("//via.placeholder.com/", "//placehold.co/");
18
18
  const usageHint = props.usageHint;
19
19
  const fit = props.fit ?? "fill";
20
20
  const classes = mergeClassMaps(theme.components.Image.all, usageHint ? theme.components.Image[usageHint] : {});
@@ -1 +1 @@
1
- {"version":3,"file":"Image.mjs","names":[],"sources":["../../../../src/react-renderer/components/content/Image.tsx"],"sourcesContent":["import { memo } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport type { A2UIComponentProps } from \"../../types\";\nimport { useA2UIComponent } from \"../../hooks/useA2UIComponent\";\nimport {\n classMapToString,\n stylesToObject,\n mergeClassMaps,\n} from \"../../lib/utils\";\n\ntype UsageHint =\n | \"icon\"\n | \"avatar\"\n | \"smallFeature\"\n | \"mediumFeature\"\n | \"largeFeature\"\n | \"header\";\ntype FitMode = \"contain\" | \"cover\" | \"fill\" | \"none\" | \"scale-down\";\n\n/**\n * Image component - renders an image from a URL with optional sizing and fit modes.\n *\n * Supports usageHint values: icon, avatar, smallFeature, mediumFeature, largeFeature, header\n * Supports fit values: contain, cover, fill, none, scale-down (maps to object-fit via CSS variable)\n */\nexport const Image = memo(function Image({\n node,\n surfaceId,\n}: A2UIComponentProps<Types.ImageNode>) {\n const { theme, resolveString } = useA2UIComponent(node, surfaceId);\n const props = node.properties;\n\n const url = resolveString(props.url);\n const usageHint = props.usageHint as UsageHint | undefined;\n const fit = (props.fit as FitMode) ?? \"fill\";\n\n // Get merged classes for section (matches Lit's Styles.merge)\n const classes = mergeClassMaps(\n theme.components.Image.all,\n usageHint ? theme.components.Image[usageHint] : {},\n );\n\n // Build style object with object-fit as CSS variable (matches Lit)\n const style: React.CSSProperties = {\n ...stylesToObject(theme.additionalStyles?.Image),\n \"--object-fit\": fit,\n } as React.CSSProperties;\n\n if (!url) {\n return null;\n }\n\n // Apply --weight CSS variable on root div (:host equivalent) for flex layouts\n const hostStyle: React.CSSProperties =\n node.weight !== undefined\n ? ({ \"--weight\": node.weight } as React.CSSProperties)\n : {};\n\n return (\n <div className=\"a2ui-image\" style={hostStyle}>\n <section className={classMapToString(classes)} style={style}>\n <img src={url} alt=\"\" />\n </section>\n </div>\n );\n});\n\nexport default Image;\n"],"mappings":";;;;;;;;;;;;;AAyBA,MAAa,QAAQ,KAAK,SAAS,MAAM,EACvC,MACA,aACsC;CACtC,MAAM,EAAE,OAAO,kBAAkB,iBAAiB,MAAM,UAAU;CAClE,MAAM,QAAQ,KAAK;CAEnB,MAAM,MAAM,cAAc,MAAM,IAAI;CACpC,MAAM,YAAY,MAAM;CACxB,MAAM,MAAO,MAAM,OAAmB;CAGtC,MAAM,UAAU,eACd,MAAM,WAAW,MAAM,KACvB,YAAY,MAAM,WAAW,MAAM,aAAa,EAAE,CACnD;CAGD,MAAM,QAA6B;EACjC,GAAG,eAAe,MAAM,kBAAkB,MAAM;EAChD,gBAAgB;EACjB;AAED,KAAI,CAAC,IACH,QAAO;AAST,QACE,oBAAC;EAAI,WAAU;EAAa,OAL5B,KAAK,WAAW,SACX,EAAE,YAAY,KAAK,QAAQ,GAC5B,EAAE;YAIJ,oBAAC;GAAQ,WAAW,iBAAiB,QAAQ;GAAS;aACpD,oBAAC;IAAI,KAAK;IAAK,KAAI;KAAK;IAChB;GACN;EAER"}
1
+ {"version":3,"file":"Image.mjs","names":[],"sources":["../../../../src/react-renderer/components/content/Image.tsx"],"sourcesContent":["import { memo } from \"react\";\nimport type { Types } from \"@a2ui/lit/0.8\";\nimport type { A2UIComponentProps } from \"../../types\";\nimport { useA2UIComponent } from \"../../hooks/useA2UIComponent\";\nimport {\n classMapToString,\n stylesToObject,\n mergeClassMaps,\n} from \"../../lib/utils\";\n\ntype UsageHint =\n | \"icon\"\n | \"avatar\"\n | \"smallFeature\"\n | \"mediumFeature\"\n | \"largeFeature\"\n | \"header\";\ntype FitMode = \"contain\" | \"cover\" | \"fill\" | \"none\" | \"scale-down\";\n\n/**\n * Image component - renders an image from a URL with optional sizing and fit modes.\n *\n * Supports usageHint values: icon, avatar, smallFeature, mediumFeature, largeFeature, header\n * Supports fit values: contain, cover, fill, none, scale-down (maps to object-fit via CSS variable)\n */\nexport const Image = memo(function Image({\n node,\n surfaceId,\n}: A2UIComponentProps<Types.ImageNode>) {\n const { theme, resolveString } = useA2UIComponent(node, surfaceId);\n const props = node.properties;\n\n const rawUrl = resolveString(props.url);\n // Rewrite known-dead placeholder services to working alternatives\n const url = rawUrl?.replace(\"//via.placeholder.com/\", \"//placehold.co/\");\n const usageHint = props.usageHint as UsageHint | undefined;\n const fit = (props.fit as FitMode) ?? \"fill\";\n\n // Get merged classes for section (matches Lit's Styles.merge)\n const classes = mergeClassMaps(\n theme.components.Image.all,\n usageHint ? theme.components.Image[usageHint] : {},\n );\n\n // Build style object with object-fit as CSS variable (matches Lit)\n const style: React.CSSProperties = {\n ...stylesToObject(theme.additionalStyles?.Image),\n \"--object-fit\": fit,\n } as React.CSSProperties;\n\n if (!url) {\n return null;\n }\n\n // Apply --weight CSS variable on root div (:host equivalent) for flex layouts\n const hostStyle: React.CSSProperties =\n node.weight !== undefined\n ? ({ \"--weight\": node.weight } as React.CSSProperties)\n : {};\n\n return (\n <div className=\"a2ui-image\" style={hostStyle}>\n <section className={classMapToString(classes)} style={style}>\n <img src={url} alt=\"\" />\n </section>\n </div>\n );\n});\n\nexport default Image;\n"],"mappings":";;;;;;;;;;;;;AAyBA,MAAa,QAAQ,KAAK,SAAS,MAAM,EACvC,MACA,aACsC;CACtC,MAAM,EAAE,OAAO,kBAAkB,iBAAiB,MAAM,UAAU;CAClE,MAAM,QAAQ,KAAK;CAInB,MAAM,MAFS,cAAc,MAAM,IAAI,EAEnB,QAAQ,0BAA0B,kBAAkB;CACxE,MAAM,YAAY,MAAM;CACxB,MAAM,MAAO,MAAM,OAAmB;CAGtC,MAAM,UAAU,eACd,MAAM,WAAW,MAAM,KACvB,YAAY,MAAM,WAAW,MAAM,aAAa,EAAE,CACnD;CAGD,MAAM,QAA6B;EACjC,GAAG,eAAe,MAAM,kBAAkB,MAAM;EAChD,gBAAgB;EACjB;AAED,KAAI,CAAC,IACH,QAAO;AAST,QACE,oBAAC;EAAI,WAAU;EAAa,OAL5B,KAAK,WAAW,SACX,EAAE,YAAY,KAAK,QAAQ,GAC5B,EAAE;YAIJ,oBAAC;GAAQ,WAAW,iBAAiB,QAAQ;GAAS;aACpD,oBAAC;IAAI,KAAK;IAAK,KAAI;KAAK;IAChB;GACN;EAER"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@copilotkit/a2ui-renderer",
3
3
  "private": false,
4
- "version": "1.52.2-next.1",
4
+ "version": "1.52.2-next.3",
5
5
  "description": "A2UI Renderer for CopilotKit - render A2UI surfaces in React applications",
6
6
  "homepage": "https://github.com/CopilotKit/CopilotKit",
7
7
  "repository": {
@@ -44,7 +44,7 @@
44
44
  "peerDependencies": {
45
45
  "react": "^18 || ^19 || ^19.0.0-rc",
46
46
  "react-dom": "^18 || ^19 || ^19.0.0-rc",
47
- "@copilotkit/react-core": "1.52.2-next.1"
47
+ "@copilotkit/react-core": "1.52.2-next.3"
48
48
  },
49
49
  "devDependencies": {
50
50
  "@testing-library/react": "^16.0.0",