AkurAI Build
Menu

Public repository / master

AkurAI-Framework / crates/ui/src/kit/mod.rs

Latest change d7f31233a0aaba65d741a85ac631a0e9004dba49 - akurai-ui kit: chat components (thread, message, tool_call, system_line, composer, presence) with Normal/Tv scale by Ólafur Búi Ólafsson

//! The component kit: accessible primitives in the spirit of Radix UI, styled
//! the way shadcn/ui styles them, on the framework's tokens and utility CSS.
//!
//! Components return an [`El`](crate::El) wherever possible, so callers keep
//! chaining (`button(Variant::Primary, Size::Md).on_click(…).child("Save")`).
//! House rule: corners are flat — nothing rounder than `rounded-md` (6px).

mod button;
mod card;
mod chat;
mod dialog;
mod form;
pub mod icons;
mod misc;
mod tabs;
mod toast;

pub use button::{button, icon_button, Size, Variant};
pub use card::{card, card_content, card_description, card_footer, card_header, card_title};
pub use chat::{
    author_chip, composer, format_clock, markdown, markdown_html, message, presence, system_line,
    thread, tool_call, AuthorKind, ChatAuthor, ChatMessage, ChatPart, ChatSize, SlashCommand,
    ToolCallView, ToolStatus,
};
pub use dialog::{confirm_dialog, dialog, dialog_footer};
pub use form::{checkbox, field, input, label, select, switch, textarea};
pub use misc::{alert, avatar, badge, empty_state, separator, skeleton, spinner, Tone};
pub use tabs::tabs;
pub use toast::{provide_toaster, toast, toast_error};

use std::cell::Cell;

/// Join class lists, skipping empty parts.
pub fn cn(parts: &[&str]) -> String {
    parts
        .iter()
        .filter(|p| !p.is_empty())
        .copied()
        .collect::<Vec<_>>()
        .join(" ")
}

thread_local! {
    static NEXT_ID: Cell<u32> = const { Cell::new(1) };
}

/// A document-unique id for wiring labels and ARIA references.
pub fn uid(prefix: &str) -> String {
    NEXT_ID.with(|n| {
        let id = n.get();
        n.set(id + 1);
        format!("{prefix}-{id}")
    })
}