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}