duskmoon_adaptive_scaffold
Adaptive scaffold widgets for the DuskMoon Design System, forked from flutter_adaptive_scaffold.
Features
DmAdaptiveScaffold— adaptive layout that adjusts to screen size using Material 3 navigation patternsAdaptiveLayout— low-level adaptive layout primitiveSlotLayout— slot-based layout composition
Getting started
dependencies:
duskmoon_adaptive_scaffold: ^1.1.0
Usage
import 'package:duskmoon_adaptive_scaffold/duskmoon_adaptive_scaffold.dart';
DmAdaptiveScaffold(
destinations: const [
NavigationDestination(icon: Icon(Icons.home), label: 'Home'),
NavigationDestination(icon: Icon(Icons.settings), label: 'Settings'),
],
body: (_) => const Center(child: Text('Body')),
)
Foldable and companion displays
DuoScreenPolicy.splitBody places the body and secondary body on opposite
sides of a separating hinge or fold. Horizontal separators split top/bottom;
vertical separators mirror body reading order in RTL. A zero-width flat fold
does not split the layout. Half-open folds and physically occluding folds do.
Feature selection is deterministic: physical hinges take precedence over folds,
then bounds are ordered top-to-bottom and left-to-right.
DuoScreenPolicy.navigationOnSecondary moves navigation beside the secondary
body. It uses the regular adaptive layout when there is no separating feature
and duoScreenRole is single, so local navigation stays available.
DmAdaptiveScaffold(
destinations: destinations,
duoScreenPolicy: DuoScreenPolicy.navigationOnSecondary,
// Use primary only after the companion view has connected successfully.
duoScreenRole: companionConnected
? DuoScreenRole.primary
: DuoScreenRole.single,
body: (_) => viewer,
secondaryBody: (_) => controller,
)
Use DuoScreenRole.secondary in the companion view. It mounts navigation and
secondaryBody only; primary mounts the main body only. Top navigation belongs
to the primary view. Hidden slots are not built, focusable, or exposed in
semantics, and their state is disposed. Visible slots retain their identity when
the role changes. A narrow companion view uses bottom navigation; on a foldable,
secondary panes narrower than 600 logical pixels also use bottom navigation.
Hinge bounds are resolved in local layout coordinates, including AppBars and ancestor padding. Pane boundaries align immediately to the physical separator; size interpolation across a hinge is deliberately disabled. Slot fades and navigation width changes remain bounded by pane clipping. View offset changes are corrected after parent positioning, with physical hinge paint and hit-test clipping protecting the first frame.
Migrating displayId
AdaptiveLayout and DmAdaptiveScaffold retain the deprecated displayId
parameter until 2.0.0. Positive values still select the secondary role and take
precedence over duoScreenRole; zero defaults to single. Replace it with
duoScreenRole, and leave platform display identifiers in the plugin or app
integration layer. Roles only affect navigationOnSecondary.
The policy remains available to existing callers importing
src/adaptive_layout.dart. DmScaffold also forwards the additive
duoScreenPolicy and duoScreenRole parameters.
Additional information
Part of the DuskMoon UI design system.