Files
dioxus/packages/html
Evan Almloff d8d11db403 Boxed and mapped signals preparing for stores (#4413)
This PR contains just the breaking changes required for the upcoming store implementation. It adds two new primitives:

Mutable mapped signals (without a different subscriber list). This lets you scope a writable value and pass it to a child component. It requires two closures to map the immutable and mutable references to the inner signal. With stores, these closures will be derived
Boxed readable and writable values (ReadSignal, and WriteSignal). Any readable or writable types can be converted to a read signal or write signal with the boxed method or built in types are automatically converted into the boxed variants when passing into props


* map signals mutably

* boxed signals

* remove mutable borrow type from boxed writable

* improve map mut example

* restore boxed_mut helper

* make boxed readable/writable types copy

* Move away from the ReadOnlySignal alias in examples

* automatically convert Write

* Fix some tests

* ReadSignal and WriteSignal

* move read only signal alias

* make maps copy

* store prototype

* implement derive macro

* Handle generics in the derive macro

* Make Selector boxable

* derive boxed conversion

* Get rid of store type

* Remove hardcoded type from derive macro

* selector -> store

* Refactor store implementation

* more vec methods

* todo mvc store example

* Implement Storable for HashMap

* fix write

* restore sorting logic in todomvc

* derive readable and writable

* improve todomvc store example

* Result store

* Option store

* collect dead subscribers

* fix clippy and formatting

* recognize some common foreign types automatically

* fix foreign stores in props

* slice and array selectors

* clean up store example

* remove stores

* writable is child owned

* fix typo

* fix clippy

* fix doc tests
2025-07-31 13:19:55 -07:00
..
2025-07-16 16:04:13 -07:00

dioxus-html: Html (and SVG) Namespace for Dioxus

Crates.io MIT licensed Build Status Discord chat

Website | Guides | API Docs | Chat

Overview

The Dioxus rsx! macro can accept any compile-time correct namespace on top of NodeFactory. This crate provides the HTML (and SVG) namespaces which get imported in the Dioxus prelude.

However, this abstraction enables you to add any namespace of elements, provided they're in scope when rsx! is called. For an example, a UI that is designed for Augmented Reality might use different primitives than HTML:

use ar_namespace::*;

rsx! {
    magic_div {
        magic_header {}
        magic_paragraph {
            on_magic_click: move |event| {
                //
            }
        }
    }
}

This is currently a not-very-explored part of Dioxus. However, the namespacing system does make it possible to provide syntax highlighting, documentation, "go to definition" and compile-time correctness, so it's worth having it abstracted.

How it works:

Elements for dioxus must implement the (simple) DioxusElement trait to be used in the rsx! macro.

struct div;
impl DioxusElement for div {
    const TAG_NAME: &'static str = "div";
    const NAME_SPACE: Option<&'static str> = None;
}

All elements should be defined as a zero-sized-struct (also known as unit struct). These structs are zero-cost and just provide the type-level trickery to Rust for compile-time correct templates.

Attributes would then be implemented as constants on these unit structs.

The HTML namespace is defined mostly with macros. However, the expanded form would look something like this:

struct base;
impl DioxusElement for base {
    const TAG_NAME: &'static str = "base";
    const NAME_SPACE: Option<&'static str> = None;
}
impl base {
    const href: (&'static str, Option<'static str>, bool) = ("href", None, false);
    const target: (&'static str, Option<'static str>, bool) = ("target", None, false);
}

Because attributes are defined as methods on the unit struct, they guard the attribute creation behind a compile-time correct interface.

How to extend it:

Whenever the rsx! macro is called, it relies on a module dioxus_elements to be in scope. When you enable the html feature in dioxus, this module gets imported in the prelude. However, you can extend this with your own set of custom elements by making your own dioxus_elements module and re-exporting the html namespace.

mod dioxus_elements {
    use dioxus::prelude::dioxus_elements::*;
    struct my_element;
    impl DioxusElement for my_element {
        const TAG_NAME: &'static str = "base";
        const NAME_SPACE: Option<&'static str> = None;
    }
}

Contributing

  • Report issues on our issue tracker.
  • Join the discord and ask questions!

License

This project is licensed under the MIT license.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in Dioxus by you shall be licensed as MIT without any additional terms or conditions.