storybook: Fix kitchen sink story (#3064)
Marshall Bowers
created 2 years ago
This PR fixes the kitchen sink story in the storybook.
Included are some additional changes that make it so the kitchen sink is
automatically populated by all of the defined stories.
Release Notes:
- N/A
Change summary
crates/storybook/src/stories/kitchen_sink.rs | 43 +++++----------------
crates/storybook/src/story_selector.rs | 42 ++++++++------------
crates/storybook/src/storybook.rs | 24 -----------
3 files changed, 28 insertions(+), 81 deletions(-)
Detailed changes
@@ -1,46 +1,23 @@
+use strum::IntoEnumIterator;
use ui::prelude::*;
use crate::story::Story;
+use crate::story_selector::{ComponentStory, ElementStory};
#[derive(Element, Default)]
pub struct KitchenSinkStory {}
impl KitchenSinkStory {
fn render<V: 'static>(&mut self, _: &mut V, cx: &mut ViewContext<V>) -> impl IntoElement<V> {
+ let element_stories = ElementStory::iter().map(|selector| selector.story());
+ let component_stories = ComponentStory::iter().map(|selector| selector.story());
+
Story::container(cx)
+ .overflow_y_scroll(ScrollState::default())
.child(Story::title(cx, "Kitchen Sink"))
- .child(
- div()
- .flex()
- .flex_col()
- .overflow_y_scroll(ScrollState::default())
- .child(crate::stories::elements::avatar::AvatarStory::default())
- .child(crate::stories::elements::button::ButtonStory::default())
- .child(crate::stories::elements::icon::IconStory::default())
- .child(crate::stories::elements::input::InputStory::default())
- .child(crate::stories::elements::label::LabelStory::default())
- .child(
- crate::stories::components::assistant_panel::AssistantPanelStory::default(),
- )
- .child(crate::stories::components::breadcrumb::BreadcrumbStory::default())
- .child(crate::stories::components::buffer::BufferStory::default())
- .child(crate::stories::components::chat_panel::ChatPanelStory::default())
- .child(crate::stories::components::collab_panel::CollabPanelStory::default())
- .child(crate::stories::components::facepile::FacepileStory::default())
- .child(crate::stories::components::keybinding::KeybindingStory::default())
- .child(crate::stories::components::palette::PaletteStory::default())
- .child(crate::stories::components::panel::PanelStory::default())
- .child(crate::stories::components::project_panel::ProjectPanelStory::default())
- .child(crate::stories::components::status_bar::StatusBarStory::default())
- .child(crate::stories::components::tab::TabStory::default())
- .child(crate::stories::components::tab_bar::TabBarStory::default())
- .child(crate::stories::components::terminal::TerminalStory::default())
- .child(crate::stories::components::title_bar::TitleBarStory::default())
- .child(crate::stories::components::toolbar::ToolbarStory::default())
- .child(
- crate::stories::components::traffic_lights::TrafficLightsStory::default(),
- )
- .child(crate::stories::components::context_menu::ContextMenuStory::default()),
- )
+ .child(Story::label(cx, "Elements"))
+ .child(div().flex().flex_col().children_any(element_stories))
+ .child(Story::label(cx, "Components"))
+ .child(div().flex().flex_col().children_any(component_stories))
}
}
@@ -123,17 +123,13 @@ impl FromStr for StorySelector {
}
impl StorySelector {
- pub fn story<V: 'static>(&self) -> Vec<AnyElement<V>> {
+ pub fn story<V: 'static>(&self) -> AnyElement<V> {
match self {
- Self::Element(element_story) => vec![element_story.story()],
- Self::Component(component_story) => vec![component_story.story()],
- Self::KitchenSink => all_story_selectors()
- .into_iter()
- // Exclude the kitchen sink to prevent `story` from recursively
- // calling itself for all eternity.
- .filter(|selector| **selector != Self::KitchenSink)
- .flat_map(|selector| selector.story())
- .collect(),
+ Self::Element(element_story) => element_story.story(),
+ Self::Component(component_story) => component_story.story(),
+ Self::KitchenSink => {
+ crate::stories::kitchen_sink::KitchenSinkStory::default().into_any()
+ }
}
}
}
@@ -141,23 +137,19 @@ impl StorySelector {
/// The list of all stories available in the storybook.
static ALL_STORY_SELECTORS: OnceLock<Vec<StorySelector>> = OnceLock::new();
-fn all_story_selectors<'a>() -> &'a [StorySelector] {
- let stories = ALL_STORY_SELECTORS.get_or_init(|| {
- let element_stories = ElementStory::iter().map(StorySelector::Element);
- let component_stories = ComponentStory::iter().map(StorySelector::Component);
-
- element_stories
- .chain(component_stories)
- .chain(std::iter::once(StorySelector::KitchenSink))
- .collect::<Vec<_>>()
- });
-
- stories
-}
-
impl ValueEnum for StorySelector {
fn value_variants<'a>() -> &'a [Self] {
- all_story_selectors()
+ let stories = ALL_STORY_SELECTORS.get_or_init(|| {
+ let element_stories = ElementStory::iter().map(StorySelector::Element);
+ let component_stories = ComponentStory::iter().map(StorySelector::Component);
+
+ element_stories
+ .chain(component_stories)
+ .chain(std::iter::once(StorySelector::KitchenSink))
+ .collect::<Vec<_>>()
+ });
+
+ stories
}
fn to_possible_value(&self) -> Option<clap::builder::PossibleValue> {
@@ -70,33 +70,11 @@ fn main() {
..Default::default()
},
|cx| match args.story {
- // HACK: Special-case the kitchen sink to fix scrolling.
- // There is something about going through `children_any` that messes
- // with the scroll interactions.
- Some(StorySelector::KitchenSink) => view(move |cx| {
- render_story(
- &mut ViewContext::new(cx),
- theme_override.clone(),
- crate::stories::kitchen_sink::KitchenSinkStory::default(),
- )
- }),
- // HACK: Special-case the panel story to fix scrolling.
- // There is something about going through `children_any` that messes
- // with the scroll interactions.
- Some(StorySelector::Component(story_selector::ComponentStory::Panel)) => {
- view(move |cx| {
- render_story(
- &mut ViewContext::new(cx),
- theme_override.clone(),
- crate::stories::components::panel::PanelStory::default(),
- )
- })
- }
Some(selector) => view(move |cx| {
render_story(
&mut ViewContext::new(cx),
theme_override.clone(),
- div().children_any(selector.story()),
+ div().flex().flex_col().h_full().child_any(selector.story()),
)
}),
None => view(move |cx| {