Add Element::when method

Nathan Sobo created

Change summary

crates/gpui2/src/element.rs                   | 21 +++++++++++++++++++++
crates/storybook/src/ui/component/facepile.rs | 12 +++++-------
2 files changed, 26 insertions(+), 7 deletions(-)

Detailed changes

crates/gpui2/src/element.rs 🔗

@@ -34,6 +34,27 @@ pub trait Element<V: 'static>: 'static + IntoElement<V> {
             phase: ElementPhase::Init,
         }))
     }
+
+    /// Applies a given function `then` to the current element if `condition` is true.
+    /// This function is used to conditionally modify the element based on a given condition.
+    /// If `condition` is false, it just returns the current element as it is.
+    ///
+    /// # Parameters
+    /// - `self`: The current element
+    /// - `condition`: The boolean condition based on which `then` is applied to the element.
+    /// - `then`: A function that takes in the current element and returns a possibly modified element.
+    ///
+    /// # Return
+    /// It returns the potentially modified element.
+    fn when(mut self, condition: bool, then: impl FnOnce(Self) -> Self) -> Self
+    where
+        Self: Sized,
+    {
+        if condition {
+            self = then(self);
+        }
+        self
+    }
 }
 
 /// Used to make ElementState<V, E> into a trait object, so we can wrap it in AnyElement<V>.

crates/storybook/src/ui/component/facepile.rs 🔗

@@ -18,13 +18,11 @@ impl Facepile {
     fn render<V: 'static>(&mut self, _: &mut V, cx: &mut ViewContext<V>) -> impl IntoElement<V> {
         let theme = theme(cx);
         let player_count = self.players.len();
-        let player_list = self.players.iter().enumerate().map(|(i, player)| {
-            let element = div().child(player.clone());
-            if i < player_count - 1 {
-                element.mr(-rems(0.5))
-            } else {
-                element
-            }
+        let player_list = self.players.iter().enumerate().map(|(ix, player)| {
+            let before_last = ix < player_count - 1;
+            div()
+                .when(before_last, |div| div.mr(-rems(0.5)))
+                .child(player.clone())
         });
         div().p_1().flex().items_center().children(player_list)
     }