Extract Story into separate story crate (#3378)

This PR extracts the `Story` component into a separate `story` crate so
that it can be shared among various crates that define stories.

Release Notes:

- N/A

---------

Co-authored-by: Nate Butler <iamnbutler@gmail.com>
This commit is contained in:
Marshall Bowers 2023-11-21 13:42:00 -05:00 committed by GitHub
parent f4b4bdfd83
commit 1b05aad30c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 309 additions and 316 deletions

9
Cargo.lock generated
View file

@ -8859,6 +8859,13 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "story"
version = "0.1.0"
dependencies = [
"gpui2",
]
[[package]] [[package]]
name = "stringprep" name = "stringprep"
version = "0.1.4" version = "0.1.4"
@ -9362,6 +9369,7 @@ dependencies = [
"serde_derive", "serde_derive",
"serde_json", "serde_json",
"settings2", "settings2",
"story",
"toml 0.5.11", "toml 0.5.11",
"util", "util",
"uuid 1.4.1", "uuid 1.4.1",
@ -10205,6 +10213,7 @@ dependencies = [
"serde", "serde",
"settings2", "settings2",
"smallvec", "smallvec",
"story",
"strum", "strum",
"theme2", "theme2",
] ]

View file

@ -111,6 +111,7 @@ members = [
"crates/ui2", "crates/ui2",
"crates/util", "crates/util",
"crates/semantic_index", "crates/semantic_index",
"crates/story",
"crates/vim", "crates/vim",
"crates/vcs_menu", "crates/vcs_menu",
"crates/workspace2", "crates/workspace2",

10
crates/story/Cargo.toml Normal file
View file

@ -0,0 +1,10 @@
[package]
name = "story"
version = "0.1.0"
edition = "2021"
publish = false
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
gpui = { package = "gpui2", path = "../gpui2" }

3
crates/story/src/lib.rs Normal file
View file

@ -0,0 +1,3 @@
mod story;
pub use story::*;

35
crates/story/src/story.rs Normal file
View file

@ -0,0 +1,35 @@
use gpui::prelude::*;
use gpui::{div, hsla, Div, SharedString};
pub struct Story {}
impl Story {
pub fn container() -> Div {
div().size_full().flex().flex_col().pt_2().px_4().bg(hsla(
0. / 360.,
0. / 100.,
100. / 100.,
1.,
))
}
pub fn title(title: impl Into<SharedString>) -> impl Element {
div()
.text_xl()
.text_color(hsla(0. / 360., 0. / 100., 0. / 100., 1.))
.child(title.into())
}
pub fn title_for<T>() -> impl Element {
Self::title(std::any::type_name::<T>())
}
pub fn label(label: impl Into<SharedString>) -> impl Element {
div()
.mt_4()
.mb_2()
.text_xs()
.text_color(hsla(0. / 360., 0. / 100., 0. / 100., 1.))
.child(label.into())
}
}

View file

@ -25,6 +25,7 @@ serde.workspace = true
settings2 = { path = "../settings2" } settings2 = { path = "../settings2" }
simplelog = "0.9" simplelog = "0.9"
smallvec.workspace = true smallvec.workspace = true
story = { path = "../story" }
strum = { version = "0.25.0", features = ["derive"] } strum = { version = "0.25.0", features = ["derive"] }
theme = { path = "../theme" } theme = { path = "../theme" }
theme2 = { path = "../theme2" } theme2 = { path = "../theme2" }

View file

@ -1,44 +0,0 @@
use crate::story::Story;
use gpui::{prelude::*, px, Div, Render};
use theme2::{default_color_scales, ColorScaleStep};
use ui::prelude::*;
pub struct ColorsStory;
impl Render for ColorsStory {
type Element = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
let color_scales = default_color_scales();
Story::container(cx)
.child(Story::title(cx, "Colors"))
.child(
div()
.id("colors")
.flex()
.flex_col()
.gap_1()
.overflow_y_scroll()
.text_color(gpui::white())
.children(color_scales.into_iter().map(|scale| {
div()
.flex()
.child(
div()
.w(px(75.))
.line_height(px(24.))
.child(scale.name().clone()),
)
.child(
div()
.flex()
.gap_1()
.children(ColorScaleStep::ALL.map(|step| {
div().flex().size_6().bg(scale.step(cx, step))
})),
)
})),
)
}
}

View file

@ -5,9 +5,9 @@ edition = "2021"
publish = false publish = false
[features] [features]
default = ["stories"] default = []
importing-themes = [] importing-themes = []
stories = ["dep:itertools"] stories = ["dep:itertools", "dep:story"]
test-support = [ test-support = [
"gpui/test-support", "gpui/test-support",
"fs/test-support", "fs/test-support",
@ -30,6 +30,7 @@ serde.workspace = true
serde_derive.workspace = true serde_derive.workspace = true
serde_json.workspace = true serde_json.workspace = true
settings = { package = "settings2", path = "../settings2" } settings = { package = "settings2", path = "../settings2" }
story = { path = "../story", optional = true }
toml.workspace = true toml.workspace = true
uuid.workspace = true uuid.workspace = true
util = { path = "../util" } util = { path = "../util" }

View file

@ -1,38 +0,0 @@
use gpui::{div, Div, Element, ParentElement, SharedString, Styled, WindowContext};
use crate::ActiveTheme;
pub struct Story {}
impl Story {
pub fn container(cx: &mut WindowContext) -> Div {
div()
.size_full()
.flex()
.flex_col()
.pt_2()
.px_4()
.font("Zed Mono")
.bg(cx.theme().colors().background)
}
pub fn title(cx: &mut WindowContext, title: SharedString) -> impl Element {
div()
.text_xl()
.text_color(cx.theme().colors().text)
.child(title)
}
pub fn title_for<T>(cx: &mut WindowContext) -> impl Element {
Self::title(cx, std::any::type_name::<T>().into())
}
pub fn label(cx: &mut WindowContext, label: impl Into<SharedString>) -> impl Element {
div()
.mt_4()
.mb_2()
.text_xs()
.text_color(cx.theme().colors().text)
.child(label.into())
}
}

View file

@ -4,8 +4,14 @@ mod status;
mod syntax; mod syntax;
mod system; mod system;
#[cfg(feature = "stories")]
mod stories;
pub use colors::*; pub use colors::*;
pub use players::*; pub use players::*;
pub use status::*; pub use status::*;
pub use syntax::*; pub use syntax::*;
pub use system::*; pub use system::*;
#[cfg(feature = "stories")]
pub use stories::*;

View file

@ -1,5 +1,7 @@
use gpui::Hsla; use gpui::Hsla;
use crate::{amber, blue, jade, lime, orange, pink, purple, red};
#[derive(Debug, Clone, Copy, Default)] #[derive(Debug, Clone, Copy, Default)]
pub struct PlayerColor { pub struct PlayerColor {
pub cursor: Hsla, pub cursor: Hsla,
@ -133,141 +135,3 @@ impl PlayerColors {
self.0[(participant_index as usize % len) + 1] self.0[(participant_index as usize % len) + 1]
} }
} }
#[cfg(feature = "stories")]
pub use stories::*;
use crate::{amber, blue, jade, lime, orange, pink, purple, red};
#[cfg(feature = "stories")]
mod stories {
use super::*;
use crate::{ActiveTheme, Story};
use gpui::{div, img, px, Div, ParentElement, Render, Styled, ViewContext};
pub struct PlayerStory;
impl Render for PlayerStory {
type Element = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
Story::container(cx).child(
div()
.flex()
.flex_col()
.gap_4()
.child(Story::title_for::<PlayerColors>(cx))
.child(Story::label(cx, "Player Colors"))
.child(
div()
.flex()
.flex_col()
.gap_1()
.child(
div().flex().gap_1().children(
cx.theme().players().0.clone().iter_mut().map(|player| {
div().w_8().h_8().rounded_md().bg(player.cursor)
}),
),
)
.child(div().flex().gap_1().children(
cx.theme().players().0.clone().iter_mut().map(|player| {
div().w_8().h_8().rounded_md().bg(player.background)
}),
))
.child(div().flex().gap_1().children(
cx.theme().players().0.clone().iter_mut().map(|player| {
div().w_8().h_8().rounded_md().bg(player.selection)
}),
)),
)
.child(Story::label(cx, "Avatar Rings"))
.child(div().flex().gap_1().children(
cx.theme().players().0.clone().iter_mut().map(|player| {
div()
.my_1()
.rounded_full()
.border_2()
.border_color(player.cursor)
.child(
img()
.rounded_full()
.uri("https://avatars.githubusercontent.com/u/1714999?v=4")
.size_6()
.bg(gpui::red()),
)
}),
))
.child(Story::label(cx, "Player Backgrounds"))
.child(div().flex().gap_1().children(
cx.theme().players().0.clone().iter_mut().map(|player| {
div()
.my_1()
.rounded_xl()
.flex()
.items_center()
.h_8()
.py_0p5()
.px_1p5()
.bg(player.background)
.child(
div().relative().neg_mx_1().rounded_full().z_index(3)
.border_2()
.border_color(player.background)
.size(px(28.))
.child(
img()
.rounded_full()
.uri("https://avatars.githubusercontent.com/u/1714999?v=4")
.size(px(24.))
.bg(gpui::red()),
),
).child(
div().relative().neg_mx_1().rounded_full().z_index(2)
.border_2()
.border_color(player.background)
.size(px(28.))
.child(
img()
.rounded_full()
.uri("https://avatars.githubusercontent.com/u/1714999?v=4")
.size(px(24.))
.bg(gpui::red()),
),
).child(
div().relative().neg_mx_1().rounded_full().z_index(1)
.border_2()
.border_color(player.background)
.size(px(28.))
.child(
img()
.rounded_full()
.uri("https://avatars.githubusercontent.com/u/1714999?v=4")
.size(px(24.))
.bg(gpui::red()),
),
)
}),
))
.child(Story::label(cx, "Player Selections"))
.child(div().flex().flex_col().gap_px().children(
cx.theme().players().0.clone().iter_mut().map(|player| {
div()
.flex()
.child(
div()
.flex()
.flex_none()
.rounded_sm()
.px_0p5()
.text_color(cx.theme().colors().text)
.bg(player.selection)
.child("The brown fox jumped over the lazy dog."),
)
.child(div().flex_1())
}),
)),
)
}
}
}

View file

@ -0,0 +1,41 @@
use gpui::prelude::*;
use gpui::{div, px, Div, ViewContext};
use story::Story;
use crate::{default_color_scales, ColorScaleStep};
pub struct ColorsStory;
impl Render for ColorsStory {
type Element = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
let color_scales = default_color_scales();
Story::container().child(Story::title("Colors")).child(
div()
.id("colors")
.flex()
.flex_col()
.gap_1()
.overflow_y_scroll()
.text_color(gpui::white())
.children(color_scales.into_iter().map(|scale| {
div()
.flex()
.child(
div()
.w(px(75.))
.line_height(px(24.))
.child(scale.name().clone()),
)
.child(
div().flex().gap_1().children(
ColorScaleStep::ALL
.map(|step| div().flex().size_6().bg(scale.step(cx, step))),
),
)
})),
)
}
}

View file

@ -0,0 +1,5 @@
mod color;
mod players;
pub use color::*;
pub use players::*;

View file

@ -0,0 +1,137 @@
use gpui::{div, img, px, Div, ParentElement, Render, Styled, ViewContext};
use story::Story;
use crate::{ActiveTheme, PlayerColors};
pub struct PlayerStory;
impl Render for PlayerStory {
type Element = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
Story::container().child(
div()
.flex()
.flex_col()
.gap_4()
.child(Story::title_for::<PlayerColors>())
.child(Story::label("Player Colors"))
.child(
div()
.flex()
.flex_col()
.gap_1()
.child(
div().flex().gap_1().children(
cx.theme()
.players()
.0
.clone()
.iter_mut()
.map(|player| div().w_8().h_8().rounded_md().bg(player.cursor)),
),
)
.child(
div().flex().gap_1().children(
cx.theme().players().0.clone().iter_mut().map(|player| {
div().w_8().h_8().rounded_md().bg(player.background)
}),
),
)
.child(
div().flex().gap_1().children(
cx.theme().players().0.clone().iter_mut().map(|player| {
div().w_8().h_8().rounded_md().bg(player.selection)
}),
),
),
)
.child(Story::label("Avatar Rings"))
.child(div().flex().gap_1().children(
cx.theme().players().0.clone().iter_mut().map(|player| {
div()
.my_1()
.rounded_full()
.border_2()
.border_color(player.cursor)
.child(
img()
.rounded_full()
.uri("https://avatars.githubusercontent.com/u/1714999?v=4")
.size_6()
.bg(gpui::red()),
)
}),
))
.child(Story::label("Player Backgrounds"))
.child(div().flex().gap_1().children(
cx.theme().players().0.clone().iter_mut().map(|player| {
div()
.my_1()
.rounded_xl()
.flex()
.items_center()
.h_8()
.py_0p5()
.px_1p5()
.bg(player.background)
.child(
div().relative().neg_mx_1().rounded_full().z_index(3)
.border_2()
.border_color(player.background)
.size(px(28.))
.child(
img()
.rounded_full()
.uri("https://avatars.githubusercontent.com/u/1714999?v=4")
.size(px(24.))
.bg(gpui::red()),
),
).child(
div().relative().neg_mx_1().rounded_full().z_index(2)
.border_2()
.border_color(player.background)
.size(px(28.))
.child(
img()
.rounded_full()
.uri("https://avatars.githubusercontent.com/u/1714999?v=4")
.size(px(24.))
.bg(gpui::red()),
),
).child(
div().relative().neg_mx_1().rounded_full().z_index(1)
.border_2()
.border_color(player.background)
.size(px(28.))
.child(
img()
.rounded_full()
.uri("https://avatars.githubusercontent.com/u/1714999?v=4")
.size(px(24.))
.bg(gpui::red()),
),
)
}),
))
.child(Story::label("Player Selections"))
.child(div().flex().flex_col().gap_px().children(
cx.theme().players().0.clone().iter_mut().map(|player| {
div()
.flex()
.child(
div()
.flex()
.flex_none()
.rounded_sm()
.px_0p5()
.text_color(cx.theme().colors().text)
.bg(player.selection)
.child("The brown fox jumped over the lazy dog."),
)
.child(div().flex_1())
}),
)),
)
}
}

View file

@ -144,8 +144,3 @@ pub struct DiagnosticStyle {
pub hint: Hsla, pub hint: Hsla,
pub ignored: Hsla, pub ignored: Hsla,
} }
#[cfg(feature = "stories")]
mod story;
#[cfg(feature = "stories")]
pub use story::*;

View file

@ -17,10 +17,11 @@ menu = { package = "menu2", path = "../menu2"}
serde.workspace = true serde.workspace = true
settings2 = { path = "../settings2" } settings2 = { path = "../settings2" }
smallvec.workspace = true smallvec.workspace = true
story = { path = "../story", optional = true }
strum = { version = "0.25.0", features = ["derive"] } strum = { version = "0.25.0", features = ["derive"] }
theme2 = { path = "../theme2" } theme2 = { path = "../theme2" }
rand = "0.8" rand = "0.8"
[features] [features]
default = [] default = []
stories = ["dep:itertools"] stories = ["dep:itertools", "dep:story"]

View file

@ -1,7 +1,8 @@
use gpui::{Div, Render}; use gpui::{Div, Render};
use story::Story;
use crate::prelude::*; use crate::prelude::*;
use crate::{Avatar, Story}; use crate::Avatar;
pub struct AvatarStory; pub struct AvatarStory;
@ -9,9 +10,9 @@ impl Render for AvatarStory {
type Element = Div; type Element = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
Story::container(cx) Story::container()
.child(Story::title_for::<Avatar>(cx)) .child(Story::title_for::<Avatar>())
.child(Story::label(cx, "Default")) .child(Story::label("Default"))
.child(Avatar::new( .child(Avatar::new(
"https://avatars.githubusercontent.com/u/1714999?v=4", "https://avatars.githubusercontent.com/u/1714999?v=4",
)) ))

View file

@ -1,8 +1,9 @@
use gpui::{rems, Div, Render}; use gpui::{rems, Div, Render};
use story::Story;
use strum::IntoEnumIterator; use strum::IntoEnumIterator;
use crate::prelude::*; use crate::prelude::*;
use crate::{h_stack, v_stack, Button, Icon, IconPosition, Label, Story}; use crate::{h_stack, v_stack, Button, Icon, IconPosition, Label};
pub struct ButtonStory; pub struct ButtonStory;
@ -12,15 +13,15 @@ impl Render for ButtonStory {
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
let states = InteractionState::iter(); let states = InteractionState::iter();
Story::container(cx) Story::container()
.child(Story::title_for::<Button>(cx)) .child(Story::title_for::<Button>())
.child( .child(
div() div()
.flex() .flex()
.gap_8() .gap_8()
.child( .child(
div() div()
.child(Story::label(cx, "Ghost (Default)")) .child(Story::label("Ghost (Default)"))
.child(h_stack().gap_2().children(states.clone().map(|state| { .child(h_stack().gap_2().children(states.clone().map(|state| {
v_stack() v_stack()
.gap_1() .gap_1()
@ -29,7 +30,7 @@ impl Render for ButtonStory {
Button::new("Label").variant(ButtonVariant::Ghost), // .state(state), Button::new("Label").variant(ButtonVariant::Ghost), // .state(state),
) )
}))) })))
.child(Story::label(cx, "Ghost Left Icon")) .child(Story::label("Ghost Left Icon"))
.child(h_stack().gap_2().children(states.clone().map(|state| { .child(h_stack().gap_2().children(states.clone().map(|state| {
v_stack() v_stack()
.gap_1() .gap_1()
@ -41,7 +42,7 @@ impl Render for ButtonStory {
.icon_position(IconPosition::Left), // .state(state), .icon_position(IconPosition::Left), // .state(state),
) )
}))) })))
.child(Story::label(cx, "Ghost Right Icon")) .child(Story::label("Ghost Right Icon"))
.child(h_stack().gap_2().children(states.clone().map(|state| { .child(h_stack().gap_2().children(states.clone().map(|state| {
v_stack() v_stack()
.gap_1() .gap_1()
@ -56,7 +57,7 @@ impl Render for ButtonStory {
) )
.child( .child(
div() div()
.child(Story::label(cx, "Filled")) .child(Story::label("Filled"))
.child(h_stack().gap_2().children(states.clone().map(|state| { .child(h_stack().gap_2().children(states.clone().map(|state| {
v_stack() v_stack()
.gap_1() .gap_1()
@ -65,7 +66,7 @@ impl Render for ButtonStory {
Button::new("Label").variant(ButtonVariant::Filled), // .state(state), Button::new("Label").variant(ButtonVariant::Filled), // .state(state),
) )
}))) })))
.child(Story::label(cx, "Filled Left Button")) .child(Story::label("Filled Left Button"))
.child(h_stack().gap_2().children(states.clone().map(|state| { .child(h_stack().gap_2().children(states.clone().map(|state| {
v_stack() v_stack()
.gap_1() .gap_1()
@ -77,7 +78,7 @@ impl Render for ButtonStory {
.icon_position(IconPosition::Left), // .state(state), .icon_position(IconPosition::Left), // .state(state),
) )
}))) })))
.child(Story::label(cx, "Filled Right Button")) .child(Story::label("Filled Right Button"))
.child(h_stack().gap_2().children(states.clone().map(|state| { .child(h_stack().gap_2().children(states.clone().map(|state| {
v_stack() v_stack()
.gap_1() .gap_1()
@ -92,7 +93,7 @@ impl Render for ButtonStory {
) )
.child( .child(
div() div()
.child(Story::label(cx, "Fixed With")) .child(Story::label("Fixed With"))
.child(h_stack().gap_2().children(states.clone().map(|state| { .child(h_stack().gap_2().children(states.clone().map(|state| {
v_stack() v_stack()
.gap_1() .gap_1()
@ -104,7 +105,7 @@ impl Render for ButtonStory {
.width(Some(rems(6.).into())), .width(Some(rems(6.).into())),
) )
}))) })))
.child(Story::label(cx, "Fixed With Left Icon")) .child(Story::label("Fixed With Left Icon"))
.child(h_stack().gap_2().children(states.clone().map(|state| { .child(h_stack().gap_2().children(states.clone().map(|state| {
v_stack() v_stack()
.gap_1() .gap_1()
@ -118,7 +119,7 @@ impl Render for ButtonStory {
.width(Some(rems(6.).into())), .width(Some(rems(6.).into())),
) )
}))) })))
.child(Story::label(cx, "Fixed With Right Icon")) .child(Story::label("Fixed With Right Icon"))
.child(h_stack().gap_2().children(states.clone().map(|state| { .child(h_stack().gap_2().children(states.clone().map(|state| {
v_stack() v_stack()
.gap_1() .gap_1()
@ -134,7 +135,7 @@ impl Render for ButtonStory {
}))), }))),
), ),
) )
.child(Story::label(cx, "Button with `on_click`")) .child(Story::label("Button with `on_click`"))
.child( .child(
Button::new("Label") Button::new("Label")
.variant(ButtonVariant::Ghost) .variant(ButtonVariant::Ghost)

View file

@ -1,7 +1,8 @@
use gpui::{Div, Render, ViewContext}; use gpui::{Div, Render, ViewContext};
use story::Story;
use crate::prelude::*; use crate::prelude::*;
use crate::{h_stack, Checkbox, Story}; use crate::{h_stack, Checkbox};
pub struct CheckboxStory; pub struct CheckboxStory;
@ -9,9 +10,9 @@ impl Render for CheckboxStory {
type Element = Div; type Element = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
Story::container(cx) Story::container()
.child(Story::title_for::<Checkbox>(cx)) .child(Story::title_for::<Checkbox>())
.child(Story::label(cx, "Default")) .child(Story::label("Default"))
.child( .child(
h_stack() h_stack()
.p_2() .p_2()
@ -26,7 +27,7 @@ impl Render for CheckboxStory {
)) ))
.child(Checkbox::new("checkbox-selected", Selection::Selected)), .child(Checkbox::new("checkbox-selected", Selection::Selected)),
) )
.child(Story::label(cx, "Disabled")) .child(Story::label("Disabled"))
.child( .child(
h_stack() h_stack()
.p_2() .p_2()

View file

@ -1,7 +1,8 @@
use gpui::{actions, Action, AnchorCorner, Div, Render, View}; use gpui::{actions, Action, AnchorCorner, Div, Render, View};
use story::Story;
use crate::prelude::*; use crate::prelude::*;
use crate::{menu_handle, ContextMenu, Label, ListItem, Story}; use crate::{menu_handle, ContextMenu, Label, ListItem};
actions!(PrintCurrentDate, PrintBestFood); actions!(PrintCurrentDate, PrintBestFood);
@ -29,7 +30,7 @@ impl Render for ContextMenuStory {
type Element = Div; type Element = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
Story::container(cx) Story::container()
.on_action(|_: &PrintCurrentDate, _| { .on_action(|_: &PrintCurrentDate, _| {
println!("printing unix time!"); println!("printing unix time!");
if let Ok(unix_time) = std::time::UNIX_EPOCH.elapsed() { if let Ok(unix_time) = std::time::UNIX_EPOCH.elapsed() {

View file

@ -1,8 +1,9 @@
use gpui::{Div, Render}; use gpui::{Div, Render};
use story::Story;
use strum::IntoEnumIterator; use strum::IntoEnumIterator;
use crate::prelude::*; use crate::prelude::*;
use crate::{Icon, IconElement, Story}; use crate::{Icon, IconElement};
pub struct IconStory; pub struct IconStory;
@ -12,9 +13,9 @@ impl Render for IconStory {
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
let icons = Icon::iter(); let icons = Icon::iter();
Story::container(cx) Story::container()
.child(Story::title_for::<IconElement>(cx)) .child(Story::title_for::<IconElement>())
.child(Story::label(cx, "All Icons")) .child(Story::label("All Icons"))
.child(div().flex().gap_3().children(icons.map(IconElement::new))) .child(div().flex().gap_3().children(icons.map(IconElement::new)))
} }
} }

View file

@ -1,7 +1,8 @@
use gpui::{Div, Render}; use gpui::{Div, Render};
use story::Story;
use crate::prelude::*; use crate::prelude::*;
use crate::{Input, Story}; use crate::Input;
pub struct InputStory; pub struct InputStory;
@ -9,9 +10,9 @@ impl Render for InputStory {
type Element = Div; type Element = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
Story::container(cx) Story::container()
.child(Story::title_for::<Input>(cx)) .child(Story::title_for::<Input>())
.child(Story::label(cx, "Default")) .child(Story::label("Default"))
.child(div().flex().child(Input::new("Search"))) .child(div().flex().child(Input::new("Search")))
} }
} }

View file

@ -1,8 +1,9 @@
use gpui::{actions, Div, Render}; use gpui::{actions, Div, Render};
use itertools::Itertools; use itertools::Itertools;
use story::Story;
use crate::prelude::*; use crate::prelude::*;
use crate::{KeyBinding, Story}; use crate::KeyBinding;
pub struct KeybindingStory; pub struct KeybindingStory;
@ -18,11 +19,11 @@ impl Render for KeybindingStory {
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
let all_modifier_permutations = ["ctrl", "alt", "cmd", "shift"].into_iter().permutations(2); let all_modifier_permutations = ["ctrl", "alt", "cmd", "shift"].into_iter().permutations(2);
Story::container(cx) Story::container()
.child(Story::title_for::<KeyBinding>(cx)) .child(Story::title_for::<KeyBinding>())
.child(Story::label(cx, "Single Key")) .child(Story::label("Single Key"))
.child(KeyBinding::new(binding("Z"))) .child(KeyBinding::new(binding("Z")))
.child(Story::label(cx, "Single Key with Modifier")) .child(Story::label("Single Key with Modifier"))
.child( .child(
div() div()
.flex() .flex()
@ -32,7 +33,7 @@ impl Render for KeybindingStory {
.child(KeyBinding::new(binding("cmd-c"))) .child(KeyBinding::new(binding("cmd-c")))
.child(KeyBinding::new(binding("shift-c"))), .child(KeyBinding::new(binding("shift-c"))),
) )
.child(Story::label(cx, "Single Key with Modifier (Permuted)")) .child(Story::label("Single Key with Modifier (Permuted)"))
.child( .child(
div().flex().flex_col().children( div().flex().flex_col().children(
all_modifier_permutations all_modifier_permutations
@ -49,11 +50,11 @@ impl Render for KeybindingStory {
}), }),
), ),
) )
.child(Story::label(cx, "Single Key with All Modifiers")) .child(Story::label("Single Key with All Modifiers"))
.child(KeyBinding::new(binding("ctrl-alt-cmd-shift-z"))) .child(KeyBinding::new(binding("ctrl-alt-cmd-shift-z")))
.child(Story::label(cx, "Chord")) .child(Story::label("Chord"))
.child(KeyBinding::new(binding("a z"))) .child(KeyBinding::new(binding("a z")))
.child(Story::label(cx, "Chord with Modifier")) .child(Story::label("Chord with Modifier"))
.child(KeyBinding::new(binding("ctrl-a shift-z"))) .child(KeyBinding::new(binding("ctrl-a shift-z")))
.child(KeyBinding::new(binding("fn-s"))) .child(KeyBinding::new(binding("fn-s")))
} }

View file

@ -1,7 +1,8 @@
use gpui::{Div, Render}; use gpui::{Div, Render};
use story::Story;
use crate::prelude::*; use crate::prelude::*;
use crate::{HighlightedLabel, Label, Story}; use crate::{HighlightedLabel, Label};
pub struct LabelStory; pub struct LabelStory;
@ -9,11 +10,11 @@ impl Render for LabelStory {
type Element = Div; type Element = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
Story::container(cx) Story::container()
.child(Story::title_for::<Label>(cx)) .child(Story::title_for::<Label>())
.child(Story::label(cx, "Default")) .child(Story::label("Default"))
.child(Label::new("Hello, world!")) .child(Label::new("Hello, world!"))
.child(Story::label(cx, "Highlighted")) .child(Story::label("Highlighted"))
.child(HighlightedLabel::new( .child(HighlightedLabel::new(
"Hello, world!", "Hello, world!",
vec![0, 1, 2, 7, 8, 12], vec![0, 1, 2, 7, 8, 12],

View file

@ -1,37 +0,0 @@
use gpui::Div;
use crate::prelude::*;
pub struct Story {}
impl Story {
pub fn container(cx: &mut gpui::WindowContext) -> Div {
div()
.size_full()
.flex()
.flex_col()
.pt_2()
.px_4()
.bg(cx.theme().colors().background)
}
pub fn title(cx: &mut WindowContext, title: impl Into<SharedString>) -> impl Element {
div()
.text_xl()
.text_color(cx.theme().colors().text)
.child(title.into())
}
pub fn title_for<T>(cx: &mut WindowContext) -> impl Element {
Self::title(cx, std::any::type_name::<T>())
}
pub fn label(cx: &mut WindowContext, label: impl Into<SharedString>) -> impl Element {
div()
.mt_4()
.mb_2()
.text_xs()
.text_color(cx.theme().colors().text)
.child(label.into())
}
}

View file

@ -24,8 +24,3 @@ pub use components::*;
pub use prelude::*; pub use prelude::*;
pub use styled_ext::*; pub use styled_ext::*;
pub use styles::*; pub use styles::*;
#[cfg(feature = "stories")]
mod story;
#[cfg(feature = "stories")]
pub use story::*;