1#![allow(missing_docs)]
2use crate::prelude::*;
3use gpui::{AnyElement, StyleRefinement};
4use smallvec::SmallVec;
5
6/// A facepile is a collection of faces stacked horizontally–
7/// always with the leftmost face on top and descending in z-index
8///
9/// Facepiles are used to display a group of people or things,
10/// such as a list of participants in a collaboration session.
11#[derive(IntoElement)]
12pub struct Facepile {
13 base: Div,
14 faces: SmallVec<[AnyElement; 2]>,
15}
16
17impl Facepile {
18 pub fn empty() -> Self {
19 Self::new(SmallVec::new())
20 }
21
22 pub fn new(faces: SmallVec<[AnyElement; 2]>) -> Self {
23 Self { base: div(), faces }
24 }
25}
26
27impl ParentElement for Facepile {
28 fn extend(&mut self, elements: impl IntoIterator<Item = AnyElement>) {
29 self.faces.extend(elements);
30 }
31}
32
33// Style methods.
34impl Facepile {
35 fn style(&mut self) -> &mut StyleRefinement {
36 self.base.style()
37 }
38
39 gpui::padding_style_methods!({
40 visibility: pub
41 });
42}
43
44impl RenderOnce for Facepile {
45 fn render(self, _cx: &mut WindowContext) -> impl IntoElement {
46 // Lay the faces out in reverse so they overlap in the desired order (left to right, front to back)
47 self.base
48 .flex()
49 .flex_row_reverse()
50 .items_center()
51 .justify_start()
52 .children(
53 self.faces
54 .into_iter()
55 .enumerate()
56 .rev()
57 .map(|(ix, player)| div().when(ix > 0, |div| div.ml_neg_1()).child(player)),
58 )
59 }
60}