Merge Component and ComponentPreview trait (#28365)

- Merge `Component` and `ComponentPreview` trait
- Adds a number of component previews
- Removes a number of stories

Release Notes:

- N/A
This commit is contained in:
Nate Butler
2025-04-08 16:09:06 -06:00
committed by GitHub
parent b15ee1b1cc
commit c05bf096f8
52 changed files with 3276 additions and 1848 deletions
+182 -173
View File
@@ -94,183 +94,192 @@ pub trait DefaultAnimations: Styled + Sized {
impl<E: Styled> DefaultAnimations for E {}
// Don't use this directly, it only exists to show animation previews
#[derive(IntoComponent)]
#[derive(RegisterComponent)]
struct Animation {}
// View this component preview using `workspace: open component-preview`
impl ComponentPreview for Animation {
fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement {
impl Component for Animation {
fn scope() -> ComponentScope {
ComponentScope::None
}
fn description() -> Option<&'static str> {
Some("Demonstrates various animation patterns and transitions available in the UI system.")
}
fn preview(_window: &mut Window, _cx: &mut App) -> Option<AnyElement> {
let container_size = 128.0;
let element_size = 32.0;
let left_offset = element_size - container_size / 2.0;
v_flex()
.gap_6()
.children(vec![
example_group_with_title(
"Animate In",
vec![
single_example(
"From Bottom",
ContentGroup::new()
.relative()
.items_center()
.justify_center()
.size(px(container_size))
.child(
div()
.id("animate-in-from-bottom")
.absolute()
.size(px(element_size))
.left(px(left_offset))
.rounded_md()
.bg(gpui::red())
.animate_in(AnimationDirection::FromBottom, false),
)
.into_any_element(),
),
single_example(
"From Top",
ContentGroup::new()
.relative()
.items_center()
.justify_center()
.size(px(container_size))
.child(
div()
.id("animate-in-from-top")
.absolute()
.size(px(element_size))
.left(px(left_offset))
.rounded_md()
.bg(gpui::blue())
.animate_in(AnimationDirection::FromTop, false),
)
.into_any_element(),
),
single_example(
"From Left",
ContentGroup::new()
.relative()
.items_center()
.justify_center()
.size(px(container_size))
.child(
div()
.id("animate-in-from-left")
.absolute()
.size(px(element_size))
.left(px(left_offset))
.rounded_md()
.bg(gpui::green())
.animate_in(AnimationDirection::FromLeft, false),
)
.into_any_element(),
),
single_example(
"From Right",
ContentGroup::new()
.relative()
.items_center()
.justify_center()
.size(px(container_size))
.child(
div()
.id("animate-in-from-right")
.absolute()
.size(px(element_size))
.left(px(left_offset))
.rounded_md()
.bg(gpui::yellow())
.animate_in(AnimationDirection::FromRight, false),
)
.into_any_element(),
),
],
)
.grow(),
example_group_with_title(
"Fade and Animate In",
vec![
single_example(
"From Bottom",
ContentGroup::new()
.relative()
.items_center()
.justify_center()
.size(px(container_size))
.child(
div()
.id("fade-animate-in-from-bottom")
.absolute()
.size(px(element_size))
.left(px(left_offset))
.rounded_md()
.bg(gpui::red())
.animate_in(AnimationDirection::FromBottom, true),
)
.into_any_element(),
),
single_example(
"From Top",
ContentGroup::new()
.relative()
.items_center()
.justify_center()
.size(px(container_size))
.child(
div()
.id("fade-animate-in-from-top")
.absolute()
.size(px(element_size))
.left(px(left_offset))
.rounded_md()
.bg(gpui::blue())
.animate_in(AnimationDirection::FromTop, true),
)
.into_any_element(),
),
single_example(
"From Left",
ContentGroup::new()
.relative()
.items_center()
.justify_center()
.size(px(container_size))
.child(
div()
.id("fade-animate-in-from-left")
.absolute()
.size(px(element_size))
.left(px(left_offset))
.rounded_md()
.bg(gpui::green())
.animate_in(AnimationDirection::FromLeft, true),
)
.into_any_element(),
),
single_example(
"From Right",
ContentGroup::new()
.relative()
.items_center()
.justify_center()
.size(px(container_size))
.child(
div()
.id("fade-animate-in-from-right")
.absolute()
.size(px(element_size))
.left(px(left_offset))
.rounded_md()
.bg(gpui::yellow())
.animate_in(AnimationDirection::FromRight, true),
)
.into_any_element(),
),
],
)
.grow(),
])
.into_any_element()
Some(
v_flex()
.gap_6()
.children(vec![
example_group_with_title(
"Animate In",
vec![
single_example(
"From Bottom",
ContentGroup::new()
.relative()
.items_center()
.justify_center()
.size(px(container_size))
.child(
div()
.id("animate-in-from-bottom")
.absolute()
.size(px(element_size))
.left(px(left_offset))
.rounded_md()
.bg(gpui::red())
.animate_in(AnimationDirection::FromBottom, false),
)
.into_any_element(),
),
single_example(
"From Top",
ContentGroup::new()
.relative()
.items_center()
.justify_center()
.size(px(container_size))
.child(
div()
.id("animate-in-from-top")
.absolute()
.size(px(element_size))
.left(px(left_offset))
.rounded_md()
.bg(gpui::blue())
.animate_in(AnimationDirection::FromTop, false),
)
.into_any_element(),
),
single_example(
"From Left",
ContentGroup::new()
.relative()
.items_center()
.justify_center()
.size(px(container_size))
.child(
div()
.id("animate-in-from-left")
.absolute()
.size(px(element_size))
.left(px(left_offset))
.rounded_md()
.bg(gpui::green())
.animate_in(AnimationDirection::FromLeft, false),
)
.into_any_element(),
),
single_example(
"From Right",
ContentGroup::new()
.relative()
.items_center()
.justify_center()
.size(px(container_size))
.child(
div()
.id("animate-in-from-right")
.absolute()
.size(px(element_size))
.left(px(left_offset))
.rounded_md()
.bg(gpui::yellow())
.animate_in(AnimationDirection::FromRight, false),
)
.into_any_element(),
),
],
)
.grow(),
example_group_with_title(
"Fade and Animate In",
vec![
single_example(
"From Bottom",
ContentGroup::new()
.relative()
.items_center()
.justify_center()
.size(px(container_size))
.child(
div()
.id("fade-animate-in-from-bottom")
.absolute()
.size(px(element_size))
.left(px(left_offset))
.rounded_md()
.bg(gpui::red())
.animate_in(AnimationDirection::FromBottom, true),
)
.into_any_element(),
),
single_example(
"From Top",
ContentGroup::new()
.relative()
.items_center()
.justify_center()
.size(px(container_size))
.child(
div()
.id("fade-animate-in-from-top")
.absolute()
.size(px(element_size))
.left(px(left_offset))
.rounded_md()
.bg(gpui::blue())
.animate_in(AnimationDirection::FromTop, true),
)
.into_any_element(),
),
single_example(
"From Left",
ContentGroup::new()
.relative()
.items_center()
.justify_center()
.size(px(container_size))
.child(
div()
.id("fade-animate-in-from-left")
.absolute()
.size(px(element_size))
.left(px(left_offset))
.rounded_md()
.bg(gpui::green())
.animate_in(AnimationDirection::FromLeft, true),
)
.into_any_element(),
),
single_example(
"From Right",
ContentGroup::new()
.relative()
.items_center()
.justify_center()
.size(px(container_size))
.child(
div()
.id("fade-animate-in-from-right")
.absolute()
.size(px(element_size))
.left(px(left_offset))
.rounded_md()
.bg(gpui::yellow())
.animate_in(AnimationDirection::FromRight, true),
)
.into_any_element(),
),
],
)
.grow(),
])
.into_any_element(),
)
}
}
+134 -2
View File
@@ -1,8 +1,21 @@
use gpui::{App, Hsla};
use crate::{Label, LabelCommon, component_prelude::*, v_flex};
use documented::{DocumentedFields, DocumentedVariants};
use gpui::{App, Hsla, IntoElement, ParentElement, Styled};
use theme::ActiveTheme;
/// Sets a color that has a consistent meaning across all themes.
#[derive(Debug, Default, Eq, PartialEq, Copy, Clone)]
#[derive(
Debug,
Default,
Eq,
PartialEq,
Copy,
Clone,
RegisterComponent,
Documented,
DocumentedFields,
DocumentedVariants,
)]
pub enum Color {
#[default]
/// The default text color. Might be known as "foreground" or "primary" in
@@ -110,3 +123,122 @@ impl From<Hsla> for Color {
Color::Custom(color)
}
}
impl Component for Color {
fn scope() -> ComponentScope {
ComponentScope::None
}
fn description() -> Option<&'static str> {
Some(Color::DOCS)
}
fn preview(_window: &mut gpui::Window, _cx: &mut App) -> Option<gpui::AnyElement> {
Some(
v_flex()
.gap_6()
.children(vec![
example_group_with_title(
"Text Colors",
vec![
single_example(
"Default",
Label::new("Default text color")
.color(Color::Default)
.into_any_element(),
)
.description(Color::Default.get_variant_docs()),
single_example(
"Muted",
Label::new("Muted text color")
.color(Color::Muted)
.into_any_element(),
)
.description(Color::Muted.get_variant_docs()),
single_example(
"Accent",
Label::new("Accent text color")
.color(Color::Accent)
.into_any_element(),
)
.description(Color::Accent.get_variant_docs()),
single_example(
"Disabled",
Label::new("Disabled text color")
.color(Color::Disabled)
.into_any_element(),
)
.description(Color::Disabled.get_variant_docs()),
],
),
example_group_with_title(
"Status Colors",
vec![
single_example(
"Success",
Label::new("Success status")
.color(Color::Success)
.into_any_element(),
)
.description(Color::Success.get_variant_docs()),
single_example(
"Warning",
Label::new("Warning status")
.color(Color::Warning)
.into_any_element(),
)
.description(Color::Warning.get_variant_docs()),
single_example(
"Error",
Label::new("Error status")
.color(Color::Error)
.into_any_element(),
)
.description(Color::Error.get_variant_docs()),
single_example(
"Info",
Label::new("Info status")
.color(Color::Info)
.into_any_element(),
)
.description(Color::Info.get_variant_docs()),
],
),
example_group_with_title(
"Version Control Colors",
vec![
single_example(
"Created",
Label::new("Created item")
.color(Color::Created)
.into_any_element(),
)
.description(Color::Created.get_variant_docs()),
single_example(
"Modified",
Label::new("Modified item")
.color(Color::Modified)
.into_any_element(),
)
.description(Color::Modified.get_variant_docs()),
single_example(
"Deleted",
Label::new("Deleted item")
.color(Color::Deleted)
.into_any_element(),
)
.description(Color::Deleted.get_variant_docs()),
single_example(
"Conflict",
Label::new("Conflict item")
.color(Color::Conflict)
.into_any_element(),
)
.description(Color::Conflict.get_variant_docs()),
],
),
])
.into_any_element(),
)
}
}
+46 -37
View File
@@ -190,7 +190,7 @@ impl HeadlineSize {
/// A headline element, used to emphasize some text and
/// create a visual hierarchy.
#[derive(IntoElement, IntoComponent)]
#[derive(IntoElement, RegisterComponent)]
pub struct Headline {
size: HeadlineSize,
text: SharedString,
@@ -233,41 +233,50 @@ impl Headline {
}
}
// View this component preview using `workspace: open component-preview`
impl ComponentPreview for Headline {
fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement {
v_flex()
.gap_1()
.children(vec![
single_example(
"XLarge",
Headline::new("XLarge Headline")
.size(HeadlineSize::XLarge)
.into_any_element(),
),
single_example(
"Large",
Headline::new("Large Headline")
.size(HeadlineSize::Large)
.into_any_element(),
),
single_example(
"Medium (Default)",
Headline::new("Medium Headline").into_any_element(),
),
single_example(
"Small",
Headline::new("Small Headline")
.size(HeadlineSize::Small)
.into_any_element(),
),
single_example(
"XSmall",
Headline::new("XSmall Headline")
.size(HeadlineSize::XSmall)
.into_any_element(),
),
])
.into_any_element()
impl Component for Headline {
fn scope() -> ComponentScope {
ComponentScope::None
}
fn description() -> Option<&'static str> {
Some("A headline element used to emphasize text and create visual hierarchy in the UI.")
}
fn preview(_window: &mut Window, _cx: &mut App) -> Option<AnyElement> {
Some(
v_flex()
.gap_1()
.children(vec![
single_example(
"XLarge",
Headline::new("XLarge Headline")
.size(HeadlineSize::XLarge)
.into_any_element(),
),
single_example(
"Large",
Headline::new("Large Headline")
.size(HeadlineSize::Large)
.into_any_element(),
),
single_example(
"Medium (Default)",
Headline::new("Medium Headline").into_any_element(),
),
single_example(
"Small",
Headline::new("Small Headline")
.size(HeadlineSize::Small)
.into_any_element(),
),
single_example(
"XSmall",
Headline::new("XSmall Headline")
.size(HeadlineSize::XSmall)
.into_any_element(),
),
])
.into_any_element(),
)
}
}