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:
parent
56cfc60875
commit
8f1ff189cc
36 changed files with 1582 additions and 976 deletions
|
@ -1,5 +1,7 @@
|
|||
#![allow(missing_docs)]
|
||||
use gpui::{AnyView, DefiniteLength};
|
||||
use component::{example_group_with_title, single_example, ComponentPreview};
|
||||
use gpui::{AnyElement, AnyView, DefiniteLength};
|
||||
use ui_macros::IntoComponent;
|
||||
|
||||
use crate::{
|
||||
prelude::*, Color, DynamicSpacing, ElevationIndex, IconPosition, KeyBinding,
|
||||
|
@ -78,7 +80,7 @@ use super::button_icon::ButtonIcon;
|
|||
/// });
|
||||
/// ```
|
||||
///
|
||||
#[derive(IntoElement)]
|
||||
#[derive(IntoElement, IntoComponent)]
|
||||
pub struct Button {
|
||||
base: ButtonLike,
|
||||
label: SharedString,
|
||||
|
@ -455,101 +457,124 @@ impl RenderOnce for Button {
|
|||
}
|
||||
|
||||
impl ComponentPreview for Button {
|
||||
fn description() -> impl Into<Option<&'static str>> {
|
||||
"A button allows users to take actions, and make choices, with a single tap."
|
||||
}
|
||||
|
||||
fn examples(_window: &mut Window, _: &mut App) -> Vec<ComponentExampleGroup<Self>> {
|
||||
vec![
|
||||
example_group_with_title(
|
||||
"Styles",
|
||||
vec![
|
||||
single_example("Default", Button::new("default", "Default")),
|
||||
single_example(
|
||||
"Filled",
|
||||
Button::new("filled", "Filled").style(ButtonStyle::Filled),
|
||||
),
|
||||
single_example(
|
||||
"Subtle",
|
||||
Button::new("outline", "Subtle").style(ButtonStyle::Subtle),
|
||||
),
|
||||
single_example(
|
||||
"Transparent",
|
||||
Button::new("transparent", "Transparent").style(ButtonStyle::Transparent),
|
||||
),
|
||||
],
|
||||
),
|
||||
example_group_with_title(
|
||||
"Tinted",
|
||||
vec![
|
||||
single_example(
|
||||
"Accent",
|
||||
Button::new("tinted_accent", "Accent")
|
||||
.style(ButtonStyle::Tinted(TintColor::Accent)),
|
||||
),
|
||||
single_example(
|
||||
"Error",
|
||||
Button::new("tinted_negative", "Error")
|
||||
.style(ButtonStyle::Tinted(TintColor::Error)),
|
||||
),
|
||||
single_example(
|
||||
"Warning",
|
||||
Button::new("tinted_warning", "Warning")
|
||||
.style(ButtonStyle::Tinted(TintColor::Warning)),
|
||||
),
|
||||
single_example(
|
||||
"Success",
|
||||
Button::new("tinted_positive", "Success")
|
||||
.style(ButtonStyle::Tinted(TintColor::Success)),
|
||||
),
|
||||
],
|
||||
),
|
||||
example_group_with_title(
|
||||
"States",
|
||||
vec![
|
||||
single_example("Default", Button::new("default_state", "Default")),
|
||||
single_example(
|
||||
"Disabled",
|
||||
Button::new("disabled", "Disabled").disabled(true),
|
||||
),
|
||||
single_example(
|
||||
"Selected",
|
||||
Button::new("selected", "Selected").toggle_state(true),
|
||||
),
|
||||
],
|
||||
),
|
||||
example_group_with_title(
|
||||
"With Icons",
|
||||
vec![
|
||||
single_example(
|
||||
"Icon Start",
|
||||
Button::new("icon_start", "Icon Start")
|
||||
.icon(IconName::Check)
|
||||
.icon_position(IconPosition::Start),
|
||||
),
|
||||
single_example(
|
||||
"Icon End",
|
||||
Button::new("icon_end", "Icon End")
|
||||
.icon(IconName::Check)
|
||||
.icon_position(IconPosition::End),
|
||||
),
|
||||
single_example(
|
||||
"Icon Color",
|
||||
Button::new("icon_color", "Icon Color")
|
||||
.icon(IconName::Check)
|
||||
.icon_color(Color::Accent),
|
||||
),
|
||||
single_example(
|
||||
"Tinted Icons",
|
||||
Button::new("tinted_icons", "Error")
|
||||
.style(ButtonStyle::Tinted(TintColor::Error))
|
||||
.color(Color::Error)
|
||||
.icon_color(Color::Error)
|
||||
.icon(IconName::Trash)
|
||||
.icon_position(IconPosition::Start),
|
||||
),
|
||||
],
|
||||
),
|
||||
]
|
||||
fn preview(_window: &mut Window, _cx: &App) -> AnyElement {
|
||||
v_flex()
|
||||
.gap_6()
|
||||
.children(vec![
|
||||
example_group_with_title(
|
||||
"Styles",
|
||||
vec![
|
||||
single_example(
|
||||
"Default",
|
||||
Button::new("default", "Default").into_any_element(),
|
||||
),
|
||||
single_example(
|
||||
"Filled",
|
||||
Button::new("filled", "Filled")
|
||||
.style(ButtonStyle::Filled)
|
||||
.into_any_element(),
|
||||
),
|
||||
single_example(
|
||||
"Subtle",
|
||||
Button::new("outline", "Subtle")
|
||||
.style(ButtonStyle::Subtle)
|
||||
.into_any_element(),
|
||||
),
|
||||
single_example(
|
||||
"Transparent",
|
||||
Button::new("transparent", "Transparent")
|
||||
.style(ButtonStyle::Transparent)
|
||||
.into_any_element(),
|
||||
),
|
||||
],
|
||||
),
|
||||
example_group_with_title(
|
||||
"Tinted",
|
||||
vec![
|
||||
single_example(
|
||||
"Accent",
|
||||
Button::new("tinted_accent", "Accent")
|
||||
.style(ButtonStyle::Tinted(TintColor::Accent))
|
||||
.into_any_element(),
|
||||
),
|
||||
single_example(
|
||||
"Error",
|
||||
Button::new("tinted_negative", "Error")
|
||||
.style(ButtonStyle::Tinted(TintColor::Error))
|
||||
.into_any_element(),
|
||||
),
|
||||
single_example(
|
||||
"Warning",
|
||||
Button::new("tinted_warning", "Warning")
|
||||
.style(ButtonStyle::Tinted(TintColor::Warning))
|
||||
.into_any_element(),
|
||||
),
|
||||
single_example(
|
||||
"Success",
|
||||
Button::new("tinted_positive", "Success")
|
||||
.style(ButtonStyle::Tinted(TintColor::Success))
|
||||
.into_any_element(),
|
||||
),
|
||||
],
|
||||
),
|
||||
example_group_with_title(
|
||||
"States",
|
||||
vec![
|
||||
single_example(
|
||||
"Default",
|
||||
Button::new("default_state", "Default").into_any_element(),
|
||||
),
|
||||
single_example(
|
||||
"Disabled",
|
||||
Button::new("disabled", "Disabled")
|
||||
.disabled(true)
|
||||
.into_any_element(),
|
||||
),
|
||||
single_example(
|
||||
"Selected",
|
||||
Button::new("selected", "Selected")
|
||||
.toggle_state(true)
|
||||
.into_any_element(),
|
||||
),
|
||||
],
|
||||
),
|
||||
example_group_with_title(
|
||||
"With Icons",
|
||||
vec![
|
||||
single_example(
|
||||
"Icon Start",
|
||||
Button::new("icon_start", "Icon Start")
|
||||
.icon(IconName::Check)
|
||||
.icon_position(IconPosition::Start)
|
||||
.into_any_element(),
|
||||
),
|
||||
single_example(
|
||||
"Icon End",
|
||||
Button::new("icon_end", "Icon End")
|
||||
.icon(IconName::Check)
|
||||
.icon_position(IconPosition::End)
|
||||
.into_any_element(),
|
||||
),
|
||||
single_example(
|
||||
"Icon Color",
|
||||
Button::new("icon_color", "Icon Color")
|
||||
.icon(IconName::Check)
|
||||
.icon_color(Color::Accent)
|
||||
.into_any_element(),
|
||||
),
|
||||
single_example(
|
||||
"Tinted Icons",
|
||||
Button::new("tinted_icons", "Error")
|
||||
.style(ButtonStyle::Tinted(TintColor::Error))
|
||||
.color(Color::Error)
|
||||
.icon_color(Color::Error)
|
||||
.icon(IconName::Trash)
|
||||
.icon_position(IconPosition::Start)
|
||||
.into_any_element(),
|
||||
),
|
||||
],
|
||||
),
|
||||
])
|
||||
.into_any_element()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue