material_navigation 0.1.1
material_navigation: ^0.1.1 copied to clipboard
Material 3 Expressive navigation for Flutter: a flexible navigation bar and a navigation rail that expands in place or as a modal, with spring motion.
0.1.1 #
Accessibility
- Destinations carry the tab role and the button flag, in one merged semantics node each, and the bar and rail carry the tab-bar role. Previously they had no role.
- A destination keeps its accessible name under every
labelBehavior. PreviouslyNavigationLabelBehavior.noneexposed only a tooltip andNavigationLabelBehavior.selectedleft unselected destinations unnamed. - A destination whose label is hidden or does not fit gets a tooltip.
Previously only
NavigationLabelBehavior.nonegave one. - The modal rail behaves like a modal: the scrim is a
ModalBarrierwith the platform's dismiss action and label, the pane is named for screen readers, and focus moves into the overlay and is restored on close. - The modal rail closes on
Escapeand on the system back gesture. PreviouslyEscapedid nothing and back left the page. - A rail not stretched to its parent's height no longer collapses to nothing behind its modal, which also left the modal unreadable to screen readers.
Changed
NavigationBar.labelBehaviorapplies to horizontal items too. Withselected, only the selected destination shows its label beside the icon, its indicator growing around the label as it is selected; withnone, items show their icons only.- Changing
labelBehavioranimates: labels ease in or out, and the bar resizes with them.
Fixes
NavigationBarno longer throws aRangeErrorwhenselectedIndexis out of range; it shows no destination as selected.NavigationBarno longer overflows at large text scales: itsheightis now a minimum, and the bar grows with its content.NavigationBarStyle.maxLabelScalecaps the labels' text scale, and with it the growth; tooltips keep the full scale.- The expanded pill grows around a label taller than the icon instead of clipping it, matching the Material 3 tokens.
- A label that does not fit wraps to a second line instead of being cut, both
below the icon and beside it, so it stays visible in full at up to twice the
text size, as Material 3's accessibility guidance asks. A label that fits one
line is unaffected;
labelMaxLines, 2 by default, sets the limit. - A
NavigationRailwhose destinations do not fit and whose style setsscrollable: falsenow clips them and reports an overflow instead of painting over the content beside it. - A collapsed
NavigationRailnarrower than its indicator no longer throws: the indicator fits the rail. - Setting
NavigationRail.expandedtotrueexpands the rail in place, as documented, even when it was last opened as a modal. NavigationRail.onExpandedChangedis no longer called during a build, so asetStatein the callback is safe.NavigationRailhonours the bottom view padding, keepingtrailingclear of a system gesture bar.NavigationRailStyle.applyBottomInsetopts out.NavigationRailHandle.isOpenandisModalalways report the rail's current state, including from a handle captured earlier.- Widgets in the rail's
leading,floatingActionButton,trailingandexpandedBodyslots keep their state when the rail opens or closes as a modal. NavigationBarfinishes its layout morph whenmotionchanges part-way through it; previously the morph stopped where it was. A change in the number of destinations part-way no longer jumps the morph to its end.
Performance
- Labels are measured once and cached rather than laid out twice per destination per frame. Expanding a seven-destination rail took 476 label layouts; it now takes none after the first frame.
- Selecting a destination no longer rebuilds the whole bar or rail on every animation tick. One tap on a seven-destination rail went from 14 rail rebuilds, 98 destination rebuilds and 196 label layouts to 1, 33 and 4.
- The
TextPaintereach destination created on every build, and never disposed, is gone.
New
NavigationBarStyle.maxLabelScale,NavigationRailStyle.applyBottomInset, andlabelMaxLinesandlabelOverflowon both styles.labelMaxLines,labelOverflowandmaxLabelScaleonNavigationDestinationStyle.NavigationRailHandle.openListenableandmodalListenable, for rebuilding when the rail opens or closes.
0.1.0 #
Breaking.
- Migrates to
material_ui. NavigationBarStyleandNavigationRailStyleare nowThemeExtensions with optional tokens, falling back to the Material 3 defaults for the currentColorSchemeandTextTheme. Addsvariant,of,mergeandlerp.- New tokens, including indicator shape, per-state icon and label styles, the
rail's header and item spacing, item heights,
groupAlignmentandscrollable. - Defaults follow the Material 3 tokens: the Expressive springs, an expanded
rail sized to its destinations instead of a fixed 280dp, the rail's header
and item spacing,
onSurfaceVariantfor disabled destinations, no shadow on the bar, and no bold active label in the baseline variant. - Adds
NavigationRail.groupAlignment,NavigationRail.modalMotion,NavigationMotion.defaultSpatialandNavigationMotion.fastSpatial. - Destinations in a rail's
trailingandexpandedBodyslots take the rail's layout and style instead of their own defaults. - Removes
itemVerticalSpace, and the style classes'besideLabelStartanddestinationStylegetters.
0.0.2 #
- Fixes
setState() or markNeedsBuild() called during buildwhen a destination is selected, or the destinations change, whileNavigationRailis open as a modal overlay. The overlay is now built with anOverlayPortal, so it also inherits what the rail inherits (such as a localTheme), and dialogs or routes opened while it is showing now appear above it instead of beneath it. - Fixes
NavigationBarthrowing anArgumentErrorand rendering no destinations when a destination is narrower than 80dp, for example five destinations on a screen under 400dp wide. Destinations now squash to fit.
0.0.1 #
- Initial release.