Plushie.Type.Theme (Plushie v0.7.2)

Copy Markdown View Source

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_color
  • scrollbar_color
  • scroller_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

Functions

Returns the list of all known built-in theme atoms.

Validates a theme value.

Build a custom theme palette map.

Returns the set of valid keys for custom/2 (excluding :base, which is handled separately).

Types

builtin()

@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

t()

@type t() :: builtin() | :system | map()

Functions

builtin_themes()

@spec builtin_themes() :: [atom()]

Returns the list of all known built-in theme atoms.

cast(v)

@spec cast(term()) :: {:ok, t()} | :error

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

custom(name, opts \\ [])

@spec custom(name :: String.t(), opts :: keyword()) :: map()

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"}

valid_custom_keys()

@spec valid_custom_keys() :: MapSet.t(atom())

Returns the set of valid keys for custom/2 (excluding :base, which is handled separately).