Detailed changes
@@ -16,6 +16,7 @@ pub enum ComponentStory {
Button,
Checkbox,
ContextMenu,
+ Disclosure,
Focus,
Icon,
IconButton,
@@ -36,6 +37,7 @@ impl ComponentStory {
Self::Button => cx.build_view(|_| ui::ButtonStory).into(),
Self::Checkbox => cx.build_view(|_| ui::CheckboxStory).into(),
Self::ContextMenu => cx.build_view(|_| ui::ContextMenuStory).into(),
+ Self::Disclosure => cx.build_view(|_| ui::DisclosureStory).into(),
Self::Focus => FocusStory::view(cx).into(),
Self::Icon => cx.build_view(|_| ui::IconStory).into(),
Self::IconButton => cx.build_view(|_| ui::IconButtonStory).into(),
@@ -1,30 +1,55 @@
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};
-pub fn disclosure_control(
+#[derive(IntoElement)]
+pub struct Disclosure {
toggle: Toggle,
on_toggle: Option<Rc<dyn Fn(&ClickEvent, &mut WindowContext) + 'static>>,
-) -> impl Element {
- match (toggle.is_toggleable(), toggle.is_toggled()) {
- (false, _) => div(),
- (_, true) => div().child(
- IconButton::new("toggle", Icon::ChevronDown)
- .color(Color::Muted)
- .size(IconSize::Small)
- .when_some(on_toggle, move |el, on_toggle| {
- el.on_click(move |e, cx| on_toggle(e, cx))
- }),
- ),
- (_, false) => div().child(
- IconButton::new("toggle", Icon::ChevronRight)
- .color(Color::Muted)
- .size(IconSize::Small)
- .when_some(on_toggle, move |el, on_toggle| {
- el.on_click(move |e, cx| on_toggle(e, cx))
- }),
- ),
+}
+
+impl Disclosure {
+ pub fn new(toggle: Toggle) -> Self {
+ Self {
+ toggle,
+ on_toggle: None,
+ }
+ }
+
+ pub fn on_toggle(
+ mut self,
+ handler: impl Into<Option<Rc<dyn Fn(&ClickEvent, &mut WindowContext) + 'static>>>,
+ ) -> Self {
+ self.on_toggle = handler.into();
+ self
+ }
+}
+
+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))
+ }),
+ )
}
}
@@ -3,7 +3,7 @@ use std::rc::Rc;
use gpui::{ClickEvent, Div};
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 {
Tools(Vec<IconButton>),
@@ -73,8 +73,6 @@ impl RenderOnce for ListHeader {
type Rendered = Div;
fn render(self, cx: &mut WindowContext) -> Self::Rendered {
- let disclosure_control = disclosure_control(self.toggle, self.on_toggle);
-
let meta = match self.meta {
Some(ListHeaderMeta::Tools(icons)) => div().child(
h_stack()
@@ -115,7 +113,7 @@ impl RenderOnce for ListHeader {
}))
.child(Label::new(self.label.clone()).color(Color::Muted)),
)
- .child(disclosure_control),
+ .child(Disclosure::new(self.toggle).on_toggle(self.on_toggle)),
)
.child(meta),
)
@@ -6,7 +6,7 @@ use gpui::{
use smallvec::SmallVec;
use crate::prelude::*;
-use crate::{disclosure_control, Avatar, GraphicSlot, Icon, IconElement, IconSize, Toggle};
+use crate::{Avatar, Disclosure, GraphicSlot, Icon, IconElement, IconSize, Toggle};
#[derive(IntoElement)]
pub struct ListItem {
@@ -150,7 +150,7 @@ impl RenderOnce for ListItem {
.gap_1()
.items_center()
.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 {
Some(GraphicSlot::Icon(i)) => this.child(
IconElement::new(i)
@@ -2,6 +2,7 @@ mod avatar;
mod button;
mod checkbox;
mod context_menu;
+mod disclosure;
mod icon;
mod icon_button;
mod keybinding;
@@ -13,6 +14,7 @@ pub use avatar::*;
pub use button::*;
pub use checkbox::*;
pub use context_menu::*;
+pub use disclosure::*;
pub use icon::*;
pub use icon_button::*;
pub use keybinding::*;
@@ -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))
+ }
+}