Rework Disclosure component

This commit is contained in:
Marshall Bowers 2023-11-29 14:07:48 -05:00
parent e99fa77bda
commit 6f5cc0af94
6 changed files with 76 additions and 27 deletions

View file

@ -16,6 +16,7 @@ pub enum ComponentStory {
Button, Button,
Checkbox, Checkbox,
ContextMenu, ContextMenu,
Disclosure,
Focus, Focus,
Icon, Icon,
IconButton, IconButton,
@ -36,6 +37,7 @@ impl ComponentStory {
Self::Button => cx.build_view(|_| ui::ButtonStory).into(), Self::Button => cx.build_view(|_| ui::ButtonStory).into(),
Self::Checkbox => cx.build_view(|_| ui::CheckboxStory).into(), Self::Checkbox => cx.build_view(|_| ui::CheckboxStory).into(),
Self::ContextMenu => cx.build_view(|_| ui::ContextMenuStory).into(), Self::ContextMenu => cx.build_view(|_| ui::ContextMenuStory).into(),
Self::Disclosure => cx.build_view(|_| ui::DisclosureStory).into(),
Self::Focus => FocusStory::view(cx).into(), Self::Focus => FocusStory::view(cx).into(),
Self::Icon => cx.build_view(|_| ui::IconStory).into(), Self::Icon => cx.build_view(|_| ui::IconStory).into(),
Self::IconButton => cx.build_view(|_| ui::IconButtonStory).into(), Self::IconButton => cx.build_view(|_| ui::IconButtonStory).into(),

View file

@ -1,30 +1,55 @@
use std::rc::Rc; use std::rc::Rc;
use gpui::{div, ClickEvent, Element, IntoElement, ParentElement, WindowContext}; use gpui::{ClickEvent, Div};
use crate::prelude::*;
use crate::{Color, Icon, IconButton, IconSize, Toggle}; use crate::{Color, Icon, IconButton, IconSize, Toggle};
pub fn disclosure_control( #[derive(IntoElement)]
pub struct Disclosure {
toggle: Toggle, toggle: Toggle,
on_toggle: Option<Rc<dyn Fn(&ClickEvent, &mut WindowContext) + 'static>>, on_toggle: Option<Rc<dyn Fn(&ClickEvent, &mut WindowContext) + 'static>>,
) -> impl Element { }
match (toggle.is_toggleable(), toggle.is_toggled()) {
(false, _) => div(), impl Disclosure {
(_, true) => div().child( pub fn new(toggle: Toggle) -> Self {
IconButton::new("toggle", Icon::ChevronDown) Self {
.color(Color::Muted) toggle,
.size(IconSize::Small) on_toggle: None,
.when_some(on_toggle, move |el, on_toggle| { }
el.on_click(move |e, cx| on_toggle(e, cx)) }
}),
), pub fn on_toggle(
(_, false) => div().child( mut self,
IconButton::new("toggle", Icon::ChevronRight) handler: impl Into<Option<Rc<dyn Fn(&ClickEvent, &mut WindowContext) + 'static>>>,
.color(Color::Muted) ) -> Self {
.size(IconSize::Small) self.on_toggle = handler.into();
.when_some(on_toggle, move |el, on_toggle| { self
el.on_click(move |e, cx| on_toggle(e, cx)) }
}), }
),
impl RenderOnce for Disclosure {
type Rendered = Div;
fn render(self, _cx: &mut WindowContext) -> Self::Rendered {
if !self.toggle.is_toggleable() {
return div();
}
div().child(
IconButton::new(
"toggle",
if self.toggle.is_toggled() {
Icon::ChevronDown
} else {
Icon::ChevronRight
},
)
.color(Color::Muted)
.size(IconSize::Small)
.when_some(self.on_toggle, move |this, on_toggle| {
this.on_click(move |event, cx| on_toggle(event, cx))
}),
)
} }
} }

View file

@ -3,7 +3,7 @@ use std::rc::Rc;
use gpui::{ClickEvent, Div}; use gpui::{ClickEvent, Div};
use crate::prelude::*; use crate::prelude::*;
use crate::{disclosure_control, h_stack, Icon, IconButton, IconElement, IconSize, Label, Toggle}; use crate::{h_stack, Disclosure, Icon, IconButton, IconElement, IconSize, Label, Toggle};
pub enum ListHeaderMeta { pub enum ListHeaderMeta {
Tools(Vec<IconButton>), Tools(Vec<IconButton>),
@ -73,8 +73,6 @@ impl RenderOnce for ListHeader {
type Rendered = Div; type Rendered = Div;
fn render(self, cx: &mut WindowContext) -> Self::Rendered { fn render(self, cx: &mut WindowContext) -> Self::Rendered {
let disclosure_control = disclosure_control(self.toggle, self.on_toggle);
let meta = match self.meta { let meta = match self.meta {
Some(ListHeaderMeta::Tools(icons)) => div().child( Some(ListHeaderMeta::Tools(icons)) => div().child(
h_stack() h_stack()
@ -115,7 +113,7 @@ impl RenderOnce for ListHeader {
})) }))
.child(Label::new(self.label.clone()).color(Color::Muted)), .child(Label::new(self.label.clone()).color(Color::Muted)),
) )
.child(disclosure_control), .child(Disclosure::new(self.toggle).on_toggle(self.on_toggle)),
) )
.child(meta), .child(meta),
) )

View file

@ -6,7 +6,7 @@ use gpui::{
use smallvec::SmallVec; use smallvec::SmallVec;
use crate::prelude::*; use crate::prelude::*;
use crate::{disclosure_control, Avatar, GraphicSlot, Icon, IconElement, IconSize, Toggle}; use crate::{Avatar, Disclosure, GraphicSlot, Icon, IconElement, IconSize, Toggle};
#[derive(IntoElement)] #[derive(IntoElement)]
pub struct ListItem { pub struct ListItem {
@ -150,7 +150,7 @@ impl RenderOnce for ListItem {
.gap_1() .gap_1()
.items_center() .items_center()
.relative() .relative()
.child(disclosure_control(self.toggle, self.on_toggle)) .child(Disclosure::new(self.toggle).on_toggle(self.on_toggle))
.map(|this| match self.left_slot { .map(|this| match self.left_slot {
Some(GraphicSlot::Icon(i)) => this.child( Some(GraphicSlot::Icon(i)) => this.child(
IconElement::new(i) IconElement::new(i)

View file

@ -2,6 +2,7 @@ mod avatar;
mod button; mod button;
mod checkbox; mod checkbox;
mod context_menu; mod context_menu;
mod disclosure;
mod icon; mod icon;
mod icon_button; mod icon_button;
mod keybinding; mod keybinding;
@ -13,6 +14,7 @@ pub use avatar::*;
pub use button::*; pub use button::*;
pub use checkbox::*; pub use checkbox::*;
pub use context_menu::*; pub use context_menu::*;
pub use disclosure::*;
pub use icon::*; pub use icon::*;
pub use icon_button::*; pub use icon_button::*;
pub use keybinding::*; pub use keybinding::*;

View file

@ -0,0 +1,22 @@
use gpui::{Div, Render};
use story::Story;
use crate::prelude::*;
use crate::{Disclosure, Toggle};
pub struct DisclosureStory;
impl Render for DisclosureStory {
type Element = Div;
fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Element {
Story::container()
.child(Story::title_for::<Disclosure>())
.child(Story::label("Toggled"))
.child(Disclosure::new(Toggle::Toggled(true)))
.child(Story::label("Not Toggled"))
.child(Disclosure::new(Toggle::Toggled(false)))
.child(Story::label("Not Toggleable"))
.child(Disclosure::new(Toggle::NotToggleable))
}
}