Skip to content

feat(examples): unified todo apps with SSR, MobX, and E2E suite#7424

Merged
janechu merged 7 commits into
mainfrom
users/janechu/update-webui-todo-example
May 22, 2026
Merged

feat(examples): unified todo apps with SSR, MobX, and E2E suite#7424
janechu merged 7 commits into
mainfrom
users/janechu/update-webui-todo-example

Conversation

@janechu
Copy link
Copy Markdown
Collaborator

@janechu janechu commented Apr 10, 2026

Pull Request

📖 Description

Adds a complete, unified Todo example surface to the examples/ tree
that showcases the same UI and behavior across three different rendering
strategies, and backs it with a shared end-to-end test suite.

What this PR delivers:

  • examples/ssr/webui-todo-app — new SSR example built on declarative
    FAST HTML templates with @microsoft/webui prerendering and
    @microsoft/fast-html client-side hydration via
    RenderableFASTElement + defineAsync (defer-and-hydrate).
  • Unified UI across all three todo apps
    examples/csr/todo-app, examples/csr/todo-mobx-app, and the new SSR
    app render the same heading, form, filter <select>, list, and
    footer. The MobX app collapsed from five components to one to match
    the canonical layout while keeping the MobX bridge (singleton store,
    makeAutoObservable, single autorun) intact.
  • Footer counter row (X items left · Y completed) in every todo
    app, finally surfacing the previously-unused computed counters on
    each store / state.
  • New @microsoft/fast-examples-e2e workspace (examples/test/)
    with a shared Playwright suite that runs identically against every
    app via per-project DOM adapters. Specs use the .pw.spec.ts suffix
    so we can add Node .spec.ts tests later without collision.
  • CInpm run test:e2e is wired into ci-validate-pr.yml as a
    separate step after the existing unit-test job.
  • @microsoft/webui bumped to 0.0.6 across the workspace.

This supersedes the approach from #7362 and replaces the older
imperative webui-todo-app example.

🎫 Issues

👩‍💻 Reviewer Notes

A few intentional choices worth a closer look:

  • @volatile on DefaultTodoList.activeCount / completedCount
    required because the initial _todos array is empty, so without
    @volatile FAST captures the dependency graph only on first
    evaluation and never subscribes to item.done for items added later.
    Inline comments document this.
  • Imperative syncCounts() in the SSR app — same pattern as the
    existing syncDescription() workaround for the fast-html text-binding
    hydration mismatch. SSR initial render does not include the counter
    text; it is populated client-side after hydration.
  • Adapter design in examples/test/ — both CSR apps share
    createCsrAdapter() since their unified UI exposes the same
    selectors; the SSR app has its own adapter because items are rendered
    through a nested <todo-item> shadow root. See
    examples/test/DESIGN.md for the
    contributor guide.

📑 Test Plan

  • npm run build — succeeds for all packages and example workspaces.
  • npm run biome:check — passes.
  • CI=1 npm run test:e2e21/21 passing across all three projects
    (6 baseline scenarios + 1 new footer-counters scenario × 3 apps).
  • npm run testfast-element and fast-html unit tests pass.
    Pre-existing Firefox flakiness in fast-test-harness (page.goto
    timeouts) is unrelated to this work; Chromium passes 46/46.
  • npm run checkchange — no change file needed (no packages/*
    source edits).

✅ Checklist

General

  • I have included a change request file using $ npm run change
  • I have added tests for my changes.
  • I have tested my changes.
  • I have updated the project documentation to reflect my changes.
  • I have read the CONTRIBUTING documentation and followed the standards for this project.

⏭ Next Steps

  • Investigate the underlying FAST observation behavior that requires
    @volatile on getters iterating reactive arrays — worth confirming
    whether this is by design or a bug that should be fixed in
    fast-element.

@janechu janechu force-pushed the users/janechu/update-webui-todo-example branch from 14ce63c to 356e778 Compare May 21, 2026 19:30
@janechu janechu changed the title feat: add webui-todo-app example with declarative FAST HTML and webui prerendering feat(examples): unified todo apps with SSR, MobX, and E2E suite May 22, 2026
@janechu janechu marked this pull request as ready for review May 22, 2026 18:02
chrisdholt
chrisdholt previously approved these changes May 22, 2026
Copy link
Copy Markdown
Member

@chrisdholt chrisdholt left a comment

Choose a reason for hiding this comment

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

Chromium test issues? Flaky or broken?

@janechu
Copy link
Copy Markdown
Collaborator Author

janechu commented May 22, 2026

Chromium test issues? Flaky or broken?

No, just missing a changefile 🙃

janechu and others added 4 commits May 22, 2026 11:19
… prerendering

Adds a new examples/webui-todo-app that demonstrates FAST declarative HTML
templates with @microsoft/webui prerendering and client-side hydration:

- Declarative HTML templates (.html) with {{}} bindings for server rendering
  and {} bindings for client-only event handlers and refs
- CSS files co-located with component templates
- RenderableFASTElement mixin with defineAsync and defer-and-hydrate
- TemplateElement configuration with observer maps for reactive tracking
- webui CLI for serving with --plugin=fast for FAST-aware template processing
- esbuild for client-side bundling
- Initial state via data/state.json
- Todo functionality: add items, toggle completion, delete, remaining count

Based on the webui todo-fast example from microsoft/webui, adapted for
the FAST monorepo with @microsoft/webui 0.0.6.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…sign tokens

- Move examples/webui-todo-app/ → examples/ssr/webui-todo-app/ to group it
  alongside other server-side-rendered examples.
- Consume @microsoft/fast-examples-design-system via tokens.css; replace
  every hard-coded color, font size, line height, spacing, corner, stroke,
  shadow, duration, and curve with var(--fast-...) tokens.
- Hard-code the light theme via <html data-theme="light"> in index.html;
  no runtime theme switching.
- Add DESIGN.md describing folder layout, build/serve flow, component
  model, and design-system wiring.
- Update root workspaces config (examples/ssr/* in lieu of webui-todo-app),
  workspace-level README.md and DESIGN.md, and .github/copilot-instructions
  to reference the new ssr/ location.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add footer 'X items left · Y completed' to all three example todo apps
  (csr/todo-app, csr/todo-mobx-app, ssr/webui-todo-app), surfacing the
  previously-unused computed counters on each store.
- Add new @microsoft/fast-examples-e2e workspace (examples/test/) with a
  shared Playwright suite that runs against all three apps via per-project
  adapters; spec uses the .pw.spec.ts suffix and testMatch leaves .spec.ts
  free for future Node tests.
- Wire 'npm run test:e2e' as a separate step in ci-validate-pr.yml.
- Unify csr/todo-mobx-app UI with the canonical csr/todo-app (single
  template + styles, drop separate todo-list/-item/-filter/-stats
  components, mirror MobX store via a single autorun).
- Refresh the SSR webui-todo-app to match the same unified UI; counters
  are filled imperatively via syncCounts() to work around the fast-html
  text-binding hydration mismatch (same pattern as syncDescription()).
- Use @volatile on DefaultTodoList.activeCount/completedCount so the
  getter re-tracks per-item .done subscriptions on every evaluation
  (initial array is empty, so without @volatile FAST never subscribes
  to later items).
- Bump @microsoft/webui to 0.0.6 across the workspace.
- Add DESIGN.md for examples/test/ with adapter architecture and contributor
  guidance.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@janechu janechu force-pushed the users/janechu/update-webui-todo-example branch from cadf2fd to 005dd49 Compare May 22, 2026 18:22
janechu and others added 3 commits May 22, 2026 11:41
The SSR webui-todo-app's ./start:server uses webui serve --watch, which
opens a livereload SSE channel and reloads the page when the app mutates
its in-memory state. In CI that turned every test that adds a todo into
an endless reload loop where Playwright saw the submit button detach and
re-attach with no opportunity to enable, hanging "adds a new todo" and
the four tests that build on it for 30s before failing.

Add a start:e2e script that builds and serves without --watch, and point
the Playwright webServer at it. Local dev workflow (npm start) is
unchanged.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Run npm run build -w @microsoft/fast-element to refresh the bundle size
table after rebasing on main. CDN Rollup Bundle size moved a few bytes
(67.59 -> 67.67 KB) due to upstream dependency changes; final-validation
checks SIZES.md is committed in sync with the actual bundle output.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@janechu janechu merged commit 13916c1 into main May 22, 2026
14 checks passed
@janechu janechu deleted the users/janechu/update-webui-todo-example branch May 22, 2026 21:01
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.

2 participants