Skip to main content

Crate aetna_core

Crate aetna_core 

Source
Expand description
Aetna badge icon

§aetna-core

Aetna hero demo — release console rendered headlessly through the wgpu backend

Backend-agnostic UI primitives for Aetna apps.

Aetna is shaped around how an LLM authors UI: vocabulary parity with the training distribution matters more than configurability, and the minimum output should be the correct output. The catalog below — card, sidebar, tabs_list, dialog, toolbar, item, etc. — mirrors the shadcn / WAI-ARIA shapes models already know. Reach for those before composing primitives. column / row / stack / button / text are layout fallbacks for when no named widget fits, not the canonical app vocabulary.

§Reach for these first

When scaffolding a UI, prefer the named affordance over the underlying primitives. The list is short:

IntentIdiomatic callAvoid
Grouped content (settings card, panel of fields, any “boxed” surface)card([card_header([card_title("Title")]), card_content([...])]) or titled_card("Title", [...])column([...]).fill(CARD).stroke(BORDER).radius(...) or column(...).surface_role(SurfaceRole::Panel) (Panel only sets stroke + shadow — not fill)
Flat sidebar / nav railsidebar([sidebar_header(...), sidebar_group([...])]) plus sidebar_menu_button_with_icon(...) for leaf itemscolumn(...).fill(CARD).stroke(BORDER).width(SIDEBAR_WIDTH) or column(...).surface_role(SurfaceRole::Panel) for the sidebar surface
Sidebar tree / dense resource listkeep sidebar([...]), then make one local tree_row(depth, leading, label, trailing, current) helper from row([...]).focusable().height(Size::Fixed(28.0..40.0)).current() and indent via paddingforcing every branch/file/stash into flat sidebar_menu_button(...), or using card/table rows inside the sidebar
Toolbar / page header rowtoolbar([toolbar_title("Documents"), spacer(), toolbar_group([...])]).padding(Sides::xy(tokens::SPACE_4, tokens::SPACE_2)) as app chrome; use card_header only inside a cardwrapping the top toolbar in card([card_content([toolbar(...)])]), or ad hoc action rows with inconsistent vertical alignment
Top-level app menusmenubar([menubar_trigger("app-menu", "file", "File", open == Some("file"))]) plus root-layer menubar_menu("app-menu", "file", [...]), folded with menubar::apply_event(&mut open, &event, "app-menu")a toolbar row of unrelated dropdown buttons, or a hand-rolled File/Edit/View strip
Conversation / event-log rowa local log_row(role_color, faint_fill, content) helper built from row([gutter, content]); use accordion_item for collapsible reasoning/tool detailscard([card_header([badge(role)]), card_content([message])]) repeated for every chat message
Tabs / segmented controltabs_list(key, &current, options) + tabs::apply_event; for icon/badge/count tabs, use tabs_list_from_triggers([tab_trigger_content(key, value, [...], selected)])manual row([button, button]).fill(MUTED) segment, or hand-rolled selected-tab state
Object/action list row (recent repo, file, project, person)item([item_media_icon(...), item_content([item_title(...), item_description(...)]), item_actions(...)]) inside item_group([...])row([column([text, text]), button, button]).key(...) — every clickable repo/file/project/person row is item, not a hand-rolled focusable row
Dialogdialog(key, [dialog_header([...]), body, dialog_footer([...])])a custom centered overlay card
Edge sheetsheet(key, SheetSide::Right, [sheet_header([...]), body])a modal manually pinned to the viewport edge
Dropdown / context menu (action menu — items perform side-effects; for a value-bound picker see the next row)dropdown_menu(key, trigger, [dropdown_menu_label(...), dropdown_menu_item_with_shortcut(...)])a popover full of hand-rolled rows; per-row [Edit][Delete] button pairs that should collapse into one trigger
Value picker (model, timezone, status, any enum field)select_trigger(key, &current_label) + select_menu(key, [(value, label), …]) paired via select::apply_event(&mut value, &mut open, &event, key, parse)dropdown_menu with hand-rolled state, an accordion-based picker, or a hand-rolled popover full of menu_items
Standard tooltip.tooltip("...") on any elementa manually-positioned popover
Callout / validation summaryalert([alert_title("Heads up"), alert_description("Details")]).warning()a manually styled card with status-colored text
Status indicator (Online, Pending, Failed)badge("Online").success() (also .warning() / .destructive() / .info() / .muted())text("● Online").text_color(SUCCESS)
User identity chipavatar_fallback("Alicia Koch") or avatar_image(img)a bare image/text node with custom circle styling
Loading placeholderskeleton().width(Size::Fixed(220.0)) or skeleton_circle(32.0)hard-coded muted rectangles
Section dividerseparator() / vertical_separator()hand-rolled 1px boxes
Command/menu rowcommand_row("git-branch", "New branch", "Ctrl+B") or command_item([...])repeating icon-slot/label/shortcut rows by hand
Collapsible sectionaccordion_item("settings", "security", "Security", open, [...]) + accordion::apply_event(...)a button plus hand-managed chevron row
Breadcrumb pathbreadcrumb_list([breadcrumb_link("Projects"), breadcrumb_separator(), breadcrumb_page("Aetna")])a raw slash-delimited text string
Paginationpagination_content([pagination_previous(), pagination_link("1", true), pagination_next()])unaligned text buttons with custom square sizing
Section heading / page title.heading() / h2(...) (or .title() / h3(...)).font_size(16.0).font_weight(Bold).text_color(...)
Field label.label().font_weight(Semibold).text_color(...)
Helper / hint text.caption() or .muted().font_size(12.0).text_color(tokens::MUTED_FOREGROUND)
Inline code / mono.code() or mono(...).font_family("monospace") (no such API)
Selected row in a collection.selected() chainablesurface_role(SurfaceRole::Selected) (works, but .selected() reads better and sets content color)
Current nav / page item.current() chainablesurface_role(SurfaceRole::Current)
Resizable divider between two panesresize_handle(Axis::Row).key(...) + resize_handle::apply_event_fixed(...)divider() (which is non-interactive) plus drag plumbing
Indent inside a list (e.g. tree depth).padding(Sides { left: indent, ..Sides::zero() })row([spacer().width(Fixed(indent)), ...])
Toggle (preferences)switch(self.value).key(k) + switch::apply_event(...)a button with two text labels
Labelled control row (settings, prefs)field_row("Label", control)hand-rolled row([text("Label").label(), spacer(), control]) repeated everywhere
Stacked long field (URL, path, token, search)form_item([form_label("Repository URL"), form_control(text_input(...).width(Size::Fill(1.0))), form_description(...)]) inside form([...])using field_row for long strings, or repeating column([text(label).label(), text_input(...)])
Date picker / month gridcalendar_month("billing-date", "May 2026", days) with CalendarDay::new(value, label).selected() / .outside() / .disabled() and calendar::apply_event(&mut selected, &event, "billing-date")a hand-rolled grid of tiny buttons with ad hoc selected/outside-month styling
Raster image (logo, screenshot, thumbnail)image(Image::from_rgba8(...)).image_fit(ImageFit::Contain)reaching for a custom shader
Throwaway notificationaccumulate ToastSpec::success("Saved") and return them from App::drain_toastsspinning a manual modal with a timer

§Smells that mean an affordance is being missed

One per line — if any of these appear in your tree, a named widget is the right reach instead.

  • column(...).surface_role(SurfaceRole::Panel) — use card() or sidebar(). Panel decorates, it doesn’t fill.
  • column([row, body]).fill(CARD).stroke(BORDER) reinventing the card silhouette — call card([...]) (or titled_card(...)).
  • column(...).fill(CARD).stroke(BORDER).width(SIDEBAR_WIDTH) reinventing the sidebar surface — call sidebar([...]).
  • A keyed/focusable row([column([t1,t2]), button, button]) used as a clickable file/repo/project/person/asset entry — use item([item_media, item_content([item_title, item_description]), item_actions([...])]) so hover, press, focus, the rail, and the slots are named.
  • Per-row [Edit][Delete] button pairs in a narrow list — collapse to one dropdown_menu trigger or a single icon-button kebab; let selection drive editing in the right pane.
  • card([card_content([toolbar(...)])]) for the top app header — a toolbar is chrome, not a boxed content object.
  • A File / Edit / View strip built from separate button(...) or dropdown_menu(...) calls — use menubar, menubar_trigger, and menubar_menu so the root, triggers, dismiss keys, and menu-row anatomy stay named.
  • row([title, spacer(), action]).fill(MUTED).stroke(BORDER) header bar sitting above a body inside a card — that’s a hand-rolled card_header. Lift the row into card_header([...]).fill(MUTED), or split the “header bar over body” block into its own card([card_header(...), card_content(...)]).
  • A sidebar full of unrelated card() sections — use sidebar_group, accordion_item, or a local dense tree_row helper inside sidebar.
  • A transcript rendered as one card() per message — use an event-log row with a narrow role gutter so long assistant output reads as a stream.
  • field_row squeezing a repository URL, filesystem path, token, or search query into the right edge of a dialog — use stacked form_item.
  • A date picker rendered as a manual 7-column row/column grid — use calendar_month so day sizing, outside-month dimming, selected state, and nav keys are canonical.
  • .gap(0.0) — already the default; delete it.
  • .font_size(...).font_weight(...).text_color(...) on the same node — use a role modifier (.heading() / .label() / .caption() / .muted()).
  • Wrapping a single child in row([single]) to apply .padding(...) — every El has .padding() directly.
  • An explicit .fill(tokens::BACKGROUND) on the root — the host already paints it.
  • IconName::AlertCircle as a placeholder when the project has its own SVG — use SvgIcon::parse_current_color(include_str!("...")) and pass it to icon(...).

§Common app shells

When the catalog widget doesn’t fit your data shape exactly, wrap it rather than replace it. card([...]) and sidebar([...]) are column-flavored containers that bundle the canonical fill + stroke + radius + shadow + role recipe — you can put any composition inside.

A two-pane workbench (sidebar + main):

row([
    sidebar([
        sidebar_header([h3("Repository")]),
        sidebar_group([
            sidebar_group_label("Branches"),
            sidebar_menu([/* sidebar_menu_button_with_icon(...) per branch */]),
        ]),
    ]),
    column([
        toolbar([toolbar_title("main"), spacer(), button("Push").primary().key("push")]),
        card([card_content([/* your view */])]).height(Size::Fill(1.0)),
    ])
    .width(Size::Fill(1.0))
    .height(Size::Fill(1.0)),
])

A three-column workbench (sidebar + center + inspector). Use card() for the inspector pane the same way — it gives you the same recipe the sidebar uses, just at Size::Fixed(WIDTH) instead of SIDEBAR_WIDTH. Reach into card_header for selected-item identity (title, metadata, copy / open actions) and card_content for the scrollable body. The slots bake shadcn’s stock recipe directly into their constructors — card_header is p-6 with a small space-y-1.5 between title and description; card_content and card_footer are p-6 pt-0. Naive use produces the right visual without an explicit .padding(...). Override per-call, Tailwind-shaped: .padding(SPACE_4) to swap the whole recipe (= p-4), or the additive shorthands .pt(...), .pb(...), .pl(...), .pr(...), .px(...), .py(...) to override a single side or axis while preserving the constructor’s defaults elsewhere (= p-6 pt-0). The two compose, so a tighter card body that keeps the no-double-pad seam is card_content([...]).padding(tokens::SPACE_3).pt(0.0) (= p-3 pt-0) — .padding(SPACE_3) alone would reset the bundled pt-0 and leave a visible doubled gap below the header. The override case below uses .padding(0.0) on card_content because its only child is a scroll(...) that should reach the card edges.

row([
    sidebar([/* nav */]),
    column([/* center pane */]).width(Size::Fill(1.0)),
    card([
        card_header([
            row([h3(item.title.clone()), spacer(), button("Copy ID").ghost().key("copy")])
                .align(Align::Center)
                .gap(tokens::SPACE_2),
            text(item.subtitle.clone()).muted().caption(),
        ]),
        card_content([scroll([/* sub-cards, fields */])])
            .padding(0.0)
            .height(Size::Fill(1.0)),
    ])
    .width(Size::Fixed(320.0))
    .height(Size::Fill(1.0)),
])

A list of selectable objects inside a card (recent repos, project imports, search results) — this is item + item_group, not a column of hand-rolled rows:

titled_card(
    "Recent repositories",
    [item_group([
        item([
            item_media_icon(IconName::Folder),
            item_content([
                item_title("aetna"),
                item_description("/home/christian/workspace/aetna"),
            ]),
            item_actions([badge("current").info()]),
        ])
        .key("recent:aetna")
        .current(),
        item([
            item_media_icon(IconName::Folder),
            item_content([
                item_title("whisper-git"),
                item_description("/home/christian/workspace/whisper-git"),
            ]),
            item_actions([icon(IconName::ChevronRight).muted()]),
        ])
        .key("recent:whisper"),
    ])],
)

A tabbed page:

column([
    tabs_list("view", &self.tab, [("working", "Working"), ("history", "History")]),
    match self.tab.as_str() {
        "history" => history_view(self),
        _ => working_view(self),
    },
])

A chat / event-log workbench:

Keep the app shell boring: sidebar on the left, toolbar for selected thread identity and actions, scroll(log_rows) for the transcript, and a bottom composer row with text_area plus actions. The transcript itself is not a card collection. Cards isolate objects; event logs should scan as one continuous record with small role markers.

fn log_row(role_color: Color, faint_fill: Option<Color>, content: El) -> El {
    let row = row([
        El::new(Kind::Custom("log_gutter"))
            .fill(role_color)
            .width(Size::Fixed(3.0))
            .height(Size::Fill(1.0)),
        content
            .padding(Sides {
                left: tokens::SPACE_3,
                right: tokens::SPACE_2,
                top: tokens::SPACE_2,
                bottom: tokens::SPACE_2,
            })
            .width(Size::Fill(1.0)),
    ])
    .width(Size::Fill(1.0));
    if let Some(fill) = faint_fill { row.fill(fill) } else { row }
}

column([
    toolbar([toolbar_title(thread.title.clone()), spacer(), badge(thread.state_label)]),
    scroll(thread.items.iter().map(|item| match item {
        // `paragraph` for plain user input; `md(...)` when the source
        // is markdown (assistant streams, tool output prose).
        ChatItem::User(text) => log_row(tokens::INFO, Some(tokens::INFO.with_alpha(38)), paragraph(text)),
        ChatItem::Assistant(text) => log_row(tokens::SUCCESS, None, md(text)),
        ChatItem::Reasoning { id, open, preview, body } => log_row(
            tokens::MUTED_FOREGROUND,
            None,
            accordion_item("reasoning", id, preview, *open, [md(body)]),
        ),
        ChatItem::Tool(call) => log_row(
            tokens::WARNING,
            None,
            accordion_item("tool", call.id, call.summary, call.open, [code_block(call.details)]),
        ),
    }))
    .key(format!("thread-scroll:{}", thread.id))
    .padding(tokens::SPACE_4)
    .gap(tokens::SPACE_2)
    .height(Size::Fill(1.0)),
    row([
        text_area(&self.compose, &self.selection, "compose").height(Size::Fixed(120.0)),
        button("Send").primary().key("send"),
    ])
    .gap(tokens::SPACE_3)
    .padding(tokens::SPACE_3)
    .align(Align::End),
])

When a text_area is fixed-height like the composer above, the app should queue text_area::caret_scroll_request_for(...) from App::drain_scroll_requests after text_area::apply_event(...) returns true. That lets PageUp/PageDown, arrows, paste, and typing keep the caret visible without emitting a scroll request every frame.

If sidebar_menu_button_with_icon doesn’t fit your row anatomy (count badges, nested sub-groups, custom leading icons), keep the outer sidebar([...]) for the panel surface and compose the rows freely inside. Same for card_content — anything column-shaped goes there.

§App trait scaffolding

Once the shell is in place, the App trait wires it to the runtime. build returns the El tree; on_event handles routed events keyed by the same string passed to .key("...") — same identifier, no separate .on_click(...) registration. Hover, press, and focus visuals are applied automatically; the author never tags a node “this one is hovered.”

use aetna_core::prelude::*;

struct Counter {
    value: i32,
}

impl App for Counter {
    fn build(&self, _cx: &BuildCx) -> El {
        column([
            h1(format!("{}", self.value)),
            row([
                button("-").key("dec"),
                button("+").key("inc").primary(),
            ])
            .gap(tokens::SPACE_2),
        ])
        .gap(tokens::SPACE_3)
        .padding(tokens::SPACE_4)
    }

    fn on_event(&mut self, event: UiEvent) {
        if event.is_click_or_activate("inc") {
            self.value += 1;
        } else if event.is_click_or_activate("dec") {
            self.value -= 1;
        }
    }
}

This is a deliberately tiny example — column/row/button is fine for a counter, but for a real app start from the workbench skeletons above. Use aetna-winit-wgpu to open a native desktop window. Use aetna-wgpu directly only when writing a custom host or embedding Aetna in an existing render loop. If the UI mirrors external state, refresh it in App::before_build — hosts call that hook immediately before each build.

§Surface roles, briefly

SurfaceRole is a decoration layer, not a fill recipe. Panel and Raised set stroke and shadow only — they assume you (or the widget wrapping you) supplied a fill. Sunken / Selected / Current / Input / Danger do default a fill from the palette. Per-variant contracts live on the SurfaceRole enum’s rustdoc; reach for the .selected() / .current() chainables for state, and for card() / sidebar() / dialog() / popover() for surface containers.

§API layers

  • prelude — the app and widget author surface; what an LLM should usually import.
  • widgets — controlled widget builders and their apply_event / apply_input helpers (e.g. text_input::apply_event, slider::normalized_from_event).
  • bundle — headless artifacts (tree.txt / draw_ops.txt / lint.txt / .svg) for tests and design review. The lint pass catches raw colors, text overflow, alignment misses, missing surface fills, and duplicate ids.
  • ir, paint, runtime, text atlas, vector mesh, and MSDF modules are advanced backend / diagnostic surfaces. Public because sibling backend crates use them; ordinary app code should not start there.

The crate ships runnable examples under examples/: settings, scroll_list, virtual_list, inline_runs, modal, custom_shader, circular_layout, plus the dashboard_01_calibration reference fixture that mirrors the shadcn dashboard-01 demo through stock widgets.

§Rendering smoke test

Any App builds and renders headlessly through the bundle pipeline:

use aetna_core::prelude::*;

struct Demo;

impl App for Demo {
    fn build(&self, _cx: &BuildCx) -> El {
        card([
            card_header([card_title("Hello")]),
            card_content([text("rendered headlessly")]),
        ])
        .width(Size::Fixed(320.0))
    }
}

let app = Demo;
let theme = app.theme();
let mut ui = app.build(&BuildCx::new(&theme));
let bundle = render_bundle(&mut ui, Rect::new(0.0, 0.0, 720.0, 400.0));
assert!(!bundle.svg.is_empty());

§Rendering pipeline

Builders produce an El tree. Layout writes rects into UiState. The draw-op pass resolves visual facts into backend-neutral DrawOp values. Backend runners turn those draw ops into GPU resources and route pointer/keyboard input back into UiEvent values.

The stock surface shader is rounded_rect; text, icons, custom shaders, and backdrop-sampling materials all flow through the same tree and event model.

Re-exports§

pub use anim::AnimProp;
pub use anim::AnimValue;
pub use anim::Animation;
pub use anim::SpringConfig;
pub use anim::Timing;
pub use anim::TweenConfig;
pub use bundle::artifact::Bundle;
pub use bundle::artifact::render_bundle;
pub use bundle::artifact::render_bundle_themed;
pub use bundle::artifact::render_bundle_with;
pub use bundle::artifact::render_bundle_with_theme;
pub use bundle::artifact::write_bundle;
pub use bundle::inspect::dump_tree;
pub use bundle::lint::Finding;
pub use bundle::lint::FindingKind;
pub use bundle::lint::LintReport;
pub use bundle::lint::lint;
pub use bundle::manifest::draw_ops_text;
pub use bundle::manifest::shader_manifest;
pub use bundle::svg::svg_from_ops;
pub use clipboard::delete_selection_event;
pub use clipboard::paste_text_event;
pub use clipboard::selected_text_for_app;
pub use cursor::Cursor;
pub use draw_ops::draw_ops;
pub use draw_ops::draw_ops_with_theme;
pub use event::App;
pub use event::AppShader;
pub use event::BuildCx;
pub use event::FrameTrigger;
pub use event::HostDiagnostics;
pub use event::KeyChord;
pub use event::KeyModifiers;
pub use event::KeyPress;
pub use event::PointerButton;
pub use event::UiEvent;
pub use event::UiEventKind;
pub use event::UiKey;
pub use event::UiTarget;
pub use focus::focus_order;
pub use hit_test::hit_test;
pub use hit_test::hit_test_target;
pub use icons::IconStroke;
pub use icons::all_icon_names;
pub use icons::icon;
pub use icons::icon_path;
pub use icons::icon_strokes;
pub use icons::icon_vector_asset;
pub use ir::DrawOp;
pub use ir::TextAnchor;
pub use layout::LayoutCtx;
pub use layout::LayoutFn;
pub use layout::VirtualAnchorPolicy;
pub use layout::VirtualItems;
pub use layout::VirtualMode;
pub use layout::layout;
pub use math::MathAtom;
pub use math::MathDisplay;
pub use math::MathExpr;
pub use math::MathLayout;
pub use math::MathParseError;
pub use math::layout_math;
pub use math::parse_mathml;
pub use math::parse_mathml_with_display;
pub use math::parse_tex;
pub use metrics::ComponentSize;
pub use metrics::MetricsRole;
pub use metrics::ThemeMetrics;
pub use shader::ShaderBinding;
pub use shader::ShaderHandle;
pub use shader::StockShader;
pub use shader::UniformBlock;
pub use shader::UniformValue;
pub use state::AnimationMode;
pub use state::UiState;
pub use state::WidgetState;
pub use style::StyleProfile;
pub use surface::AppTexture;
pub use surface::AppTextureBackend;
pub use surface::AppTextureId;
pub use surface::SurfaceAlpha;
pub use surface::SurfaceFormat;
pub use surface::SurfaceSource;
pub use surface::next_app_texture_id;
pub use svg_icon::IconSource;
pub use svg_icon::IntoIconSource;
pub use svg_icon::SvgIcon;
pub use svg_icon::SvgIconPaintMode;
pub use palette::Palette;
pub use selection::Selection;
pub use selection::SelectionPoint;
pub use selection::SelectionRange;
pub use selection::selected_text;
pub use text::metrics::MeasuredText;
pub use text::metrics::TextGeometry;
pub use text::metrics::TextHit;
pub use text::metrics::TextLayout;
pub use text::metrics::TextLine;
pub use text::metrics::caret_xy;
pub use text::metrics::caret_xy_with_family;
pub use text::metrics::hit_text;
pub use text::metrics::hit_text_with_family;
pub use text::metrics::layout_text;
pub use text::metrics::layout_text_with_family;
pub use text::metrics::layout_text_with_line_height_and_family;
pub use text::metrics::line_height;
pub use text::metrics::line_width;
pub use text::metrics::line_width_with_family;
pub use text::metrics::measure_text;
pub use text::metrics::selection_rects;
pub use text::metrics::selection_rects_with_family;
pub use text::metrics::wrap_lines;
pub use text::metrics::wrap_lines_with_family;
pub use theme::Theme;
pub use tree::Align;
pub use tree::Axis;
pub use tree::Color;
pub use tree::Corners;
pub use tree::El;
pub use tree::FontFamily;
pub use tree::FontWeight;
pub use tree::IconName;
pub use tree::InteractionState;
pub use tree::Justify;
pub use tree::Kind;
pub use tree::Rect;
pub use tree::Sides;
pub use tree::Size;
pub use tree::Source;
pub use tree::SurfaceRole;
pub use tree::TextAlign;
pub use tree::TextOverflow;
pub use tree::TextRole;
pub use tree::TextWrap;
pub use tree::column;
pub use tree::divider;
pub use tree::hard_break;
pub use tree::math;
pub use tree::math_block;
pub use tree::math_inline;
pub use tree::row;
pub use tree::scroll;
pub use tree::spacer;
pub use tree::stack;
pub use tree::surface;
pub use tree::text_runs;
pub use tree::vector;
pub use tree::virtual_list;
pub use tree::virtual_list_dyn;
pub use vector::IconMaterial;
pub use vector::VectorRenderMode;
pub use widgets::accordion::AccordionAction;
pub use widgets::accordion::accordion;
pub use widgets::accordion::accordion_content;
pub use widgets::accordion::accordion_item;
pub use widgets::accordion::accordion_item_key;
pub use widgets::accordion::accordion_separator;
pub use widgets::accordion::accordion_trigger;
pub use widgets::accordion::accordion_trigger_with_icon;
pub use widgets::alert::alert;
pub use widgets::alert::alert_description;
pub use widgets::alert::alert_title;
pub use widgets::avatar::DEFAULT_AVATAR_SIZE;
pub use widgets::avatar::avatar_fallback;
pub use widgets::avatar::avatar_image;
pub use widgets::avatar::avatar_initials;
pub use widgets::badge::badge;
pub use widgets::blockquote::blockquote;
pub use widgets::breadcrumb::breadcrumb;
pub use widgets::breadcrumb::breadcrumb_item;
pub use widgets::breadcrumb::breadcrumb_list;
pub use widgets::breadcrumb::breadcrumb_page;
pub use widgets::breadcrumb::breadcrumb_separator;
pub use widgets::button::button;
pub use widgets::button::button_with_icon;
pub use widgets::button::icon_button;
pub use widgets::calendar::CalendarAction;
pub use widgets::calendar::CalendarDay;
pub use widgets::calendar::calendar_day_key;
pub use widgets::calendar::calendar_month;
pub use widgets::card::card;
pub use widgets::card::card_content;
pub use widgets::card::card_description;
pub use widgets::card::card_header;
pub use widgets::card::card_title;
pub use widgets::card::titled_card;
pub use widgets::checkbox::checkbox;
pub use widgets::code_block::code_block;
pub use widgets::code_block::code_block_chrome;
pub use widgets::command::command_group;
pub use widgets::command::command_icon;
pub use widgets::command::command_item;
pub use widgets::command::command_label;
pub use widgets::command::command_row;
pub use widgets::command::command_shortcut;
pub use widgets::dialog::dialog;
pub use widgets::dialog::dialog_content;
pub use widgets::dialog::dialog_description;
pub use widgets::dialog::dialog_header;
pub use widgets::dialog::dialog_title;
pub use widgets::dropdown_menu::dropdown_menu;
pub use widgets::dropdown_menu::dropdown_menu_content;
pub use widgets::dropdown_menu::dropdown_menu_group;
pub use widgets::dropdown_menu::dropdown_menu_icon;
pub use widgets::dropdown_menu::dropdown_menu_item;
pub use widgets::dropdown_menu::dropdown_menu_item_label;
pub use widgets::dropdown_menu::dropdown_menu_item_with_icon;
pub use widgets::dropdown_menu::dropdown_menu_item_with_icon_and_shortcut;
pub use widgets::dropdown_menu::dropdown_menu_item_with_shortcut;
pub use widgets::dropdown_menu::dropdown_menu_label;
pub use widgets::dropdown_menu::dropdown_menu_separator;
pub use widgets::dropdown_menu::dropdown_menu_shortcut;
pub use widgets::editor_tabs::ActiveTabStyle;
pub use widgets::editor_tabs::CloseVisibility;
pub use widgets::editor_tabs::EditorTabsAction;
pub use widgets::editor_tabs::EditorTabsConfig;
pub use widgets::editor_tabs::editor_tab;
pub use widgets::editor_tabs::editor_tab_add_key;
pub use widgets::editor_tabs::editor_tab_close_key;
pub use widgets::editor_tabs::editor_tab_select_key;
pub use widgets::editor_tabs::editor_tabs;
pub use widgets::editor_tabs::editor_tabs_with;
pub use widgets::form::field_row;
pub use widgets::form::form;
pub use widgets::form::form_control;
pub use widgets::form::form_description;
pub use widgets::form::form_item;
pub use widgets::form::form_label;
pub use widgets::form::form_message;
pub use widgets::form::form_section;
pub use widgets::input_otp::input_otp;
pub use widgets::item::item;
pub use widgets::item::item_actions;
pub use widgets::item::item_content;
pub use widgets::item::item_description;
pub use widgets::item::item_group;
pub use widgets::item::item_header;
pub use widgets::item::item_media;
pub use widgets::item::item_media_icon;
pub use widgets::item::item_separator;
pub use widgets::item::item_title;
pub use widgets::list::bullet_list;
pub use widgets::list::numbered_list;
pub use widgets::list::numbered_list_from;
pub use widgets::list::task_list;
pub use widgets::menubar::MenubarAction;
pub use widgets::menubar::menubar;
pub use widgets::menubar::menubar_content;
pub use widgets::menubar::menubar_group;
pub use widgets::menubar::menubar_icon;
pub use widgets::menubar::menubar_item;
pub use widgets::menubar::menubar_item_label;
pub use widgets::menubar::menubar_item_with_icon;
pub use widgets::menubar::menubar_item_with_icon_and_shortcut;
pub use widgets::menubar::menubar_item_with_shortcut;
pub use widgets::menubar::menubar_label;
pub use widgets::menubar::menubar_menu;
pub use widgets::menubar::menubar_separator;
pub use widgets::menubar::menubar_shortcut;
pub use widgets::menubar::menubar_trigger;
pub use widgets::menubar::menubar_trigger_key;
pub use widgets::numeric_input::NumericInputOpts;
pub use widgets::numeric_input::numeric_input;
pub use widgets::overlay::modal;
pub use widgets::overlay::modal_panel;
pub use widgets::overlay::overlay;
pub use widgets::overlay::overlays;
pub use widgets::overlay::scrim;
pub use widgets::pagination::pagination;
pub use widgets::pagination::pagination_content;
pub use widgets::pagination::pagination_ellipsis;
pub use widgets::pagination::pagination_item;
pub use widgets::pagination::pagination_next;
pub use widgets::pagination::pagination_previous;
pub use widgets::popover::Anchor;
pub use widgets::popover::Side;
pub use widgets::popover::anchor_rect;
pub use widgets::popover::context_menu;
pub use widgets::popover::dropdown;
pub use widgets::popover::menu_item;
pub use widgets::popover::popover;
pub use widgets::popover::popover_panel;
pub use widgets::progress::progress;
pub use widgets::radio::RadioAction;
pub use widgets::radio::radio_group;
pub use widgets::radio::radio_item;
pub use widgets::radio::radio_option_key;
pub use widgets::select::SelectAction;
pub use widgets::select::select_menu;
pub use widgets::select::select_option_key;
pub use widgets::select::select_trigger;
pub use widgets::separator::separator;
pub use widgets::separator::vertical_separator;
pub use widgets::sheet::SheetSide;
pub use widgets::sheet::sheet;
pub use widgets::sheet::sheet_content;
pub use widgets::sheet::sheet_description;
pub use widgets::sheet::sheet_header;
pub use widgets::sheet::sheet_title;
pub use widgets::sidebar::sidebar;
pub use widgets::sidebar::sidebar_group;
pub use widgets::sidebar::sidebar_group_label;
pub use widgets::sidebar::sidebar_header;
pub use widgets::sidebar::sidebar_menu;
pub use widgets::sidebar::sidebar_menu_button;
pub use widgets::sidebar::sidebar_menu_button_with_icon;
pub use widgets::sidebar::sidebar_menu_item;
pub use widgets::sidebar::sidebar_menu_label;
pub use widgets::skeleton::skeleton;
pub use widgets::skeleton::skeleton_circle;
pub use widgets::slider::SliderAction;
pub use widgets::slider::slider;
pub use widgets::switch::switch;
pub use widgets::table::table;
pub use widgets::table::table_body;
pub use widgets::table::table_cell;
pub use widgets::table::table_head;
pub use widgets::table::table_head_el;
pub use widgets::table::table_header;
pub use widgets::table::table_row;
pub use widgets::tabs::TabsAction;
pub use widgets::tabs::tab_option_key;
pub use widgets::tabs::tab_trigger;
pub use widgets::tabs::tab_trigger_content;
pub use widgets::tabs::tabs_list;
pub use widgets::tabs::tabs_list_from_triggers;
pub use widgets::text::h1;
pub use widgets::text::h2;
pub use widgets::text::h3;
pub use widgets::text::mono;
pub use widgets::text::paragraph;
pub use widgets::text::text;
pub use widgets::text_area::text_area;
pub use widgets::text_input::ClipboardKind;
pub use widgets::text_input::MaskMode;
pub use widgets::text_input::TextInputOpts;
pub use widgets::text_input::TextSelection;
pub use widgets::text_input::text_input;
pub use widgets::text_input::text_input_with;
pub use widgets::toggle::ToggleAction;
pub use widgets::toggle::toggle;
pub use widgets::toggle::toggle_group;
pub use widgets::toggle::toggle_group_multi;
pub use widgets::toggle::toggle_item;
pub use widgets::toggle::toggle_option_key;
pub use widgets::toolbar::toolbar;
pub use widgets::toolbar::toolbar_description;
pub use widgets::toolbar::toolbar_group;
pub use widgets::toolbar::toolbar_title;

Modules§

affine
2D affine transforms.
anim
Animation primitives.
bundle
Artifact pipeline — the agent loop’s feedback channel.
clipboard
Backend-neutral clipboard helpers for host integrations.
cursor
Pointer-cursor model.
draw_ops
Tree → DrawOp resolution.
event
Event types and the App trait.
focus
Linear focus traversal — collects the focusable keyed nodes into the order Tab/Shift-Tab walks. Ancestors with clip shrink the visible rect so a focusable that’s been scrolled out of view is dropped.
hit_test
Pointer hit-testing and scroll routing on a laid-out tree.
icon_msdf
MSDF generation for vector icons.
icon_msdf_atlas
Icon MTSDF atlas — backs the MSDF icon rendering path.
icons
Built-in vector icons.
image
App-supplied raster images.
ir
Backend-neutral draw-op IR.
layout
Flex-style layout pass over the El tree.
math
Native math expression IR and box layout.
metrics
Component sizing vocabulary.
palette
Runtime color palette — the swappable rgba backing for color tokens.
prelude
App and widget author prelude.
profile
Span-tracing primitives gated behind the profiling Cargo feature.
scroll
App-side scroll request types.
selection
Library-level text selection model.
shader
Shader handles, uniform values, and bindings.
state
UiState — the renderer’s interaction-state side store.
style
Style modifier methods on El — kind-aware via StyleProfile.
surface
App-owned GPU textures composited into the paint stream.
svg_icon
App-supplied SVG icons.
text
Text shaping + atlas infrastructure. The unified RGBA glyph atlas (color emoji + outline glyphs) lives in atlas; line measurement, wrapping, and the TextLayout value backends consume live in metrics.
theme
Theme-level shader routing.
toast
Runtime-synthesized toast notifications.
tokens
Design tokens — the named, finite vocabulary of values everything else refers to.
tooltip
Hover-driven tooltips.
tree
The El tree — the central data structure.
vector
Backend-agnostic SVG/vector asset IR.
widgets
Stock widget vocabulary — reach for these before composing column / row / button / text by hand.

Macros§

profile_span
Enter a span for the rest of the current scope. No-op unless the profiling feature is enabled. Pass a &'static str literal — the macro forwards it to tracing::trace_span! (or to a () binding when off).