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:
parent
f4b4bdfd83
commit
1b05aad30c
26 changed files with 309 additions and 316 deletions
9
Cargo.lock
generated
9
Cargo.lock
generated
|
@ -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",
|
||||||
]
|
]
|
||||||
|
|
|
@ -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
10
crates/story/Cargo.toml
Normal 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
3
crates/story/src/lib.rs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
mod story;
|
||||||
|
|
||||||
|
pub use story::*;
|
35
crates/story/src/story.rs
Normal file
35
crates/story/src/story.rs
Normal 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())
|
||||||
|
}
|
||||||
|
}
|
|
@ -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" }
|
||||||
|
|
|
@ -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))
|
|
||||||
})),
|
|
||||||
)
|
|
||||||
})),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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" }
|
||||||
|
|
|
@ -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())
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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::*;
|
||||||
|
|
|
@ -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())
|
|
||||||
}),
|
|
||||||
)),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
41
crates/theme2/src/styles/stories/color.rs
Normal file
41
crates/theme2/src/styles/stories/color.rs
Normal 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))),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
})),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
5
crates/theme2/src/styles/stories/mod.rs
Normal file
5
crates/theme2/src/styles/stories/mod.rs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
mod color;
|
||||||
|
mod players;
|
||||||
|
|
||||||
|
pub use color::*;
|
||||||
|
pub use players::*;
|
137
crates/theme2/src/styles/stories/players.rs
Normal file
137
crates/theme2/src/styles/stories/players.rs
Normal 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())
|
||||||
|
}),
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -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::*;
|
|
||||||
|
|
|
@ -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"]
|
||||||
|
|
|
@ -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",
|
||||||
))
|
))
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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")))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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")))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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],
|
||||||
|
|
|
@ -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())
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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::*;
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue