gpuicn Components

Component 11 of 60

Collapsible

An interactive panel that expands and collapses.

site/src/previews/collapsible.rs

Starting the preview. GPUI compiles to WebAssembly, so the first load takes a few seconds. This browser has neither WebGPU nor WebGL 2, so the live preview cannot run. The code on this page still works. The preview did not start.

Collapsible, running in the browser. The second tab shows the preview's own source, which includes its layout and demo state. For the smallest working example, see Usage below. Download the whole showcase for its imports and helpers.

Installation

After the one-time setup, run the command from your app root. The CLI writes the modules and keeps src/ui/mod.rs in step.

gpuicn add collapsible

If you prefer to copy the files by hand, declare them yourself:

// src/ui/mod.rs
pub mod theme;
pub mod collapsible;

// src/main.rs
mod ui;

Usage

Put this in a view module and return example(open, window, cx) from its render method.

use crate::ui::collapsible::*;
use gpui_kit::{App, IntoElement, ParentElement, Window};

fn example(open: bool, window: &mut Window, cx: &mut App) -> impl IntoElement {
    collapsible("projects-region", open, window, cx)
        .child(collapsible_trigger("projects", open, cx).child("Recent projects"))
        .content(collapsible_content(cx).child("Design system"))
}

API reference

pub fn collapsible(
    id: impl Into<ElementId>,
    open: bool,
    window: &mut Window,
    cx: &mut App,
) -> Collapsible

Creates a controlled region that reveals and removes its content with theme motion.

pub fn collapsible_trigger(id: impl Into<ElementId>, open: bool, cx: &App) -> Button

Creates an accessible trigger. Update the caller's open state in its click handler.

pub fn collapsible_content(cx: &App) -> Div

Creates the disclosure content's text treatment.

Installed source, 57 lines
//! Nova presentation for GPUI Kit's controlled collapsible region.
use super::theme::UiTheme;
use gpui_kit::base::Button;
pub use gpui_kit::base::Collapsible;
use gpui_kit::{
    App, Div, ElementId, InteractiveElement as _, StatefulInteractiveElement as _, Styled, Window,
    div,
};

/// Creates a controlled region that reveals and removes its content with theme motion.
pub fn collapsible(
    id: impl Into<ElementId>,
    open: bool,
    window: &mut Window,
    cx: &mut App,
) -> Collapsible {
    let id = id.into();
    let presence = super::theme::presence(id.clone(), open, window, cx);
    let visible = presence.should_render() && (open || presence.progress > 0.);
    let mut region = Collapsible::new().open(visible);
    if visible {
        region = region.reveal(id, presence.progress);
    }
    region
        .flex()
        .flex_col()
        .font_family(UiTheme::read(cx).fonts.body.clone())
}
/// Creates an accessible trigger. Update the caller's open state in its click handler.
pub fn collapsible_trigger(id: impl Into<ElementId>, open: bool, cx: &App) -> Button {
    let theme = UiTheme::read(cx);
    let colors = theme.colors;
    Button::new(id)
        .aria_expanded(open)
        .px(theme.space(2.5))
        .py(theme.space(1.5))
        .rounded(theme.radius.lg)
        .border_1()
        .border_color(colors.background.opacity(0.))
        .text_size(theme.text(14.))
        .text_color(colors.foreground)
        .cursor_pointer()
        .hover(move |s| s.bg(colors.muted))
        .focus_visible(move |s| s.border_color(colors.ring))
}
/// Creates the disclosure content's text treatment.
pub fn collapsible_content(cx: &App) -> Div {
    let theme = UiTheme::read(cx);
    div()
        .w_full()
        .pt(theme.space(2.))
        .overflow_hidden()
        .font_family(theme.fonts.body.clone())
        .text_size(theme.text(14.))
        .text_color(theme.colors.foreground)
}

Platform notes

Visual reference: shadcn/ui 4.19.0, Neutral Nova. Implementation: crates/ui/registry/collapsible/collapsible.rs, using GPUI Kit 0.6.4.

The application passes open state and handles the trigger click. Kit supplies the disclosure host and trigger; gpuicn adds Nova spacing and typography.

The Rust source and Usage example define the supported API. Browser DOM/CSS behavior, exact exit animations and cross-platform screen-reader parity are not implied by the native component. See migration qualification for the checks completed on this revision.