Detailed changes
@@ -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",
@@ -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 }
@@ -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
@@ -1 +0,0 @@
-../../LICENSE-GPL
@@ -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> {
- 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<SharedString>, cx: &App) -> impl Element {
- div()
- .text_xs()
- .text_color(cx.default_colors().text)
- .child(title.into())
- }
-
- pub fn title_for<T>(cx: &App) -> impl Element {
- Self::title(std::any::type_name::<T>(), 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<SharedString>, 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<SharedString>, 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<SharedString>, 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<SharedString>,
- usage: Option<SharedString>,
-}
-
-impl StoryItem {
- pub fn new(label: impl Into<SharedString>, 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<SharedString>) -> Self {
- self.description = Some(description.into());
- self
- }
-
- pub fn usage(mut self, code: impl Into<SharedString>) -> 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<SharedString>,
- 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<SharedString>) -> 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<Item = AnyElement>) {
- self.children.extend(elements)
- }
-}
@@ -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"] }
@@ -1 +0,0 @@
-../../LICENSE-GPL
@@ -1,9 +0,0 @@
-fn main() {
- #[cfg(target_os = "windows")]
- {
- #[cfg(target_env = "msvc")]
- {
- println!("cargo:rustc-link-arg=/stack:{}", 8 * 1024 * 1024);
- }
- }
-}
@@ -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<E: Element> {
-
-}
-
-impl<V> Element<V> 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<V>(layout: Layout, cx: &mut PaintContext<V>);
- pub fn paint_foreground<V>(layout: Layout, cx: &mut PaintContext<V>);
-}
-
-pub trait Interactive<V> {
- fn interactions(&mut self) -> &mut Interactions<V>;
-
- fn on_click(self, )
-}
-
-struct Interactions<V> {
- click: SmallVec<[<Rc<dyn Fn(&mut V, &dyn Any, )>; 1]>,
-}
-```
-
-```rs
-trait Stylable {
- type Style;
-
- fn with_style(self, style: Self::Style) -> Self;
-}
-```
@@ -1,2 +0,0 @@
-use gpui::actions;
-actions!(storybook, [Quit]);
@@ -1,7 +0,0 @@
-use gpui::{Menu, MenuItem};
-
-pub fn app_menus() -> Vec<Menu> {
- use crate::actions::Quit;
-
- vec![Menu::new("Storybook").items([MenuItem::action("Quit", Quit)])]
-}
@@ -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<Option<Cow<'static, [u8]>>> {
- 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<Vec<SharedString>> {
- Ok(Self::iter()
- .filter(|p| p.starts_with(path))
- .map(SharedString::from)
- .collect())
- }
-}
@@ -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::*;
@@ -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<Editor>,
-}
-
-impl AutoHeightEditorStory {
- pub fn new(window: &mut Window, cx: &mut App) -> gpui::Entity<Self> {
- 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<Self>) -> impl IntoElement {
- div()
- .size_full()
- .bg(white())
- .text_sm()
- .child(div().w_32().bg(gpui::black()).child(self.editor.clone()))
- }
-}
@@ -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<Self>) -> impl IntoElement {
- let all_cursors: [(&str, Box<dyn Fn(Stateful<Div>) -> Stateful<Div>>); 19] = [
- (
- "cursor_default",
- Box::new(|el: Stateful<Div>| el.cursor_default()),
- ),
- (
- "cursor_pointer",
- Box::new(|el: Stateful<Div>| el.cursor_pointer()),
- ),
- (
- "cursor_text",
- Box::new(|el: Stateful<Div>| el.cursor_text()),
- ),
- (
- "cursor_move",
- Box::new(|el: Stateful<Div>| el.cursor_move()),
- ),
- (
- "cursor_not_allowed",
- Box::new(|el: Stateful<Div>| el.cursor_not_allowed()),
- ),
- (
- "cursor_context_menu",
- Box::new(|el: Stateful<Div>| el.cursor_context_menu()),
- ),
- (
- "cursor_crosshair",
- Box::new(|el: Stateful<Div>| el.cursor_crosshair()),
- ),
- (
- "cursor_vertical_text",
- Box::new(|el: Stateful<Div>| el.cursor_vertical_text()),
- ),
- (
- "cursor_alias",
- Box::new(|el: Stateful<Div>| el.cursor_alias()),
- ),
- (
- "cursor_copy",
- Box::new(|el: Stateful<Div>| el.cursor_copy()),
- ),
- (
- "cursor_no_drop",
- Box::new(|el: Stateful<Div>| el.cursor_no_drop()),
- ),
- (
- "cursor_grab",
- Box::new(|el: Stateful<Div>| el.cursor_grab()),
- ),
- (
- "cursor_grabbing",
- Box::new(|el: Stateful<Div>| el.cursor_grabbing()),
- ),
- (
- "cursor_col_resize",
- Box::new(|el: Stateful<Div>| el.cursor_col_resize()),
- ),
- (
- "cursor_row_resize",
- Box::new(|el: Stateful<Div>| el.cursor_row_resize()),
- ),
- (
- "cursor_n_resize",
- Box::new(|el: Stateful<Div>| el.cursor_n_resize()),
- ),
- (
- "cursor_e_resize",
- Box::new(|el: Stateful<Div>| el.cursor_e_resize()),
- ),
- (
- "cursor_s_resize",
- Box::new(|el: Stateful<Div>| el.cursor_s_resize()),
- ),
- (
- "cursor_w_resize",
- Box::new(|el: Stateful<Div>| 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)),
- )
- }))
- }
-}
@@ -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<Subscription>,
-}
-
-impl FocusStory {
- pub fn model(window: &mut Window, cx: &mut App) -> Entity<Self> {
- 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<Self>) -> 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"),
- )
- }
-}
@@ -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<usize>,
-}
-
-impl IndentGuidesStory {
- pub fn model(_window: &mut Window, cx: &mut App) -> Entity<Self> {
- 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<Self>) -> 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<usize>, _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()
- },
- ),
- ),
- ),
- )
- }
-}
@@ -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<Self> {
- cx.new(|_| Self)
- }
-}
-
-impl Render for KitchenSinkStory {
- fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
- let component_stories = ComponentStory::iter()
- .map(|selector| selector.story(window, cx))
- .collect::<Vec<_>>();
-
- 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())
- }
-}
@@ -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<Self>) -> 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)))
- })),
- )
- }
-}
@@ -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<Picker<Delegate>>,
-}
-
-struct Delegate {
- candidates: Arc<[StringMatchCandidate]>,
- matches: Vec<usize>,
- 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<str> {
- "Test".into()
- }
-
- fn render_match(
- &self,
- ix: usize,
- selected: bool,
- _window: &mut Window,
- _cx: &mut Context<Picker<Self>>,
- ) -> Option<Self::ListItem> {
- 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<Picker<Self>>) {
- self.selected_ix = ix;
- cx.notify();
- }
-
- fn confirm(&mut self, secondary: bool, _window: &mut Window, _cx: &mut Context<Picker<Self>>) {
- 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<Picker<Self>>) {
- cx.quit();
- }
-
- fn update_matches(
- &mut self,
- query: String,
- _: &mut Window,
- cx: &mut Context<Picker<Self>>,
- ) -> 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<Self> {
- 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<Self>) -> impl IntoElement {
- div()
- .bg(cx.theme().styles.colors.background)
- .size_full()
- .child(self.picker.clone())
- }
-}
@@ -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<ScrollStory> {
- cx.new(|_| ScrollStory)
- }
-}
-
-impl Render for ScrollStory {
- fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> 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))
- })
- }))
- }))
- }
-}
@@ -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<Self> {
- cx.new(|_| Self)
- }
-}
-
-impl Render for TextStory {
- fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> 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()
- }
-}
@@ -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<Self>) -> 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"),
- ),
- )
- }
-}
@@ -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<Self>) -> 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<AnyElement>,
-}
-
-impl Example {
- pub fn new(rem_size: impl Into<Pixels>, 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<Item = AnyElement>) {
- 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),
- )
- }
-}
@@ -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<Self, Self::Err> {
- 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<Vec<StorySelector>> = 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::<Vec<_>>()
- })) as _
- }
-
- fn to_possible_value(&self) -> Option<clap::builder::PossibleValue> {
- let value = match self {
- Self::Component(story) => format!("components/{story}"),
- Self::KitchenSink => "kitchen_sink".to_string(),
- };
-
- Some(PossibleValue::new(value))
- }
-}
@@ -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<StorySelector>,
-
- /// The name of the theme to use in the storybook.
- ///
- /// If not provided, the default theme will be used.
- #[arg(long)]
- theme: Option<String>,
-}
-
-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::<Vec<_>>();
-
- 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<Self>) -> 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();
-}
@@ -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"] }
@@ -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<ThemeRegistry>);
+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<ThemeRegistry>;
+
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}
+
impl Global for GlobalThemeRegistry {}
struct ThemeRegistryState {
@@ -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 {
@@ -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
@@ -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<ApplicationMenu>,
-}
-
-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<Self>) -> impl IntoElement {
- Story::container(cx)
- .child(Story::title_for::<ApplicationMenu>(cx))
- .child(StorySection::new().child(StoryItem::new(
- "Application Menu",
- h_flex().child(self.menu.clone()),
- )))
- }
-}
@@ -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;
@@ -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"]
@@ -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::*;
@@ -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<SharedString>,
-) -> Entity<ContextMenu> {
- 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<Self>) -> 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")),
- ),
- )
- }
-}