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 45 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 playground includes a Code section with paste-ready Dart that tracks
the current controls (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 |
| 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, font family, and M3 Expressive
type styles on Roboto Flex).
cd example
flutter run
Features
- 45 widgets across 40 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, liquid 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.44.0 |
| Dart | ^3.12.0 |
Migrating to material_ui
This package uses material_ui ^1.0.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.44.0 or newer
is required (material_ui will not resolve on older SDKs).
Installation
Add the package to your pubspec.yaml:
dependencies:
material_3_expressive: ^1.0.8
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) |
motor |
Unified motion API — physics springs and curves that drive expressive morphs and liquid 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.
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 rolestypeScale—M3ETypeScale(display, headline, title, label, body)spacing,visualDensity, per-component*Themeextensions
Shared typography (font family, fallback, package, size factor/delta, color,
decoration, and variable-font axes) is a one-knob on the type scale — not a
full TextStyle:
final themed = M3EThemeData.light(seedColor: seed).copyWith(
typeScale: M3ETypeScale.baseline().apply(
fontFamily: 'Roboto Flex',
fontVariations: M3ETypeVariations.emphasized.variations,
),
);
// Sugar: same result without building a type scale by hand
final alsoThemed = M3EThemeData.light(seedColor: seed).copyWith(
fontFamily: 'Roboto Flex',
fontVariations: M3ETypeVariations.emphasized.variations,
);
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 to apply the same type-scale knobs at the shell:
M3EMaterialApp(
data: M3EThemeData.light(seedColor: seed),
fontFamily: 'Roboto Flex',
fontVariations: M3ETypeVariations.wide.variations,
home: const HomePage(),
);
M3ETypeVariations is an enum of Roboto Flex axes (.variations): regular,
emphasized, condensed, extra condensed, wide, extra wide, and round. Static
and mono fonts ignore axes they do not define. The shell projects the 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
Five color variants with shape morphing on press. Optional
M3EButtonDecoration gradients: backgroundGradient, foregroundGradient
(text/icons), overlayGradient (state layer), and outlineGradient (stroke
width still comes from side).
M3EButton(
style: M3EButtonStyle.elevated,
onPressed: () {},
child: const Text('Elevated'),
);
M3EButton(
decoration: M3EButtonDecoration(
backgroundGradient: WidgetStateProperty.all(
const LinearGradient(colors: [Color(0xFF6750A4), Color(0xFF9A82DB)]),
),
foregroundGradient: WidgetStateProperty.all(
const LinearGradient(colors: [Color(0xFFFFFFFF), Color(0xFFEADDFF)]),
),
outlineGradient: WidgetStateProperty.all(
const LinearGradient(colors: [Color(0xFF6750A4), Color(0xFF9A82DB)]),
),
side: WidgetStateProperty.all(const BorderSide(width: 1)),
),
onPressed: () {},
child: const Text('Gradient'),
);
M3EIconButton
Icon-only actions; supports toggle selection. Optional visualSize overrides
the painted control size while hit target follows theme rules. Hover and press
morph container radius (theme radiusHovered / press tokens). Pass
decoration: M3EIconButtonDecoration(...) for fill, foreground, overlay, and
outline gradients (same fields as M3EButtonDecoration).
M3EIconButton(
icon: const Icon(M3EIcons.edit),
variant: M3EIconButtonVariant.filled,
onPressed: () {},
);
// in State
M3EIconButton(
icon: const Icon(M3EIcons.add),
selectedIcon: const Icon(M3EIcons.check),
isSelected: isFavorite,
onPressed: () => setState(() => isFavorite = !isFavorite),
);
M3EFab
Floating action button in three sizes. Optional decoration: M3EFabDecoration
for fill, foreground, overlay, and outline gradients.
M3EFab(
icon: const Icon(M3EIcons.add),
size: M3EFabSize.large,
color: M3EFabColor.tertiary,
onPressed: () {},
);
M3EExtendedFab
FAB with a text label. Accepts the same M3EFabDecoration as M3EFab.
M3EExtendedFab(
label: 'Compose',
icon: const Icon(M3EIcons.edit),
onPressed: () {},
);
M3EFabMenu
Speed-dial menu anchored to a FAB. The FAB morphs size (80↔56) and circle when
opening; use position for left/right anchor, and optional expandIcon /
collapseIcon (fallbacks: icon / closeIcon). Pass decoration for the
trigger FAB. Menu-item fill, foreground, and outline gradients live on
M3EFabMenuTheme (itemBackgroundGradient, itemForegroundGradient,
itemOutlineGradient / itemOutlineColor, itemBorderWidth).
M3EFabMenu(
position: M3EFabMenuPosition.right,
expandIcon: const Icon(M3EIcons.add),
collapseIcon: const Icon(M3EIcons.close),
decoration: M3EFabDecoration(
backgroundGradient: WidgetStateProperty.all(
const LinearGradient(colors: [Color(0xFF6750A4), Color(0xFF9A82DB)]),
),
),
items: [
M3EFabMenuItem(
icon: const Icon(M3EIcons.edit),
label: 'Note',
onPressed: () {},
),
M3EFabMenuItem(
icon: const Icon(M3EIcons.schedule),
label: 'Reminder',
onPressed: () {},
),
],
);
M3EButtonGroup
Grouped icon buttons with neighbour squish or connected corner morphing.
// in State
M3EButtonGroup(
selectedIndex: groupIndex,
onSelectedIndexChanged: (i) => setState(() => groupIndex = i ?? groupIndex),
actions: const [
M3EButtonGroupAction(icon: Icon(M3EIcons.arrow_back)),
M3EButtonGroupAction(icon: Icon(M3EIcons.add)),
M3EButtonGroupAction(icon: Icon(M3EIcons.arrow_forward)),
],
);
M3EButtonGroup(
type: M3EButtonGroupType.connected,
actions: const [
M3EButtonGroupAction(icon: Icon(M3EIcons.chevron_left)),
M3EButtonGroupAction(icon: Icon(M3EIcons.menu)),
M3EButtonGroupAction(icon: Icon(M3EIcons.chevron_right)),
],
);
M3EToggleButton
Toggle with round-to-square shape morphing. Optional
decoration: M3EToggleButtonDecoration(...) for the same gradient fields as
M3EButtonDecoration. M3EButtonGroup / M3EToggleButtonGroup accept a
group-level decoration and per-action M3EButtonGroupAction.decoration.
// in State
M3EToggleButton.filled(
icon: const Icon(M3EIcons.favorite_border),
checkedIcon: const Icon(M3EIcons.favorite),
checked: isFavorite,
onCheckedChange: (v) => setState(() => isFavorite = v),
);
M3EToggleButton.text(
label: const Text('Bold'),
checked: isBold,
onCheckedChange: (v) => setState(() => isBold = v),
);
M3ESegmentedButton
Single- or multi-select segmented control. Theme
M3ESegmentedButtonTheme can set outlineColor / outlineGradient,
dividerColor / dividerGradient (sampled across the whole group), and
selected/unselected background and foreground colors or gradients.
// in State — single select
M3ESegmentedButton<String>(
segments: const [
M3ESegment(value: 'list', label: 'List'),
M3ESegment(value: 'grid', label: 'Grid'),
],
selected: viewMode,
onSelectionChanged: (v) => setState(() => viewMode = v),
);
// multi select
M3ESegmentedButton<String>(
multiSelect: true,
segments: const [
M3ESegment(value: 'new', label: 'New'),
M3ESegment(value: 'sale', label: 'Sale'),
],
selected: filters,
onSelectionChanged: (v) => setState(() => filters = v),
);
M3ESplitButton
Primary action with a trailing menu. Use items for a flat list, or
m3eMenuBuilder for a rich M3E menu tree (groups, dividers, submenus). Legacy
menuBuilder still opens Flutter showMenu. Gradients on
M3ESplitButtonDecoration span both segments; optional
trailingBackgroundGradient / trailingForegroundGradient /
trailingOutlineGradient / trailingOverlayGradient override the trailing
half. decoration.animationDuration defaults to Duration.zero so the
trailing radius morph stays on the spring.
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')),
],
);
M3ESplitButton<String>(
label: 'Share',
items: null,
onSelected: (value) {},
m3eMenuBuilder: (context) => [
M3EMenuSelectable(label: 'Copy link', value: 'link'),
const M3EMenuDivider(),
M3EMenuSelectable(label: 'Email', value: 'email'),
],
);
Selection
See also:
example/lib/pages/playground/pick/(Pick tab)
M3ECheckbox
Binary and tristate checkbox.
// in State
M3ECheckbox(
value: checked,
onChanged: (v) => setState(() => checked = v),
);
M3ECheckbox(
value: tristateValue,
tristate: true,
onChanged: (v) => setState(() => tristateValue = v),
);
M3ERadio
Mutually exclusive selection within a group. Optional label is part of the
tap target.
// in State
M3ERadio<String>(
value: 'pro',
groupValue: plan,
label: const Text('Pro'),
onChanged: (v) => setState(() => plan = v),
);
M3ESwitch
On/off toggle with optional selected icon. Hover/focus/press paints a
thumb-centered translucent state layer (stateLayerSize, default 48 via theme).
Pressed thumb expands to the track edges (thumbSizePressed defaults to
trackHeight).
// in State
M3ESwitch(
value: wifiEnabled,
selectedIcon: const Icon(M3EIcons.check),
onChanged: (v) => setState(() => wifiEnabled = v),
);
M3ESwitch(
value: bluetoothEnabled,
stateLayerSize: 56,
onChanged: (v) => setState(() => bluetoothEnabled = v),
);
M3EChip
Assist, filter, input, and suggestion chip types.
M3EChip(
label: 'Assist',
leading: const Icon(M3EIcons.edit),
onPressed: () {},
);
// in State — filter chip
M3EChip(
label: 'Flutter',
type: M3EChipType.filter,
selected: chips.contains('flutter'),
onPressed: () => toggleChip('flutter'),
);
M3EDropdownMenu
Static list, multi-select, search, and async loading. When search is enabled,
the in-panel field defaults to surface fill and the panel container radius.
// Single select
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) {},
);
// Multi select with search
M3EDropdownMenu<String>(
searchEnabled: true,
items: const [
M3EDropdownItem(label: 'Layout', value: 'layout'),
M3EDropdownItem(label: 'Theming', value: 'theming'),
],
fieldStyle: const M3EDropdownFieldStyle(hintText: 'Select skills'),
onSelectionChanged: (items) {},
);
// Async items
M3EDropdownMenu<String>.future(
singleSelect: true,
future: () async => [
const M3EDropdownItem(label: 'Ghana', value: 'gh'),
const M3EDropdownItem(label: 'Kenya', value: 'ke'),
],
fieldStyle: const M3EDropdownFieldStyle(hintText: 'Load countries'),
onSelectionChanged: (items) {},
);
M3ESlider
Compose Material 3 expressive slider — standard, centered, wavy, vertical, and
range. Optional trackThickness, cornerRadius, thumbLength, dotSize,
dotSpacing, and dotBuilder customize track, thumb, and stop/tick markers.
cornerRadius defaults to theme trackCornerRadius (8) and is not derived
from track thickness. Tap outside the slider clears focus.
// in State
M3ESlider(
value: volume,
onChanged: (v) => setState(() => volume = v),
);
M3ESlider(
value: brightness,
max: 5,
divisions: 5,
onChanged: (v) => setState(() => brightness = v),
);
// Wavy active value (inactive track stays flat)
M3ESlider.wavy(
value: progress,
onChanged: (v) => setState(() => progress = v),
);
M3ESlider.centered(
value: balance,
min: -100,
max: 100,
onChanged: (v) => setState(() => balance = v),
);
// Custom track / thumb / end dots (size & edge padding)
M3ESlider(
value: level,
max: 4,
divisions: 4,
trackThickness: 30,
cornerRadius: 8,
thumbLength: 50,
dotSize: 12,
dotSpacing: 10,
onChanged: (v) => setState(() => level = v),
dotBuilder: ({
required context,
required color,
required size,
required active,
}) {
// e.g. paint M3EMaterialNewShapes.cookie4Sided / softBurst
return ColoredBox(color: color);
},
);
M3ERangeSlider(
values: range,
onChanged: (v) => setState(() => range = v),
);
M3ERangeSlider.wavy(
values: range,
onChanged: (v) => setState(() => range = v),
);
SizedBox(
height: 160,
width: 48,
child: M3ESlider.vertical(
value: level,
onChanged: (v) => setState(() => level = v),
),
);
M3EDatePicker
Dialog and inline calendar date pickers.
// Inline calendar
M3ECalendarDatePicker(
initialDate: date,
firstDate: DateTime(2020),
lastDate: DateTime(2030),
onDateChanged: (v) => setState(() => date = v),
);
// Dialog
final picked = await M3EDatePicker.show(
context,
initialDate: date,
firstDate: DateTime(2020),
lastDate: DateTime(2030),
);
// Range dialog
final range = await M3EDatePicker.showRange(
context,
firstDate: DateTime(2020),
lastDate: DateTime(2030),
);
M3ETimePicker
Dialog and dial-style time picker.
// Dialog
final M3ETime? picked = await M3ETimePicker.show(
context,
initialTime: time,
);
// Inline dial
M3EDialTimePicker(
value: time,
onChanged: (v) => setState(() => time = v),
);
Containment
See also:
example/lib/pages/playground/view/(View tab)
M3ECard
Elevated, filled, and outlined surface for content and actions.
M3ECard(child: const Text('Elevated'));
M3ECard(
variant: M3ECardVariant.filled,
child: const Text('Filled'),
);
M3ECard(
variant: M3ECardVariant.outlined,
onPressed: () {},
child: const Text('Outlined (tap)'),
);
M3ECarousel
Hero, contained, and uncontained layouts — horizontal by default, or vertical
via axis. Use onChange for leading/focal index updates (e.g. hide labels on
smaller items).
M3ECarousel(
type: M3ECarouselType.hero,
heroAlignment: M3ECarouselHeroAlignment.center,
onTap: (index) {},
onChange: (details) {
// details.focalIndex / details.leadingIndex / details.isFocal(i)
},
children: List.generate(10, (i) => ColoredBox(color: Colors.blue)),
);
M3EListItem
Standard list row with headline, supporting text, and slots. Optional
variant / border control the standalone card outline.
M3EListItem(
headline: 'Wireless charging',
supportingText: 'On · Fast charge enabled',
leading: const Icon(M3EIcons.schedule),
trailing: const Icon(M3EIcons.chevron_right),
variant: M3ECardVariant.outlined,
onTap: () {},
);
M3ECardList
Vertically stacked cards with dynamic corner rounding. Pass
variant: M3ECardVariant.outlined (or border) for outlined cards.
M3ECardList(
variant: M3ECardVariant.outlined,
itemCount: 3,
onTap: (index) {},
itemBuilder: (context, index) => M3EListItem(
headline: 'Inbox',
leading: const Icon(M3EIcons.schedule),
),
);
// Scrollable / lazy
M3ECardList.builder(
itemCount: 20,
shrinkWrap: true,
itemBuilder: (context, index) => M3EListItem(
headline: 'Item $index',
),
);
M3ESelection
Multi-select host: optional M3ESelectionController, M3ESelectionAppBar
(idle header → contextual bar + select-all; idle is any Widget), and any
list body (M3ECardList, M3EDismissibleList, …). Selected rows pick up
selectedColor (or M3ESelectionTheme.highlightColor, default
secondaryContainer) automatically — no colorBuilder required for the
highlight. Use borderRadiusBuilder for selected-item corner morph (spring),
gestures (onTap / onLongPress), and M3ESelectionLeading on each item.
Wrap with PopScope so system back clears selection first. Prefer
listPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 8).
final selection = M3ESelectionController();
PopScope(
canPop: !selection.isSelectionMode,
onPopInvokedWithResult: (didPop, _) {
if (!didPop) selection.clear();
},
child: M3ESelection(
controller: selection,
itemCount: items.length,
selectedColor: const Color(0xFFC8E6C9),
appBar: M3ESelectionAppBar(
idle: M3EAppBar.search(
searchController: searchController,
suggestionsBuilder: (_, __) => const [],
barHintText: 'Search items',
),
actions: [
M3EIconButton(icon: Icon(M3EIcons.archive), onPressed: () {}),
M3EIconButton(icon: Icon(M3EIcons.delete), onPressed: () {}),
],
),
body: M3ECardList.builder(
itemCount: items.length,
listPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
borderRadiusBuilder: (i, pos) => selection.isSelected(i)
? BorderRadius.circular(24)
: null,
onLongPress: (i) => selection.select(i),
onTap: (i) {
if (selection.isSelectionMode) {
selection.toggle(i);
}
},
itemBuilder: (context, i) => M3EListItem(
headline: items[i],
leading: M3ESelectionLeading(
selected: selection.isSelected(i),
onTap: () => selection.toggle(i),
selectedChild: CircleAvatar(child: Icon(M3EIcons.check)),
child: CircleAvatar(child: Text('$i')),
),
),
),
),
);
Advanced: wire M3ESelectionAppBar + a shared controller yourself (omit
M3ESelection), or pass M3EDismissibleList as body for swipe + select.
An explicit colorBuilder still wins over the selection highlight.
M3EDismissibleColumn
Vertically swipeable card list with expressive physics.
M3EDismissibleColumn(
itemCount: 3,
onDismiss: (index, direction) async => true,
onTap: (index) {},
itemBuilder: (context, index) => M3EListItem(
headline: 'Swipe to dismiss',
leading: const Icon(M3EIcons.schedule),
),
);
M3EDismissibleList
Horizontal swipeable card list — same API as M3EDismissibleColumn.
SizedBox(
height: 120,
child: M3EDismissibleList(
itemCount: 5,
onDismiss: (index, direction) async => true,
itemBuilder: (context, index) => M3EListItem(
headline: 'Card $index',
),
),
);
M3EExpandableList
Expandable cards with expressive open/close motion.
M3EExpandableList(
data: [
M3EExpandableData(
title: 'Battery level low',
subtitle: 'Plug in your device.',
leading: const Icon(M3EIcons.battery_alert),
body: const Text('Your battery is at 10%.'),
),
],
);
// Scrollable variant for long lists
M3EExpandableList.scrollable(
data: expandableItems,
shrinkWrap: true,
);
// Sliver variant for CustomScrollView
CustomScrollView(
slivers: [
M3EExpandableList.sliver(data: expandableItems),
],
);
M3EDivider
Horizontal and vertical dividers.
const M3EDivider();
Row(
children: [
const Text('Left'),
const SizedBox(width: 12),
const M3EDivider(axis: M3EDividerAxis.vertical),
const SizedBox(width: 12),
const Text('Right'),
],
);
M3EDialog
Modal dialog — use the static .show helper. Optional topDivider /
bottomDivider draw full-bleed lines between header, content, and actions
(padding lives on those sections so dividers can reach the edges).
M3EDialog.show<void>(
context,
dialog: M3EDialog(
title: 'Reset settings?',
content: const Text('This restores default values.'),
topDivider: true,
bottomDivider: true,
actions: [
M3EButton(
style: M3EButtonStyle.text,
onPressed: () => Navigator.of(context).pop(),
child: const Text('Cancel'),
),
M3EButton(
onPressed: () => Navigator.of(context).pop(),
child: const Text('Reset'),
),
],
),
);
// Selection list (single or multi); confirm disabled until a choice is made
final List<String>? picked = await M3EDialog.showSelectionScreen(
context,
title: 'Choose a plan',
options: const <String>['Standard', 'Pro', 'Team'],
multiSelect: false,
);
// Full-screen variant
M3EDialog.showFullScreen<void>(
context,
title: 'New event',
body: const Padding(
padding: EdgeInsets.all(24),
child: Text('Full-screen dialog body.'),
),
);
M3EBottomSheet
Modal bottom sheet — use .show.
M3EBottomSheet.show<void>(
context,
builder: (context) => const Padding(
padding: EdgeInsets.all(24),
child: Text('A modal bottom sheet with a drag handle.'),
),
);
M3ESideSheet
Side sheet panel — use .show.
M3ESideSheet.show<void>(
context,
title: 'Filters',
body: const Padding(
padding: EdgeInsets.all(24),
child: Text('Side sheet content.'),
),
);
Navigation
See also:
example/lib/pages/playground/nav/(Nav tab)
M3EAppBar
Top, search, sliver, and bottom app bar variants. Docked top/bottom bars apply
single-edge safeArea padding from MediaQuery.viewPadding by default
(opt out with safeArea: false).
M3EAppBar.top(
titleText: 'Inbox',
leading: const Icon(M3EIcons.menu),
actions: const [Icon(M3EIcons.search)],
);
// Anchored search title — tap opens fullscreen (or docked) search.
// Idle pill content (leading + hint + trailing) defaults to Alignment.center.
M3EAppBar.search(
searchController: searchController,
barHintText: 'Search mail',
leading: const Icon(M3EIcons.menu),
actions: const [Icon(M3EIcons.tune)],
suggestionsBuilder: (context, controller) sync* {
yield const ListTile(title: Text('Suggestion'));
},
);
// Sliver (inside CustomScrollView)
M3EAppBar.sliver(
titleText: 'Sliver • medium',
actions: const [Icon(M3EIcons.search)],
);
// Bottom app bar with FAB slot
M3EAppBar.bottom(
actions: const [Icon(M3EIcons.menu), Icon(M3EIcons.search)],
floatingActionButton: M3EFab(
icon: const Icon(M3EIcons.add),
size: M3EFabSize.small,
onPressed: () {},
),
);
M3ETabs
Primary and secondary tab bars.
// in State
M3ETabs(
selectedIndex: tabIndex,
onTabSelected: (i) => setState(() => tabIndex = i),
tabs: const [
M3ETab(label: 'Overview'),
M3ETab(label: 'Specs'),
M3ETab(label: 'Reviews'),
],
);
M3ETabs(
variant: M3ETabsVariant.secondary,
selectedIndex: tabIndex,
onTabSelected: (i) => setState(() => tabIndex = i),
tabs: const [
M3ETab(label: 'Photos', icon: Icon(M3EIcons.calendar_today)),
M3ETab(label: 'Albums', icon: Icon(M3EIcons.menu)),
],
);
M3ENavigationBar
Bottom navigation for compact layouts. Destinations use a click mouse cursor on desktop/web (same for rail and drawer).
// in State
M3ENavigationBar(
destinations: const [
M3ENavigationBarDestination(icon: Icon(M3EIcons.menu), label: 'Home'),
M3ENavigationBarDestination(
icon: Icon(M3EIcons.search),
label: 'Search',
badgeDot: true,
),
],
selectedIndex: barIndex,
onDestinationSelected: (i) => setState(() => barIndex = i),
);
M3ENavigationRail
Vertical navigation for medium and expanded layouts.
// in State
M3ENavigationRail(
sections: const [
M3ENavigationRailSection(
destinations: [
M3ENavigationRailDestination(
icon: Icon(M3EIcons.menu),
label: 'Home',
),
M3ENavigationRailDestination(
icon: Icon(M3EIcons.search),
label: 'Search',
),
],
),
],
selectedIndex: railIndex,
onDestinationSelected: (i) => setState(() => railIndex = i),
fab: M3ENavigationRailFabSlot(
icon: const Icon(M3EIcons.add),
label: 'Compose',
onPressed: () {},
),
);
M3ENavigationDrawer
Modal navigation drawer.
// in State
M3ENavigationDrawer(
headline: 'Mail',
destinations: const [
M3ENavigationDestination(icon: Icon(M3EIcons.menu), label: 'Home'),
M3ENavigationDestination(
icon: Icon(M3EIcons.search),
label: 'Search',
showBadge: true,
),
],
selectedIndex: drawerIndex,
onDestinationSelected: (i) => setState(() => drawerIndex = i),
);
M3EToolbar
Compose Material 3 expressive floating and docked toolbars. Floating toolbars
own expand/collapse when one action sets isExpandTrigger (expanded is the
initial state; the adjacent FAB stays visible and does not toggle expansion).
Optional visibilityController / scrollBehavior enable scroll-exit or manual
show/hide. Set onActiveIndexChanged for toolbar-managed action selection
(labeled actions animate width). Use fabExpandIcon / fabCollapseIcon when a
FAB morphs with the pill. Set fabExpandsToolbar: false for a fixed small FAB
that only runs onFabPressed (pill stays open). Set pillActiveSpring: false
to keep a fixed pill width for labeled selection (widest label + icon-only
neighbors) while action labels still morph.
// Floating (default) — pill, wrap-content
M3EToolbar(
actions: <M3EToolbarItem>[
M3EToolbarAction(icon: M3EIcons.edit, onPressed: () {}),
M3EToolbarAction(icon: M3EIcons.share, onPressed: () {}),
],
);
// Floating + expand trigger + adjacent FAB
M3EToolbar(
expanded: true,
onExpandedChanged: (open) {},
actions: <M3EToolbarItem>[
M3EToolbarAction(
icon: M3EIcons.menu,
isExpandTrigger: true,
onPressed: () {},
),
M3EToolbarAction(icon: M3EIcons.edit, onPressed: () {}),
M3EToolbarAction(icon: M3EIcons.share, onPressed: () {}),
],
fabIcon: const Icon(M3EIcons.add),
fabExpandIcon: const Icon(M3EIcons.add),
fabCollapseIcon: const Icon(M3EIcons.close),
onFabPressed: () {},
);
// Small FAB — no pill expand/collapse (only onFabPressed)
M3EToolbar(
fabExpandsToolbar: false,
onFabPressed: () {},
fabExpandIcon: const Icon(M3EIcons.add),
actions: <M3EToolbarItem>[...],
);
// Action selection (internal active index when onActiveIndexChanged is set)
M3EToolbar(
onActiveIndexChanged: (i) {},
actions: <M3EToolbarItem>[
M3EToolbarAction(
icon: M3EIcons.edit,
label: 'Edit',
onPressed: () {},
),
M3EToolbarAction(icon: M3EIcons.share, onPressed: () {}),
],
);
// Labeled selection — fixed pill width (action labels still spring)
M3EToolbar(
pillActiveSpring: false,
onActiveIndexChanged: (i) {},
actions: <M3EToolbarItem>[...],
);
// Scroll-exit / manual visibility
final visibility = M3EToolbarVisibilityController();
M3EToolbarScrollWrapper(
behavior: M3EToolbarScrollBehavior.exitAlways(controller: visibility),
child: ListView(...),
);
M3EToolbar(
visibilityController: visibility,
actions: <M3EToolbarItem>[...],
);
// Mixed icon actions + custom widgets (widgets stay inline; height-capped)
M3EToolbar(
actions: <M3EToolbarItem>[
M3EToolbarAction(icon: M3EIcons.edit, onPressed: () {}),
M3EToolbarWidget(
child: M3ESplitButton<String>(
size: M3EButtonSize.sm,
label: 'Sort',
items: const [
M3ESplitButtonItem(value: 'name', child: 'Name'),
M3ESplitButtonItem(value: 'date', child: 'Date'),
],
onSelected: (_) {},
),
),
M3EToolbarAction(icon: M3EIcons.share, onPressed: () {}),
],
);
// Vertical floating
M3EToolbar(
axis: Axis.vertical,
colorStyle: M3EToolbarColorStyle.vibrant,
actions: <M3EToolbarItem>[...],
);
// Docked — full width; safeArea pads only the dock edge
M3EToolbar.docked(
dockEdge: M3EToolbarDockEdge.bottom,
safeArea: true,
titleText: 'Inbox',
actions: <M3EToolbarItem>[
M3EToolbarAction(icon: M3EIcons.search, onPressed: () {}),
M3EToolbarAction(
icon: M3EIcons.delete,
label: 'Delete',
isDestructive: true,
onPressed: () {},
),
],
);
M3EMenu
Anchored dropdown menu. Top-level M3EMenuGroups each render as an elevated
surface with a gap between them; dividers stay inside a surface. Opening the
menu focuses the popup without pre-highlighting the first item.
M3EMenu(
anchorBuilder: (context, open) => M3EButton.icon(
style: M3EButtonStyle.outlined,
icon: const Icon(M3EIcons.arrow_drop_down),
label: const Text('Open menu'),
onPressed: open,
),
children: [
M3EMenuGroup.entries(
entries: [
M3EMenuEntry(
label: 'Edit',
leading: const Icon(M3EIcons.edit),
onPressed: () {},
),
const M3EMenuEntry(label: 'Disabled', enabled: false),
],
),
M3EMenuGroup.entries(
label: 'More',
entries: [
M3EMenuEntry(
label: 'Copy',
trailingText: '⌘C',
onPressed: () {},
),
],
),
],
);
Feedback
See also:
example/lib/pages/playground/find/(Find tab)
M3EBadge
Notification dot or numeric badge on a child. alignment places the
indicator at topLeft, topCenter, or topRight of the child's own box
(default topRight). The badge sizes itself to cover the child plus
indicator — no parent SizedBox is required. offset nudges away from the
anchored edge (dx is ignored when centered).
const M3EBadge(
showDot: true,
child: Icon(M3EIcons.menu, size: 28),
);
const M3EBadge(
count: 8,
alignment: M3EBadgeAlignment.topLeft,
child: Icon(M3EIcons.calendar_today, size: 28),
);
M3EProgressIndicator
Material 3 Expressive progress indicators with circular and linear variants,
including Compose-style wavy forms. Null value runs indeterminate animation
(classic linear: dual traveling segments with gaps; wavy linear/circular: m3e
style travel / spin+sweep; classic circular: same rot/sweep timing as wavy,
flat arcs with gaps).
// Classic
const M3EProgressIndicator.circular();
M3EProgressIndicator.circular(value: 0.6);
const M3EProgressIndicator.linear();
SizedBox(
width: 200,
child: M3EProgressIndicator.linear(value: 0.6),
);
// Expressive wavy (Compose CircularWavy / LinearWavy)
const M3EProgressIndicator.circularWavy();
M3EProgressIndicator.circularWavy(value: 0.6);
SizedBox(
width: 200,
child: M3EProgressIndicator.linearWavy(),
);
SizedBox(
width: 200,
child: M3EProgressIndicator.linearWavy(value: 0.6),
);
M3ELoadingIndicator
Expressive loading spinner. Shape morph settle uses
M3EMotion.expressiveSpatialDefault.
const M3ELoadingIndicator();
const M3ELoadingIndicator(
variant: M3ELoadingIndicatorVariant.contained,
);
M3ERefreshIndicator
Pull-to-refresh wrapper for scrollables.
M3ERefreshIndicator(
onRefresh: () async {
await Future<void>.delayed(const Duration(seconds: 2));
},
child: ListView.builder(
itemCount: 12,
itemBuilder: (context, index) => Text('Item ${index + 1}'),
),
);
// Contained variant
M3ERefreshIndicator.contained(
onRefresh: () async {},
child: listView,
);
M3ETooltip
Descriptive label on hover or long-press.
M3ETooltip(
message: 'Compose a new message',
child: M3EIconButton(
icon: const Icon(M3EIcons.edit),
onPressed: () {},
),
);
M3ESnackbar
Brief feedback message — use .show (hosts via internal M3ESnackbarHost).
M3ESnackbar.show(
context,
message: 'Draft saved',
actionLabel: 'Undo',
onAction: () {},
);
M3ETextField
Filled and outlined text input with floating label. The focused stroke is
painted over the field so width/height stay stable. Height grows with
maxLines. An empty label sits vertically centered; with no label, the
value is centered. inputFormatters are forwarded to the inner
EditableText. M3ETextFieldVariant and M3ETextFieldTheme are public.
M3ETextField(
controller: nameController,
label: 'Full name',
supportingText: 'As it appears on your ID',
leading: const Icon(M3EIcons.edit),
);
const M3ETextField(
label: 'Email',
variant: M3ETextFieldVariant.outlined,
errorText: 'Enter a valid email address',
);
M3ESearchBar / M3ESearchAnchor
Inline search field, or a bar that opens a full search view with suggestions.
When embedded in toolbars or app bars, expandOnFocus / expandRestPadding
control the horizontal inset spring on focus. Use alignment /
barAlignment to place leading + hint + trailing while empty and unfocused
(defaults to start; M3EAppBar.search defaults to Alignment.center).
// Inline bar
M3ESearchBar(
controller: searchController,
hintText: 'Search components',
trailing: [
M3EIconButton(
icon: const Icon(M3EIcons.close),
onPressed: searchController.clear,
),
],
);
// Anchor + search view
final controller = M3ESearchController();
M3ESearchAnchor.bar(
searchController: controller,
barHintText: 'Search',
suggestionsBuilder: (context, controller) sync* {
for (final name in names.where((n) => n.contains(controller.text))) {
yield ListTile(
title: Text(name),
onTap: () => controller.closeView(name),
);
}
},
);
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, M3EDialog.showFullScreen |
M3EBottomSheet |
M3EBottomSheet.show |
M3ESideSheet |
M3ESideSheet.show |
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 (platform default, Roboto Flex, Roboto Mono) plus M3 Expressive type styles on Flex. - Pages: playgrounds under
example/lib/pages/playground/, grouped by tab (do/,pick/,view/,nav/,find/). - 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
Optional custom lint rules (if klin_dart is enabled in your environment):
dart run custom_lint
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, toggle 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/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/m3e_bottom_sheets
- components/bottom_sheets/styles/m3e_bottom_sheet_theme
- components/buttons/components/m3e_focus_ring
- 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/enums/m3e_card_variant
- components/cards/m3e_cards
- components/cards/styles/m3e_card_theme
- 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/styles/m3e_carousel_theme
- 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_dialog_content
- 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/m3e_dialogs
- components/dialogs/styles/m3e_dialog_theme
- components/divider/enums/m3e_divider_axis
- 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/m3e_extended_fabs
- 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_builders
- components/lists/components/m3e_expandable_data
- components/lists/components/m3e_expandable_item
- components/lists/components/m3e_expandable_list_base
- components/lists/components/m3e_list_item_scope
- components/lists/controllers/m3e_dismissible_card_controller
- components/lists/enums/m3e_expandable_enums
- components/lists/enums/m3e_list_enums
- components/lists/m3e_lists
- components/lists/models/m3e_dismissible_slot
- components/lists/styles/m3e_dismissible_list_style
- components/lists/styles/m3e_expandable_style
- components/lists/styles/m3e_list_theme
- components/lists/utils/m3e_expandable_spring_motion
- 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/enums/m3e_refresh_status
- components/refresh_indicator/m3e_refresh_indicator
- components/refresh_indicator/styles/m3e_refresh_indicator_theme
- components/search/components/m3e_search_view
- components/search/controllers/m3e_search_controller
- components/search/m3e_search
- components/search/m3e_search_anchor
- components/search/m3e_search_bar
- components/search/res/m3e_search_constants
- components/search/styles/m3e_search_bar_theme
- components/search/styles/m3e_search_view_theme
- 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_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/m3e_side_sheets
- components/side_sheets/styles/m3e_side_sheet_theme
- 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/m3e_snackbar
- components/snackbar/styles/m3e_snackbar_theme
- components/switch_control/m3e_switch_control
- components/switch_control/styles/m3e_switch_theme
- components/tabs/enums/m3e_tabs_variant
- components/tabs/m3e_tabs
- components/tabs/models/m3e_tab
- components/tabs/styles/m3e_tab_theme
- components/text_fields/enums/m3e_text_field_variant
- components/text_fields/m3e_text_fields
- components/text_fields/styles/m3e_text_field_theme
- components/time_pickers/components/m3e_dial_time_picker
- 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/m3e_tooltips
- components/tooltips/styles/m3e_tooltip_theme
- foundations/components/m3e_component_theme
- foundations/foundations
- Design tokens, theming hosts, and shared interaction primitives for Material 3 Expressive components.
- foundations/m3e_color_scheme
- foundations/m3e_color_utils
- foundations/m3e_dimensions
- foundations/m3e_dynamic_color_host
- foundations/m3e_elevation
- foundations/m3e_focus
- foundations/m3e_haptics
- foundations/m3e_icons
- foundations/m3e_ink_splash_theme
- foundations/m3e_material_app
- foundations/m3e_material_new_shapes_bridge
- foundations/m3e_motion
- foundations/m3e_resolved_theme
- foundations/m3e_scrim_system_ui
- foundations/m3e_shape_clipper
- foundations/m3e_shape_container
- foundations/m3e_shape_kind
- foundations/m3e_shapes
- foundations/m3e_spacing
- foundations/m3e_state_layer
- foundations/m3e_state_layer_overlay
- foundations/m3e_tappable
- foundations/m3e_tappable_ink_scope
- foundations/m3e_theme
- foundations/m3e_theme_controller
- foundations/m3e_theme_data
- foundations/m3e_theme_defaults
- foundations/m3e_theme_extension
- foundations/m3e_theme_scope
- foundations/m3e_typography
- material_3_expressive
- Material 3 Expressive: a faithful Flutter implementation of the Material 3
component set, exposed as direct
M3E*component widgets.




