Add facepile, indicator, follow_group
This commit is contained in:
parent
9f2a9d43b1
commit
db1dacde5d
9 changed files with 142 additions and 19 deletions
|
@ -5,7 +5,7 @@ pub enum ButtonVariant {
|
|||
Filled,
|
||||
}
|
||||
|
||||
#[derive(Default, PartialEq)]
|
||||
#[derive(Default, PartialEq, Clone, Copy)]
|
||||
pub enum Shape {
|
||||
#[default]
|
||||
Circle,
|
||||
|
|
|
@ -2,20 +2,17 @@ mod component;
|
|||
mod element;
|
||||
mod module;
|
||||
|
||||
pub use component::tab::tab;
|
||||
pub use component::tab::Tab;
|
||||
pub use component::facepile::*;
|
||||
pub use component::follow_group::*;
|
||||
pub use component::tab::*;
|
||||
|
||||
pub use module::chat_panel::chat_panel;
|
||||
pub use module::status_bar::status_bar;
|
||||
pub use module::status_bar::StatusBar;
|
||||
pub use module::tab_bar::tab_bar;
|
||||
pub use module::title_bar::title_bar;
|
||||
pub use module::chat_panel::*;
|
||||
pub use module::status_bar::*;
|
||||
pub use module::tab_bar::*;
|
||||
pub use module::title_bar::*;
|
||||
|
||||
pub use element::avatar::avatar;
|
||||
pub use element::avatar::Avatar;
|
||||
pub use element::icon_button::icon_button;
|
||||
pub use element::icon_button::IconButton;
|
||||
pub use element::text_button::text_button;
|
||||
pub use element::text_button::TextButton;
|
||||
pub use element::tool_divider::tool_divider;
|
||||
pub use element::tool_divider::ToolDivider;
|
||||
pub use element::avatar::*;
|
||||
pub use element::icon_button::*;
|
||||
pub use element::indicator::*;
|
||||
pub use element::text_button::*;
|
||||
pub use element::tool_divider::*;
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
pub(crate) mod facepile;
|
||||
pub(crate) mod follow_group;
|
||||
pub(crate) mod tab;
|
||||
|
|
31
crates/storybook/src/ui/component/facepile.rs
Normal file
31
crates/storybook/src/ui/component/facepile.rs
Normal file
|
@ -0,0 +1,31 @@
|
|||
use crate::theme::theme;
|
||||
use crate::ui::Avatar;
|
||||
use gpui2::style::StyleHelpers;
|
||||
use gpui2::{elements::div, IntoElement};
|
||||
use gpui2::{Element, ParentElement, ViewContext};
|
||||
|
||||
#[derive(Element)]
|
||||
pub struct Facepile {
|
||||
players: Vec<Avatar>,
|
||||
}
|
||||
|
||||
pub fn facepile(players: Vec<Avatar>) -> Facepile {
|
||||
Facepile { players }
|
||||
}
|
||||
|
||||
impl Facepile {
|
||||
fn render<V: 'static>(&mut self, _: &mut V, cx: &mut ViewContext<V>) -> impl IntoElement<V> {
|
||||
let theme = theme(cx);
|
||||
let player_list = self
|
||||
.players
|
||||
.iter()
|
||||
.map(|player| div().right_1().child(player.clone()));
|
||||
|
||||
div()
|
||||
.relative()
|
||||
.p_1()
|
||||
.flex()
|
||||
.items_center()
|
||||
.children(player_list)
|
||||
}
|
||||
}
|
52
crates/storybook/src/ui/component/follow_group.rs
Normal file
52
crates/storybook/src/ui/component/follow_group.rs
Normal file
|
@ -0,0 +1,52 @@
|
|||
use crate::theme::theme;
|
||||
use crate::ui::{facepile, indicator, Avatar};
|
||||
use gpui2::style::StyleHelpers;
|
||||
use gpui2::{elements::div, IntoElement};
|
||||
use gpui2::{Element, ParentElement, ViewContext};
|
||||
|
||||
#[derive(Element)]
|
||||
pub struct FollowGroup {
|
||||
player: usize,
|
||||
players: Vec<Avatar>,
|
||||
}
|
||||
|
||||
pub fn follow_group(players: Vec<Avatar>) -> FollowGroup {
|
||||
FollowGroup { player: 0, players }
|
||||
}
|
||||
|
||||
impl FollowGroup {
|
||||
pub fn player(mut self, player: usize) -> Self {
|
||||
self.player = player;
|
||||
self
|
||||
}
|
||||
|
||||
fn render<V: 'static>(&mut self, _: &mut V, cx: &mut ViewContext<V>) -> impl IntoElement<V> {
|
||||
let theme = theme(cx);
|
||||
let player_bg = theme.players[self.player].selection;
|
||||
|
||||
div()
|
||||
.h_full()
|
||||
.flex()
|
||||
.flex_col()
|
||||
.gap_px()
|
||||
.justify_center()
|
||||
.child(
|
||||
div()
|
||||
.flex()
|
||||
.justify_center()
|
||||
.w_full()
|
||||
.child(indicator().player(self.player)),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.flex()
|
||||
.items_center()
|
||||
.justify_center()
|
||||
.h_6()
|
||||
.px_1()
|
||||
.rounded_lg()
|
||||
.fill(player_bg)
|
||||
.child(facepile(self.players.clone())),
|
||||
)
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
pub(crate) mod avatar;
|
||||
pub(crate) mod icon_button;
|
||||
pub(crate) mod indicator;
|
||||
pub(crate) mod text_button;
|
||||
pub(crate) mod tool_divider;
|
||||
|
|
|
@ -7,7 +7,7 @@ use gpui2::{Element, ViewContext};
|
|||
|
||||
pub type UnknownString = ArcCow<'static, str>;
|
||||
|
||||
#[derive(Element)]
|
||||
#[derive(Element, Clone)]
|
||||
pub struct Avatar {
|
||||
src: ArcCow<'static, str>,
|
||||
shape: Shape,
|
||||
|
|
32
crates/storybook/src/ui/element/indicator.rs
Normal file
32
crates/storybook/src/ui/element/indicator.rs
Normal file
|
@ -0,0 +1,32 @@
|
|||
use crate::theme::theme;
|
||||
use gpui2::style::StyleHelpers;
|
||||
use gpui2::{elements::div, IntoElement};
|
||||
use gpui2::{Element, ViewContext};
|
||||
|
||||
#[derive(Element)]
|
||||
pub struct Indicator {
|
||||
player: usize,
|
||||
}
|
||||
|
||||
pub fn indicator() -> Indicator {
|
||||
Indicator { player: 0 }
|
||||
}
|
||||
|
||||
impl Indicator {
|
||||
pub fn player(mut self, player: usize) -> Self {
|
||||
self.player = player;
|
||||
self
|
||||
}
|
||||
|
||||
fn render<V: 'static>(&mut self, _: &mut V, cx: &mut ViewContext<V>) -> impl IntoElement<V> {
|
||||
let theme = theme(cx);
|
||||
let player_color = theme.players[self.player].cursor;
|
||||
|
||||
div()
|
||||
.w_4()
|
||||
.h_1()
|
||||
.rounded_bl_sm()
|
||||
.rounded_br_sm()
|
||||
.fill(player_color)
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@ use std::marker::PhantomData;
|
|||
|
||||
use crate::prelude::Shape;
|
||||
use crate::theme::theme;
|
||||
use crate::ui::{avatar, icon_button, text_button, tool_divider};
|
||||
use crate::ui::{avatar, follow_group, icon_button, text_button, tool_divider};
|
||||
use gpui2::style::StyleHelpers;
|
||||
use gpui2::{elements::div, IntoElement};
|
||||
use gpui2::{Element, ParentElement, ViewContext};
|
||||
|
@ -21,6 +21,10 @@ pub fn title_bar<V: 'static>() -> TitleBar<V> {
|
|||
impl<V: 'static> TitleBar<V> {
|
||||
fn render(&mut self, _: &mut V, cx: &mut ViewContext<V>) -> impl IntoElement<V> {
|
||||
let theme = theme(cx);
|
||||
let player_list = vec![
|
||||
avatar("https://avatars.githubusercontent.com/u/1714999?v=4"),
|
||||
avatar("https://avatars.githubusercontent.com/u/1714999?v=4"),
|
||||
];
|
||||
|
||||
div()
|
||||
.flex()
|
||||
|
@ -70,9 +74,13 @@ impl<V: 'static> TitleBar<V> {
|
|||
.flex()
|
||||
.items_center()
|
||||
.gap_1()
|
||||
.child(text_button("maxbrunsfeld"))
|
||||
.child(text_button("zed"))
|
||||
.child(text_button("nate/gpui2-ui-components")),
|
||||
),
|
||||
)
|
||||
.child(follow_group(player_list.clone()).player(0))
|
||||
.child(follow_group(player_list.clone()).player(1))
|
||||
.child(follow_group(player_list.clone()).player(2)),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue