iced-shadcn 0.5.0

Shadcn-inspired component kit for iced
Documentation

iced-shadcn


[!WARNING] API STABILITY NOTICE: iced-shadcn API is currently unstable and may change between versions, including breaking changes. Always pin exact crate versions and review release notes before upgrading.

Overview

iced-shadcn is planned as a set of components for iced styled after shadcn/ui.
The goal is to provide a shared visual language and theme tokens that match the rest of the shadcn-rs ecosystem.

Status

This crate is under active development. Public API, theming model, and component set are not stable yet and may change at any time.

Coming soon:

  • Component catalog with parity to egui-shadcn where it makes sense
  • Theming guide and tokens
  • Usage examples and best practices

Tabs

Minimal example using the new Tabs API:

use iced::widget::text;
use iced_shadcn::{
    tabs_content, tabs_contents, tabs_list, tabs_root, tabs_trigger, TabsHover, TabsListProps,
    TabsListVariant, TabsRootProps, Theme,
};

fn view<'a, Message: Clone + 'a>(theme: &Theme, active: &'a str) -> iced::Element<'a, Message> {
    let list = tabs_list(
        vec![
            tabs_trigger("account", "Account"),
            tabs_trigger("password", "Password"),
        ],
        active,
        None::<fn(String) -> Message>,
        TabsRootProps::new(),
        TabsListProps::new()
            .variant(TabsListVariant::Pill)
            .transparent_container(true)
            .hover(TabsHover::Soft)
            .hover_intensity(0.75),
        theme,
    );

    let content = tabs_contents(
        vec![
            tabs_content("account", text("Account content")),
            tabs_content("password", text("Password content")),
        ],
        active,
    );

    tabs_root(list, content)
}

Examples:

  • crates/iced-shadcn/examples/tabs-demo
  • crates/iced-shadcn/examples/tabs-line
  • crates/iced-shadcn/examples/tabs-size
  • crates/iced-shadcn/examples/tabs-color
  • crates/iced-shadcn/examples/tabs-disabled

Navigation Menu

Minimal example using Navigation Menu API:

use iced::widget::{column, text};
use iced_shadcn::{
    navigation_menu_content, navigation_menu_item, navigation_menu_link_item, navigation_menu_list,
    navigation_menu_root, navigation_menu_trigger, navigation_menu_viewport,
    NavigationMenuContentProps, NavigationMenuListProps, NavigationMenuProps, Theme,
};

fn view<'a, Message: Clone + 'a>(
    theme: &Theme,
    open: Option<&'a str>,
    on_open: Option<fn(String) -> Message>,
) -> iced::Element<'a, Message> {
    let items = navigation_menu_list(vec![
        navigation_menu_item(
            navigation_menu_trigger("home", "Home"),
            navigation_menu_content(column![text("Intro"), text("Installation")].spacing(6))
                .props(NavigationMenuContentProps::new().width(240.0)),
        ),
        navigation_menu_link_item("docs", text("Docs"), None::<Message>),
    ]);

    navigation_menu_root(
        items,
        open,
        on_open,
        NavigationMenuProps::new().viewport_component(navigation_menu_viewport()),
        NavigationMenuListProps::new(),
        theme,
    )
}

Example:

  • crates/iced-shadcn/examples/navigation-menu-demo

Breadcrumb

Minimal example using the Breadcrumb API:

use iced_shadcn::{
    BreadcrumbProps, Theme, breadcrumb, breadcrumb_item, breadcrumb_link, breadcrumb_list,
    breadcrumb_page, breadcrumb_separator,
};

fn view<'a, Message: Clone + 'a>(theme: &Theme) -> iced::Element<'a, Message> {
    breadcrumb(theme, BreadcrumbProps::new(), |ctx| {
        breadcrumb_list(
            ctx,
            vec![
                breadcrumb_item(ctx, vec![breadcrumb_link("Docs", None, ctx)]),
                breadcrumb_separator(ctx, None),
                breadcrumb_item(ctx, vec![breadcrumb_link("Components", None, ctx)]),
                breadcrumb_separator(ctx, None),
                breadcrumb_item(ctx, vec![breadcrumb_page("Breadcrumb", ctx)]),
            ],
        )
    })
}

Example:

  • crates/iced-shadcn/examples/breadcrumb

Empty

Composable example matching the shadcn-svelte structure:

use lucide_icons::Icon;
use iced_shadcn::{
    EmptyContentProps, EmptyHeaderProps, EmptyMediaProps, EmptyMediaVariant, EmptyRootProps,
    EmptyTitleProps, Theme, button, empty_content, empty_description, empty_header, empty_media,
    empty_root, empty_title,
};

fn view<'a, Message: Clone + 'a>(theme: &'a Theme) -> iced::Element<'a, Message> {
    empty_root(
        iced::widget::column![
            empty_header(
                vec![
                    empty_media(
                        iced::widget::text(char::from(Icon::Folder).to_string()),
                        EmptyMediaProps::new().variant(EmptyMediaVariant::Icon),
                        theme,
                    ),
                    empty_title("No data", EmptyTitleProps::new(), theme),
                    empty_description("No data found", Default::default(), theme),
                ],
                EmptyHeaderProps::new(),
            ),
            empty_content(
                vec![button("Add data", None::<Message>, Default::default(), theme).into()],
                EmptyContentProps::new(),
            ),
        ]
        .spacing(24),
        EmptyRootProps::new(),
        theme,
    )
}

Example:

  • crates/iced-shadcn/examples/empty

Resizable

Example demonstrating both splitter directions, live Vec<f32> state management, and handle options:

use iced_shadcn::{
    ResizableDirection, ResizableHandleProps, ResizablePanelGroupProps, ResizablePanelProps,
    Theme, resizable_handle, resizable_panel, resizable_panel_group,
};

// See crates/iced-shadcn/examples/resizable-demo/main.rs for a complete example.

Example:

  • crates/iced-shadcn/examples/resizable-demo

Image Cropper

Example demonstrating dialog-based crop flow, PNG export, round/rect preview, and optional picker integration:

use iced_shadcn::{
    ImageCropShape, ImageCropperAction, ImageCropperProps, ImageCropperState, Theme,
    image_cropper_cancel, image_cropper_canvas, image_cropper_controls, image_cropper_crop,
    image_cropper_dialog, image_cropper_preview, image_cropper_root, image_cropper_upload_trigger,
};

// See crates/iced-shadcn/examples/image-cropper-demo/main.rs for a complete example.

Example:

  • crates/iced-shadcn/examples/image-cropper-demo

License

MIT


Inspired by shadcn/ui · Icons by Lucide