Skip to content

feat: A2UI column template rendering#2638

Merged
HuJean merged 2 commits into
mainfrom
p/a2ui-column-template-rendering
May 14, 2026
Merged

feat: A2UI column template rendering#2638
HuJean merged 2 commits into
mainfrom
p/a2ui-column-template-rendering

Conversation

@HuJean
Copy link
Copy Markdown
Collaborator

@HuJean HuJean commented May 14, 2026

Summary by CodeRabbit

  • New Features

    • Column components support dynamic children driven by templates.
    • Buttons include an optional validity state with visual feedback and disabled behavior.
  • Bug Fixes

    • Nested bindings in Column templates now preserve correct data context paths.
    • Component rendering preserves caller-provided context to avoid context overwrite.
  • Style

    • Updated Button styles and added disabled styling.
    • Removed default Image padding and added theme variables for buttons and image sizes.

Review Change Stack

Checklist

  • Tests updated (or not required).
  • Documentation updated (or not required).
  • Changeset added, and when a BREAKING CHANGE occurs, it needs to be clearly marked (or not required).

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 14, 2026

🦋 Changeset detected

Latest commit: e36b253

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 0 packages

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 14, 2026

📝 Walkthrough

Walkthrough

Patch updates: Button gains an isValid gating prop and disabled styling; Column supports template-driven dynamic children with per-item dataContextPath; NodeRenderer preserves caller dataContextPath via effectiveComponent; theme and image styles add variables and remove image padding.

Changes

A2UI Component and Renderer Updates

Layer / File(s) Summary
Button disabled state
packages/genui/a2ui/src/catalog/Button/index.tsx, packages/genui/a2ui/styles/catalog/Button.css
Button adds optional isValid?: boolean (default true); click handler dispatches only when isValid && action. Render adds button-disabled class and disables bindtap when invalid. CSS refines base/variant styles and adds disabled opacity rules.
Column dynamic children support
packages/genui/a2ui/src/catalog/Column/index.tsx
Column now accepts static child ID arrays or a DynamicColumnItem template, adds buildChild, uses useDataBinding and useMemo to produce childList with per-item dataContextPath and stable-ish keys for rendering.
NodeRenderer context path preservation
packages/genui/a2ui/src/react/A2UIRenderer.tsx
NodeRendererImpl computes effectiveComponent to preserve initialComponent.dataContextPath; missing-component effect, useResolvedProps, action payload, and buildNodeRecursive use effectiveComponent.
Theme variables and image styling
packages/genui/a2ui/styles/theme.css, packages/genui/a2ui/styles/catalog/Image.css
Adds button-related CSS custom properties and image feature sizes to :root; removes padding from .a2ui-image.

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested Reviewers

  • PupilTong
  • gaoachao
  • fzx2666-fz

Poem

🐰 A button learns to say "no" with grace,
Columns line up items, each in place,
Context paths hold steady, true,
Nested bindings see it through,
Hooray — A2UI hops anew!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: A2UI column template rendering' directly aligns with the main change: the Column component now supports dynamic template rendering with proper dataContextPath handling.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch p/a2ui-column-template-rendering

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 14, 2026

❌ 1 Tests Failed:

Tests completed Failed Passed Skipped
4913 1 4912 145
View the top 3 failed test(s) by shortest run time
tests/lynx.spec.ts > kitten-lynx testing framework > can click
Stack Traces | 5.01s run time
Error: No response found for deviceId: emulator-5554 port: 8901
 ❯ Connector.#sendMessageWithTransport ../...../devtool-connector/src/index.ts:442:11
 ❯ Connector.sendCDPMessage ../...../devtool-connector/src/index.ts:215:12
 ❯ CDPChannel.send src/CDPChannel.ts:158:12
 ❯ KittenLynxView.locator src/KittenLynxView.ts:257:24
 ❯ tests/lynx.spec.ts:88:24
tests/lynx.spec.ts > kitten-lynx testing framework
Stack Traces | 25.3s run time
Error: cannot find session for URL: http://127.0.0.1:3001/react-example.lynx.bundle
 ❯ KittenLynxView.goto src/KittenLynxView.ts:232:13
 ❯ tests/lynx.spec.ts:49:5
tests/lynx.spec.ts > kitten-lynx testing framework > can take a screenshot
Stack Traces | 50s run time
Error: Test timed out in 50000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
 ❯ tests/lynx.spec.ts:100:3

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

@HuJean HuJean force-pushed the p/a2ui-column-template-rendering branch from c0cec8b to c2eeb7d Compare May 14, 2026 09:42
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
.changeset/tame-bears-happen.md (1)

5-5: ⚡ Quick win

Consider documenting all user-facing changes.

The changeset currently documents the Column template rendering and NodeRenderer fixes, but the stack context indicates this release also includes Button disabled state support (new isValid prop) and theme/styling updates. Users reading the changelog would benefit from knowing about all changes in this release.

📝 Suggested expanded description
-Fix `Column` template rendering so nested bindings keep the correct `dataContextPath`, and preserve the caller-provided context in `NodeRenderer` instead of overwriting it from the stored component snapshot.
+Fix `Column` template rendering so nested bindings keep the correct `dataContextPath`, and preserve the caller-provided context in `NodeRenderer` instead of overwriting it from the stored component snapshot. Add `isValid` prop to Button for disabled state handling. Update theme variables for Button styling and image feature sizes.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.changeset/tame-bears-happen.md at line 5, Update the changeset text to
document all user-facing changes in this release: keep the existing note about
fixing Column template rendering and preserving caller context in NodeRenderer,
and add concise entries mentioning Button disabled-state support via the new
isValid prop (e.g., "Button: added isValid prop to control disabled state") and
the theme/styling updates (briefly summarize what changed visually or theming
API-wise); ensure the entries reference "Column" and "NodeRenderer" and the new
"isValid" prop so users can quickly see the scope of changes.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/genui/a2ui/src/react/A2UIRenderer.tsx`:
- Around line 185-189: The current logic only overwrites
component.dataContextPath when initialComponent.dataContextPath is defined,
leaving stale paths when initial was undefined; change the condition in the
effectiveComponent assignment to compare initialComponent.dataContextPath
directly with component.dataContextPath (i.e., if they are not equal) and, when
different, return { ...component, dataContextPath:
initialComponent.dataContextPath } so the initial value (including undefined)
replaces the current one; update the code referencing effectiveComponent,
initialComponent.dataContextPath, and component.dataContextPath accordingly.

---

Nitpick comments:
In @.changeset/tame-bears-happen.md:
- Line 5: Update the changeset text to document all user-facing changes in this
release: keep the existing note about fixing Column template rendering and
preserving caller context in NodeRenderer, and add concise entries mentioning
Button disabled-state support via the new isValid prop (e.g., "Button: added
isValid prop to control disabled state") and the theme/styling updates (briefly
summarize what changed visually or theming API-wise); ensure the entries
reference "Column" and "NodeRenderer" and the new "isValid" prop so users can
quickly see the scope of changes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6dc6e20d-e7e9-4918-a179-719c16ee4a8f

📥 Commits

Reviewing files that changed from the base of the PR and between 189be6c and c0cec8b.

📒 Files selected for processing (7)
  • .changeset/tame-bears-happen.md
  • packages/genui/a2ui/src/catalog/Button/index.tsx
  • packages/genui/a2ui/src/catalog/Column/index.tsx
  • packages/genui/a2ui/src/react/A2UIRenderer.tsx
  • packages/genui/a2ui/styles/catalog/Button.css
  • packages/genui/a2ui/styles/catalog/Image.css
  • packages/genui/a2ui/styles/theme.css
💤 Files with no reviewable changes (1)
  • packages/genui/a2ui/styles/catalog/Image.css

Comment thread packages/genui/a2ui/src/react/A2UIRenderer.tsx Outdated
Sherry-hue
Sherry-hue previously approved these changes May 14, 2026
@HuJean HuJean force-pushed the p/a2ui-column-template-rendering branch from c2eeb7d to 43e34f4 Compare May 14, 2026 12:28
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/genui/a2ui/src/catalog/Column/index.tsx`:
- Around line 29-33: The Column component currently overwrites a child's
explicit dataContextPath; update the logic around childWithContext so it only
assigns props.dataContextPath when the child does not already provide one (i.e.,
if childPath is falsy and the child lacks dataContextPath then set
dataContextPath = props.dataContextPath), preserving any existing
child.dataContextPath; locate the assignment using the variables
childWithContext, childPath and dataContextPath and change the branching to
inherit parent dataContextPath only when the child has no predefined
dataContextPath.
- Around line 81-100: childList is memoizing actual ComponentInstance objects
from surface.components which can mutate in place and cause stale renders;
change this by stopping memoization of resolved components—either remove the
useMemo around childList and compute children each render, or have childList
memoize only IDs/paths/keys (e.g., the children array, template.componentId,
item keys and itemPath) and call buildChild/surface.components lookup during
render so the latest ComponentInstance is used; update references to
childList/buildChild accordingly and remove the now-unused useMemo import.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 69bf241e-2939-4647-9833-15524f6c57b2

📥 Commits

Reviewing files that changed from the base of the PR and between c2eeb7d and 43e34f4.

📒 Files selected for processing (7)
  • .changeset/tame-bears-happen.md
  • packages/genui/a2ui/src/catalog/Button/index.tsx
  • packages/genui/a2ui/src/catalog/Column/index.tsx
  • packages/genui/a2ui/src/react/A2UIRenderer.tsx
  • packages/genui/a2ui/styles/catalog/Button.css
  • packages/genui/a2ui/styles/catalog/Image.css
  • packages/genui/a2ui/styles/theme.css
💤 Files with no reviewable changes (1)
  • packages/genui/a2ui/styles/catalog/Image.css
✅ Files skipped from review due to trivial changes (1)
  • .changeset/tame-bears-happen.md
🚧 Files skipped from review as they are similar to previous changes (4)
  • packages/genui/a2ui/styles/theme.css
  • packages/genui/a2ui/src/catalog/Button/index.tsx
  • packages/genui/a2ui/src/react/A2UIRenderer.tsx
  • packages/genui/a2ui/styles/catalog/Button.css

Comment thread packages/genui/a2ui/src/catalog/Column/index.tsx
Comment thread packages/genui/a2ui/src/catalog/Column/index.tsx
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented May 14, 2026

Merging this PR will degrade performance by 6.81%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 1 improved benchmark
❌ 1 regressed benchmark
✅ 79 untouched benchmarks
⏩ 26 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
002-hello-reactLynx-destroyBackground 670.3 µs 916.9 µs -26.9%
008-many-use-state-destroyBackground 9.5 ms 8 ms +18.79%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing p/a2ui-column-template-rendering (e36b253) with main (ee79eff)2

Open in CodSpeed

Footnotes

  1. 26 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

  2. No successful run was found on main (d55deae) during the generation of this report, so ee79eff was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 14, 2026

React External

#1351 Bundle Size — 695.33KiB (0%).

e36b253(current) vs d55deae main#1346(baseline)

Bundle metrics  no changes
                 Current
#1351
     Baseline
#1346
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
No change  Cache Invalidation 0% 0%
No change  Chunks 0 0
No change  Assets 3 3
No change  Modules 17 17
No change  Duplicate Modules 5 5
No change  Duplicate Code 8.59% 8.59%
No change  Packages 0 0
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#1351
     Baseline
#1346
No change  Other 695.33KiB 695.33KiB

Bundle analysis reportBranch p/a2ui-column-template-renderingProject dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 14, 2026

React Example

#8237 Bundle Size — 237.15KiB (0%).

e36b253(current) vs d55deae main#8232(baseline)

Bundle metrics  no changes
                 Current
#8237
     Baseline
#8232
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
No change  Cache Invalidation 0% 0%
No change  Chunks 0 0
No change  Assets 4 4
No change  Modules 197 197
No change  Duplicate Modules 80 80
No change  Duplicate Code 44.89% 44.89%
No change  Packages 2 2
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#8237
     Baseline
#8232
No change  IMG 145.76KiB 145.76KiB
No change  Other 91.39KiB 91.39KiB

Bundle analysis reportBranch p/a2ui-column-template-renderingProject dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 14, 2026

React Example with Element Template

#504 Bundle Size — 199.83KiB (0%).

e36b253(current) vs d55deae main#499(baseline)

Bundle metrics  Change 2 changes
                 Current
#504
     Baseline
#499
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
No change  Cache Invalidation 0% 0%
No change  Chunks 0 0
No change  Assets 4 4
Change  Modules 88(+1.15%) 87
No change  Duplicate Modules 26 26
Change  Duplicate Code 40.01%(-0.1%) 40.05%
No change  Packages 2 2
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#504
     Baseline
#499
No change  IMG 145.76KiB 145.76KiB
No change  Other 54.08KiB 54.08KiB

Bundle analysis reportBranch p/a2ui-column-template-renderingProject dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 14, 2026

React MTF Example

#1370 Bundle Size — 208.1KiB (0%).

e36b253(current) vs d55deae main#1365(baseline)

Bundle metrics  no changes
                 Current
#1370
     Baseline
#1365
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
No change  Cache Invalidation 0% 0%
No change  Chunks 0 0
No change  Assets 3 3
No change  Modules 192 192
No change  Duplicate Modules 77 77
No change  Duplicate Code 44.4% 44.4%
No change  Packages 2 2
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#1370
     Baseline
#1365
No change  IMG 111.23KiB 111.23KiB
No change  Other 96.86KiB 96.86KiB

Bundle analysis reportBranch p/a2ui-column-template-renderingProject dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 14, 2026

Web Explorer

#9811 Bundle Size — 901.35KiB (0%).

e36b253(current) vs d55deae main#9806(baseline)

Bundle metrics  Change 2 changes
                 Current
#9811
     Baseline
#9806
No change  Initial JS 45.06KiB 45.06KiB
No change  Initial CSS 2.22KiB 2.22KiB
No change  Cache Invalidation 0% 0%
No change  Chunks 9 9
No change  Assets 11 11
Change  Modules 227(-1.3%) 230
No change  Duplicate Modules 11 11
Change  Duplicate Code 27.23%(+0.07%) 27.21%
No change  Packages 10 10
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#9811
     Baseline
#9806
No change  JS 497.08KiB 497.08KiB
No change  Other 402.06KiB 402.06KiB
No change  CSS 2.22KiB 2.22KiB

Bundle analysis reportBranch p/a2ui-column-template-renderingProject dashboard


Generated by RelativeCIDocumentationReport issue

@HuJean HuJean enabled auto-merge (squash) May 14, 2026 13:15
@HuJean HuJean merged commit a4692da into main May 14, 2026
112 of 115 checks passed
@HuJean HuJean deleted the p/a2ui-column-template-rendering branch May 14, 2026 14:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants