You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Remix is intended to be a composable design system, but the dashboard, examples, and much of the test harness currently make MaterialApp + Scaffold look like a runtime requirement. That creates two problems:
Consumers cannot tell which infrastructure Remix actually requires when it is embedded in a MaterialApp, CupertinoApp, WidgetsApp, router-based application, or another design system.
App-shell behavior can accidentally mask overlay bugs. The dashboard toast inserts a raw OverlayEntry; that entry is built under the target Overlay, not under its trigger's subtree, so it loses the route-local DefaultTextStyle. Under MaterialApp, the remaining app-level style is intentionally the red/yellow warning style, which caused the observed toast regression.
The current implementation confirms that Remix core does not use MaterialApp, Scaffold, Drawer, ScaffoldMessenger, or ThemeData. Those are dashboard concerns today. However, packages/remix/lib still has 28 material.dart imports for convenience constants/default icons and enables uses-material-design, while packages/dashboard/lib has 23 Material imports.
WidgetsApp can run without a Navigator when it is given only a builder. In that configuration, the application must provide an Overlay if it uses portal-based UI. Scaffold does not provide that overlay; a Navigator commonly does.
The Remix overlay families currently have two distinct contracts:
Menu, select, popover, and tooltip flow through Naked UI's RawMenuAnchor, which uses Flutter OverlayPortal. OverlayPortal preserves all inherited widgets from the trigger subtree and needs an Overlay, but not a Navigator or Scaffold.
showRemixDialog flows through showNakedDialog and pushes a RawDialogRoute; it intentionally requires a caller-owned Navigator. Naked UI captures Flutter InheritedThemes, while Remix also replays MixScope and FortalTheme because those scopes are not InheritedThemes.
A temporary Flutter 3.44 widget test validated that WidgetsApp.builder + FortalScope + a standalone Overlay, with no Navigator, can open RemixPopover and retain both Fortal and Mix scopes. The same test confirmed that route dialogs have no navigator in that configuration and that a raw OverlayEntry sees the host-level text style rather than a trigger-local one.
Remix must not own or replace an application's navigator/router, localization, shortcuts, restoration, or platform app configuration.
Optional RemixApp convenience wrapper
Defer
It would largely mirror the broad WidgetsApp API before Remix has a second concrete use case. Consumers can compose Remix through an app builder or around a subtree.
General RemixScaffold
Do not add
Scaffold combines unrelated Material page concerns. Remix does not yet have a generalized app bar, drawer, FAB, snackbar, or bottom-sheet contract, and none is required for portals.
Focused RemixOverlayHost (proposed name)
Add
A small opt-in host solves the concrete no-Navigator case by owning only an Overlay, without introducing routes or back-stack behavior.
FortalScope remains the navigation-independent design-system root. It must work around an entire app, inside an existing app's builder, or around an embedded subtree.
Proposed navigation-free usage (API sketch, not current code):
Applications that already provide an overlay through their navigator/router do not need this host. Route-based APIs such as showRemixDialog continue to use the caller's navigator; Remix must not silently create one.
Scope
Add a focused, opt-in overlay host (name subject to API review) that:
owns an Overlay and base content entry;
does not create a Navigator, Router, routes, or back-button behavior;
updates and disposes its entry correctly;
supports nesting intentionally and documents nearest/root-overlay behavior.
Replace the dashboard toast's raw OverlayEntry approach with OverlayPortal or the shared host/layer mechanism so live DefaultTextStyle, Fortal, Mix, directionality, localization, and accessibility context are preserved.
Migrate the dashboard app shell from MaterialApp to WidgetsApp. The dashboard may explicitly own a navigator because it demonstrates route dialogs; that navigator is an application choice, not a Remix requirement.
Replace the dashboard Scaffold/Drawer with a dashboard-private responsive shell. Do not promote it to Remix until there is a second reusable page-shell use case and an explicit API contract.
Remove the remaining Material-only constants/defaults from Remix core:
replace Colors.* with tokens or framework Color constants;
replace Material Icons.* defaults with Remix-owned icons/paths;
switch imports to widgets.dart, painting.dart, foundation.dart, services.dart, or dart:ui as appropriate;
remove uses-material-design when the icon-font dependency is gone.
Update examples and test helpers so Material is an interoperability example, not the only demonstrated host.
Document the host capability matrix: plain subtree, overlay-only host, caller-provided navigator, and router-based app.
Acceptance criteria
Remix widgets render inside existing Material, Cupertino, Widgets, router, and embedded-subtree hosts without Remix taking ownership of navigation.
A WidgetsApp.builder test with the opt-in overlay host contains no Navigator and verifies menu/select/popover/tooltip behavior plus live Fortal/Mix inheritance.
Dialog tests run with a caller-provided Navigator under WidgetsApp, and showRemixDialog clearly documents/asserts that requirement.
Toast/global transient UI no longer displays Flutter's fallback warning text style and updates when the active Fortal theme changes.
Dashboard responsive sidebar behavior, modal dismissal, focus restoration, Escape/back handling, semantics, and compact/wide layouts remain covered without Scaffold or Drawer.
packages/remix/lib has no package:flutter/material.dart imports and the Remix package no longer enables uses-material-design.
Public documentation does not present MaterialApp/Scaffold as a Remix prerequisite.
No public RemixApp or catch-all RemixScaffold is introduced as part of this work.
Non-goals
Defining a Remix router or navigation stack.
Reimplementing route dialogs on an overlay-only host.
Adding generalized app bar, drawer, FAB, snackbar, or bottom-sheet APIs before their component contracts exist.
Problem
Remix is intended to be a composable design system, but the dashboard, examples, and much of the test harness currently make
MaterialApp+Scaffoldlook like a runtime requirement. That creates two problems:MaterialApp,CupertinoApp,WidgetsApp, router-based application, or another design system.OverlayEntry; that entry is built under the targetOverlay, not under its trigger's subtree, so it loses the route-localDefaultTextStyle. UnderMaterialApp, the remaining app-level style is intentionally the red/yellow warning style, which caused the observed toast regression.The current implementation confirms that Remix core does not use
MaterialApp,Scaffold,Drawer,ScaffoldMessenger, orThemeData. Those are dashboard concerns today. However,packages/remix/libstill has 28material.dartimports for convenience constants/default icons and enablesuses-material-design, whilepackages/dashboard/libhas 23 Material imports.Relevant code:
MaterialAppScaffold/DrawerOverlayEntryand manual scope replayshowRemixDialogscope captureFortalScopehost guidanceuses-material-designFindings
Navigation and overlays are separate requirements
WidgetsAppcan run without aNavigatorwhen it is given only abuilder. In that configuration, the application must provide anOverlayif it uses portal-based UI.Scaffolddoes not provide that overlay; aNavigatorcommonly does.The Remix overlay families currently have two distinct contracts:
RawMenuAnchor, which uses FlutterOverlayPortal.OverlayPortalpreserves all inherited widgets from the trigger subtree and needs anOverlay, but not aNavigatororScaffold.showRemixDialogflows throughshowNakedDialogand pushes aRawDialogRoute; it intentionally requires a caller-ownedNavigator. Naked UI captures FlutterInheritedThemes, while Remix also replaysMixScopeandFortalThemebecause those scopes are notInheritedThemes.A temporary Flutter 3.44 widget test validated that
WidgetsApp.builder+FortalScope+ a standaloneOverlay, with noNavigator, can openRemixPopoverand retain both Fortal and Mix scopes. The same test confirmed that route dialogs have no navigator in that configuration and that a rawOverlayEntrysees the host-level text style rather than a trigger-local one.Flutter references:
WidgetsAppWidgetsApp.builderand optional navigationOverlayPortalinherited-widget behaviorInheritedTheme.captureMaterialAppfallback text styleDirection
RemixAppRemixAppconvenience wrapperWidgetsAppAPI before Remix has a second concrete use case. Consumers can compose Remix through an appbuilderor around a subtree.RemixScaffoldScaffoldcombines unrelated Material page concerns. Remix does not yet have a generalized app bar, drawer, FAB, snackbar, or bottom-sheet contract, and none is required for portals.RemixOverlayHost(proposed name)Navigatorcase by owning only anOverlay, without introducing routes or back-stack behavior.FortalScoperemains the navigation-independent design-system root. It must work around an entire app, inside an existing app'sbuilder, or around an embedded subtree.Proposed navigation-free usage (API sketch, not current code):
Applications that already provide an overlay through their navigator/router do not need this host. Route-based APIs such as
showRemixDialogcontinue to use the caller's navigator; Remix must not silently create one.Scope
Overlayand base content entry;Navigator,Router, routes, or back-button behavior;OverlayEntryapproach withOverlayPortalor the shared host/layer mechanism so liveDefaultTextStyle, Fortal, Mix, directionality, localization, and accessibility context are preserved.MaterialApptoWidgetsApp. The dashboard may explicitly own a navigator because it demonstrates route dialogs; that navigator is an application choice, not a Remix requirement.Scaffold/Drawerwith a dashboard-private responsive shell. Do not promote it to Remix until there is a second reusable page-shell use case and an explicit API contract.Colors.*with tokens or frameworkColorconstants;Icons.*defaults with Remix-owned icons/paths;widgets.dart,painting.dart,foundation.dart,services.dart, ordart:uias appropriate;uses-material-designwhen the icon-font dependency is gone.Acceptance criteria
WidgetsApp.buildertest with the opt-in overlay host contains noNavigatorand verifies menu/select/popover/tooltip behavior plus live Fortal/Mix inheritance.NavigatorunderWidgetsApp, andshowRemixDialogclearly documents/asserts that requirement.ScaffoldorDrawer.packages/remix/libhas nopackage:flutter/material.dartimports and the Remix package no longer enablesuses-material-design.MaterialApp/Scaffoldas a Remix prerequisite.RemixAppor catch-allRemixScaffoldis introduced as part of this work.Non-goals