Make Disclosure accept an ID (#3701)

This PR makes the `Disclosure` component accept an ID rather than using
a static ID for all disclosures.

Release Notes:

- N/A
This commit is contained in:
Marshall Bowers 2023-12-18 15:21:04 -05:00 committed by GitHub
parent 4fdf6a867a
commit 9785481aba
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 53 additions and 46 deletions

View file

@ -4,13 +4,15 @@ use crate::{prelude::*, Color, Icon, IconButton, IconSize};
#[derive(IntoElement)]
pub struct Disclosure {
id: ElementId,
is_open: bool,
on_toggle: Option<Box<dyn Fn(&ClickEvent, &mut WindowContext) + 'static>>,
}
impl Disclosure {
pub fn new(is_open: bool) -> Self {
pub fn new(id: impl Into<ElementId>, is_open: bool) -> Self {
Self {
id: id.into(),
is_open,
on_toggle: None,
}
@ -30,7 +32,7 @@ impl RenderOnce for Disclosure {
fn render(self, _cx: &mut WindowContext) -> Self::Rendered {
IconButton::new(
"toggle",
self.id,
match self.is_open {
true => Icon::ChevronDown,
false => Icon::ChevronRight,

View file

@ -1,5 +1,6 @@
use gpui::{AnyElement, ClickEvent, Div, Stateful};
use crate::{h_stack, prelude::*, Disclosure, Label};
use gpui::{AnyElement, ClickEvent, Div};
#[derive(IntoElement)]
pub struct ListHeader {
@ -75,48 +76,52 @@ impl Selectable for ListHeader {
}
impl RenderOnce for ListHeader {
type Rendered = Div;
type Rendered = Stateful<Div>;
fn render(self, cx: &mut WindowContext) -> Self::Rendered {
h_stack().w_full().relative().group("list_header").child(
div()
.h_7()
.when(self.inset, |this| this.px_2())
.when(self.selected, |this| {
this.bg(cx.theme().colors().ghost_element_selected)
})
.flex()
.flex_1()
.items_center()
.justify_between()
.w_full()
.gap_1()
.child(
h_stack()
.gap_1()
.children(
self.toggle
.map(|is_open| Disclosure::new(is_open).on_toggle(self.on_toggle)),
)
.child(
div()
.flex()
.gap_1()
.items_center()
.children(self.start_slot)
.child(Label::new(self.label.clone()).color(Color::Muted)),
),
)
.child(h_stack().children(self.end_slot))
.when_some(self.end_hover_slot, |this, end_hover_slot| {
this.child(
div()
.absolute()
.right_0()
.visible_on_hover("list_header")
.child(end_hover_slot),
h_stack()
.id(self.label.clone())
.w_full()
.relative()
.group("list_header")
.child(
div()
.h_7()
.when(self.inset, |this| this.px_2())
.when(self.selected, |this| {
this.bg(cx.theme().colors().ghost_element_selected)
})
.flex()
.flex_1()
.items_center()
.justify_between()
.w_full()
.gap_1()
.child(
h_stack()
.gap_1()
.children(self.toggle.map(|is_open| {
Disclosure::new("toggle", is_open).on_toggle(self.on_toggle)
}))
.child(
div()
.flex()
.gap_1()
.items_center()
.children(self.start_slot)
.child(Label::new(self.label.clone()).color(Color::Muted)),
),
)
}),
)
.child(h_stack().children(self.end_slot))
.when_some(self.end_hover_slot, |this, end_hover_slot| {
this.child(
div()
.absolute()
.right_0()
.visible_on_hover("list_header")
.child(end_hover_slot),
)
}),
)
}
}

View file

@ -193,7 +193,7 @@ impl RenderOnce for ListItem {
.absolute()
.left(rems(-1.))
.when(is_open, |this| this.visible_on_hover(""))
.child(Disclosure::new(is_open).on_toggle(self.on_toggle))
.child(Disclosure::new("toggle", is_open).on_toggle(self.on_toggle))
}))
.child(
h_stack()

View file

@ -13,8 +13,8 @@ impl Render for DisclosureStory {
Story::container()
.child(Story::title_for::<Disclosure>())
.child(Story::label("Toggled"))
.child(Disclosure::new(true))
.child(Disclosure::new("toggled", true))
.child(Story::label("Not Toggled"))
.child(Disclosure::new(false))
.child(Disclosure::new("not_toggled", false))
}
}