native-theme-iced 0.5.2

iced toolkit connector for native-theme
Documentation

native-theme-iced

iced toolkit connector for native-theme.

Maps native_theme::ResolvedThemeVariant data to iced's theming system, producing a fully configured iced::Theme with correct colors for all built-in widget styles via iced's Catalog system.

Usage

Add both crates to your Cargo.toml:

[dependencies]
native-theme = "0.5.2"
native-theme-iced = "0.5.2"

Then create an iced theme from any native-theme preset:

use native_theme::ThemeSpec;
use native_theme_iced::to_theme;

// Load a preset and resolve it
let nt = ThemeSpec::preset("dracula").unwrap();
let is_dark = true;
if let Some(variant) = nt.pick_variant(is_dark) {
    let mut v = variant.clone();
    v.resolve();
    let resolved = v.validate().unwrap();
    let theme = to_theme(&resolved, "My App");
    // Use `theme` as your iced application theme
}

Or read the OS theme at runtime:

use native_theme::SystemTheme;
use native_theme_iced::to_theme;

let system = SystemTheme::from_system().unwrap();
let theme = to_theme(system.active(), "System Theme");

Widget Metrics

The crate exposes helper functions for widget sizing that iced applies per-widget rather than through the Catalog:

  • button_padding(resolved) -- horizontal and vertical padding
  • input_padding(resolved) -- text input padding
  • border_radius(resolved) -- standard corner radius
  • border_radius_lg(resolved) -- large corner radius (e.g., dialogs)
  • scrollbar_width(resolved) -- scrollbar track width
  • font_family(resolved) -- primary UI font family name
  • font_size(resolved) -- primary UI font size in logical pixels
  • mono_font_family(resolved) -- monospace font family name
  • mono_font_size(resolved) -- monospace font size in pixels

All helpers take a &ResolvedThemeVariant reference.

Modules

Module Purpose
palette Maps native-theme colors to iced's 6-field Palette
extended Overrides iced's Extended palette for secondary and background.weak
icons Icon role mapping, SVG widget helpers, and animated icon playback

Custom Icons

For app-specific icons defined via native-theme-build, the connector provides:

  • custom_icon_to_image_handle(provider, icon_set) -- load a custom icon as an iced image handle
  • custom_icon_to_svg_handle(provider, icon_set, color) -- load as an SVG handle (pass None for uncolored)

These work with any type implementing IconProvider.

Animated Icons

The connector provides helpers for displaying animated icons from loading_indicator():

  • animated_frames_to_svg_handles() -- converts AnimatedIcon::Frames to a Vec<svg::Handle> for frame-based playback
  • spin_rotation_radians() -- computes the current rotation angle for AnimatedIcon::Transform playback
use native_theme::{loading_indicator, prefers_reduced_motion, AnimatedIcon};
use native_theme_iced::icons::{animated_frames_to_svg_handles, spin_rotation_radians};

if let Some(anim) = loading_indicator("material") {
    if prefers_reduced_motion() {
        // Static fallback for accessibility
        let static_icon = anim.first_frame();
    } else {
        match &anim {
            AnimatedIcon::Frames { frame_duration_ms, .. } => {
                // Cache this -- do not call on every frame tick
                let handles = animated_frames_to_svg_handles(&anim);
                // Use iced::time::every(Duration::from_millis(*frame_duration_ms as u64))
                // to drive frame_index = (frame_index + 1) % handles.len()
                // In view: Svg::new(handles[frame_index].clone())
            }
            AnimatedIcon::Transform { icon, animation } => {
                let angle = spin_rotation_radians(elapsed, 1000);
                // Svg::new(handle).rotation(Rotation::Floating(angle))
            }
        }
    }
}

Cache the Vec<svg::Handle> from animated_frames_to_svg_handles() -- do not call it on every frame tick. Use Rotation::Floating (not Rotation::Solid) for spin animations to avoid layout jitter during rotation.

Example

Run the showcase widget gallery to explore all 16 presets interactively:

cargo run -p native-theme-iced --example showcase

Linux

KDE Breeze Dark KDE Breeze Light Material Dark Material Light Catppuccin Mocha Dark Catppuccin Mocha Light

macOS

macOS Sonoma Light macOS Sonoma Dark

Windows

Windows 11 Light Windows 11 Dark

The showcase displays all iced widgets (buttons, inputs, sliders, checkboxes, togglers, etc.) themed with native-theme presets, with live theme switching and a color map inspector.

License

Licensed under either of

at your option.