limn
    ↑↓ ChooseEnter OpenEsc Close
    GitHub

    Components/Layout

    PanelHeader

    The header row of a panel: a title that takes the width left, the panel's tools after it, and optional back and close buttons at the ends.

    Native componentGuide source

    Preview

    CodeSource
    fn view(palette: ComponentPalette) -> Element {
        PanelHeader::new("Source control", palette)
            .trailing(vec![
                IconButton::new("refresh", Icon::Refresh, palette)
                    .variant(ButtonVariant::Ghost)
                    .size(ControlSize::Dense)
                    .render(),
            ])
            .render()
    }

    Examples

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

    Panel header2 / 4
    CodeSource

    Read the source of this example.

    Panel header3 / 4
    CodeSource

    Read the source of this example.

    Panel header4 / 4
    CodeSource

    Read the source of this example.

    Back, close, and long title1 / 3
    CodeSource
    framed(
        cx,
        width,
        PanelHeader::new("A title too long to fit alongside its tools", palette)
            .back("panel-back", "Back to changes")
            .trailing(vec![
                tool(cx, "panel-long-refresh", Icon::Refresh, "Refresh"),
                Separator::vertical(palette).length(14.0).centered_in(24.0).margin(4.0).render(),
                tool(cx, "panel-long-add", Icon::Add, "Add"),
            ])
            .dismiss("panel-dismiss", "Close")
            .sizing(PanelHeaderSizing::CARD)
            .render(),
    )
    Back, close, and long title2 / 3
    CodeSource
    framed(cx, width, PanelHeader::new("Debugging", palette).render())
    Back, close, and long title3 / 3
    CodeSource
    framed(
        cx,
        width,
        PanelHeader::new("Debugging", palette)
            .trailing(vec![tool(cx, "panel-top-refresh", Icon::Refresh, "Refresh")])
            .sizing(PanelHeaderSizing { center_tools: false, ..PanelHeaderSizing::SIDEBAR })
            .render(),
    )
    A field in place of the title
    CodeSource
    framed(
                cx,
                width,
                PanelHeader::with_leading(
                    TextField::new("panel-address", cx.state.text("panel-address"), "Address…", palette)
                        .size(ControlSize::Compact)
                        .render(),
                    palette,
                )
                    .trailing(vec![tool(cx, "panel-field-more", Icon::More, "More actions")])
                    // A profile of the host's own: room for a 28 px field.
                    .sizing(PanelHeaderSizing { height: 36.0, ..PanelHeaderSizing::PANE })
                    .render(),
            )
    A tint behind the header
    CodeSource
    framed(
        cx,
        width,
        Element::column(vec![
            Text::new("An album", palette).role(TextRole::Heading).render(),
            Text::new("The cover color fades down from the edge into the surface.", palette).muted().render(),
            Element::spacer().size(None, Some(72.0)),
        ])
        .gap(4.0)
        .padding(12.0)
        .top_background_fade(AlertColors::for_tone(AlertTone::Info, palette).accent, 96.0),
    )
    .clip_children()

    PanelHeader

    The header row of a panel: a title that takes the width left, the panel’s tools after it, and optional back and close buttons at the ends.

    Import

    use limn::{Component, PanelHeaderSizing, PanelHeader};

    Usage

    A header needs a title and the palette. The title is cut to one line before the tools. The header decides the height, the inset, the gap and where the tools stand; it paints no fill.

    fn view(palette: ComponentPalette) -> Element {
        PanelHeader::new("Source control", palette)
            .trailing(vec![
                IconButton::new("refresh", Icon::Refresh, palette)
                    .variant(ButtonVariant::Ghost)
                    .size(ControlSize::Dense)
                    .render(),
            ])
            .render()
    }

    Tools

    trailing takes the panel’s tools as a vector of elements, placed after the title. Each tool reports its own action. A rule between two groups is a Separator with a length, in the vector:

    PanelHeader::new("Source control", palette)
        .trailing(vec![
            refresh,
            Separator::vertical(palette).length(14.0).centered_in(24.0).margin(4.0).render(),
            add,
        ])
        .render()

    Back and dismiss

    back(id, tooltip) puts a back arrow before the title and dismiss(id, tooltip) a close button after the tools. Each reports UiAction::Clicked with its ID. Their hints open downward; an empty tooltip shows none.

    fn view(palette: ComponentPalette) -> Element {
        PanelHeader::new("Commit", palette)
            .back("commit-back", "Back to changes")
            .dismiss("commit-close", "Close")
            .render()
    }
    
    fn update(state: &mut State, action: &UiAction) {
        if let UiAction::Clicked { id } = action {
            match id.as_str() {
                "commit-back" => state.show_changes(),
                "commit-close" => state.close_panel(),
                _ => {}
            }
        }
    }

    An element in place of the title

    PanelHeader::with_leading(
        TextField::new("address", &state.address, "Address…", palette)
            .size(ControlSize::Compact)
            .render(),
        palette,
    )
        .sizing(PanelHeaderSizing { height: 36.0, ..PanelHeaderSizing::PANE })
        .render()

    leading puts an element in place of the title, such as a strip of tabs, a breadcrumb or a field. It takes the width the tools leave, and the title is not drawn.

    Sizing

    PanelHeader::new("Commit", palette).sizing(PanelHeaderSizing::CARD).render()
    ProfileForHeightInsetGapTitle
    PanelHeaderSizing::SIDEBARThe heading of a sidebar; the default2602TextRole::Caption
    PanelHeaderSizing::PANEThe bar over a pane, as tall as a tab strip3244TextRole::Caption
    PanelHeaderSizing::CARDThe heading of a card2824TextRole::Body
    PanelHeaderSizing::POPOVERThe heading of a popover2406TextRole::Caption

    The fields are height, padding, gap, title_role and center_tools. Every profile centers the tools in the header’s height; PanelHeaderSizing { center_tools: false, ..PanelHeaderSizing::SIDEBAR } hangs them from the top inset instead.

    Width

    width fixes the header’s width. A non-finite value is ignored.

    A tint behind the header

    The header paints no fill, so a color behind it belongs to its container. Element::top_background_fade(color, height) paints a color from the container’s top edge down that gives way to the surface below it, behind the container’s children. bottom_background_fade does the same from the bottom edge.

    Element::column(vec![header, body])
        .top_background_fade(cover_color, 96.0)

    Actions

    ActionWhen
    UiAction::Clicked { id }The back arrow or the close button is clicked, with the ID given to back or dismiss.

    Accessibility

    The back and close buttons are named by the tooltips given to back and dismiss; with an empty tooltip they have no name. With an id the title is a heading the platform knows by that ID.

    PanelHeader::new("Files", palette)
        .id("files-heading")
        .dismiss("files-close", "Close")
        .render()

    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/panels.rs.