Skip to content

feat(a2ui_flutter): add the gallery app - #3094

Open
andrewkolos wants to merge 29 commits into
feat/flutter-adapter-examplefrom
feat/flutter-adapter-gallery
Open

andrewkolos wants to merge 29 commits into
feat/flutter-adapter-examplefrom
feat/flutter-adapter-gallery

Conversation

@andrewkolos

@andrewkolos andrewkolos commented Oct 8, 2026 •

Copy link
Copy Markdown
Collaborator

Adds dart/a2ui_flutter/a2ui_explorer, the renderer's gallery app, as section 9 of the framework adapter blueprint describes.

Contents

  • A three column layout, as specified by section 9 of the blueprint. The left lists the v0.9 basic catalog examples. The center shows the selected example's surfaces above its messages, with Advance, Run all and Reset. The right shows each surface's live data model above a log of actions and errors.
  • Selecting an example renders all of its messages. Reset starts it over for stepping through.
  • A demo catalog: the basic catalog plus the custom components the examples name, CustomGrid and CustomSlider.
  • The app bundles the specification's examples through a link, assets/examples.
  • macOS and web, like samples/client/flutter/restaurant_finder.
gallery.mp4

Testing

A test runs and renders every example and fails on any error, and another checks that an error reported during a surface's first build reaches the log. Integration tests drive the examples through what section 9 lists: static rendering, layout, two-way binding, reactive updates, and action context inside a template, plus Advance, Run all and Reset. No example has an action inside a List template, so the template test uses a Column's.

Pre-launch Checklist

One time:

For this PR:

  • I have updated the relevant CHANGELOG.md file.
  • I updated/added relevant documentation.
  • My code changes (if any) have tests.
  • If my branch is on a fork, I have verified that scripts/e2e_test.sh passes.

ℹ️ Initial text drafted by agent

gemini-code-assist[bot]

This comment was marked as resolved.

Base automatically changed from feat/flutter-adapter-basic-catalog to main October 15, 2026 00:39
a2ui_explorer is the renderer's gallery app, as section 8 of the
framework adapter blueprint describes. It lists the v0.9 basic catalog
examples, steps through each one's messages with Advance, Run all and
Reset, and shows each surface next to its live data model and the
actions and errors it reports. A demo catalog adds the custom components
the examples name. Its integration tests drive the examples through
static rendering, layout, two-way binding, reactive updates and action
context inside a template.
@andrewkolos
andrewkolos force-pushed the feat/flutter-adapter-gallery branch from 7fc7533 to 810989d Compare October 15, 2026 00:39
#3194 renamed A2uiClientError to A2uiRendererError and
MessageProcessor.groupModel to model, and replaced EventSource.addListener
with subscribe, so the gallery no longer analyzed against main.

The demo catalog also passes the basic catalog's definitions, which the
generated component schemas reference as #/$defs/CatalogComponentCommon.
Without them every example failed to resolve its schemas and rendered
nothing.

⚠️ Agent-generated
Same ignore line #3249 added to a2ui_flutter. Pull request CI runs
Flutter stable only, but pushes to main also run beta, where the
material.dart import is reported as deprecated.

⚠️ Agent-generated
copyWith keeps the basic catalog's protocol version, title,
description and instructions, which the hand-built catalog left out.

⚠️ Agent-generated
DataModel.subscribe already skips the current value when it is
subscribed to, so the data model view no longer needs its own flag for
that. ExampleRun.dispose now disposes the whole message processor, not
only its surface group, as its doc says.

⚠️ Agent-generated
…tions

An example name or description with a newline or carriage return put a
raw line break inside a single-quoted literal, which does not compile.

⚠️ Agent-generated
flutter_markdown_plus styles links as tappable and shows a click cursor
over them, but does nothing on a tap without onTapLink. The Markdown
builder now opens the link with url_launcher.

⚠️ Agent-generated
…indow

- Each run gets new Messages, Data Model and Action Log lists, so a
  newly selected example opens at the top instead of keeping the last
  one's scroll offset. Only the lists are keyed by the run, so the
  Reset button keeps keyboard focus.
- CustomGrid's stretched column of Expanded cells threw "BoxConstraints
  forces an infinite width" inside a horizontal List. It now limits
  itself to the screen's width there, as the basic catalog's components
  do.
- The macOS window opens at 1280x800. The template's 800x600 window is
  narrower than the layout's 1120 pixel minimum, so the right column
  opened off-screen.

The Native Grid test now checks the grid's two columns, and the Markdown
test a heading's text.

⚠️ Agent-generated
Each entry now shows the action or error as toJson gives it, so an
action's time and an error's details appear, as in the TypeScript
galleries. New tests cover the errors the processor throws, the errors
a surface reports, and a deleteSurface message.

⚠️ Agent-generated
The label rounded the value, so 0.3 showed as 0, while the data model,
the basic Slider and the TypeScript galleries show 0.3. A move rounded
to a whole number could also land outside fractional bounds, or let a
slider from 0.2 to 0.8 write only its two bounds. A move now writes min
plus a whole number of steps of 1, as far as max allows.

⚠️ Agent-generated
…rately

The gallery README now says the gallery is for protocol v0.9, that the
log also holds the errors the message processor reports, and that the
examples are generated because a Flutter build does not ship assets
declared from outside the app's directory. The comments on the gallery's
processor and on examples_test say each message is checked against the
surface it leaves behind, which is what a2ui_core does, and list what
those checks allow.

⚠️ Agent-generated
scrollUntilVisible ends by jumping the list to the tile without a frame,
so the app tests tapped the tile's old position and missed for 15 of the
44 examples, leaving the first example selected. They now pump before
the tap.

A new test runs every example through ExampleRun and renders its
surfaces, failing on any logged error or exception. It catches a demo
catalog that cannot process the examples, and errors raised while they
build, without opening each example in the app. The generator test also
covers a backslash.

⚠️ Agent-generated
@andrewkolos
andrewkolos force-pushed the feat/flutter-adapter-gallery branch from b9bbaee to ce784a0 Compare October 19, 2026 03:46
Expanded takes a key itself, so the KeyedSubtree around it added
nothing.

⚠️ Agent-generated
assets/examples is a link to the specification's v0.9 basic catalog
examples, and the app loads them from its asset bundle at startup. This
replaces the generated copy in examples.g.dart and the tool that had to
be rerun whenever an example changed. A test checks that the bundle
holds every specification example.

⚠️ Agent-generated
…-gallery

Keep both the gallery and the v0.9 example entries in pubspec.yaml and
dart/a2ui_flutter/README.md.

⚠️ Agent-generated
With the resolver delivering diagnostics in a microtask, no listener in
the gallery runs during a build, so ExampleRun notifies its listeners
directly and the data-model view calls setState directly. runOutsideBuild
is deleted. A new test runs an example whose regex fails on the data the
surface first shows, through ExampleRun.

(cherry picked from commit a1a85f1)

⚠️ Agent-generated
The test that a surface error reported on first appearance reaches the
log now lives in example_run_test.dart and builds its run with the
shared _run helper. The separate mount_error_test.dart, which repeated
that setup and lacked the blank line after the license header, is gone.

(cherry picked from commit f7f9c66)

⚠️ Agent-generated
@andrewkolos
andrewkolos force-pushed the feat/flutter-adapter-gallery branch from e959dc5 to d16dba2 Compare October 25, 2026 00:23
…-gallery

Takes layer 1 cut down to the delivery fix alone, with no new public API.

⚠️ Agent-generated
@andrewkolos
andrewkolos removed this pull request from stack #3089 October 26, 2026 13:49
@andrewkolos
andrewkolos changed the base branch from main to feat/flutter-adapter-example October 26, 2026 13:51
@andrewkolos
andrewkolos added this pull request to stack #3617 October 26, 2026 13:51
…-adapter-gallery

Brings in the v0.9 example's chat field focus fix.

⚠️ Agent-generated
…-adapter-gallery

Brings in main's CI runner pin (#3613) and the v0.9 example's link fix.

⚠️ Agent-generated
@andrewkolos
andrewkolos marked this pull request as ready for review October 26, 2026 17:53
@andrewkolos
andrewkolos removed this pull request from stack #3617 October 26, 2026 18:17
@andrewkolos
andrewkolos added this pull request to stack #3628 October 26, 2026 18:17
@andrewkolos
andrewkolos removed this pull request from stack #3628 October 26, 2026 21:54

This branch has not been deployed

No deployments
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.

1 participant