component: Add component and component_preview crates to power UI components (#24456)
This PR formalizes design components with the Component and ComponentPreview traits. You can open the preview UI with `workspace: open component preview`. Component previews no longer need to return `Self` allowing for more complex previews, and previews of components like `ui::Tooltip` that supplement other components rather than are rendered by default. `cargo-machete` incorrectly identifies `linkme` as an unused dep on crates that have components deriving `IntoComponent`, so you may need to add this to that crate's `Cargo.toml`: ```toml # cargo-machete doesn't understand that linkme is used in the component macro [package.metadata.cargo-machete] ignored = ["linkme"] ``` Release Notes: - N/A --------- Co-authored-by: Marshall Bowers <git@maxdeviant.com>
This commit is contained in:
co-authored by
Marshall Bowers
parent
56cfc60875
commit
8f1ff189cc
@@ -1,10 +1,8 @@
|
||||
use gpui::{IntoElement, Point};
|
||||
use gpui::{AnyElement, IntoElement, Point};
|
||||
|
||||
use crate::{
|
||||
prelude::*, traits::component_preview::ComponentPreview, IconDecoration, IconDecorationKind,
|
||||
};
|
||||
use crate::{prelude::*, IconDecoration, IconDecorationKind};
|
||||
|
||||
#[derive(IntoElement)]
|
||||
#[derive(IntoElement, IntoComponent)]
|
||||
pub struct DecoratedIcon {
|
||||
icon: Icon,
|
||||
decoration: Option<IconDecoration>,
|
||||
@@ -27,12 +25,7 @@ impl RenderOnce for DecoratedIcon {
|
||||
}
|
||||
|
||||
impl ComponentPreview for DecoratedIcon {
|
||||
fn examples(_: &mut Window, cx: &mut App) -> Vec<ComponentExampleGroup<Self>> {
|
||||
let icon_1 = Icon::new(IconName::FileDoc);
|
||||
let icon_2 = Icon::new(IconName::FileDoc);
|
||||
let icon_3 = Icon::new(IconName::FileDoc);
|
||||
let icon_4 = Icon::new(IconName::FileDoc);
|
||||
|
||||
fn preview(_window: &mut Window, cx: &App) -> AnyElement {
|
||||
let decoration_x = IconDecoration::new(
|
||||
IconDecorationKind::X,
|
||||
cx.theme().colors().surface_background,
|
||||
@@ -66,22 +59,32 @@ impl ComponentPreview for DecoratedIcon {
|
||||
y: px(-2.),
|
||||
});
|
||||
|
||||
let examples = vec![
|
||||
single_example("no_decoration", DecoratedIcon::new(icon_1, None)),
|
||||
single_example(
|
||||
"with_decoration",
|
||||
DecoratedIcon::new(icon_2, Some(decoration_x)),
|
||||
),
|
||||
single_example(
|
||||
"with_decoration",
|
||||
DecoratedIcon::new(icon_3, Some(decoration_triangle)),
|
||||
),
|
||||
single_example(
|
||||
"with_decoration",
|
||||
DecoratedIcon::new(icon_4, Some(decoration_dot)),
|
||||
),
|
||||
];
|
||||
|
||||
vec![example_group(examples)]
|
||||
v_flex()
|
||||
.gap_6()
|
||||
.children(vec![example_group_with_title(
|
||||
"Decorations",
|
||||
vec![
|
||||
single_example(
|
||||
"No Decoration",
|
||||
DecoratedIcon::new(Icon::new(IconName::FileDoc), None).into_any_element(),
|
||||
),
|
||||
single_example(
|
||||
"X Decoration",
|
||||
DecoratedIcon::new(Icon::new(IconName::FileDoc), Some(decoration_x))
|
||||
.into_any_element(),
|
||||
),
|
||||
single_example(
|
||||
"Triangle Decoration",
|
||||
DecoratedIcon::new(Icon::new(IconName::FileDoc), Some(decoration_triangle))
|
||||
.into_any_element(),
|
||||
),
|
||||
single_example(
|
||||
"Dot Decoration",
|
||||
DecoratedIcon::new(Icon::new(IconName::FileDoc), Some(decoration_dot))
|
||||
.into_any_element(),
|
||||
),
|
||||
],
|
||||
)])
|
||||
.into_any_element()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use gpui::{svg, Hsla, IntoElement, Point};
|
||||
use strum::{EnumIter, EnumString, IntoEnumIterator, IntoStaticStr};
|
||||
use strum::{EnumIter, EnumString, IntoStaticStr};
|
||||
use ui_macros::DerivePathStr;
|
||||
|
||||
use crate::{prelude::*, traits::component_preview::ComponentPreview};
|
||||
use crate::prelude::*;
|
||||
|
||||
const ICON_DECORATION_SIZE: Pixels = px(11.);
|
||||
|
||||
@@ -149,21 +149,3 @@ impl RenderOnce for IconDecoration {
|
||||
.child(background)
|
||||
}
|
||||
}
|
||||
|
||||
impl ComponentPreview for IconDecoration {
|
||||
fn examples(_: &mut Window, cx: &mut App) -> Vec<ComponentExampleGroup<Self>> {
|
||||
let all_kinds = IconDecorationKind::iter().collect::<Vec<_>>();
|
||||
|
||||
let examples = all_kinds
|
||||
.iter()
|
||||
.map(|kind| {
|
||||
single_example(
|
||||
format!("{kind:?}"),
|
||||
IconDecoration::new(*kind, cx.theme().colors().surface_background, cx),
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
|
||||
vec![example_group(examples)]
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user