Colocate component stories with their components
This commit is contained in:
parent
b1d88ced61
commit
30088afa89
52 changed files with 1085 additions and 1012 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -9060,6 +9060,7 @@ dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"chrono",
|
"chrono",
|
||||||
"gpui3",
|
"gpui3",
|
||||||
|
"itertools 0.11.0",
|
||||||
"rand 0.8.5",
|
"rand 0.8.5",
|
||||||
"serde",
|
"serde",
|
||||||
"settings",
|
"settings",
|
||||||
|
|
|
@ -1,3 +1,2 @@
|
||||||
pub mod components;
|
|
||||||
pub mod elements;
|
pub mod elements;
|
||||||
pub mod kitchen_sink;
|
pub mod kitchen_sink;
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
pub mod breadcrumb;
|
|
||||||
pub mod buffer;
|
|
||||||
pub mod chat_panel;
|
|
||||||
pub mod collab_panel;
|
|
||||||
pub mod command_palette;
|
|
||||||
pub mod context_menu;
|
|
||||||
pub mod facepile;
|
|
||||||
pub mod keybinding;
|
|
||||||
pub mod language_selector;
|
|
||||||
pub mod multi_buffer;
|
|
||||||
pub mod palette;
|
|
||||||
pub mod panel;
|
|
||||||
pub mod project_panel;
|
|
||||||
pub mod recent_projects;
|
|
||||||
pub mod tab;
|
|
||||||
pub mod tab_bar;
|
|
||||||
pub mod terminal;
|
|
||||||
pub mod theme_selector;
|
|
||||||
pub mod title_bar;
|
|
||||||
pub mod toast;
|
|
||||||
pub mod toolbar;
|
|
||||||
pub mod traffic_lights;
|
|
||||||
pub mod workspace;
|
|
|
@ -1,54 +0,0 @@
|
||||||
use std::marker::PhantomData;
|
|
||||||
use std::path::PathBuf;
|
|
||||||
use std::str::FromStr;
|
|
||||||
|
|
||||||
use ui::prelude::*;
|
|
||||||
use ui::{Breadcrumb, HighlightedText, Symbol};
|
|
||||||
|
|
||||||
use crate::story::Story;
|
|
||||||
|
|
||||||
#[derive(Element)]
|
|
||||||
pub struct BreadcrumbStory<S: 'static + Send + Sync + Clone> {
|
|
||||||
state_type: PhantomData<S>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S: 'static + Send + Sync + Clone> BreadcrumbStory<S> {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
state_type: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
|
||||||
let theme = theme(cx);
|
|
||||||
|
|
||||||
Story::container(cx)
|
|
||||||
.child(Story::title_for::<_, Breadcrumb<S>>(cx))
|
|
||||||
.child(Story::label(cx, "Default"))
|
|
||||||
.child(Breadcrumb::new(
|
|
||||||
PathBuf::from_str("crates/ui/src/components/toolbar.rs").unwrap(),
|
|
||||||
vec![
|
|
||||||
Symbol(vec![
|
|
||||||
HighlightedText {
|
|
||||||
text: "impl ".to_string(),
|
|
||||||
color: HighlightColor::Keyword.hsla(&theme),
|
|
||||||
},
|
|
||||||
HighlightedText {
|
|
||||||
text: "BreadcrumbStory".to_string(),
|
|
||||||
color: HighlightColor::Function.hsla(&theme),
|
|
||||||
},
|
|
||||||
]),
|
|
||||||
Symbol(vec![
|
|
||||||
HighlightedText {
|
|
||||||
text: "fn ".to_string(),
|
|
||||||
color: HighlightColor::Keyword.hsla(&theme),
|
|
||||||
},
|
|
||||||
HighlightedText {
|
|
||||||
text: "render".to_string(),
|
|
||||||
color: HighlightColor::Function.hsla(&theme),
|
|
||||||
},
|
|
||||||
]),
|
|
||||||
],
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,46 +0,0 @@
|
||||||
use std::marker::PhantomData;
|
|
||||||
|
|
||||||
use gpui3::rems;
|
|
||||||
use ui::prelude::*;
|
|
||||||
use ui::{
|
|
||||||
empty_buffer_example, hello_world_rust_buffer_example,
|
|
||||||
hello_world_rust_buffer_with_status_example, Buffer,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::story::Story;
|
|
||||||
|
|
||||||
#[derive(Element)]
|
|
||||||
pub struct BufferStory<S: 'static + Send + Sync + Clone> {
|
|
||||||
state_type: PhantomData<S>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S: 'static + Send + Sync + Clone> BufferStory<S> {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
state_type: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
|
||||||
let theme = theme(cx);
|
|
||||||
|
|
||||||
Story::container(cx)
|
|
||||||
.child(Story::title_for::<_, Buffer<S>>(cx))
|
|
||||||
.child(Story::label(cx, "Default"))
|
|
||||||
.child(div().w(rems(64.)).h_96().child(empty_buffer_example()))
|
|
||||||
.child(Story::label(cx, "Hello World (Rust)"))
|
|
||||||
.child(
|
|
||||||
div()
|
|
||||||
.w(rems(64.))
|
|
||||||
.h_96()
|
|
||||||
.child(hello_world_rust_buffer_example(&theme)),
|
|
||||||
)
|
|
||||||
.child(Story::label(cx, "Hello World (Rust) with Status"))
|
|
||||||
.child(
|
|
||||||
div()
|
|
||||||
.w(rems(64.))
|
|
||||||
.h_96()
|
|
||||||
.child(hello_world_rust_buffer_with_status_example(&theme)),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,56 +0,0 @@
|
||||||
use std::marker::PhantomData;
|
|
||||||
|
|
||||||
use chrono::DateTime;
|
|
||||||
use ui::prelude::*;
|
|
||||||
use ui::{ChatMessage, ChatPanel, Panel};
|
|
||||||
|
|
||||||
use crate::story::Story;
|
|
||||||
|
|
||||||
#[derive(Element)]
|
|
||||||
pub struct ChatPanelStory<S: 'static + Send + Sync + Clone> {
|
|
||||||
state_type: PhantomData<S>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S: 'static + Send + Sync + Clone> ChatPanelStory<S> {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
state_type: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
|
||||||
Story::container(cx)
|
|
||||||
.child(Story::title_for::<_, ChatPanel<S>>(cx))
|
|
||||||
.child(Story::label(cx, "Default"))
|
|
||||||
.child(Panel::new(
|
|
||||||
ScrollState::default(),
|
|
||||||
|_, _| vec![ChatPanel::new(ScrollState::default()).into_any()],
|
|
||||||
Box::new(()),
|
|
||||||
))
|
|
||||||
.child(Story::label(cx, "With Mesages"))
|
|
||||||
.child(Panel::new(
|
|
||||||
ScrollState::default(),
|
|
||||||
|_, _| {
|
|
||||||
vec![ChatPanel::new(ScrollState::default())
|
|
||||||
.with_messages(vec![
|
|
||||||
ChatMessage::new(
|
|
||||||
"osiewicz".to_string(),
|
|
||||||
"is this thing on?".to_string(),
|
|
||||||
DateTime::parse_from_rfc3339("2023-09-27T15:40:52.707Z")
|
|
||||||
.unwrap()
|
|
||||||
.naive_local(),
|
|
||||||
),
|
|
||||||
ChatMessage::new(
|
|
||||||
"maxdeviant".to_string(),
|
|
||||||
"Reading you loud and clear!".to_string(),
|
|
||||||
DateTime::parse_from_rfc3339("2023-09-28T15:40:52.707Z")
|
|
||||||
.unwrap()
|
|
||||||
.naive_local(),
|
|
||||||
),
|
|
||||||
])
|
|
||||||
.into_any()]
|
|
||||||
},
|
|
||||||
Box::new(()),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
use std::marker::PhantomData;
|
|
||||||
|
|
||||||
use ui::prelude::*;
|
|
||||||
use ui::CollabPanel;
|
|
||||||
|
|
||||||
use crate::story::Story;
|
|
||||||
|
|
||||||
#[derive(Element)]
|
|
||||||
pub struct CollabPanelStory<S: 'static + Send + Sync + Clone> {
|
|
||||||
state_type: PhantomData<S>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S: 'static + Send + Sync + Clone> CollabPanelStory<S> {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
state_type: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
|
||||||
Story::container(cx)
|
|
||||||
.child(Story::title_for::<_, CollabPanel<S>>(cx))
|
|
||||||
.child(Story::label(cx, "Default"))
|
|
||||||
.child(CollabPanel::new(ScrollState::default()))
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
use std::marker::PhantomData;
|
|
||||||
|
|
||||||
use ui::prelude::*;
|
|
||||||
use ui::CommandPalette;
|
|
||||||
|
|
||||||
use crate::story::Story;
|
|
||||||
|
|
||||||
#[derive(Element)]
|
|
||||||
pub struct CommandPaletteStory<S: 'static + Send + Sync + Clone> {
|
|
||||||
state_type: PhantomData<S>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S: 'static + Send + Sync + Clone> CommandPaletteStory<S> {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
state_type: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
|
||||||
Story::container(cx)
|
|
||||||
.child(Story::title_for::<_, CommandPalette<S>>(cx))
|
|
||||||
.child(Story::label(cx, "Default"))
|
|
||||||
.child(CommandPalette::new(ScrollState::default()))
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
use std::marker::PhantomData;
|
|
||||||
|
|
||||||
use ui::prelude::*;
|
|
||||||
use ui::{ContextMenu, ContextMenuItem, Label};
|
|
||||||
|
|
||||||
use crate::story::Story;
|
|
||||||
|
|
||||||
#[derive(Element)]
|
|
||||||
pub struct ContextMenuStory<S: 'static + Send + Sync + Clone> {
|
|
||||||
state_type: PhantomData<S>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S: 'static + Send + Sync + Clone> ContextMenuStory<S> {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
state_type: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
|
||||||
Story::container(cx)
|
|
||||||
.child(Story::title_for::<_, ContextMenu<S>>(cx))
|
|
||||||
.child(Story::label(cx, "Default"))
|
|
||||||
.child(ContextMenu::new([
|
|
||||||
ContextMenuItem::header("Section header"),
|
|
||||||
ContextMenuItem::Separator,
|
|
||||||
ContextMenuItem::entry(Label::new("Some entry")),
|
|
||||||
]))
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
use std::marker::PhantomData;
|
|
||||||
|
|
||||||
use ui::prelude::*;
|
|
||||||
use ui::{static_players, Facepile};
|
|
||||||
|
|
||||||
use crate::story::Story;
|
|
||||||
|
|
||||||
#[derive(Element)]
|
|
||||||
pub struct FacepileStory<S: 'static + Send + Sync> {
|
|
||||||
state_type: PhantomData<S>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S: 'static + Send + Sync> FacepileStory<S> {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
state_type: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
|
||||||
let players = static_players();
|
|
||||||
|
|
||||||
Story::container(cx)
|
|
||||||
.child(Story::title_for::<_, Facepile<S>>(cx))
|
|
||||||
.child(Story::label(cx, "Default"))
|
|
||||||
.child(
|
|
||||||
div()
|
|
||||||
.flex()
|
|
||||||
.gap_3()
|
|
||||||
.child(Facepile::new(players.clone().into_iter().take(1)))
|
|
||||||
.child(Facepile::new(players.clone().into_iter().take(2)))
|
|
||||||
.child(Facepile::new(players.clone().into_iter().take(3))),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,74 +0,0 @@
|
||||||
use std::marker::PhantomData;
|
|
||||||
|
|
||||||
use itertools::Itertools;
|
|
||||||
use strum::IntoEnumIterator;
|
|
||||||
use ui::prelude::*;
|
|
||||||
use ui::{Keybinding, ModifierKey, ModifierKeys};
|
|
||||||
|
|
||||||
use crate::story::Story;
|
|
||||||
|
|
||||||
#[derive(Element)]
|
|
||||||
pub struct KeybindingStory<S: 'static + Send + Sync + Clone> {
|
|
||||||
state_type: PhantomData<S>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S: 'static + Send + Sync + Clone> KeybindingStory<S> {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
state_type: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
|
||||||
let all_modifier_permutations = ModifierKey::iter().permutations(2);
|
|
||||||
|
|
||||||
Story::container(cx)
|
|
||||||
.child(Story::title_for::<_, Keybinding<S>>(cx))
|
|
||||||
.child(Story::label(cx, "Single Key"))
|
|
||||||
.child(Keybinding::new("Z".to_string(), ModifierKeys::new()))
|
|
||||||
.child(Story::label(cx, "Single Key with Modifier"))
|
|
||||||
.child(
|
|
||||||
div()
|
|
||||||
.flex()
|
|
||||||
.gap_3()
|
|
||||||
.children(ModifierKey::iter().map(|modifier| {
|
|
||||||
Keybinding::new("C".to_string(), ModifierKeys::new().add(modifier))
|
|
||||||
})),
|
|
||||||
)
|
|
||||||
.child(Story::label(cx, "Single Key with Modifier (Permuted)"))
|
|
||||||
.child(
|
|
||||||
div().flex().flex_col().children(
|
|
||||||
all_modifier_permutations
|
|
||||||
.chunks(4)
|
|
||||||
.into_iter()
|
|
||||||
.map(|chunk| {
|
|
||||||
div()
|
|
||||||
.flex()
|
|
||||||
.gap_4()
|
|
||||||
.py_3()
|
|
||||||
.children(chunk.map(|permutation| {
|
|
||||||
let mut modifiers = ModifierKeys::new();
|
|
||||||
|
|
||||||
for modifier in permutation {
|
|
||||||
modifiers = modifiers.add(modifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
Keybinding::new("X".to_string(), modifiers)
|
|
||||||
}))
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.child(Story::label(cx, "Single Key with All Modifiers"))
|
|
||||||
.child(Keybinding::new("Z".to_string(), ModifierKeys::all()))
|
|
||||||
.child(Story::label(cx, "Chord"))
|
|
||||||
.child(Keybinding::new_chord(
|
|
||||||
("A".to_string(), ModifierKeys::new()),
|
|
||||||
("Z".to_string(), ModifierKeys::new()),
|
|
||||||
))
|
|
||||||
.child(Story::label(cx, "Chord with Modifier"))
|
|
||||||
.child(Keybinding::new_chord(
|
|
||||||
("A".to_string(), ModifierKeys::new().control(true)),
|
|
||||||
("Z".to_string(), ModifierKeys::new().shift(true)),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
use std::marker::PhantomData;
|
|
||||||
|
|
||||||
use ui::prelude::*;
|
|
||||||
use ui::LanguageSelector;
|
|
||||||
|
|
||||||
use crate::story::Story;
|
|
||||||
|
|
||||||
#[derive(Element)]
|
|
||||||
pub struct LanguageSelectorStory<S: 'static + Send + Sync + Clone> {
|
|
||||||
state_type: PhantomData<S>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S: 'static + Send + Sync + Clone> LanguageSelectorStory<S> {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
state_type: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
|
||||||
Story::container(cx)
|
|
||||||
.child(Story::title_for::<_, LanguageSelector<S>>(cx))
|
|
||||||
.child(Story::label(cx, "Default"))
|
|
||||||
.child(LanguageSelector::new())
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
use std::marker::PhantomData;
|
|
||||||
|
|
||||||
use ui::prelude::*;
|
|
||||||
use ui::{hello_world_rust_buffer_example, MultiBuffer};
|
|
||||||
|
|
||||||
use crate::story::Story;
|
|
||||||
|
|
||||||
#[derive(Element)]
|
|
||||||
pub struct MultiBufferStory<S: 'static + Send + Sync + Clone> {
|
|
||||||
state_type: PhantomData<S>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S: 'static + Send + Sync + Clone> MultiBufferStory<S> {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
state_type: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
|
||||||
let theme = theme(cx);
|
|
||||||
|
|
||||||
Story::container(cx)
|
|
||||||
.child(Story::title_for::<_, MultiBuffer<S>>(cx))
|
|
||||||
.child(Story::label(cx, "Default"))
|
|
||||||
.child(MultiBuffer::new(vec![
|
|
||||||
hello_world_rust_buffer_example(&theme),
|
|
||||||
hello_world_rust_buffer_example(&theme),
|
|
||||||
hello_world_rust_buffer_example(&theme),
|
|
||||||
hello_world_rust_buffer_example(&theme),
|
|
||||||
hello_world_rust_buffer_example(&theme),
|
|
||||||
]))
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,63 +0,0 @@
|
||||||
use std::marker::PhantomData;
|
|
||||||
|
|
||||||
use ui::prelude::*;
|
|
||||||
use ui::{Keybinding, ModifierKeys, Palette, PaletteItem};
|
|
||||||
|
|
||||||
use crate::story::Story;
|
|
||||||
|
|
||||||
#[derive(Element)]
|
|
||||||
pub struct PaletteStory<S: 'static + Send + Sync + Clone> {
|
|
||||||
state_type: PhantomData<S>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S: 'static + Send + Sync + Clone> PaletteStory<S> {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
state_type: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
|
||||||
Story::container(cx)
|
|
||||||
.child(Story::title_for::<_, Palette<S>>(cx))
|
|
||||||
.child(Story::label(cx, "Default"))
|
|
||||||
.child(Palette::new(ScrollState::default()))
|
|
||||||
.child(Story::label(cx, "With Items"))
|
|
||||||
.child(
|
|
||||||
Palette::new(ScrollState::default())
|
|
||||||
.placeholder("Execute a command...")
|
|
||||||
.items(vec![
|
|
||||||
PaletteItem::new("theme selector: toggle").keybinding(
|
|
||||||
Keybinding::new_chord(
|
|
||||||
("k".to_string(), ModifierKeys::new().command(true)),
|
|
||||||
("t".to_string(), ModifierKeys::new().command(true)),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
PaletteItem::new("assistant: inline assist").keybinding(Keybinding::new(
|
|
||||||
"enter".to_string(),
|
|
||||||
ModifierKeys::new().command(true),
|
|
||||||
)),
|
|
||||||
PaletteItem::new("assistant: quote selection").keybinding(Keybinding::new(
|
|
||||||
">".to_string(),
|
|
||||||
ModifierKeys::new().command(true),
|
|
||||||
)),
|
|
||||||
PaletteItem::new("assistant: toggle focus").keybinding(Keybinding::new(
|
|
||||||
"?".to_string(),
|
|
||||||
ModifierKeys::new().command(true),
|
|
||||||
)),
|
|
||||||
PaletteItem::new("auto update: check"),
|
|
||||||
PaletteItem::new("auto update: view release notes"),
|
|
||||||
PaletteItem::new("branches: open recent").keybinding(Keybinding::new(
|
|
||||||
"b".to_string(),
|
|
||||||
ModifierKeys::new().command(true).alt(true),
|
|
||||||
)),
|
|
||||||
PaletteItem::new("chat panel: toggle focus"),
|
|
||||||
PaletteItem::new("cli: install"),
|
|
||||||
PaletteItem::new("client: sign in"),
|
|
||||||
PaletteItem::new("client: sign out"),
|
|
||||||
PaletteItem::new("editor: cancel")
|
|
||||||
.keybinding(Keybinding::new("escape".to_string(), ModifierKeys::new())),
|
|
||||||
]),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
use std::marker::PhantomData;
|
|
||||||
|
|
||||||
use ui::prelude::*;
|
|
||||||
use ui::{Label, Panel};
|
|
||||||
|
|
||||||
use crate::story::Story;
|
|
||||||
|
|
||||||
#[derive(Element)]
|
|
||||||
pub struct PanelStory<S: 'static + Send + Sync + Clone> {
|
|
||||||
state_type: PhantomData<S>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S: 'static + Send + Sync + Clone> PanelStory<S> {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
state_type: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
|
||||||
Story::container(cx)
|
|
||||||
.child(Story::title_for::<_, Panel<S>>(cx))
|
|
||||||
.child(Story::label(cx, "Default"))
|
|
||||||
.child(Panel::new(
|
|
||||||
ScrollState::default(),
|
|
||||||
|_, _| {
|
|
||||||
vec![div()
|
|
||||||
.overflow_y_scroll(ScrollState::default())
|
|
||||||
.children((0..100).map(|ix| Label::new(format!("Item {}", ix + 1))))
|
|
||||||
.into_any()]
|
|
||||||
},
|
|
||||||
Box::new(()),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
use std::marker::PhantomData;
|
|
||||||
|
|
||||||
use ui::prelude::*;
|
|
||||||
use ui::{Panel, ProjectPanel};
|
|
||||||
|
|
||||||
use crate::story::Story;
|
|
||||||
|
|
||||||
#[derive(Element)]
|
|
||||||
pub struct ProjectPanelStory<S: 'static + Send + Sync + Clone> {
|
|
||||||
state_type: PhantomData<S>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S: 'static + Send + Sync + Clone> ProjectPanelStory<S> {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
state_type: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
|
||||||
Story::container(cx)
|
|
||||||
.child(Story::title_for::<_, ProjectPanel<S>>(cx))
|
|
||||||
.child(Story::label(cx, "Default"))
|
|
||||||
.child(Panel::new(
|
|
||||||
ScrollState::default(),
|
|
||||||
|_, _| vec![ProjectPanel::new(ScrollState::default()).into_any()],
|
|
||||||
Box::new(()),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
use std::marker::PhantomData;
|
|
||||||
|
|
||||||
use ui::prelude::*;
|
|
||||||
use ui::RecentProjects;
|
|
||||||
|
|
||||||
use crate::story::Story;
|
|
||||||
|
|
||||||
#[derive(Element)]
|
|
||||||
pub struct RecentProjectsStory<S: 'static + Send + Sync + Clone> {
|
|
||||||
state_type: PhantomData<S>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S: 'static + Send + Sync + Clone> RecentProjectsStory<S> {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
state_type: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
|
||||||
Story::container(cx)
|
|
||||||
.child(Story::title_for::<_, RecentProjects<S>>(cx))
|
|
||||||
.child(Story::label(cx, "Default"))
|
|
||||||
.child(RecentProjects::new())
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,101 +0,0 @@
|
||||||
use std::marker::PhantomData;
|
|
||||||
|
|
||||||
use strum::IntoEnumIterator;
|
|
||||||
use ui::prelude::*;
|
|
||||||
use ui::{h_stack, v_stack, Tab};
|
|
||||||
|
|
||||||
use crate::story::Story;
|
|
||||||
|
|
||||||
#[derive(Element)]
|
|
||||||
pub struct TabStory<S: 'static + Send + Sync + Clone> {
|
|
||||||
state_type: PhantomData<S>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S: 'static + Send + Sync + Clone> TabStory<S> {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
state_type: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
|
||||||
let git_statuses = GitStatus::iter();
|
|
||||||
let fs_statuses = FileSystemStatus::iter();
|
|
||||||
|
|
||||||
Story::container(cx)
|
|
||||||
.child(Story::title_for::<_, Tab<S>>(cx))
|
|
||||||
.child(
|
|
||||||
h_stack().child(
|
|
||||||
v_stack()
|
|
||||||
.gap_2()
|
|
||||||
.child(Story::label(cx, "Default"))
|
|
||||||
.child(Tab::new()),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.child(
|
|
||||||
h_stack().child(
|
|
||||||
v_stack().gap_2().child(Story::label(cx, "Current")).child(
|
|
||||||
h_stack()
|
|
||||||
.gap_4()
|
|
||||||
.child(Tab::new().title("Current".to_string()).current(true))
|
|
||||||
.child(Tab::new().title("Not Current".to_string()).current(false)),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.child(
|
|
||||||
h_stack().child(
|
|
||||||
v_stack()
|
|
||||||
.gap_2()
|
|
||||||
.child(Story::label(cx, "Titled"))
|
|
||||||
.child(Tab::new().title("label".to_string())),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.child(
|
|
||||||
h_stack().child(
|
|
||||||
v_stack()
|
|
||||||
.gap_2()
|
|
||||||
.child(Story::label(cx, "With Icon"))
|
|
||||||
.child(
|
|
||||||
Tab::new()
|
|
||||||
.title("label".to_string())
|
|
||||||
.icon(Some(ui::Icon::Envelope)),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.child(
|
|
||||||
h_stack().child(
|
|
||||||
v_stack()
|
|
||||||
.gap_2()
|
|
||||||
.child(Story::label(cx, "Close Side"))
|
|
||||||
.child(
|
|
||||||
h_stack()
|
|
||||||
.gap_4()
|
|
||||||
.child(
|
|
||||||
Tab::new()
|
|
||||||
.title("Left".to_string())
|
|
||||||
.close_side(IconSide::Left),
|
|
||||||
)
|
|
||||||
.child(Tab::new().title("Right".to_string())),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.child(
|
|
||||||
v_stack()
|
|
||||||
.gap_2()
|
|
||||||
.child(Story::label(cx, "Git Status"))
|
|
||||||
.child(h_stack().gap_4().children(git_statuses.map(|git_status| {
|
|
||||||
Tab::new()
|
|
||||||
.title(git_status.to_string())
|
|
||||||
.git_status(git_status)
|
|
||||||
}))),
|
|
||||||
)
|
|
||||||
.child(
|
|
||||||
v_stack()
|
|
||||||
.gap_2()
|
|
||||||
.child(Story::label(cx, "File System Status"))
|
|
||||||
.child(h_stack().gap_4().children(fs_statuses.map(|fs_status| {
|
|
||||||
Tab::new().title(fs_status.to_string()).fs_status(fs_status)
|
|
||||||
}))),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,56 +0,0 @@
|
||||||
use std::marker::PhantomData;
|
|
||||||
|
|
||||||
use ui::prelude::*;
|
|
||||||
use ui::{Tab, TabBar};
|
|
||||||
|
|
||||||
use crate::story::Story;
|
|
||||||
|
|
||||||
#[derive(Element)]
|
|
||||||
pub struct TabBarStory<S: 'static + Send + Sync + Clone> {
|
|
||||||
state_type: PhantomData<S>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S: 'static + Send + Sync + Clone> TabBarStory<S> {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
state_type: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
|
||||||
Story::container(cx)
|
|
||||||
.child(Story::title_for::<_, TabBar<S>>(cx))
|
|
||||||
.child(Story::label(cx, "Default"))
|
|
||||||
.child(TabBar::new(vec![
|
|
||||||
Tab::new()
|
|
||||||
.title("Cargo.toml".to_string())
|
|
||||||
.current(false)
|
|
||||||
.git_status(GitStatus::Modified),
|
|
||||||
Tab::new()
|
|
||||||
.title("Channels Panel".to_string())
|
|
||||||
.current(false),
|
|
||||||
Tab::new()
|
|
||||||
.title("channels_panel.rs".to_string())
|
|
||||||
.current(true)
|
|
||||||
.git_status(GitStatus::Modified),
|
|
||||||
Tab::new()
|
|
||||||
.title("workspace.rs".to_string())
|
|
||||||
.current(false)
|
|
||||||
.git_status(GitStatus::Modified),
|
|
||||||
Tab::new()
|
|
||||||
.title("icon_button.rs".to_string())
|
|
||||||
.current(false),
|
|
||||||
Tab::new()
|
|
||||||
.title("storybook.rs".to_string())
|
|
||||||
.current(false)
|
|
||||||
.git_status(GitStatus::Created),
|
|
||||||
Tab::new().title("theme.rs".to_string()).current(false),
|
|
||||||
Tab::new()
|
|
||||||
.title("theme_registry.rs".to_string())
|
|
||||||
.current(false),
|
|
||||||
Tab::new()
|
|
||||||
.title("styleable_helpers.rs".to_string())
|
|
||||||
.current(false),
|
|
||||||
]))
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
use std::marker::PhantomData;
|
|
||||||
|
|
||||||
use ui::prelude::*;
|
|
||||||
use ui::Terminal;
|
|
||||||
|
|
||||||
use crate::story::Story;
|
|
||||||
|
|
||||||
#[derive(Element)]
|
|
||||||
pub struct TerminalStory<S: 'static + Send + Sync + Clone> {
|
|
||||||
state_type: PhantomData<S>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S: 'static + Send + Sync + Clone> TerminalStory<S> {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
state_type: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
|
||||||
Story::container(cx)
|
|
||||||
.child(Story::title_for::<_, Terminal<S>>(cx))
|
|
||||||
.child(Story::label(cx, "Default"))
|
|
||||||
.child(Terminal::new())
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
use std::marker::PhantomData;
|
|
||||||
|
|
||||||
use ui::prelude::*;
|
|
||||||
use ui::ThemeSelector;
|
|
||||||
|
|
||||||
use crate::story::Story;
|
|
||||||
|
|
||||||
#[derive(Element)]
|
|
||||||
pub struct ThemeSelectorStory<S: 'static + Send + Sync + Clone> {
|
|
||||||
state_type: PhantomData<S>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S: 'static + Send + Sync + Clone> ThemeSelectorStory<S> {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
state_type: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
|
||||||
Story::container(cx)
|
|
||||||
.child(Story::title_for::<_, ThemeSelector<S>>(cx))
|
|
||||||
.child(Story::label(cx, "Default"))
|
|
||||||
.child(ThemeSelector::new())
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
use std::marker::PhantomData;
|
|
||||||
|
|
||||||
use ui::prelude::*;
|
|
||||||
use ui::TitleBar;
|
|
||||||
|
|
||||||
use crate::story::Story;
|
|
||||||
|
|
||||||
#[derive(Element)]
|
|
||||||
pub struct TitleBarStory<S: 'static + Send + Sync + Clone> {
|
|
||||||
state_type: PhantomData<S>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S: 'static + Send + Sync + Clone> TitleBarStory<S> {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
state_type: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
|
||||||
Story::container(cx)
|
|
||||||
.child(Story::title_for::<_, TitleBar<S>>(cx))
|
|
||||||
.child(Story::label(cx, "Default"))
|
|
||||||
.child(TitleBar::new(cx))
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
use std::marker::PhantomData;
|
|
||||||
|
|
||||||
use ui::prelude::*;
|
|
||||||
use ui::{Label, Toast, ToastOrigin};
|
|
||||||
|
|
||||||
use crate::story::Story;
|
|
||||||
|
|
||||||
#[derive(Element)]
|
|
||||||
pub struct ToastStory<S: 'static + Send + Sync + Clone> {
|
|
||||||
state_type: PhantomData<S>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S: 'static + Send + Sync + Clone> ToastStory<S> {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
state_type: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
|
||||||
Story::container(cx)
|
|
||||||
.child(Story::title_for::<_, Toast<S>>(cx))
|
|
||||||
.child(Story::label(cx, "Default"))
|
|
||||||
.child(Toast::new(
|
|
||||||
ToastOrigin::Bottom,
|
|
||||||
|_, _| vec![Label::new("label").into_any()],
|
|
||||||
Box::new(()),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,79 +0,0 @@
|
||||||
use std::marker::PhantomData;
|
|
||||||
use std::path::PathBuf;
|
|
||||||
use std::str::FromStr;
|
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use ui::prelude::*;
|
|
||||||
use ui::{theme, Breadcrumb, HighlightColor, HighlightedText, Icon, IconButton, Symbol, Toolbar};
|
|
||||||
|
|
||||||
use crate::story::Story;
|
|
||||||
|
|
||||||
#[derive(Element)]
|
|
||||||
pub struct ToolbarStory<S: 'static + Send + Sync + Clone> {
|
|
||||||
state_type: PhantomData<S>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S: 'static + Send + Sync + Clone> ToolbarStory<S> {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
state_type: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
|
||||||
let theme = theme(cx);
|
|
||||||
|
|
||||||
struct LeftItemsPayload {
|
|
||||||
pub theme: Arc<Theme>,
|
|
||||||
}
|
|
||||||
|
|
||||||
Story::container(cx)
|
|
||||||
.child(Story::title_for::<_, Toolbar<S>>(cx))
|
|
||||||
.child(Story::label(cx, "Default"))
|
|
||||||
.child(Toolbar::new(
|
|
||||||
|_, payload| {
|
|
||||||
let payload = payload.downcast_ref::<LeftItemsPayload>().unwrap();
|
|
||||||
|
|
||||||
let theme = payload.theme.clone();
|
|
||||||
|
|
||||||
vec![Breadcrumb::new(
|
|
||||||
PathBuf::from_str("crates/ui/src/components/toolbar.rs").unwrap(),
|
|
||||||
vec![
|
|
||||||
Symbol(vec![
|
|
||||||
HighlightedText {
|
|
||||||
text: "impl ".to_string(),
|
|
||||||
color: HighlightColor::Keyword.hsla(&theme),
|
|
||||||
},
|
|
||||||
HighlightedText {
|
|
||||||
text: "ToolbarStory".to_string(),
|
|
||||||
color: HighlightColor::Function.hsla(&theme),
|
|
||||||
},
|
|
||||||
]),
|
|
||||||
Symbol(vec![
|
|
||||||
HighlightedText {
|
|
||||||
text: "fn ".to_string(),
|
|
||||||
color: HighlightColor::Keyword.hsla(&theme),
|
|
||||||
},
|
|
||||||
HighlightedText {
|
|
||||||
text: "render".to_string(),
|
|
||||||
color: HighlightColor::Function.hsla(&theme),
|
|
||||||
},
|
|
||||||
]),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
.into_any()]
|
|
||||||
},
|
|
||||||
Box::new(LeftItemsPayload {
|
|
||||||
theme: theme.clone(),
|
|
||||||
}),
|
|
||||||
|_, _| {
|
|
||||||
vec![
|
|
||||||
IconButton::new(Icon::InlayHint).into_any(),
|
|
||||||
IconButton::new(Icon::MagnifyingGlass).into_any(),
|
|
||||||
IconButton::new(Icon::MagicWand).into_any(),
|
|
||||||
]
|
|
||||||
},
|
|
||||||
Box::new(()),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
use std::marker::PhantomData;
|
|
||||||
|
|
||||||
use ui::prelude::*;
|
|
||||||
use ui::TrafficLights;
|
|
||||||
|
|
||||||
use crate::story::Story;
|
|
||||||
|
|
||||||
#[derive(Element)]
|
|
||||||
pub struct TrafficLightsStory<S: 'static + Send + Sync> {
|
|
||||||
state_type: PhantomData<S>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S: 'static + Send + Sync> TrafficLightsStory<S> {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
state_type: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
|
||||||
Story::container(cx)
|
|
||||||
.child(Story::title_for::<_, TrafficLights<S>>(cx))
|
|
||||||
.child(Story::label(cx, "Default"))
|
|
||||||
.child(TrafficLights::new())
|
|
||||||
.child(Story::label(cx, "Unfocused"))
|
|
||||||
.child(TrafficLights::new().window_has_focus(false))
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
use std::marker::PhantomData;
|
|
||||||
|
|
||||||
use ui::prelude::*;
|
|
||||||
use ui::WorkspaceElement;
|
|
||||||
|
|
||||||
#[derive(Element)]
|
|
||||||
pub struct WorkspaceStory<S: 'static + Send + Sync + Clone> {
|
|
||||||
state_type: PhantomData<S>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S: 'static + Send + Sync + Clone> WorkspaceStory<S> {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
state_type: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
|
||||||
// Just render the workspace without any story boilerplate.
|
|
||||||
WorkspaceElement::new()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -68,39 +68,31 @@ pub enum ComponentStory {
|
||||||
|
|
||||||
impl ComponentStory {
|
impl ComponentStory {
|
||||||
pub fn story<S: 'static + Send + Sync + Clone>(&self) -> AnyElement<S> {
|
pub fn story<S: 'static + Send + Sync + Clone>(&self) -> AnyElement<S> {
|
||||||
use crate::stories::components;
|
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
Self::AssistantPanel => ui::AssistantPanelStory::new().into_any(),
|
Self::AssistantPanel => ui::AssistantPanelStory::new().into_any(),
|
||||||
Self::Buffer => components::buffer::BufferStory::new().into_any(),
|
Self::Buffer => ui::BufferStory::new().into_any(),
|
||||||
Self::Breadcrumb => components::breadcrumb::BreadcrumbStory::new().into_any(),
|
Self::Breadcrumb => ui::BreadcrumbStory::new().into_any(),
|
||||||
Self::ChatPanel => components::chat_panel::ChatPanelStory::new().into_any(),
|
Self::ChatPanel => ui::ChatPanelStory::new().into_any(),
|
||||||
Self::CollabPanel => components::collab_panel::CollabPanelStory::new().into_any(),
|
Self::CollabPanel => ui::CollabPanelStory::new().into_any(),
|
||||||
Self::CommandPalette => {
|
Self::CommandPalette => ui::CommandPaletteStory::new().into_any(),
|
||||||
components::command_palette::CommandPaletteStory::new().into_any()
|
Self::ContextMenu => ui::ContextMenuStory::new().into_any(),
|
||||||
}
|
Self::Facepile => ui::FacepileStory::new().into_any(),
|
||||||
Self::ContextMenu => components::context_menu::ContextMenuStory::new().into_any(),
|
Self::Keybinding => ui::KeybindingStory::new().into_any(),
|
||||||
Self::Facepile => components::facepile::FacepileStory::new().into_any(),
|
Self::LanguageSelector => ui::LanguageSelectorStory::new().into_any(),
|
||||||
Self::Keybinding => components::keybinding::KeybindingStory::new().into_any(),
|
Self::MultiBuffer => ui::MultiBufferStory::new().into_any(),
|
||||||
Self::LanguageSelector => {
|
Self::Palette => ui::PaletteStory::new().into_any(),
|
||||||
components::language_selector::LanguageSelectorStory::new().into_any()
|
Self::Panel => ui::PanelStory::new().into_any(),
|
||||||
}
|
Self::ProjectPanel => ui::ProjectPanelStory::new().into_any(),
|
||||||
Self::MultiBuffer => components::multi_buffer::MultiBufferStory::new().into_any(),
|
Self::RecentProjects => ui::RecentProjectsStory::new().into_any(),
|
||||||
Self::Palette => components::palette::PaletteStory::new().into_any(),
|
Self::Tab => ui::TabStory::new().into_any(),
|
||||||
Self::Panel => components::panel::PanelStory::new().into_any(),
|
Self::TabBar => ui::TabBarStory::new().into_any(),
|
||||||
Self::ProjectPanel => components::project_panel::ProjectPanelStory::new().into_any(),
|
Self::Terminal => ui::TerminalStory::new().into_any(),
|
||||||
Self::RecentProjects => {
|
Self::ThemeSelector => ui::ThemeSelectorStory::new().into_any(),
|
||||||
components::recent_projects::RecentProjectsStory::new().into_any()
|
Self::TitleBar => ui::TitleBarStory::new().into_any(),
|
||||||
}
|
Self::Toast => ui::ToastStory::new().into_any(),
|
||||||
Self::Tab => components::tab::TabStory::new().into_any(),
|
Self::Toolbar => ui::ToolbarStory::new().into_any(),
|
||||||
Self::TabBar => components::tab_bar::TabBarStory::new().into_any(),
|
Self::TrafficLights => ui::TrafficLightsStory::new().into_any(),
|
||||||
Self::Terminal => components::terminal::TerminalStory::new().into_any(),
|
Self::Workspace => ui::WorkspaceStory::new().into_any(),
|
||||||
Self::ThemeSelector => components::theme_selector::ThemeSelectorStory::new().into_any(),
|
|
||||||
Self::TitleBar => components::title_bar::TitleBarStory::new().into_any(),
|
|
||||||
Self::Toast => components::toast::ToastStory::new().into_any(),
|
|
||||||
Self::Toolbar => components::toolbar::ToolbarStory::new().into_any(),
|
|
||||||
Self::TrafficLights => components::traffic_lights::TrafficLightsStory::new().into_any(),
|
|
||||||
Self::Workspace => components::workspace::WorkspaceStory::new().into_any(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ publish = false
|
||||||
anyhow.workspace = true
|
anyhow.workspace = true
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
gpui3 = { path = "../gpui3" }
|
gpui3 = { path = "../gpui3" }
|
||||||
|
itertools = { version = "0.11.0", optional = true }
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
settings = { path = "../settings" }
|
settings = { path = "../settings" }
|
||||||
smallvec.workspace = true
|
smallvec.workspace = true
|
||||||
|
@ -17,4 +18,4 @@ rand = "0.8"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["stories"]
|
default = ["stories"]
|
||||||
stories = []
|
stories = ["dep:itertools"]
|
||||||
|
|
|
@ -94,7 +94,7 @@ pub use stories::*;
|
||||||
|
|
||||||
#[cfg(feature = "stories")]
|
#[cfg(feature = "stories")]
|
||||||
mod stories {
|
mod stories {
|
||||||
use crate::story::Story;
|
use crate::Story;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
|
|
@ -75,3 +75,61 @@ impl<S: 'static + Send + Sync + Clone> Breadcrumb<S> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
pub use stories::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
mod stories {
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
use crate::Story;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[derive(Element)]
|
||||||
|
pub struct BreadcrumbStory<S: 'static + Send + Sync + Clone> {
|
||||||
|
state_type: PhantomData<S>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S: 'static + Send + Sync + Clone> BreadcrumbStory<S> {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
state_type: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
||||||
|
let theme = theme(cx);
|
||||||
|
|
||||||
|
Story::container(cx)
|
||||||
|
.child(Story::title_for::<_, Breadcrumb<S>>(cx))
|
||||||
|
.child(Story::label(cx, "Default"))
|
||||||
|
.child(Breadcrumb::new(
|
||||||
|
PathBuf::from_str("crates/ui/src/components/toolbar.rs").unwrap(),
|
||||||
|
vec![
|
||||||
|
Symbol(vec![
|
||||||
|
HighlightedText {
|
||||||
|
text: "impl ".to_string(),
|
||||||
|
color: HighlightColor::Keyword.hsla(&theme),
|
||||||
|
},
|
||||||
|
HighlightedText {
|
||||||
|
text: "BreadcrumbStory".to_string(),
|
||||||
|
color: HighlightColor::Function.hsla(&theme),
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
Symbol(vec![
|
||||||
|
HighlightedText {
|
||||||
|
text: "fn ".to_string(),
|
||||||
|
color: HighlightColor::Keyword.hsla(&theme),
|
||||||
|
},
|
||||||
|
HighlightedText {
|
||||||
|
text: "render".to_string(),
|
||||||
|
color: HighlightColor::Function.hsla(&theme),
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -236,3 +236,54 @@ impl<S: 'static + Send + Sync + Clone> Buffer<S> {
|
||||||
.children(rows)
|
.children(rows)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
pub use stories::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
mod stories {
|
||||||
|
use gpui3::rems;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
empty_buffer_example, hello_world_rust_buffer_example,
|
||||||
|
hello_world_rust_buffer_with_status_example, Story,
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[derive(Element)]
|
||||||
|
pub struct BufferStory<S: 'static + Send + Sync + Clone> {
|
||||||
|
state_type: PhantomData<S>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S: 'static + Send + Sync + Clone> BufferStory<S> {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
state_type: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
||||||
|
let theme = theme(cx);
|
||||||
|
|
||||||
|
Story::container(cx)
|
||||||
|
.child(Story::title_for::<_, Buffer<S>>(cx))
|
||||||
|
.child(Story::label(cx, "Default"))
|
||||||
|
.child(div().w(rems(64.)).h_96().child(empty_buffer_example()))
|
||||||
|
.child(Story::label(cx, "Hello World (Rust)"))
|
||||||
|
.child(
|
||||||
|
div()
|
||||||
|
.w(rems(64.))
|
||||||
|
.h_96()
|
||||||
|
.child(hello_world_rust_buffer_example(&theme)),
|
||||||
|
)
|
||||||
|
.child(Story::label(cx, "Hello World (Rust) with Status"))
|
||||||
|
.child(
|
||||||
|
div()
|
||||||
|
.w(rems(64.))
|
||||||
|
.h_96()
|
||||||
|
.child(hello_world_rust_buffer_with_status_example(&theme)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -106,3 +106,64 @@ impl<S: 'static + Send + Sync + Clone> ChatMessage<S> {
|
||||||
.child(div().child(Label::new(self.text.clone())))
|
.child(div().child(Label::new(self.text.clone())))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
pub use stories::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
mod stories {
|
||||||
|
use chrono::DateTime;
|
||||||
|
|
||||||
|
use crate::{Panel, Story};
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[derive(Element)]
|
||||||
|
pub struct ChatPanelStory<S: 'static + Send + Sync + Clone> {
|
||||||
|
state_type: PhantomData<S>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S: 'static + Send + Sync + Clone> ChatPanelStory<S> {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
state_type: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
||||||
|
Story::container(cx)
|
||||||
|
.child(Story::title_for::<_, ChatPanel<S>>(cx))
|
||||||
|
.child(Story::label(cx, "Default"))
|
||||||
|
.child(Panel::new(
|
||||||
|
ScrollState::default(),
|
||||||
|
|_, _| vec![ChatPanel::new(ScrollState::default()).into_any()],
|
||||||
|
Box::new(()),
|
||||||
|
))
|
||||||
|
.child(Story::label(cx, "With Mesages"))
|
||||||
|
.child(Panel::new(
|
||||||
|
ScrollState::default(),
|
||||||
|
|_, _| {
|
||||||
|
vec![ChatPanel::new(ScrollState::default())
|
||||||
|
.with_messages(vec![
|
||||||
|
ChatMessage::new(
|
||||||
|
"osiewicz".to_string(),
|
||||||
|
"is this thing on?".to_string(),
|
||||||
|
DateTime::parse_from_rfc3339("2023-09-27T15:40:52.707Z")
|
||||||
|
.unwrap()
|
||||||
|
.naive_local(),
|
||||||
|
),
|
||||||
|
ChatMessage::new(
|
||||||
|
"maxdeviant".to_string(),
|
||||||
|
"Reading you loud and clear!".to_string(),
|
||||||
|
DateTime::parse_from_rfc3339("2023-09-28T15:40:52.707Z")
|
||||||
|
.unwrap()
|
||||||
|
.naive_local(),
|
||||||
|
),
|
||||||
|
])
|
||||||
|
.into_any()]
|
||||||
|
},
|
||||||
|
Box::new(()),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -158,3 +158,33 @@ impl<S: 'static + Send + Sync + Clone> CollabPanel<S> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
pub use stories::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
mod stories {
|
||||||
|
use crate::Story;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[derive(Element)]
|
||||||
|
pub struct CollabPanelStory<S: 'static + Send + Sync + Clone> {
|
||||||
|
state_type: PhantomData<S>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S: 'static + Send + Sync + Clone> CollabPanelStory<S> {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
state_type: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
||||||
|
Story::container(cx)
|
||||||
|
.child(Story::title_for::<_, CollabPanel<S>>(cx))
|
||||||
|
.child(Story::label(cx, "Default"))
|
||||||
|
.child(CollabPanel::new(ScrollState::default()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -27,3 +27,33 @@ impl<S: 'static + Send + Sync + Clone> CommandPalette<S> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
pub use stories::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
mod stories {
|
||||||
|
use crate::Story;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[derive(Element)]
|
||||||
|
pub struct CommandPaletteStory<S: 'static + Send + Sync + Clone> {
|
||||||
|
state_type: PhantomData<S>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S: 'static + Send + Sync + Clone> CommandPaletteStory<S> {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
state_type: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
||||||
|
Story::container(cx)
|
||||||
|
.child(Story::title_for::<_, CommandPalette<S>>(cx))
|
||||||
|
.child(Story::label(cx, "Default"))
|
||||||
|
.child(CommandPalette::new(ScrollState::default()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -65,3 +65,39 @@ impl<S: 'static + Send + Sync + Clone> ContextMenu<S> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
pub use stories::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
mod stories {
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
use crate::story::Story;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[derive(Element)]
|
||||||
|
pub struct ContextMenuStory<S: 'static + Send + Sync + Clone> {
|
||||||
|
state_type: PhantomData<S>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S: 'static + Send + Sync + Clone> ContextMenuStory<S> {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
state_type: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
||||||
|
Story::container(cx)
|
||||||
|
.child(Story::title_for::<_, ContextMenu<S>>(cx))
|
||||||
|
.child(Story::label(cx, "Default"))
|
||||||
|
.child(ContextMenu::new([
|
||||||
|
ContextMenuItem::header("Section header"),
|
||||||
|
ContextMenuItem::Separator,
|
||||||
|
ContextMenuItem::entry(Label::new("Some entry")),
|
||||||
|
]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -30,3 +30,42 @@ impl<S: 'static + Send + Sync> Facepile<S> {
|
||||||
div().p_1().flex().items_center().children(player_list)
|
div().p_1().flex().items_center().children(player_list)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
pub use stories::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
mod stories {
|
||||||
|
use crate::{static_players, Story};
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[derive(Element)]
|
||||||
|
pub struct FacepileStory<S: 'static + Send + Sync> {
|
||||||
|
state_type: PhantomData<S>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S: 'static + Send + Sync> FacepileStory<S> {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
state_type: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
||||||
|
let players = static_players();
|
||||||
|
|
||||||
|
Story::container(cx)
|
||||||
|
.child(Story::title_for::<_, Facepile<S>>(cx))
|
||||||
|
.child(Story::label(cx, "Default"))
|
||||||
|
.child(
|
||||||
|
div()
|
||||||
|
.flex()
|
||||||
|
.gap_3()
|
||||||
|
.child(Facepile::new(players.clone().into_iter().take(1)))
|
||||||
|
.child(Facepile::new(players.clone().into_iter().take(2)))
|
||||||
|
.child(Facepile::new(players.clone().into_iter().take(3))),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -165,3 +165,81 @@ impl ModifierKeys {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
pub use stories::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
mod stories {
|
||||||
|
use itertools::Itertools;
|
||||||
|
|
||||||
|
use crate::Story;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[derive(Element)]
|
||||||
|
pub struct KeybindingStory<S: 'static + Send + Sync + Clone> {
|
||||||
|
state_type: PhantomData<S>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S: 'static + Send + Sync + Clone> KeybindingStory<S> {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
state_type: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
||||||
|
let all_modifier_permutations = ModifierKey::iter().permutations(2);
|
||||||
|
|
||||||
|
Story::container(cx)
|
||||||
|
.child(Story::title_for::<_, Keybinding<S>>(cx))
|
||||||
|
.child(Story::label(cx, "Single Key"))
|
||||||
|
.child(Keybinding::new("Z".to_string(), ModifierKeys::new()))
|
||||||
|
.child(Story::label(cx, "Single Key with Modifier"))
|
||||||
|
.child(
|
||||||
|
div()
|
||||||
|
.flex()
|
||||||
|
.gap_3()
|
||||||
|
.children(ModifierKey::iter().map(|modifier| {
|
||||||
|
Keybinding::new("C".to_string(), ModifierKeys::new().add(modifier))
|
||||||
|
})),
|
||||||
|
)
|
||||||
|
.child(Story::label(cx, "Single Key with Modifier (Permuted)"))
|
||||||
|
.child(
|
||||||
|
div().flex().flex_col().children(
|
||||||
|
all_modifier_permutations
|
||||||
|
.chunks(4)
|
||||||
|
.into_iter()
|
||||||
|
.map(|chunk| {
|
||||||
|
div()
|
||||||
|
.flex()
|
||||||
|
.gap_4()
|
||||||
|
.py_3()
|
||||||
|
.children(chunk.map(|permutation| {
|
||||||
|
let mut modifiers = ModifierKeys::new();
|
||||||
|
|
||||||
|
for modifier in permutation {
|
||||||
|
modifiers = modifiers.add(modifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
Keybinding::new("X".to_string(), modifiers)
|
||||||
|
}))
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.child(Story::label(cx, "Single Key with All Modifiers"))
|
||||||
|
.child(Keybinding::new("Z".to_string(), ModifierKeys::all()))
|
||||||
|
.child(Story::label(cx, "Chord"))
|
||||||
|
.child(Keybinding::new_chord(
|
||||||
|
("A".to_string(), ModifierKeys::new()),
|
||||||
|
("Z".to_string(), ModifierKeys::new()),
|
||||||
|
))
|
||||||
|
.child(Story::label(cx, "Chord with Modifier"))
|
||||||
|
.child(Keybinding::new_chord(
|
||||||
|
("A".to_string(), ModifierKeys::new().control(true)),
|
||||||
|
("Z".to_string(), ModifierKeys::new().shift(true)),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -38,3 +38,33 @@ impl<S: 'static + Send + Sync + Clone> LanguageSelector<S> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
pub use stories::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
mod stories {
|
||||||
|
use crate::Story;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[derive(Element)]
|
||||||
|
pub struct LanguageSelectorStory<S: 'static + Send + Sync + Clone> {
|
||||||
|
state_type: PhantomData<S>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S: 'static + Send + Sync + Clone> LanguageSelectorStory<S> {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
state_type: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
||||||
|
Story::container(cx)
|
||||||
|
.child(Story::title_for::<_, LanguageSelector<S>>(cx))
|
||||||
|
.child(Story::label(cx, "Default"))
|
||||||
|
.child(LanguageSelector::new())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -40,3 +40,41 @@ impl<S: 'static + Send + Sync + Clone> MultiBuffer<S> {
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
pub use stories::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
mod stories {
|
||||||
|
use crate::{hello_world_rust_buffer_example, Story};
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[derive(Element)]
|
||||||
|
pub struct MultiBufferStory<S: 'static + Send + Sync + Clone> {
|
||||||
|
state_type: PhantomData<S>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S: 'static + Send + Sync + Clone> MultiBufferStory<S> {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
state_type: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
||||||
|
let theme = theme(cx);
|
||||||
|
|
||||||
|
Story::container(cx)
|
||||||
|
.child(Story::title_for::<_, MultiBuffer<S>>(cx))
|
||||||
|
.child(Story::label(cx, "Default"))
|
||||||
|
.child(MultiBuffer::new(vec![
|
||||||
|
hello_world_rust_buffer_example(&theme),
|
||||||
|
hello_world_rust_buffer_example(&theme),
|
||||||
|
hello_world_rust_buffer_example(&theme),
|
||||||
|
hello_world_rust_buffer_example(&theme),
|
||||||
|
hello_world_rust_buffer_example(&theme),
|
||||||
|
]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -150,3 +150,72 @@ impl<S: 'static + Send + Sync + Clone> PaletteItem<S> {
|
||||||
.children(self.keybinding.clone())
|
.children(self.keybinding.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
pub use stories::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
mod stories {
|
||||||
|
use crate::{ModifierKeys, Story};
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[derive(Element)]
|
||||||
|
pub struct PaletteStory<S: 'static + Send + Sync + Clone> {
|
||||||
|
state_type: PhantomData<S>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S: 'static + Send + Sync + Clone> PaletteStory<S> {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
state_type: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
||||||
|
Story::container(cx)
|
||||||
|
.child(Story::title_for::<_, Palette<S>>(cx))
|
||||||
|
.child(Story::label(cx, "Default"))
|
||||||
|
.child(Palette::new(ScrollState::default()))
|
||||||
|
.child(Story::label(cx, "With Items"))
|
||||||
|
.child(
|
||||||
|
Palette::new(ScrollState::default())
|
||||||
|
.placeholder("Execute a command...")
|
||||||
|
.items(vec![
|
||||||
|
PaletteItem::new("theme selector: toggle").keybinding(
|
||||||
|
Keybinding::new_chord(
|
||||||
|
("k".to_string(), ModifierKeys::new().command(true)),
|
||||||
|
("t".to_string(), ModifierKeys::new().command(true)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
PaletteItem::new("assistant: inline assist").keybinding(
|
||||||
|
Keybinding::new(
|
||||||
|
"enter".to_string(),
|
||||||
|
ModifierKeys::new().command(true),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
PaletteItem::new("assistant: quote selection").keybinding(
|
||||||
|
Keybinding::new(">".to_string(), ModifierKeys::new().command(true)),
|
||||||
|
),
|
||||||
|
PaletteItem::new("assistant: toggle focus").keybinding(
|
||||||
|
Keybinding::new("?".to_string(), ModifierKeys::new().command(true)),
|
||||||
|
),
|
||||||
|
PaletteItem::new("auto update: check"),
|
||||||
|
PaletteItem::new("auto update: view release notes"),
|
||||||
|
PaletteItem::new("branches: open recent").keybinding(Keybinding::new(
|
||||||
|
"b".to_string(),
|
||||||
|
ModifierKeys::new().command(true).alt(true),
|
||||||
|
)),
|
||||||
|
PaletteItem::new("chat panel: toggle focus"),
|
||||||
|
PaletteItem::new("cli: install"),
|
||||||
|
PaletteItem::new("client: sign in"),
|
||||||
|
PaletteItem::new("client: sign out"),
|
||||||
|
PaletteItem::new("editor: cancel").keybinding(Keybinding::new(
|
||||||
|
"escape".to_string(),
|
||||||
|
ModifierKeys::new(),
|
||||||
|
)),
|
||||||
|
]),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -143,3 +143,42 @@ impl<S: 'static + Send + Sync> Panel<S> {
|
||||||
panel_base.children_any((self.children)(cx, self.payload.as_ref()))
|
panel_base.children_any((self.children)(cx, self.payload.as_ref()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
pub use stories::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
mod stories {
|
||||||
|
use crate::{Label, Story};
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[derive(Element)]
|
||||||
|
pub struct PanelStory<S: 'static + Send + Sync + Clone> {
|
||||||
|
state_type: PhantomData<S>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S: 'static + Send + Sync + Clone> PanelStory<S> {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
state_type: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
||||||
|
Story::container(cx)
|
||||||
|
.child(Story::title_for::<_, Panel<S>>(cx))
|
||||||
|
.child(Story::label(cx, "Default"))
|
||||||
|
.child(Panel::new(
|
||||||
|
ScrollState::default(),
|
||||||
|
|_, _| {
|
||||||
|
vec![div()
|
||||||
|
.overflow_y_scroll(ScrollState::default())
|
||||||
|
.children((0..100).map(|ix| Label::new(format!("Item {}", ix + 1))))
|
||||||
|
.into_any()]
|
||||||
|
},
|
||||||
|
Box::new(()),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -56,3 +56,37 @@ impl<S: 'static + Send + Sync + Clone> ProjectPanel<S> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
pub use stories::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
mod stories {
|
||||||
|
use crate::{Panel, Story};
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[derive(Element)]
|
||||||
|
pub struct ProjectPanelStory<S: 'static + Send + Sync + Clone> {
|
||||||
|
state_type: PhantomData<S>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S: 'static + Send + Sync + Clone> ProjectPanelStory<S> {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
state_type: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
||||||
|
Story::container(cx)
|
||||||
|
.child(Story::title_for::<_, ProjectPanel<S>>(cx))
|
||||||
|
.child(Story::label(cx, "Default"))
|
||||||
|
.child(Panel::new(
|
||||||
|
ScrollState::default(),
|
||||||
|
|_, _| vec![ProjectPanel::new(ScrollState::default()).into_any()],
|
||||||
|
Box::new(()),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -34,3 +34,33 @@ impl<S: 'static + Send + Sync + Clone> RecentProjects<S> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
pub use stories::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
mod stories {
|
||||||
|
use crate::Story;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[derive(Element)]
|
||||||
|
pub struct RecentProjectsStory<S: 'static + Send + Sync + Clone> {
|
||||||
|
state_type: PhantomData<S>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S: 'static + Send + Sync + Clone> RecentProjectsStory<S> {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
state_type: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
||||||
|
Story::container(cx)
|
||||||
|
.child(Story::title_for::<_, RecentProjects<S>>(cx))
|
||||||
|
.child(Story::label(cx, "Default"))
|
||||||
|
.child(RecentProjects::new())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -133,3 +133,109 @@ impl<S: 'static + Send + Sync + Clone> Tab<S> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
pub use stories::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
mod stories {
|
||||||
|
use strum::IntoEnumIterator;
|
||||||
|
|
||||||
|
use crate::{h_stack, v_stack, Icon, Story};
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[derive(Element)]
|
||||||
|
pub struct TabStory<S: 'static + Send + Sync + Clone> {
|
||||||
|
state_type: PhantomData<S>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S: 'static + Send + Sync + Clone> TabStory<S> {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
state_type: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
||||||
|
let git_statuses = GitStatus::iter();
|
||||||
|
let fs_statuses = FileSystemStatus::iter();
|
||||||
|
|
||||||
|
Story::container(cx)
|
||||||
|
.child(Story::title_for::<_, Tab<S>>(cx))
|
||||||
|
.child(
|
||||||
|
h_stack().child(
|
||||||
|
v_stack()
|
||||||
|
.gap_2()
|
||||||
|
.child(Story::label(cx, "Default"))
|
||||||
|
.child(Tab::new()),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
h_stack().child(
|
||||||
|
v_stack().gap_2().child(Story::label(cx, "Current")).child(
|
||||||
|
h_stack()
|
||||||
|
.gap_4()
|
||||||
|
.child(Tab::new().title("Current".to_string()).current(true))
|
||||||
|
.child(Tab::new().title("Not Current".to_string()).current(false)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
h_stack().child(
|
||||||
|
v_stack()
|
||||||
|
.gap_2()
|
||||||
|
.child(Story::label(cx, "Titled"))
|
||||||
|
.child(Tab::new().title("label".to_string())),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
h_stack().child(
|
||||||
|
v_stack()
|
||||||
|
.gap_2()
|
||||||
|
.child(Story::label(cx, "With Icon"))
|
||||||
|
.child(
|
||||||
|
Tab::new()
|
||||||
|
.title("label".to_string())
|
||||||
|
.icon(Some(Icon::Envelope)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
h_stack().child(
|
||||||
|
v_stack()
|
||||||
|
.gap_2()
|
||||||
|
.child(Story::label(cx, "Close Side"))
|
||||||
|
.child(
|
||||||
|
h_stack()
|
||||||
|
.gap_4()
|
||||||
|
.child(
|
||||||
|
Tab::new()
|
||||||
|
.title("Left".to_string())
|
||||||
|
.close_side(IconSide::Left),
|
||||||
|
)
|
||||||
|
.child(Tab::new().title("Right".to_string())),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
v_stack()
|
||||||
|
.gap_2()
|
||||||
|
.child(Story::label(cx, "Git Status"))
|
||||||
|
.child(h_stack().gap_4().children(git_statuses.map(|git_status| {
|
||||||
|
Tab::new()
|
||||||
|
.title(git_status.to_string())
|
||||||
|
.git_status(git_status)
|
||||||
|
}))),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
v_stack()
|
||||||
|
.gap_2()
|
||||||
|
.child(Story::label(cx, "File System Status"))
|
||||||
|
.child(h_stack().gap_4().children(fs_statuses.map(|fs_status| {
|
||||||
|
Tab::new().title(fs_status.to_string()).fs_status(fs_status)
|
||||||
|
}))),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -83,3 +83,63 @@ impl<S: 'static + Send + Sync + Clone> TabBar<S> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
pub use stories::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
mod stories {
|
||||||
|
use crate::Story;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[derive(Element)]
|
||||||
|
pub struct TabBarStory<S: 'static + Send + Sync + Clone> {
|
||||||
|
state_type: PhantomData<S>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S: 'static + Send + Sync + Clone> TabBarStory<S> {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
state_type: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
||||||
|
Story::container(cx)
|
||||||
|
.child(Story::title_for::<_, TabBar<S>>(cx))
|
||||||
|
.child(Story::label(cx, "Default"))
|
||||||
|
.child(TabBar::new(vec![
|
||||||
|
Tab::new()
|
||||||
|
.title("Cargo.toml".to_string())
|
||||||
|
.current(false)
|
||||||
|
.git_status(GitStatus::Modified),
|
||||||
|
Tab::new()
|
||||||
|
.title("Channels Panel".to_string())
|
||||||
|
.current(false),
|
||||||
|
Tab::new()
|
||||||
|
.title("channels_panel.rs".to_string())
|
||||||
|
.current(true)
|
||||||
|
.git_status(GitStatus::Modified),
|
||||||
|
Tab::new()
|
||||||
|
.title("workspace.rs".to_string())
|
||||||
|
.current(false)
|
||||||
|
.git_status(GitStatus::Modified),
|
||||||
|
Tab::new()
|
||||||
|
.title("icon_button.rs".to_string())
|
||||||
|
.current(false),
|
||||||
|
Tab::new()
|
||||||
|
.title("storybook.rs".to_string())
|
||||||
|
.current(false)
|
||||||
|
.git_status(GitStatus::Created),
|
||||||
|
Tab::new().title("theme.rs".to_string()).current(false),
|
||||||
|
Tab::new()
|
||||||
|
.title("theme_registry.rs".to_string())
|
||||||
|
.current(false),
|
||||||
|
Tab::new()
|
||||||
|
.title("styleable_helpers.rs".to_string())
|
||||||
|
.current(false),
|
||||||
|
]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -87,3 +87,33 @@ impl<S: 'static + Send + Sync + Clone> Terminal<S> {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
pub use stories::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
mod stories {
|
||||||
|
use crate::Story;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[derive(Element)]
|
||||||
|
pub struct TerminalStory<S: 'static + Send + Sync + Clone> {
|
||||||
|
state_type: PhantomData<S>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S: 'static + Send + Sync + Clone> TerminalStory<S> {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
state_type: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
||||||
|
Story::container(cx)
|
||||||
|
.child(Story::title_for::<_, Terminal<S>>(cx))
|
||||||
|
.child(Story::label(cx, "Default"))
|
||||||
|
.child(Terminal::new())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -39,3 +39,33 @@ impl<S: 'static + Send + Sync + Clone> ThemeSelector<S> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
pub use stories::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
mod stories {
|
||||||
|
use crate::Story;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[derive(Element)]
|
||||||
|
pub struct ThemeSelectorStory<S: 'static + Send + Sync + Clone> {
|
||||||
|
state_type: PhantomData<S>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S: 'static + Send + Sync + Clone> ThemeSelectorStory<S> {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
state_type: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
||||||
|
Story::container(cx)
|
||||||
|
.child(Story::title_for::<_, ThemeSelector<S>>(cx))
|
||||||
|
.child(Story::label(cx, "Default"))
|
||||||
|
.child(ThemeSelector::new())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -117,3 +117,33 @@ impl<S: 'static + Send + Sync + Clone> TitleBar<S> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
pub use stories::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
mod stories {
|
||||||
|
use crate::Story;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[derive(Element)]
|
||||||
|
pub struct TitleBarStory<S: 'static + Send + Sync + Clone> {
|
||||||
|
state_type: PhantomData<S>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S: 'static + Send + Sync + Clone> TitleBarStory<S> {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
state_type: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
||||||
|
Story::container(cx)
|
||||||
|
.child(Story::title_for::<_, TitleBar<S>>(cx))
|
||||||
|
.child(Story::label(cx, "Default"))
|
||||||
|
.child(TitleBar::new(cx))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -65,3 +65,39 @@ impl<S: 'static + Send + Sync> Toast<S> {
|
||||||
.children_any((self.children)(cx, self.payload.as_ref()))
|
.children_any((self.children)(cx, self.payload.as_ref()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
pub use stories::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
mod stories {
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
use crate::{Label, Story};
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[derive(Element)]
|
||||||
|
pub struct ToastStory<S: 'static + Send + Sync + Clone> {
|
||||||
|
state_type: PhantomData<S>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S: 'static + Send + Sync + Clone> ToastStory<S> {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
state_type: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
||||||
|
Story::container(cx)
|
||||||
|
.child(Story::title_for::<_, Toast<S>>(cx))
|
||||||
|
.child(Story::label(cx, "Default"))
|
||||||
|
.child(Toast::new(
|
||||||
|
ToastOrigin::Bottom,
|
||||||
|
|_, _| vec![Label::new("label").into_any()],
|
||||||
|
Box::new(()),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -47,3 +47,88 @@ impl<S: 'static + Send + Sync> Toolbar<S> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
pub use stories::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
mod stories {
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use std::str::FromStr;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use crate::{Breadcrumb, HighlightedText, Icon, IconButton, Story, Symbol};
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[derive(Element)]
|
||||||
|
pub struct ToolbarStory<S: 'static + Send + Sync + Clone> {
|
||||||
|
state_type: PhantomData<S>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S: 'static + Send + Sync + Clone> ToolbarStory<S> {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
state_type: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
||||||
|
let theme = theme(cx);
|
||||||
|
|
||||||
|
struct LeftItemsPayload {
|
||||||
|
pub theme: Arc<Theme>,
|
||||||
|
}
|
||||||
|
|
||||||
|
Story::container(cx)
|
||||||
|
.child(Story::title_for::<_, Toolbar<S>>(cx))
|
||||||
|
.child(Story::label(cx, "Default"))
|
||||||
|
.child(Toolbar::new(
|
||||||
|
|_, payload| {
|
||||||
|
let payload = payload.downcast_ref::<LeftItemsPayload>().unwrap();
|
||||||
|
|
||||||
|
let theme = payload.theme.clone();
|
||||||
|
|
||||||
|
vec![Breadcrumb::new(
|
||||||
|
PathBuf::from_str("crates/ui/src/components/toolbar.rs").unwrap(),
|
||||||
|
vec![
|
||||||
|
Symbol(vec![
|
||||||
|
HighlightedText {
|
||||||
|
text: "impl ".to_string(),
|
||||||
|
color: HighlightColor::Keyword.hsla(&theme),
|
||||||
|
},
|
||||||
|
HighlightedText {
|
||||||
|
text: "ToolbarStory".to_string(),
|
||||||
|
color: HighlightColor::Function.hsla(&theme),
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
Symbol(vec![
|
||||||
|
HighlightedText {
|
||||||
|
text: "fn ".to_string(),
|
||||||
|
color: HighlightColor::Keyword.hsla(&theme),
|
||||||
|
},
|
||||||
|
HighlightedText {
|
||||||
|
text: "render".to_string(),
|
||||||
|
color: HighlightColor::Function.hsla(&theme),
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
.into_any()]
|
||||||
|
},
|
||||||
|
Box::new(LeftItemsPayload {
|
||||||
|
theme: theme.clone(),
|
||||||
|
}),
|
||||||
|
|_, _| {
|
||||||
|
vec![
|
||||||
|
IconButton::new(Icon::InlayHint).into_any(),
|
||||||
|
IconButton::new(Icon::MagnifyingGlass).into_any(),
|
||||||
|
IconButton::new(Icon::MagicWand).into_any(),
|
||||||
|
]
|
||||||
|
},
|
||||||
|
Box::new(()),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -82,3 +82,35 @@ impl<S: 'static + Send + Sync> TrafficLights<S> {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
pub use stories::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
mod stories {
|
||||||
|
use crate::Story;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[derive(Element)]
|
||||||
|
pub struct TrafficLightsStory<S: 'static + Send + Sync> {
|
||||||
|
state_type: PhantomData<S>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S: 'static + Send + Sync> TrafficLightsStory<S> {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
state_type: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
||||||
|
Story::container(cx)
|
||||||
|
.child(Story::title_for::<_, TrafficLights<S>>(cx))
|
||||||
|
.child(Story::label(cx, "Default"))
|
||||||
|
.child(TrafficLights::new())
|
||||||
|
.child(Story::label(cx, "Unfocused"))
|
||||||
|
.child(TrafficLights::new().window_has_focus(false))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -195,3 +195,29 @@ impl<S: 'static + Send + Sync + Clone> WorkspaceElement<S> {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
pub use stories::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "stories")]
|
||||||
|
mod stories {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[derive(Element)]
|
||||||
|
pub struct WorkspaceStory<S: 'static + Send + Sync + Clone> {
|
||||||
|
state_type: PhantomData<S>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S: 'static + Send + Sync + Clone> WorkspaceStory<S> {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
state_type: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
|
||||||
|
// Just render the workspace without any story boilerplate.
|
||||||
|
WorkspaceElement::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue