appSwitchStateColors function

({Color? border, Color? container, Color indicator}) appSwitchStateColors(
  1. AppColorTheme theme, {
  2. required bool selected,
  3. required bool disabled,
  4. required bool isDark,
})

Cores do AppSwitch por estado (função pura, testável — ver test/src/theme/component_state_contrast_test.dart).

  • indicator: o thumb (knob) — a marca que corre no trilho;
  • container: o trilho (track); null no desligado (fill semântico ausente) para o switch participar do eixo AppStyle como check/radio — o resolver escolhe surfaceContainer (filled/elevated) ou deixa vazado (outlined);
  • border: cor do contorno do outlined (ligado = acento primário, desligado = outline), consumida por resolveStyleDecoration.

Ligado o trilho usa o acento primário resolvido por brilho (AppColorTheme.primaryAccent: base no claro, s400 no escuro — o primary cru é escuro demais no escuro e o trilho sumia), com o thumb em surfaceContainer (furo que revela a superfície por baixo do trilho, contrastando com o acento). Desligado o thumb usa outline (não mais branco): como o trilho deixou de ser um cinza sólido, o thumb precisa de uma cor que contraste ≥3:1 com a superfície do trilho nos dois temas.

Desabilitado usa AppColorTheme.disabledColor (apagado por tom, não por opacidade). Ver doc/COLOR_ACCESSIBILITY_RULES.md §7.

Implementation

({Color indicator, Color? container, Color? border}) appSwitchStateColors(
  AppColorTheme theme, {
  required bool selected,
  required bool disabled,
  required bool isDark,
}) {
  // Acento primário resolvido por brilho (base no claro, `s400` no escuro): o
  // `primary` cru é escuro demais como trilho sobre a superfície escura e o
  // switch ligado sumia. O thumb usa `surfaceContainer` — "vaza" a superfície
  // elevada por baixo do trilho (efeito de furo), contrastando com o acento nos
  // dois temas (acento e superfície ficam em pontas opostas).
  final Color accent = theme.primaryAccent(isDark: isDark);
  if (disabled) {
    if (selected) {
      final Color track = theme.disabledColor(accent);
      return (
        indicator: disabledIndicatorOn(track),
        container: track,
        border: track,
      );
    }
    // Desligado desabilitado: trilho ghost (fill nulo → `surfaceContainer` no
    // `filled`); thumb e borda num neutro apagado por tom.
    final Color muted = theme.disabledColor(theme.outline);
    return (indicator: muted, container: null, border: muted);
  }
  if (selected) {
    return (
      indicator: theme.surfaceContainer,
      container: accent,
      border: accent,
    );
  }
  // Desligado: fill semântico NULO (participa do eixo de style). O thumb usa
  // `outline` p/ contrastar com a superfície do trilho (`surfaceContainer` no
  // `filled`, a própria `surface` no `outlined` vazado).
  return (indicator: theme.outline, container: null, border: theme.outline);
}