diff --git a/Cargo.lock b/Cargo.lock index 8c0f51e2893f53c3e6ef78dbd5ef711f8d9dc95c..85d3f9ac3a68aa8a420910dfa61102f03c9812ef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3418,19 +3418,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "console" -version = "0.15.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8" -dependencies = [ - "encode_unicode", - "libc", - "once_cell", - "unicode-width", - "windows-sys 0.59.0", -] - [[package]] name = "console_error_panic_hook" version = "0.1.7" @@ -4851,20 +4838,6 @@ dependencies = [ "zlog", ] -[[package]] -name = "dialoguer" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "658bce805d770f407bc62102fca7c2c64ceef2fbcb2b8bd19d2765ce093980de" -dependencies = [ - "console", - "fuzzy-matcher", - "shell-words", - "tempfile", - "thiserror 1.0.69", - "zeroize", -] - [[package]] name = "diff" version = "0.1.13" @@ -5546,12 +5519,6 @@ dependencies = [ "phf 0.11.3", ] -[[package]] -name = "encode_unicode" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" - [[package]] name = "encoding_rs" version = "0.8.35" @@ -6747,15 +6714,6 @@ dependencies = [ "util", ] -[[package]] -name = "fuzzy-matcher" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54614a3312934d066701a80f20f15fa3b56d67ac7722b39eea5b4c9dd1d66c94" -dependencies = [ - "thread_local", -] - [[package]] name = "fuzzy_nucleo" version = "0.1.0" @@ -16745,44 +16703,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" -[[package]] -name = "story" -version = "0.1.0" -dependencies = [ - "gpui", - "itertools 0.14.0", - "smallvec", -] - -[[package]] -name = "storybook" -version = "0.1.0" -dependencies = [ - "anyhow", - "clap", - "ctrlc", - "dialoguer", - "editor", - "fuzzy", - "gpui", - "gpui_platform", - "indoc", - "language", - "log", - "menu", - "picker", - "reqwest_client", - "rust-embed", - "settings", - "simplelog", - "story", - "strum 0.27.2", - "theme", - "theme_settings", - "title_bar", - "ui", -] - [[package]] name = "streaming-iterator" version = "0.1.9" @@ -17704,7 +17624,6 @@ version = "0.1.0" dependencies = [ "anyhow", "collections", - "derive_more", "gpui", "palette", "parking_lot", @@ -18027,7 +17946,6 @@ dependencies = [ "serde", "settings", "smallvec", - "story", "telemetry", "theme", "ui", @@ -18926,7 +18844,6 @@ dependencies = [ "schemars", "serde", "smallvec", - "story", "strum 0.27.2", "theme", "ui_macros", diff --git a/Cargo.toml b/Cargo.toml index 59f8e265694f060c9f65b30143b79e324de1f08c..b9e99a5a87020a7eda8c8a2983bcf7b07fabc82c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -183,8 +183,6 @@ members = [ "crates/snippets_ui", "crates/sqlez", "crates/sqlez_macros", - "crates/story", - "crates/storybook", "crates/streaming_diff", "crates/sum_tree", "crates/svg_preview", @@ -437,7 +435,6 @@ snippet_provider = { path = "crates/snippet_provider" } snippets_ui = { path = "crates/snippets_ui" } sqlez = { path = "crates/sqlez" } sqlez_macros = { path = "crates/sqlez_macros" } -story = { path = "crates/story" } streaming_diff = { path = "crates/streaming_diff" } sum_tree = { path = "crates/sum_tree" } codestral = { path = "crates/codestral" } @@ -935,7 +932,6 @@ session = { codegen-units = 1 } sidebar = { codegen-units = 1 } snippet = { codegen-units = 1 } snippets_ui = { codegen-units = 1 } -story = { codegen-units = 1 } telemetry_events = { codegen-units = 1 } theme_selector = { codegen-units = 1 } time_format = { codegen-units = 1 } diff --git a/crates/story/Cargo.toml b/crates/story/Cargo.toml deleted file mode 100644 index 798461402de00c102af9325c091eb9edfdf89b09..0000000000000000000000000000000000000000 --- a/crates/story/Cargo.toml +++ /dev/null @@ -1,17 +0,0 @@ -[package] -name = "story" -version = "0.1.0" -edition.workspace = true -publish.workspace = true -license = "GPL-3.0-or-later" - -[lib] -path = "src/story.rs" - -[lints] -workspace = true - -[dependencies] -gpui.workspace = true -itertools.workspace = true -smallvec.workspace = true diff --git a/crates/story/LICENSE-GPL b/crates/story/LICENSE-GPL deleted file mode 120000 index 89e542f750cd3860a0598eff0dc34b56d7336dc4..0000000000000000000000000000000000000000 --- a/crates/story/LICENSE-GPL +++ /dev/null @@ -1 +0,0 @@ -../../LICENSE-GPL \ No newline at end of file diff --git a/crates/story/src/story.rs b/crates/story/src/story.rs deleted file mode 100644 index b59cb6fb99086de7eb22ab2645dc01dbe15fb959..0000000000000000000000000000000000000000 --- a/crates/story/src/story.rs +++ /dev/null @@ -1,209 +0,0 @@ -use gpui::{ - AnyElement, App, Div, SharedString, Window, colors::DefaultColors, div, prelude::*, px, rems, -}; -use itertools::Itertools; -use smallvec::SmallVec; - -pub struct Story {} - -impl Story { - pub fn container(cx: &App) -> gpui::Stateful
{ - div() - .id("story_container") - .overflow_y_scroll() - .w_full() - .min_h_full() - .flex() - .flex_col() - .text_color(cx.default_colors().text) - .bg(cx.default_colors().background) - } - - pub fn title(title: impl Into, cx: &App) -> impl Element { - div() - .text_xs() - .text_color(cx.default_colors().text) - .child(title.into()) - } - - pub fn title_for(cx: &App) -> impl Element { - Self::title(std::any::type_name::(), cx) - } - - pub fn section(cx: &App) -> Div { - div() - .p_4() - .m_4() - .border_1() - .border_color(cx.default_colors().separator) - } - - pub fn section_title(cx: &App) -> Div { - div().text_lg().text_color(cx.default_colors().text) - } - - pub fn group(cx: &App) -> Div { - div().my_2().bg(cx.default_colors().container) - } - - pub fn code_block(code: impl Into, cx: &App) -> Div { - div() - .size_full() - .p_2() - .max_w(rems(36.)) - .bg(cx.default_colors().container) - .rounded_sm() - .text_sm() - .text_color(cx.default_colors().text) - .overflow_hidden() - .child(code.into()) - } - - pub fn divider(cx: &App) -> Div { - div().my_2().h(px(1.)).bg(cx.default_colors().separator) - } - - pub fn description(description: impl Into, cx: &App) -> impl Element { - div() - .text_sm() - .text_color(cx.default_colors().text) - .min_w_96() - .child(description.into()) - } - - pub fn label(label: impl Into, cx: &App) -> impl Element { - div() - .text_xs() - .text_color(cx.default_colors().text) - .child(label.into()) - } - - /// Note: Not `ui::v_flex` as the `story` crate doesn't depend on the `ui` crate. - pub fn v_flex() -> Div { - div().flex().flex_col().gap_1() - } -} - -#[derive(IntoElement)] -pub struct StoryItem { - label: SharedString, - item: AnyElement, - description: Option, - usage: Option, -} - -impl StoryItem { - pub fn new(label: impl Into, item: impl IntoElement) -> Self { - Self { - label: label.into(), - item: item.into_any_element(), - description: None, - usage: None, - } - } - - pub fn description(mut self, description: impl Into) -> Self { - self.description = Some(description.into()); - self - } - - pub fn usage(mut self, code: impl Into) -> Self { - self.usage = Some(code.into()); - self - } -} - -impl RenderOnce for StoryItem { - fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement { - let colors = cx.default_colors(); - - div() - .my_2() - .flex() - .gap_4() - .w_full() - .child( - Story::v_flex() - .px_2() - .w_1_2() - .min_h_px() - .child(Story::label(self.label, cx)) - .child( - div() - .rounded_sm() - .bg(colors.background) - .border_1() - .border_color(colors.border) - .py_1() - .px_2() - .overflow_hidden() - .child(self.item), - ) - .when_some(self.description, |this, description| { - this.child(Story::description(description, cx)) - }), - ) - .child( - Story::v_flex() - .px_2() - .flex_none() - .w_1_2() - .min_h_px() - .when_some(self.usage, |this, usage| { - this.child(Story::label("Example Usage", cx)) - .child(Story::code_block(usage, cx)) - }), - ) - } -} - -#[derive(IntoElement)] -pub struct StorySection { - description: Option, - children: SmallVec<[AnyElement; 2]>, -} - -impl Default for StorySection { - fn default() -> Self { - Self::new() - } -} - -impl StorySection { - pub fn new() -> Self { - Self { - description: None, - children: SmallVec::new(), - } - } - - pub fn description(mut self, description: impl Into) -> Self { - self.description = Some(description.into()); - self - } -} - -impl RenderOnce for StorySection { - fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement { - let children: SmallVec<[AnyElement; 2]> = SmallVec::from_iter(Itertools::intersperse_with( - self.children.into_iter(), - || Story::divider(cx).into_any_element(), - )); - - Story::section(cx) - // Section title - .py_2() - // Section description - .when_some(self.description, |section, description| { - section.child(Story::description(description, cx)) - }) - .child(div().flex().flex_col().gap_2().children(children)) - .child(Story::divider(cx)) - } -} - -impl ParentElement for StorySection { - fn extend(&mut self, elements: impl IntoIterator) { - self.children.extend(elements) - } -} diff --git a/crates/storybook/Cargo.toml b/crates/storybook/Cargo.toml deleted file mode 100644 index b641e5cbd8b5ce5e66f9fb082e74ea42124f8993..0000000000000000000000000000000000000000 --- a/crates/storybook/Cargo.toml +++ /dev/null @@ -1,41 +0,0 @@ -[package] -name = "storybook" -version = "0.1.0" -edition.workspace = true -publish.workspace = true -license = "GPL-3.0-or-later" - -[lints] -workspace = true - -[[bin]] -name = "storybook" -path = "src/storybook.rs" - -[dependencies] -anyhow.workspace = true -clap = { workspace = true, features = ["derive", "string"] } -ctrlc = "3.4" -dialoguer = { version = "0.11.0", features = ["fuzzy-select"] } -editor.workspace = true -fuzzy.workspace = true -gpui = { workspace = true, default-features = true } -gpui_platform.workspace = true -indoc.workspace = true -language.workspace = true -log.workspace = true -menu.workspace = true -picker.workspace = true -reqwest_client.workspace = true -rust-embed.workspace = true -settings.workspace = true -theme_settings.workspace = true -simplelog.workspace = true -story.workspace = true -strum = { workspace = true, features = ["derive"] } -theme.workspace = true -title_bar = { workspace = true, features = ["stories"] } -ui = { workspace = true, features = ["stories"] } - -[dev-dependencies] -gpui = { workspace = true, features = ["test-support"] } diff --git a/crates/storybook/LICENSE-GPL b/crates/storybook/LICENSE-GPL deleted file mode 120000 index 89e542f750cd3860a0598eff0dc34b56d7336dc4..0000000000000000000000000000000000000000 --- a/crates/storybook/LICENSE-GPL +++ /dev/null @@ -1 +0,0 @@ -../../LICENSE-GPL \ No newline at end of file diff --git a/crates/storybook/build.rs b/crates/storybook/build.rs deleted file mode 100644 index 66791cae4218e34d6d1fa5e156fc900eb6cf8c59..0000000000000000000000000000000000000000 --- a/crates/storybook/build.rs +++ /dev/null @@ -1,9 +0,0 @@ -fn main() { - #[cfg(target_os = "windows")] - { - #[cfg(target_env = "msvc")] - { - println!("cargo:rustc-link-arg=/stack:{}", 8 * 1024 * 1024); - } - } -} diff --git a/crates/storybook/docs/thoughts.md b/crates/storybook/docs/thoughts.md deleted file mode 100644 index cdeef621f362f4ff0deff7551af894b314ed96d4..0000000000000000000000000000000000000000 --- a/crates/storybook/docs/thoughts.md +++ /dev/null @@ -1,57 +0,0 @@ -Much of element styling is now handled by an external engine. - -How do I make an element hover. - -There's a hover style. - -Hoverable needs to wrap another element. That element can be styled. - -```rs -struct Hoverable { - -} - -impl Element for Hoverable { - -} -``` - -```rs -#[derive(Styled, Interactive)] -pub struct Div { - declared_style: StyleRefinement, - interactions: Interactions -} - -pub trait Styled { - fn declared_style(&mut self) -> &mut StyleRefinement; - fn compute_style(&mut self) -> Style { - Style::default().refine(self.declared_style()) - } - - // All the tailwind classes, modifying self.declared_style() -} - -impl Style { - pub fn paint_background(layout: Layout, cx: &mut PaintContext); - pub fn paint_foreground(layout: Layout, cx: &mut PaintContext); -} - -pub trait Interactive { - fn interactions(&mut self) -> &mut Interactions; - - fn on_click(self, ) -} - -struct Interactions { - click: SmallVec<[; 1]>, -} -``` - -```rs -trait Stylable { - type Style; - - fn with_style(self, style: Self::Style) -> Self; -} -``` diff --git a/crates/storybook/src/actions.rs b/crates/storybook/src/actions.rs deleted file mode 100644 index 03ee5b580c55d8ffbbc745214f1298d2dd0a19be..0000000000000000000000000000000000000000 --- a/crates/storybook/src/actions.rs +++ /dev/null @@ -1,2 +0,0 @@ -use gpui::actions; -actions!(storybook, [Quit]); diff --git a/crates/storybook/src/app_menus.rs b/crates/storybook/src/app_menus.rs deleted file mode 100644 index c3045cf7999b851245a2f540c6318b7d0ef57b4f..0000000000000000000000000000000000000000 --- a/crates/storybook/src/app_menus.rs +++ /dev/null @@ -1,7 +0,0 @@ -use gpui::{Menu, MenuItem}; - -pub fn app_menus() -> Vec { - use crate::actions::Quit; - - vec![Menu::new("Storybook").items([MenuItem::action("Quit", Quit)])] -} diff --git a/crates/storybook/src/assets.rs b/crates/storybook/src/assets.rs deleted file mode 100644 index 4da4081212c0c4d97fe881e5e2b792462c2318e6..0000000000000000000000000000000000000000 --- a/crates/storybook/src/assets.rs +++ /dev/null @@ -1,32 +0,0 @@ -use std::borrow::Cow; - -use anyhow::{Context as _, Result}; -use gpui::{AssetSource, SharedString}; -use rust_embed::RustEmbed; - -#[derive(RustEmbed)] -#[folder = "../../assets"] -#[include = "fonts/**/*"] -#[include = "icons/**/*"] -#[include = "images/**/*"] -#[include = "themes/**/*"] -#[include = "sounds/**/*"] -#[include = "*.md"] -#[exclude = "*.DS_Store"] -pub struct Assets; - -impl AssetSource for Assets { - fn load(&self, path: &str) -> Result>> { - Self::get(path) - .map(|f| f.data) - .with_context(|| format!("could not find asset at path {path:?}")) - .map(Some) - } - - fn list(&self, path: &str) -> Result> { - Ok(Self::iter() - .filter(|p| p.starts_with(path)) - .map(SharedString::from) - .collect()) - } -} diff --git a/crates/storybook/src/stories.rs b/crates/storybook/src/stories.rs deleted file mode 100644 index 63992d259c7a1cb76a3684f53c55fe255522aced..0000000000000000000000000000000000000000 --- a/crates/storybook/src/stories.rs +++ /dev/null @@ -1,23 +0,0 @@ -mod auto_height_editor; -mod cursor; -mod focus; -mod indent_guides; -mod kitchen_sink; -mod overflow_scroll; -mod picker; -mod scroll; -mod text; -mod viewport_units; -mod with_rem_size; - -pub use auto_height_editor::*; -pub use cursor::*; -pub use focus::*; -pub use indent_guides::*; -pub use kitchen_sink::*; -pub use overflow_scroll::*; -pub use picker::*; -pub use scroll::*; -pub use text::*; -pub use viewport_units::*; -pub use with_rem_size::*; diff --git a/crates/storybook/src/stories/auto_height_editor.rs b/crates/storybook/src/stories/auto_height_editor.rs deleted file mode 100644 index 702d5774f2c7f353ae9ea600e9b17309f7051ead..0000000000000000000000000000000000000000 --- a/crates/storybook/src/stories/auto_height_editor.rs +++ /dev/null @@ -1,36 +0,0 @@ -use editor::Editor; -use gpui::{ - App, AppContext as _, Context, Entity, IntoElement, KeyBinding, ParentElement, Render, Styled, - Window, div, white, -}; - -pub struct AutoHeightEditorStory { - editor: Entity, -} - -impl AutoHeightEditorStory { - pub fn new(window: &mut Window, cx: &mut App) -> gpui::Entity { - cx.bind_keys([KeyBinding::new( - "enter", - editor::actions::Newline, - Some("Editor"), - )]); - cx.new(|cx| Self { - editor: cx.new(|cx| { - let mut editor = Editor::auto_height(1, 3, window, cx); - editor.set_soft_wrap_mode(language::language_settings::SoftWrap::EditorWidth, cx); - editor - }), - }) - } -} - -impl Render for AutoHeightEditorStory { - fn render(&mut self, _window: &mut Window, _cx: &mut Context) -> impl IntoElement { - div() - .size_full() - .bg(white()) - .text_sm() - .child(div().w_32().bg(gpui::black()).child(self.editor.clone())) - } -} diff --git a/crates/storybook/src/stories/cursor.rs b/crates/storybook/src/stories/cursor.rs deleted file mode 100644 index 00bae999172a50ed9041d5e9fff2903d0c3fbc46..0000000000000000000000000000000000000000 --- a/crates/storybook/src/stories/cursor.rs +++ /dev/null @@ -1,109 +0,0 @@ -use gpui::{Div, Render, Stateful}; -use story::Story; -use ui::prelude::*; - -pub struct CursorStory; - -impl Render for CursorStory { - fn render(&mut self, _window: &mut Window, cx: &mut Context) -> impl IntoElement { - let all_cursors: [(&str, Box) -> Stateful
>); 19] = [ - ( - "cursor_default", - Box::new(|el: Stateful
| el.cursor_default()), - ), - ( - "cursor_pointer", - Box::new(|el: Stateful
| el.cursor_pointer()), - ), - ( - "cursor_text", - Box::new(|el: Stateful
| el.cursor_text()), - ), - ( - "cursor_move", - Box::new(|el: Stateful
| el.cursor_move()), - ), - ( - "cursor_not_allowed", - Box::new(|el: Stateful
| el.cursor_not_allowed()), - ), - ( - "cursor_context_menu", - Box::new(|el: Stateful
| el.cursor_context_menu()), - ), - ( - "cursor_crosshair", - Box::new(|el: Stateful
| el.cursor_crosshair()), - ), - ( - "cursor_vertical_text", - Box::new(|el: Stateful
| el.cursor_vertical_text()), - ), - ( - "cursor_alias", - Box::new(|el: Stateful
| el.cursor_alias()), - ), - ( - "cursor_copy", - Box::new(|el: Stateful
| el.cursor_copy()), - ), - ( - "cursor_no_drop", - Box::new(|el: Stateful
| el.cursor_no_drop()), - ), - ( - "cursor_grab", - Box::new(|el: Stateful
| el.cursor_grab()), - ), - ( - "cursor_grabbing", - Box::new(|el: Stateful
| el.cursor_grabbing()), - ), - ( - "cursor_col_resize", - Box::new(|el: Stateful
| el.cursor_col_resize()), - ), - ( - "cursor_row_resize", - Box::new(|el: Stateful
| el.cursor_row_resize()), - ), - ( - "cursor_n_resize", - Box::new(|el: Stateful
| el.cursor_n_resize()), - ), - ( - "cursor_e_resize", - Box::new(|el: Stateful
| el.cursor_e_resize()), - ), - ( - "cursor_s_resize", - Box::new(|el: Stateful
| el.cursor_s_resize()), - ), - ( - "cursor_w_resize", - Box::new(|el: Stateful
| el.cursor_w_resize()), - ), - ]; - - Story::container(cx) - .flex() - .gap_1() - .child(Story::title("cursor", cx)) - .children(all_cursors.map(|(name, apply_cursor)| { - div().gap_1().flex().text_color(gpui::white()).child( - div() - .flex() - .items_center() - .justify_center() - .id(name) - .map(apply_cursor) - .w_64() - .h_8() - .bg(gpui::red()) - .active(|style| style.bg(gpui::green())) - .text_sm() - .child(Story::label(name, cx)), - ) - })) - } -} diff --git a/crates/storybook/src/stories/focus.rs b/crates/storybook/src/stories/focus.rs deleted file mode 100644 index a64c272ba75a902f3debe3dedfe7b95c969e0d45..0000000000000000000000000000000000000000 --- a/crates/storybook/src/stories/focus.rs +++ /dev/null @@ -1,123 +0,0 @@ -use gpui::{ - App, Entity, FocusHandle, KeyBinding, Render, Subscription, Window, actions, div, prelude::*, -}; -use ui::prelude::*; - -actions!(focus, [ActionA, ActionB, ActionC]); - -pub struct FocusStory { - parent_focus: FocusHandle, - child_1_focus: FocusHandle, - child_2_focus: FocusHandle, - _focus_subscriptions: Vec, -} - -impl FocusStory { - pub fn model(window: &mut Window, cx: &mut App) -> Entity { - cx.bind_keys([ - KeyBinding::new("cmd-a", ActionA, Some("parent")), - KeyBinding::new("cmd-a", ActionB, Some("child-1")), - KeyBinding::new("cmd-c", ActionC, None), - ]); - - cx.new(|cx| { - let parent_focus = cx.focus_handle(); - let child_1_focus = cx.focus_handle(); - let child_2_focus = cx.focus_handle(); - let _focus_subscriptions = vec![ - cx.on_focus(&parent_focus, window, |_, _, _| { - println!("Parent focused"); - }), - cx.on_blur(&parent_focus, window, |_, _, _| { - println!("Parent blurred"); - }), - cx.on_focus(&child_1_focus, window, |_, _, _| { - println!("Child 1 focused"); - }), - cx.on_blur(&child_1_focus, window, |_, _, _| { - println!("Child 1 blurred"); - }), - cx.on_focus(&child_2_focus, window, |_, _, _| { - println!("Child 2 focused"); - }), - cx.on_blur(&child_2_focus, window, |_, _, _| { - println!("Child 2 blurred"); - }), - ]; - - Self { - parent_focus, - child_1_focus, - child_2_focus, - _focus_subscriptions, - } - }) - } -} - -impl Render for FocusStory { - fn render(&mut self, _: &mut Window, cx: &mut Context) -> impl IntoElement { - let theme = cx.theme(); - let color_1 = theme.status().created; - let color_2 = theme.status().modified; - let color_4 = theme.status().conflict; - let color_5 = theme.status().ignored; - let color_6 = theme.status().renamed; - let color_7 = theme.status().hint; - - div() - .id("parent") - .active(|style| style.bg(color_7)) - .track_focus(&self.parent_focus) - .key_context("parent") - .on_action(cx.listener(|_, _action: &ActionA, _window, _cx| { - println!("Action A dispatched on parent"); - })) - .on_action(cx.listener(|_, _action: &ActionB, _window, _cx| { - println!("Action B dispatched on parent"); - })) - .on_key_down(cx.listener(|_, event, _, _| println!("Key down on parent {:?}", event))) - .on_key_up(cx.listener(|_, event, _, _| println!("Key up on parent {:?}", event))) - .size_full() - .bg(color_1) - .focus(|style| style.bg(color_2)) - .child( - div() - .track_focus(&self.child_1_focus) - .key_context("child-1") - .on_action(cx.listener(|_, _action: &ActionB, _window, _cx| { - println!("Action B dispatched on child 1 during"); - })) - .w_full() - .h_6() - .bg(color_4) - .focus(|style| style.bg(color_5)) - .in_focus(|style| style.bg(color_6)) - .on_key_down( - cx.listener(|_, event, _, _| println!("Key down on child 1 {:?}", event)), - ) - .on_key_up( - cx.listener(|_, event, _, _| println!("Key up on child 1 {:?}", event)), - ) - .child("Child 1"), - ) - .child( - div() - .track_focus(&self.child_2_focus) - .key_context("child-2") - .on_action(cx.listener(|_, _action: &ActionC, _window, _cx| { - println!("Action C dispatched on child 2"); - })) - .w_full() - .h_6() - .bg(color_4) - .on_key_down( - cx.listener(|_, event, _, _| println!("Key down on child 2 {:?}", event)), - ) - .on_key_up( - cx.listener(|_, event, _, _| println!("Key up on child 2 {:?}", event)), - ) - .child("Child 2"), - ) - } -} diff --git a/crates/storybook/src/stories/indent_guides.rs b/crates/storybook/src/stories/indent_guides.rs deleted file mode 100644 index db23ea79bd43c267e02e4f81b1b0586b0c1d19cd..0000000000000000000000000000000000000000 --- a/crates/storybook/src/stories/indent_guides.rs +++ /dev/null @@ -1,82 +0,0 @@ -use std::ops::Range; - -use gpui::{Entity, Render, div, uniform_list}; -use gpui::{prelude::*, *}; -use ui::{AbsoluteLength, Color, DefiniteLength, Label, LabelCommon, px, v_flex}; - -use story::Story; - -const LENGTH: usize = 100; - -pub struct IndentGuidesStory { - depths: Vec, -} - -impl IndentGuidesStory { - pub fn model(_window: &mut Window, cx: &mut App) -> Entity { - let mut depths = Vec::new(); - depths.push(0); - depths.push(1); - depths.push(2); - for _ in 0..LENGTH - 6 { - depths.push(3); - } - depths.push(2); - depths.push(1); - depths.push(0); - - cx.new(|_cx| Self { depths }) - } -} - -impl Render for IndentGuidesStory { - fn render(&mut self, _window: &mut Window, cx: &mut Context) -> impl IntoElement { - Story::container(cx) - .child(Story::title("Indent guides", cx)) - .child( - v_flex().size_full().child( - uniform_list( - "some-list", - self.depths.len(), - cx.processor(move |this, range: Range, _window, _cx| { - this.depths - .iter() - .enumerate() - .skip(range.start) - .take(range.end - range.start) - .map(|(i, depth)| { - div() - .pl(DefiniteLength::Absolute(AbsoluteLength::Pixels(px( - 16. * (*depth as f32), - )))) - .child(Label::new(format!("Item {}", i)).color(Color::Info)) - }) - .collect() - }), - ) - .with_sizing_behavior(gpui::ListSizingBehavior::Infer) - .with_decoration( - ui::indent_guides( - px(16.), - ui::IndentGuideColors { - default: Color::Info.color(cx), - hover: Color::Accent.color(cx), - active: Color::Accent.color(cx), - }, - ) - .with_compute_indents_fn( - cx.entity(), - |this, range, _cx, _context| { - this.depths - .iter() - .skip(range.start) - .take(range.end - range.start) - .cloned() - .collect() - }, - ), - ), - ), - ) - } -} diff --git a/crates/storybook/src/stories/kitchen_sink.rs b/crates/storybook/src/stories/kitchen_sink.rs deleted file mode 100644 index aaddf733f8201874580e766055b8ea0cfb4c10fb..0000000000000000000000000000000000000000 --- a/crates/storybook/src/stories/kitchen_sink.rs +++ /dev/null @@ -1,32 +0,0 @@ -use gpui::{Entity, Render, prelude::*}; -use story::Story; -use strum::IntoEnumIterator; -use ui::prelude::*; - -use crate::story_selector::ComponentStory; - -pub struct KitchenSinkStory; - -impl KitchenSinkStory { - pub fn model(cx: &mut App) -> Entity { - cx.new(|_| Self) - } -} - -impl Render for KitchenSinkStory { - fn render(&mut self, window: &mut Window, cx: &mut Context) -> impl IntoElement { - let component_stories = ComponentStory::iter() - .map(|selector| selector.story(window, cx)) - .collect::>(); - - Story::container(cx) - .id("kitchen-sink") - .overflow_y_scroll() - .child(Story::title("Kitchen Sink", cx)) - .child(Story::label("Components", cx)) - .child(div().flex().flex_col().children(component_stories)) - // Add a bit of space at the bottom of the kitchen sink so elements - // don't end up squished right up against the bottom of the screen. - .child(div().p_4()) - } -} diff --git a/crates/storybook/src/stories/overflow_scroll.rs b/crates/storybook/src/stories/overflow_scroll.rs deleted file mode 100644 index a9ba09d6a30bfe825e8275c6f2b5432dd8a1941b..0000000000000000000000000000000000000000 --- a/crates/storybook/src/stories/overflow_scroll.rs +++ /dev/null @@ -1,41 +0,0 @@ -use gpui::Render; -use story::Story; - -use ui::prelude::*; - -pub struct OverflowScrollStory; - -impl Render for OverflowScrollStory { - fn render(&mut self, _window: &mut Window, cx: &mut Context) -> impl IntoElement { - Story::container(cx) - .child(Story::title("Overflow Scroll", cx)) - .child(Story::label("`overflow_x_scroll`", cx)) - .child( - h_flex() - .id("overflow_x_scroll") - .gap_2() - .overflow_x_scroll() - .children((0..100).map(|i| { - div() - .p_4() - .debug_bg_cyan() - .child(SharedString::from(format!("Child {}", i + 1))) - })), - ) - .child(Story::label("`overflow_y_scroll`", cx)) - .child( - v_flex() - .w_full() - .flex_1() - .id("overflow_y_scroll") - .gap_2() - .overflow_y_scroll() - .children((0..100).map(|i| { - div() - .p_4() - .debug_bg_green() - .child(SharedString::from(format!("Child {}", i + 1))) - })), - ) - } -} diff --git a/crates/storybook/src/stories/picker.rs b/crates/storybook/src/stories/picker.rs deleted file mode 100644 index fa65fd085dc158a22666262a5ed84573eb744651..0000000000000000000000000000000000000000 --- a/crates/storybook/src/stories/picker.rs +++ /dev/null @@ -1,206 +0,0 @@ -use fuzzy::StringMatchCandidate; -use gpui::{App, Entity, KeyBinding, Render, SharedString, Styled, Task, Window, div, prelude::*}; -use picker::{Picker, PickerDelegate}; -use std::sync::Arc; -use ui::{Label, ListItem}; -use ui::{ListItemSpacing, prelude::*}; - -pub struct PickerStory { - picker: Entity>, -} - -struct Delegate { - candidates: Arc<[StringMatchCandidate]>, - matches: Vec, - selected_ix: usize, -} - -impl Delegate { - fn new(strings: &[&str]) -> Self { - Self { - candidates: strings - .iter() - .copied() - .enumerate() - .map(|(id, string)| StringMatchCandidate::new(id, string)) - .collect(), - matches: vec![], - selected_ix: 0, - } - } -} - -impl PickerDelegate for Delegate { - type ListItem = ListItem; - - fn match_count(&self) -> usize { - self.candidates.len() - } - - fn placeholder_text(&self, _window: &mut Window, _cx: &mut App) -> Arc { - "Test".into() - } - - fn render_match( - &self, - ix: usize, - selected: bool, - _window: &mut Window, - _cx: &mut Context>, - ) -> Option { - let candidate_ix = self.matches.get(ix)?; - // TASK: Make StringMatchCandidate::string a SharedString - let candidate = SharedString::from(self.candidates[*candidate_ix].string.clone()); - - Some( - ListItem::new(ix) - .inset(true) - .spacing(ListItemSpacing::Sparse) - .toggle_state(selected) - .child(Label::new(candidate)), - ) - } - - fn selected_index(&self) -> usize { - self.selected_ix - } - - fn set_selected_index(&mut self, ix: usize, _: &mut Window, cx: &mut Context>) { - self.selected_ix = ix; - cx.notify(); - } - - fn confirm(&mut self, secondary: bool, _window: &mut Window, _cx: &mut Context>) { - let candidate_ix = self.matches[self.selected_ix]; - let candidate = self.candidates[candidate_ix].string.clone(); - - if secondary { - eprintln!("Secondary confirmed {}", candidate) - } else { - eprintln!("Confirmed {}", candidate) - } - } - - fn dismissed(&mut self, _: &mut Window, cx: &mut Context>) { - cx.quit(); - } - - fn update_matches( - &mut self, - query: String, - _: &mut Window, - cx: &mut Context>, - ) -> Task<()> { - let candidates = self.candidates.clone(); - self.matches = cx - .foreground_executor() - .block_on(fuzzy::match_strings( - &candidates, - &query, - true, - true, - 100, - &Default::default(), - cx.background_executor().clone(), - )) - .into_iter() - .map(|r| r.candidate_id) - .collect(); - self.selected_ix = 0; - Task::ready(()) - } -} - -impl PickerStory { - pub fn new(window: &mut Window, cx: &mut App) -> Entity { - cx.new(|cx| { - cx.bind_keys([ - KeyBinding::new("up", menu::SelectPrevious, Some("picker")), - KeyBinding::new("pageup", menu::SelectFirst, Some("picker")), - KeyBinding::new("shift-pageup", menu::SelectFirst, Some("picker")), - KeyBinding::new("ctrl-p", menu::SelectPrevious, Some("picker")), - KeyBinding::new("down", menu::SelectNext, Some("picker")), - KeyBinding::new("pagedown", menu::SelectLast, Some("picker")), - KeyBinding::new("shift-pagedown", menu::SelectFirst, Some("picker")), - KeyBinding::new("ctrl-n", menu::SelectNext, Some("picker")), - KeyBinding::new("cmd-up", menu::SelectFirst, Some("picker")), - KeyBinding::new("cmd-down", menu::SelectLast, Some("picker")), - KeyBinding::new("enter", menu::Confirm, Some("picker")), - KeyBinding::new("ctrl-enter", menu::SecondaryConfirm, Some("picker")), - KeyBinding::new("cmd-enter", menu::SecondaryConfirm, Some("picker")), - KeyBinding::new("escape", menu::Cancel, Some("picker")), - KeyBinding::new("ctrl-c", menu::Cancel, Some("picker")), - ]); - - PickerStory { - picker: cx.new(|cx| { - let mut delegate = Delegate::new(&[ - "Baguette (France)", - "Baklava (Turkey)", - "Beef Wellington (UK)", - "Biryani (India)", - "Borscht (Ukraine)", - "Bratwurst (Germany)", - "Bulgogi (Korea)", - "Burrito (USA)", - "Ceviche (Peru)", - "Chicken Tikka Masala (India)", - "Churrasco (Brazil)", - "Couscous (North Africa)", - "Croissant (France)", - "Dim Sum (China)", - "Empanada (Argentina)", - "Fajitas (Mexico)", - "Falafel (Middle East)", - "Feijoada (Brazil)", - "Fish and Chips (UK)", - "Fondue (Switzerland)", - "Goulash (Hungary)", - "Haggis (Scotland)", - "Kebab (Middle East)", - "Kimchi (Korea)", - "Lasagna (Italy)", - "Maple Syrup Pancakes (Canada)", - "Moussaka (Greece)", - "Pad Thai (Thailand)", - "Paella (Spain)", - "Pancakes (USA)", - "Pasta Carbonara (Italy)", - "Pavlova (Australia)", - "Peking Duck (China)", - "Pho (Vietnam)", - "Pierogi (Poland)", - "Pizza (Italy)", - "Poutine (Canada)", - "Pretzel (Germany)", - "Ramen (Japan)", - "Rendang (Indonesia)", - "Sashimi (Japan)", - "Satay (Indonesia)", - "Shepherd's Pie (Ireland)", - "Sushi (Japan)", - "Tacos (Mexico)", - "Tandoori Chicken (India)", - "Tortilla (Spain)", - "Tzatziki (Greece)", - "Wiener Schnitzel (Austria)", - ]); - delegate.update_matches("".into(), window, cx).detach(); - - let picker = Picker::uniform_list(delegate, window, cx); - picker.focus(window, cx); - picker - }), - } - }) - } -} - -impl Render for PickerStory { - fn render(&mut self, _: &mut Window, cx: &mut Context) -> impl IntoElement { - div() - .bg(cx.theme().styles.colors.background) - .size_full() - .child(self.picker.clone()) - } -} diff --git a/crates/storybook/src/stories/scroll.rs b/crates/storybook/src/stories/scroll.rs deleted file mode 100644 index 8a4c7ea7689042675764bc55faf019a8cc8fc2a9..0000000000000000000000000000000000000000 --- a/crates/storybook/src/stories/scroll.rs +++ /dev/null @@ -1,52 +0,0 @@ -use gpui::{App, Entity, Render, SharedString, Styled, Window, div, prelude::*, px}; -use ui::Tooltip; -use ui::prelude::*; - -pub struct ScrollStory; - -impl ScrollStory { - pub fn model(cx: &mut App) -> Entity { - cx.new(|_| ScrollStory) - } -} - -impl Render for ScrollStory { - fn render(&mut self, _: &mut Window, cx: &mut Context) -> impl IntoElement { - let theme = cx.theme(); - let color_1 = theme.status().created; - let color_2 = theme.status().modified; - - div() - .id("parent") - .bg(theme.colors().background) - .size_full() - .overflow_scroll() - .children((0..10).map(|row| { - div() - .w(px(1000.)) - .h(px(100.)) - .flex() - .flex_row() - .children((0..10).map(|column| { - let id = SharedString::from(format!("{}, {}", row, column)); - let bg = if row % 2 == column % 2 { - color_1 - } else { - color_2 - }; - div() - .id(id.clone()) - .tooltip(Tooltip::text(id)) - .bg(bg) - .size(px(100_f32)) - .when(row >= 5 && column >= 5, |d| { - d.overflow_scroll() - .child(div().size(px(50.)).bg(color_1)) - .child(div().size(px(50.)).bg(color_2)) - .child(div().size(px(50.)).bg(color_1)) - .child(div().size(px(50.)).bg(color_2)) - }) - })) - })) - } -} diff --git a/crates/storybook/src/stories/text.rs b/crates/storybook/src/stories/text.rs deleted file mode 100644 index 7ba2378307e8e7ff9827534978da3abf23261e6d..0000000000000000000000000000000000000000 --- a/crates/storybook/src/stories/text.rs +++ /dev/null @@ -1,120 +0,0 @@ -use gpui::{ - App, AppContext as _, Context, Entity, HighlightStyle, InteractiveText, IntoElement, - ParentElement, Render, Styled, StyledText, Window, div, green, red, -}; -use indoc::indoc; -use story::*; - -pub struct TextStory; - -impl TextStory { - pub fn model(cx: &mut App) -> Entity { - cx.new(|_| Self) - } -} - -impl Render for TextStory { - fn render(&mut self, window: &mut Window, cx: &mut Context) -> impl IntoElement { - Story::container(cx) - .child(Story::title("Text", cx)) - .children(vec![ - StorySection::new() - .child( - StoryItem::new("Default", div().bg(gpui::blue()).child("Hello World!")) - .usage(indoc! {r##" - div() - .child("Hello World!") - "## - }), - ) - .child( - StoryItem::new( - "Wrapping Text", - div().max_w_96().child(concat!( - "The quick brown fox jumps over the lazy dog. ", - "Meanwhile, the lazy dog decided it was time for a change. ", - "He started daily workout routines, ate healthier and became the fastest dog in town.", - )), - ) - .description("Set a width or max-width to enable text wrapping.") - .usage(indoc! {r##" - div() - .max_w_96() - .child("Some text that you want to wrap.") - "## - }), - ) - .child( - StoryItem::new( - "tbd", - div().flex().w_96().child( - div().overflow_hidden().child(concat!( - "flex-row. width 96. overflow-hidden. The quick brown fox jumps over the lazy dog. ", - "Meanwhile, the lazy dog decided it was time for a change. ", - "He started daily workout routines, ate healthier and became the fastest dog in town.", - )), - ), - ), - ) - .child( - StoryItem::new( - "Text in Horizontal Flex", - div().flex().w_96().bg(red()).child(concat!( - "flex-row. width 96. The quick brown fox jumps over the lazy dog. ", - "Meanwhile, the lazy dog decided it was time for a change. ", - "He started daily workout routines, ate healthier and became the fastest dog in town.", - )), - ) - .usage(indoc! {r##" - // NOTE: When rendering text in a horizontal flex container, - // Taffy will not pass width constraints down from the parent. - // To fix this, render text in a parent with overflow: hidden - - div() - .max_w_96() - .child("Some text that you want to wrap.") - "## - }), - ) - .child( - StoryItem::new( - "Interactive Text", - InteractiveText::new( - "interactive", - StyledText::new("Hello world, how is it going?").with_default_highlights( - &window.text_style(), - [ - ( - 6..11, - HighlightStyle { - background_color: Some(green()), - ..Default::default() - }, - ), - ], - ), - ) - .on_click(vec![2..4, 1..3, 7..9], |range_ix, _, _cx| { - println!("Clicked range {range_ix}"); - }), - ) - .usage(indoc! {r##" - InteractiveText::new( - "interactive", - StyledText::new("Hello world, how is it going?").with_highlights(&window.text_style(), [ - (6..11, HighlightStyle { - background_color: Some(green()), - ..Default::default() - }), - ]), - ) - .on_click(vec![2..4, 1..3, 7..9], |range_ix, _cx| { - println!("Clicked range {range_ix}"); - }) - "## - }), - ), - ]) - .into_element() - } -} diff --git a/crates/storybook/src/stories/viewport_units.rs b/crates/storybook/src/stories/viewport_units.rs deleted file mode 100644 index 1259a713ee888deedd3c1beb2a1ccd30a3eff252..0000000000000000000000000000000000000000 --- a/crates/storybook/src/stories/viewport_units.rs +++ /dev/null @@ -1,32 +0,0 @@ -use gpui::Render; -use story::Story; - -use ui::prelude::*; - -pub struct ViewportUnitsStory; - -impl Render for ViewportUnitsStory { - fn render(&mut self, window: &mut Window, cx: &mut Context) -> impl IntoElement { - Story::container(cx).child( - div() - .flex() - .flex_row() - .child( - div() - .w(vw(0.5, window)) - .h(vh(0.8, window)) - .bg(gpui::red()) - .text_color(gpui::white()) - .child("50vw, 80vh"), - ) - .child( - div() - .w(vw(0.25, window)) - .h(vh(0.33, window)) - .bg(gpui::green()) - .text_color(gpui::white()) - .child("25vw, 33vh"), - ), - ) - } -} diff --git a/crates/storybook/src/stories/with_rem_size.rs b/crates/storybook/src/stories/with_rem_size.rs deleted file mode 100644 index eeca3fb89f6382dbc13d696f2701f0c6b28027ee..0000000000000000000000000000000000000000 --- a/crates/storybook/src/stories/with_rem_size.rs +++ /dev/null @@ -1,61 +0,0 @@ -use gpui::{AnyElement, Hsla, Render}; -use story::Story; - -use ui::{prelude::*, utils::WithRemSize}; - -pub struct WithRemSizeStory; - -impl Render for WithRemSizeStory { - fn render(&mut self, _window: &mut Window, cx: &mut Context) -> impl IntoElement { - Story::container(cx).child( - Example::new(16., gpui::red()) - .child( - Example::new(24., gpui::green()) - .child(Example::new(8., gpui::blue())) - .child(Example::new(16., gpui::yellow())), - ) - .child( - Example::new(12., gpui::green()) - .child(Example::new(48., gpui::blue())) - .child(Example::new(16., gpui::yellow())), - ), - ) - } -} - -#[derive(IntoElement)] -struct Example { - rem_size: Pixels, - border_color: Hsla, - children: Vec, -} - -impl Example { - pub fn new(rem_size: impl Into, border_color: Hsla) -> Self { - Self { - rem_size: rem_size.into(), - border_color, - children: Vec::new(), - } - } -} - -impl ParentElement for Example { - fn extend(&mut self, elements: impl IntoIterator) { - self.children.extend(elements); - } -} - -impl RenderOnce for Example { - fn render(self, _window: &mut Window, _cx: &mut App) -> impl IntoElement { - WithRemSize::new(self.rem_size).child( - v_flex() - .gap_2() - .p_2() - .border_2() - .border_color(self.border_color) - .child(Label::new(format!("1rem = {}px", f32::from(self.rem_size)))) - .children(self.children), - ) - } -} diff --git a/crates/storybook/src/story_selector.rs b/crates/storybook/src/story_selector.rs deleted file mode 100644 index 4c1113f70f54051bab973595f6f7e7bdbc9c0029..0000000000000000000000000000000000000000 --- a/crates/storybook/src/story_selector.rs +++ /dev/null @@ -1,109 +0,0 @@ -use std::str::FromStr; -use std::sync::OnceLock; - -use crate::stories::*; -use clap::ValueEnum; -use clap::builder::PossibleValue; -use gpui::AnyView; -use strum::{EnumIter, EnumString, IntoEnumIterator}; -use ui::prelude::*; - -#[derive(Debug, PartialEq, Eq, Clone, Copy, strum::Display, EnumString, EnumIter)] -#[strum(serialize_all = "snake_case")] -pub enum ComponentStory { - ApplicationMenu, - AutoHeightEditor, - ContextMenu, - Cursor, - Focus, - OverflowScroll, - Picker, - Scroll, - Text, - ViewportUnits, - WithRemSize, - IndentGuides, -} - -impl ComponentStory { - pub fn story(&self, window: &mut Window, cx: &mut App) -> AnyView { - match self { - Self::ApplicationMenu => cx - .new(|cx| title_bar::ApplicationMenuStory::new(window, cx)) - .into(), - Self::AutoHeightEditor => AutoHeightEditorStory::new(window, cx).into(), - Self::ContextMenu => cx.new(|_| ui::ContextMenuStory).into(), - Self::Cursor => cx.new(|_| crate::stories::CursorStory).into(), - Self::Focus => FocusStory::model(window, cx).into(), - Self::OverflowScroll => cx.new(|_| crate::stories::OverflowScrollStory).into(), - Self::Picker => PickerStory::new(window, cx).into(), - Self::Scroll => ScrollStory::model(cx).into(), - Self::Text => TextStory::model(cx).into(), - Self::ViewportUnits => cx.new(|_| crate::stories::ViewportUnitsStory).into(), - Self::WithRemSize => cx.new(|_| crate::stories::WithRemSizeStory).into(), - Self::IndentGuides => crate::stories::IndentGuidesStory::model(window, cx).into(), - } - } -} - -#[derive(Debug, PartialEq, Eq, Clone, Copy)] -pub enum StorySelector { - Component(ComponentStory), - KitchenSink, -} - -impl FromStr for StorySelector { - type Err = anyhow::Error; - - fn from_str(raw_story_name: &str) -> std::result::Result { - use anyhow::Context as _; - - let story = raw_story_name.to_ascii_lowercase(); - - if story == "kitchen_sink" { - return Ok(Self::KitchenSink); - } - - if let Some((_, story)) = story.split_once("components/") { - let component_story = ComponentStory::from_str(story) - .with_context(|| format!("story not found for component '{story}'"))?; - - return Ok(Self::Component(component_story)); - } - - anyhow::bail!("story not found for '{raw_story_name}'") - } -} - -impl StorySelector { - pub fn story(&self, window: &mut Window, cx: &mut App) -> AnyView { - match self { - Self::Component(component_story) => component_story.story(window, cx), - Self::KitchenSink => KitchenSinkStory::model(cx).into(), - } - } -} - -/// The list of all stories available in the storybook. -static ALL_STORY_SELECTORS: OnceLock> = OnceLock::new(); - -impl ValueEnum for StorySelector { - fn value_variants<'a>() -> &'a [Self] { - (ALL_STORY_SELECTORS.get_or_init(|| { - let component_stories = ComponentStory::iter().map(StorySelector::Component); - - component_stories - .chain(std::iter::once(StorySelector::KitchenSink)) - .collect::>() - })) as _ - } - - fn to_possible_value(&self) -> Option { - let value = match self { - Self::Component(story) => format!("components/{story}"), - Self::KitchenSink => "kitchen_sink".to_string(), - }; - - Some(PossibleValue::new(value)) - } -} diff --git a/crates/storybook/src/storybook.rs b/crates/storybook/src/storybook.rs deleted file mode 100644 index d3df9bbc3a078793ab8e00c71cd4cb5cb9810fa6..0000000000000000000000000000000000000000 --- a/crates/storybook/src/storybook.rs +++ /dev/null @@ -1,162 +0,0 @@ -mod actions; -mod app_menus; -mod assets; -mod stories; -mod story_selector; - -use std::sync::Arc; - -use clap::Parser; -use dialoguer::FuzzySelect; -use gpui::{ - AnyView, App, Bounds, Context, Render, Window, WindowBounds, WindowOptions, - colors::{Colors, GlobalColors}, - div, px, size, -}; -use log::LevelFilter; -use reqwest_client::ReqwestClient; -use settings::{KeymapFile, Settings as _}; -use simplelog::SimpleLogger; -use strum::IntoEnumIterator; -use theme_settings::ThemeSettings; -use ui::prelude::*; - -use crate::app_menus::app_menus; -use crate::assets::Assets; -use crate::story_selector::{ComponentStory, StorySelector}; -use actions::Quit; -pub use indoc::indoc; - -#[derive(Parser)] -#[command(author, version, about, long_about = None)] -struct Args { - #[arg(value_enum)] - story: Option, - - /// The name of the theme to use in the storybook. - /// - /// If not provided, the default theme will be used. - #[arg(long)] - theme: Option, -} - -fn main() { - SimpleLogger::init(LevelFilter::Info, Default::default()).expect("could not initialize logger"); - - menu::init(); - let args = Args::parse(); - - let story_selector = args.story.unwrap_or_else(|| { - let stories = ComponentStory::iter().collect::>(); - - ctrlc::set_handler(move || {}).unwrap(); - - let result = FuzzySelect::new() - .with_prompt("Choose a story to run:") - .items(&stories) - .interact(); - - let Ok(selection) = result else { - dialoguer::console::Term::stderr().show_cursor().unwrap(); - std::process::exit(0); - }; - - StorySelector::Component(stories[selection]) - }); - let theme_name = args.theme.unwrap_or("One Dark".to_string()); - - gpui_platform::application() - .with_assets(Assets) - .run(move |cx| { - load_embedded_fonts(cx).unwrap(); - - cx.set_global(GlobalColors(Arc::new(Colors::default()))); - - let http_client = ReqwestClient::user_agent("zed_storybook").unwrap(); - cx.set_http_client(Arc::new(http_client)); - - settings::init(cx); - theme_settings::init(theme::LoadThemes::All(Box::new(Assets)), cx); - - let selector = story_selector; - - let mut theme_settings = ThemeSettings::get_global(cx).clone(); - theme_settings.theme = - theme_settings::ThemeSelection::Static(settings::ThemeName(theme_name.into())); - ThemeSettings::override_global(theme_settings, cx); - - editor::init(cx); - init(cx); - load_storybook_keymap(cx); - cx.set_menus(app_menus()); - - let size = size(px(1500.), px(780.)); - let bounds = Bounds::centered(None, size, cx); - let _window = cx.open_window( - WindowOptions { - window_bounds: Some(WindowBounds::Windowed(bounds)), - ..Default::default() - }, - move |window, cx| { - theme_settings::setup_ui_font(window, cx); - - cx.new(|cx| StoryWrapper::new(selector.story(window, cx))) - }, - ); - - cx.activate(true); - }); -} - -#[derive(Clone)] -pub struct StoryWrapper { - story: AnyView, -} - -impl StoryWrapper { - pub(crate) fn new(story: AnyView) -> Self { - Self { story } - } -} - -impl Render for StoryWrapper { - fn render(&mut self, _window: &mut Window, _cx: &mut Context) -> impl IntoElement { - div() - .flex() - .flex_col() - .size_full() - .font_family(".ZedMono") - .child(self.story.clone()) - } -} - -fn load_embedded_fonts(cx: &App) -> anyhow::Result<()> { - let font_paths = cx.asset_source().list("fonts")?; - let mut embedded_fonts = Vec::new(); - for font_path in font_paths { - if font_path.ends_with(".ttf") { - let font_bytes = cx - .asset_source() - .load(&font_path)? - .expect("Should never be None in the storybook"); - embedded_fonts.push(font_bytes); - } - } - - cx.text_system().add_fonts(embedded_fonts) -} - -fn load_storybook_keymap(cx: &mut App) { - cx.bind_keys(KeymapFile::load_asset("keymaps/storybook.json", None, cx).unwrap()); -} - -pub fn init(cx: &mut App) { - cx.on_action(quit); -} - -fn quit(_: &Quit, cx: &mut App) { - cx.spawn(async move |cx| { - cx.update(|cx| cx.quit()); - }) - .detach(); -} diff --git a/crates/theme/Cargo.toml b/crates/theme/Cargo.toml index 5bb624dd0c101aa978e296a7ff33c02b2faa99c1..77570b2ae4abd71bb54c11e3394f4514d9dc156e 100644 --- a/crates/theme/Cargo.toml +++ b/crates/theme/Cargo.toml @@ -19,7 +19,6 @@ doctest = false [dependencies] anyhow.workspace = true collections.workspace = true -derive_more.workspace = true gpui.workspace = true syntax_theme.workspace = true palette = { workspace = true, default-features = false, features = ["std"] } diff --git a/crates/theme/src/registry.rs b/crates/theme/src/registry.rs index 8630af9deda0d403e257bbc173f0f260ef32e184..6d8ae4ab86389de6ada63d12f2593863b21dcfae 100644 --- a/crates/theme/src/registry.rs +++ b/crates/theme/src/registry.rs @@ -3,7 +3,6 @@ use std::{fmt::Debug, path::Path}; use anyhow::Result; use collections::HashMap; -use derive_more::{Deref, DerefMut}; use gpui::{App, AssetSource, Global, SharedString}; use parking_lot::RwLock; use thiserror::Error; @@ -38,9 +37,23 @@ pub struct IconThemeNotFoundError(pub SharedString); /// inserting the [`ThemeRegistry`] into the context as a global. /// /// This should not be exposed outside of this module. -#[derive(Default, Deref, DerefMut)] +#[derive(Default)] struct GlobalThemeRegistry(Arc); +impl std::ops::DerefMut for GlobalThemeRegistry { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl std::ops::Deref for GlobalThemeRegistry { + type Target = Arc; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + impl Global for GlobalThemeRegistry {} struct ThemeRegistryState { diff --git a/crates/theme/src/theme.rs b/crates/theme/src/theme.rs index faa18bd3ce9ed71f4afed6d21d577d48b14680fb..cf4203dc763a6bbb04c8798d55e39b78f8e8a645 100644 --- a/crates/theme/src/theme.rs +++ b/crates/theme/src/theme.rs @@ -22,7 +22,6 @@ mod ui_density; use std::sync::Arc; -use derive_more::{Deref, DerefMut}; use gpui::BorrowAppContext; use gpui::Global; use gpui::{ @@ -129,18 +128,40 @@ impl ActiveTheme for App { } /// The appearance of the system. -#[derive(Debug, Clone, Copy, Deref)] +#[derive(Debug, Clone, Copy)] pub struct SystemAppearance(pub Appearance); +impl std::ops::Deref for SystemAppearance { + type Target = Appearance; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + impl Default for SystemAppearance { fn default() -> Self { Self(Appearance::Dark) } } -#[derive(Deref, DerefMut, Default)] +#[derive(Default)] struct GlobalSystemAppearance(SystemAppearance); +impl std::ops::DerefMut for GlobalSystemAppearance { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl std::ops::Deref for GlobalSystemAppearance { + type Target = SystemAppearance; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + impl Global for GlobalSystemAppearance {} impl SystemAppearance { diff --git a/crates/title_bar/Cargo.toml b/crates/title_bar/Cargo.toml index ef59ada28baa878d2cfc37ba52b4912e261274e8..eed94c839c0d0489944bf64725537234052c8e5f 100644 --- a/crates/title_bar/Cargo.toml +++ b/crates/title_bar/Cargo.toml @@ -14,7 +14,7 @@ doctest = false [features] default = [] -stories = ["dep:story"] + test-support = [ "call/test-support", "client/test-support", @@ -53,7 +53,6 @@ schemars.workspace = true serde.workspace = true settings.workspace = true smallvec.workspace = true -story = { workspace = true, optional = true } telemetry.workspace = true theme.workspace = true ui.workspace = true diff --git a/crates/title_bar/src/stories/application_menu.rs b/crates/title_bar/src/stories/application_menu.rs deleted file mode 100644 index f47f2a6c76b0781c6011993690d1aada95414545..0000000000000000000000000000000000000000 --- a/crates/title_bar/src/stories/application_menu.rs +++ /dev/null @@ -1,29 +0,0 @@ -use gpui::{Entity, Render}; -use story::{Story, StoryItem, StorySection}; - -use ui::prelude::*; - -use crate::application_menu::ApplicationMenu; - -pub struct ApplicationMenuStory { - menu: Entity, -} - -impl ApplicationMenuStory { - pub fn new(window: &mut Window, cx: &mut App) -> Self { - Self { - menu: cx.new(|cx| ApplicationMenu::new(window, cx)), - } - } -} - -impl Render for ApplicationMenuStory { - fn render(&mut self, _window: &mut Window, cx: &mut Context) -> impl IntoElement { - Story::container(cx) - .child(Story::title_for::(cx)) - .child(StorySection::new().child(StoryItem::new( - "Application Menu", - h_flex().child(self.menu.clone()), - ))) - } -} diff --git a/crates/title_bar/src/title_bar.rs b/crates/title_bar/src/title_bar.rs index 164cefc296e0a618e8698f1da5e387b84648ff96..34cad6f9540b1f8ba17aca08176b6950cdc7febe 100644 --- a/crates/title_bar/src/title_bar.rs +++ b/crates/title_bar/src/title_bar.rs @@ -5,9 +5,6 @@ mod plan_chip; mod title_bar_settings; mod update_version; -#[cfg(feature = "stories")] -mod stories; - use crate::application_menu::{ApplicationMenu, show_menus}; use crate::plan_chip::PlanChip; pub use platform_title_bar::{ @@ -56,9 +53,6 @@ use zed_actions::OpenRemote; pub use onboarding_banner::restore_banner; -#[cfg(feature = "stories")] -pub use stories::*; - const MAX_PROJECT_NAME_LENGTH: usize = 40; const MAX_BRANCH_NAME_LENGTH: usize = 40; const MAX_SHORT_SHA_LENGTH: usize = 8; diff --git a/crates/ui/Cargo.toml b/crates/ui/Cargo.toml index 05433bf8eebf78eccbbedff7a4bfcfb39b0022a7..4ae0e6d2e46b393d2962671de1f0a49f050fda19 100644 --- a/crates/ui/Cargo.toml +++ b/crates/ui/Cargo.toml @@ -24,7 +24,6 @@ menu.workspace = true schemars.workspace = true serde.workspace = true smallvec.workspace = true -story = { workspace = true, optional = true } strum.workspace = true theme.workspace = true ui_macros.workspace = true @@ -38,4 +37,3 @@ gpui = { workspace = true, features = ["test-support"] } [features] default = [] -stories = ["dep:story"] diff --git a/crates/ui/src/components.rs b/crates/ui/src/components.rs index 367d80d79c9af8722091e36c8e04bafb7ef0d8b5..6c0242a79130641376aefd744e2ffa08bbc65a40 100644 --- a/crates/ui/src/components.rs +++ b/crates/ui/src/components.rs @@ -40,9 +40,6 @@ mod toggle; mod tooltip; mod tree_view_item; -#[cfg(feature = "stories")] -mod stories; - pub use ai::*; pub use avatar::*; pub use banner::*; @@ -84,6 +81,3 @@ pub use tab_bar::*; pub use toggle::*; pub use tooltip::*; pub use tree_view_item::*; - -#[cfg(feature = "stories")] -pub use stories::*; diff --git a/crates/ui/src/components/stories/context_menu.rs b/crates/ui/src/components/stories/context_menu.rs deleted file mode 100644 index 197964adc86ef25b52eacd0631e4e7989b49bec0..0000000000000000000000000000000000000000 --- a/crates/ui/src/components/stories/context_menu.rs +++ /dev/null @@ -1,81 +0,0 @@ -use gpui::{Corner, Entity, Render, actions}; -use story::Story; - -use crate::prelude::*; -use crate::{ContextMenu, Label, right_click_menu}; - -actions!(stories, [PrintCurrentDate, PrintBestFood]); - -fn build_menu( - window: &mut Window, - cx: &mut App, - header: impl Into, -) -> Entity { - ContextMenu::build(window, cx, |menu, _, _| { - menu.header(header) - .separator() - .action("Print current time", Box::new(PrintCurrentDate)) - .entry( - "Print best food", - Some(Box::new(PrintBestFood)), - |window, cx| window.dispatch_action(Box::new(PrintBestFood), cx), - ) - }) -} - -pub struct ContextMenuStory; - -impl Render for ContextMenuStory { - fn render(&mut self, _window: &mut Window, cx: &mut Context) -> impl IntoElement { - Story::container(cx) - .on_action(|_: &PrintCurrentDate, _, _| { - println!("printing unix time!"); - if let Ok(unix_time) = std::time::UNIX_EPOCH.elapsed() { - println!("Current Unix time is {:?}", unix_time.as_secs()); - } - }) - .on_action(|_: &PrintBestFood, _, _| { - println!("burrito"); - }) - .flex() - .flex_row() - .justify_between() - .child( - div() - .flex() - .flex_col() - .justify_between() - .child( - right_click_menu("test2") - .trigger(|_, _, _| Label::new("TOP LEFT")) - .menu(move |window, cx| build_menu(window, cx, "top left")), - ) - .child( - right_click_menu("test1") - .trigger(|_, _, _| Label::new("BOTTOM LEFT")) - .anchor(Corner::BottomLeft) - .attach(Corner::TopLeft) - .menu(move |window, cx| build_menu(window, cx, "bottom left")), - ), - ) - .child( - div() - .flex() - .flex_col() - .justify_between() - .child( - right_click_menu("test3") - .trigger(|_, _, _| Label::new("TOP RIGHT")) - .anchor(Corner::TopRight) - .menu(move |window, cx| build_menu(window, cx, "top right")), - ) - .child( - right_click_menu("test4") - .trigger(|_, _, _| Label::new("BOTTOM RIGHT")) - .anchor(Corner::BottomRight) - .attach(Corner::TopRight) - .menu(move |window, cx| build_menu(window, cx, "bottom right")), - ), - ) - } -}