diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 7f0567668bf..002b8f244de 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -38,6 +38,7 @@ Each package includes a DESIGN.md file, read that to gain a general understandin - `examples/design-system/` — Shared semantic design tokens (`@microsoft/fast-examples-design-system`) consumed by all example apps. - `examples/csr/todo-app/` — A simple To-Do app demonstrating FAST usage patterns and using the shared `@microsoft/fast-examples-design-system` tokens. - `examples/csr/todo-mobx-app/` — A To-Do app demonstrating how to integrate MobX state with `@microsoft/fast-element` using a single `autorun` per component (no custom bridge code). +- `examples/ssr/webui-todo-app/` — A To-Do app demonstrating FAST declarative HTML with `@microsoft/webui` prerendering and `@microsoft/fast-html` hydration. Light theme. ## Skills diff --git a/examples/DESIGN.md b/examples/DESIGN.md index 9d908241f3a..be532c63ffe 100644 --- a/examples/DESIGN.md +++ b/examples/DESIGN.md @@ -1,10 +1,10 @@ # FAST example apps — design guidance This document is the workspace-level guide for building UI in `examples/*` -and its rendering-strategy subfolders (currently `examples/csr/`). It -explains how the apps share a visual language, the constraints every example -must follow, and the rules that humans and coding agents should apply when -making changes. The token vocabulary itself lives in +and its rendering-strategy subfolders (`examples/csr/` and `examples/ssr/`). +It explains how the apps share a visual language, the constraints every +example must follow, and the rules that humans and coding agents should +apply when making changes. The token vocabulary itself lives in [`design-system/DESIGN.md`](./design-system/DESIGN.md); read that file alongside this one. @@ -157,8 +157,10 @@ document.documentElement.removeAttribute("data-theme"); // restore system ``` For an intentionally single-theme app — like -[`todo-app`](./todo-app/) — hard-code the attribute in markup -(``) and never touch it from JavaScript. +[`csr/todo-app`](./csr/todo-app/) and +[`ssr/webui-todo-app`](./ssr/webui-todo-app/) — hard-code the attribute in +markup (`` or ``) and never +touch it from JavaScript. ## Authoring rules diff --git a/examples/README.md b/examples/README.md index dbc01138c1e..a5a1d7d56aa 100644 --- a/examples/README.md +++ b/examples/README.md @@ -12,10 +12,11 @@ FAST patterns in a complete app context. | `design-system` | `@microsoft/fast-examples-design-system` | Shared CSS design tokens (no JS) consumed by every example app. | | `csr/todo-app` | `@microsoft/fast-todo-app-example` | A To-Do app demonstrating `@microsoft/fast-element` patterns end to end, styled with the shared design-system tokens (light theme, no runtime toggle). | | `csr/todo-mobx-app` | `@microsoft/fast-todo-mobx-app-example` | A To-Do app showing how to integrate MobX state with `@microsoft/fast-element` using a single `autorun` per component (no custom bridge code), styled with the shared design-system tokens. | +| `ssr/webui-todo-app` | `@microsoft/fast-webui-todo-app-example` | A To-Do app pre-rendered by `@microsoft/webui` and hydrated by `@microsoft/fast-html`, styled with the shared design-system tokens (light theme, no runtime toggle). | Example apps are grouped by rendering strategy. Client-side-rendered (CSR) -apps live under [`examples/csr/`](./csr/); future server-side-rendered (SSR) -apps will live alongside them under their own subfolder. +apps live under [`examples/csr/`](./csr/) and server-side-rendered (SSR) apps +live under [`examples/ssr/`](./ssr/). ## Shared design system @@ -51,17 +52,20 @@ See: ## Creating a new example app 1. Scaffold a new folder under the appropriate rendering-strategy subfolder - (CSR apps go under `examples/csr//`). -2. Use [`examples/csr/todo-app/`](./csr/todo-app/) as a reference for - `package.json`, `tsconfig.json`, `vite.config.ts`, and `index.html`. -3. Add `"@microsoft/fast-examples-design-system": "workspace:*"` to the new + (CSR apps go under `examples/csr//`; SSR apps go under + `examples/ssr//`). +2. Use [`examples/csr/todo-app/`](./csr/todo-app/) as a reference for CSR + apps, or [`examples/ssr/webui-todo-app/`](./ssr/webui-todo-app/) as a + reference for SSR apps (`package.json`, `tsconfig.json`, build config, + entry HTML). +3. Add `"@microsoft/fast-examples-design-system": "^1.0.0"` to the new app's `dependencies` and run `npm install` from the repo root. 4. Import `@microsoft/fast-examples-design-system/tokens.css` exactly once at - the app entry point (typically `src/main.ts`). For an intentionally - single-theme app, hard-code `` (or `"dark"`) - in `index.html` and never touch it from JavaScript. + the app entry point (typically `src/main.ts` or `src/index.ts`). For an + intentionally single-theme app, hard-code `` (or + `"dark"`) in the entry HTML and never touch it from JavaScript. 5. Reference tokens via `var(--fast-...)` in component `css` template - literals — do not hard-code design values. + literals or `.css` files — do not hard-code design values. 6. If the app needs a theme toggle, set or remove the `data-theme` attribute on `` from your app code: ```ts @@ -86,6 +90,7 @@ For the existing example apps: ```shell npm start -w @microsoft/fast-todo-app-example npm start -w @microsoft/fast-todo-mobx-app-example +npm start -w @microsoft/fast-webui-todo-app-example ``` ## Useful links diff --git a/examples/ssr/webui-todo-app/DESIGN.md b/examples/ssr/webui-todo-app/DESIGN.md new file mode 100644 index 00000000000..e6f15347c2d --- /dev/null +++ b/examples/ssr/webui-todo-app/DESIGN.md @@ -0,0 +1,142 @@ +# WebUI Todo App — design and architecture + +This document describes the SSR todo example in +`examples/ssr/webui-todo-app/`. For the shared token catalog and naming rules, +see [`../../design-system/README.md`](../../design-system/README.md) and +[`../../design-system/DESIGN.md`](../../design-system/DESIGN.md). + +## Purpose + +This example demonstrates three pieces working together: + +- FAST declarative templates stored as co-located `*.html` and `*.css` files. +- `@microsoft/webui` prerendering on the server, including Declarative Shadow + DOM output. +- Client-side hydration through `@microsoft/fast-html`, so the prerendered UI + becomes interactive without re-rendering from scratch. + +The app stays intentionally small: a single todo list with add, toggle, and +delete behavior backed by a JSON state file. + +## Folder structure + +```text +examples/ssr/webui-todo-app/ +├── DESIGN.md +├── README.md +├── data/ +│ └── state.json +├── src/ +│ ├── index.html +│ ├── index.ts +│ ├── todo-app/ +│ │ ├── todo-app.css +│ │ ├── todo-app.html +│ │ └── todo-app.ts +│ └── todo-item/ +│ ├── todo-item.css +│ ├── todo-item.html +│ └── todo-item.ts +├── package.json +└── tsconfig.json +``` + +### File roles + +- `src/index.html` — document shell, page-level layout, and static + `data-theme="light"` selection. +- `src/index.ts` — hydration entry; imports shared `tokens.css`, registers the + custom elements, and defines ``. +- `src/todo-app/` — root template, styles, and list management logic. +- `src/todo-item/` — per-row template, styles, and event dispatch for toggle + and delete actions. +- `data/state.json` — initial server state consumed by `webui serve`. + +## Build and serve flow + +1. `npm run build -w @microsoft/fast-webui-todo-app-example` runs esbuild on + `src/index.ts`. +2. Esbuild emits `dist/index.js` for hydration and bootstrap code. +3. Because `src/index.ts` imports + `@microsoft/fast-examples-design-system/tokens.css`, esbuild also emits + `dist/index.css`. +4. `webui serve ./src --state ./data/state.json --plugin=fast --servedir ./dist` + uses `./src` as the source root for HTML templates and exposes the bundled + assets from `./dist`. +5. On each request, `webui` reads `src/index.html`, resolves `{{}}` bindings + from `data/state.json`, renders Declarative Shadow DOM, and returns + prerendered HTML. +6. In the browser, `/index.js` defines the FAST custom elements and hydrates the + prerendered DOM in place. +7. `/index.css` makes the shared `--fast-*` tokens available to both the page + shell and shadow-root component styles. + +## Component model + +### `todo-app` + +`todo-app` is the root custom element. It: + +- reads the prerendered `` children during `prepare()`, +- converts them into an observable `items` array, +- tracks `remainingCount`, +- handles add, toggle, and delete operations, and +- re-renders the list through FAST bindings after hydration. + +### `todo-item` + +`todo-item` is a focused row component. It accepts `id`, `title`, and `state` +attributes, then emits `toggle-item` and `delete-item` events that the parent +handles. + +## Design system wiring + +This example consumes the shared +`@microsoft/fast-examples-design-system` workspace package. + +- `src/index.ts` imports `@microsoft/fast-examples-design-system/tokens.css` + exactly once. +- `src/index.html` links the generated `/index.css` bundle before its inline + page-shell styles. +- `` hard-codes the + light theme at document level. +- There is no runtime theme toggle, no theme persistence, and no JavaScript + that mutates `data-theme`. + +The design-system package is CSS-only. This example just consumes the +registered custom properties through `var(--fast-...)`. + +## Representative tokens + +The component styles rely on shared tokens rather than hard-coded design +values. Representative examples include: + +- Page shell: `--fast-background-web-page-primary`, + `--fast-foreground-ctrl-neutral-primary-rest`, + `--fast-padding-content-xx-large`. +- Root card and section chrome: `--fast-background-layer-primary-solid`, + `--fast-stroke-divider-subtle`, `--fast-corner-large`, + `--fast-shadow-card-rest`. +- Typography: `--fast-text-style-default-regular-font-family`, + `--fast-text-global-body3-font-size`, + `--fast-text-global-body3-line-height`, + `--fast-text-global-title1-font-size`, + `--fast-text-global-title1-line-height`. +- Brand actions: `--fast-background-ctrl-brand-rest`, + `--fast-background-ctrl-brand-hover`, + `--fast-background-ctrl-brand-pressed`, + `--fast-foreground-ctrl-on-brand-rest`. +- Focus and motion: `--fast-ctrl-focus-outer-stroke`, + `--fast-ctrl-focus-outer-stroke-width`, `--fast-duration-fast`, + `--fast-curve-easy-ease`. +- Status states: `--fast-status-success-tint-foreground`, + `--fast-status-success-tint-background`, + `--fast-status-danger-tint-foreground`, + `--fast-status-danger-tint-background`. + +## Why this example lives under `examples/ssr/` + +Although the UI hydrates into client-side FAST components, the initial render is +produced through `@microsoft/webui` on the server. The important example +behavior is therefore SSR + prerendering + hydration, not a purely client-only +bootstrap. diff --git a/examples/ssr/webui-todo-app/README.md b/examples/ssr/webui-todo-app/README.md new file mode 100644 index 00000000000..26c8c286b25 --- /dev/null +++ b/examples/ssr/webui-todo-app/README.md @@ -0,0 +1,124 @@ +# WebUI Todo App + +A Todo app demonstrating FAST declarative HTML templates with +[webui](https://github.com/microsoft/webui) prerendering and hydration. + +This example shows how to combine `@microsoft/fast-html` declarative templates +with `@microsoft/webui` for server-side prerendering, producing a fast initial +render that hydrates into a fully interactive FAST web component application. + +## Features + +- **Declarative templates**: Uses `.html` and `.css` files instead of + imperative `html`/`css` tagged template literals +- **Server-side prerendering**: `webui serve` compiles declarative templates + and renders initial state into static HTML +- **Client-side hydration**: `@microsoft/fast-html` picks up prerendered DOM + and attaches FAST reactive bindings +- **Todo functionality**: Add items, toggle completion, delete items, + remaining count + +## Prerequisites + +From the monorepo root, install dependencies and build packages: + +```bash +npm ci +npm run build +``` + +## Running + +```bash +# Build client bundle and start the webui dev server +npm start -w @microsoft/fast-webui-todo-app-example +``` + +The app will be available at `http://localhost:8081`. + +For development with live reloading, run the client and server in separate +terminals: + +```bash +# Terminal 1: Watch and rebuild client bundle +npm run start:client -w @microsoft/fast-webui-todo-app-example + +# Terminal 2: Start webui dev server with --watch +npm run start:server -w @microsoft/fast-webui-todo-app-example +``` + +## Design system + +This example consumes the shared `@microsoft/fast-examples-design-system` +workspace package. The design-system package is **CSS-only** — there are no +JavaScript or TypeScript exports. `src/index.ts` imports +`@microsoft/fast-examples-design-system/tokens.css` once, and the rest of the +app references the registered `--fast-*` design tokens through `var(...)`. + +The app uses the **light** theme. `` is set +statically in [`src/index.html`](./src/index.html); the app does not implement +a runtime theme toggle. (The shared design-system package supports dark and +system-preference themes via the same `data-theme` attribute — see +[`../../design-system/README.md`](../../design-system/README.md) — but this +example deliberately keeps the SSR surface area minimal and demonstrates only +token consumption.) + +For the shared package overview, the token catalog, and authoring rules, see +[`../../design-system/README.md`](../../design-system/README.md) and +[`../../design-system/DESIGN.md`](../../design-system/DESIGN.md). + +## Architecture + +### Server-side (`webui serve`) + +The `webui` CLI serves the app with the `--plugin=fast` flag, which enables +FAST-aware template processing: + +1. Scans `./src` for declarative HTML templates (`.html` files wrapped in + `` or containing `