Skip to main content

euv_core/vdom/attribute/
enum.rs

1use super::*;
2
3/// Represents the value of an HTML attribute.
4///
5/// Attributes can be static text, reactive signals, event handlers, dynamic expressions,
6/// CSS class references, or raw HTML fragments assigned via `inner_html:`.
7#[derive(Clone, CustomDebug)]
8pub enum AttributeValue {
9    /// A static string value.
10    Text(String),
11    /// OPT 10: a `'static` string slice that bypasses the runtime allocation
12    /// that `Text(String)` would require.
13    ///
14    /// Used by the `html!` and `class!` macros when every component of the
15    /// value is a string literal (e.g. `style: { color: "red" }` or
16    /// `class: "static-class-name"`). Renderer treats this exactly like
17    /// `Text(value.to_string())` minus the heap allocation.
18    StaticText(&'static str),
19    /// A dynamic signal-backed value.
20    #[debug(skip)]
21    Signal(Signal<String>),
22    /// An event handler callback.
23    #[debug(skip)]
24    Event(NativeEventHandler),
25    /// A dynamic expression value of any type (for component props).
26    Dynamic(String),
27    /// A CSS class reference created by the `class!` macro.
28    Css(Css),
29    /// OPT 11: a borrowed `'static` reference to a `Css` produced by the
30    /// `class!` macro, avoiding the deep `Css::clone()` that the owned
31    /// [`AttributeValue::Css`] variant performs.
32    ///
33    /// The reference points to the `OnceLock<Css>` instance that `class!`
34    /// returns, so the lifetime is `'static` for the duration of the
35    /// program. Renderers inject the style on first sight and then read
36    /// the class name through the reference with zero copies.
37    CssRef(&'static Css),
38    /// A raw HTML fragment assigned via the `inner_html:` attribute.
39    ///
40    /// Replaces the element's children wholesale via
41    /// [`web_sys::Element::set_inner_html`]. Unlike `Text` (which the
42    /// browser escapes), this variant trusts the input string and runs
43    /// any embedded `<script>` tags — it is the euv equivalent of
44    /// React's `dangerouslySetInnerHTML`. Always document the XSS
45    /// surface when exposing this attribute to user-supplied data.
46    ///
47    /// When both `inner_html:` and `class:` / other attributes are set
48    /// on the same element, `inner_html` is applied last so it wins on
49    /// children. Element children listed inside the same `html!` block
50    /// are skipped (mirroring React's behaviour).
51    InnerHtml(String),
52    /// A reactive `inner_html:` payload that re-renders the element's
53    /// children whenever the signal value changes.
54    ///
55    /// Same XSS semantics as [`AttributeValue::InnerHtml`] — the signal
56    /// may carry any HTML, including executable `<script>` tags.
57    #[debug(skip)]
58    InnerHtmlSignal(Signal<String>),
59    /// A reactive handle to the element being created, populated by the
60    /// renderer after the corresponding `ref:` attribute fires.
61    ///
62    /// The renderer does **not** write a `ref="..."` attribute into the
63    /// DOM — it intercepts this variant, calls [`NodeRefDyn::set`] with
64    /// the freshly-created element, then `clear()`s it on unmount.
65    #[debug(skip)]
66    Ref(NodeRefDyn),
67}