storybook: Fix kitchen sink story (#3064)

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
This commit is contained in:
Marshall Bowers 2023-09-28 21:22:50 -04:00 committed by GitHub
parent f26ca0866c
commit 247c7eff14
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 28 additions and 81 deletions

View file

@ -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))
}
}

View file

@ -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> {

View file

@ -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| {