Built-in iced themes and custom palette support.
Each built-in theme is an atom that maps to the corresponding iced::Theme
variant on the Rust side. Custom themes are plain maps that the renderer
parses into an iced::Theme::custom() palette.
Extended palette shade overrides
Custom themes automatically generate shade variants (strong, weak, etc.) from the six core palette colors using iced's Oklch-based algorithm. If you need precise control over specific shades, you can override them with flat keys in the theme map. Shade overrides only apply to custom themes -- built-in themes are not affected.
Each shade key targets a specific Pair (background color + text color)
in the extended palette. Append _text to any shade key to override
the text color for that shade.
Color families (base, weak, strong)
primary, success, warning, danger are core palette seeds
(set via custom/2). secondary is auto-derived from background
and text by iced's palette generator.
All five families support shade overrides: {family}_base,
{family}_weak, {family}_strong, plus _text variants.
Background family (8 levels)
background_base, background_weakest, background_weaker,
background_weak, background_neutral, background_strong,
background_stronger, background_strongest, plus _text variants.
Example
# Custom theme with shade overrides
theme = %{
name: "my-theme",
background: "#1a1a2e",
text: "#e0e0e0",
primary: "#0f3460",
primary_strong: "#1a5276",
primary_strong_text: "#ffffff",
background_weakest: "#0d0d1a"
}Any shade key you omit keeps the auto-generated value.
Widget chrome colour tokens
Custom themes can also carry theme-level colour tokens for cursor and scrollbar styling:
cursor_colorscrollbar_colorscroller_color
These values are cast as colours and sent in the custom theme map. The renderer uses scrollbar tokens as scrollable defaults. The cursor token applies to focused text entry widgets through iced's focused text style, and explicit widget text styling still wins.
Summary
Types
@type builtin() ::
:ferra
| :oxocarbon
| :nightfly
| :moonfly
| :kanagawa_lotus
| :kanagawa_dragon
| :kanagawa_wave
| :tokyo_night_light
| :tokyo_night_storm
| :tokyo_night
| :catppuccin_mocha
| :catppuccin_macchiato
| :catppuccin_frappe
| :catppuccin_latte
| :gruvbox_dark
| :gruvbox_light
| :solarized_dark
| :solarized_light
| :nord
| :dracula
| :dark
| :light
Functions
@spec builtin_themes() :: [atom()]
Returns the list of all known built-in theme atoms.
Validates a theme value.
Accepts built-in theme atoms, :system, or a custom theme map
(a map with at least a :name key).
Examples
iex> Plushie.Type.Theme.cast(:dark)
{:ok, :dark}
iex> Plushie.Type.Theme.cast(:system)
{:ok, :system}
iex> Plushie.Type.Theme.cast(%{name: "custom"})
{:ok, %{name: "custom"}}
iex> Plushie.Type.Theme.cast(:bogus)
:error
Build a custom theme palette map.
The returned map is passed through to the Rust renderer, which uses it to
construct an iced::Theme::custom() with a modified Palette.
Options
:base- built-in theme atom to use as the palette starting point:background- page background color:text- default text color:primary- primary accent color:success- success color:danger- danger color:warning- warning color:cursor_color- text cursor color:scrollbar_color- scrollbar track color:scroller_color- scrollbar handle color
All color values accept any form Color.cast/1 supports (hex
strings or named atoms). Shade override keys (e.g. primary_strong,
background_weakest, primary_strong_text) are also accepted and
cast as colors.
Note: :secondary is not a core seed. It is auto-derived from
:background and :text by iced's palette generator. To customize
the secondary palette, use shade overrides: secondary_base,
secondary_weak, secondary_strong (plus _text variants).
Unknown keys raise ArgumentError. Use valid_custom_keys/0 for
the complete set.
Examples
iex> Plushie.Type.Theme.custom("Tokyo Remix", primary: "#7aa2f7", danger: "#f7768e")
%{name: "Tokyo Remix", primary: "#7aa2f7", danger: "#f7768e"}
iex> Plushie.Type.Theme.custom("Nord+", base: :nord, primary: "#88c0d0")
%{name: "Nord+", base: "nord", primary: "#88c0d0"}
Returns the set of valid keys for custom/2 (excluding :base, which
is handled separately).