seededColorScheme function

ColorScheme seededColorScheme({
  1. required Color seedColor,
  2. required Brightness brightness,
  3. ColorStyle style = ColorStyle.vivid,
})

.agents/surfaces.md explains why each role this replaces leaves Material's value.

Implementation

ColorScheme seededColorScheme({
  required Color seedColor,
  required Brightness brightness,
  ColorStyle style = ColorStyle.vivid,
}) {
  final dark = brightness == Brightness.dark;
  final source = Hct.fromInt(seedColor.toARGB32());
  final scheme = _dynamicScheme(source, dark, style);
  final primary = scheme.primaryPalette;
  final container = TonalPalette.of(
    primary.hue,
    min(primary.chroma, _primaryContainerChroma),
  );
  final tint = style == ColorStyle.tinted
      ? min(source.chroma / _tintDivisor, _maxTintChroma)
      : null;
  Color neutral(DynamicColor role, double maxChroma, [double? darkTone]) {
    final palette = role.palette(scheme);
    return Color(
      Hct.from(
        palette.hue,
        tint ?? min(palette.chroma, maxChroma),
        (dark ? darkTone : null) ?? role.getTone(scheme),
      ).toInt(),
    );
  }

  Color role(DynamicColor color) => Color(color.getArgb(scheme));

  final paperChroma = dark ? _surfaceChroma : _paperChroma;
  final accent = switch (style) {
    ColorStyle.vivid || ColorStyle.tinted => _accent(seedColor, source, dark),
    ColorStyle.soft || ColorStyle.monochrome => null,
  };
  final primaryColor = accent?.primary ?? role(MaterialDynamicColors.primary);
  return ColorScheme(
    brightness: brightness,
    primary: primaryColor,
    onPrimary: accent?.onPrimary ?? role(MaterialDynamicColors.onPrimary),
    surfaceTint: primaryColor,
    primaryContainer: Color(container.get(dark ? 30 : 90)),
    onPrimaryContainer: Color(container.get(dark ? 90 : 30)),
    primaryFixed: role(MaterialDynamicColors.primaryFixed),
    primaryFixedDim: role(MaterialDynamicColors.primaryFixedDim),
    onPrimaryFixed: role(MaterialDynamicColors.onPrimaryFixed),
    onPrimaryFixedVariant: role(MaterialDynamicColors.onPrimaryFixedVariant),
    secondary: role(MaterialDynamicColors.secondary),
    onSecondary: role(MaterialDynamicColors.onSecondary),
    secondaryContainer: role(MaterialDynamicColors.secondaryContainer),
    onSecondaryContainer: role(MaterialDynamicColors.onSecondaryContainer),
    secondaryFixed: role(MaterialDynamicColors.secondaryFixed),
    secondaryFixedDim: role(MaterialDynamicColors.secondaryFixedDim),
    onSecondaryFixed: role(MaterialDynamicColors.onSecondaryFixed),
    onSecondaryFixedVariant: role(
      MaterialDynamicColors.onSecondaryFixedVariant,
    ),
    tertiary: role(MaterialDynamicColors.tertiary),
    onTertiary: role(MaterialDynamicColors.onTertiary),
    tertiaryContainer: role(MaterialDynamicColors.tertiaryContainer),
    onTertiaryContainer: role(MaterialDynamicColors.onTertiaryContainer),
    tertiaryFixed: role(MaterialDynamicColors.tertiaryFixed),
    tertiaryFixedDim: role(MaterialDynamicColors.tertiaryFixedDim),
    onTertiaryFixed: role(MaterialDynamicColors.onTertiaryFixed),
    onTertiaryFixedVariant: role(MaterialDynamicColors.onTertiaryFixedVariant),
    error: role(MaterialDynamicColors.error),
    onError: role(MaterialDynamicColors.onError),
    errorContainer: role(MaterialDynamicColors.errorContainer),
    onErrorContainer: role(MaterialDynamicColors.onErrorContainer),
    outline: role(MaterialDynamicColors.outline),
    onSurface: dark
        ? Color(
            MaterialDynamicColors.onSurface
                .palette(scheme)
                .get(_darkOnSurfaceTone),
          )
        : role(MaterialDynamicColors.onSurface),
    onSurfaceVariant: role(MaterialDynamicColors.onSurfaceVariant),
    inverseSurface: role(MaterialDynamicColors.inverseSurface),
    onInverseSurface: role(MaterialDynamicColors.inverseOnSurface),
    inversePrimary: role(MaterialDynamicColors.inversePrimary),
    shadow: role(MaterialDynamicColors.shadow),
    scrim: role(MaterialDynamicColors.scrim),
    surface: neutral(MaterialDynamicColors.surface, paperChroma),
    surfaceBright: neutral(MaterialDynamicColors.surfaceBright, paperChroma),
    surfaceDim: neutral(MaterialDynamicColors.surfaceDim, _surfaceChroma),
    surfaceContainerLowest: neutral(
      MaterialDynamicColors.surfaceContainerLowest,
      _surfaceChroma,
    ),
    surfaceContainerLow: neutral(
      MaterialDynamicColors.surfaceContainerLow,
      _surfaceChroma,
    ),
    surfaceContainer: neutral(
      MaterialDynamicColors.surfaceContainer,
      _surfaceChroma,
      _darkCardTone,
    ),
    surfaceContainerHigh: neutral(
      MaterialDynamicColors.surfaceContainerHigh,
      _surfaceChroma,
      _darkBlockTone,
    ),
    surfaceContainerHighest: neutral(
      MaterialDynamicColors.surfaceContainerHighest,
      _surfaceChroma,
      _darkInsetTone,
    ),
    outlineVariant: neutral(MaterialDynamicColors.outlineVariant, 4),
  );
}