feat(examples): unified todo apps with SSR, MobX, and E2E suite#7424
Merged
Conversation
5 tasks
14ce63c to
356e778
Compare
chrisdholt
previously approved these changes
May 22, 2026
Member
chrisdholt
left a comment
There was a problem hiding this comment.
Chromium test issues? Flaky or broken?
Collaborator
Author
No, just missing a changefile 🙃 |
… 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>
cadf2fd to
005dd49
Compare
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>
chrisdholt
approved these changes
May 22, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pull Request
📖 Description
Adds a complete, unified Todo example surface to the
examples/treethat 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 declarativeFAST HTML templates with
@microsoft/webuiprerendering and@microsoft/fast-htmlclient-side hydration viaRenderableFASTElement+defineAsync(defer-and-hydrate).examples/csr/todo-app,examples/csr/todo-mobx-app, and the new SSRapp render the same heading, form, filter
<select>, list, andfooter. The MobX app collapsed from five components to one to match
the canonical layout while keeping the MobX bridge (singleton store,
makeAutoObservable, singleautorun) intact.X items left · Y completed) in every todoapp, finally surfacing the previously-unused computed counters on
each store / state.
@microsoft/fast-examples-e2eworkspace (examples/test/)with a shared Playwright suite that runs identically against every
app via per-project DOM adapters. Specs use the
.pw.spec.tssuffixso we can add Node
.spec.tstests later without collision.npm run test:e2eis wired intoci-validate-pr.ymlas aseparate step after the existing unit-test job.
@microsoft/webuibumped to 0.0.6 across the workspace.This supersedes the approach from #7362 and replaces the older
imperative
webui-todo-appexample.🎫 Issues
👩💻 Reviewer Notes
A few intentional choices worth a closer look:
@volatileonDefaultTodoList.activeCount/completedCount—required because the initial
_todosarray is empty, so without@volatileFAST captures the dependency graph only on firstevaluation and never subscribes to
item.donefor items added later.Inline comments document this.
syncCounts()in the SSR app — same pattern as theexisting
syncDescription()workaround for the fast-html text-bindinghydration mismatch. SSR initial render does not include the counter
text; it is populated client-side after hydration.
examples/test/— both CSR apps sharecreateCsrAdapter()since their unified UI exposes the sameselectors; the SSR app has its own adapter because items are rendered
through a nested
<todo-item>shadow root. Seeexamples/test/DESIGN.mdfor thecontributor guide.
📑 Test Plan
npm run build— succeeds for all packages and example workspaces.npm run biome:check— passes.CI=1 npm run test:e2e— 21/21 passing across all three projects(6 baseline scenarios + 1 new footer-counters scenario × 3 apps).
npm run test—fast-elementandfast-htmlunit tests pass.Pre-existing Firefox flakiness in
fast-test-harness(page.gototimeouts) is unrelated to this work; Chromium passes 46/46.
npm run checkchange— no change file needed (nopackages/*source edits).
✅ Checklist
General
$ npm run change⏭ Next Steps
@volatileon getters iterating reactive arrays — worth confirmingwhether this is by design or a bug that should be fixed in
fast-element.