This file provides guidance to Claude Code (claude.ai/code) when working inside example/. The parent project at ../CLAUDE.md and its .claude/rules/*.md files load first; this file adds example-app-specific rules on top.
example/ is a standalone Flutter app (own pubspec.yaml, analysis_options.yaml, web/android/ios/desktop targets) that boots lib/main.dart into a navigable showcase gallery. It serves as the canonical visual reference embedded at fluttersdk.com/wind via per-page iframes.
Wind itself is consumed via pubspec.yaml: fluttersdk_wind: { path: ../ }. A code change in ../lib/ is visible here on the next hot-reload; the example app is the manual smoke test for the parent package.
The standalone JSON playground formerly hosted here (lib/play.dart, lib/playground.dart) has been migrated to the wind_playground_web package in the fluttersdk.com repository. The wind package only ships the demo gallery now.
There is NO auto-discovery. Pages are wired by hand in lib/routes.dart. To add one:
- Create the page file at
lib/pages/<category>/<feature>_basic.dart. File name is snake_case; class name is<Feature>BasicExamplePage(PascalCase, ends inExamplePage). Page shape (rootWDivwithscrollPrimary: true,_buildHeader+_buildSectionhelpers, dark-mode pairs on every color token) is governed by../.claude/rules/example-pages.md— read it before writing the page body. - Add
import 'pages/<category>/<feature>_basic.dart';to the top oflib/routes.dart(alphabetically inside its category block). - Add
'/<category>/<feature>_basic': const <Feature>BasicExamplePage(),to theappRoutesmap at the bottom oflib/routes.dart.
Verify by running flutter run -d chrome and navigating to /<category>/<feature>_basic. The route key MUST exactly match the file basename (sans .dart) — the docs website uses this URL to iframe the page.
A doc file at ../doc/<section>/<page>.md embeds an example page via:
<x-preview path="<category>/<feature>_basic" size="md" source="example/lib/pages/<category>/<feature>_basic.dart"></x-preview>The docs website resolves this by iframing the deployed web build at /<category>/<feature>_basic. Three things MUST hold for the iframe to render:
- The
pathattribute matches a key inappRoutesexactly. Case-sensitive. Snake_case only — kebab-case caused 8 doc 404s in commita2dee86and was reverted globally. - The
sourceattribute is the repo-root-relative path to the actual.dartfile. - The route exists in
lib/routes.dartAND the page widget compiles cleanly underflutter build web --target lib/main.dart.
If you rename, move, or delete a page, grep ../doc/ for the old path= / source= value FIRST. Update or remove every matching x-preview in the same change set. A stale x-preview is a broken doc.
Empty path="" is the documented special case for the root / route → installation_basic.dart.
The size="sm|md|lg" attribute is interpreted by the docs website's iframe wrapper CSS only; the example page itself renders to whatever viewport it gets. Do not branch on size inside Dart.
The docs website iframes a deployed web build of lib/main.dart and navigates to /<route> per <x-preview>. Pages must work inside an iframe with unpredictable height:
- Root widget of every page is
WDiv(className: 'w-full h-full overflow-y-auto p-4', scrollPrimary: true, child: ...). SkippingscrollPrimary: truebreaks iOS Safari tap-to-top inside the iframe. - No hard-coded width or height that exceeds typical iframe dimensions (1024 wide is safe; > 1280 risks horizontal scroll in narrow embed contexts).
- No
Navigator.of(context).pop(),SystemNavigator.pop(),dart:jswindow manipulation, or anything that escapes the iframe sandbox. - No real network calls (HTTP 400 in the test binding, hang in the production iframe). Use static fixtures.
lib/main.dart wraps the gallery in WindTheme(data: windTheme, builder: (ctx, controller) => MaterialApp(theme: controller.toThemeData(), routes: appRoutes.map(...), ...)). The floating theme-toggle FAB in AppLayout calls context.windTheme.toggleTheme().
fluttersdk_wind: { path: ../ }— local path to the parent. Do not bump to a pub.dev version; the example tests pre-release parent code.google_fonts: ^6.1.0— pulled by some pages for non-system font demos.
pubspec.lock is committed (this is an application, not a library). Do not delete it.
lib/routes.dartroute keys — renaming a route silently breaks every doc page that links to it. Run a grep across../doc/BEFORE renaming.web/index.html,web/manifest.json— standard Flutter web scaffolding. Editing them changes the iframe-host page chrome; coordinate with the docs site before touching.
The 90% coverage gate enforced by ../tool/coverage.sh 90 measures the PARENT package only (../lib/src/). The example app contributes nothing to coverage. Tests for new parent features go to ../test/.
../CLAUDE.md— Wind-wide stack, commands, post-change sync discipline (which lists example/lib/pages/ as one of the 5 surfaces every code change updates), coverage policy.../.claude/rules/example-pages.md(paths: example/lib/pages/**) — per-page file shape, helpers (_buildHeader,_buildSection), dark-mode pair rule, naming convention.../.claude/rules/docs.md(paths: doc/**) — the doc-side half of the<x-preview>contract.../.claude/rules/dynamic.md(paths: {lib/src/dynamic,test/dynamic}/**) —WDynamicschema and security model.