feat: dev-only MagicPreview catalog framework#7
Open
anilcancakir wants to merge 5 commits into
Open
Conversation
Add the MagicPreview framework: a PreviewEntry contract, a
MagicPreviewCatalog (sidebar nav + per-preview side-by-side light/dark
panes + a global toggle bound to wind's WindThemeController), and a
/preview ShellRoute with :component children registered through magic's
router. The catalog is dev-only: registerRoutes() is gated by
kReleaseMode + a const bool.fromEnvironment('PREVIEW_ENABLED') and snapshots
entries inside the function body, so release builds tree-shake the whole
catalog (verified in Step 19). Adds the fluttersdk_wind dependency.
Three runtime defects the analyze/build/unit-test gates missed, caught by actually running the app in a browser: - The catalog group's index child path '/' composed to '/preview/', which trips go_router's trailing-slash assertion and blanked the WHOLE app on every route. Index child path is now '' (composes to '/preview'). - Each light/dark preview pane used a bare WindThemeData with no aliases, so component semantic tokens resolved to no-ops and previews rendered Flutter's red unstyled-text fallback. Panes now copyWith(brightness:) the ambient app theme, keeping aliases + brand colors. - The preview surface and panes now scroll (vertical surface, horizontal panes) so wide variant matrices no longer overflow the side-by-side layout. Release strip re-verified: the catalog still tree-shakes from release.
The catalog used a persistent ShellRoute whose _PreviewShell read stale global pathParameters and never rebuilt when only the child route swapped, so /preview/<slug> always showed the first entry. Replace it with two plain pages: /preview (index) and /preview/:component, the latter receiving the slug in its builder and rebuilding on navigation. Add a regression test asserting both paths register and none ends with '/' (the boot-crash guard).
…ADME Keep a Changelog section order; replace em-dashes with ':'/';'/',' in the README to satisfy the no-em-dash convention. Content unchanged.
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Pull request overview
Adds a dev-only MagicPreview component catalog to magic_devtools, exposing a /preview index and /preview/:component deep link along with the PreviewEntry contract and catalog UI backed by fluttersdk_wind.
Changes:
- Introduces
MagicPreviewregistration + route wiring, gated behindkReleaseModeandPREVIEW_ENABLED. - Adds
MagicPreviewCatalogUI that renders each selected preview in side-by-side light/dark panes and binds a global theme toggle toWindThemeController. - Adds widget/unit tests for route registration and catalog behavior; updates docs/changelog and adds the
fluttersdk_winddependency.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| test/preview/preview_routes_test.dart | Exercises MagicPreview.register() and registerRoutes() behavior and guards against bad route paths. |
| test/preview/magic_preview_test.dart | Widget-tests catalog rendering in both brightnesses and the wind theme toggle binding. |
| lib/src/preview/preview_routes.dart | Implements MagicPreview registry and registers /preview + /preview/:component routes behind release/dev guards. |
| lib/src/preview/magic_preview.dart | Defines PreviewEntry and the MagicPreviewCatalog sidebar + dual-pane preview UI. |
| lib/preview.dart | Adds public barrel export for the preview catalog framework. |
| README.md | Documents the new preview catalog barrel and wiring guidance. |
| CHANGELOG.md | Records the new preview catalog framework and related fixes/behavior. |
| pubspec.yaml | Adds fluttersdk_wind dependency required by the catalog UI. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+8
to
+13
| /// Defaults to [kDebugMode]: the catalog is reachable in debug and profile | ||
| /// builds, never in release. A host can force it off in any mode with | ||
| /// `--dart-define=PREVIEW_ENABLED=false`. Because this is a `const`, the | ||
| /// release-mode optimizer can fold the guarded branch in | ||
| /// [MagicPreview.registerRoutes] dead and tree-shake the entire catalog, | ||
| /// every [PreviewEntry], and every builder it transitively references. |
Comment on lines
+40
to
+54
| /// The registered previews. Populated by [register]; empty until then. | ||
| static List<PreviewEntry> _entries = const <PreviewEntry>[]; | ||
|
|
||
| /// The currently registered previews (read-only view). | ||
| static List<PreviewEntry> get entries => List.unmodifiable(_entries); | ||
|
|
||
| /// Register the catalog [entries]. | ||
| /// | ||
| /// Call this BEFORE [registerRoutes], typically from the consumer's | ||
| /// `RouteServiceProvider.boot()`. In release builds the guard in | ||
| /// [registerRoutes] short-circuits, so even if entries are registered they | ||
| /// are never wired into a route and stay tree-shakeable. | ||
| static void register(List<PreviewEntry> entries) { | ||
| _entries = entries; | ||
| } |
Comment on lines
+32
to
+36
| Three import barrels: | ||
|
|
||
| - `package:magic_devtools/dusk.dart` — `MagicDuskIntegration` registers 14 Magic-aware enrichers into fluttersdk_dusk's snapshot pipeline. | ||
| - `package:magic_devtools/telescope.dart` — `MagicTelescopeIntegration` registers 5 Magic watchers and `MagicHttpFacadeAdapter` into fluttersdk_telescope. | ||
| - `package:magic_devtools/dusk.dart`: `MagicDuskIntegration` registers 14 Magic-aware enrichers into fluttersdk_dusk's snapshot pipeline. | ||
| - `package:magic_devtools/telescope.dart`: `MagicTelescopeIntegration` registers 5 Magic watchers and `MagicHttpFacadeAdapter` into fluttersdk_telescope. | ||
| - `package:magic_devtools/preview.dart`: `MagicPreview` hosts a dev-only component preview catalog behind a `/preview` ShellRoute, tree-shaken from release builds. |
Comment on lines
+3
to
+7
| /// Import this file to host the auto-discovered component previews behind a | ||
| /// `/preview` ShellRoute. The whole surface is dev-only: it is reachable only | ||
| /// through [MagicPreview.registerRoutes], which is guarded by `kReleaseMode` + | ||
| /// `bool.fromEnvironment('PREVIEW_ENABLED')` and tree-shaken from release | ||
| /// builds. |
Comment on lines
+74
to
+76
| /// Invoked when a sidebar item is tapped. The `/preview` ShellRoute wires | ||
| /// this to navigation; when null, selection updates local state only. | ||
| final ValueChanged<PreviewEntry>? onSelect; |
Comment on lines
+6
to
+12
| /// Tests for [MagicPreview]'s registration entrypoint and the `/preview` | ||
| /// ShellRoute it wires into [MagicRouter]. | ||
| /// | ||
| /// The release boundary itself (the `kReleaseMode` early return + tree-shaking) | ||
| /// is asserted by Step 19 (a release-bundle symbol grep); these tests cover the | ||
| /// debug-mode behavior: entries round-trip, and `registerRoutes` adds exactly | ||
| /// one `magic-preview` layout BEFORE the router locks. |
Comment on lines
+12
to
+16
| - `MagicPreview` framework: a dev-only component preview catalog hosted behind a | ||
| `/preview` ShellRoute. New `package:magic_devtools/preview.dart` barrel exports | ||
| the `PreviewEntry` contract (`label`, `slug`, `builder`), the | ||
| `MagicPreviewCatalog` widget (sidebar nav plus a light/dark pair per preview, | ||
| with a global theme toggle bound to wind's `WindTheme.of(context).toggleTheme()`), |
The catalog now shows one preview pane under the ambient wind theme; the header "Toggle theme" button flips brightness for the whole catalog. A single pane also mounts each controller-backed feature-screen preview once, avoiding the duplicate-mount churn of the two-pane layout.
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.
Adds the
MagicPreviewcatalog (PreviewEntry contract, sidebar nav, side-by-side light/dark panes bound to WindThemeController) + the/previewpage and/preview/:componentdeep link. Dev-only: gated by kReleaseMode + PREVIEW_ENABLED, tree-shaken from release (verified). Adds fluttersdk_wind dep. analyze 0, 95 tests.Cross-repo: this design-first component system spans 5 repos. Land in dependency order: wind (WindRecipe + 5 primitives) first, then magic (design:sync/lint, previews:refresh, make:component) and magic_devtools (preview catalog) which consume wind, then magic_starter (component library + view rewrite), then magic_example (consumer app). Branches are all
feat/design-first-component-system. Verified locally end-to-end (analyze 0, full suites green, real-browser e2e of the /preview catalog, release-strip confirmed).