Factor story boilerplate out into separate components (#3016)
This PR factors out the bulk of the boilerplate required to setup a story in the storybook out into separate components. The pattern we're using here is adapted from the "[associated component](https://maxdeviant.com/posts/2021/react-associated-components/)" pattern in React. Release Notes: - N/A
This commit is contained in:
parent
afa7045847
commit
d8c6adf338
5 changed files with 49 additions and 55 deletions
|
@ -1,8 +1,10 @@
|
|||
use gpui2::elements::div;
|
||||
use gpui2::style::StyleHelpers;
|
||||
use gpui2::{rgb, Element, Hsla, IntoElement, ParentElement, ViewContext};
|
||||
use ui::{avatar, theme};
|
||||
use ui::{facepile, prelude::*};
|
||||
use gpui2::{Element, IntoElement, ParentElement, ViewContext};
|
||||
use ui::prelude::*;
|
||||
use ui::{avatar, facepile, theme};
|
||||
|
||||
use crate::story::Story;
|
||||
|
||||
#[derive(Element, Default)]
|
||||
pub struct FacepileStory {}
|
||||
|
@ -11,20 +13,8 @@ impl FacepileStory {
|
|||
fn render<V: 'static>(&mut self, _: &mut V, cx: &mut ViewContext<V>) -> impl IntoElement<V> {
|
||||
let theme = theme(cx);
|
||||
|
||||
div()
|
||||
.size_full()
|
||||
.flex()
|
||||
.flex_col()
|
||||
.pt_2()
|
||||
.px_4()
|
||||
.font("Zed Mono Extended")
|
||||
.fill(rgb::<Hsla>(0x282c34))
|
||||
.child(
|
||||
div()
|
||||
.text_2xl()
|
||||
.text_color(rgb::<Hsla>(0xffffff))
|
||||
.child(std::any::type_name::<ui::Facepile>()),
|
||||
)
|
||||
Story::container()
|
||||
.child(Story::title(std::any::type_name::<ui::Facepile>()))
|
||||
.child(
|
||||
div()
|
||||
.flex()
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use gpui2::elements::div;
|
||||
use gpui2::style::StyleHelpers;
|
||||
use gpui2::{rgb, Element, Hsla, IntoElement, ParentElement, ViewContext};
|
||||
use gpui2::{Element, IntoElement, ParentElement, ViewContext};
|
||||
use ui::{theme, traffic_lights};
|
||||
|
||||
use crate::story::Story;
|
||||
|
||||
#[derive(Element, Default)]
|
||||
pub struct TrafficLightsStory {}
|
||||
|
||||
|
@ -10,20 +10,8 @@ impl TrafficLightsStory {
|
|||
fn render<V: 'static>(&mut self, _: &mut V, cx: &mut ViewContext<V>) -> impl IntoElement<V> {
|
||||
let theme = theme(cx);
|
||||
|
||||
div()
|
||||
.size_full()
|
||||
.flex()
|
||||
.flex_col()
|
||||
.pt_2()
|
||||
.px_4()
|
||||
.font("Zed Mono Extended")
|
||||
.fill(rgb::<Hsla>(0x282c34))
|
||||
.child(
|
||||
div()
|
||||
.text_2xl()
|
||||
.text_color(rgb::<Hsla>(0xffffff))
|
||||
.child(std::any::type_name::<ui::TrafficLights>()),
|
||||
)
|
||||
Story::container()
|
||||
.child(Story::title(std::any::type_name::<ui::TrafficLights>()))
|
||||
.child(traffic_lights())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
use gpui2::elements::div;
|
||||
use gpui2::style::StyleHelpers;
|
||||
use gpui2::{rgb, Element, Hsla, IntoElement, ParentElement, ViewContext};
|
||||
use gpui2::{Element, IntoElement, ParentElement, ViewContext};
|
||||
use ui::prelude::*;
|
||||
use ui::{avatar, theme};
|
||||
|
||||
use crate::story::Story;
|
||||
|
||||
#[derive(Element, Default)]
|
||||
pub struct AvatarStory {}
|
||||
|
||||
|
@ -11,20 +13,8 @@ impl AvatarStory {
|
|||
fn render<V: 'static>(&mut self, _: &mut V, cx: &mut ViewContext<V>) -> impl IntoElement<V> {
|
||||
let theme = theme(cx);
|
||||
|
||||
div()
|
||||
.size_full()
|
||||
.flex()
|
||||
.flex_col()
|
||||
.pt_2()
|
||||
.px_4()
|
||||
.font("Zed Mono Extended")
|
||||
.fill(rgb::<Hsla>(0x282c34))
|
||||
.child(
|
||||
div()
|
||||
.text_2xl()
|
||||
.text_color(rgb::<Hsla>(0xffffff))
|
||||
.child(std::any::type_name::<ui::Avatar>()),
|
||||
)
|
||||
Story::container()
|
||||
.child(Story::title(std::any::type_name::<ui::Avatar>()))
|
||||
.child(
|
||||
div()
|
||||
.flex()
|
||||
|
|
25
crates/storybook/src/story.rs
Normal file
25
crates/storybook/src/story.rs
Normal file
|
@ -0,0 +1,25 @@
|
|||
use gpui2::elements::div;
|
||||
use gpui2::style::StyleHelpers;
|
||||
use gpui2::{rgb, Element, Hsla, ParentElement};
|
||||
|
||||
pub struct Story {}
|
||||
|
||||
impl Story {
|
||||
pub fn container<V: 'static>() -> div::Div<V> {
|
||||
div()
|
||||
.size_full()
|
||||
.flex()
|
||||
.flex_col()
|
||||
.pt_2()
|
||||
.px_4()
|
||||
.font("Zed Mono Extended")
|
||||
.fill(rgb::<Hsla>(0x282c34))
|
||||
}
|
||||
|
||||
pub fn title<V: 'static>(title: &str) -> impl Element<V> {
|
||||
div()
|
||||
.text_2xl()
|
||||
.text_color(rgb::<Hsla>(0xffffff))
|
||||
.child(title.to_owned())
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
mod collab_panel;
|
||||
mod stories;
|
||||
mod story;
|
||||
mod workspace;
|
||||
|
||||
use std::str::FromStr;
|
||||
|
@ -24,12 +25,12 @@ gpui2::actions! {
|
|||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
enum Story {
|
||||
enum StorySelector {
|
||||
Element(ElementStory),
|
||||
Component(ComponentStory),
|
||||
}
|
||||
|
||||
impl FromStr for Story {
|
||||
impl FromStr for StorySelector {
|
||||
type Err = anyhow::Error;
|
||||
|
||||
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
|
||||
|
@ -55,7 +56,7 @@ enum ComponentStory {
|
|||
|
||||
#[derive(Parser)]
|
||||
struct Args {
|
||||
story: Option<Story>,
|
||||
story: Option<StorySelector>,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
@ -79,13 +80,13 @@ fn main() {
|
|||
..Default::default()
|
||||
},
|
||||
|cx| match args.story {
|
||||
Some(Story::Element(ElementStory::Avatar)) => {
|
||||
Some(StorySelector::Element(ElementStory::Avatar)) => {
|
||||
view(|cx| render_story(&mut ViewContext::new(cx), AvatarStory::default()))
|
||||
}
|
||||
Some(Story::Component(ComponentStory::Facepile)) => {
|
||||
Some(StorySelector::Component(ComponentStory::Facepile)) => {
|
||||
view(|cx| render_story(&mut ViewContext::new(cx), FacepileStory::default()))
|
||||
}
|
||||
Some(Story::Component(ComponentStory::TrafficLights)) => view(|cx| {
|
||||
Some(StorySelector::Component(ComponentStory::TrafficLights)) => view(|cx| {
|
||||
render_story(&mut ViewContext::new(cx), TrafficLightsStory::default())
|
||||
}),
|
||||
None => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue