Theme

Presets, brand colors, radius and font scale — all from one config.

Try it

These controls restyle this whole site. “Copy theme” gives you the exact config.

Style
Preset
Radius
Font size
Mode

Config

import { createUniversalConfig } from '@advui/theme'

export const config = createUniversalConfig({
  preset: 'violet',
  colors: {
    primary: '#7c3aed',   // any hex/rgb/hsl or a scale name ('indigo', 'teal'…)
    secondary: 'mauve',
    accent: 'mauve',
    success: 'green',
    warning: 'amber',
    error: 'red',
    info: 'blue',
    destructive: 'red',
  },
  radius: 'lg',
  fontScale: 'default',
  fonts: { body: 'Inter, system-ui, sans-serif', native: { body: 'Inter' } },
})

Custom colors become 12-step scales (in OKLCH) for light and dark mode. Foregrounds are chosen — and solid colors adjusted if needed — so text always meets WCAG AA.

Material 3

Prefer Google’s Material Design? material() gives every component the Material 3 look without changing any component code:

import { createUniversalConfig } from '@advui/theme'
import { material } from '@advui/theme/material'

export const config = createUniversalConfig({
  ...material({ seed: '#6750A4' }),   // any brand color
  fontScale: 'default',
})
  • Color: every role is generated from the seed with Google’s material-color-utilities (the “tonal spot” scheme Android uses for dynamic color). Material roles map onto ours: primaryContainer → primarySoft, secondaryContainer → secondary (the tonal button), outline → input. Success, warning and info are harmonized toward the seed.
  • Shape: pill buttons and icon buttons, 4px fields, 12px cards and 28px dialogs and sheets, through the button, buttonLg and dialog radius tokens.
  • Type: Roboto on web (load it in your app, e.g. from Google Fonts); the platform font on iOS and Android.
  • Press ripple (Android): buttons, chips, tabs, the navigation bar, menu rows and other pressables show Android’s native ripple from the touch point instead of a pressed color. Web and iOS keep their press colors. Turn it off with material({ androidRipple: false }), or on for any theme with createUniversalConfig({ androidRipple: true }); useRipple() adds it to your own pressables.
  • Accessibility: the same WCAG AA contrast checks run on Material themes as on every preset.
@advui/theme/material is a separate entry: apps that do not import it do not ship the color library. Material and the Adv UI presets share one component API, so you can switch at any time.

Theme tokens

Components only reference semantic tokens, so a new palette never requires component changes:

  • background foreground card popover muted mutedForeground
  • primary primaryForeground primaryHover primarySoft secondary accent
  • success warning error info destructive (+ Soft, Foreground, Border variants)
  • border borderStrong input ring overlay shadow-color

See every value on the Colors page.

Dark mode

Dark themes use hand-tuned dark scales (Radix Colors), not inverted light colors: backgrounds are layered (background → card → popover), shadows get stronger and solid colors keep their brand hue.

Runtime changes

Themes can be changed while the app runs with Tamagui’s updateTheme() — that is how the customizer on this site works, on web and native alike.

import { updateTheme } from '@tamagui/theme'
import { createThemeColors } from '@advui/theme'

// light, dark and the primary and inverse sub-themes (light_primary…)
const themes = createThemeColors({ primary: '#e11d48' })
for (const [name, theme] of Object.entries(themes)) updateTheme({ name, theme })
Edit this page on GitHub