crates/storybook2/src/stories.rs 🔗
@@ -1,2 +1,2 @@
-pub mod elements;
pub mod kitchen_sink;
+pub mod z_index;
Marshall Bowers created
crates/storybook2/src/stories.rs | 2
crates/storybook2/src/stories/elements.rs | 7
crates/storybook2/src/stories/elements/avatar.rs | 33 --
crates/storybook2/src/stories/elements/button.rs | 200 ----------------
crates/storybook2/src/stories/elements/details.rs | 31 --
crates/storybook2/src/stories/elements/icon.rs | 29 --
crates/storybook2/src/stories/elements/input.rs | 26 --
crates/storybook2/src/stories/elements/label.rs | 28 --
crates/storybook2/src/stories/z_index.rs | 0
crates/storybook2/src/story_selector.rs | 16
crates/ui2/src/elements/avatar.rs | 37 +++
crates/ui2/src/elements/button.rs | 203 +++++++++++++++++
crates/ui2/src/elements/details.rs | 35 ++
crates/ui2/src/elements/icon.rs | 34 ++
crates/ui2/src/elements/input.rs | 30 ++
crates/ui2/src/elements/label.rs | 32 ++
16 files changed, 379 insertions(+), 364 deletions(-)
@@ -1,2 +1,2 @@
-pub mod elements;
pub mod kitchen_sink;
+pub mod z_index;
@@ -1,7 +0,0 @@
-pub mod avatar;
-pub mod button;
-pub mod details;
-pub mod icon;
-pub mod input;
-pub mod label;
-pub mod z_index;
@@ -1,33 +0,0 @@
-use std::marker::PhantomData;
-
-use ui::prelude::*;
-use ui::Avatar;
-
-use crate::story::Story;
-
-#[derive(Element)]
-pub struct AvatarStory<S: 'static + Send + Sync> {
- state_type: PhantomData<S>,
-}
-
-impl<S: 'static + Send + Sync> AvatarStory<S> {
- pub fn new() -> Self {
- Self {
- state_type: PhantomData,
- }
- }
-
- fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
- Story::container(cx)
- .child(Story::title_for::<_, Avatar<S>>(cx))
- .child(Story::label(cx, "Default"))
- .child(Avatar::new(
- "https://avatars.githubusercontent.com/u/1714999?v=4",
- ))
- .child(Story::label(cx, "Rounded rectangle"))
- .child(
- Avatar::new("https://avatars.githubusercontent.com/u/1714999?v=4")
- .shape(Shape::RoundedRectangle),
- )
- }
-}
@@ -1,200 +0,0 @@
-use std::marker::PhantomData;
-
-use gpui3::rems;
-use strum::IntoEnumIterator;
-use ui::prelude::*;
-use ui::{h_stack, v_stack, Button, Icon, IconPosition, Label};
-
-use crate::story::Story;
-
-#[derive(Element)]
-pub struct ButtonStory<S: 'static + Send + Sync + Clone> {
- state_type: PhantomData<S>,
-}
-
-impl<S: 'static + Send + Sync + Clone> ButtonStory<S> {
- pub fn new() -> Self {
- Self {
- state_type: PhantomData,
- }
- }
-
- fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
- let states = InteractionState::iter();
-
- Story::container(cx)
- .child(Story::title_for::<_, Button<S>>(cx))
- .child(
- div()
- .flex()
- .gap_8()
- .child(
- div()
- .child(Story::label(cx, "Ghost (Default)"))
- .child(h_stack().gap_2().children(states.clone().map(|state| {
- v_stack()
- .gap_1()
- .child(
- Label::new(state.to_string())
- .color(ui::LabelColor::Muted)
- .size(ui::LabelSize::Small),
- )
- .child(
- Button::new("Label")
- .variant(ButtonVariant::Ghost)
- .state(state),
- )
- })))
- .child(Story::label(cx, "Ghost – Left Icon"))
- .child(h_stack().gap_2().children(states.clone().map(|state| {
- v_stack()
- .gap_1()
- .child(
- Label::new(state.to_string())
- .color(ui::LabelColor::Muted)
- .size(ui::LabelSize::Small),
- )
- .child(
- Button::new("Label")
- .variant(ButtonVariant::Ghost)
- .icon(Icon::Plus)
- .icon_position(IconPosition::Left)
- .state(state),
- )
- })))
- .child(Story::label(cx, "Ghost – Right Icon"))
- .child(h_stack().gap_2().children(states.clone().map(|state| {
- v_stack()
- .gap_1()
- .child(
- Label::new(state.to_string())
- .color(ui::LabelColor::Muted)
- .size(ui::LabelSize::Small),
- )
- .child(
- Button::new("Label")
- .variant(ButtonVariant::Ghost)
- .icon(Icon::Plus)
- .icon_position(IconPosition::Right)
- .state(state),
- )
- }))),
- )
- .child(
- div()
- .child(Story::label(cx, "Filled"))
- .child(h_stack().gap_2().children(states.clone().map(|state| {
- v_stack()
- .gap_1()
- .child(
- Label::new(state.to_string())
- .color(ui::LabelColor::Muted)
- .size(ui::LabelSize::Small),
- )
- .child(
- Button::new("Label")
- .variant(ButtonVariant::Filled)
- .state(state),
- )
- })))
- .child(Story::label(cx, "Filled – Left Button"))
- .child(h_stack().gap_2().children(states.clone().map(|state| {
- v_stack()
- .gap_1()
- .child(
- Label::new(state.to_string())
- .color(ui::LabelColor::Muted)
- .size(ui::LabelSize::Small),
- )
- .child(
- Button::new("Label")
- .variant(ButtonVariant::Filled)
- .icon(Icon::Plus)
- .icon_position(IconPosition::Left)
- .state(state),
- )
- })))
- .child(Story::label(cx, "Filled – Right Button"))
- .child(h_stack().gap_2().children(states.clone().map(|state| {
- v_stack()
- .gap_1()
- .child(
- Label::new(state.to_string())
- .color(ui::LabelColor::Muted)
- .size(ui::LabelSize::Small),
- )
- .child(
- Button::new("Label")
- .variant(ButtonVariant::Filled)
- .icon(Icon::Plus)
- .icon_position(IconPosition::Right)
- .state(state),
- )
- }))),
- )
- .child(
- div()
- .child(Story::label(cx, "Fixed With"))
- .child(h_stack().gap_2().children(states.clone().map(|state| {
- v_stack()
- .gap_1()
- .child(
- Label::new(state.to_string())
- .color(ui::LabelColor::Muted)
- .size(ui::LabelSize::Small),
- )
- .child(
- Button::new("Label")
- .variant(ButtonVariant::Filled)
- .state(state)
- .width(Some(rems(6.).into())),
- )
- })))
- .child(Story::label(cx, "Fixed With – Left Icon"))
- .child(h_stack().gap_2().children(states.clone().map(|state| {
- v_stack()
- .gap_1()
- .child(
- Label::new(state.to_string())
- .color(ui::LabelColor::Muted)
- .size(ui::LabelSize::Small),
- )
- .child(
- Button::new("Label")
- .variant(ButtonVariant::Filled)
- .state(state)
- .icon(Icon::Plus)
- .icon_position(IconPosition::Left)
- .width(Some(rems(6.).into())),
- )
- })))
- .child(Story::label(cx, "Fixed With – Right Icon"))
- .child(h_stack().gap_2().children(states.clone().map(|state| {
- v_stack()
- .gap_1()
- .child(
- Label::new(state.to_string())
- .color(ui::LabelColor::Muted)
- .size(ui::LabelSize::Small),
- )
- .child(
- Button::new("Label")
- .variant(ButtonVariant::Filled)
- .state(state)
- .icon(Icon::Plus)
- .icon_position(IconPosition::Right)
- .width(Some(rems(6.).into())),
- )
- }))),
- ),
- )
- .child(Story::label(cx, "Button with `on_click`"))
- .child(
- Button::new("Label")
- .variant(ButtonVariant::Ghost)
- // NOTE: There currently appears to be a bug in GPUI2 where only the last event handler will fire.
- // So adding additional buttons with `on_click`s after this one will cause this `on_click` to not fire.
- // .on_click(|_view, _cx| println!("Button clicked.")),
- )
- }
-}
@@ -1,31 +0,0 @@
-use std::marker::PhantomData;
-
-use ui::prelude::*;
-use ui::Details;
-
-use crate::story::Story;
-
-#[derive(Element)]
-pub struct DetailsStory<S: 'static + Send + Sync + Clone> {
- state_type: PhantomData<S>,
-}
-
-impl<S: 'static + Send + Sync + Clone> DetailsStory<S> {
- pub fn new() -> Self {
- Self {
- state_type: PhantomData,
- }
- }
-
- fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
- Story::container(cx)
- .child(Story::title_for::<_, Details<S>>(cx))
- .child(Story::label(cx, "Default"))
- .child(Details::new("The quick brown fox jumps over the lazy dog"))
- .child(Story::label(cx, "With meta"))
- .child(
- Details::new("The quick brown fox jumps over the lazy dog")
- .meta_text("Sphinx of black quartz, judge my vow."),
- )
- }
-}
@@ -1,29 +0,0 @@
-use std::marker::PhantomData;
-
-use strum::IntoEnumIterator;
-use ui::prelude::*;
-use ui::{Icon, IconElement};
-
-use crate::story::Story;
-
-#[derive(Element, Default)]
-pub struct IconStory<S: 'static + Send + Sync> {
- state_type: PhantomData<S>,
-}
-
-impl<S: 'static + Send + Sync> IconStory<S> {
- pub fn new() -> Self {
- Self {
- state_type: PhantomData,
- }
- }
-
- fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
- let icons = Icon::iter();
-
- Story::container(cx)
- .child(Story::title_for::<_, IconElement<S>>(cx))
- .child(Story::label(cx, "All Icons"))
- .child(div().flex().gap_3().children(icons.map(IconElement::new)))
- }
-}
@@ -1,26 +0,0 @@
-use std::marker::PhantomData;
-
-use ui::prelude::*;
-use ui::Input;
-
-use crate::story::Story;
-
-#[derive(Element)]
-pub struct InputStory<S: 'static + Send + Sync + Clone> {
- state_type: PhantomData<S>,
-}
-
-impl<S: 'static + Send + Sync + Clone> InputStory<S> {
- pub fn new() -> Self {
- Self {
- state_type: PhantomData,
- }
- }
-
- fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
- Story::container(cx)
- .child(Story::title_for::<_, Input<S>>(cx))
- .child(Story::label(cx, "Default"))
- .child(div().flex().child(Input::new("Search")))
- }
-}
@@ -1,28 +0,0 @@
-use std::marker::PhantomData;
-
-use ui::prelude::*;
-use ui::Label;
-
-use crate::story::Story;
-
-#[derive(Element)]
-pub struct LabelStory<S: 'static + Send + Sync + Clone> {
- state_type: PhantomData<S>,
-}
-
-impl<S: 'static + Send + Sync + Clone> LabelStory<S> {
- pub fn new() -> Self {
- Self {
- state_type: PhantomData,
- }
- }
-
- fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
- Story::container(cx)
- .child(Story::title_for::<_, Label<S>>(cx))
- .child(Story::label(cx, "Default"))
- .child(Label::new("Hello, world!"))
- .child(Story::label(cx, "Highlighted"))
- .child(Label::new("Hello, world!").with_highlights(vec![0, 1, 2, 7, 8, 12]))
- }
-}
@@ -23,16 +23,14 @@ pub enum ElementStory {
impl ElementStory {
pub fn story<S: 'static + Send + Sync + Clone>(&self) -> AnyElement<S> {
- use crate::stories::elements;
-
match self {
- Self::Avatar => elements::avatar::AvatarStory::new().into_any(),
- Self::Button => elements::button::ButtonStory::new().into_any(),
- Self::Details => elements::details::DetailsStory::new().into_any(),
- Self::Icon => elements::icon::IconStory::new().into_any(),
- Self::Input => elements::input::InputStory::new().into_any(),
- Self::Label => elements::label::LabelStory::new().into_any(),
- Self::ZIndex => elements::z_index::ZIndexStory::new().into_any(),
+ Self::Avatar => ui::AvatarStory::new().into_any(),
+ Self::Button => ui::ButtonStory::new().into_any(),
+ Self::Details => ui::DetailsStory::new().into_any(),
+ Self::Icon => ui::IconStory::new().into_any(),
+ Self::Input => ui::InputStory::new().into_any(),
+ Self::Label => ui::LabelStory::new().into_any(),
+ Self::ZIndex => crate::stories::z_index::ZIndexStory::new().into_any(),
}
}
}
@@ -42,3 +42,40 @@ impl<S: 'static + Send + Sync> Avatar<S> {
.fill(theme.middle.warning.default.foreground)
}
}
+
+#[cfg(feature = "stories")]
+pub use stories::*;
+
+#[cfg(feature = "stories")]
+mod stories {
+ use crate::Story;
+
+ use super::*;
+
+ #[derive(Element)]
+ pub struct AvatarStory<S: 'static + Send + Sync> {
+ state_type: PhantomData<S>,
+ }
+
+ impl<S: 'static + Send + Sync> AvatarStory<S> {
+ pub fn new() -> Self {
+ Self {
+ state_type: PhantomData,
+ }
+ }
+
+ fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
+ Story::container(cx)
+ .child(Story::title_for::<_, Avatar<S>>(cx))
+ .child(Story::label(cx, "Default"))
+ .child(Avatar::new(
+ "https://avatars.githubusercontent.com/u/1714999?v=4",
+ ))
+ .child(Story::label(cx, "Rounded rectangle"))
+ .child(
+ Avatar::new("https://avatars.githubusercontent.com/u/1714999?v=4")
+ .shape(Shape::RoundedRectangle),
+ )
+ }
+ }
+}
@@ -202,3 +202,206 @@ impl<S: 'static + Send + Sync + Clone> Button<S> {
el
}
}
+
+#[cfg(feature = "stories")]
+pub use stories::*;
+
+#[cfg(feature = "stories")]
+mod stories {
+ use gpui3::rems;
+ use strum::IntoEnumIterator;
+
+ use crate::{h_stack, v_stack, LabelColor, LabelSize, Story};
+
+ use super::*;
+
+ #[derive(Element)]
+ pub struct ButtonStory<S: 'static + Send + Sync + Clone> {
+ state_type: PhantomData<S>,
+ }
+
+ impl<S: 'static + Send + Sync + Clone> ButtonStory<S> {
+ pub fn new() -> Self {
+ Self {
+ state_type: PhantomData,
+ }
+ }
+
+ fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
+ let states = InteractionState::iter();
+
+ Story::container(cx)
+ .child(Story::title_for::<_, Button<S>>(cx))
+ .child(
+ div()
+ .flex()
+ .gap_8()
+ .child(
+ div()
+ .child(Story::label(cx, "Ghost (Default)"))
+ .child(h_stack().gap_2().children(states.clone().map(|state| {
+ v_stack()
+ .gap_1()
+ .child(
+ Label::new(state.to_string())
+ .color(LabelColor::Muted)
+ .size(LabelSize::Small),
+ )
+ .child(
+ Button::new("Label")
+ .variant(ButtonVariant::Ghost)
+ .state(state),
+ )
+ })))
+ .child(Story::label(cx, "Ghost – Left Icon"))
+ .child(h_stack().gap_2().children(states.clone().map(|state| {
+ v_stack()
+ .gap_1()
+ .child(
+ Label::new(state.to_string())
+ .color(LabelColor::Muted)
+ .size(LabelSize::Small),
+ )
+ .child(
+ Button::new("Label")
+ .variant(ButtonVariant::Ghost)
+ .icon(Icon::Plus)
+ .icon_position(IconPosition::Left)
+ .state(state),
+ )
+ })))
+ .child(Story::label(cx, "Ghost – Right Icon"))
+ .child(h_stack().gap_2().children(states.clone().map(|state| {
+ v_stack()
+ .gap_1()
+ .child(
+ Label::new(state.to_string())
+ .color(LabelColor::Muted)
+ .size(LabelSize::Small),
+ )
+ .child(
+ Button::new("Label")
+ .variant(ButtonVariant::Ghost)
+ .icon(Icon::Plus)
+ .icon_position(IconPosition::Right)
+ .state(state),
+ )
+ }))),
+ )
+ .child(
+ div()
+ .child(Story::label(cx, "Filled"))
+ .child(h_stack().gap_2().children(states.clone().map(|state| {
+ v_stack()
+ .gap_1()
+ .child(
+ Label::new(state.to_string())
+ .color(LabelColor::Muted)
+ .size(LabelSize::Small),
+ )
+ .child(
+ Button::new("Label")
+ .variant(ButtonVariant::Filled)
+ .state(state),
+ )
+ })))
+ .child(Story::label(cx, "Filled – Left Button"))
+ .child(h_stack().gap_2().children(states.clone().map(|state| {
+ v_stack()
+ .gap_1()
+ .child(
+ Label::new(state.to_string())
+ .color(LabelColor::Muted)
+ .size(LabelSize::Small),
+ )
+ .child(
+ Button::new("Label")
+ .variant(ButtonVariant::Filled)
+ .icon(Icon::Plus)
+ .icon_position(IconPosition::Left)
+ .state(state),
+ )
+ })))
+ .child(Story::label(cx, "Filled – Right Button"))
+ .child(h_stack().gap_2().children(states.clone().map(|state| {
+ v_stack()
+ .gap_1()
+ .child(
+ Label::new(state.to_string())
+ .color(LabelColor::Muted)
+ .size(LabelSize::Small),
+ )
+ .child(
+ Button::new("Label")
+ .variant(ButtonVariant::Filled)
+ .icon(Icon::Plus)
+ .icon_position(IconPosition::Right)
+ .state(state),
+ )
+ }))),
+ )
+ .child(
+ div()
+ .child(Story::label(cx, "Fixed With"))
+ .child(h_stack().gap_2().children(states.clone().map(|state| {
+ v_stack()
+ .gap_1()
+ .child(
+ Label::new(state.to_string())
+ .color(LabelColor::Muted)
+ .size(LabelSize::Small),
+ )
+ .child(
+ Button::new("Label")
+ .variant(ButtonVariant::Filled)
+ .state(state)
+ .width(Some(rems(6.).into())),
+ )
+ })))
+ .child(Story::label(cx, "Fixed With – Left Icon"))
+ .child(h_stack().gap_2().children(states.clone().map(|state| {
+ v_stack()
+ .gap_1()
+ .child(
+ Label::new(state.to_string())
+ .color(LabelColor::Muted)
+ .size(LabelSize::Small),
+ )
+ .child(
+ Button::new("Label")
+ .variant(ButtonVariant::Filled)
+ .state(state)
+ .icon(Icon::Plus)
+ .icon_position(IconPosition::Left)
+ .width(Some(rems(6.).into())),
+ )
+ })))
+ .child(Story::label(cx, "Fixed With – Right Icon"))
+ .child(h_stack().gap_2().children(states.clone().map(|state| {
+ v_stack()
+ .gap_1()
+ .child(
+ Label::new(state.to_string())
+ .color(LabelColor::Muted)
+ .size(LabelSize::Small),
+ )
+ .child(
+ Button::new("Label")
+ .variant(ButtonVariant::Filled)
+ .state(state)
+ .icon(Icon::Plus)
+ .icon_position(IconPosition::Right)
+ .width(Some(rems(6.).into())),
+ )
+ }))),
+ ),
+ )
+ .child(Story::label(cx, "Button with `on_click`"))
+ .child(
+ Button::new("Label").variant(ButtonVariant::Ghost), // NOTE: There currently appears to be a bug in GPUI2 where only the last event handler will fire.
+ // So adding additional buttons with `on_click`s after this one will cause this `on_click` to not fire.
+ // .on_click(|_view, _cx| println!("Button clicked.")),
+ )
+ }
+ }
+}
@@ -38,3 +38,38 @@ impl<S: 'static + Send + Sync + Clone> Details<S> {
.children(self.meta.map(|m| m))
}
}
+
+#[cfg(feature = "stories")]
+pub use stories::*;
+
+#[cfg(feature = "stories")]
+mod stories {
+ use crate::Story;
+
+ use super::*;
+
+ #[derive(Element)]
+ pub struct DetailsStory<S: 'static + Send + Sync + Clone> {
+ state_type: PhantomData<S>,
+ }
+
+ impl<S: 'static + Send + Sync + Clone> DetailsStory<S> {
+ pub fn new() -> Self {
+ Self {
+ state_type: PhantomData,
+ }
+ }
+
+ fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
+ Story::container(cx)
+ .child(Story::title_for::<_, Details<S>>(cx))
+ .child(Story::label(cx, "Default"))
+ .child(Details::new("The quick brown fox jumps over the lazy dog"))
+ .child(Story::label(cx, "With meta"))
+ .child(
+ Details::new("The quick brown fox jumps over the lazy dog")
+ .meta_text("Sphinx of black quartz, judge my vow."),
+ )
+ }
+ }
+}
@@ -182,3 +182,37 @@ impl<S: 'static + Send + Sync> IconElement<S> {
sized_svg.flex_none().path(self.icon.path()).fill(fill)
}
}
+
+#[cfg(feature = "stories")]
+pub use stories::*;
+
+#[cfg(feature = "stories")]
+mod stories {
+ use strum::IntoEnumIterator;
+
+ use crate::Story;
+
+ use super::*;
+
+ #[derive(Element, Default)]
+ pub struct IconStory<S: 'static + Send + Sync> {
+ state_type: PhantomData<S>,
+ }
+
+ impl<S: 'static + Send + Sync> IconStory<S> {
+ pub fn new() -> Self {
+ Self {
+ state_type: PhantomData,
+ }
+ }
+
+ fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
+ let icons = Icon::iter();
+
+ Story::container(cx)
+ .child(Story::title_for::<_, IconElement<S>>(cx))
+ .child(Story::label(cx, "All Icons"))
+ .child(div().flex().gap_3().children(icons.map(IconElement::new)))
+ }
+ }
+}
@@ -108,3 +108,33 @@ impl<S: 'static + Send + Sync> Input<S> {
)
}
}
+
+#[cfg(feature = "stories")]
+pub use stories::*;
+
+#[cfg(feature = "stories")]
+mod stories {
+ use crate::Story;
+
+ use super::*;
+
+ #[derive(Element)]
+ pub struct InputStory<S: 'static + Send + Sync + Clone> {
+ state_type: PhantomData<S>,
+ }
+
+ impl<S: 'static + Send + Sync + Clone> InputStory<S> {
+ pub fn new() -> Self {
+ Self {
+ state_type: PhantomData,
+ }
+ }
+
+ fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
+ Story::container(cx)
+ .child(Story::title_for::<_, Input<S>>(cx))
+ .child(Story::label(cx, "Default"))
+ .child(div().flex().child(Input::new("Search")))
+ }
+ }
+}
@@ -163,3 +163,35 @@ struct Run {
pub text: String,
pub color: Hsla,
}
+
+#[cfg(feature = "stories")]
+pub use stories::*;
+
+#[cfg(feature = "stories")]
+mod stories {
+ use crate::Story;
+
+ use super::*;
+
+ #[derive(Element)]
+ pub struct LabelStory<S: 'static + Send + Sync + Clone> {
+ state_type: PhantomData<S>,
+ }
+
+ impl<S: 'static + Send + Sync + Clone> LabelStory<S> {
+ pub fn new() -> Self {
+ Self {
+ state_type: PhantomData,
+ }
+ }
+
+ fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
+ Story::container(cx)
+ .child(Story::title_for::<_, Label<S>>(cx))
+ .child(Story::label(cx, "Default"))
+ .child(Label::new("Hello, world!"))
+ .child(Story::label(cx, "Highlighted"))
+ .child(Label::new("Hello, world!").with_highlights(vec![0, 1, 2, 7, 8, 12]))
+ }
+ }
+}