Add map method to Components (#3210)

This PR adds a `map` method to the `Component` trait.

`map` is a fully-generalized form of `when`, as `when` can be expressed
in terms of `map`:

```rs
div().map(|this| if condition { then(this) } else { this })
```

This allows us to take advantage of Rust's pattern matching when
building up conditions:

```rs
// Before
div()
    .when(self.current_side == PanelSide::Left, |this| this.border_r())
    .when(self.current_side == PanelSide::Right, |this| {
        this.border_l()
    })
    .when(self.current_side == PanelSide::Bottom, |this| {
        this.border_b().w_full().h(current_size)
    })

// After
div()
    .map(|this| match self.current_side {
        PanelSide::Left => this.border_r(),
        PanelSide::Right => this.border_l(),
        PanelSide::Bottom => this.border_b().w_full().h(current_size),
    })
```

Release Notes:

- N/A
This commit is contained in:
Marshall Bowers 2023-11-02 16:39:40 +01:00 committed by GitHub
parent 5e12b48ae0
commit ec0cff0e1a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 24 additions and 22 deletions

View file

@ -198,14 +198,19 @@ impl<V> AnyElement<V> {
pub trait Component<V> { pub trait Component<V> {
fn render(self) -> AnyElement<V>; fn render(self) -> AnyElement<V>;
fn when(mut self, condition: bool, then: impl FnOnce(Self) -> Self) -> Self fn map<U>(self, f: impl FnOnce(Self) -> U) -> U
where
Self: Sized,
U: Component<V>,
{
f(self)
}
fn when(self, condition: bool, then: impl FnOnce(Self) -> Self) -> Self
where where
Self: Sized, Self: Sized,
{ {
if condition { self.map(|this| if condition { then(this) } else { this })
self = then(self);
}
self
} }
} }

View file

@ -98,16 +98,14 @@ impl<V: 'static> Panel<V> {
v_stack() v_stack()
.id(self.id.clone()) .id(self.id.clone())
.flex_initial() .flex_initial()
.when( .map(|this| match self.current_side {
self.current_side == PanelSide::Left || self.current_side == PanelSide::Right, PanelSide::Left | PanelSide::Right => this.h_full().w(current_size),
|this| this.h_full().w(current_size), PanelSide::Bottom => this,
)
.when(self.current_side == PanelSide::Left, |this| this.border_r())
.when(self.current_side == PanelSide::Right, |this| {
this.border_l()
}) })
.when(self.current_side == PanelSide::Bottom, |this| { .map(|this| match self.current_side {
this.border_b().w_full().h(current_size) PanelSide::Left => this.border_r(),
PanelSide::Right => this.border_l(),
PanelSide::Bottom => this.border_b().w_full().h(current_size),
}) })
.bg(cx.theme().colors().surface) .bg(cx.theme().colors().surface)
.border_color(cx.theme().colors().border) .border_color(cx.theme().colors().border)

View file

@ -94,14 +94,13 @@ impl Input {
.active(|style| style.bg(input_active_bg)) .active(|style| style.bg(input_active_bg))
.flex() .flex()
.items_center() .items_center()
.child( .child(div().flex().items_center().text_sm().map(|this| {
div() if self.value.is_empty() {
.flex() this.child(placeholder_label)
.items_center() } else {
.text_sm() this.child(label)
.when(self.value.is_empty(), |this| this.child(placeholder_label)) }
.when(!self.value.is_empty(), |this| this.child(label)), }))
)
} }
} }