Material 3 Expressive
A faithful Flutter implementation of the Material 3 Expressive component set.
Every widget is exposed as a direct M3E* class with spring-driven press
feedback, shape morphing, and hover/focus/press state layers. Design tokens
(color, typography, motion, shapes, elevation) are provided through
M3ETheme.
Runtime dependencies are intentionally small — see
Dependencies for the packages declared in
pubspec.yaml.
Samples
| Actions | Selection |
|---|---|
![]() |
![]() |
| Containment | Navigation |
|---|---|
![]() |
![]() |
| Feedback |
|---|
![]() |
Example app
Try the live gallery on the web: paadevelopments.github.io/material_3_expressive.
An interactive gallery demonstrating all 44 widgets also lives in the
example/ directory (same build as the live demo). It groups
components the same way as the official Material 3 catalog, with a live
playground per component under example/lib/pages/playground/.
Each tab lists its components (a card grid on wide windows). Opening one shows
its preview screen: the component sits in its real place (app bars on top, nav
bars at the bottom, FABs in the FAB slot), next to a controls pane on wide
windows or behind a Tap for controls banner that opens a full-height
bottom sheet on narrow ones. Only the controls that apply to the selected
variant appear, and a Code tab shows paste-ready Dart that tracks them
(copy to clipboard).
| Tab | Playgrounds | Components |
|---|---|---|
| Do | playground/do/ |
Buttons, FABs, FAB menu, groups, segmented & split buttons |
| Pick | playground/pick/ |
Checkbox, radio, switch, chips, dropdown, slider (incl. wavy), pickers |
| View | playground/view/ |
Cards, carousel, lists, selection, divider, dialogs, sheets, shapes, typography |
| Nav | playground/nav/ |
App bars (incl. search), tabs, nav bar/rail/drawer, toolbar, menu |
| Find | playground/find/ |
Badges, progress, refresh, tooltip, snackbar, inputs |
The gallery shell in example/lib/main.dart uses
M3EMaterialApp with adaptive theming, a light/dark toggle, and a palette
action that opens theme_config_page.dart
(auto theming, dynamic color, five seed colors, and font family — default
Google Sans Flex). For type scale, variable-font axes, and style
conversion, use the Typography playground under the View tab.
cd example
flutter run
Features
- 44 widgets across 39 component modules, covering Actions, Selection, Containment, Navigation, and Feedback (communication + text input).
- Direct component API — construct each
M3E*widget directly; enums and models are exported from a single library import. Action surfaces accept optional gradient decorations (fill, foreground, overlay, outline). - Expressive motion & interaction — spring physics (via
motor), shape morphing, per-destination selection indicators, shared haptics (M3EHaptics), and proper state layers on every interactive surface. - Design token foundations — color schemes, typography, motion, shapes
(including
material_new_shapesmorph polygons), spacing and radius viaM3EDimensions, elevation, haptics, and state layers via theM3EThemeinherited widget. - Interactive example gallery — run locally from
example/, or open the live web demo.
Requirements
| Tool | Version |
|---|---|
| Flutter | >= 3.47.0 |
| Dart | ^3.13.0 |
Migrating to material_ui
This package uses material_ui ^1.5.0
for Material widgets (MaterialApp, ThemeData, ColorScheme, and the rest of
the Material library). Do not import package:flutter/material.dart.
import 'package:material_ui/material_ui.dart';
import 'package:material_3_expressive/material_3_expressive.dart';
Apps that still import package:flutter/material.dart should switch those
imports to package:material_ui/material_ui.dart. Flutter 3.47.0 or newer
(Dart 3.13.0+) is required (material_ui will not resolve on older SDKs).
ColorScheme.harmonized() / Color.harmonizeWith() come from
dynamic_color ^2.1.0 (re-exported
through this package). Prefer those APIs rather than a local duplicate.
What's new in 1.1.5
Summary of updates since 1.1.4 (details in CHANGELOG.md):
- Search — spec pill bar, contained or divided view (full-screen below
600, docked above) and
M3ESliverSearchBar. - Text fields — spec filled and outlined fields with prefix/suffix, counter, clear and password buttons, density and multi-line alignment.
- Dialogs — spec basic and full-screen dialogs, spring motion, focus trap,
M3EDialogControllerandM3EDialog.showAdaptive. - Bottom sheets — spec sheets with preset heights,
.standard, full-screen expansion,M3EBottomSheetControllerand.showAdaptive. - Side sheets — spec modal, standard and detached sheets,
M3ESideSheetLayoutandM3ESideSheetController. - Buttons —
M3EButtonDecorationScopeand live state layers. - Lists — expanded-row fill, single Tab stop with arrow keys, and a
working
M3EList.sliver. - Breaking —
M3ESideSheetThemeandM3ETextFieldThemewere rebuilt (see the changelog for migration).
Installation
Add the package to your pubspec.yaml:
dependencies:
material_3_expressive: ^1.1.5
Then fetch it:
flutter pub get
Or add it from the command line:
flutter pub add material_3_expressive
Dependencies
External packages declared in pubspec.yaml:
| Package | Role in this library |
|---|---|
flutter |
SDK — widgets, painting, gestures |
material_ui |
Official Material widget library (MaterialApp, ThemeData, ColorScheme) |
collection |
Small collection helpers used by component logic |
dynamic_color |
Platform dynamic / Material You seed colors for M3EMaterialApp (dynamicColoring); ColorScheme.harmonized / Color.harmonizeWith (2.x, material_ui) |
motor |
Unified motion API — physics springs and curves that drive expressive morphs and selection indicators |
material_new_shapes |
Expressive RoundedPolygon morph shapes (M3EMaterialNewShapes, M3EShapeKind, M3EShapeClipper, M3EShapeContainer) used by loading / shape-driven surfaces |
Dev-only: flutter_lints, flutter_test, and custom_lint.
Quick start
Import the library — a single import exposes every component and foundation:
import 'package:material_3_expressive/material_3_expressive.dart';
Recommended: M3EMaterialApp
Wrap your app in M3EMaterialApp for adaptive theming, dynamic color, and
Material ThemeMode alignment (same pattern as the example gallery):
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return M3EMaterialApp(
title: 'My App',
data: M3EThemeData.light(seedColor: const Color(0xFF6750A4)),
autoTheming: true,
dynamicColoring: true,
drawUnderSystemBars: true, // transparent system bars, edge-to-edge layout
home: const HomePage(),
);
}
}
Surfaces draw behind the OS navigation bar; components such as M3ENavigationBar
keep interactive content above the gesture area via viewPadding.
Actionable controls draw an outset keyboard focus ring when focused via
Tab (hidden after pointer interaction). Override globally with
focusRingTheme / keyboardFocusIndicators on M3EThemeData, or try the
example Focus rings playground (View tab):
M3EThemeData.light(seedColor: seed).copyWith(
keyboardFocusIndicators: true,
focusRingTheme: const M3EFocusRingTheme(
color: Color(0xFF6750A4),
width: 2,
gap: 2,
),
);
Alternative: M3ETheme subtree
If you already have an app shell, wrap any subtree in M3ETheme:
M3ETheme(
data: M3EThemeData.light(seedColor: const Color(0xFF6750A4)),
child: myApp,
);
Use M3EThemeData.dark(...) for a dark scheme. If no M3ETheme is found,
components fall back to a default light theme.
Accessing theme tokens
final theme = M3ETheme.of(context);
final scheme = theme.colorScheme;
final type = theme.typeScale;
// Toggle brightness at runtime (requires adaptive M3EMaterialApp / M3EThemeScope)
M3ETheme.controllerOf(context)?.toggleBrightness(
fallback: theme.brightness,
autoTheming: true,
);
Theming
M3EThemeData bundles expressive tokens and per-component themes:
final theme = M3EThemeData.light(
seedColor: const Color(0xFF6750A4),
);
// Override a single component theme
final custom = theme.copyWith(
buttonTheme: M3EButtonTheme.defaults.copyWith(/* ... */),
);
Key properties on M3EThemeData:
colorScheme—M3EColorSchemewith M3 semantic rolestypography—M3ETypographywith baseline and emphasized scales (30 styles)typeScale— baseline alias fortypography.baseline(used by components)spacing,visualDensity, per-component*ThemeextensionsfocusRingTheme/keyboardFocusIndicators— keyboard focus chrome- Per-component
M3ESpringmotion fields on themes such asswitchTheme,fabMenuTheme,navigationRailTheme,listTheme,toolbarTheme,sliderTheme,iconButtonTheme,checkboxTheme, andrefreshIndicatorTheme(defaults preserve prior hard-coded springs)
The M3 type system has 15 baseline and 15 emphasized roles. Use emphasized styles for selection, actions, and editorial hierarchy:
final theme = M3ETheme.of(context);
Text('Headline', style: theme.typography.emphasized.headlineSmall);
Shared typography (font family, fallback, package, size factor/delta, color,
decoration, brand/plain typefaces, and variable-font axes) is applied through
M3ETypography.apply or theme copyWith — not a full TextStyle:
final themed = M3EThemeData.light(seedColor: seed).copyWith(
typography: M3ETypography.material3().apply(
fontFamily: 'Roboto Flex',
fontVariations: M3ETypeVariations.graded.variations,
),
);
// Sugar: same result without building typography by hand
final alsoThemed = M3EThemeData.light(seedColor: seed).copyWith(
fontFamily: 'Roboto Flex',
fontVariations: M3ETypeVariations.graded.variations,
);
// Per-role variable-font axes (opsz, wght, split ROND, emphasized GRAD)
final variable = M3EThemeData.light(seedColor: seed).copyWith(
fontFamily: 'Roboto Flex',
typeScaleMode: M3ETypeScaleMode.variable,
variableFont: const M3EVariableFontConfig(
global: M3EVariableFontAxes(wght: 500, opsz: 16),
brand: M3EVariableFontAxes(rond: 25),
body: M3EVariableFontAxes(rond: 50),
),
);
// Convert any TextStyle to a spec variant
final converted = M3ETypeStyleConversion.toVariant(
Theme.of(context).textTheme.bodyLarge!,
variant: M3ETypeScaleVariant.emphasized,
role: M3ETypeRole.bodyLarge,
);
// Customize token fields before building a TextStyle
final tokens = M3ETypeStyleTokens.fromTextStyle(style).copyWith(
letterSpacing: 0.25,
);
final custom = tokens.toTextStyle(fontFamily: 'Roboto Flex');
M3EMaterialApp additionally supports autoTheming (platform brightness) and
dynamicColoring (OS seed color on supported platforms — Material You primary
on Android 12+, accent color on desktop — with schemes generated via
ColorScheme.fromSeed). Pass fontFamily / fontFamilyFallback /
fontVariations, typeScaleMode, typeface, or variableFont to apply
type-scale knobs at the shell. Use buildM3EThemeDefaults()
to assemble a full M3EThemeData
from core tokens, or M3EDynamicColorHost
when you need device dynamic color outside M3EMaterialApp:
M3EMaterialApp(
data: M3EThemeData.light(seedColor: seed),
fontFamily: 'Roboto Flex',
typeScaleMode: M3ETypeScaleMode.variable,
variableFont: const M3EVariableFontConfig(),
home: const HomePage(),
);
M3ETypeVariations is an enum of Roboto Flex axis presets (.variations):
regular, graded (alias for the weight+grade preset formerly named emphasized),
condensed, extra condensed, wide, extra wide, and round. This is not the M3
emphasized type scale — use theme.typography.emphasized for that. Static
and mono fonts ignore axes they do not define. The shell projects the baseline
type scale onto ThemeData.textTheme and DefaultTextStyle.
Components
Every component is a widget you construct directly. Snippets below use a single
import. Stateful controls show // in State where a setState wrapper is
needed.
Actions
See also:
example/lib/pages/playground/do/(Do tab)
M3EButton
Text button in five sizes with a press shape morph and the sparkle ripple.
Styles are elevated, filled, tonal, outlined and text. isSelected turns it
into a toggle that morphs round to square, with optional selectedIcon and
selectedLabel (not on text buttons). State layers are 0.08 hover and
0.1 focus and press. Gradients and per-state colors go on
M3EButtonDecoration; customize defaults on M3EButtonTheme.
M3EButton(
style: M3EButtonStyle.elevated,
onPressed: () {},
child: const Text('Elevated'),
);
// Toggle (in State)
M3EButton.filled(
icon: const Icon(M3EIcons.favorite_border),
selectedIcon: const Icon(M3EIcons.favorite),
isSelected: isFavorite,
onPressed: () => setState(() => isFavorite = !isFavorite),
);
Keyboard: Tab, then Space or Enter.
M3EIconButton
Icon-only button in filled (default), tonal, outlined and standard variants.
Toggle it with isSelected and selectedIcon. Customize it on
M3EIconButtonTheme.
M3EIconButton(
icon: const Icon(M3EIcons.edit),
onPressed: () {},
);
// Toggle (in State)
M3EIconButton(
icon: const Icon(M3EIcons.add),
selectedIcon: const Icon(M3EIcons.check),
isSelected: isFavorite,
onPressed: () => setState(() => isFavorite = !isFavorite),
);
Keyboard: Tab, then Space or Enter.
M3EFab
Floating action button in small 40, regular 56, medium 80
(default) and large 96. M3EFabController with
M3EFabScrollVisibility hides it on scroll, and openBuilder opens a
full-screen container transform. Customize it on M3EFabTheme.
M3EFab(
icon: const Icon(M3EIcons.add),
size: M3EFabSize.large,
color: M3EFabColor.tertiary,
openBuilder: (context) => const ComposePage(), // optional transform
onPressed: () {},
);
Keyboard: Tab, then Space or Enter.
M3EExtendedFab
FAB with a required label, in small 56 (default), medium 80 and
large 96. M3EExtendedFabController with
M3EExtendedFabScrollVisibility hides it on scroll, and openBuilder opens a
container transform. Customize it on M3EExtendedFabTheme.
M3EExtendedFab(
label: 'Compose',
icon: const Icon(M3EIcons.edit),
size: M3EExtendedFabSize.medium,
onPressed: () {},
);
Keyboard: Tab, then Space or Enter.
M3EFabMenu
Speed-dial menu of 2–6 items. The trigger morphs into a 56 close
button, and back closes the menu before the route. Customize it on
M3EFabMenuTheme.
M3EFabMenu(
expandIcon: const Icon(M3EIcons.add),
collapseIcon: const Icon(M3EIcons.close),
items: [
M3EFabMenuItem(icon: const Icon(M3EIcons.edit), label: 'Note', onPressed: () {}),
M3EFabMenuItem(icon: const Icon(M3EIcons.schedule), label: 'Reminder', onPressed: () {}),
],
);
Keyboard: Tab walks the items. Escape closes.
M3EButtonGroup
Standard or connected group of M3EButton actions with single or multi
selection. Density changes the height, not the gap. Customize it on
M3EButtonGroupTheme.
// in State
M3EButtonGroup(
type: M3EButtonGroupType.connected,
selectedIndex: groupIndex,
onSelectedIndexChanged: (i) => setState(() => groupIndex = i),
actions: const [
M3EButtonGroupAction(label: Text('Day')),
M3EButtonGroupAction(label: Text('Week')),
M3EButtonGroupAction(label: Text('Month')),
],
);
Keyboard: Tab, then Space or Enter.
M3ESegmentedButton
Outlined single or multi-select control with 2–5 segments, 40 tall
with a 48 target, and a 1 outline border. Density lowers the
height. Customize it on M3ESegmentedButtonTheme.
// in State
M3ESegmentedButton<String>(
segments: const [
M3ESegment(value: 'list', label: 'List'),
M3ESegment(value: 'grid', label: 'Grid'),
],
selected: viewMode,
onSelectionChanged: (v) => setState(() => viewMode = v),
);
Keyboard: Tab, then Space or Enter.
M3ESplitButton
A primary action and a menu trigger, 2 apart. The menu comes from items
or m3eMenuBuilder, and back closes it before the route. Customize it on
M3ESplitButtonTheme.
M3ESplitButton<String>(
label: 'Save',
leadingIcon: M3EIcons.check,
onPressed: () {},
onSelected: (value) {},
items: const [
M3ESplitButtonItem(value: 'draft', child: Text('Save as draft')),
M3ESplitButtonItem(value: 'copy', child: Text('Save a copy')),
],
);
Keyboard: Tab, then Space or Enter. Escape closes the menu.
Selection
See also:
example/lib/pages/playground/pick/(Pick tab)
M3ECheckbox
Checkbox with an 18 box, 2 corners, a 40 state layer and a 48
target, with optional tristate and label. Customize it on
M3ECheckboxTheme.
// in State
M3ECheckbox(
value: checked,
label: const Text('Remember me'),
onChanged: (v) => setState(() => checked = v),
);
Keyboard: Tab, then Space or Enter.
M3ERadio
Radio with a 20 icon, a 40 state layer and a 48 target. Wrap
options in M3ERadioGroup for arrow-key selection. Customize it on
M3ERadioTheme.
// in State
M3ERadioGroup<String>(
groupValue: plan,
groupLabel: 'Plan',
onChanged: (v) => setState(() => plan = v),
child: M3ERadio<String>(
value: 'pro',
groupValue: plan,
label: const Text('Pro'),
onChanged: (v) => setState(() => plan = v),
),
);
Keyboard: Tab enters the selected radio. Arrows move, select and wrap.
M3ESwitch
Switch with a 52×32 track. The handle is 16 off, 24 on or with an
icon, and 28 pressed. Dragging past the midpoint toggles it. Customize it
on M3ESwitchTheme.
// in State
M3ESwitch(
value: wifiEnabled,
selectedIcon: const Icon(M3EIcons.check),
onChanged: (v) => setState(() => wifiEnabled = v),
);
Keyboard: Tab, then Space or Enter.
M3EChip
Assist, filter, input and suggestion chips, 32 tall with 8 corners.
M3EChipGroup moves focus between chips with the arrow keys. Customize them
on M3EChipTheme.
M3EChip(
label: 'Assist',
leading: const Icon(M3EIcons.edit),
onPressed: () {},
);
// Filter chip (in State)
M3EChip(
label: 'Flutter',
type: M3EChipType.filter,
selected: chips.contains('flutter'),
onPressed: () => toggleChip('flutter'),
);
Keyboard: Tab, then Space or Enter. In a group, arrows move. Backspace or Delete removes an input chip.
M3EDropdownMenu
Dropdown for one or many values, with optional search, a selection limit
and async items (.future). Back closes the panel before the route. Customize
it on M3EDropdownMenuTheme.
M3EDropdownMenu<String>(
singleSelect: true,
items: const [
M3EDropdownItem(label: 'Flutter', value: 'flutter'),
M3EDropdownItem(label: 'Dart', value: 'dart'),
],
fieldStyle: const M3EDropdownFieldStyle(hintText: 'Choose a framework'),
onSelectionChanged: (items) {},
);
Keyboard: Space or Enter opens. Arrows move in the panel. Escape closes.
M3ESlider
Value or range slider, also centered, wavy and vertical. Sizes xs–xl scale
the track (16–96) and handle (44–108) together. The active track and
handle are primary, the inactive track secondary container, and
divisions adds stops. Customize it on M3ESliderTheme.
// in State
M3ESlider(
value: volume,
size: M3ESliderSize.l,
divisions: 5,
onChanged: (v) => setState(() => volume = v),
);
M3ERangeSlider(
values: range,
onChanged: (v) => setState(() => range = v),
);
Keyboard: arrows step. Page Up and Page Down jump. Home and End go to the ends.
M3EDatePicker
Inline calendar (M3ECalendarDatePicker) and dialogs for one date or a range,
with a year grid and text input. The inline calendar is 328 wide.
Customize it on M3EDatePickerTheme.
// Inline (in State)
M3ECalendarDatePicker(
initialDate: date,
firstDate: DateTime(2020),
lastDate: DateTime(2030),
onDateChanged: (v) => setState(() => date = v),
);
// Dialog; use showRange for a range
final picked = await M3EDatePicker.show(
context,
initialDate: date,
firstDate: DateTime(2020),
lastDate: DateTime(2030),
);
Keyboard: Tab, then Space or Enter. Left and Right change the month.
M3ETimePicker
Dialog and inline dial (256) for a time of day. Customize it on
M3ETimePickerTheme.
final M3ETime? picked = await M3ETimePicker.show(context, initialTime: time);
// Inline (in State)
M3EDialTimePicker(
value: time,
onChanged: (v) => setState(() => time = v),
);
Keyboard: Tab, then Enter moves focus on.
Containment
See also:
example/lib/pages/playground/view/(View tab)
M3ECard
Elevated, filled and outlined card with 16 content padding and a
secondary 3 focus ring. It has optional media, headline, supporting
text, actions and overflow slots, a swipe action, and an openBuilder
container transform. M3ECardGroup lays out and reorders a set of cards.
Customize it on M3ECardTheme.
M3ECard(
variant: M3ECardVariant.outlined,
media: Image.network(imageUrl, fit: BoxFit.cover),
headline: const Text('Weekend trip'),
supportingText: const Text('12 photos · 3 people'),
actions: M3EButton.text(onPressed: () {}, child: const Text('Share')),
onPressed: () {},
);
Keyboard: Tab, then Space or Enter. Left and Right reveal a swipe action, and Escape hides it.
M3ECarousel
Multi-browse, uncontained, multi-aspect, hero and full-screen carousels,
horizontal or vertical (axis). Items are M3ECarouselItem, onChange
reports the focal item, and M3ECarouselController steps, jumps or opens the
show-all list. Customize it on M3ECarouselTheme.
M3ECarousel(
type: M3ECarouselType.hero,
children: [
for (final url in imageUrls)
M3ECarouselItem(
image: Image.network(url, fit: BoxFit.cover),
title: const Text('Title'),
onTap: () {},
),
],
);
Keyboard: Tab or arrows move between items. Space or Enter opens one.
M3EListItem
List row with a headline, supporting text, and leading and trailing slots.
Rows are 56, 72 and 88 tall for one, two and three lines, with
16 side padding. variant and border style a standalone row. Customize
it on M3EListItemTheme.
M3EListItem(
headline: 'Wireless charging',
supportingText: 'On · Fast charge enabled',
leading: const Icon(M3EIcons.schedule),
trailing: const Icon(M3EIcons.chevron_right),
onTap: () {},
);
Keyboard: Tab, then Space or Enter.
M3EList
The list widget, with segmented (default) or standard corners. Rows opt into
swipe actions, expansion, sub-lists (a nested M3EList) and container
transforms, and the list adds selection and drag-to-reorder. Expanded rows
fill surface container high. Use .scrollable for a lazy list and
.sliver in a CustomScrollView. Customize it on M3EListTheme.
M3EList(
variant: M3ECardVariant.outlined,
itemCount: 3,
onTap: (index) {},
itemBuilder: (context, index) => M3EListItem(
headline: 'Inbox $index',
leading: const Icon(M3EIcons.schedule),
),
);
Keyboard: the list is one Tab stop. Arrows move through rows, row actions and sub-rows. Space or Enter activates.
M3ESelection
Multi-select host: an M3ESelectionAppBar swaps its idle bar for a
contextual bar with a count, select-all and actions while rows are selected,
over any list body. Selected rows use selectedColor. Customize it on
M3ESelectionTheme.
final selection = M3ESelectionController();
M3ESelection(
controller: selection,
itemCount: items.length,
appBar: M3ESelectionAppBar(
idle: M3EAppBar.top(titleText: 'Files'),
actions: [
M3EIconButton(icon: const Icon(M3EIcons.delete), onPressed: () {}),
],
),
body: M3EList.scrollable(
itemCount: items.length,
selection: true,
selectionController: selection,
itemBuilder: (context, i) => M3EListItem(headline: items[i]),
),
);
Keyboard: Tab, then Space or Enter selects a row.
M3EDivider
1 outline variant line, full width unless inset or outerMargin is
set, horizontal or vertical. Customize it on M3EDividerTheme.
const M3EDivider();
const M3EDivider(axis: M3EDividerAxis.vertical);
M3EDialog
Basic and full-screen dialogs. A basic dialog is 280–560 wide on
surface container high, with 28 corners and 24 padding, over a
0.32 scrim. The headline and actions stay pinned while content scrolls.
showAdaptive is full-screen below 600. Customize it on M3EDialogTheme.
M3EDialog.show<void>(
context,
dialog: M3EDialog(
title: 'Reset settings?',
content: const Text('This restores default values.'),
actions: [
M3EButton.text(onPressed: () => Navigator.pop(context), child: const Text('Cancel')),
M3EButton.text(onPressed: () => Navigator.pop(context), child: const Text('Reset')),
],
),
);
// Full screen below 600dp, basic dialog above.
M3EDialog.showAdaptive<void>(
context,
title: 'Create album',
content: const Text('Album details'),
confirmLabel: 'Save',
onConfirm: () => Navigator.pop(context),
);
Keyboard: Tab and Shift+Tab stay inside. Space or Enter activates. Escape closes.
M3EBottomSheet
Modal and standard bottom sheets, full width up to 640, on surface
container low, with 28 top corners and a 32×4 drag handle. A modal
sheet opens over a 0.32 scrim at up to half the screen and can be pulled
up to its content height. .standard sits next to the content without a
scrim. Customize it on M3EBottomSheetTheme.
// Modal
M3EBottomSheet.show<void>(
context,
builder: (context) => const ShareTargets(),
);
// Standard, driven by a controller
final controller = M3EBottomSheetController();
M3EBottomSheet.standard(
controller: controller,
previewHeight: 64,
child: const PlacesList(),
);
Keyboard: Tab focuses the handle, and Space or Enter cycles the heights. Escape closes a modal sheet.
M3ESideSheet
Modal and standard side sheets on the end edge, 256 wide (up to 400).
A modal sheet is on surface container low with 16 corners over a
0.32 scrim. A standard sheet is on surface and pushes the content.
M3ESideSheetLayout makes it modal below 600. Customize it on
M3ESideSheetTheme.
// Modal
M3ESideSheet.show<void>(
context,
title: 'Filters',
body: const FilterList(),
);
// Standard next to your content, modal on compact windows
M3ESideSheetLayout(
controller: controller,
body: const Inbox(),
sheet: const M3ESideSheet.standard(title: 'Details', body: Details()),
);
Keyboard: Tab moves through the icons, content and actions. Escape closes a modal sheet.
Navigation
See also:
example/lib/pages/playground/nav/(Nav tab)
M3EAppBar
Top, search, sliver and bottom app bars. The small bar is 64, flexible
medium 112 and large 120 (taller with a subtitle), and docked bars pad
for the system bars (safeArea). hideMode and M3EAppBarController
collapse or hide the bar on scroll. For a .top or .search bar that
collapses, set extendBodyBehindAppBar: true on the Scaffold so the bar
moves with the content. Customize it on M3EAppBarTheme.
Scaffold(
extendBodyBehindAppBar: true,
appBar: M3EAppBar.top(
titleText: 'Inbox',
variant: M3EAppBarVariant.mediumFlexible,
actions: const [Icon(M3EIcons.search)],
),
body: ListView(children: messages),
);
// In a CustomScrollView
M3EAppBar.sliver(titleText: 'Inbox');
Keyboard: Tab, then Space or Enter on the actions.
M3ETabs
Primary and secondary tab bars, 48 tall (64 for primary icon and
label), with a 3 (primary) or 2 (secondary) indicator. M3ETabsView
keeps a swipeable body in sync, and .sliver scrolls away with content.
Customize it on M3ETabTheme.
// in State
M3ETabs(
selectedIndex: tabIndex,
onTabSelected: (i) => setState(() => tabIndex = i),
tabs: const [
M3ETab(label: 'Overview'),
M3ETab(label: 'Specs'),
],
);
Keyboard: Tab enters. Left and Right move. Space or Enter selects.
M3ENavigationBar
Bottom navigation with a selection pill that scales in place. Wide windows get
a row of icon-and-label chips, and hideOnScroll with
M3ENavigationBarController hides it on scroll. Customize it on
M3ENavigationBarTheme.
// in State
M3ENavigationBar(
destinations: const [
M3ENavigationBarDestination(icon: Icon(M3EIcons.home), label: 'Home'),
M3ENavigationBarDestination(icon: Icon(M3EIcons.search), label: 'Search'),
],
selectedIndex: barIndex,
onDestinationSelected: (i) => setState(() => barIndex = i),
);
Keyboard: Tab enters. Left and Right move. Space or Enter selects.
M3ENavigationRail
Vertical navigation, 96 wide collapsed (80 narrow) and 220–360
expanded, with an optional FAB slot. A modal rail closes on the scrim, Escape
or back. M3ENavigationRailController expands, collapses and selects.
Customize it on M3ENavigationRailTheme.
// in State
M3ENavigationRail(
sections: const [
M3ENavigationRailSection(
destinations: [
M3ENavigationRailDestination(icon: Icon(M3EIcons.home), label: 'Home'),
M3ENavigationRailDestination(icon: Icon(M3EIcons.search), label: 'Search'),
],
),
],
selectedIndex: railIndex,
onDestinationSelected: (i) => setState(() => railIndex = i),
);
Keyboard: Tab enters. Arrows move. Space or Enter selects. Escape closes a modal rail.
M3ENavigationDrawer
Standard (default) or modal drawer, 360 wide with 16 end corners. A
modal drawer closes on a destination, the scrim, a drag or back, and
M3ENavigationDrawerController opens and closes it. Customize it on
M3ENavigationDrawerTheme.
// in State
M3ENavigationDrawer(
headline: 'Mail',
destinations: const [
M3ENavigationDestination(icon: Icon(M3EIcons.inbox), label: 'Inbox'),
M3ENavigationDestination(icon: Icon(M3EIcons.favorite), label: 'Starred'),
],
selectedIndex: drawerIndex,
onDestinationSelected: (i) => setState(() => drawerIndex = i),
);
Keyboard: Tab enters. Up and Down move. Space or Enter selects.
M3EToolbar
Floating (default) or docked toolbar, 64 tall. A floating toolbar is a
pill placed by alignment, 16 off the edge (screenOffset), with an
optional paired FAB. M3EToolbar.docked spans the width and lays out actions
at 600 and wider with contentAlignment. Customize it on
M3EToolbarTheme.
M3EToolbar(
actions: <M3EToolbarItem>[
M3EToolbarAction(icon: M3EIcons.edit, onPressed: () {}),
M3EToolbarAction(icon: M3EIcons.share, onPressed: () {}),
],
);
M3EToolbar.docked(
actions: <M3EToolbarItem>[
M3EToolbarAction(icon: M3EIcons.search, onPressed: () {}),
M3EToolbarAction(icon: M3EIcons.delete, onPressed: () {}),
],
);
Keyboard: Tab or arrows move between actions. Space or Enter activates.
M3EMenu
Vertical and baseline menus, 112–280 wide with 48 entries, plus
groups, submenus and multi-select. Opening focuses the first enabled item,
and back closes a submenu, then the menu. Customize it on M3EMenuTheme.
M3EMenu(
anchorBuilder: (context, open) => M3EButton(
onPressed: open,
child: const Text('Open menu'),
),
children: [
M3EMenuGroup.entries(
entries: [
M3EMenuEntry(label: 'Edit', onPressed: () {}),
M3EMenuEntry(label: 'Copy', trailingText: '⌘C', onPressed: () {}),
],
),
],
);
Keyboard: Up and Down move. Left and Right open or close a submenu. Letters jump. Enter or Space activates. Escape closes.
Feedback
See also:
example/lib/pages/playground/find/(Find tab)
M3EBadge
A 6 dot or a label badge (at least 16) in error and on error,
drawn over its child without moving it. Counts cap at 999. Customize it on
M3EBadgeTheme.
const M3EBadge(
count: 8,
child: Icon(M3EIcons.mail),
);
M3EProgressIndicator
Circular and linear progress, flat or wavy, determinate or indeterminate. The
indicator is primary on a secondary container track (showTrack: false hides it). Customize it on M3EProgressIndicatorTheme.
const M3EProgressIndicator.circular(); // indeterminate
M3EProgressIndicator.linearWavy(value: 0.6);
M3ELoadingIndicator
Indeterminate morphing shape, 48 outer and 38 active by default,
plain or contained. size scales both together. Customize it on
M3ELoadingIndicatorTheme.
const M3ELoadingIndicator();
const M3ELoadingIndicator(
variant: M3ELoadingIndicatorVariant.contained,
size: 96,
);
M3ERefreshIndicator
Pull-to-refresh for scrollables that shows a contained M3ELoadingIndicator.
It arms once fully revealed, and M3ERefreshIndicatorController.show()
refreshes from code. Customize it on M3ERefreshIndicatorTheme.
M3ERefreshIndicator(
onRefresh: () async => reload(),
child: ListView(children: items),
);
M3ETooltip
Plain tooltip (up to 200 wide, above the target) or rich tooltip (up to
320, with a title and actions). persistent keeps a rich tooltip open.
Customize it on M3ETooltipTheme.
M3ETooltip(
message: 'Compose a new message',
child: M3EIconButton(
icon: const Icon(M3EIcons.edit),
onPressed: () {},
),
);
Keyboard: the tooltip shows when its child gets keyboard focus.
M3ESnackbar
Short message at the bottom, at least 48 tall and up to 600 wide, with
an optional action and close button. A bar with either stays until dismissed.
Customize it on M3ESnackbarTheme.
M3ESnackbar.show(
context,
message: 'Draft saved',
actionLabel: 'Undo',
onAction: () {},
);
Keyboard: Escape dismisses it when focused.
M3ETextField
Filled or outlined field, 56 tall with 4 corners, and a label that
springs between the middle and the top. It supports icons, prefix and suffix
text, a placeholder, supporting or error text, a counter, required and
read-only fields, clear and password buttons, multi-line input and density
(0 to -3). Focus is primary and errors are error. Customize it
on M3ETextFieldTheme and M3ETextFieldColorTheme.
M3ETextField(
controller: nameController,
label: 'Full name',
supportingText: 'As it appears on your ID',
showClearButton: true,
);
const M3ETextField(
label: 'Password',
variant: M3ETextFieldVariant.outlined,
obscureText: true,
showPasswordToggle: true,
);
Keyboard: Tab focuses enabled fields. Escape unfocuses.
M3ESearchBar / M3ESearchAnchor / M3ESliverSearchBar
56 pill search bar on surface container high, 24 from its pane and
12 when focused, and a search view (contained or divided) that is
full-screen below 600 and docked above. M3ESliverSearchBar scrolls away
with content. Customize it on M3ESearchBarTheme and M3ESearchViewTheme.
final controller = M3ESearchController();
M3ESearchAnchor.bar(
searchController: controller,
barHintText: 'Search messages',
suggestionsBuilder: (context, controller) => [
for (final name in names)
M3EListItem(headline: name, onTap: () => controller.closeView(name)),
],
);
Keyboard: Tab, then Space or Enter opens the view. Arrows move through results. Escape closes.
Modal surfaces
Several components present transient UI over the app. They all require a
BuildContext with a Navigator / Overlay ancestor (any MaterialApp or
WidgetsApp provides this):
| Component | API |
|---|---|
M3EDialog |
M3EDialog.show, .showSelectionScreen, .showFullScreen, .showAdaptive |
M3EBottomSheet |
M3EBottomSheet.show, .showAdaptive, .standard |
M3ESideSheet |
M3ESideSheet.show, M3ESideSheetLayout |
M3ESnackbar |
M3ESnackbar.show |
Example app (detailed)
Live web build: paadevelopments.github.io/material_3_expressive.
The example/ project is a full gallery app:
- Entry point:
example/lib/main.dart—M3EMaterialAppwithautoTheming,dynamicColoring, and a five-tab catalog-driven gallery shell. The home app bar palette action openstheme_config_page.dartto toggle auto theming and dynamic color, pick one of five seed colors when dynamic color is off, and choose a font family (Google Sans Flex default, system, Roboto Flex, or Roboto Mono). Open View → Typography for type scale, variable-font axes, and conversion demos. - Pages: playgrounds under
example/lib/pages/playground/, grouped by tab (do/,pick/,view/,nav/,find/). Each opens onpreview_screen.dart; the shared layout and controls live inexample/lib/widgets/playground/. - Theme toggle: app-bar
M3EIconButtoncallsM3ETheme.controllerOf(context)?.toggleBrightness(...).
cd example
flutter pub get
flutter run
Pick a device or simulator when prompted. Use the bottom navigation bar to switch between component groups, the palette icon for theme settings, and the brightness icon to toggle light/dark mode.
Development
Static analysis and tests:
flutter analyze
flutter test
Custom lint rules live in tools/klin_dart (path dependency, omitted from the published archive):
export PATH="$PWD/.fvm/flutter_sdk/bin:$PATH"
dart run custom_lint
Support
If this package helps your project:
- Star it on pub.dev
- Star or fork the repo on GitHub
- Share it with others building Material 3 Expressive UIs
Version 1.1.1 — API compatibility
Version 1.1.1 adds typography foundations (M3ETypography, variable-font
axes, style conversion) and exports buildM3EThemeDefaults() and
M3EDynamicColorHost through the public barrel. These changes are additive:
M3EThemeData.typeScale remains a baseline alias, and existing component code
continues to work without migration.
Credits
Several components were ported or vendored from earlier Material 3 Expressive implementations. Thanks to the original authors:
| Author | Components | Source |
|---|---|---|
| Mudit Purohit | Buttons, split buttons, button groups | m3e_buttons |
| Mudit Purohit | Dropdown menus | m3e_dropdown_menu |
| Mudit Purohit | Expandable lists | m3e_expandable |
| Emily | Icon buttons | icon_button_m3e |
| Emily | Navigation bar | navigation_bar_m3e |
| Emily | Navigation rail | navigation_rail_m3e |
| Emily | Loading indicator (Flutter package) | loading_indicator_m3e |
| The Android Open Source Project | Loading indicator (Compose reference) | LoadingIndicator.kt |
| The Android Open Source Project | Slider / RangeSlider / VerticalSlider (Compose reference, material3:1.4.0-alpha01) |
Slider.kt / SliderTokens.kt |
| The Android Open Source Project | Linear / circular wavy progress (Compose reference) | LinearWavyProgressIndicator / CircularWavyProgressIndicator |
| The Android Open Source Project | Floating / docked toolbars (Compose reference, material3:1.4.0-alpha01) |
FloatingToolbar.kt / FlexibleBottomAppBar / DockedToolbarTokens |
| The Flutter Authors | Carousel view layout (CarouselView) |
Flutter SDK / m3_carousel |
| pub.dev | Spring motion (motor), expressive morph polygons (material_new_shapes), dynamic color (dynamic_color) |
See Dependencies |
Copyright notices and licenses from those sources are retained in the
corresponding source files where applicable, and summarized in
NOTICE.
License
Distributed under the MIT License. See LICENSE for details.
Copyright (c) 2026 Paa Developments paa.code.me@gmail.com
Libraries
- components/app_bars/components/m3e_app_bar_semantics
- components/app_bars/controllers/m3e_app_bar_controller
- components/app_bars/enums/m3e_app_bar_enums
- components/app_bars/m3e_app_bars
- components/app_bars/styles/m3e_app_bar_theme
- components/badges/components/m3e_badge_layout
- components/badges/enums/m3e_badge_alignment
- components/badges/m3e_badges
- components/badges/styles/m3e_badge_theme
- components/bottom_sheets/components/m3e_bottom_sheet_drag_handle
- components/bottom_sheets/components/m3e_bottom_sheet_drag_region
- components/bottom_sheets/components/m3e_bottom_sheet_frame
- components/bottom_sheets/components/m3e_bottom_sheet_header
- components/bottom_sheets/components/m3e_bottom_sheet_modal_host
- components/bottom_sheets/components/m3e_bottom_sheet_surface
- components/bottom_sheets/controllers/m3e_bottom_sheet_controller
- components/bottom_sheets/controllers/m3e_bottom_sheet_scroll_controller
- components/bottom_sheets/enums/m3e_bottom_sheet_enums
- components/bottom_sheets/m3e_bottom_sheets
- components/bottom_sheets/models/m3e_bottom_sheet_labels
- components/bottom_sheets/res/m3e_bottom_sheet_strings
- components/bottom_sheets/res/m3e_bottom_sheet_system_ui
- components/bottom_sheets/styles/m3e_bottom_sheet_colors
- components/bottom_sheets/styles/m3e_bottom_sheet_drag_handle_style
- components/bottom_sheets/styles/m3e_bottom_sheet_theme
- components/bottom_sheets/utils/m3e_bottom_sheet_detents
- components/bottom_sheets/utils/m3e_bottom_sheet_size_reporter
- components/bottom_sheets/utils/m3e_bottom_sheet_spring
- components/buttons/components/m3e_no_overflow_strategy
- components/buttons/components/m3e_overflow_strategy
- components/buttons/components/m3e_radius_and_padding_motion
- components/buttons/components/m3e_scroll_overflow_strategy
- components/buttons/styles/m3e_overflow_bottom_sheet_decoration
- components/buttons/styles/m3e_overflow_popup_decoration
- components/cards/components/m3e_card_container_transform
- components/cards/components/m3e_card_group
- components/cards/components/m3e_card_group_scope
- components/cards/controllers/m3e_card_controller
- components/cards/enums/m3e_card_divider_span
- components/cards/enums/m3e_card_group_layout
- components/cards/enums/m3e_card_overflow_alignment
- components/cards/enums/m3e_card_swipe_mode
- components/cards/enums/m3e_card_variant
- components/cards/m3e_cards
- components/cards/styles/m3e_card_theme
- components/carousel/components/m3e_carousel_item
- components/carousel/components/m3e_carousel_show_all
- components/carousel/components/m3e_carousel_slot_scope
- components/carousel/components/m3e_carousel_step_physics
- components/carousel/components/m3e_carousel_track_clip
- components/carousel/components/m3e_carousel_view
- components/carousel/components/m3e_carousel_wrapper
- components/carousel/enums/m3e_carousel_type
- components/carousel/m3e_carousel
- components/carousel/models/m3e_carousel_change_details
- components/carousel/models/m3e_carousel_scrim
- components/carousel/styles/m3e_carousel_theme
- components/carousel/utils/m3e_carousel_layout
- components/carousel/utils/m3e_carousel_scroll_helper
- components/checkbox/m3e_checkbox
- components/checkbox/styles/m3e_checkbox_theme
- components/chips/enums/m3e_chip_type
- components/chips/m3e_chips
- components/chips/styles/m3e_chip_theme
- components/date_pickers/components/m3e_calendar_date_range_picker
- components/date_pickers/components/m3e_date_picker_actions
- components/date_pickers/components/m3e_date_picker_header
- components/date_pickers/components/m3e_date_picker_mode_toggle
- components/date_pickers/components/m3e_day_cell
- components/date_pickers/components/m3e_day_picker
- components/date_pickers/components/m3e_input_date_picker_form_field
- components/date_pickers/components/m3e_input_date_range_picker_form_field
- components/date_pickers/components/m3e_month_picker
- components/date_pickers/components/m3e_year_picker
- components/date_pickers/enums/m3e_date_picker_enums
- components/date_pickers/m3e_calendar_date_picker
- components/date_pickers/m3e_date_picker_dialog
- components/date_pickers/m3e_date_pickers
- components/date_pickers/m3e_date_range_picker_dialog
- components/date_pickers/models/m3e_calendar_labels
- components/date_pickers/models/m3e_date_picker_models
- components/date_pickers/res/m3e_date_picker_constants
- components/date_pickers/styles/m3e_date_picker_theme
- components/date_pickers/utils/m3e_date_picker_utils
- components/dialogs/components/m3e_adaptive_dialog
- components/dialogs/components/m3e_dialog_actions
- components/dialogs/components/m3e_dialog_dismiss_scope
- components/dialogs/components/m3e_dialog_headline
- components/dialogs/components/m3e_dialog_inset
- components/dialogs/components/m3e_dialog_transition
- components/dialogs/components/m3e_full_screen_dialog
- components/dialogs/controllers/m3e_dialog_controller
- components/dialogs/enums/m3e_dialog_enums
- components/dialogs/m3e_dialogs
- components/dialogs/models/m3e_dialog_discard_labels
- components/dialogs/res/m3e_dialog_strings
- components/dialogs/styles/m3e_dialog_appearance
- components/dialogs/styles/m3e_dialog_theme
- components/dialogs/styles/m3e_full_screen_dialog_theme
- components/dialogs/utils/m3e_dialog_spring
- components/dialogs/utils/m3e_dialog_surface
- components/divider/enums/m3e_divider_axis
- components/divider/enums/m3e_divider_inset
- components/divider/m3e_divider
- components/divider/styles/m3e_divider_theme
- components/dropdown_menus/components/m3e_dropdown_chips
- components/dropdown_menus/controllers/m3e_dropdown_controller
- components/dropdown_menus/enums/m3e_dropdown_expand_direction
- components/dropdown_menus/models/m3e_dropdown_item
- components/dropdown_menus/styles/m3e_dropdown_chip_style
- components/dropdown_menus/styles/m3e_dropdown_field_style
- components/dropdown_menus/styles/m3e_dropdown_item_style
- components/dropdown_menus/styles/m3e_dropdown_panel_style
- components/dropdown_menus/styles/m3e_dropdown_search_style
- components/dropdown_menus/utils/m3e_dropdown_spring_motion
- components/extended_fabs/controllers/m3e_extended_fab_controller
- components/extended_fabs/enums/m3e_extended_fab
- components/extended_fabs/m3e_extended_fabs
- components/floating_action_buttons/components/m3e_fab_container_transform
- components/floating_action_buttons/controllers/m3e_fab_controller
- components/floating_action_buttons/enums/m3e_fab
- components/floating_action_buttons/styles/m3e_fab_decoration
- components/floating_action_buttons/styles/m3e_fab_theme
- components/lists/components/m3e_card_list_item
- components/lists/components/m3e_card_radius_motion
- components/lists/components/m3e_expandable_data
- components/lists/components/m3e_expandable_expanded
- components/lists/components/m3e_expandable_item
- components/lists/components/m3e_expandable_nest_scope
- components/lists/components/m3e_expandable_snap_collapse
- components/lists/components/m3e_expandable_sublist
- components/lists/components/m3e_list_avatar
- components/lists/components/m3e_list_drag_proxy_scope
- components/lists/components/m3e_list_feature_host
- components/lists/components/m3e_list_feature_scope
- components/lists/components/m3e_list_focus_ring
- components/lists/components/m3e_list_image
- components/lists/components/m3e_list_interaction
- components/lists/components/m3e_list_item_scope
- components/lists/components/m3e_list_key_target
- components/lists/components/m3e_list_keyboard
- components/lists/components/m3e_list_reorder_exclude
- components/lists/components/m3e_list_reorder_host
- components/lists/components/m3e_list_reorder_placeholder
- components/lists/components/m3e_list_reorder_session_scope
- components/lists/components/m3e_list_row_surface
- components/lists/components/m3e_list_swipe_overflow
- components/lists/components/m3e_list_trailing_override
- components/lists/components/m3e_list_transform_publisher
- components/lists/components/m3e_list_transform_scope
- components/lists/components/m3e_list_video
- components/lists/controllers/m3e_dismissible_card_controller
- components/lists/controllers/m3e_dismissible_list_controller
- components/lists/controllers/m3e_expandable_list_controller
- components/lists/enums/m3e_expandable_enums
- components/lists/enums/m3e_list_enums
- components/lists/enums/m3e_list_selection_enums
- components/lists/enums/m3e_list_swipe_edge
- components/lists/enums/m3e_list_swipe_mode
- components/lists/m3e_lists
- components/lists/models/m3e_dismissible_slot
- components/lists/models/m3e_list_item_swipe
- components/lists/models/m3e_list_swipe_action
- components/lists/styles/m3e_dismissible_list_style
- components/lists/styles/m3e_expandable_style
- components/lists/styles/m3e_list_card_list_theme
- components/lists/styles/m3e_list_dismissible_theme
- components/lists/styles/m3e_list_expandable_theme
- components/lists/styles/m3e_list_item_theme
- components/lists/styles/m3e_list_reorder_state
- components/lists/styles/m3e_list_selection_state
- components/lists/styles/m3e_list_theme
- components/lists/utils/m3e_expandable_spring_motion
- components/lists/utils/m3e_list_immediate_tap
- components/lists/utils/m3e_list_row_features
- components/lists/utils/m3e_list_selection_binding
- components/lists/utils/m3e_list_selection_fill
- components/lists/utils/m3e_measure_size
- components/loading_indicator/components/m3e_expressive_loading_indicator
- components/loading_indicator/enums/m3e_loading_indicator_variant
- components/loading_indicator/m3e_loading_indicator
- components/loading_indicator/styles/m3e_loading_indicator_theme
- components/navigation_rail/components/m3e_rail_badge_view
- components/navigation_rail/components/m3e_rail_item
- components/progress_indicators/components/m3e_circular_progress_painter
- components/progress_indicators/components/m3e_circular_wavy_progress_painter
- components/progress_indicators/components/m3e_linear_progress_painter
- components/progress_indicators/enums/m3e_progress_enums
- components/progress_indicators/m3e_progress_indicators
- components/progress_indicators/styles/m3e_progress_indicator_theme
- components/progress_indicators/utils/m3e_progress_indicator_utils
- components/radio_button/styles/m3e_radio_theme
- components/refresh_indicator/controllers/m3e_refresh_indicator_controller
- components/refresh_indicator/enums/m3e_refresh_status
- components/refresh_indicator/m3e_refresh_indicator
- components/refresh_indicator/styles/m3e_refresh_indicator_theme
- components/search/components/m3e_search_anchor_scope
- components/search/components/m3e_search_view
- components/search/controllers/m3e_search_controller
- components/search/enums/m3e_search_enums
- components/search/m3e_search
- components/search/m3e_search_anchor
- components/search/m3e_search_bar
- components/search/m3e_sliver_search_bar
- components/search/models/m3e_search_anchor_surface
- components/search/res/m3e_search_constants
- components/search/styles/m3e_search_bar_theme
- components/search/styles/m3e_search_view_theme
- components/search/utils/m3e_search_selection_controls
- components/search/utils/m3e_search_spring
- components/segmented_buttons/components/m3e_segment_divider
- components/segmented_buttons/models/m3e_segment
- components/selection/components/m3e_selection_app_bar
- components/selection/components/m3e_selection_flip
- components/selection/components/m3e_selection_leading
- components/selection/components/m3e_selection_scope
- components/selection/controllers/m3e_selection_controller
- components/selection/m3e_selection
- components/selection/styles/m3e_selection_theme
- components/side_sheets/components/m3e_side_sheet_actions
- components/side_sheets/components/m3e_side_sheet_back_transform
- components/side_sheets/components/m3e_side_sheet_body
- components/side_sheets/components/m3e_side_sheet_header
- components/side_sheets/components/m3e_side_sheet_icon_action
- components/side_sheets/components/m3e_side_sheet_scrim
- components/side_sheets/components/m3e_side_sheet_surface
- components/side_sheets/controllers/m3e_side_sheet_controller
- components/side_sheets/enums/m3e_side_sheet_enums
- components/side_sheets/m3e_side_sheets
- components/side_sheets/models/m3e_side_sheet_labels
- components/side_sheets/res/m3e_side_sheet_strings
- components/side_sheets/res/m3e_side_sheet_system_ui
- components/side_sheets/styles/m3e_side_sheet_action_style
- components/side_sheets/styles/m3e_side_sheet_colors
- components/side_sheets/styles/m3e_side_sheet_motion
- components/side_sheets/styles/m3e_side_sheet_theme
- components/side_sheets/utils/m3e_side_sheet_animator
- components/side_sheets/utils/m3e_side_sheet_spring
- components/sliders/components/m3e_range_slider_track
- components/sliders/components/m3e_slider_centered_track
- components/sliders/components/m3e_slider_dot_overlay
- components/sliders/components/m3e_slider_thumb
- components/sliders/components/m3e_slider_track
- components/sliders/components/m3e_slider_track_painter
- components/sliders/components/m3e_slider_value_indicator
- components/sliders/enums/m3e_slider_enums
- components/sliders/m3e_range_slider
- components/sliders/m3e_sliders
- components/sliders/models/m3e_slider_dot_builder
- components/sliders/models/m3e_slider_range
- components/sliders/models/m3e_slider_range_labels
- components/sliders/models/m3e_slider_track_icons
- components/sliders/res/m3e_slider_tokens
- components/sliders/styles/m3e_slider_theme
- components/sliders/utils/m3e_slider_dot_geometry
- components/sliders/utils/m3e_slider_dot_layout
- components/sliders/utils/m3e_slider_math
- components/sliders/utils/m3e_slider_track_paint_metrics
- components/snackbar/components/m3e_snackbar_host
- components/snackbar/controllers/m3e_snackbar_controller
- components/snackbar/m3e_snackbar
- components/snackbar/styles/m3e_snackbar_theme
- components/switch_control/m3e_switch_control
- components/switch_control/styles/m3e_switch_theme
- components/tabs/controllers/m3e_tabs_controller
- components/tabs/enums/m3e_tabs_alignment
- components/tabs/enums/m3e_tabs_variant
- components/tabs/m3e_tabs
- components/tabs/m3e_tabs_view
- components/tabs/models/m3e_tab
- components/tabs/styles/m3e_tab_theme
- components/text_fields/components/m3e_text_field_affordance
- components/text_fields/components/m3e_text_field_container_painter
- components/text_fields/components/m3e_text_field_label
- components/text_fields/components/m3e_text_field_selection_builder
- components/text_fields/components/m3e_text_field_supporting_row
- components/text_fields/enums/m3e_text_field_slot_alignment
- components/text_fields/enums/m3e_text_field_variant
- components/text_fields/m3e_text_fields
- components/text_fields/models/m3e_text_field_colors
- components/text_fields/models/m3e_text_field_states
- components/text_fields/styles/m3e_text_field_color_theme
- components/text_fields/styles/m3e_text_field_theme
- components/text_fields/utils/m3e_text_field_autofill_client
- components/text_fields/utils/m3e_text_field_selection_controls
- components/time_pickers/components/m3e_day_period_control
- components/time_pickers/components/m3e_dial_time_picker
- components/time_pickers/components/m3e_hour_minute_text_field
- components/time_pickers/components/m3e_input_time_picker_form_field
- components/time_pickers/components/m3e_time_dial_painter
- components/time_pickers/components/m3e_time_picker_actions
- components/time_pickers/components/m3e_time_picker_dialog_content
- components/time_pickers/components/m3e_time_picker_header
- components/time_pickers/enums/m3e_time_picker_enums
- components/time_pickers/m3e_time_picker_dialog
- components/time_pickers/m3e_time_pickers
- components/time_pickers/models/m3e_time
- components/time_pickers/res/m3e_time_picker_constants
- components/time_pickers/styles/m3e_time_picker_theme
- components/time_pickers/utils/m3e_time_picker_utils
- components/toolbars/components/m3e_toolbar_actions_row
- components/toolbars/components/m3e_toolbar_body
- components/toolbars/components/m3e_toolbar_expanding_actions
- components/toolbars/components/m3e_toolbar_fab_layout
- components/toolbars/components/m3e_toolbar_fab_slot
- components/toolbars/components/m3e_toolbar_measure_size
- components/toolbars/components/m3e_toolbar_title_block
- components/toolbars/controllers/m3e_toolbar_visibility_controller
- components/toolbars/enums/m3e_toolbar_enums
- components/toolbars/m3e_toolbar_scroll_behavior
- components/toolbars/m3e_toolbars
- components/toolbars/models/m3e_toolbar_item
- components/toolbars/res/m3e_toolbar_tokens
- components/toolbars/styles/m3e_toolbar_theme
- components/toolbars/utils/m3e_toolbar_item_layout
- components/toolbars/utils/m3e_toolbar_spring_motion
- components/tooltips/controllers/m3e_tooltip_controller
- components/tooltips/enums/m3e_tooltip_placement
- components/tooltips/m3e_tooltips
- components/tooltips/styles/m3e_tooltip_theme
- components/tooltips/utils/m3e_tooltip_position_delegate
- foundations/color/m3e_color_scheme
- foundations/color/m3e_color_utils
- foundations/components/m3e_component_theme
- foundations/foundations
- Design tokens, theming hosts, and shared interaction primitives for Material 3 Expressive components.
- foundations/interaction/m3e_focus
- foundations/interaction/m3e_focus_interaction
- foundations/interaction/m3e_focus_ring
- foundations/interaction/m3e_focus_ring_theme
- foundations/interaction/m3e_haptics
- foundations/interaction/m3e_ink_splash_theme
- foundations/interaction/m3e_motion
- foundations/interaction/m3e_overlay_history
- foundations/interaction/m3e_state_layer
- foundations/interaction/m3e_state_layer_overlay
- foundations/interaction/m3e_tappable
- foundations/interaction/m3e_tappable_ink_scope
- foundations/m3e_icons
- foundations/shape/m3e_material_new_shapes_bridge
- foundations/shape/m3e_shape_clipper
- foundations/shape/m3e_shape_container
- foundations/shape/m3e_shape_kind
- foundations/shape/m3e_shapes
- foundations/theme/m3e_dynamic_color_host
- foundations/theme/m3e_material_app
- foundations/theme/m3e_resolved_theme
- foundations/theme/m3e_theme
- foundations/theme/m3e_theme_controller
- foundations/theme/m3e_theme_data
- foundations/theme/m3e_theme_defaults
- foundations/theme/m3e_theme_extension
- foundations/theme/m3e_theme_scope
- foundations/tokens/m3e_dimensions
- foundations/tokens/m3e_elevation
- foundations/tokens/m3e_safe_area
- foundations/tokens/m3e_scrim_system_ui
- foundations/tokens/m3e_spacing
- foundations/type/m3e_type_style_conversion
- foundations/type/m3e_type_style_tokens
- foundations/type/m3e_typography
- foundations/type/m3e_variable_font_axes
- foundations/type/m3e_variable_font_config
- material_3_expressive
- Material 3 Expressive: a faithful Flutter implementation of the Material 3
component set, exposed as direct
M3E*component widgets.




