Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Layout Components

Components for layout and structure: avatar, separator, accordion, and more.

Avatar

User profile images with fallback:

#![allow(unused)]
fn main() {
use blinc_cn::prelude::*;

avatar()
    .src("user.jpg")
    .fallback("JD")
}

Avatar Sizes

#![allow(unused)]
fn main() {
avatar().size(AvatarSize::Sm)    // 32px
avatar().size(AvatarSize::Md)    // 40px (default)
avatar().size(AvatarSize::Lg)    // 48px
avatar().size(AvatarSize::Xl)    // 64px
}

Avatar Fallback

#![allow(unused)]
fn main() {
// Initials fallback
avatar()
    .src("user.jpg")  // If fails to load...
    .fallback("JD")   // Show initials

// Icon fallback
avatar()
    .fallback_icon(icons::USER)
}

Avatar Group

#![allow(unused)]
fn main() {
avatar_group()
    .max(3)  // Show max 3, then "+N"
    .child(avatar().src("user1.jpg"))
    .child(avatar().src("user2.jpg"))
    .child(avatar().src("user3.jpg"))
    .child(avatar().src("user4.jpg"))
    .child(avatar().src("user5.jpg"))
// Displays: [avatar1] [avatar2] [avatar3] [+2]
}

Separator

Visual divider:

#![allow(unused)]
fn main() {
// Horizontal (default)
separator()

// Vertical
separator().orientation(Orientation::Vertical)
}

With Label

#![allow(unused)]
fn main() {
div()
    .flex_row()
    .items_center()
    .gap(8.0)
    .child(separator().flex_1())
    .child(text("or").color(Color::GRAY))
    .child(separator().flex_1())
}

Aspect Ratio

Maintain aspect ratio:

#![allow(unused)]
fn main() {
aspect_ratio(16.0 / 9.0)
    .child(img("video-thumbnail.jpg").cover())
}

Common Ratios

#![allow(unused)]
fn main() {
// 16:9 (video)
aspect_ratio(16.0 / 9.0)

// 4:3 (classic)
aspect_ratio(4.0 / 3.0)

// 1:1 (square)
aspect_ratio(1.0)

// 3:4 (portrait)
aspect_ratio(3.0 / 4.0)
}

Scroll Area

Custom scrollbars:

#![allow(unused)]
fn main() {
scroll_area()
    .h(400.0)
    .child(
        div()
            .flex_col()
            .gap(8.0)
            .children((0..50).map(|i| text(format!("Item {}", i))))
    )
}

Horizontal Scroll

#![allow(unused)]
fn main() {
scroll_area()
    .orientation(Orientation::Horizontal)
    .w(300.0)
    .child(
        div()
            .flex_row()
            .gap(8.0)
            .children((0..20).map(|i|
                card().w(150.0).child(text(format!("Card {}", i)))
            ))
    )
}

Collapsible

Expandable content:

#![allow(unused)]
fn main() {
let is_open = use_state(false);

collapsible()
    .open(is_open)
    .on_open_change(|open| set_is_open(open))
    .child(collapsible_trigger()
        .child(
            div().flex_row().items_center().gap(8.0)
                .child(text("Show more"))
                .child(icon(if is_open { icons::CHEVRON_UP } else { icons::CHEVRON_DOWN }))
        ))
    .child(collapsible_content()
        .child(text("Hidden content that expands...")))
}

Accordion

Multiple collapsible sections:

#![allow(unused)]
fn main() {
accordion()
    .accordion_type(AccordionType::Single)  // Only one open at a time
    .child(accordion_item("item-1")
        .child(accordion_trigger()
            .child(text("Section 1")))
        .child(accordion_content()
            .child(text("Content for section 1"))))
    .child(accordion_item("item-2")
        .child(accordion_trigger()
            .child(text("Section 2")))
        .child(accordion_content()
            .child(text("Content for section 2"))))
    .child(accordion_item("item-3")
        .child(accordion_trigger()
            .child(text("Section 3")))
        .child(accordion_content()
            .child(text("Content for section 3"))))
}

Multiple Open

#![allow(unused)]
fn main() {
accordion()
    .accordion_type(AccordionType::Multiple)  // Multiple can be open
    // ... accordion items
}

Resizable

Resizable panels:

#![allow(unused)]
fn main() {
resizable()
    .direction(ResizeDirection::Horizontal)
    .child(resizable_panel()
        .default_size(30.0)  // 30%
        .min_size(20.0)
        .child(text("Left Panel")))
    .child(resizable_handle())
    .child(resizable_panel()
        .default_size(70.0)  // 70%
        .child(text("Right Panel")))
}

Vertical Resizable

#![allow(unused)]
fn main() {
resizable()
    .direction(ResizeDirection::Vertical)
    .child(resizable_panel()
        .default_size(50.0)
        .child(text("Top Panel")))
    .child(resizable_handle())
    .child(resizable_panel()
        .default_size(50.0)
        .child(text("Bottom Panel")))
}

Examples

User List Item

#![allow(unused)]
fn main() {
div()
    .flex_row()
    .items_center()
    .gap(12.0)
    .p(12.0)
    .child(avatar().src(&user.avatar).fallback(&user.initials))
    .child(
        div().flex_col()
            .child(text(&user.name).weight(FontWeight::Medium))
            .child(text(&user.email).size(14.0).color(Color::GRAY))
    )
}

FAQ Accordion

#![allow(unused)]
fn main() {
accordion()
    .accordion_type(AccordionType::Single)
    .child(accordion_item("faq-1")
        .child(accordion_trigger()
            .child(text("How do I get started?")))
        .child(accordion_content()
            .child(text("To get started, first install the package..."))))
    .child(accordion_item("faq-2")
        .child(accordion_trigger()
            .child(text("What are the system requirements?")))
        .child(accordion_content()
            .child(text("You need Rust 1.70+ and..."))))
}

Split Pane Editor

#![allow(unused)]
fn main() {
resizable()
    .direction(ResizeDirection::Horizontal)
    .h_full()
    .child(resizable_panel()
        .default_size(25.0)
        .min_size(15.0)
        .child(sidebar()))  // File tree
    .child(resizable_handle())
    .child(resizable_panel()
        .default_size(75.0)
        .child(
            resizable()
                .direction(ResizeDirection::Vertical)
                .child(resizable_panel()
                    .default_size(70.0)
                    .child(editor()))  // Code editor
                .child(resizable_handle())
                .child(resizable_panel()
                    .default_size(30.0)
                    .child(terminal()))  // Terminal
        ))
}