limn
    ↑↓ ChooseEnter OpenEsc Close
    GitHub

    Components/Data

    Attachment

    A card for a file or an image attached to a message or a draft: an icon or a preview, a title and a description, and optionally a button that removes it.

    Native componentGuide source

    Preview

    CodeSource
    fn view(state: &State, palette: ComponentPalette) -> Element {
        Attachment::new("notes", "notes.md", palette)
            .description("Markdown · 2 KB")
            .remove_action("notes-remove")
            .render()
    }
    
    fn update(state: &mut State, action: &UiAction) {
        if let UiAction::Clicked { id } = action {
            if id == "notes-remove" {
                state.detach("notes");
            }
        }
    }

    Examples

    Each one is the library drawing it. Press, type and hover.

    Attachment2 / 3
    CodeSource
    row(vec![
        Attachment::new("media-open-card", "quarterly-report-2026-final-reviewed.pdf", palette)
            .description("PDF · 1.2 MB")
            .help("Shared by Ada on Monday")
            .open_action("media-opened=quarterly-report-2026-final-reviewed.pdf")
            .render(),
        Attachment::new("media-plain-card", "a-long-file-name-that-does-not-fit.txt", palette)
            .description("Text · 640 B")
            .width(160.0)
            .render(),
    ])
    Attachment3 / 3
    CodeSource
    fit(cx, 500.0, vec![
        Attachment::new("media-image-row", PICTURES[0].0, palette)
            .description("PNG · 528 B")
            .preview(picture(0).cover())
            .render(),
        Attachment::new("media-image-column", PICTURES[1].0, palette)
            .description("PNG · 546 B")
            .preview(picture(1).cover())
            .orientation(AttachmentOrientation::Vertical)
            .remove_action("media-image-column-remove")
            .width(160.0)
            .render(),
        Attachment::new("media-image-only", PICTURES[2].0, palette)
            .description("PNG · 436 B")
            .preview(picture(2).cover())
            .preview_only()
            .width(Attachment::PREVIEW_SIZE)
            .render(),
    ])

    Attachment

    A card for a file or an image attached to a message or a draft: an icon or a preview, a title and a description, and optionally a button that removes it.

    Import

    use limn::{Attachment, AttachmentOrientation, Component};

    Usage

    An attachment takes an ID, a title and the palette. The host owns the file: the card shows what it is given and reports the actions the host names.

    fn view(state: &State, palette: ComponentPalette) -> Element {
        Attachment::new("notes", "notes.md", palette)
            .description("Markdown · 2 KB")
            .remove_action("notes-remove")
            .render()
    }
    
    fn update(state: &mut State, action: &UiAction) {
        if let UiAction::Clicked { id } = action {
            if id == "notes-remove" {
                state.detach("notes");
            }
        }
    }

    The title and the description take one line each and are cut with an ellipsis. Hovering them shows the title in full over the description.

    Icon and preview

    Attachment::new("take", "take-04.wav", palette).icon(Icon::Audio).render()
    Attachment::new("photo", "dusk.png", palette).preview(picture).render()

    icon replaces the file glyph. preview takes a RasterImage and shows it in the icon’s place.

    Remove and open

    remove_action(id) adds a close button that reports that ID. open_action(id) makes the whole card a button that reports that ID, with the title and the description as its hint.

    Attachment::new("report", "report.pdf", palette)
        .description("PDF · 1.2 MB")
        .help("Shared by Ada on Monday")
        .open_action("report-open")
        .render()

    help is the text of the hint, in place of the description.

    Orientation

    Attachment::new("photo", "dusk.png", palette)
        .preview(picture)
        .orientation(AttachmentOrientation::Vertical)
        .render()

    AttachmentOrientation::Horizontal, the default, puts the icon or preview beside the caption in a card Attachment::FILE_HEIGHT (64) high. Vertical puts it above the caption in a card Attachment::IMAGE_HEIGHT (140) high, with the remove button over its top corner.

    Preview only

    Attachment::new("photo", "dusk.png", palette)
        .preview(picture)
        .preview_only()
        .width(Attachment::PREVIEW_SIZE)
        .render()

    preview_only draws a square of the card’s width with the preview alone; the title and the description stay in its hint. It sets the vertical orientation, and a later orientation brings the caption back.

    Width

    width fixes the card’s width, never under 80; the default is 220. A width that is not finite is ignored.

    Actions

    ActionWhen
    UiAction::Clicked { id } with the remove IDThe close button is clicked.
    UiAction::Clicked { id } with the open IDThe card is clicked.

    Accessibility

    With an open action the card is a button named by its title and described by help, or by the description without one. The remove button is named for what it removes, as “Remove notes.md”.

    API reference

    The guide covers composition, options and actions. Generate the complete Rust type and builder reference from the checkout:

    cargo doc -p limn --open

    Component API overview · State and actions

    The example is drawn by crates/limn-gallery/src/pages/media.rs.