Skip to content

Theming

CDX UI is themed through a single ThemeExtensionCdxConfig — and a factory function — createCdxTheme — that produces a ThemeData with every Material component theme pre-wired. Apps customize tokens once; every CDX widget picks them up automatically.

Live Example

Open the full route: Theming.

CdxConfig

CdxConfig is registered as a ThemeData.extensions entry. Resolve it anywhere via:

dart
final cdx = CdxConfig.of(context);          // never null — falls back to defaults
final maybeCdx = CdxConfig.maybeOf(context); // null if not registered

Shape tokens

TokenTypeDefaultUsed by
controlBorderRadiusBorderRadius4Badges, chips, dropdown frames, dialog actions
containerBorderRadiusBorderRadius8Cards, dialogs, panels, banners
controlPaddingdouble4Badge padding, chip padding (multiplied)
containerPaddingdouble16SectionCard, banner, locked surface
controlHeightdouble36Button, SplitActionButton, CdxSegmentedTabs, dropdown triggers
horizontalGapdouble16Dialog footer actions, toolbars, header action rows
verticalGapdouble16Form groups, settings rows, stacked section rhythm
compactControlSizedouble32Button.icon(compact: true), CdxChip(size: compact)
iconSizedouble16In-control icons across buttons, menus, segmented tabs, triggers
headerHeightdouble70Entity / panel / dialog header bands

Color tokens

Every color is nullablenull means "use the Material ColorScheme fallback". Resolvers are colocated with the field so call sites read from one place.

ResolverFalls back to
primaryOf(scheme)scheme.primary
errorOf(scheme)scheme.error
surfaceOf(scheme)scheme.surface
borderOf(scheme)scheme.outline
disabledOf(scheme)scheme.onSurface @ 38%
disabledButtonFillOf(scheme)scheme.onSurface @ 12% (M3 spec)
disabledButtonTextOf(scheme)scheme.onSurface @ 38% (M3 spec)
hoverTintOf(scheme)primary @ 8%
selectedTintOf(scheme)primary @ 16%

Status palette (Material does NOT ship this)

CdxConfig adds three brightness-aware palettes Material 3 lacks: success, warning, neutral. critical and info resolve through error and primary respectively (same canonical hex). All container/on-container pairs target ≥7:1 contrast (AAA).

dart
final cdx = CdxConfig.of(context);
final scheme = Theme.of(context).colorScheme;

cdx.successOf(scheme);          // Green-700 light / Emerald-400 dark
cdx.successContainerOf(scheme); // Green-100 light / Emerald-900 dark
cdx.warningOf(scheme);          // Amber-500 light / Amber-400 dark
cdx.criticalOf(scheme);         // == errorOf
cdx.infoOf(scheme);             // == primaryOf
cdx.neutralOf(scheme);          // Slate-600 light / Slate-400 dark

Used by Banner, StatusBadge, ActivityTimeline (ActivityOutcome), the workflow timeline, and any widget that needs status semantics.

Custom theme

dart
final theme = ThemeData.from(colorScheme: ColorScheme.fromSeed(...))
    .copyWith(extensions: [
  CdxConfig(
    controlHeight: 36,                          // tighter buttons
    selectedTint: Colors.indigo.withValues(alpha: 0.18),
    warning: const Color(0xffd97706),            // brand-tuned amber
  ),
]);

Or wire everything at once with createCdxTheme.

createCdxTheme

createCdxTheme returns a ThemeData with every Material component theme pre-wired (buttons, dialog, card, snackbar, picker, chip, slider, divider, navigation rail, tab bar, etc.) plus the CdxConfig extension. Brands typically call it once per brightness:

dart
final lightTheme = createCdxTheme(
  colorScheme: brand.lightScheme,
  textTheme: brand.textTheme,
);

final darkTheme = createCdxTheme(
  colorScheme: brand.darkScheme,
  textTheme: brand.textTheme,
);

// Tune sizing if needed:
final dense = createCdxTheme(
  colorScheme: brand.lightScheme,
  textTheme: brand.textTheme,
  config: const CdxConfig(controlHeight: 36, compactControlSize: 28),
);

The component themes pulled in by createCdxTheme cover:

  • Buttons (elevated, filled, outlined, text, icon, floating, menu)
  • Inputs (inputDecorationTheme, dropdownMenuTheme, searchBarTheme, searchViewTheme)
  • Containers (cardTheme, dialogTheme, appBarTheme, navigationBarTheme, navigationRailTheme, tabBarTheme)
  • Form controls (switchTheme, checkboxTheme, radioTheme, sliderTheme, chipTheme)
  • Data (dataTableTheme, segmentedButtonTheme, listTileTheme)
  • Pickers (datePickerTheme, timePickerTheme)
  • Menus & overlays (popupMenuTheme, menuTheme, tooltipTheme, snackBarTheme)
  • Misc (dividerTheme, progressIndicatorTheme)
  • Density & SizingcontrolHeight, compactControlSize, headerHeight
  • OverlayshoverTint, selectedTint, CdxStateLayer
  • Buttons — read controlHeight and controlBorderRadius
  • BadgesStatusBadge reads the status palette