Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
ea77512
Rename Icon path property to svgPath to fix type collision
josemontespg May 6, 2026
f994274
Address review comments: update React Icon to render SVG, revert lock…
josemontespg May 6, 2026
d46fb22
don't use any in icon component
josemontespg May 6, 2026
d1c8bc8
Update Lit Icon component to support svgPath
josemontespg May 7, 2026
f8cf81c
Apply formatting fixes
josemontespg May 7, 2026
ec49bee
Merge remote-tracking branch 'upstream/main' into rename-icon-path
josemontespg May 7, 2026
843cf7b
Update changelogs for Icon path rename
josemontespg May 7, 2026
5a405f2
Use Unreleased section in web_core changelog
josemontespg May 7, 2026
ff5c60c
Merge remote-tracking branch 'upstream/main' into rename-icon-path
josemontespg May 7, 2026
789da19
Merge remote-tracking branch 'upstream/main' into rename-icon-path
josemontespg May 7, 2026
4444ba7
Merge remote-tracking branch 'upstream/main' into rename-icon-path
josemontespg May 8, 2026
15037e3
Mark Icon path rename as breaking change in changelogs
josemontespg May 8, 2026
e7569f6
Update specification to use svgPath for Icon
josemontespg May 8, 2026
e0dde59
Merge remote-tracking branch 'upstream/main' into rename-icon-path
josemontespg May 8, 2026
481da88
Fix test case after merge conflict resolution
josemontespg May 8, 2026
5cbf752
Allow DataBinding for Icon name in specification and schema
josemontespg May 8, 2026
4f9fe86
Merge remote-tracking branch 'upstream/main' into rename-icon-path
josemontespg May 8, 2026
3082293
Merge remote-tracking branch 'upstream/main' into rename-icon-path
josemontespg May 8, 2026
472c73d
Merge remote-tracking branch 'upstream/main' into rename-icon-path
josemontespg May 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions renderers/angular/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## Unreleased

- **BREAKING CHANGE**: (v0_9) Rename Icon `path` property to `svgPath` to fix type collision and avoid forced casts.
- (v0_9) Re-style the v0_9 catalog components using the default theme from
`web_core`. [#1166](https://github.com/google/A2UI/pull/1166)
- (v0_9) Improve type safety of `props()` in Catalog components. Custom catalog
Expand Down
15 changes: 9 additions & 6 deletions renderers/angular/src/v0_9/catalog/basic/icon.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ const ICON_NAME_OVERRIDES: Record<string, string> = {
standalone: true,
imports: [],
template: `
@if (isPath()) {
@if (isSvgPath()) {
<svg class="a2ui-icon svg" viewBox="0 0 24 24" [style.fill]="color() || 'currentColor'">
<path [attr.d]="path()"></path>
<path [attr.d]="svgPath()"></path>
</svg>
} @else {
<i class="material-icons a2ui-icon" [style.color]="color()">
Expand Down Expand Up @@ -88,14 +88,17 @@ export class IconComponent extends BasicCatalogComponent<typeof IconApi> {
readonly color = computed(() => (this.props() as AnyDuringSchemaAlignment)['color']?.value());
readonly iconNameRaw = computed(() => this.props()['name']?.value());

readonly isPath = computed(() => {
readonly isSvgPath = computed(() => {
const name = this.iconNameRaw();
return typeof name === 'object' && name !== null && 'path' in name;
return typeof name === 'object' && name !== null && 'svgPath' in name;
});

readonly path = computed(() => {
readonly svgPath = computed(() => {
const name = this.iconNameRaw();
return (name as any)?.path || '';
if (typeof name === 'object' && name !== null && 'svgPath' in name) {
return name.svgPath;
}
return '';
});

readonly iconName = computed(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ describe('Simple Components', () => {
setComponentProps(fixture, {
...defaultProps,
name: createBoundProperty({
path: 'M10 10...',
svgPath: 'M10 10...',
}) as unknown as ComponentToProps<IconComponent>['name'],
});
fixture.detectChanges();
Expand Down
1 change: 1 addition & 0 deletions renderers/lit/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## Unreleased

- **BREAKING CHANGE**: (v0_9) Rename Icon `path` property to `svgPath` and update component to correctly render SVG elements.
- (v0_9) Wire up agent-provided primary color to basic catalog components.
- (v0_9) Re-style the v0_9 catalog components using the default theme from
`web_core`. [#1079](https://github.com/google/A2UI/pull/1079)
Expand Down
16 changes: 14 additions & 2 deletions renderers/lit/src/v0_9/catalogs/basic/components/Icon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ export class A2uiIconElement extends BasicCatalogA2uiLitElement<typeof IconApi>
color: var(--a2ui-icon-color, inherit);
font-variation-settings: var(--a2ui-icon-font-variation-settings, 'FILL' 1);
}
.svg {
fill: currentColor;
width: var(--_icon-size);
height: var(--_icon-size);
}
`;

protected createController() {
Expand All @@ -74,8 +79,15 @@ export class A2uiIconElement extends BasicCatalogA2uiLitElement<typeof IconApi>
const props = this.controller.props;
if (!props) return nothing;

const iconName =
typeof props.name === 'string' ? toMaterialSymbol(props.name) : (props.name as any)?.path;
const name = props.name;
const isPath = typeof name === 'object' && name !== null && 'svgPath' in name;

if (isPath) {
const path = (name as {svgPath: string}).svgPath;
return html`<svg class="svg" viewBox="0 0 24 24"><path d=${path}></path></svg>`;
}

const iconName = typeof name === 'string' ? toMaterialSymbol(name) : '';
return html`<span class="material-symbol">${iconName}</span>`;
}
}
Expand Down
1 change: 1 addition & 0 deletions renderers/react/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## Unreleased

- **BREAKING CHANGE**: (v0_9) Rename Icon `path` property to `svgPath` and update component to correctly render SVG elements.
- Added license.
- (v0_8) Exclude SVG elements and descendants from CSS reset to restore SVG rendering. [#1252](https://github.com/google/A2UI/pull/1252)
- **BREAKING CHANGE**: Renamed `createReactComponent` to `createComponentImplementation`.
Expand Down
38 changes: 30 additions & 8 deletions renderers/react/src/v0_9/catalog/basic/components/Icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,29 +36,51 @@ function toMaterialSymbol(str: string): string {

export const Icon = createComponentImplementation(IconApi, ({props}) => {
useBasicCatalogStyles();
const iconName =
typeof props.name === 'string'
? toMaterialSymbol(props.name)
: (props.name as {path?: string})?.path;

const style: React.CSSProperties = {
const isPath = typeof props.name === 'object' && props.name !== null && 'svgPath' in props.name;

const baseStyle: React.CSSProperties = {
...getBaseLeafStyle(),
display: 'inline-flex',
alignItems: 'center',
justifyContent: 'center',
fontFamily: 'var(--a2ui-icon-font-family, "Material Symbols Outlined", sans-serif)',
fontSize: 'var(--a2ui-icon-size, var(--a2ui-font-size-xl, 24px))',
color: 'var(--a2ui-icon-color, inherit)',
lineHeight: 1,
};

if (isPath) {
const path = (props.name as {svgPath: string}).svgPath;
return (
<svg
className="a2ui-icon svg"
viewBox="0 0 24 24"
style={{
...baseStyle,
fill: 'currentColor',
width: 'var(--a2ui-icon-size, 24px)',
height: 'var(--a2ui-icon-size, 24px)',
}}
>
<path d={path}></path>
</svg>
);
}

const iconName = typeof props.name === 'string' ? toMaterialSymbol(props.name) : '';

const fontStyle: React.CSSProperties = {
...baseStyle,
fontFamily: 'var(--a2ui-icon-font-family, "Material Symbols Outlined", sans-serif)',
fontVariationSettings: 'var(--a2ui-icon-font-variation-settings, "FILL" 1)',
fontWeight: 'normal',
fontStyle: 'normal',
lineHeight: 1,
letterSpacing: 'normal',
textTransform: 'none',
};

return (
<span className="material-symbols-outlined" style={style}>
<span className="material-symbols-outlined" style={fontStyle}>
{iconName}
</span>
);
Expand Down
1 change: 1 addition & 0 deletions renderers/web_core/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## Unreleased

- **BREAKING CHANGE**: Rename Icon `path` property to `svgPath` to fix type collision with `DataBindingType`.
- (v0_9) Add `computeColorVariant` helper function for basic catalog components to generate CSS formulas for color variants (light, dark, hover), allowing reuse across renderers.

## 0.9.1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,11 @@ export const IconApi = {
name: z
.union([
z.enum(ICON_NAMES),
z
.object({
svgPath: z.string().describe('Custom SVG path data'),
Comment thread
josemontespg marked this conversation as resolved.
})
.strict(),
z
.object({
path: z.string(),
Expand Down
7 changes: 5 additions & 2 deletions specification/v0_9/json/basic_catalog.json
Original file line number Diff line number Diff line change
Expand Up @@ -162,12 +162,15 @@
{
"type": "object",
"properties": {
"path": {
"svgPath": {
"type": "string"
}
},
"required": ["path"],
"required": ["svgPath"],
"additionalProperties": false
},
{
"$ref": "common_types.json#/$defs/DataBinding"
}
]
}
Expand Down
Loading