Theming
Customize every aspect of Floe UI using the design token system.
How It Works
Floe UI uses a DesignTokens struct that mirrors the CSS custom property system from shadcn/ui (--background, --primary, etc.). Every component reads its colors, radii, and spacing from these tokens — so changing one token updates every component that uses it.
theming.rs
use floe_ui::prelude::*;
"text-zinc-500">// Use a built-in theme
let theme = FloeTheme::zinc_dark();
let tokens = &theme.tokens;
"text-zinc-500">// All components automatically use these tokens
let btn = button::primary("Click me", tokens);
let card = card::styled(text("Hello!"), tokens);Token Reference
Semantic Colors
| Name | Type | Description |
|---|---|---|
| background | Color | App background color |
| foreground | Color | Default text / foreground color |
| card | Color | Card surface color |
| card_foreground | Color | Text color on cards |
| popover | Color | Popover / dropdown surface |
| popover_foreground | Color | Text inside popovers |
| primary | Color | Primary brand color (buttons, links) |
| primary_foreground | Color | Text on primary surfaces |
| secondary | Color | Secondary / muted action color |
| secondary_foreground | Color | Text on secondary surfaces |
| muted | Color | Muted backgrounds (disabled, subtle) |
| muted_foreground | Color | Text on muted surfaces |
| accent | Color | Accent highlight (hovers, selections) |
| accent_foreground | Color | Text on accent surfaces |
| destructive | Color | Danger / destructive actions |
| destructive_foreground | Color | Text on destructive surfaces |
| border | Color | Default border color |
| input | Color | Input field border color |
| ring | Color | Focus ring color |
Border Radius Scale
| Name | Type | Description |
|---|---|---|
| radius_sm | f32 | Small radius — inner elements |
| radius_md | f32 | Medium radius — buttons, inputs |
| radius_lg | f32 | Large radius — cards, modals |
| radius_xl | f32 | Extra large radius — hero sections |
| radius_full | f32 | Full radius — pills, avatars |
Spacing Scale
| Name | Type | Description |
|---|---|---|
| xs | f32 | Tightest spacing |
| sm | f32 | Small spacing |
| md | f32 | Medium spacing |
| lg | f32 | Large spacing — default padding |
| xl | f32 | Extra large spacing |
| xxl | f32 | Widest spacing |
Creating a Custom Theme
You can create a fully custom theme by constructing DesignTokens with your own colors. Use the hsl() and hsla() helpers for easy color definition.
custom_theme.rs
use floe_ui::prelude::*;
let my_tokens = DesignTokens {
background: hsl(222.0, 0.84, 0.05), "text-zinc-500">// Deep navy
foreground: hsl(210.0, 0.40, 0.98), "text-zinc-500">// Near white
primary: hsl(217.0, 0.91, 0.60), "text-zinc-500">// Bright blue
primary_foreground: hsl(0.0, 0.0, 1.0), "text-zinc-500">// White
"text-zinc-500">// ... fill in all other tokens ...
"text-zinc-500">// Use default radii
radius_sm: 4.0,
radius_md: 6.0,
radius_lg: 8.0,
radius_xl: 12.0,
radius_full: 9999.0,
spacing: SpacingScale::default(),
};Color Helper Functions
Floe UI provides utility functions for working with colors:
| Function | Description |
|---|---|
| hsl(h, s, l) | Create a Color from HSL values (hue 0-360, saturation 0-1, lightness 0-1) |
| hsla(h, s, l, a) | Create a Color from HSLA values with alpha |
| with_alpha(color, alpha) | Apply an alpha value (0.0 – 1.0) to an existing color |
| darken(color, amount) | Darken a color by mixing toward black |
| lighten(color, amount) | Lighten a color by mixing toward white |
Current Theme Preview
The Zinc Dark theme used on this site:
Background
Foreground
Primary
Secondary
Muted
Accent
Destructive
Border