Skip to content
PorabuildHeroGPUI component library
v0.14.0 · Apache-2.0

Navigation

Disclosure

A single collapsible section.

Rust
use herogpui::components::disclosure::{Disclosure, DisclosureGroup};

Disclosure on docs.rsSource at v0.14.0

Usage

Showing Usage, live: HeroGPUI compiled to WebAssembly. The canvas has no accessibility tree; each example's description and code below carry the same information.

Usage

The measured panel animates height and opacity over 200ms and stays mounted until the close transition completes. An element expression with window: &mut Window and cx: &mut App in scope.

Rust
use herogpui::prelude::{Disclosure, DisclosureGroup};
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;

gpui::div()
    .flex()
    .flex_col()
    .items_start()
    .justify_center()
    .gap(px(12.))
    .children(vec![Disclosure::new(
        "disclosure-usage",
        "Shipping details"
    )
    .child(gpui::div().child("Ships in 2-4 business days."))
    .into_any_element()])

Render Function

The body is built from the Disclosure's current expanded and disabled state. Runs in a view's render: self is the view holding this example's state and cx is its Context<Self>.

Rust
use herogpui::prelude::{Disclosure, DisclosureGroup};
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;

{
    let render_expanded = self.demo_flag("disclosure-render", true);
    gpui::div()
        .flex()
        .flex_col()
        .items_start()
        .justify_center()
        .gap(px(12.))
        .children(vec![Disclosure::new("disclosure-render", "Account details")
                .is_expanded(render_expanded)
                .on_expanded_change(cx.listener(
                    |this, value: &bool, _, cx| {
                        this.set_demo_flag("disclosure-render", *value);
                        cx.notify();
                    },
                ))
                .content(|state| {
                    gpui::div()
                        .child(format!(
                            "The render closure received is_expanded={} and is_disabled={}.",
                            state.is_expanded, state.is_disabled
                        ))
                        .into_any_element()
                })
                .into_any_element()])
        .into_any_element()
}

Controlled

Runs in a view's render: self is the view holding this example's state and cx is its Context<Self>.

Rust
use herogpui::prelude::{ActiveTheme, Disclosure, DisclosureGroup};
use herogpui::gpui::prelude::*;
use herogpui::gpui::{App, SharedString, px};
use herogpui::gpui;
use std::collections::HashSet;

let group = self.disclosure_group_expanded.clone();

gpui::div()
    .flex()
    .flex_col()
    .items_start()
    .justify_center()
    .gap(px(12.))
    .children(vec![
        DisclosureGroup::new("disclosure-controlled")
            .item("returns", "Returns", gpui::div().child("Thirty days."))
            .item("warranty", "Warranty", gpui::div().child("Two years."))
            .expanded_keys(group.clone())
            .on_expanded_change(cx.listener(
                |this, keys: &HashSet<SharedString>, _, cx| {
                    this.disclosure_group_expanded = keys.clone();
                    cx.notify();
                },
            ))
            .into_any_element(),
        para(&format!("{} expanded", group.len()), cx),
    ])

Also calls para (included when you copy).

Single

Runs in a view's render: self is the view holding this example's state and cx is its Context<Self>.

Rust
use herogpui::prelude::{Disclosure, DisclosureGroup};
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;

let expanded = self.disclosure_expanded;

gpui::div()
    .flex()
    .flex_col()
    .items_start()
    .justify_center()
    .gap(px(12.))
    .children(vec![Disclosure::new(
        "disclosure-single",
        "Shipping details"
    )
    .is_expanded(expanded)
    .on_expanded_change(cx.listener(|this, v: &bool, _, cx| {
        this.disclosure_expanded = *v;
        cx.notify();
    }))
    .child(gpui::div().child("Ships in 2-4 business days."))
    .into_any_element()])

Group

An element expression with window: &mut Window and cx: &mut App in scope.

Rust
use herogpui::prelude::{Disclosure, DisclosureGroup};
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;

gpui::div()
    .flex()
    .flex_col()
    .items_start()
    .justify_center()
    .gap(px(12.))
    .children(vec![DisclosureGroup::new("disclosure-group")
        .item(
            "item-1",
            "Returns",
            gpui::div().child("Free returns within 30 days."),
        )
        .item(
            "item-2",
            "Warranty",
            gpui::div().child("Two years of coverage."),
        )
        .default_expanded_keys(["item-1"])
        .into_any_element()])

Disabled Group

An element expression with window: &mut Window and cx: &mut App in scope.

Rust
use herogpui::prelude::{Disclosure, DisclosureGroup};
use herogpui::gpui::prelude::*;
use herogpui::gpui::px;
use herogpui::gpui;

gpui::div()
    .flex()
    .flex_col()
    .items_start()
    .justify_center()
    .gap(px(12.))
    .children(vec![DisclosureGroup::new("disclosure-disabled-group")
        .item("returns", "Returns", gpui::div().child("Thirty days."))
        .item("warranty", "Warranty", gpui::div().child("Two years."))
        .default_expanded_keys(["returns"])
        .is_disabled(true)
        .into_any_element()])

Helpers used by these examples

Plain functions over the public API, defined once here and copied with each example that calls them.

para
fn para(text: &str, cx: &App) -> gpui::AnyElement {
    let colors = cx.colors();
    gpui::div()
        .text_size(px(14.5))
        .line_height(px(24.))
        .text_color(colors.foreground)
        .max_w(px(720.))
        .child(text.to_owned())
        .into_any_element()
}

Anatomy

Rust types

DisclosureGroupDisclosure

Disclosure is assembled from these builders. The API reference lists each one.

API reference

Against HeroUI v3.2.6: 21 entries ported, 8 partial, 6 not ported. Partial rows are marked in the tables; entries not ported are listed under each table with the reason.

Builders

Disclosure builders
BuilderValuesDefaultDescription
expanded_keys(keys)Set<Key>—The currently expanded items (controlled).
default_expanded_keys(keys)iterable of keys—The initially expanded items (uncontrolled).
on_expanded_change(callback)Fn(keys: Set<Key>) -> ()—Reports the complete next expanded set.
allows_multiple_expanded(bool)true | falsefalseAllows more than one item to remain expanded.
is_disabled(bool)true | falsefalseDisables every disclosure trigger in the group.
item(key, title, content)PartialAnyElement | render closure—Composed disclosure items; GPUI builds keyed items through a typed method.
is_expanded(bool)true | falsefalseControls whether the panel is expanded.
default_expanded(bool)true | falsefalseInitial expanded state when the disclosure owns its state; inherited from pinned.
content(render)PartialAnyElement | render closure—Compound heading, trigger and panel children; the GPUI control builds the trigger and accepts static body children through ParentElement or a state-aware body render closure.
new(id, title)PartialAnyElement | render closure—Custom trigger content; accepts an id and title and builds a HeroGPUI Button.
Not ported6 HeroUI entries not ported
Disclosure builders not ported
HeroUI v3Why it is not ported
DisclosureGroup.className
Disclosure.className
Disclosure.renderRoot substitution has no GPUI equivalent.
Disclosure.Trigger.classNameAdditional trigger classes.
Disclosure.Content.classNameAdditional content classes.
Disclosure.Content.renderRoot substitution has no GPUI equivalent.

Parts

Disclosure parts
PartDescription
DisclosureGroupFull-width owner of the expanded key set.
DisclosureRelative root for one trigger and panel.
DisclosurePartialHeading wrapper is built into the monolithic trigger row.
DisclosurePartialA built-in HeroGPUI Button rather than a separately composable trigger.
DisclosureBuilt-in 16px down-chevron that rotates through 180 degrees as expansion changes.
DisclosureMeasured panel container that stays mounted during the 200ms closing transition.
DisclosureEight-pixel padded body around caller content.

States

Disclosure states
StateBuilderDescription
Expandedis_expanded(bool)Shows the body and rotates the shared down-chevron to its expanded endpoint.
Disabledis_disabled(bool)Disables one trigger or every trigger in the group.
Focus visibleButton tab_stop_handleThe built-in Button owns keyboard focus and its focus ring.
Single expansionallows_multiple_expanded(false)Opening one item replaces the previous expanded set by default.
Multiple expansionallows_multiple_expanded(true)Opt-in mode toggles membership without closing siblings.