Skip to content

Latest commit

 

History

History
319 lines (269 loc) · 16.8 KB

elements.md

File metadata and controls

319 lines (269 loc) · 16.8 KB
title description
Elements
Both HTML and SVG elements are supported

DOM nodes

There are many reasons why you might want to create or manage DOM nodes manually in Yew, such as when integrating with JS libraries that can cause conflicts with managed components.

Using web-sys, you can create DOM elements and convert them into a Node - which can then be used as a Html value using VRef:

    // ...
    fn view(&self) -> Html {
        use yew::{utils::document, web_sys::{Element, Node}};

        // Create a div element from the document
        let div: Element = document().create_element("div").unwrap();
        // Add content, classes etc.
        div.set_inner_html("Hello, World!");
        // Convert Element into a Node
        let node: Node = div.into();
        // Return that Node as a Html value
        Html::VRef(node)
    }

Dynamic tag names

When building a higher-order component you might find yourself in a situation where the element's tag name isn't static. For example, you might have a Title component which can render anything from h1 to h6 depending on a level prop. Instead of having to use a big match expression, Yew allows you to set the tag name dynamically using @{name} where name can be any expression that returns a string.

let level = 5;
let text = "Hello World!".to_owned()

html! {
    <@{format!("h{}", level)} class="title">{ content }</@>
}

Boolean Attributes

Some content attributes (e.g checked, hidden, required) are called boolean attributes. In Yew, boolean attributes need to be set to a bool value:

    html! {
        <div hidden=true>
            { "This div is hidden." }
        </div>
    }

This will result in HTML that's functionally equivalent to this:

    <div hidden>This div is hidden.</div>

Setting a boolean attribute to false is equivalent to not using the attribute at all; values from boolean expressions can be used:

    let no = 1 + 1 != 2;

    html! {
        <div hidden=no>
            { "This div is NOT hidden." }
        </div>
    }

This will result in the following HTML:

    <div>This div is NOT hidden.</div>

Optional attributes for HTML elements

Most HTML attributes can be marked as optional by placing a ? in front of the = sign. This makes them accept the same type of value as otherwise, but wrapped in an Option<T>:

let maybe_id = Some("foobar");

html! {
    <div id?=maybe_id></div>
}

If the attribute is set to None, the attribute won't be set in the DOM.

Listeners

Listener attributes need to be passed a Callback which is a wrapper around a closure. How you create your callback depends on how you wish your app to react to a listener event:

struct MyComponent {
    link: ComponentLink<Self>,
}

enum Msg {
    Click,
}

impl Component for MyComponent {
    type Message = Msg;
    type Properties = ();

    fn create(_: Self::Properties, link: ComponentLink<Self>) -> Self {
        MyComponent { link }
    }

    fn update(&mut self, msg: Self::Message) -> ShouldRender {
        match msg {
            Msg::Click => {
                // Handle Click
            }
        }
    }

    fn view(&self) -> Html {
        // Create a callback from a component link to handle it in a component
        let click_callback = self.link.callback(|_: ClickEvent| Msg::Click);
        html! {
            <button onclick=click_callback>
                { "Click me!" }
            </button>
        }
    }
}
struct MyComponent {
    worker: Dispatcher<MyWorker>,
}

impl Component for MyComponent {
    type Message = ();
    type Properties = ();

    fn create(_: Self::Properties, _: ComponentLink<Self>) -> Self {
        MyComponent {
            worker: MyWorker::dispatcher()
        }
    }

    fn update(&mut self, _: Self::Message) -> ShouldRender {
        false
    }

    fn view(&self) -> Html {
        // Create a callback from a worker to handle it in another context
        let click_callback = self.worker.callback(|_: ClickEvent| WorkerMsg::Process);
        html! {
            <button onclick=click_callback>
                { "Click me!" }
            </button>
        }
    }
}
struct MyComponent;

impl Component for MyComponent {
    type Message = ();
    type Properties = ();

    fn create(_: Self::Properties, _: ComponentLink<Self>) -> Self {
        MyComponent
    }

    fn update(&mut self, _: Self::Message) -> ShouldRender {
        false
    }

    fn view(&self) -> Html {
        // Create an ephemeral callback
        let click_callback = Callback::from(|| {
            console_log!("clicked!");
        });

        html! {
            <button onclick=click_callback>
                { "Click me!" }
            </button>
        }
    }
}

Event Types

:::tip All the event types mentioned in the following table are re-exported under yew::events. Using the types from yew::events makes it easier to ensure version compatibility than if you were to manually include web-sys as a dependency in your crate because you won't end up using a version which conflicts with the version that Yew specifies. :::

Event name web_sys Event Type
onabort Event
onauxclick MouseEvent
onblur FocusEvent
oncancel Event
oncanplay Event
oncanplaythrough Event
onchange ChangeData
onclick MouseEvent
onclose Event
oncontextmenu MouseEvent
oncuechange Event
ondblclick MouseEvent
ondrag DragEvent
ondragend DragEvent
ondragenter DragEvent
ondragexit DragEvent
ondragleave DragEvent
ondragover DragEvent
ondragstart DragEvent
ondrop DragEvent
ondurationchange Event
onemptied Event
onended Event
onerror Event
onfocus FocusEvent
onfocusin FocusEvent
onfocusout FocusEvent
onformdata Event
oninput InputData
oninvalid Event
onkeydown KeyboardEvent
onkeypress KeyboardEvent
onkeyup KeyboardEvent
onload Event
onloadeddata Event
onloadedmetadata Event
onloadstart ProgressEvent
onmousedown MouseEvent
onmouseenter MouseEvent
onmouseleave MouseEvent
onmousemove MouseEvent
onmouseout MouseEvent
onmouseover MouseEvent
onmouseup MouseEvent
onpause Event
onplay Event
onplaying Event
onprogress ProgressEvent
onratechange Event
onreset Event
onresize Event
onscroll Event
onsecuritypolicyviolation Event
onseeked Event
onseeking Event
onselect Event
onslotchange Event
onstalled Event
onsubmit FocusEvent
onsuspend Event
ontimeupdate Event
ontoggle Event
onvolumechange Event
onwaiting Event
onwheel WheelEvent
oncopy Event
oncut Event
onpaste Event
onanimationcancel AnimationEvent
onanimationend AnimationEvent
onanimationiteration AnimationEvent
onanimationstart AnimationEvent
ongotpointercapture PointerEvent
onloadend ProgressEvent
onlostpointercapture PointerEvent
onpointercancel PointerEvent
onpointerdown PointerEvent
onpointerenter PointerEvent
onpointerleave PointerEvent
onpointerlockchange Event
onpointerlockerror Event
onpointermove PointerEvent
onpointerout PointerEvent
onpointerover PointerEvent
onpointerup PointerEvent
onselectionchange Event
onselectstart Event
onshow Event
ontouchcancel TouchEvent
ontouchend TouchEvent
ontouchmove TouchEvent
ontouchstart TouchEvent
ontransitioncancel TransitionEvent
ontransitionend TransitionEvent
ontransitionrun TransitionEvent
ontransitionstart TransitionEvent

Relevant examples