# Refine element and component traits \(\#3367\) · gitcafe/zed

[View on GitCafe](https://git.cafe/gitcafe/zed/commit/6f0cdc35f3ed4c182e6f610e93fe06a4b91cc7d2)

Repository: [gitcafe/zed](https://git.cafe/gitcafe/zed)

Visibility: public

Requested revision: 6f0cdc35f3ed4c182e6f610e93fe06a4b91cc7d2

Requested commit: 6f0cdc35f3ed4c182e6f610e93fe06a4b91cc7d2

Commit: 6f0cdc35f3ed4c182e6f610e93fe06a4b91cc7d2

Tree: 7c28056c2587603b71d72ddbf86643bdd931ca41

Author: Conrad Irwin

Committer: GitHub

## Message

````
Refine element and component traits (#3367)

This PR changes `Element::paint` to move self and introduces a new
`RenderOnce` trait, which renders into an element by moving self.
Elements are required to be `RenderOnce`, and `element_id` is now on
`RenderOnce` so we can get the id without moving self. The `child` and
`children` methods now expect `impl RenderOnce`.

```rust
pub trait Element<V: 'static>: 'static + RenderOnce<V> {
    type State: 'static;

    fn layout(
        &mut self,
        view_state: &mut V,
        element_state: Option<Self::State>,
        cx: &mut ViewContext<V>,
    ) -> (LayoutId, Self::State);

    fn paint(
        self,
        bounds: Bounds<Pixels>,
        view_state: &mut V,
        element_state: &mut Self::State,
        cx: &mut ViewContext<V>,
    );

    fn into_any(self) -> AnyElement<V> {
        AnyElement::new(self)
    }
}

pub trait RenderOnce<V: 'static>: Sized {
    type Element: Element<V> + 'static;

    fn element_id(&self) -> Option<ElementId>;

    fn render_once(self) -> Self::Element;

   // default helpers ...
}
```

To make a type a component, you can add `#[derive(RenderOnce)]`, which
will require your type to implement the `Component` trait:

```rust
pub trait Component<V: 'static>: 'static {
    type Rendered: RenderOnce<V>;

    fn render(self, view: &mut V, cx: &mut ViewContext<V>) -> Self::Rendered;
}
```

I'm satisfied with this being what we open source for elements, aside
from maybe adding a `StatefulComponent` trait that uses element state.
Things finally feel like they slot into a coherent and simple narrative.

Release Notes:

- N/A
````

## Parents

- [385028865e92c438af2395db63c4ed6958554c10](https://git.cafe/gitcafe/zed/commit/385028865e92c438af2395db63c4ed6958554c10?format=markdown)

- [b19a6c0dcc2a775ccf12a5f41cc8e5b58ad79d92](https://git.cafe/gitcafe/zed/commit/b19a6c0dcc2a775ccf12a5f41cc8e5b58ad79d92?format=markdown)

[Source at this commit](https://git.cafe/gitcafe/zed/tree/6f0cdc35f3ed4c182e6f610e93fe06a4b91cc7d2?format=markdown)
