Skip to main content

Custom Theme

You can create a fully custom theme by constructing SsoResolvedTheme directly.

Example

final myTheme = SsoResolvedTheme(
isDark: true,
fontFamily: 'Roboto',

// Shape tokens — override any of these to reshape controls
radiusButton: 12.0, // default 8.0
radiusInput: 12.0, // default 8.0
radiusBlock: 24.0, // default 24.0
radiusButtonIcon: 1000.0, // default 1000.0 (pill)
radiusBottomSheet: 16.0, // default 8.0

text: SsoTextColors(
primary: Color(0xFFFFFFFF),
secondary: Color(0xFFB0B0B0),
tertiary: Color(0xFF808080),
disabled: Color(0xFF555555),
onGradient: Color(0xFFFFFFFF),
onSnackbarHint: Color(0xFFCCCCCC),
highlight: Color(0xFFFFD700),
inverse: SsoInverseTextColors(
primary: Color(0xFF000000),
secondary: Color(0xFF333333),
tertiary: Color(0xFF666666),
),
),

brand: SsoBrandColors(
primary: Color(0xFF6C5CE7),
onPrimary: Color(0xFFFFFFFF),
inverse: SsoInverseBrandColors(
primary: Color(0xFF6C5CE7),
onPrimary: Color(0xFFFFFFFF),
),
),

surface: SsoSurfaceColors(
primary: Color(0xFF1E1E2E),
secondary: Color(0xFF2A2A3E),
tertiary: Color(0xFF333350),
),

background: SsoBackgroundColors(
primary: Color(0xFF121220),
secondary: Color(0xFF1A1A2E),
),

// ... configure all other required groups
// See SsoResolvedTheme constructor for the full list
);

Shape tokens

In addition to colors, SsoResolvedTheme accepts five radius tokens that control the corner rounding of SDK widgets. All are optional and have sensible defaults:

TokenDefaultApplied to
radiusButton8.0Primary / secondary buttons, provider buttons
radiusInput8.0Text inputs, dropdowns
radiusBlock24.0Cards, info blocks
radiusButtonIcon1000.0Round icon buttons (keep large for pill shape)
radiusBottomSheet8.0Auth bottom sheet top corners

Each built-in theme uses its own radius values (see theme.md), so when you start from scratch you are only constrained by the defaults above.

Using a custom theme

At initialization (global default)

await SsoSdk.initialize(SsoConfig(
baseUrl: '...',
origin: SsoOrigin.heroDev,
appName: 'MyApp',
theme: myTheme,
));

Per auth screen (override)

SsoSdk.authScreen(
enabledProviders: [...],
theme: myTheme,
);

Extending a built-in theme

The simplest approach is to start from a built-in theme and modify specific tokens using copyWith-style construction:

final baseTheme = SsoResolvedTheme.heroDark();

// Create a new theme, overriding only the brand color and the button radius
final myTheme = SsoResolvedTheme(
// Copy all groups from the base theme
text: baseTheme.text,
surface: baseTheme.surface,
background: baseTheme.background,
border: baseTheme.border,
interactive: baseTheme.interactive,
alerts: baseTheme.alerts,
accent: baseTheme.accent,
disabled: baseTheme.disabled,
elevation: baseTheme.elevation,
tag: baseTheme.tag,
gradient: baseTheme.gradient,
graphs: baseTheme.graphs,
skeleton: baseTheme.skeleton,
native: baseTheme.native,
skrim: baseTheme.skrim,
links: baseTheme.links,
logo: baseTheme.logo,
temporaryChat: baseTheme.temporaryChat,
gradients: baseTheme.gradients,
shadow: baseTheme.shadow,
isDark: baseTheme.isDark,
fontFamily: baseTheme.fontFamily,

// Carry over the base theme's shape tokens — otherwise they fall back
// to the constructor defaults (8 / 8 / 24 / 1000 / 8) and you'd lose
// the pill buttons from the Hero theme.
radiusButton: baseTheme.radiusButton,
radiusInput: baseTheme.radiusInput,
radiusBlock: baseTheme.radiusBlock,
radiusButtonIcon: baseTheme.radiusButtonIcon,
radiusBottomSheet: baseTheme.radiusBottomSheet,

// Override only the brand
brand: SsoBrandColors(
primary: Color(0xFFFF6B6B),
onPrimary: Color(0xFFFFFFFF),
inverse: SsoInverseBrandColors(
primary: Color(0xFFFF6B6B),
onPrimary: Color(0xFFFFFFFF),
),
),
);

Tip: if you want square buttons on top of Hero colors, override just radiusButton: 8.0 (and keep the rest copied from baseTheme).

Accessing theme in widgets

Inside any SDK widget, the current theme is available via:

final theme = SsoThemeProvider.of(context);
// theme.brand.primary, theme.text.secondary, etc.