ui: Remove outdated/unused component stories (#43118)
This PR removes basically all of the component stories, with the exception of the context menu, which is a bit more intricate to set up. All of the component that won't have a story after this PR will have an entry in the Component Preview, which serves basically the same purpose. Release Notes: - N/A
This commit is contained in:
@@ -17,16 +17,9 @@ pub enum ComponentStory {
|
||||
ContextMenu,
|
||||
Cursor,
|
||||
Focus,
|
||||
IconButton,
|
||||
Keybinding,
|
||||
List,
|
||||
ListHeader,
|
||||
ListItem,
|
||||
OverflowScroll,
|
||||
Picker,
|
||||
Scroll,
|
||||
Tab,
|
||||
TabBar,
|
||||
Text,
|
||||
ViewportUnits,
|
||||
WithRemSize,
|
||||
@@ -46,16 +39,9 @@ impl ComponentStory {
|
||||
Self::ContextMenu => cx.new(|_| ui::ContextMenuStory).into(),
|
||||
Self::Cursor => cx.new(|_| crate::stories::CursorStory).into(),
|
||||
Self::Focus => FocusStory::model(window, cx).into(),
|
||||
Self::IconButton => cx.new(|_| ui::IconButtonStory).into(),
|
||||
Self::Keybinding => cx.new(|_| ui::KeybindingStory).into(),
|
||||
Self::List => cx.new(|_| ui::ListStory).into(),
|
||||
Self::ListHeader => cx.new(|_| ui::ListHeaderStory).into(),
|
||||
Self::ListItem => cx.new(|_| ui::ListItemStory).into(),
|
||||
Self::OverflowScroll => cx.new(|_| crate::stories::OverflowScrollStory).into(),
|
||||
Self::Picker => PickerStory::new(window, cx).into(),
|
||||
Self::Scroll => ScrollStory::model(cx).into(),
|
||||
Self::Tab => cx.new(|_| ui::TabStory).into(),
|
||||
Self::TabBar => cx.new(|_| ui::TabBarStory).into(),
|
||||
Self::Text => TextStory::model(cx).into(),
|
||||
Self::ViewportUnits => cx.new(|_| crate::stories::ViewportUnitsStory).into(),
|
||||
Self::WithRemSize => cx.new(|_| crate::stories::WithRemSizeStory).into(),
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
use component::{Component, ComponentScope, example_group_with_title, single_example};
|
||||
use gpui::AnyElement;
|
||||
use smallvec::SmallVec;
|
||||
|
||||
use crate::{Label, ListHeader, prelude::*, v_flex};
|
||||
use crate::{Label, ListHeader, ListItem, prelude::*};
|
||||
|
||||
pub enum EmptyMessage {
|
||||
Text(SharedString),
|
||||
Element(AnyElement),
|
||||
}
|
||||
|
||||
#[derive(IntoElement)]
|
||||
#[derive(IntoElement, RegisterComponent)]
|
||||
pub struct List {
|
||||
/// Message to display when the list is empty
|
||||
/// Defaults to "No items"
|
||||
@@ -92,3 +93,50 @@ impl RenderOnce for List {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Component for List {
|
||||
fn scope() -> ComponentScope {
|
||||
ComponentScope::Layout
|
||||
}
|
||||
|
||||
fn description() -> Option<&'static str> {
|
||||
Some(
|
||||
"A container component for displaying a collection of list items with optional header and empty state.",
|
||||
)
|
||||
}
|
||||
|
||||
fn preview(_window: &mut Window, _cx: &mut App) -> Option<AnyElement> {
|
||||
Some(
|
||||
v_flex()
|
||||
.gap_6()
|
||||
.children(vec![example_group_with_title(
|
||||
"Basic Lists",
|
||||
vec![
|
||||
single_example(
|
||||
"Simple List",
|
||||
List::new()
|
||||
.child(ListItem::new("item1").child(Label::new("Item 1")))
|
||||
.child(ListItem::new("item2").child(Label::new("Item 2")))
|
||||
.child(ListItem::new("item3").child(Label::new("Item 3")))
|
||||
.into_any_element(),
|
||||
),
|
||||
single_example(
|
||||
"With Header",
|
||||
List::new()
|
||||
.header(ListHeader::new("Section Header"))
|
||||
.child(ListItem::new("item1").child(Label::new("Item 1")))
|
||||
.child(ListItem::new("item2").child(Label::new("Item 2")))
|
||||
.into_any_element(),
|
||||
),
|
||||
single_example(
|
||||
"Empty List",
|
||||
List::new()
|
||||
.empty_message("No items to display")
|
||||
.into_any_element(),
|
||||
),
|
||||
],
|
||||
)])
|
||||
.into_any_element(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
use crate::{ListItem, prelude::*};
|
||||
use component::{Component, ComponentScope, example_group_with_title, single_example};
|
||||
use gpui::{IntoElement, ParentElement, SharedString};
|
||||
|
||||
#[derive(IntoElement)]
|
||||
#[derive(IntoElement, RegisterComponent)]
|
||||
pub struct ListBulletItem {
|
||||
label: SharedString,
|
||||
}
|
||||
@@ -38,3 +39,45 @@ impl RenderOnce for ListBulletItem {
|
||||
.into_any_element()
|
||||
}
|
||||
}
|
||||
|
||||
impl Component for ListBulletItem {
|
||||
fn scope() -> ComponentScope {
|
||||
ComponentScope::DataDisplay
|
||||
}
|
||||
|
||||
fn description() -> Option<&'static str> {
|
||||
Some("A list item with a bullet point indicator for unordered lists.")
|
||||
}
|
||||
|
||||
fn preview(_window: &mut Window, _cx: &mut App) -> Option<AnyElement> {
|
||||
Some(
|
||||
v_flex()
|
||||
.gap_6()
|
||||
.child(example_group_with_title(
|
||||
"Bullet Items",
|
||||
vec![
|
||||
single_example(
|
||||
"Simple",
|
||||
ListBulletItem::new("First bullet item").into_any_element(),
|
||||
),
|
||||
single_example(
|
||||
"Multiple Lines",
|
||||
v_flex()
|
||||
.child(ListBulletItem::new("First item"))
|
||||
.child(ListBulletItem::new("Second item"))
|
||||
.child(ListBulletItem::new("Third item"))
|
||||
.into_any_element(),
|
||||
),
|
||||
single_example(
|
||||
"Long Text",
|
||||
ListBulletItem::new(
|
||||
"A longer bullet item that demonstrates text wrapping behavior",
|
||||
)
|
||||
.into_any_element(),
|
||||
),
|
||||
],
|
||||
))
|
||||
.into_any_element(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::{Disclosure, Label, h_flex, prelude::*};
|
||||
use crate::{Disclosure, prelude::*};
|
||||
use component::{Component, ComponentScope, example_group_with_title, single_example};
|
||||
use gpui::{AnyElement, ClickEvent};
|
||||
use settings::Settings;
|
||||
use theme::ThemeSettings;
|
||||
|
||||
#[derive(IntoElement)]
|
||||
#[derive(IntoElement, RegisterComponent)]
|
||||
pub struct ListHeader {
|
||||
/// The label of the header.
|
||||
label: SharedString,
|
||||
@@ -138,3 +139,80 @@ impl RenderOnce for ListHeader {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Component for ListHeader {
|
||||
fn scope() -> ComponentScope {
|
||||
ComponentScope::DataDisplay
|
||||
}
|
||||
|
||||
fn description() -> Option<&'static str> {
|
||||
Some(
|
||||
"A header component for lists with support for icons, actions, and collapsible sections.",
|
||||
)
|
||||
}
|
||||
|
||||
fn preview(_window: &mut Window, _cx: &mut App) -> Option<AnyElement> {
|
||||
Some(
|
||||
v_flex()
|
||||
.gap_6()
|
||||
.children(vec![
|
||||
example_group_with_title(
|
||||
"Basic Headers",
|
||||
vec![
|
||||
single_example(
|
||||
"Simple",
|
||||
ListHeader::new("Section Header").into_any_element(),
|
||||
),
|
||||
single_example(
|
||||
"With Icon",
|
||||
ListHeader::new("Files")
|
||||
.start_slot(Icon::new(IconName::File))
|
||||
.into_any_element(),
|
||||
),
|
||||
single_example(
|
||||
"With End Slot",
|
||||
ListHeader::new("Recent")
|
||||
.end_slot(Label::new("5").color(Color::Muted))
|
||||
.into_any_element(),
|
||||
),
|
||||
],
|
||||
),
|
||||
example_group_with_title(
|
||||
"Collapsible Headers",
|
||||
vec![
|
||||
single_example(
|
||||
"Expanded",
|
||||
ListHeader::new("Expanded Section")
|
||||
.toggle(Some(true))
|
||||
.into_any_element(),
|
||||
),
|
||||
single_example(
|
||||
"Collapsed",
|
||||
ListHeader::new("Collapsed Section")
|
||||
.toggle(Some(false))
|
||||
.into_any_element(),
|
||||
),
|
||||
],
|
||||
),
|
||||
example_group_with_title(
|
||||
"States",
|
||||
vec![
|
||||
single_example(
|
||||
"Selected",
|
||||
ListHeader::new("Selected Header")
|
||||
.toggle_state(true)
|
||||
.into_any_element(),
|
||||
),
|
||||
single_example(
|
||||
"Inset",
|
||||
ListHeader::new("Inset Header")
|
||||
.inset(true)
|
||||
.into_any_element(),
|
||||
),
|
||||
],
|
||||
),
|
||||
])
|
||||
.into_any_element(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use component::{Component, ComponentScope, example_group_with_title, single_example};
|
||||
use gpui::{AnyElement, AnyView, ClickEvent, MouseButton, MouseDownEvent, Pixels, px};
|
||||
use smallvec::SmallVec;
|
||||
|
||||
@@ -13,7 +14,7 @@ pub enum ListItemSpacing {
|
||||
Sparse,
|
||||
}
|
||||
|
||||
#[derive(IntoElement)]
|
||||
#[derive(IntoElement, RegisterComponent)]
|
||||
pub struct ListItem {
|
||||
id: ElementId,
|
||||
group_name: Option<SharedString>,
|
||||
@@ -355,3 +356,115 @@ impl RenderOnce for ListItem {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Component for ListItem {
|
||||
fn scope() -> ComponentScope {
|
||||
ComponentScope::DataDisplay
|
||||
}
|
||||
|
||||
fn description() -> Option<&'static str> {
|
||||
Some(
|
||||
"A flexible list item component with support for icons, actions, disclosure toggles, and hierarchical display.",
|
||||
)
|
||||
}
|
||||
|
||||
fn preview(_window: &mut Window, _cx: &mut App) -> Option<AnyElement> {
|
||||
Some(
|
||||
v_flex()
|
||||
.gap_6()
|
||||
.children(vec![
|
||||
example_group_with_title(
|
||||
"Basic List Items",
|
||||
vec![
|
||||
single_example(
|
||||
"Simple",
|
||||
ListItem::new("simple")
|
||||
.child(Label::new("Simple list item"))
|
||||
.into_any_element(),
|
||||
),
|
||||
single_example(
|
||||
"With Icon",
|
||||
ListItem::new("with_icon")
|
||||
.start_slot(Icon::new(IconName::File))
|
||||
.child(Label::new("List item with icon"))
|
||||
.into_any_element(),
|
||||
),
|
||||
single_example(
|
||||
"Selected",
|
||||
ListItem::new("selected")
|
||||
.toggle_state(true)
|
||||
.start_slot(Icon::new(IconName::Check))
|
||||
.child(Label::new("Selected item"))
|
||||
.into_any_element(),
|
||||
),
|
||||
],
|
||||
),
|
||||
example_group_with_title(
|
||||
"List Item Spacing",
|
||||
vec![
|
||||
single_example(
|
||||
"Dense",
|
||||
ListItem::new("dense")
|
||||
.spacing(ListItemSpacing::Dense)
|
||||
.child(Label::new("Dense spacing"))
|
||||
.into_any_element(),
|
||||
),
|
||||
single_example(
|
||||
"Extra Dense",
|
||||
ListItem::new("extra_dense")
|
||||
.spacing(ListItemSpacing::ExtraDense)
|
||||
.child(Label::new("Extra dense spacing"))
|
||||
.into_any_element(),
|
||||
),
|
||||
single_example(
|
||||
"Sparse",
|
||||
ListItem::new("sparse")
|
||||
.spacing(ListItemSpacing::Sparse)
|
||||
.child(Label::new("Sparse spacing"))
|
||||
.into_any_element(),
|
||||
),
|
||||
],
|
||||
),
|
||||
example_group_with_title(
|
||||
"With Slots",
|
||||
vec![
|
||||
single_example(
|
||||
"End Slot",
|
||||
ListItem::new("end_slot")
|
||||
.child(Label::new("Item with end slot"))
|
||||
.end_slot(Icon::new(IconName::ChevronRight))
|
||||
.into_any_element(),
|
||||
),
|
||||
single_example(
|
||||
"With Toggle",
|
||||
ListItem::new("with_toggle")
|
||||
.toggle(Some(true))
|
||||
.child(Label::new("Expandable item"))
|
||||
.into_any_element(),
|
||||
),
|
||||
],
|
||||
),
|
||||
example_group_with_title(
|
||||
"States",
|
||||
vec![
|
||||
single_example(
|
||||
"Disabled",
|
||||
ListItem::new("disabled")
|
||||
.disabled(true)
|
||||
.child(Label::new("Disabled item"))
|
||||
.into_any_element(),
|
||||
),
|
||||
single_example(
|
||||
"Non-selectable",
|
||||
ListItem::new("non_selectable")
|
||||
.selectable(false)
|
||||
.child(Label::new("Non-selectable item"))
|
||||
.into_any_element(),
|
||||
),
|
||||
],
|
||||
),
|
||||
])
|
||||
.into_any_element(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::prelude::*;
|
||||
use crate::{Icon, IconName, IconSize, Label, h_flex};
|
||||
use component::{Component, ComponentScope, example_group_with_title, single_example};
|
||||
|
||||
#[derive(IntoElement)]
|
||||
#[derive(IntoElement, RegisterComponent)]
|
||||
pub struct ListSubHeader {
|
||||
label: SharedString,
|
||||
start_slot: Option<IconName>,
|
||||
@@ -85,3 +85,65 @@ impl RenderOnce for ListSubHeader {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Component for ListSubHeader {
|
||||
fn scope() -> ComponentScope {
|
||||
ComponentScope::DataDisplay
|
||||
}
|
||||
|
||||
fn description() -> Option<&'static str> {
|
||||
Some(
|
||||
"A sub-header component for organizing list content into subsections with optional icons and end slots.",
|
||||
)
|
||||
}
|
||||
|
||||
fn preview(_window: &mut Window, _cx: &mut App) -> Option<AnyElement> {
|
||||
Some(
|
||||
v_flex()
|
||||
.gap_6()
|
||||
.children(vec![
|
||||
example_group_with_title(
|
||||
"Basic Sub-headers",
|
||||
vec![
|
||||
single_example(
|
||||
"Simple",
|
||||
ListSubHeader::new("Subsection").into_any_element(),
|
||||
),
|
||||
single_example(
|
||||
"With Icon",
|
||||
ListSubHeader::new("Documents")
|
||||
.left_icon(Some(IconName::File))
|
||||
.into_any_element(),
|
||||
),
|
||||
single_example(
|
||||
"With End Slot",
|
||||
ListSubHeader::new("Recent")
|
||||
.end_slot(
|
||||
Label::new("3").color(Color::Muted).into_any_element(),
|
||||
)
|
||||
.into_any_element(),
|
||||
),
|
||||
],
|
||||
),
|
||||
example_group_with_title(
|
||||
"States",
|
||||
vec![
|
||||
single_example(
|
||||
"Selected",
|
||||
ListSubHeader::new("Selected")
|
||||
.toggle_state(true)
|
||||
.into_any_element(),
|
||||
),
|
||||
single_example(
|
||||
"Inset",
|
||||
ListSubHeader::new("Inset Sub-header")
|
||||
.inset(true)
|
||||
.into_any_element(),
|
||||
),
|
||||
],
|
||||
),
|
||||
])
|
||||
.into_any_element(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,3 @@
|
||||
mod context_menu;
|
||||
mod icon_button;
|
||||
mod keybinding;
|
||||
mod list;
|
||||
mod list_header;
|
||||
mod list_item;
|
||||
mod tab;
|
||||
mod tab_bar;
|
||||
|
||||
pub use context_menu::*;
|
||||
pub use icon_button::*;
|
||||
pub use keybinding::*;
|
||||
pub use list::*;
|
||||
pub use list_header::*;
|
||||
pub use list_item::*;
|
||||
pub use tab::*;
|
||||
pub use tab_bar::*;
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
use gpui::Render;
|
||||
use story::Story;
|
||||
|
||||
use crate::Disclosure;
|
||||
use crate::prelude::*;
|
||||
|
||||
pub struct DisclosureStory;
|
||||
|
||||
impl Render for DisclosureStory {
|
||||
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
Story::container(cx)
|
||||
.child(Story::title_for::<Disclosure>(cx))
|
||||
.child(Story::label("Toggled"))
|
||||
.child(Disclosure::new("toggled", true))
|
||||
.child(Story::label("Not Toggled"))
|
||||
.child(Disclosure::new("not_toggled", false))
|
||||
}
|
||||
}
|
||||
@@ -1,148 +0,0 @@
|
||||
use gpui::Render;
|
||||
use story::{Story, StoryItem, StorySection};
|
||||
|
||||
use crate::{IconButton, IconName};
|
||||
use crate::{IconButtonShape, Tooltip, prelude::*};
|
||||
|
||||
pub struct IconButtonStory;
|
||||
|
||||
impl Render for IconButtonStory {
|
||||
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let default_button = StoryItem::new(
|
||||
"Default",
|
||||
IconButton::new("default_icon_button", IconName::Hash),
|
||||
)
|
||||
.description("Displays an icon button.")
|
||||
.usage(
|
||||
r#"
|
||||
IconButton::new("default_icon_button", Icon::Hash)
|
||||
"#,
|
||||
);
|
||||
|
||||
let selected_button = StoryItem::new(
|
||||
"Selected",
|
||||
IconButton::new("selected_icon_button", IconName::Hash).toggle_state(true),
|
||||
)
|
||||
.description("Displays an icon button that is selected.")
|
||||
.usage(
|
||||
r#"
|
||||
IconButton::new("selected_icon_button", Icon::Hash).selected(true)
|
||||
"#,
|
||||
);
|
||||
|
||||
let selected_with_selected_icon = StoryItem::new(
|
||||
"Selected with `selected_icon`",
|
||||
IconButton::new("selected_with_selected_icon_button", IconName::AudioOn)
|
||||
.toggle_state(true)
|
||||
.selected_icon(IconName::AudioOff),
|
||||
)
|
||||
.description(
|
||||
"Displays an icon button that is selected and shows a different icon when selected.",
|
||||
)
|
||||
.usage(
|
||||
r#"
|
||||
IconButton::new("selected_with_selected_icon_button", Icon::AudioOn)
|
||||
.selected(true)
|
||||
.selected_icon(Icon::AudioOff)
|
||||
"#,
|
||||
);
|
||||
|
||||
let disabled_button = StoryItem::new(
|
||||
"Disabled",
|
||||
IconButton::new("disabled_icon_button", IconName::Hash).disabled(true),
|
||||
)
|
||||
.description("Displays an icon button that is disabled.")
|
||||
.usage(
|
||||
r#"
|
||||
IconButton::new("disabled_icon_button", Icon::Hash).disabled(true)
|
||||
"#,
|
||||
);
|
||||
|
||||
let with_on_click_button = StoryItem::new(
|
||||
"With `on_click`",
|
||||
IconButton::new("with_on_click_button", IconName::Ai).on_click(
|
||||
|_event, _window, _cx| {
|
||||
println!("Clicked!");
|
||||
},
|
||||
),
|
||||
)
|
||||
.description("Displays an icon button which triggers an event on click.")
|
||||
.usage(
|
||||
r#"
|
||||
IconButton::new("with_on_click_button", Icon::Ai).on_click(|_event, _cx| {
|
||||
println!("Clicked!");
|
||||
})
|
||||
"#,
|
||||
);
|
||||
|
||||
let with_tooltip_button = StoryItem::new(
|
||||
"With `tooltip`",
|
||||
IconButton::new("with_tooltip_button", IconName::Chat)
|
||||
.tooltip(Tooltip::text("Open messages")),
|
||||
)
|
||||
.description("Displays an icon button that has a tooltip when hovered.")
|
||||
.usage(
|
||||
r#"
|
||||
IconButton::new("with_tooltip_button", Icon::MessageBubbles)
|
||||
.tooltip(Tooltip::text_f("Open messages"))
|
||||
"#,
|
||||
);
|
||||
|
||||
let selected_with_tooltip_button = StoryItem::new(
|
||||
"Selected with `tooltip`",
|
||||
IconButton::new("selected_with_tooltip_button", IconName::CaseSensitive)
|
||||
.toggle_state(true)
|
||||
.tooltip(Tooltip::text("Toggle inlay hints")),
|
||||
)
|
||||
.description("Displays a selected icon button with tooltip.")
|
||||
.usage(
|
||||
r#"
|
||||
IconButton::new("selected_with_tooltip_button", Icon::InlayHint)
|
||||
.selected(true)
|
||||
.tooltip(Tooltip::text_f("Toggle inlay hints"))
|
||||
"#,
|
||||
);
|
||||
|
||||
let buttons = vec![
|
||||
default_button,
|
||||
selected_button,
|
||||
selected_with_selected_icon,
|
||||
disabled_button,
|
||||
with_on_click_button,
|
||||
with_tooltip_button,
|
||||
selected_with_tooltip_button,
|
||||
];
|
||||
|
||||
Story::container(cx)
|
||||
.child(Story::title_for::<IconButton>(cx))
|
||||
.child(StorySection::new().children(buttons))
|
||||
.child(
|
||||
StorySection::new().child(StoryItem::new(
|
||||
"Square",
|
||||
h_flex()
|
||||
.gap_2()
|
||||
.child(
|
||||
IconButton::new("square-medium", IconName::Close)
|
||||
.shape(IconButtonShape::Square)
|
||||
.icon_size(IconSize::Medium),
|
||||
)
|
||||
.child(
|
||||
IconButton::new("square-small", IconName::Close)
|
||||
.shape(IconButtonShape::Square)
|
||||
.icon_size(IconSize::Small),
|
||||
)
|
||||
.child(
|
||||
IconButton::new("square-xsmall", IconName::Close)
|
||||
.shape(IconButtonShape::Square)
|
||||
.icon_size(IconSize::XSmall),
|
||||
)
|
||||
.child(
|
||||
IconButton::new("square-indicator", IconName::Close)
|
||||
.shape(IconButtonShape::Square)
|
||||
.icon_size(IconSize::Indicator),
|
||||
),
|
||||
)),
|
||||
)
|
||||
.into_element()
|
||||
}
|
||||
}
|
||||
@@ -1,136 +0,0 @@
|
||||
use gpui::NoAction;
|
||||
use gpui::Render;
|
||||
use itertools::Itertools;
|
||||
use settings::KeybindSource;
|
||||
use story::Story;
|
||||
|
||||
use crate::{KeyBinding, prelude::*};
|
||||
|
||||
pub struct KeybindingStory;
|
||||
|
||||
pub fn binding(key: &str) -> gpui::KeyBinding {
|
||||
gpui::KeyBinding::new(key, NoAction {}, None)
|
||||
}
|
||||
|
||||
impl Render for KeybindingStory {
|
||||
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let all_modifier_permutations = ["ctrl", "alt", "cmd", "shift"].into_iter().permutations(2);
|
||||
|
||||
const SOURCE: KeybindSource = KeybindSource::Base;
|
||||
|
||||
Story::container(cx)
|
||||
.child(Story::title_for::<KeyBinding>(cx))
|
||||
.child(Story::label("Single Key", cx))
|
||||
.child(KeyBinding::from_keystrokes(
|
||||
binding("Z").keystrokes().into(),
|
||||
SOURCE,
|
||||
))
|
||||
.child(Story::label("Single Key with Modifier", cx))
|
||||
.child(
|
||||
div()
|
||||
.flex()
|
||||
.gap_3()
|
||||
.child(KeyBinding::from_keystrokes(
|
||||
binding("ctrl-c").keystrokes().into(),
|
||||
SOURCE,
|
||||
))
|
||||
.child(KeyBinding::from_keystrokes(
|
||||
binding("alt-c").keystrokes().into(),
|
||||
SOURCE,
|
||||
))
|
||||
.child(KeyBinding::from_keystrokes(
|
||||
binding("cmd-c").keystrokes().into(),
|
||||
SOURCE,
|
||||
))
|
||||
.child(KeyBinding::from_keystrokes(
|
||||
binding("shift-c").keystrokes().into(),
|
||||
SOURCE,
|
||||
)),
|
||||
)
|
||||
.child(Story::label("Single Key with Modifier (Permuted)", cx))
|
||||
.child(
|
||||
div().flex().flex_col().children(
|
||||
all_modifier_permutations
|
||||
.chunks(4)
|
||||
.into_iter()
|
||||
.map(|chunk| {
|
||||
div()
|
||||
.flex()
|
||||
.gap_4()
|
||||
.py_3()
|
||||
.children(chunk.map(|permutation| {
|
||||
KeyBinding::from_keystrokes(
|
||||
binding(&(permutation.join("-") + "-x"))
|
||||
.keystrokes()
|
||||
.into(),
|
||||
SOURCE,
|
||||
)
|
||||
}))
|
||||
}),
|
||||
),
|
||||
)
|
||||
.child(Story::label("Single Key with All Modifiers", cx))
|
||||
.child(KeyBinding::from_keystrokes(
|
||||
binding("ctrl-alt-cmd-shift-z").keystrokes().into(),
|
||||
SOURCE,
|
||||
))
|
||||
.child(Story::label("Chord", cx))
|
||||
.child(KeyBinding::from_keystrokes(
|
||||
binding("a z").keystrokes().into(),
|
||||
SOURCE,
|
||||
))
|
||||
.child(Story::label("Chord with Modifier", cx))
|
||||
.child(KeyBinding::from_keystrokes(
|
||||
binding("ctrl-a shift-z").keystrokes().into(),
|
||||
SOURCE,
|
||||
))
|
||||
.child(KeyBinding::from_keystrokes(
|
||||
binding("fn-s").keystrokes().into(),
|
||||
SOURCE,
|
||||
))
|
||||
.child(Story::label("Single Key with All Modifiers (Linux)", cx))
|
||||
.child(
|
||||
KeyBinding::from_keystrokes(
|
||||
binding("ctrl-alt-cmd-shift-z").keystrokes().into(),
|
||||
SOURCE,
|
||||
)
|
||||
.platform_style(PlatformStyle::Linux),
|
||||
)
|
||||
.child(Story::label("Chord (Linux)", cx))
|
||||
.child(
|
||||
KeyBinding::from_keystrokes(binding("a z").keystrokes().into(), SOURCE)
|
||||
.platform_style(PlatformStyle::Linux),
|
||||
)
|
||||
.child(Story::label("Chord with Modifier (Linux)", cx))
|
||||
.child(
|
||||
KeyBinding::from_keystrokes(binding("ctrl-a shift-z").keystrokes().into(), SOURCE)
|
||||
.platform_style(PlatformStyle::Linux),
|
||||
)
|
||||
.child(
|
||||
KeyBinding::from_keystrokes(binding("fn-s").keystrokes().into(), SOURCE)
|
||||
.platform_style(PlatformStyle::Linux),
|
||||
)
|
||||
.child(Story::label("Single Key with All Modifiers (Windows)", cx))
|
||||
.child(
|
||||
KeyBinding::from_keystrokes(
|
||||
binding("ctrl-alt-cmd-shift-z").keystrokes().into(),
|
||||
SOURCE,
|
||||
)
|
||||
.platform_style(PlatformStyle::Windows),
|
||||
)
|
||||
.child(Story::label("Chord (Windows)", cx))
|
||||
.child(
|
||||
KeyBinding::from_keystrokes(binding("a z").keystrokes().into(), SOURCE)
|
||||
.platform_style(PlatformStyle::Windows),
|
||||
)
|
||||
.child(Story::label("Chord with Modifier (Windows)", cx))
|
||||
.child(
|
||||
KeyBinding::from_keystrokes(binding("ctrl-a shift-z").keystrokes().into(), SOURCE)
|
||||
.platform_style(PlatformStyle::Windows),
|
||||
)
|
||||
.child(
|
||||
KeyBinding::from_keystrokes(binding("fn-s").keystrokes().into(), SOURCE)
|
||||
.platform_style(PlatformStyle::Windows),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
use gpui::Render;
|
||||
use story::Story;
|
||||
|
||||
use crate::{List, ListItem};
|
||||
use crate::{ListHeader, ListSeparator, ListSubHeader, prelude::*};
|
||||
|
||||
pub struct ListStory;
|
||||
|
||||
impl Render for ListStory {
|
||||
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
Story::container(cx)
|
||||
.child(Story::title_for::<List>(cx))
|
||||
.child(Story::label("Default", cx))
|
||||
.child(
|
||||
List::new()
|
||||
.child(ListItem::new("apple").child("Apple"))
|
||||
.child(ListItem::new("banana").child("Banana"))
|
||||
.child(ListItem::new("cherry").child("Cherry")),
|
||||
)
|
||||
.child(Story::label("With sections", cx))
|
||||
.child(
|
||||
List::new()
|
||||
.header(ListHeader::new("Produce"))
|
||||
.child(ListSubHeader::new("Fruits"))
|
||||
.child(ListItem::new("apple").child("Apple"))
|
||||
.child(ListItem::new("banana").child("Banana"))
|
||||
.child(ListItem::new("cherry").child("Cherry"))
|
||||
.child(ListSeparator)
|
||||
.child(ListSubHeader::new("Root Vegetables"))
|
||||
.child(ListItem::new("carrot").child("Carrot"))
|
||||
.child(ListItem::new("potato").child("Potato"))
|
||||
.child(ListSubHeader::new("Leafy Vegetables"))
|
||||
.child(ListItem::new("kale").child("Kale")),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
use gpui::Render;
|
||||
use story::Story;
|
||||
|
||||
use crate::{IconButton, prelude::*};
|
||||
use crate::{IconName, ListHeader};
|
||||
|
||||
pub struct ListHeaderStory;
|
||||
|
||||
impl Render for ListHeaderStory {
|
||||
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
Story::container(cx)
|
||||
.child(Story::title_for::<ListHeader>(cx))
|
||||
.child(Story::label("Default", cx))
|
||||
.child(ListHeader::new("Section 1"))
|
||||
.child(Story::label("With left icon", cx))
|
||||
.child(ListHeader::new("Section 2").start_slot(Icon::new(IconName::Bell)))
|
||||
.child(Story::label("With left icon and meta", cx))
|
||||
.child(
|
||||
ListHeader::new("Section 3")
|
||||
.start_slot(Icon::new(IconName::BellOff))
|
||||
.end_slot(IconButton::new("action_1", IconName::BoltFilled)),
|
||||
)
|
||||
.child(Story::label("With multiple meta", cx))
|
||||
.child(
|
||||
ListHeader::new("Section 4")
|
||||
.end_slot(IconButton::new("action_1", IconName::BoltFilled))
|
||||
.end_slot(IconButton::new("action_2", IconName::Warning))
|
||||
.end_slot(IconButton::new("action_3", IconName::Plus)),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,131 +0,0 @@
|
||||
use gpui::Render;
|
||||
use story::Story;
|
||||
|
||||
use crate::{Avatar, prelude::*};
|
||||
use crate::{IconName, ListItem};
|
||||
|
||||
const OVERFLOWING_TEXT: &str = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean mauris ligula, luctus vel dignissim eu, vestibulum sed libero. Sed at convallis velit.";
|
||||
|
||||
pub struct ListItemStory;
|
||||
|
||||
impl Render for ListItemStory {
|
||||
fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
Story::container(cx)
|
||||
.bg(cx.theme().colors().background)
|
||||
.child(Story::title_for::<ListItem>(cx))
|
||||
.child(Story::label("Default", cx))
|
||||
.child(ListItem::new("hello_world").child("Hello, world!"))
|
||||
.child(Story::label("Inset", cx))
|
||||
.child(
|
||||
ListItem::new("inset_list_item")
|
||||
.inset(true)
|
||||
.start_slot(
|
||||
Icon::new(IconName::Bell)
|
||||
.size(IconSize::Small)
|
||||
.color(Color::Muted),
|
||||
)
|
||||
.child("Hello, world!")
|
||||
.end_slot(
|
||||
Icon::new(IconName::Bell)
|
||||
.size(IconSize::Small)
|
||||
.color(Color::Muted),
|
||||
),
|
||||
)
|
||||
.child(Story::label("With start slot icon", cx))
|
||||
.child(
|
||||
ListItem::new("with start slot_icon")
|
||||
.child("Hello, world!")
|
||||
.start_slot(
|
||||
Icon::new(IconName::Bell)
|
||||
.size(IconSize::Small)
|
||||
.color(Color::Muted),
|
||||
),
|
||||
)
|
||||
.child(Story::label("With start slot avatar", cx))
|
||||
.child(
|
||||
ListItem::new("with_start slot avatar")
|
||||
.child("Hello, world!")
|
||||
.start_slot(Avatar::new(
|
||||
"https://avatars.githubusercontent.com/u/1714999?v=4",
|
||||
)),
|
||||
)
|
||||
.child(Story::label("With end slot", cx))
|
||||
.child(
|
||||
ListItem::new("with_left_avatar")
|
||||
.child("Hello, world!")
|
||||
.end_slot(Avatar::new(
|
||||
"https://avatars.githubusercontent.com/u/1714999?v=4",
|
||||
)),
|
||||
)
|
||||
.child(Story::label("With end hover slot", cx))
|
||||
.child(
|
||||
ListItem::new("with_end_hover_slot")
|
||||
.child("Hello, world!")
|
||||
.end_slot(
|
||||
h_flex()
|
||||
.gap_2()
|
||||
.child(Avatar::new(
|
||||
"https://avatars.githubusercontent.com/u/1789?v=4",
|
||||
))
|
||||
.child(Avatar::new(
|
||||
"https://avatars.githubusercontent.com/u/1789?v=4",
|
||||
))
|
||||
.child(Avatar::new(
|
||||
"https://avatars.githubusercontent.com/u/1789?v=4",
|
||||
))
|
||||
.child(Avatar::new(
|
||||
"https://avatars.githubusercontent.com/u/1789?v=4",
|
||||
))
|
||||
.child(Avatar::new(
|
||||
"https://avatars.githubusercontent.com/u/1789?v=4",
|
||||
)),
|
||||
)
|
||||
.end_hover_slot(Avatar::new(
|
||||
"https://avatars.githubusercontent.com/u/1714999?v=4",
|
||||
)),
|
||||
)
|
||||
.child(Story::label("With `on_click`", cx))
|
||||
.child(ListItem::new("with_on_click").child("Click me").on_click(
|
||||
|_event, _window, _cx| {
|
||||
println!("Clicked!");
|
||||
},
|
||||
))
|
||||
.child(Story::label("With `on_secondary_mouse_down`", cx))
|
||||
.child(
|
||||
ListItem::new("with_on_secondary_mouse_down")
|
||||
.child("Right click me")
|
||||
.on_secondary_mouse_down(|_event, _window, _cx| {
|
||||
println!("Right mouse down!");
|
||||
}),
|
||||
)
|
||||
.child(Story::label(
|
||||
"With overflowing content in the `end_slot`",
|
||||
cx,
|
||||
))
|
||||
.child(
|
||||
ListItem::new("with_overflowing_content_in_end_slot")
|
||||
.child("An excerpt")
|
||||
.end_slot(Label::new(OVERFLOWING_TEXT).color(Color::Muted)),
|
||||
)
|
||||
.child(Story::label(
|
||||
"`inset` with overflowing content in the `end_slot`",
|
||||
cx,
|
||||
))
|
||||
.child(
|
||||
ListItem::new("inset_with_overflowing_content_in_end_slot")
|
||||
.inset(true)
|
||||
.child("An excerpt")
|
||||
.end_slot(Label::new(OVERFLOWING_TEXT).color(Color::Muted)),
|
||||
)
|
||||
.child(Story::label(
|
||||
"`inset` with overflowing content in `children` and `end_slot`",
|
||||
cx,
|
||||
))
|
||||
.child(
|
||||
ListItem::new("inset_with_overflowing_content_in_children_and_end_slot")
|
||||
.inset(true)
|
||||
.child(Label::new(OVERFLOWING_TEXT))
|
||||
.end_slot(Label::new(OVERFLOWING_TEXT).color(Color::Muted)),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
use std::cmp::Ordering;
|
||||
|
||||
use gpui::Render;
|
||||
use story::Story;
|
||||
|
||||
use crate::{IconButtonShape, TabPosition, prelude::*};
|
||||
use crate::{Indicator, Tab};
|
||||
|
||||
pub struct TabStory;
|
||||
|
||||
impl Render for TabStory {
|
||||
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
Story::container(cx)
|
||||
.child(Story::title_for::<Tab>(cx))
|
||||
.child(Story::label("Default", cx))
|
||||
.child(h_flex().child(Tab::new("tab_1").child("Tab 1")))
|
||||
.child(Story::label("With indicator", cx))
|
||||
.child(
|
||||
h_flex().child(
|
||||
Tab::new("tab_1")
|
||||
.start_slot(Indicator::dot().color(Color::Warning))
|
||||
.child("Tab 1"),
|
||||
),
|
||||
)
|
||||
.child(Story::label("With close button", cx))
|
||||
.child(
|
||||
h_flex().child(
|
||||
Tab::new("tab_1")
|
||||
.end_slot(
|
||||
IconButton::new("close_button", IconName::Close)
|
||||
.visible_on_hover("")
|
||||
.shape(IconButtonShape::Square)
|
||||
.icon_color(Color::Muted)
|
||||
.size(ButtonSize::None)
|
||||
.icon_size(IconSize::XSmall),
|
||||
)
|
||||
.child("Tab 1"),
|
||||
),
|
||||
)
|
||||
.child(Story::label("List of tabs", cx))
|
||||
.child(
|
||||
h_flex()
|
||||
.child(Tab::new("tab_1").child("Tab 1"))
|
||||
.child(Tab::new("tab_2").child("Tab 2")),
|
||||
)
|
||||
.child(Story::label("List of tabs with first tab selected", cx))
|
||||
.child(
|
||||
h_flex()
|
||||
.child(
|
||||
Tab::new("tab_1")
|
||||
.toggle_state(true)
|
||||
.position(TabPosition::First)
|
||||
.child("Tab 1"),
|
||||
)
|
||||
.child(
|
||||
Tab::new("tab_2")
|
||||
.position(TabPosition::Middle(Ordering::Greater))
|
||||
.child("Tab 2"),
|
||||
)
|
||||
.child(
|
||||
Tab::new("tab_3")
|
||||
.position(TabPosition::Middle(Ordering::Greater))
|
||||
.child("Tab 3"),
|
||||
)
|
||||
.child(Tab::new("tab_4").position(TabPosition::Last).child("Tab 4")),
|
||||
)
|
||||
.child(Story::label("List of tabs with last tab selected", cx))
|
||||
.child(
|
||||
h_flex()
|
||||
.child(
|
||||
Tab::new("tab_1")
|
||||
.position(TabPosition::First)
|
||||
.child("Tab 1"),
|
||||
)
|
||||
.child(
|
||||
Tab::new("tab_2")
|
||||
.position(TabPosition::Middle(Ordering::Less))
|
||||
.child("Tab 2"),
|
||||
)
|
||||
.child(
|
||||
Tab::new("tab_3")
|
||||
.position(TabPosition::Middle(Ordering::Less))
|
||||
.child("Tab 3"),
|
||||
)
|
||||
.child(
|
||||
Tab::new("tab_4")
|
||||
.position(TabPosition::Last)
|
||||
.toggle_state(true)
|
||||
.child("Tab 4"),
|
||||
),
|
||||
)
|
||||
.child(Story::label("List of tabs with second tab selected", cx))
|
||||
.child(
|
||||
h_flex()
|
||||
.child(
|
||||
Tab::new("tab_1")
|
||||
.position(TabPosition::First)
|
||||
.child("Tab 1"),
|
||||
)
|
||||
.child(
|
||||
Tab::new("tab_2")
|
||||
.position(TabPosition::Middle(Ordering::Equal))
|
||||
.toggle_state(true)
|
||||
.child("Tab 2"),
|
||||
)
|
||||
.child(
|
||||
Tab::new("tab_3")
|
||||
.position(TabPosition::Middle(Ordering::Greater))
|
||||
.child("Tab 3"),
|
||||
)
|
||||
.child(Tab::new("tab_4").position(TabPosition::Last).child("Tab 4")),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
use gpui::Render;
|
||||
use story::Story;
|
||||
|
||||
use crate::{Tab, TabBar, TabPosition, prelude::*};
|
||||
|
||||
pub struct TabBarStory;
|
||||
|
||||
impl Render for TabBarStory {
|
||||
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let tab_count = 20;
|
||||
let selected_tab_index = 3;
|
||||
|
||||
let tabs = (0..tab_count)
|
||||
.map(|index| {
|
||||
Tab::new(index)
|
||||
.toggle_state(index == selected_tab_index)
|
||||
.position(if index == 0 {
|
||||
TabPosition::First
|
||||
} else if index == tab_count - 1 {
|
||||
TabPosition::Last
|
||||
} else {
|
||||
TabPosition::Middle(index.cmp(&selected_tab_index))
|
||||
})
|
||||
.child(Label::new(format!("Tab {}", index + 1)).color(
|
||||
if index == selected_tab_index {
|
||||
Color::Default
|
||||
} else {
|
||||
Color::Muted
|
||||
},
|
||||
))
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
Story::container(cx)
|
||||
.child(Story::title_for::<TabBar>(cx))
|
||||
.child(Story::label("Default", cx))
|
||||
.child(
|
||||
h_flex().child(
|
||||
TabBar::new("tab_bar_1")
|
||||
.start_child(
|
||||
IconButton::new("navigate_backward", IconName::ArrowLeft)
|
||||
.icon_size(IconSize::Small),
|
||||
)
|
||||
.start_child(
|
||||
IconButton::new("navigate_forward", IconName::ArrowRight)
|
||||
.icon_size(IconSize::Small),
|
||||
)
|
||||
.end_child(
|
||||
IconButton::new("new", IconName::Plus).icon_size(IconSize::Small),
|
||||
)
|
||||
.end_child(
|
||||
IconButton::new("split_pane", IconName::Split)
|
||||
.icon_size(IconSize::Small),
|
||||
)
|
||||
.children(tabs),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user