parent
b129e18396
commit
29c5ea0a50
4 changed files with 217 additions and 4 deletions
|
@ -1,7 +1,7 @@
|
||||||
#![allow(missing_docs)]
|
#![allow(missing_docs)]
|
||||||
use gpui::{AnyView, DefiniteLength};
|
use gpui::{AnyView, DefiniteLength};
|
||||||
|
|
||||||
use crate::{prelude::*, ElevationIndex, IconPosition, KeyBinding, Spacing};
|
use crate::{prelude::*, ElevationIndex, IconPosition, KeyBinding, Spacing, TintColor};
|
||||||
use crate::{
|
use crate::{
|
||||||
ButtonCommon, ButtonLike, ButtonSize, ButtonStyle, IconName, IconSize, Label, LineHeightStyle,
|
ButtonCommon, ButtonLike, ButtonSize, ButtonStyle, IconName, IconSize, Label, LineHeightStyle,
|
||||||
};
|
};
|
||||||
|
@ -437,3 +437,103 @@ 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() -> Vec<ComponentExampleGroup<Self>> {
|
||||||
|
vec![
|
||||||
|
example_group(
|
||||||
|
"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(
|
||||||
|
"Tinted",
|
||||||
|
vec![
|
||||||
|
single_example(
|
||||||
|
"Accent",
|
||||||
|
Button::new("tinted_accent", "Accent")
|
||||||
|
.style(ButtonStyle::Tinted(TintColor::Accent)),
|
||||||
|
),
|
||||||
|
single_example(
|
||||||
|
"Negative",
|
||||||
|
Button::new("tinted_negative", "Negative")
|
||||||
|
.style(ButtonStyle::Tinted(TintColor::Negative)),
|
||||||
|
),
|
||||||
|
single_example(
|
||||||
|
"Warning",
|
||||||
|
Button::new("tinted_warning", "Warning")
|
||||||
|
.style(ButtonStyle::Tinted(TintColor::Warning)),
|
||||||
|
),
|
||||||
|
single_example(
|
||||||
|
"Positive",
|
||||||
|
Button::new("tinted_positive", "Positive")
|
||||||
|
.style(ButtonStyle::Tinted(TintColor::Positive)),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
example_group(
|
||||||
|
"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").selected(true),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
example_group(
|
||||||
|
"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("icon_color", "Delete")
|
||||||
|
.style(ButtonStyle::Tinted(TintColor::Negative))
|
||||||
|
.color(Color::Error)
|
||||||
|
.icon_color(Color::Error)
|
||||||
|
.icon(IconName::Trash)
|
||||||
|
.icon_position(IconPosition::Start),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
#![allow(missing_docs)]
|
use crate::{prelude::*, Avatar};
|
||||||
use crate::prelude::*;
|
|
||||||
use gpui::{AnyElement, StyleRefinement};
|
use gpui::{AnyElement, StyleRefinement};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
|
||||||
|
@ -15,10 +14,12 @@ pub struct Facepile {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Facepile {
|
impl Facepile {
|
||||||
|
/// Creates a new empty facepile.
|
||||||
pub fn empty() -> Self {
|
pub fn empty() -> Self {
|
||||||
Self::new(SmallVec::new())
|
Self::new(SmallVec::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates a new facepile with the given faces.
|
||||||
pub fn new(faces: SmallVec<[AnyElement; 2]>) -> Self {
|
pub fn new(faces: SmallVec<[AnyElement; 2]>) -> Self {
|
||||||
Self { base: div(), faces }
|
Self { base: div(), faces }
|
||||||
}
|
}
|
||||||
|
@ -58,3 +59,61 @@ impl RenderOnce for Facepile {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ComponentPreview for Facepile {
|
||||||
|
fn description() -> impl Into<Option<&'static str>> {
|
||||||
|
"A facepile is a collection of faces stacked horizontally–\
|
||||||
|
always with the leftmost face on top and descending in z-index.\
|
||||||
|
\n\nFacepiles are used to display a group of people or things,\
|
||||||
|
such as a list of participants in a collaboration session."
|
||||||
|
}
|
||||||
|
fn examples() -> Vec<ComponentExampleGroup<Self>> {
|
||||||
|
let few_faces: [&'static str; 3] = [
|
||||||
|
"https://avatars.githubusercontent.com/u/1714999?s=60&v=4",
|
||||||
|
"https://avatars.githubusercontent.com/u/67129314?s=60&v=4",
|
||||||
|
"https://avatars.githubusercontent.com/u/482957?s=60&v=4",
|
||||||
|
];
|
||||||
|
|
||||||
|
let many_faces: [&'static str; 6] = [
|
||||||
|
"https://avatars.githubusercontent.com/u/326587?s=60&v=4",
|
||||||
|
"https://avatars.githubusercontent.com/u/2280405?s=60&v=4",
|
||||||
|
"https://avatars.githubusercontent.com/u/1789?s=60&v=4",
|
||||||
|
"https://avatars.githubusercontent.com/u/67129314?s=60&v=4",
|
||||||
|
"https://avatars.githubusercontent.com/u/482957?s=60&v=4",
|
||||||
|
"https://avatars.githubusercontent.com/u/1714999?s=60&v=4",
|
||||||
|
];
|
||||||
|
|
||||||
|
vec![example_group(
|
||||||
|
"Examples",
|
||||||
|
vec![
|
||||||
|
single_example(
|
||||||
|
"Few Faces",
|
||||||
|
Facepile::new(
|
||||||
|
few_faces
|
||||||
|
.iter()
|
||||||
|
.map(|&url| Avatar::new(url).into_any_element())
|
||||||
|
.collect(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
single_example(
|
||||||
|
"Many Faces",
|
||||||
|
Facepile::new(
|
||||||
|
many_faces
|
||||||
|
.iter()
|
||||||
|
.map(|&url| Avatar::new(url).into_any_element())
|
||||||
|
.collect(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
single_example(
|
||||||
|
"Custom Size",
|
||||||
|
Facepile::new(
|
||||||
|
few_faces
|
||||||
|
.iter()
|
||||||
|
.map(|&url| Avatar::new(url).size(px(24.)).into_any_element())
|
||||||
|
.collect(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ enum IndicatorKind {
|
||||||
#[derive(IntoElement)]
|
#[derive(IntoElement)]
|
||||||
pub struct Indicator {
|
pub struct Indicator {
|
||||||
kind: IndicatorKind,
|
kind: IndicatorKind,
|
||||||
|
border_color: Option<Color>,
|
||||||
pub color: Color,
|
pub color: Color,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +20,7 @@ impl Indicator {
|
||||||
pub fn dot() -> Self {
|
pub fn dot() -> Self {
|
||||||
Self {
|
Self {
|
||||||
kind: IndicatorKind::Dot,
|
kind: IndicatorKind::Dot,
|
||||||
|
border_color: None,
|
||||||
color: Color::Default,
|
color: Color::Default,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +28,8 @@ impl Indicator {
|
||||||
pub fn bar() -> Self {
|
pub fn bar() -> Self {
|
||||||
Self {
|
Self {
|
||||||
kind: IndicatorKind::Bar,
|
kind: IndicatorKind::Bar,
|
||||||
|
border_color: None,
|
||||||
|
|
||||||
color: Color::Default,
|
color: Color::Default,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,6 +37,8 @@ impl Indicator {
|
||||||
pub fn icon(icon: impl Into<AnyIcon>) -> Self {
|
pub fn icon(icon: impl Into<AnyIcon>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
kind: IndicatorKind::Icon(icon.into()),
|
kind: IndicatorKind::Icon(icon.into()),
|
||||||
|
border_color: None,
|
||||||
|
|
||||||
color: Color::Default,
|
color: Color::Default,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,11 +47,25 @@ impl Indicator {
|
||||||
self.color = color;
|
self.color = color;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn border_color(mut self, color: Color) -> Self {
|
||||||
|
self.border_color = Some(color);
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RenderOnce for Indicator {
|
impl RenderOnce for Indicator {
|
||||||
fn render(self, cx: &mut WindowContext) -> impl IntoElement {
|
fn render(self, cx: &mut WindowContext) -> impl IntoElement {
|
||||||
let container = div().flex_none();
|
let container = div().flex_none();
|
||||||
|
let container = if let Some(border_color) = self.border_color {
|
||||||
|
if matches!(self.kind, IndicatorKind::Dot | IndicatorKind::Bar) {
|
||||||
|
container.border_1().border_color(border_color.color(cx))
|
||||||
|
} else {
|
||||||
|
container
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
container
|
||||||
|
};
|
||||||
|
|
||||||
match self.kind {
|
match self.kind {
|
||||||
IndicatorKind::Icon(icon) => container
|
IndicatorKind::Icon(icon) => container
|
||||||
|
@ -63,3 +83,34 @@ impl RenderOnce for Indicator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ComponentPreview for Indicator {
|
||||||
|
fn description() -> impl Into<Option<&'static str>> {
|
||||||
|
"An indicator visually represents a status or state."
|
||||||
|
}
|
||||||
|
|
||||||
|
fn examples() -> Vec<ComponentExampleGroup<Self>> {
|
||||||
|
vec![
|
||||||
|
example_group(
|
||||||
|
"Types",
|
||||||
|
vec![
|
||||||
|
single_example("Dot", Indicator::dot().color(Color::Info)),
|
||||||
|
single_example("Bar", Indicator::bar().color(Color::Player(2))),
|
||||||
|
single_example(
|
||||||
|
"Icon",
|
||||||
|
Indicator::icon(Icon::new(IconName::Check).color(Color::Success)),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
example_group(
|
||||||
|
"Examples",
|
||||||
|
vec![
|
||||||
|
single_example("Info", Indicator::dot().color(Color::Info)),
|
||||||
|
single_example("Success", Indicator::dot().color(Color::Success)),
|
||||||
|
single_example("Warning", Indicator::dot().color(Color::Warning)),
|
||||||
|
single_example("Error", Indicator::dot().color(Color::Error)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use theme::all_theme_colors;
|
||||||
use ui::{
|
use ui::{
|
||||||
prelude::*, utils::calculate_contrast_ratio, AudioStatus, Availability, Avatar,
|
prelude::*, utils::calculate_contrast_ratio, AudioStatus, Availability, Avatar,
|
||||||
AvatarAudioStatusIndicator, AvatarAvailabilityIndicator, ButtonLike, Checkbox, ElevationIndex,
|
AvatarAudioStatusIndicator, AvatarAvailabilityIndicator, ButtonLike, Checkbox, ElevationIndex,
|
||||||
Facepile, TintColor, Tooltip,
|
Facepile, Indicator, TintColor, Tooltip,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{Item, Workspace};
|
use crate::{Item, Workspace};
|
||||||
|
@ -510,6 +510,9 @@ impl ThemePreview {
|
||||||
.size_full()
|
.size_full()
|
||||||
.gap_2()
|
.gap_2()
|
||||||
.child(Checkbox::render_component_previews(cx))
|
.child(Checkbox::render_component_previews(cx))
|
||||||
|
.child(Facepile::render_component_previews(cx))
|
||||||
|
.child(Button::render_component_previews(cx))
|
||||||
|
.child(Indicator::render_component_previews(cx))
|
||||||
.child(Icon::render_component_previews(cx))
|
.child(Icon::render_component_previews(cx))
|
||||||
.child(self.render_avatars(cx))
|
.child(self.render_avatars(cx))
|
||||||
.child(self.render_buttons(layer, cx))
|
.child(self.render_buttons(layer, cx))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue