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    /// A dynamic signal-backed value.
12    #[debug(skip)]
13    Signal(Signal<String>),
14    /// An event handler callback.
15    #[debug(skip)]
16    Event(NativeEventHandler),
17    /// A dynamic expression value of any type (for component props).
18    Dynamic(String),
19    /// A CSS class reference created by the `class!` macro.
20    Css(Css),
21    /// A raw HTML fragment assigned via the `inner_html:` attribute.
22    ///
23    /// Replaces the element's children wholesale via
24    /// [`web_sys::Element::set_inner_html`]. Unlike `Text` (which the
25    /// browser escapes), this variant trusts the input string and runs
26    /// any embedded `<script>` tags — it is the euv equivalent of
27    /// React's `dangerouslySetInnerHTML`. Always document the XSS
28    /// surface when exposing this attribute to user-supplied data.
29    ///
30    /// When both `inner_html:` and `class:` / other attributes are set
31    /// on the same element, `inner_html` is applied last so it wins on
32    /// children. Element children listed inside the same `html!` block
33    /// are skipped (mirroring React's behaviour).
34    InnerHtml(String),
35    /// A reactive `inner_html:` payload that re-renders the element's
36    /// children whenever the signal value changes.
37    ///
38    /// Same XSS semantics as [`AttributeValue::InnerHtml`] — the signal
39    /// may carry any HTML, including executable `<script>` tags.
40    #[debug(skip)]
41    InnerHtmlSignal(Signal<String>),
42    /// A reactive handle to the element being created, populated by the
43    /// renderer after the corresponding `ref:` attribute fires.
44    ///
45    /// The renderer does **not** write a `ref="..."` attribute into the
46    /// DOM — it intercepts this variant, calls [`NodeRefDyn::set`] with
47    /// the freshly-created element, then `clear()`s it on unmount.
48    #[debug(skip)]
49    Ref(NodeRefDyn),
50}