diff --git a/renderers/react/src/components/content/Divider.tsx b/renderers/react/src/components/content/Divider.tsx
index 0c7e99b41..010e7f0d4 100644
--- a/renderers/react/src/components/content/Divider.tsx
+++ b/renderers/react/src/components/content/Divider.tsx
@@ -1,8 +1,24 @@
-import { memo } from 'react';
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {memo} from 'react';
import type * as Types from '@a2ui/web_core/types/types';
-import type { A2UIComponentProps } from '../../types';
-import { useA2UIComponent } from '../../hooks/useA2UIComponent';
-import { classMapToString, stylesToObject } from '../../lib/utils';
+import type {A2UIComponentProps} from '../../types';
+import {useA2UIComponent} from '../../hooks/useA2UIComponent';
+import {classMapToString, stylesToObject} from '../../lib/utils';
/**
* Divider component - renders a visual separator line.
@@ -12,13 +28,15 @@ import { classMapToString, stylesToObject } from '../../lib/utils';
* ← internal element
*
diff --git a/renderers/react/src/components/content/Icon.tsx b/renderers/react/src/components/content/Icon.tsx
index 4dd250061..be8a607ee 100644
--- a/renderers/react/src/components/content/Icon.tsx
+++ b/renderers/react/src/components/content/Icon.tsx
@@ -1,8 +1,24 @@
-import { memo } from 'react';
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {memo} from 'react';
import type * as Types from '@a2ui/web_core/types/types';
-import type { A2UIComponentProps } from '../../types';
-import { useA2UIComponent } from '../../hooks/useA2UIComponent';
-import { classMapToString, stylesToObject } from '../../lib/utils';
+import type {A2UIComponentProps} from '../../types';
+import {useA2UIComponent} from '../../hooks/useA2UIComponent';
+import {classMapToString, stylesToObject} from '../../lib/utils';
/**
* Convert camelCase to snake_case for Material Symbols font.
@@ -24,8 +40,8 @@ function toSnakeCase(str: string): string {
*
* ```
*/
-export const Icon = memo(function Icon({ node, surfaceId }: A2UIComponentProps) {
- const { theme, resolveString } = useA2UIComponent(node, surfaceId);
+export const Icon = memo(function Icon({node, surfaceId}: A2UIComponentProps) {
+ const {theme, resolveString} = useA2UIComponent(node, surfaceId);
const props = node.properties;
const iconName = resolveString(props.name);
@@ -38,9 +54,8 @@ export const Icon = memo(function Icon({ node, surfaceId }: A2UIComponentProps
diff --git a/renderers/react/src/components/content/Image.tsx b/renderers/react/src/components/content/Image.tsx
index e6597e38a..95e1b8de7 100644
--- a/renderers/react/src/components/content/Image.tsx
+++ b/renderers/react/src/components/content/Image.tsx
@@ -1,8 +1,24 @@
-import { memo } from 'react';
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {memo} from 'react';
import type * as Types from '@a2ui/web_core/types/types';
-import type { A2UIComponentProps } from '../../types';
-import { useA2UIComponent } from '../../hooks/useA2UIComponent';
-import { classMapToString, stylesToObject, mergeClassMaps } from '../../lib/utils';
+import type {A2UIComponentProps} from '../../types';
+import {useA2UIComponent} from '../../hooks/useA2UIComponent';
+import {classMapToString, stylesToObject, mergeClassMaps} from '../../lib/utils';
type UsageHint = 'icon' | 'avatar' | 'smallFeature' | 'mediumFeature' | 'largeFeature' | 'header';
type FitMode = 'contain' | 'cover' | 'fill' | 'none' | 'scale-down';
@@ -13,8 +29,8 @@ type FitMode = 'contain' | 'cover' | 'fill' | 'none' | 'scale-down';
* Supports usageHint values: icon, avatar, smallFeature, mediumFeature, largeFeature, header
* Supports fit values: contain, cover, fill, none, scale-down (maps to object-fit via CSS variable)
*/
-export const Image = memo(function Image({ node, surfaceId }: A2UIComponentProps) {
- const { theme, resolveString } = useA2UIComponent(node, surfaceId);
+export const Image = memo(function Image({node, surfaceId}: A2UIComponentProps) {
+ const {theme, resolveString} = useA2UIComponent(node, surfaceId);
const props = node.properties;
const url = resolveString(props.url);
@@ -39,16 +55,12 @@ export const Image = memo(function Image({ node, surfaceId }: A2UIComponentProps
}
// Apply --weight CSS variable on root div (:host equivalent) for flex layouts
- const hostStyle: React.CSSProperties = node.weight !== undefined
- ? { '--weight': node.weight } as React.CSSProperties
- : {};
+ const hostStyle: React.CSSProperties =
+ node.weight !== undefined ? ({'--weight': node.weight} as React.CSSProperties) : {};
return (
-
+
diff --git a/renderers/react/src/components/content/Text.tsx b/renderers/react/src/components/content/Text.tsx
index df872e31f..dc5da434c 100644
--- a/renderers/react/src/components/content/Text.tsx
+++ b/renderers/react/src/components/content/Text.tsx
@@ -1,8 +1,24 @@
-import { useMemo, memo } from 'react';
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {useMemo, memo} from 'react';
import type * as Types from '@a2ui/web_core/types/types';
-import type { A2UIComponentProps } from '../../types';
-import { useA2UIComponent } from '../../hooks/useA2UIComponent';
-import { classMapToString, stylesToObject, mergeClassMaps } from '../../lib/utils';
+import type {A2UIComponentProps} from '../../types';
+import {useA2UIComponent} from '../../hooks/useA2UIComponent';
+import {classMapToString, stylesToObject, mergeClassMaps} from '../../lib/utils';
import MarkdownIt from 'markdown-it';
type UsageHint = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'caption' | 'body';
@@ -41,8 +57,12 @@ const markdownRenderer = new MarkdownIt();
*/
const TAG_TO_TOKEN: Record = {
p: 'paragraph',
- h1: 'heading', h2: 'heading', h3: 'heading',
- h4: 'heading', h5: 'heading', h6: 'heading',
+ h1: 'heading',
+ h2: 'heading',
+ h3: 'heading',
+ h4: 'heading',
+ h5: 'heading',
+ h6: 'heading',
ul: 'bullet_list',
ol: 'ordered_list',
li: 'list_item',
@@ -53,7 +73,9 @@ const TAG_TO_TOKEN: Record = {
function toClassArray(classes: string[] | Record): string[] {
if (Array.isArray(classes)) return classes;
- return Object.entries(classes).filter(([, v]) => v).map(([k]) => k);
+ return Object.entries(classes)
+ .filter(([, v]) => v)
+ .map(([k]) => k);
}
/**
@@ -99,7 +121,6 @@ function renderWithTheme(text: string, markdownTheme: Types.Theme['markdown']):
return html;
}
-
/**
* Text component - renders text content with markdown support.
*
@@ -123,8 +144,8 @@ function renderWithTheme(text: string, markdownTheme: Types.Theme['markdown']):
*
* Note: Raw HTML is disabled for security.
*/
-export const Text = memo(function Text({ node, surfaceId }: A2UIComponentProps) {
- const { theme, resolveString } = useA2UIComponent(node, surfaceId);
+export const Text = memo(function Text({node, surfaceId}: A2UIComponentProps) {
+ const {theme, resolveString} = useA2UIComponent(node, surfaceId);
const props = node.properties;
const textValue = resolveString(props.text);
@@ -179,7 +200,7 @@ export const Text = memo(function Text({ node, surfaceId }: A2UIComponentProps
diff --git a/renderers/react/src/components/content/Video.tsx b/renderers/react/src/components/content/Video.tsx
index 121bda89f..cf3b674ef 100644
--- a/renderers/react/src/components/content/Video.tsx
+++ b/renderers/react/src/components/content/Video.tsx
@@ -1,21 +1,35 @@
-import { memo } from 'react';
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {memo} from 'react';
import type * as Types from '@a2ui/web_core/types/types';
-import type { A2UIComponentProps } from '../../types';
-import { useA2UIComponent } from '../../hooks/useA2UIComponent';
-import { classMapToString, stylesToObject } from '../../lib/utils';
+import type {A2UIComponentProps} from '../../types';
+import {useA2UIComponent} from '../../hooks/useA2UIComponent';
+import {classMapToString, stylesToObject} from '../../lib/utils';
/**
* Check if a URL is a YouTube URL and extract the video ID.
*/
function getYouTubeVideoId(url: string): string | null {
- const patterns = [
- /(?:youtube\.com\/watch\?v=|youtu\.be\/|youtube\.com\/embed\/)([^&\s?]+)/,
- ];
+ const patterns = [/(?:youtube\.com\/watch\?v=|youtu\.be\/|youtube\.com\/embed\/)([^&\s?]+)/];
for (const pattern of patterns) {
const match = url.match(pattern);
if (match && match.length > 1) {
// Non-null assertion is safe here since we checked match.length > 1
-
+
return match[1]!;
}
}
@@ -27,8 +41,8 @@ function getYouTubeVideoId(url: string): string | null {
*
* Supports regular video URLs and YouTube URLs (renders as embedded iframe).
*/
-export const Video = memo(function Video({ node, surfaceId }: A2UIComponentProps) {
- const { theme, resolveString } = useA2UIComponent(node, surfaceId);
+export const Video = memo(function Video({node, surfaceId}: A2UIComponentProps) {
+ const {theme, resolveString} = useA2UIComponent(node, surfaceId);
const props = node.properties;
const url = resolveString(props.url);
@@ -40,9 +54,8 @@ export const Video = memo(function Video({ node, surfaceId }: A2UIComponentProps
const youtubeId = getYouTubeVideoId(url);
// Apply --weight CSS variable on root div (:host equivalent) for flex layouts
- const hostStyle: React.CSSProperties = node.weight !== undefined
- ? { '--weight': node.weight } as React.CSSProperties
- : {};
+ const hostStyle: React.CSSProperties =
+ node.weight !== undefined ? ({'--weight': node.weight} as React.CSSProperties) : {};
return (
@@ -56,7 +69,7 @@ export const Video = memo(function Video({ node, surfaceId }: A2UIComponentProps
title="YouTube video player"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
- style={{ border: 'none', width: '100%', aspectRatio: '16/9' }}
+ style={{border: 'none', width: '100%', aspectRatio: '16/9'}}
/>
) : (
diff --git a/renderers/react/src/components/content/index.ts b/renderers/react/src/components/content/index.ts
index 4f8989e24..bf36c0952 100644
--- a/renderers/react/src/components/content/index.ts
+++ b/renderers/react/src/components/content/index.ts
@@ -1,6 +1,22 @@
-export { Text } from './Text';
-export { Image } from './Image';
-export { Icon } from './Icon';
-export { Divider } from './Divider';
-export { Video } from './Video';
-export { AudioPlayer } from './AudioPlayer';
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export {Text} from './Text';
+export {Image} from './Image';
+export {Icon} from './Icon';
+export {Divider} from './Divider';
+export {Video} from './Video';
+export {AudioPlayer} from './AudioPlayer';
diff --git a/renderers/react/src/components/interactive/Button.tsx b/renderers/react/src/components/interactive/Button.tsx
index 57f5f574f..50f47214f 100644
--- a/renderers/react/src/components/interactive/Button.tsx
+++ b/renderers/react/src/components/interactive/Button.tsx
@@ -1,9 +1,25 @@
-import { useCallback, memo } from 'react';
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {useCallback, memo} from 'react';
import type * as Types from '@a2ui/web_core/types/types';
-import type { A2UIComponentProps } from '../../types';
-import { useA2UIComponent } from '../../hooks/useA2UIComponent';
-import { classMapToString, stylesToObject } from '../../lib/utils';
-import { ComponentNode } from '../../core/ComponentNode';
+import type {A2UIComponentProps} from '../../types';
+import {useA2UIComponent} from '../../hooks/useA2UIComponent';
+import {classMapToString, stylesToObject} from '../../lib/utils';
+import {ComponentNode} from '../../core/ComponentNode';
/**
* Button component - a clickable element that triggers an action.
@@ -11,8 +27,11 @@ import { ComponentNode } from '../../core/ComponentNode';
* Contains a child component (usually Text or Icon) and dispatches
* a user action when clicked.
*/
-export const Button = memo(function Button({ node, surfaceId }: A2UIComponentProps) {
- const { theme, sendAction } = useA2UIComponent(node, surfaceId);
+export const Button = memo(function Button({
+ node,
+ surfaceId,
+}: A2UIComponentProps) {
+ const {theme, sendAction} = useA2UIComponent(node, surfaceId);
const props = node.properties;
const handleClick = useCallback(() => {
@@ -22,9 +41,8 @@ export const Button = memo(function Button({ node, surfaceId }: A2UIComponentPro
}, [props.action, sendAction]);
// Apply --weight CSS variable on root div (:host equivalent) for flex layouts
- const hostStyle: React.CSSProperties = node.weight !== undefined
- ? { '--weight': node.weight } as React.CSSProperties
- : {};
+ const hostStyle: React.CSSProperties =
+ node.weight !== undefined ? ({'--weight': node.weight} as React.CSSProperties) : {};
return (
diff --git a/renderers/react/src/components/interactive/CheckBox.tsx b/renderers/react/src/components/interactive/CheckBox.tsx
index 89bf64174..26ec15f24 100644
--- a/renderers/react/src/components/interactive/CheckBox.tsx
+++ b/renderers/react/src/components/interactive/CheckBox.tsx
@@ -1,16 +1,35 @@
-import { useState, useCallback, useEffect, useId, memo } from 'react';
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {useState, useCallback, useEffect, useId, memo} from 'react';
import type * as Types from '@a2ui/web_core/types/types';
-import type { A2UIComponentProps } from '../../types';
-import { useA2UIComponent } from '../../hooks/useA2UIComponent';
-import { classMapToString, stylesToObject } from '../../lib/utils';
+import type {A2UIComponentProps} from '../../types';
+import {useA2UIComponent} from '../../hooks/useA2UIComponent';
+import {classMapToString, stylesToObject} from '../../lib/utils';
/**
* CheckBox component - a boolean toggle with a label.
*
* Supports two-way data binding for the checked state.
*/
-export const CheckBox = memo(function CheckBox({ node, surfaceId }: A2UIComponentProps) {
- const { theme, resolveString, resolveBoolean, setValue, getValue } = useA2UIComponent(
+export const CheckBox = memo(function CheckBox({
+ node,
+ surfaceId,
+}: A2UIComponentProps) {
+ const {theme, resolveString, resolveBoolean, setValue, getValue} = useA2UIComponent(
node,
surfaceId
);
@@ -62,9 +81,8 @@ export const CheckBox = memo(function CheckBox({ node, surfaceId }: A2UIComponen
//
// Apply --weight CSS variable on root div (:host equivalent) for flex layouts
- const hostStyle: React.CSSProperties = node.weight !== undefined
- ? { '--weight': node.weight } as React.CSSProperties
- : {};
+ const hostStyle: React.CSSProperties =
+ node.weight !== undefined ? ({'--weight': node.weight} as React.CSSProperties) : {};
return (
// Apply --weight CSS variable on root div (:host equivalent) for flex layouts
- const hostStyle: React.CSSProperties = node.weight !== undefined
- ? { '--weight': node.weight } as React.CSSProperties
- : {};
+ const hostStyle: React.CSSProperties =
+ node.weight !== undefined ? ({'--weight': node.weight} as React.CSSProperties) : {};
return (
-
-
+
+
{label}
-
- {value}
-
+ {value}
);
diff --git a/renderers/react/src/components/interactive/TextField.tsx b/renderers/react/src/components/interactive/TextField.tsx
index 6b667b602..d99727368 100644
--- a/renderers/react/src/components/interactive/TextField.tsx
+++ b/renderers/react/src/components/interactive/TextField.tsx
@@ -1,8 +1,24 @@
-import { useState, useCallback, useEffect, useId, memo } from 'react';
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {useState, useCallback, useEffect, useId, memo} from 'react';
import type * as Types from '@a2ui/web_core/types/types';
-import type { A2UIComponentProps } from '../../types';
-import { useA2UIComponent } from '../../hooks/useA2UIComponent';
-import { classMapToString, stylesToObject } from '../../lib/utils';
+import type {A2UIComponentProps} from '../../types';
+import {useA2UIComponent} from '../../hooks/useA2UIComponent';
+import {classMapToString, stylesToObject} from '../../lib/utils';
type TextFieldType = 'shortText' | 'longText' | 'number' | 'date';
@@ -11,8 +27,11 @@ type TextFieldType = 'shortText' | 'longText' | 'number' | 'date';
*
* Supports various input types and two-way data binding.
*/
-export const TextField = memo(function TextField({ node, surfaceId }: A2UIComponentProps) {
- const { theme, resolveString, setValue, getValue } = useA2UIComponent(node, surfaceId);
+export const TextField = memo(function TextField({
+ node,
+ surfaceId,
+}: A2UIComponentProps) {
+ const {theme, resolveString, setValue, getValue} = useA2UIComponent(node, surfaceId);
const props = node.properties;
const id = useId();
@@ -54,12 +73,7 @@ export const TextField = memo(function TextField({ node, surfaceId }: A2UICompon
[validationRegexp, textPath, setValue]
);
- const inputType =
- fieldType === 'number'
- ? 'number'
- : fieldType === 'date'
- ? 'date'
- : 'text';
+ const inputType = fieldType === 'number' ? 'number' : fieldType === 'date' ? 'date' : 'text';
const isTextArea = fieldType === 'longText';
// Structure mirrors Lit's TextField component:
@@ -71,18 +85,14 @@ export const TextField = memo(function TextField({ node, surfaceId }: A2UICompon
//
// Apply --weight CSS variable on root div (:host equivalent) for flex layouts
- const hostStyle: React.CSSProperties = node.weight !== undefined
- ? { '--weight': node.weight } as React.CSSProperties
- : {};
+ const hostStyle: React.CSSProperties =
+ node.weight !== undefined ? ({'--weight': node.weight} as React.CSSProperties) : {};
return (
{label && (
-
+
{label}
)}
diff --git a/renderers/react/src/components/interactive/index.ts b/renderers/react/src/components/interactive/index.ts
index 9c5c00f6b..6065306e0 100644
--- a/renderers/react/src/components/interactive/index.ts
+++ b/renderers/react/src/components/interactive/index.ts
@@ -1,6 +1,22 @@
-export { Button } from './Button';
-export { TextField } from './TextField';
-export { CheckBox } from './CheckBox';
-export { Slider } from './Slider';
-export { DateTimeInput } from './DateTimeInput';
-export { MultipleChoice } from './MultipleChoice';
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export {Button} from './Button';
+export {TextField} from './TextField';
+export {CheckBox} from './CheckBox';
+export {Slider} from './Slider';
+export {DateTimeInput} from './DateTimeInput';
+export {MultipleChoice} from './MultipleChoice';
diff --git a/renderers/react/src/components/layout/Card.tsx b/renderers/react/src/components/layout/Card.tsx
index b159acb05..2215fb956 100644
--- a/renderers/react/src/components/layout/Card.tsx
+++ b/renderers/react/src/components/layout/Card.tsx
@@ -1,9 +1,25 @@
-import { memo } from 'react';
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {memo} from 'react';
import type * as Types from '@a2ui/web_core/types/types';
-import type { A2UIComponentProps } from '../../types';
-import { useA2UIComponent } from '../../hooks/useA2UIComponent';
-import { classMapToString, stylesToObject } from '../../lib/utils';
-import { ComponentNode } from '../../core/ComponentNode';
+import type {A2UIComponentProps} from '../../types';
+import {useA2UIComponent} from '../../hooks/useA2UIComponent';
+import {classMapToString, stylesToObject} from '../../lib/utils';
+import {ComponentNode} from '../../core/ComponentNode';
/**
* Card component - a container that visually groups content.
@@ -17,8 +33,8 @@ import { ComponentNode } from '../../core/ComponentNode';
*
* All styles come from componentSpecificStyles CSS, no inline styles needed.
*/
-export const Card = memo(function Card({ node, surfaceId }: A2UIComponentProps) {
- const { theme } = useA2UIComponent(node, surfaceId);
+export const Card = memo(function Card({node, surfaceId}: A2UIComponentProps) {
+ const {theme} = useA2UIComponent(node, surfaceId);
const props = node.properties;
// Card can have either a single child or multiple children
@@ -26,9 +42,8 @@ export const Card = memo(function Card({ node, surfaceId }: A2UIComponentProps
@@ -37,12 +52,14 @@ export const Card = memo(function Card({ node, surfaceId }: A2UIComponentProps
{children.map((child, index) => {
- const childId = typeof child === 'object' && child !== null && 'id' in child
- ? (child as Types.AnyComponentNode).id
- : `child-${index}`;
- const childNode = typeof child === 'object' && child !== null && 'type' in child
- ? (child as Types.AnyComponentNode)
- : null;
+ const childId =
+ typeof child === 'object' && child !== null && 'id' in child
+ ? (child as Types.AnyComponentNode).id
+ : `child-${index}`;
+ const childNode =
+ typeof child === 'object' && child !== null && 'type' in child
+ ? (child as Types.AnyComponentNode)
+ : null;
return ;
})}
diff --git a/renderers/react/src/components/layout/Column.tsx b/renderers/react/src/components/layout/Column.tsx
index f18fd968d..833c00717 100644
--- a/renderers/react/src/components/layout/Column.tsx
+++ b/renderers/react/src/components/layout/Column.tsx
@@ -1,17 +1,36 @@
-import { memo } from 'react';
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {memo} from 'react';
import type * as Types from '@a2ui/web_core/types/types';
-import type { A2UIComponentProps } from '../../types';
-import { useA2UIComponent } from '../../hooks/useA2UIComponent';
-import { classMapToString, stylesToObject } from '../../lib/utils';
-import { ComponentNode } from '../../core/ComponentNode';
+import type {A2UIComponentProps} from '../../types';
+import {useA2UIComponent} from '../../hooks/useA2UIComponent';
+import {classMapToString, stylesToObject} from '../../lib/utils';
+import {ComponentNode} from '../../core/ComponentNode';
/**
* Column component - arranges children vertically using flexbox.
*
* Supports distribution (justify-content) and alignment (align-items) properties.
*/
-export const Column = memo(function Column({ node, surfaceId }: A2UIComponentProps) {
- const { theme } = useA2UIComponent(node, surfaceId);
+export const Column = memo(function Column({
+ node,
+ surfaceId,
+}: A2UIComponentProps) {
+ const {theme} = useA2UIComponent(node, surfaceId);
const props = node.properties;
// Match Lit's default values
@@ -21,23 +40,29 @@ export const Column = memo(function Column({ node, surfaceId }: A2UIComponentPro
const children = Array.isArray(props.children) ? props.children : [];
// Apply --weight CSS variable on root div (:host equivalent) for flex layouts
- const hostStyle: React.CSSProperties = node.weight !== undefined
- ? { '--weight': node.weight } as React.CSSProperties
- : {};
+ const hostStyle: React.CSSProperties =
+ node.weight !== undefined ? ({'--weight': node.weight} as React.CSSProperties) : {};
return (
-
+
{children.map((child, index) => {
- const childId = typeof child === 'object' && child !== null && 'id' in child
- ? (child as Types.AnyComponentNode).id
- : `child-${index}`;
- const childNode = typeof child === 'object' && child !== null && 'type' in child
- ? (child as Types.AnyComponentNode)
- : null;
+ const childId =
+ typeof child === 'object' && child !== null && 'id' in child
+ ? (child as Types.AnyComponentNode).id
+ : `child-${index}`;
+ const childNode =
+ typeof child === 'object' && child !== null && 'type' in child
+ ? (child as Types.AnyComponentNode)
+ : null;
return ;
})}
diff --git a/renderers/react/src/components/layout/List.tsx b/renderers/react/src/components/layout/List.tsx
index 9c9c92b3e..306ff32df 100644
--- a/renderers/react/src/components/layout/List.tsx
+++ b/renderers/react/src/components/layout/List.tsx
@@ -1,17 +1,33 @@
-import { memo } from 'react';
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {memo} from 'react';
import type * as Types from '@a2ui/web_core/types/types';
-import type { A2UIComponentProps } from '../../types';
-import { useA2UIComponent } from '../../hooks/useA2UIComponent';
-import { classMapToString, stylesToObject } from '../../lib/utils';
-import { ComponentNode } from '../../core/ComponentNode';
+import type {A2UIComponentProps} from '../../types';
+import {useA2UIComponent} from '../../hooks/useA2UIComponent';
+import {classMapToString, stylesToObject} from '../../lib/utils';
+import {ComponentNode} from '../../core/ComponentNode';
/**
* List component - renders a scrollable list of items.
*
* Supports direction (vertical/horizontal) properties.
*/
-export const List = memo(function List({ node, surfaceId }: A2UIComponentProps) {
- const { theme } = useA2UIComponent(node, surfaceId);
+export const List = memo(function List({node, surfaceId}: A2UIComponentProps) {
+ const {theme} = useA2UIComponent(node, surfaceId);
const props = node.properties;
// Match Lit's default value
@@ -20,9 +36,8 @@ export const List = memo(function List({ node, surfaceId }: A2UIComponentProps
@@ -31,12 +46,14 @@ export const List = memo(function List({ node, surfaceId }: A2UIComponentProps
{children.map((child, index) => {
- const childId = typeof child === 'object' && child !== null && 'id' in child
- ? (child as Types.AnyComponentNode).id
- : `child-${index}`;
- const childNode = typeof child === 'object' && child !== null && 'type' in child
- ? (child as Types.AnyComponentNode)
- : null;
+ const childId =
+ typeof child === 'object' && child !== null && 'id' in child
+ ? (child as Types.AnyComponentNode).id
+ : `child-${index}`;
+ const childNode =
+ typeof child === 'object' && child !== null && 'type' in child
+ ? (child as Types.AnyComponentNode)
+ : null;
return ;
})}
diff --git a/renderers/react/src/components/layout/Modal.tsx b/renderers/react/src/components/layout/Modal.tsx
index 017f92d9f..b20b2e6ce 100644
--- a/renderers/react/src/components/layout/Modal.tsx
+++ b/renderers/react/src/components/layout/Modal.tsx
@@ -1,9 +1,25 @@
-import { useState, useCallback, useRef, useEffect, memo } from 'react';
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {useState, useCallback, useRef, useEffect, memo} from 'react';
import type * as Types from '@a2ui/web_core/types/types';
-import type { A2UIComponentProps } from '../../types';
-import { useA2UIComponent } from '../../hooks/useA2UIComponent';
-import { classMapToString, stylesToObject } from '../../lib/utils';
-import { ComponentNode } from '../../core/ComponentNode';
+import type {A2UIComponentProps} from '../../types';
+import {useA2UIComponent} from '../../hooks/useA2UIComponent';
+import {classMapToString, stylesToObject} from '../../lib/utils';
+import {ComponentNode} from '../../core/ComponentNode';
/**
* Modal component - displays content in a dialog overlay.
@@ -15,8 +31,8 @@ import { ComponentNode } from '../../core/ComponentNode';
* The dialog is rendered in place (no portal) so it stays inside .a2ui-surface
* and CSS selectors work correctly. showModal() handles the top-layer overlay.
*/
-export const Modal = memo(function Modal({ node, surfaceId }: A2UIComponentProps) {
- const { theme } = useA2UIComponent(node, surfaceId);
+export const Modal = memo(function Modal({node, surfaceId}: A2UIComponentProps) {
+ const {theme} = useA2UIComponent(node, surfaceId);
const props = node.properties;
const [isOpen, setIsOpen] = useState(false);
@@ -68,15 +84,14 @@ export const Modal = memo(function Modal({ node, surfaceId }: A2UIComponentProps
);
// Apply --weight CSS variable on root div (:host equivalent) for flex layouts
- const hostStyle: React.CSSProperties = node.weight !== undefined
- ? { '--weight': node.weight } as React.CSSProperties
- : {};
+ const hostStyle: React.CSSProperties =
+ node.weight !== undefined ? ({'--weight': node.weight} as React.CSSProperties) : {};
// Match Lit's render approach: closed shows section with entry, open shows dialog
if (!isOpen) {
return (
-
+
diff --git a/renderers/react/src/components/layout/Row.tsx b/renderers/react/src/components/layout/Row.tsx
index 8bbaf7766..a38b012d1 100644
--- a/renderers/react/src/components/layout/Row.tsx
+++ b/renderers/react/src/components/layout/Row.tsx
@@ -1,17 +1,33 @@
-import { memo } from 'react';
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {memo} from 'react';
import type * as Types from '@a2ui/web_core/types/types';
-import type { A2UIComponentProps } from '../../types';
-import { useA2UIComponent } from '../../hooks/useA2UIComponent';
-import { classMapToString, stylesToObject } from '../../lib/utils';
-import { ComponentNode } from '../../core/ComponentNode';
+import type {A2UIComponentProps} from '../../types';
+import {useA2UIComponent} from '../../hooks/useA2UIComponent';
+import {classMapToString, stylesToObject} from '../../lib/utils';
+import {ComponentNode} from '../../core/ComponentNode';
/**
* Row component - arranges children horizontally using flexbox.
*
* Supports distribution (justify-content) and alignment (align-items) properties.
*/
-export const Row = memo(function Row({ node, surfaceId }: A2UIComponentProps) {
- const { theme } = useA2UIComponent(node, surfaceId);
+export const Row = memo(function Row({node, surfaceId}: A2UIComponentProps) {
+ const {theme} = useA2UIComponent(node, surfaceId);
const props = node.properties;
// Match Lit's default values
@@ -21,23 +37,29 @@ export const Row = memo(function Row({ node, surfaceId }: A2UIComponentProps
+
{children.map((child, index) => {
- const childId = typeof child === 'object' && child !== null && 'id' in child
- ? (child as Types.AnyComponentNode).id
- : `child-${index}`;
- const childNode = typeof child === 'object' && child !== null && 'type' in child
- ? (child as Types.AnyComponentNode)
- : null;
+ const childId =
+ typeof child === 'object' && child !== null && 'id' in child
+ ? (child as Types.AnyComponentNode).id
+ : `child-${index}`;
+ const childNode =
+ typeof child === 'object' && child !== null && 'type' in child
+ ? (child as Types.AnyComponentNode)
+ : null;
return ;
})}
diff --git a/renderers/react/src/components/layout/Tabs.tsx b/renderers/react/src/components/layout/Tabs.tsx
index 3785a7830..e4067ef20 100644
--- a/renderers/react/src/components/layout/Tabs.tsx
+++ b/renderers/react/src/components/layout/Tabs.tsx
@@ -1,15 +1,31 @@
-import { useState, memo } from 'react';
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {useState, memo} from 'react';
import type * as Types from '@a2ui/web_core/types/types';
-import type { A2UIComponentProps } from '../../types';
-import { useA2UIComponent } from '../../hooks/useA2UIComponent';
-import { classMapToString, stylesToObject, mergeClassMaps } from '../../lib/utils';
-import { ComponentNode } from '../../core/ComponentNode';
+import type {A2UIComponentProps} from '../../types';
+import {useA2UIComponent} from '../../hooks/useA2UIComponent';
+import {classMapToString, stylesToObject, mergeClassMaps} from '../../lib/utils';
+import {ComponentNode} from '../../core/ComponentNode';
/**
* Tabs component - displays content in switchable tabs.
*/
-export const Tabs = memo(function Tabs({ node, surfaceId }: A2UIComponentProps) {
- const { theme, resolveString } = useA2UIComponent(node, surfaceId);
+export const Tabs = memo(function Tabs({node, surfaceId}: A2UIComponentProps) {
+ const {theme, resolveString} = useA2UIComponent(node, surfaceId);
const props = node.properties;
const [selectedIndex, setSelectedIndex] = useState(0);
@@ -17,54 +33,47 @@ export const Tabs = memo(function Tabs({ node, surfaceId }: A2UIComponentProps
-
- {/* Tab buttons - uses Tabs.element for the container */}
-
- {tabItems.map((tab, index) => {
- const title = resolveString(tab.title);
- const isSelected = index === selectedIndex;
+ {/* Tab buttons - uses Tabs.element for the container */}
+
);
});
diff --git a/renderers/react/src/components/layout/index.ts b/renderers/react/src/components/layout/index.ts
index 28023efd6..1add6cea7 100644
--- a/renderers/react/src/components/layout/index.ts
+++ b/renderers/react/src/components/layout/index.ts
@@ -1,6 +1,22 @@
-export { Row } from './Row';
-export { Column } from './Column';
-export { List } from './List';
-export { Card } from './Card';
-export { Tabs } from './Tabs';
-export { Modal } from './Modal';
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export {Row} from './Row';
+export {Column} from './Column';
+export {List} from './List';
+export {Card} from './Card';
+export {Tabs} from './Tabs';
+export {Modal} from './Modal';
diff --git a/renderers/react/src/core/A2UIProvider.tsx b/renderers/react/src/core/A2UIProvider.tsx
index a11882258..045bb122f 100644
--- a/renderers/react/src/core/A2UIProvider.tsx
+++ b/renderers/react/src/core/A2UIProvider.tsx
@@ -1,18 +1,27 @@
-import {
- createContext,
- useContext,
- useRef,
- useState,
- useMemo,
- type ReactNode,
-} from 'react';
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {createContext, useContext, useRef, useState, useMemo, type ReactNode} from 'react';
import type * as Types from '@a2ui/web_core/types/types';
-import { A2uiMessageProcessor } from '@a2ui/web_core/data/model-processor';
-import type { A2UIContextValue, A2UIActions } from './store';
-import { ThemeProvider } from '../theme/ThemeContext';
-import { initializeDefaultCatalog } from '../registry/defaultCatalog';
-import { injectStyles } from '../styles';
-import type { OnActionCallback } from '../types';
+import {A2uiMessageProcessor} from '@a2ui/web_core/data/model-processor';
+import type {A2UIContextValue, A2UIActions} from './store';
+import {ThemeProvider} from '../theme/ThemeContext';
+import {initializeDefaultCatalog} from '../registry/defaultCatalog';
+import {injectStyles} from '../styles';
+import type {OnActionCallback} from '../types';
// Auto-initialize catalog and styles once on first import
let initialized = false;
@@ -34,7 +43,7 @@ const A2UIActionsContext = createContext(null);
* Context for reactive state (changes trigger re-renders).
* Only components that need to react to state changes subscribe to this.
*/
-const A2UIStateContext = createContext<{ version: number } | null>(null);
+const A2UIStateContext = createContext<{version: number} | null>(null);
/**
* Props for the A2UIProvider component.
@@ -74,7 +83,7 @@ export interface A2UIProviderProps {
* }
* ```
*/
-export function A2UIProvider({ onAction, theme, children }: A2UIProviderProps) {
+export function A2UIProvider({onAction, theme, children}: A2UIProviderProps) {
ensureInitialized();
// Create message processor only once using ref
@@ -141,7 +150,7 @@ export function A2UIProvider({ onAction, theme, children }: A2UIProviderProps) {
const actions = actionsRef.current;
// State context value - only changes when version changes
- const stateValue = useMemo(() => ({ version }), [version]);
+ const stateValue = useMemo(() => ({version}), [version]);
return (
@@ -174,7 +183,7 @@ export function useA2UIActions(): A2UIActions {
* @returns Current version number
* @throws If used outside of an A2UIProvider
*/
-export function useA2UIState(): { version: number } {
+export function useA2UIState(): {version: number} {
const state = useContext(A2UIStateContext);
if (!state) {
throw new Error('useA2UIState must be used within an A2UIProvider');
diff --git a/renderers/react/src/core/A2UIRenderer.tsx b/renderers/react/src/core/A2UIRenderer.tsx
index 2c44a6b9b..a674bd2f9 100644
--- a/renderers/react/src/core/A2UIRenderer.tsx
+++ b/renderers/react/src/core/A2UIRenderer.tsx
@@ -1,13 +1,29 @@
-import { Suspense, useMemo, memo, type ReactNode } from 'react';
-import { useA2UI } from '../hooks/useA2UI';
-import { ComponentNode } from './ComponentNode';
-import { type ComponentRegistry } from '../registry/ComponentRegistry';
-import { cn } from '../lib/utils';
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {Suspense, useMemo, memo, type ReactNode} from 'react';
+import {useA2UI} from '../hooks/useA2UI';
+import {ComponentNode} from './ComponentNode';
+import {type ComponentRegistry} from '../registry/ComponentRegistry';
+import {cn} from '../lib/utils';
/** Default loading fallback - memoized to prevent recreation */
const DefaultLoadingFallback = memo(function DefaultLoadingFallback() {
return (
-
+
Loading...
);
@@ -52,7 +68,7 @@ export const A2UIRenderer = memo(function A2UIRenderer({
loadingFallback,
registry,
}: A2UIRendererProps) {
- const { getSurface, version } = useA2UI();
+ const {getSurface, version} = useA2UI();
// Get surface - this will re-render when version changes
const surface = getSurface(surfaceId);
@@ -117,11 +133,7 @@ export const A2UIRenderer = memo(function A2UIRenderer({
data-version={version}
>
-
+
);
diff --git a/renderers/react/src/core/A2UIViewer.tsx b/renderers/react/src/core/A2UIViewer.tsx
index 0949d9728..fae5413dc 100644
--- a/renderers/react/src/core/A2UIViewer.tsx
+++ b/renderers/react/src/core/A2UIViewer.tsx
@@ -1,11 +1,27 @@
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
'use client';
-import React, { useId, useMemo, useEffect, useRef } from 'react';
+import React, {useId, useMemo, useEffect, useRef} from 'react';
import type * as Types from '@a2ui/web_core/types/types';
-import { A2UIProvider, useA2UIActions } from './A2UIProvider';
-import { A2UIRenderer } from './A2UIRenderer';
-import { litTheme } from '../theme/litTheme';
-import type { OnActionCallback } from '../types';
+import {A2UIProvider, useA2UIActions} from './A2UIProvider';
+import {A2UIRenderer} from './A2UIRenderer';
+import {litTheme} from '../theme/litTheme';
+import type {OnActionCallback} from '../types';
/**
* Component instance format for static A2UI definitions.
@@ -127,7 +143,7 @@ function A2UIViewerInner({
data: Record;
className?: string;
}) {
- const { processMessages } = useA2UIActions();
+ const {processMessages} = useA2UIActions();
const lastProcessedRef = useRef('');
// Process messages when props change
@@ -137,8 +153,8 @@ function A2UIViewerInner({
lastProcessedRef.current = key;
const messages: Types.ServerToClientMessage[] = [
- { beginRendering: { surfaceId, root, styles: {} } },
- { surfaceUpdate: { surfaceId, components } },
+ {beginRendering: {surfaceId, root, styles: {}}},
+ {surfaceUpdate: {surfaceId, components}},
];
// Add data model updates
@@ -146,7 +162,7 @@ function A2UIViewerInner({
const contents = objectToValueMaps(data);
if (contents.length > 0) {
messages.push({
- dataModelUpdate: { surfaceId, path: '/', contents },
+ dataModelUpdate: {surfaceId, path: '/', contents},
});
}
}
@@ -174,28 +190,26 @@ function objectToValueMaps(obj: Record): Types.ValueMap[] {
*/
function valueToValueMap(key: string, value: unknown): Types.ValueMap {
if (typeof value === 'string') {
- return { key, valueString: value };
+ return {key, valueString: value};
}
if (typeof value === 'number') {
- return { key, valueNumber: value };
+ return {key, valueNumber: value};
}
if (typeof value === 'boolean') {
- return { key, valueBoolean: value };
+ return {key, valueBoolean: value};
}
if (value === null || value === undefined) {
- return { key };
+ return {key};
}
if (Array.isArray(value)) {
- const valueMap = value.map((item, index) =>
- valueToValueMap(String(index), item)
- );
- return { key, valueMap };
+ const valueMap = value.map((item, index) => valueToValueMap(String(index), item));
+ return {key, valueMap};
}
if (typeof value === 'object') {
const valueMap = objectToValueMaps(value as Record);
- return { key, valueMap };
+ return {key, valueMap};
}
- return { key };
+ return {key};
}
export default A2UIViewer;
diff --git a/renderers/react/src/core/ComponentNode.tsx b/renderers/react/src/core/ComponentNode.tsx
index 86b665a14..acb2cf4af 100644
--- a/renderers/react/src/core/ComponentNode.tsx
+++ b/renderers/react/src/core/ComponentNode.tsx
@@ -1,11 +1,27 @@
-import { Suspense, useMemo, memo } from 'react';
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {Suspense, useMemo, memo} from 'react';
import type * as Types from '@a2ui/web_core/types/types';
-import { ComponentRegistry } from '../registry/ComponentRegistry';
+import {ComponentRegistry} from '../registry/ComponentRegistry';
/** Memoized loading fallback to avoid recreating on each render */
const LoadingFallback = memo(function LoadingFallback() {
return (
-
+
Loading...
);
diff --git a/renderers/react/src/core/store.ts b/renderers/react/src/core/store.ts
index 946c7670d..b568b2c8b 100644
--- a/renderers/react/src/core/store.ts
+++ b/renderers/react/src/core/store.ts
@@ -1,5 +1,21 @@
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import type * as Types from '@a2ui/web_core/types/types';
-import type { OnActionCallback } from '../types';
+import type {OnActionCallback} from '../types';
/**
* Stable actions that never change (won't cause re-renders).
diff --git a/renderers/react/src/hooks/useA2UI.ts b/renderers/react/src/hooks/useA2UI.ts
index c6a741644..82529b6e9 100644
--- a/renderers/react/src/hooks/useA2UI.ts
+++ b/renderers/react/src/hooks/useA2UI.ts
@@ -1,5 +1,21 @@
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import type * as Types from '@a2ui/web_core/types/types';
-import { useA2UIActions, useA2UIState } from '../core/A2UIProvider';
+import {useA2UIActions, useA2UIState} from '../core/A2UIProvider';
/**
* Result returned by the useA2UI hook.
diff --git a/renderers/react/src/hooks/useA2UIComponent.ts b/renderers/react/src/hooks/useA2UIComponent.ts
index 57452a32d..03fbb2bb4 100644
--- a/renderers/react/src/hooks/useA2UIComponent.ts
+++ b/renderers/react/src/hooks/useA2UIComponent.ts
@@ -1,8 +1,24 @@
-import { useCallback, useId, useMemo } from 'react';
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {useCallback, useId, useMemo} from 'react';
import type * as Types from '@a2ui/web_core/types/types';
import type * as Primitives from '@a2ui/web_core/types/primitives';
-import { useA2UIActions, useA2UIState } from '../core/A2UIProvider';
-import { useTheme } from '../theme/ThemeContext';
+import {useA2UIActions, useA2UIState} from '../core/A2UIProvider';
+import {useTheme} from '../theme/ThemeContext';
/**
* Result returned by the useA2UIComponent hook.
@@ -224,6 +240,15 @@ export function useA2UIComponent(
sendAction,
getUniqueId,
}),
- [theme, resolveString, resolveNumber, resolveBoolean, setValue, getValue, sendAction, getUniqueId]
+ [
+ theme,
+ resolveString,
+ resolveNumber,
+ resolveBoolean,
+ setValue,
+ getValue,
+ sendAction,
+ getUniqueId,
+ ]
);
}
diff --git a/renderers/react/src/index.ts b/renderers/react/src/index.ts
index 1ef980b1c..4ed8c4a87 100644
--- a/renderers/react/src/index.ts
+++ b/renderers/react/src/index.ts
@@ -1,33 +1,44 @@
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
// Core components and provider
-export {
- A2UIProvider,
- useA2UIActions,
- useA2UIState,
- useA2UIContext,
-} from './core/A2UIProvider';
-export type { A2UIProviderProps } from './core/A2UIProvider';
-export { A2UIRenderer } from './core/A2UIRenderer';
-export type { A2UIRendererProps } from './core/A2UIRenderer';
-export { A2UIViewer } from './core/A2UIViewer';
-export type { A2UIViewerProps, ComponentInstance, A2UIActionEvent } from './core/A2UIViewer';
-export { ComponentNode } from './core/ComponentNode';
+export {A2UIProvider, useA2UIActions, useA2UIState, useA2UIContext} from './core/A2UIProvider';
+export type {A2UIProviderProps} from './core/A2UIProvider';
+export {A2UIRenderer} from './core/A2UIRenderer';
+export type {A2UIRendererProps} from './core/A2UIRenderer';
+export {A2UIViewer} from './core/A2UIViewer';
+export type {A2UIViewerProps, ComponentInstance, A2UIActionEvent} from './core/A2UIViewer';
+export {ComponentNode} from './core/ComponentNode';
// Hooks
-export { useA2UI } from './hooks/useA2UI';
-export type { UseA2UIResult } from './hooks/useA2UI';
-export { useA2UIComponent } from './hooks/useA2UIComponent';
-export type { UseA2UIComponentResult } from './hooks/useA2UIComponent';
+export {useA2UI} from './hooks/useA2UI';
+export type {UseA2UIResult} from './hooks/useA2UI';
+export {useA2UIComponent} from './hooks/useA2UIComponent';
+export type {UseA2UIComponentResult} from './hooks/useA2UIComponent';
// Registry
-export { ComponentRegistry } from './registry/ComponentRegistry';
-export { registerDefaultCatalog, initializeDefaultCatalog } from './registry/defaultCatalog';
+export {ComponentRegistry} from './registry/ComponentRegistry';
+export {registerDefaultCatalog, initializeDefaultCatalog} from './registry/defaultCatalog';
// Theme
-export { ThemeProvider, useTheme, useThemeOptional } from './theme/ThemeContext';
-export { litTheme, defaultTheme } from './theme/litTheme';
+export {ThemeProvider, useTheme, useThemeOptional} from './theme/ThemeContext';
+export {litTheme, defaultTheme} from './theme/litTheme';
// Utilities
-export { cn, classMapToString, stylesToObject } from './lib/utils';
+export {cn, classMapToString, stylesToObject} from './lib/utils';
// Types - re-export from types
export type {
@@ -53,25 +64,25 @@ export type {
} from './types';
// Content components
-export { Text } from './components/content/Text';
-export { Image } from './components/content/Image';
-export { Icon } from './components/content/Icon';
-export { Divider } from './components/content/Divider';
-export { Video } from './components/content/Video';
-export { AudioPlayer } from './components/content/AudioPlayer';
+export {Text} from './components/content/Text';
+export {Image} from './components/content/Image';
+export {Icon} from './components/content/Icon';
+export {Divider} from './components/content/Divider';
+export {Video} from './components/content/Video';
+export {AudioPlayer} from './components/content/AudioPlayer';
// Layout components
-export { Row } from './components/layout/Row';
-export { Column } from './components/layout/Column';
-export { List } from './components/layout/List';
-export { Card } from './components/layout/Card';
-export { Tabs } from './components/layout/Tabs';
-export { Modal } from './components/layout/Modal';
+export {Row} from './components/layout/Row';
+export {Column} from './components/layout/Column';
+export {List} from './components/layout/List';
+export {Card} from './components/layout/Card';
+export {Tabs} from './components/layout/Tabs';
+export {Modal} from './components/layout/Modal';
// Interactive components
-export { Button } from './components/interactive/Button';
-export { TextField } from './components/interactive/TextField';
-export { CheckBox } from './components/interactive/CheckBox';
-export { Slider } from './components/interactive/Slider';
-export { DateTimeInput } from './components/interactive/DateTimeInput';
-export { MultipleChoice } from './components/interactive/MultipleChoice';
+export {Button} from './components/interactive/Button';
+export {TextField} from './components/interactive/TextField';
+export {CheckBox} from './components/interactive/CheckBox';
+export {Slider} from './components/interactive/Slider';
+export {DateTimeInput} from './components/interactive/DateTimeInput';
+export {MultipleChoice} from './components/interactive/MultipleChoice';
diff --git a/renderers/react/src/lib/utils.ts b/renderers/react/src/lib/utils.ts
index 56f0bb634..4d3091436 100644
--- a/renderers/react/src/lib/utils.ts
+++ b/renderers/react/src/lib/utils.ts
@@ -1,4 +1,20 @@
-import { clsx, type ClassValue } from 'clsx';
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {clsx, type ClassValue} from 'clsx';
import * as Styles from '@a2ui/web_core/styles/index';
/**
@@ -22,7 +38,7 @@ export function cn(...inputs: ClassValue[]): string {
* @param classMap - An object where keys are class names and values are booleans
* @returns A space-separated string of class names where the value is true
*/
-export { classMapToString, stylesToObject } from '../theme/utils';
+export {classMapToString, stylesToObject} from '../theme/utils';
/**
* Merges multiple class maps into a single class map.
diff --git a/renderers/react/src/registry/ComponentRegistry.ts b/renderers/react/src/registry/ComponentRegistry.ts
index 9f032e042..d1223c2eb 100644
--- a/renderers/react/src/registry/ComponentRegistry.ts
+++ b/renderers/react/src/registry/ComponentRegistry.ts
@@ -1,6 +1,22 @@
-import { lazy, type ComponentType } from 'react';
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {lazy, type ComponentType} from 'react';
import type * as Types from '@a2ui/web_core/types/types';
-import type { A2UIComponentProps, ComponentLoader, ComponentRegistration } from '../types';
+import type {A2UIComponentProps, ComponentLoader, ComponentRegistration} from '../types';
/**
* Registry for A2UI components. Allows registration of custom components
diff --git a/renderers/react/src/registry/defaultCatalog.ts b/renderers/react/src/registry/defaultCatalog.ts
index d36d0e5a1..b7036addc 100644
--- a/renderers/react/src/registry/defaultCatalog.ts
+++ b/renderers/react/src/registry/defaultCatalog.ts
@@ -1,28 +1,44 @@
-import { ComponentRegistry } from './ComponentRegistry';
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {ComponentRegistry} from './ComponentRegistry';
// Content components
-import { Text } from '../components/content/Text';
-import { Image } from '../components/content/Image';
-import { Icon } from '../components/content/Icon';
-import { Divider } from '../components/content/Divider';
-import { Video } from '../components/content/Video';
-import { AudioPlayer } from '../components/content/AudioPlayer';
+import {Text} from '../components/content/Text';
+import {Image} from '../components/content/Image';
+import {Icon} from '../components/content/Icon';
+import {Divider} from '../components/content/Divider';
+import {Video} from '../components/content/Video';
+import {AudioPlayer} from '../components/content/AudioPlayer';
// Layout components
-import { Row } from '../components/layout/Row';
-import { Column } from '../components/layout/Column';
-import { List } from '../components/layout/List';
-import { Card } from '../components/layout/Card';
-import { Tabs } from '../components/layout/Tabs';
-import { Modal } from '../components/layout/Modal';
+import {Row} from '../components/layout/Row';
+import {Column} from '../components/layout/Column';
+import {List} from '../components/layout/List';
+import {Card} from '../components/layout/Card';
+import {Tabs} from '../components/layout/Tabs';
+import {Modal} from '../components/layout/Modal';
// Interactive components
-import { Button } from '../components/interactive/Button';
-import { TextField } from '../components/interactive/TextField';
-import { CheckBox } from '../components/interactive/CheckBox';
-import { Slider } from '../components/interactive/Slider';
-import { DateTimeInput } from '../components/interactive/DateTimeInput';
-import { MultipleChoice } from '../components/interactive/MultipleChoice';
+import {Button} from '../components/interactive/Button';
+import {TextField} from '../components/interactive/TextField';
+import {CheckBox} from '../components/interactive/CheckBox';
+import {Slider} from '../components/interactive/Slider';
+import {DateTimeInput} from '../components/interactive/DateTimeInput';
+import {MultipleChoice} from '../components/interactive/MultipleChoice';
/**
* Registers all standard A2UI components in the registry.
@@ -31,30 +47,30 @@ import { MultipleChoice } from '../components/interactive/MultipleChoice';
*/
export function registerDefaultCatalog(registry: ComponentRegistry): void {
// Content components (small, load immediately)
- registry.register('Text', { component: Text });
- registry.register('Image', { component: Image });
- registry.register('Icon', { component: Icon });
- registry.register('Divider', { component: Divider });
- registry.register('Video', { component: Video });
- registry.register('AudioPlayer', { component: AudioPlayer });
+ registry.register('Text', {component: Text});
+ registry.register('Image', {component: Image});
+ registry.register('Icon', {component: Icon});
+ registry.register('Divider', {component: Divider});
+ registry.register('Video', {component: Video});
+ registry.register('AudioPlayer', {component: AudioPlayer});
// Layout components
- registry.register('Row', { component: Row });
- registry.register('Column', { component: Column });
- registry.register('List', { component: List });
- registry.register('Card', { component: Card });
+ registry.register('Row', {component: Row});
+ registry.register('Column', {component: Column});
+ registry.register('List', {component: List});
+ registry.register('Card', {component: Card});
// Additional layout components
- registry.register('Tabs', { component: Tabs });
- registry.register('Modal', { component: Modal });
+ registry.register('Tabs', {component: Tabs});
+ registry.register('Modal', {component: Modal});
// Interactive components
- registry.register('Button', { component: Button });
- registry.register('TextField', { component: TextField });
- registry.register('CheckBox', { component: CheckBox });
- registry.register('Slider', { component: Slider });
- registry.register('DateTimeInput', { component: DateTimeInput });
- registry.register('MultipleChoice', { component: MultipleChoice });
+ registry.register('Button', {component: Button});
+ registry.register('TextField', {component: TextField});
+ registry.register('CheckBox', {component: CheckBox});
+ registry.register('Slider', {component: Slider});
+ registry.register('DateTimeInput', {component: DateTimeInput});
+ registry.register('MultipleChoice', {component: MultipleChoice});
}
/**
diff --git a/renderers/react/src/styles/index.d.ts b/renderers/react/src/styles/index.d.ts
index 6ac5f4c8b..acfc690ca 100644
--- a/renderers/react/src/styles/index.d.ts
+++ b/renderers/react/src/styles/index.d.ts
@@ -1,3 +1,19 @@
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
/**
* Structural CSS styles converted from Lit renderer.
* Uses .a2ui-surface {} instead of :host {} for non-Shadow DOM usage.
diff --git a/renderers/react/src/styles/index.ts b/renderers/react/src/styles/index.ts
index 13b0b5815..f7f41ac44 100644
--- a/renderers/react/src/styles/index.ts
+++ b/renderers/react/src/styles/index.ts
@@ -1,5 +1,21 @@
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import * as Styles from '@a2ui/web_core/styles/index';
-import { resetStyles } from './reset';
+import {resetStyles} from './reset';
/**
* Structural CSS styles from the Lit renderer, converted for global DOM use.
diff --git a/renderers/react/src/styles/reset.ts b/renderers/react/src/styles/reset.ts
index 63a265f80..c6e38ced9 100644
--- a/renderers/react/src/styles/reset.ts
+++ b/renderers/react/src/styles/reset.ts
@@ -1,3 +1,19 @@
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
/**
* Browser default reset for A2UI surfaces.
*
diff --git a/renderers/react/src/theme/ThemeContext.tsx b/renderers/react/src/theme/ThemeContext.tsx
index 42e99e370..cb3b5fec9 100644
--- a/renderers/react/src/theme/ThemeContext.tsx
+++ b/renderers/react/src/theme/ThemeContext.tsx
@@ -1,6 +1,22 @@
-import { createContext, useContext, type ReactNode } from 'react';
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {createContext, useContext, type ReactNode} from 'react';
import type * as Types from '@a2ui/web_core/types/types';
-import { defaultTheme } from './litTheme';
+import {defaultTheme} from './litTheme';
/**
* React context for the A2UI theme.
@@ -20,12 +36,8 @@ export interface ThemeProviderProps {
/**
* Provider component that makes the A2UI theme available to descendant components.
*/
-export function ThemeProvider({ theme, children }: ThemeProviderProps) {
- return (
-
- {children}
-
- );
+export function ThemeProvider({theme, children}: ThemeProviderProps) {
+ return {children};
}
/**
diff --git a/renderers/react/src/theme/litTheme.ts b/renderers/react/src/theme/litTheme.ts
index 54477ce2c..ccb94d10f 100644
--- a/renderers/react/src/theme/litTheme.ts
+++ b/renderers/react/src/theme/litTheme.ts
@@ -1,3 +1,19 @@
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import type * as Types from '@a2ui/web_core/types/types';
/**
@@ -172,7 +188,7 @@ export const litTheme: Types.Theme = {
'layout-w-100': true,
'layout-h-100': true,
},
- avatar: { 'is-avatar': true },
+ avatar: {'is-avatar': true},
header: {},
icon: {},
largeFeature: {},
diff --git a/renderers/react/src/theme/utils.ts b/renderers/react/src/theme/utils.ts
index 44d734f9e..9de8c5d4e 100644
--- a/renderers/react/src/theme/utils.ts
+++ b/renderers/react/src/theme/utils.ts
@@ -1,3 +1,19 @@
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
/**
* Converts a theme class map (Record) to a className string.
*
diff --git a/renderers/react/src/types.ts b/renderers/react/src/types.ts
index 7db73e3e0..7c3be2851 100644
--- a/renderers/react/src/types.ts
+++ b/renderers/react/src/types.ts
@@ -1,9 +1,25 @@
-import type { ComponentType } from 'react';
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import type {ComponentType} from 'react';
import type * as Types from '@a2ui/web_core/types/types';
import type * as Primitives from '@a2ui/web_core/types/primitives';
// Re-export the Types and Primitives namespaces for convenience
-export type { Types, Primitives };
+export type {Types, Primitives};
// Re-export commonly used types from Types namespace
export type AnyComponentNode = Types.AnyComponentNode;
@@ -34,9 +50,10 @@ export interface A2UIComponentProps = () => Promise<{
- default: ComponentType>;
-}>;
+export type ComponentLoader =
+ () => Promise<{
+ default: ComponentType>;
+ }>;
/**
* Registration entry for a component in the registry.
diff --git a/renderers/react/tests/integration/ThemeContext.test.tsx b/renderers/react/tests/integration/ThemeContext.test.tsx
index 06701db00..21444f55a 100644
--- a/renderers/react/tests/integration/ThemeContext.test.tsx
+++ b/renderers/react/tests/integration/ThemeContext.test.tsx
@@ -1,3 +1,19 @@
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import { describe, it, expect } from 'vitest';
import { render } from '@testing-library/react';
import React from 'react';
diff --git a/renderers/react/tests/integration/actions.test.tsx b/renderers/react/tests/integration/actions.test.tsx
index 01d8f3275..8087ccad9 100644
--- a/renderers/react/tests/integration/actions.test.tsx
+++ b/renderers/react/tests/integration/actions.test.tsx
@@ -1,3 +1,19 @@
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import { describe, it, expect, vi } from 'vitest';
import { render, screen, fireEvent } from '@testing-library/react';
import React from 'react';
diff --git a/renderers/react/tests/integration/components.test.tsx b/renderers/react/tests/integration/components.test.tsx
index 4b40f475e..dcba83bc2 100644
--- a/renderers/react/tests/integration/components.test.tsx
+++ b/renderers/react/tests/integration/components.test.tsx
@@ -1,3 +1,19 @@
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import { describe, it, expect, vi } from 'vitest';
import { render, screen, waitFor } from '@testing-library/react';
import React, { useEffect } from 'react';
diff --git a/renderers/react/tests/integration/data-binding.test.tsx b/renderers/react/tests/integration/data-binding.test.tsx
index 3ad9e9b5a..879a6a27b 100644
--- a/renderers/react/tests/integration/data-binding.test.tsx
+++ b/renderers/react/tests/integration/data-binding.test.tsx
@@ -1,3 +1,19 @@
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import { describe, it, expect } from 'vitest';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import React, { useEffect } from 'react';
diff --git a/renderers/react/tests/integration/hooks.test.tsx b/renderers/react/tests/integration/hooks.test.tsx
index aae6d2c44..44e1951dd 100644
--- a/renderers/react/tests/integration/hooks.test.tsx
+++ b/renderers/react/tests/integration/hooks.test.tsx
@@ -1,3 +1,19 @@
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import { describe, it, expect, vi } from 'vitest';
import { render } from '@testing-library/react';
import React from 'react';
diff --git a/renderers/react/tests/integration/messages.test.tsx b/renderers/react/tests/integration/messages.test.tsx
index 049a27d94..0fe4ce706 100644
--- a/renderers/react/tests/integration/messages.test.tsx
+++ b/renderers/react/tests/integration/messages.test.tsx
@@ -1,3 +1,19 @@
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import { describe, it, expect } from 'vitest';
import { render, screen, waitFor } from '@testing-library/react';
import React, { useEffect } from 'react';
diff --git a/renderers/react/tests/integration/property-updates.test.tsx b/renderers/react/tests/integration/property-updates.test.tsx
index 8c23ae53c..710ff4270 100644
--- a/renderers/react/tests/integration/property-updates.test.tsx
+++ b/renderers/react/tests/integration/property-updates.test.tsx
@@ -1,3 +1,19 @@
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import { describe, it, expect } from 'vitest';
import { render, screen, waitFor } from '@testing-library/react';
import React, { useEffect } from 'react';
diff --git a/renderers/react/tests/integration/templates.test.tsx b/renderers/react/tests/integration/templates.test.tsx
index 8bc3cc7a0..f2154f41b 100644
--- a/renderers/react/tests/integration/templates.test.tsx
+++ b/renderers/react/tests/integration/templates.test.tsx
@@ -1,3 +1,19 @@
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import { describe, it, expect, vi } from 'vitest';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import React, { useEffect } from 'react';
diff --git a/renderers/react/tests/setup.ts b/renderers/react/tests/setup.ts
index b22682cde..9098c3aba 100644
--- a/renderers/react/tests/setup.ts
+++ b/renderers/react/tests/setup.ts
@@ -1,3 +1,19 @@
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import '@testing-library/jest-dom/vitest';
import { beforeAll } from 'vitest';
import { initializeDefaultCatalog } from '../src';
diff --git a/renderers/react/tests/unit/components/Button.test.tsx b/renderers/react/tests/unit/components/Button.test.tsx
index bb8e87621..0edda1d28 100644
--- a/renderers/react/tests/unit/components/Button.test.tsx
+++ b/renderers/react/tests/unit/components/Button.test.tsx
@@ -1,3 +1,19 @@
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import { describe, it, expect, vi } from 'vitest';
import { render, screen, fireEvent } from '@testing-library/react';
import React from 'react';
diff --git a/renderers/react/tests/unit/components/Card.test.tsx b/renderers/react/tests/unit/components/Card.test.tsx
index 3053d1fa3..d62f05e53 100644
--- a/renderers/react/tests/unit/components/Card.test.tsx
+++ b/renderers/react/tests/unit/components/Card.test.tsx
@@ -1,3 +1,19 @@
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import { describe, it, expect } from 'vitest';
import { render, screen } from '@testing-library/react';
import React from 'react';
diff --git a/renderers/react/tests/unit/components/CheckBox.test.tsx b/renderers/react/tests/unit/components/CheckBox.test.tsx
index aa74ea718..42a91f129 100644
--- a/renderers/react/tests/unit/components/CheckBox.test.tsx
+++ b/renderers/react/tests/unit/components/CheckBox.test.tsx
@@ -1,3 +1,19 @@
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import { describe, it, expect } from 'vitest';
import { render, screen, fireEvent } from '@testing-library/react';
import React from 'react';
diff --git a/renderers/react/tests/unit/components/Column.test.tsx b/renderers/react/tests/unit/components/Column.test.tsx
index 8a067a922..92f6cc1fb 100644
--- a/renderers/react/tests/unit/components/Column.test.tsx
+++ b/renderers/react/tests/unit/components/Column.test.tsx
@@ -1,3 +1,19 @@
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import { describe, it, expect } from 'vitest';
import { render, screen } from '@testing-library/react';
import React from 'react';
diff --git a/renderers/react/tests/unit/components/DateTimeInput.test.tsx b/renderers/react/tests/unit/components/DateTimeInput.test.tsx
index 0dc9c6503..93ca9850d 100644
--- a/renderers/react/tests/unit/components/DateTimeInput.test.tsx
+++ b/renderers/react/tests/unit/components/DateTimeInput.test.tsx
@@ -1,3 +1,19 @@
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import { describe, it, expect } from 'vitest';
import { render, fireEvent } from '@testing-library/react';
import React from 'react';
diff --git a/renderers/react/tests/unit/components/Divider.test.tsx b/renderers/react/tests/unit/components/Divider.test.tsx
index 13e7bb4e6..58900b01b 100644
--- a/renderers/react/tests/unit/components/Divider.test.tsx
+++ b/renderers/react/tests/unit/components/Divider.test.tsx
@@ -1,3 +1,19 @@
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import { describe, it, expect } from 'vitest';
import { render } from '@testing-library/react';
import React from 'react';
diff --git a/renderers/react/tests/unit/components/Icon.test.tsx b/renderers/react/tests/unit/components/Icon.test.tsx
index 7c621e4c6..515316fe0 100644
--- a/renderers/react/tests/unit/components/Icon.test.tsx
+++ b/renderers/react/tests/unit/components/Icon.test.tsx
@@ -1,3 +1,19 @@
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import { describe, it, expect, beforeEach } from 'vitest';
import { render, screen } from '@testing-library/react';
import React from 'react';
diff --git a/renderers/react/tests/unit/components/Image.test.tsx b/renderers/react/tests/unit/components/Image.test.tsx
index 665a94610..bfa520918 100644
--- a/renderers/react/tests/unit/components/Image.test.tsx
+++ b/renderers/react/tests/unit/components/Image.test.tsx
@@ -1,3 +1,19 @@
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import { describe, it, expect } from 'vitest';
import { render } from '@testing-library/react';
import React from 'react';
diff --git a/renderers/react/tests/unit/components/List.test.tsx b/renderers/react/tests/unit/components/List.test.tsx
index 4cb538565..4f04896b2 100644
--- a/renderers/react/tests/unit/components/List.test.tsx
+++ b/renderers/react/tests/unit/components/List.test.tsx
@@ -1,3 +1,19 @@
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import { describe, it, expect } from 'vitest';
import { render } from '@testing-library/react';
import React from 'react';
diff --git a/renderers/react/tests/unit/components/Modal.test.tsx b/renderers/react/tests/unit/components/Modal.test.tsx
index 297b84ddd..ee876ec54 100644
--- a/renderers/react/tests/unit/components/Modal.test.tsx
+++ b/renderers/react/tests/unit/components/Modal.test.tsx
@@ -1,3 +1,19 @@
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import React from 'react';
diff --git a/renderers/react/tests/unit/components/MultipleChoice.test.tsx b/renderers/react/tests/unit/components/MultipleChoice.test.tsx
index 013199e13..6daa845da 100644
--- a/renderers/react/tests/unit/components/MultipleChoice.test.tsx
+++ b/renderers/react/tests/unit/components/MultipleChoice.test.tsx
@@ -1,3 +1,19 @@
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import { describe, it, expect } from 'vitest';
import { render, fireEvent } from '@testing-library/react';
import React from 'react';
diff --git a/renderers/react/tests/unit/components/Row.test.tsx b/renderers/react/tests/unit/components/Row.test.tsx
index faf6b05de..4a5152f9d 100644
--- a/renderers/react/tests/unit/components/Row.test.tsx
+++ b/renderers/react/tests/unit/components/Row.test.tsx
@@ -1,3 +1,19 @@
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import { describe, it, expect } from 'vitest';
import { render, screen } from '@testing-library/react';
import React from 'react';
diff --git a/renderers/react/tests/unit/components/Slider.test.tsx b/renderers/react/tests/unit/components/Slider.test.tsx
index 6a5e6065e..8c75226af 100644
--- a/renderers/react/tests/unit/components/Slider.test.tsx
+++ b/renderers/react/tests/unit/components/Slider.test.tsx
@@ -1,3 +1,19 @@
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import { describe, it, expect } from 'vitest';
import { render, fireEvent } from '@testing-library/react';
import React from 'react';
diff --git a/renderers/react/tests/unit/components/Tabs.test.tsx b/renderers/react/tests/unit/components/Tabs.test.tsx
index ec22016ee..e5e49d2b8 100644
--- a/renderers/react/tests/unit/components/Tabs.test.tsx
+++ b/renderers/react/tests/unit/components/Tabs.test.tsx
@@ -1,3 +1,19 @@
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import { describe, it, expect } from 'vitest';
import { render, screen, fireEvent } from '@testing-library/react';
import React from 'react';
diff --git a/renderers/react/tests/unit/components/Text.test.tsx b/renderers/react/tests/unit/components/Text.test.tsx
index 067e6c125..20edee325 100644
--- a/renderers/react/tests/unit/components/Text.test.tsx
+++ b/renderers/react/tests/unit/components/Text.test.tsx
@@ -1,3 +1,19 @@
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import { describe, it, expect } from 'vitest';
import { render, screen, waitFor } from '@testing-library/react';
import React from 'react';
diff --git a/renderers/react/tests/unit/components/TextField.test.tsx b/renderers/react/tests/unit/components/TextField.test.tsx
index 83f2b1864..57b9f70b4 100644
--- a/renderers/react/tests/unit/components/TextField.test.tsx
+++ b/renderers/react/tests/unit/components/TextField.test.tsx
@@ -1,3 +1,19 @@
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import { describe, it, expect } from 'vitest';
import { render, screen, fireEvent } from '@testing-library/react';
import React from 'react';
diff --git a/renderers/react/tests/utils/assertions.ts b/renderers/react/tests/utils/assertions.ts
index 825d6a32e..518274ce5 100644
--- a/renderers/react/tests/utils/assertions.ts
+++ b/renderers/react/tests/utils/assertions.ts
@@ -1,3 +1,19 @@
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import type { Mock } from 'vitest';
/**
diff --git a/renderers/react/tests/utils/index.ts b/renderers/react/tests/utils/index.ts
index 2fbef006b..6f483d65d 100644
--- a/renderers/react/tests/utils/index.ts
+++ b/renderers/react/tests/utils/index.ts
@@ -1,3 +1,19 @@
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
// Re-export all test utilities for convenient importing
export * from './render';
export * from './messages';
diff --git a/renderers/react/tests/utils/messages.ts b/renderers/react/tests/utils/messages.ts
index 6cd03c319..32f87a50e 100644
--- a/renderers/react/tests/utils/messages.ts
+++ b/renderers/react/tests/utils/messages.ts
@@ -1,3 +1,19 @@
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import type * as Types from '@a2ui/web_core/types/types';
/**
diff --git a/renderers/react/tests/utils/render.tsx b/renderers/react/tests/utils/render.tsx
index 04afeacba..96270d4f6 100644
--- a/renderers/react/tests/utils/render.tsx
+++ b/renderers/react/tests/utils/render.tsx
@@ -1,3 +1,19 @@
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import React, { useEffect, type ReactNode } from 'react';
import { A2UIProvider, A2UIRenderer, useA2UI } from '../../src';
import type * as Types from '@a2ui/web_core/types/types';
diff --git a/renderers/react/tsup.config.ts b/renderers/react/tsup.config.ts
index 8d675f821..43f454650 100644
--- a/renderers/react/tsup.config.ts
+++ b/renderers/react/tsup.config.ts
@@ -1,3 +1,19 @@
+/**
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
import { defineConfig } from 'tsup';
export default defineConfig([
diff --git a/renderers/react/visual-parity/README.md b/renderers/react/visual-parity/README.md
index 68845df5c..76a152827 100644
--- a/renderers/react/visual-parity/README.md
+++ b/renderers/react/visual-parity/README.md
@@ -1,13 +1,15 @@
# Visual Parity Tests
-Visual parity tests ensure the React renderer produces pixel-identical output to the Lit renderer (the reference implementation).
+Visual parity tests ensure the React renderer produces pixel-identical output to
+the Lit renderer (the reference implementation).
## Overview
-These tests compare screenshots of the same A2UI components rendered by both implementations:
+These tests compare screenshots of the same A2UI components rendered by both
+implementations:
-- **Lit renderer** (Shadow DOM) - Reference implementation at `localhost:5002`
-- **React renderer** (Light DOM) - Test subject at `localhost:5001`
+- **Lit renderer** (Shadow DOM) - Reference implementation at `localhost:5002`
+- **React renderer** (Light DOM) - Test subject at `localhost:5001`
Tests pass when the pixel difference is ≤1%.
@@ -42,18 +44,10 @@ Tests pass when the pixel difference is ≤1%.
### Prerequisites
-1. Build the React renderer first:
- ```bash
- cd renderers/react
- npm install
- npm run build
- ```
+1. Build the React renderer first: `bash cd renderers/react npm install npm run
+ build`
-2. Install visual-parity dependencies:
- ```bash
- cd visual-parity
- npm install
- ```
+2. Install visual-parity dependencies: `bash cd visual-parity npm install`
### Running Tests
@@ -87,9 +81,8 @@ npm run dev:react # localhost:5001
npm run dev:lit # localhost:5002
```
-Then open:
-- http://localhost:5001?fixture=buttonPrimary&theme=lit (React)
-- http://localhost:5002?fixture=buttonPrimary&theme=lit (Lit)
+Then open: - http://localhost:5001?fixture=buttonPrimary&theme=lit (React) -
+http://localhost:5002?fixture=buttonPrimary&theme=lit (Lit)
## Project Structure
@@ -204,24 +197,22 @@ interface ComponentFixture {
Tests run across multiple themes to ensure theme switching works:
-| Theme | Description |
-|-------|-------------|
-| `lit` | Default litTheme from @a2ui/react |
-| `visualParity` | Alternate theme for testing |
-| `minimal` | Stripped-down theme |
+Theme | Description
+-------------- | ---------------------------------
+`lit` | Default litTheme from @a2ui/react
+`visualParity` | Alternate theme for testing
+`minimal` | Stripped-down theme
-To test a specific theme:
-```bash
-npm test -- --grep "Theme: minimal"
-```
+To test a specific theme: `bash npm test -- --grep "Theme: minimal"`
## Skipped Fixtures
Some fixtures are skipped due to known implementation differences:
-| Fixture | Reason |
-|---------|--------|
-| `multipleChoice*` | Implementation differs: React uses radio/checkboxes, Lit uses `