Skip to content

Theme, Colors & Motion

This chapter covers flutter_miuix's theming infrastructure: MiuixTheme/MiuixSystemTheme provide static theming, while MiuixThemeController offers full Monet dynamic color. MiuixColors defines 50+ HyperOS semantic roles, MiuixTextStyles defines 14 preset type styles, and MiuixMotion plus folmeSpring deliver the original library's springs and easing curves.

MiuixThemeData

Immutable Miuix theme data aggregating MiuixColors, MiuixTextStyles and Brightness.

Field / MethodTypeDescription
colorsMiuixColorsColor scheme
textStylesMiuixTextStylesText style set
brightnessBrightnessCurrent brightness mode
MiuixThemeData.light({colors, textStyles})factoryLight theme; defaults to lightColorScheme + defaultTextStyles
MiuixThemeData.dark({colors, textStyles})factoryDark theme; defaults to darkColorScheme + defaultTextStyles
MiuixThemeData.of(brightness, {lightColors, darkColors, textStyles})factoryAuto-selects light/dark by system brightness
copyWith({colors, textStyles, brightness})MiuixThemeDataCopies and overrides selected fields

Example:

dart
final data = MiuixThemeData.light(
  colors: lightColorScheme().copy(primary: Color(0xFFFF6B35)),
);

MiuixTheme

An InheritedWidget that provides MiuixThemeData to a subtree.

Parameter / MethodTypeDefaultDescription
dataMiuixThemeDatarequiredTheme data
childWidgetrequiredSubtree
MiuixTheme.of(context)MiuixThemeDataReturns current theme; falls back to MiuixThemeData.light() if not wrapped
MiuixTheme.maybeOf(context)MiuixThemeData?Reads without establishing a dependency; returns null if not wrapped

Example:

dart
MiuixTheme(
  data: MiuixThemeData.light(),
  child: MyApp(),
)

MiuixSystemTheme

A convenience widget that applies light/dark theme automatically based on MediaQuery.platformBrightnessOf.

ParameterTypeDefaultDescription
lightMiuixColors?null (= lightColorScheme)Custom light colors
darkMiuixColors?null (= darkColorScheme)Custom dark colors
textStylesMiuixTextStyles?null (= defaultTextStyles)Custom text styles
childWidgetrequiredSubtree

Example:

dart
MiuixSystemTheme(
  child: Builder(builder: (context) {
    final theme = MiuixTheme.of(context);
    return MaterialApp(
      theme: ThemeData(brightness: theme.brightness),
      home: const HomePage(),
    );
  }),
)

MiuixColorSchemeMode

Color scheme mode enum.

ValueDescription
systemFollows system brightness, uses static light/dark colors
lightForces light
darkForces dark
monetSystemFollows system brightness + Monet dynamic color
monetLightLight + Monet dynamic color
monetDarkDark + Monet dynamic color

monet* modes: when keyColor is non-null, colors are generated synchronously from the seed (pure HCT computation); when keyColor is null, the platform wallpaper is read (Android), and a fixed seed 0xFF6750A4 is used on other platforms.

MiuixThemeController

Full theme controller that resolves colors by MiuixColorSchemeMode and provides MiuixTheme to the subtree.

ParameterTypeDefaultDescription
colorSchemeModeMiuixColorSchemeModesystemColor scheme mode
lightColorsMiuixColors?null (= lightColorScheme)Static light colors
darkColorsMiuixColors?null (= darkColorScheme)Static dark colors
textStylesMiuixTextStyles?null (= defaultTextStyles)Text styles
keyColorColor?nullMonet seed color; null reads platform wallpaper
colorSpecMiuixThemeColorSpecspec2021Color spec version
paletteStyleMiuixThemePaletteStyletonalSpotMonet palette style
isDarkbool?nullForce dark; null follows the system
childWidgetrequiredSubtree

Monet resolution flow:

  1. keyColor non-null → synchronously calls miuixColorsFromSeed (pure HCT, no platform channel).
  2. keyColor null → asynchronously calls miuixPlatformDynamicColors (Android wallpaper; other platforms fall back to the fixed seed). Until the result is ready, miuixMonetSystemColors is used as a placeholder to avoid flicker.

Example:

dart
MiuixThemeController(
  colorSchemeMode: MiuixColorSchemeMode.monetSystem,
  keyColor: const Color(0xFF6750A4),
  child: MyApp(),
)

MiuixColors

Miuix color scheme. All fields are non-nullable and can be partially overridden via copy; light/dark defaults are provided by lightColorScheme / darkColorScheme, matching the HyperOS specification.

Primary semantic roles

FieldDescription
primary / onPrimaryPrimary color / text-on-primary (Switch, Button, Slider)
primaryVariant / onPrimaryVariantPrimary variant (Card)
primaryContainer / onPrimaryContainerPrimary container
secondary / onSecondarySecondary color / text-on-secondary
secondaryVariant / onSecondaryVariantSecondary variant
secondaryContainer / onSecondaryContainerSecondary container
secondaryContainerVariant / onSecondaryContainerVariantSecondary container variant
tertiaryContainer / onTertiaryContainer / tertiaryContainerVariantTertiary container
error / onErrorError color / text-on-error
errorContainer / onErrorContainerError container
background / onBackground / onBackgroundVariantApp background / text / variant text
surface / onSurface / surfaceVariantSurface / text-on-surface / variant
onSurfaceSecondarySecondary text on surface (80% alpha)
onSurfaceVariantSummary / onSurfaceVariantActionsSummary / action text on surface variant
surfaceContainer / onSurfaceContainer / onSurfaceContainerVariantSurface container / text / variant text
surfaceContainerHigh / onSurfaceContainerHighHigh surface container
surfaceContainerHighest / onSurfaceContainerHighestHighest surface container
outlineOutline / border
dividerLineDivider line
windowDimmingWindow dim color (Dialog / Dropdown / Spinner / BottomSheet)
sliderKeyPoint / sliderKeyPointForeground / sliderBackgroundSlider key point / foreground / background

Disabled-state colors

FieldDescription
disabledPrimary / disabledOnPrimarySwitch disabled primary / text
disabledPrimaryButton / disabledOnPrimaryButtonButton disabled primary / text
disabledPrimarySliderSlider disabled primary
disabledSecondary / disabledOnSecondaryDisabled secondary / text
disabledSecondaryVariant / disabledOnSecondaryVariantDisabled secondary variant / text
disabledOnSurfaceDisabled text on surface

Default color factories

FunctionReturnsDescription
lightColorScheme()MiuixColorsDefault light (primary=0xFF3482FF, background=white)
darkColorScheme()MiuixColorsDefault dark (primary=0xFF277AF7, background=0xFF242424)

MiuixColors.copy(...)

Copies and overrides selected colors; every parameter is nullable and falls back to the original value. Returns a new MiuixColors instance.

Example:

dart
final colors = lightColorScheme().copy(
  primary: const Color(0xFFFF6B35),
  background: const Color(0xFFFFFBF8),
);

MiuixTextStyles

Miuix text style set. Only font size / weight / line height are stored; the runtime color comes from MiuixTheme's onBackground.

FieldSizeHeight/WeightUsage
main17Main text
paragraph171.2emParagraph
body116Body 1
body214Body 2
button17Button
footnote113Footnote 1
footnote211Footnote 2
headline117Headline 1
headline216Headline 2
subtitle14boldSubtitle
title132Title 1
title224Title 2
title320Title 3
title418Title 4

MiuixTextStyles.copy({...})

Copies and overrides selected fields, returning a new instance.

defaultTextStyles()

Returns the default style set matching the Miuix specification (all values in the table above). Can be replaced by passing it to the textStyles parameter of MiuixThemeData / MiuixSystemTheme / MiuixThemeController.

Monet dynamic color

MiuixThemeColorSpec

Material color spec version. The current material_color_utilities 0.13.0 only implements SPEC_2021; spec2025 is semantically equivalent to requesting 2025 on supported palettes but actually generates via 2021 (matching the original library's "fall back when unsupported" path).

ValueDescription
spec2021Material You 2021 color spec
spec2025Material You 2025 spec (currently equivalent to spec2021)

MiuixThemePaletteStyle

Monet dynamic color palette style.

ValueDynamicScheme
tonalSpotSchemeTonalSpot (default)
neutralSchemeNeutral
vibrantSchemeVibrant
expressiveSchemeExpressive
rainbowSchemeRainbow
fruitSaladSchemeFruitSalad
monochromeSchemeMonochrome
fidelitySchemeFidelity
contentSchemeContent

miuixColorsFromSeed({seed, colorSpec, paletteStyle, dark})

Generates a full Miuix color set from a seed color.

ParameterTypeDefaultDescription
seedColorrequiredSeed color
colorSpecMiuixThemeColorSpecspec2021Color spec
paletteStyleMiuixThemePaletteStyletonalSpotPalette style
darkboolrequiredWhether dark

Returns MiuixColors. Flow: select the DynamicScheme by paletteStyle → extract 27 MD3 roles via MaterialDynamicColors → map to Miuix colors via mapMd3RolesToMiuixColors (alpha-bearing colors are composited onto their backgrounds to ensure fully opaque results).

miuixMonetSystemColors({dark})

Default Monet colors: fixed seed 0xFF6750A4 + TonalSpot + Spec2021. Also the platformDynamicColors fallback on non-Android platforms.

miuixPlatformDynamicColors({dark})Future<MiuixColors>

Platform dynamic color.

  • Android (and supported platforms): reads the system wallpaper/theme seed via DynamicColorPlugin.getAccentColor; if non-null, generates via miuixColorsFromSeed (TonalSpot + Spec2021).
  • Other platforms or read failures: falls back to miuixMonetSystemColors (fixed seed).

The platform channel is asynchronous, so this function returns a Future. The UI layer (MiuixThemeController) uses miuixMonetSystemColors as a placeholder until the result is ready.

MiuixMonetRoles

A set of MD3 (Monet) dynamic color roles (27 fields). Filled by miuixColorsFromSeed from a DynamicScheme, then passed to mapMd3RolesToMiuixColors to convert to MiuixColors.

Main roles: primary, onPrimary, primaryFixed, onPrimaryFixed, error, onError, errorContainer, onErrorContainer, primaryContainer, onPrimaryContainer, secondary, onSecondary, secondaryContainer, onSecondaryContainer, tertiaryContainer, onTertiaryContainer, background, onBackground, surface, onSurface, surfaceVariant, surfaceContainer, surfaceContainerHigh, surfaceContainerHighest, outline, outlineVariant, onSurfaceVariant.

mapMd3RolesToMiuixColors(roles, {dark})

Maps MD3 (Monet) roles to Miuix MiuixColors. Replicates the original field-by-field mapping; alpha-bearing disabled/slider/onSurfaceSecondary colors are composited onto their backgrounds via ensureOpaqueOver to ensure fully opaque results.

MiuixMotion

A collection of commonly used Miuix motion curves and springs, grouped by HyperOS interaction conventions.

Field / MethodTypeDescription
standardDecelerateCurveStandard decelerate, for enter/appear (DecelerateEasing(1.0))
standardAccelerateCurveStandard accelerate, for exit/disappear (AccelerateEasing(1.0))
sinOutCurveSine ease-out, for soft translation/scale (SinOutEasing)
pressSpringSpringDescriptionGeneral press/state toggle (critically damped, response=0.35s)
bouncySpringSpringDescriptionBouncy toggle (slightly under-damped 0.85, response=0.45s, natural rebound)

folmeSpring({damping, response})SpringDescription

Constructs a SpringDescription from damping ratio damping and response time response (seconds): stiffness = (2π/response)².

ParameterTypeDescription
dampingdoubleDamping ratio; 1.0=critical, <1 under-damped (rebound), >1 over-damped
responsedoubleResponse time (seconds); smaller is faster

AccelerateEasing

Accelerate curve. With factor=1, y=x²; larger factor exaggerates ease-in.

dart
const curve = AccelerateEasing(1.0);

DecelerateEasing

Decelerate curve. With factor=1, 1-(1-x)²; larger factor exaggerates ease-out.

SinOutEasing

Sine ease-out curve: sin(t·π/2).

Full motion example:

dart
AnimationController(vsync: this)
  ..animateWith(
    SpringSimulation(
      folmeSpring(damping: 0.85, response: 0.45),
      0.0, 1.0, 0.0,
    ),
  );

// Or use presets
AnimationController(vsync: this)
  ..animateTo(1.0, curve: MiuixMotion.standardDecelerate);

Released under the Apache-2.0 License.