///|
/// Check if element has dynamic content that needs hydration
pub fn[E, A] has_dynamic_content(attrs : Array[(String, Attr[E, A])]) -> Bool {
for attr in attrs {
let (_, value) = attr
match value {
VDynamic(_) | VHandler(_) | VAction(_) => return true
_ => ()
}
}
false
}
// Attr factory functions for external packages
///|
/// Create a static attribute value.
/// ```mbt check
/// test {
/// let attr : Attr[Unit, String] = attr_static("my-class")
/// guard attr is VStatic(v) else { fail("expected VStatic") }
/// inspect(v, content="my-class")
/// }
/// ```
pub fn[E, A] attr_static(value : A) -> Attr[E, A] {
VStatic(value)
}
///|
/// Create a dynamic attribute value.
/// The value is computed lazily on each render.
/// ```mbt check
/// test {
/// let mut count = 0
/// let attr : Attr[Unit, String] = attr_dynamic(fn() {
/// "count-" + count.to_string()
/// })
/// guard attr is VDynamic(getter) else { fail("expected VDynamic") }
/// inspect(getter(), content="count-0")
/// count = 5
/// inspect(getter(), content="count-5")
/// }
/// ```
pub fn[E, A] attr_dynamic(getter : () -> A) -> Attr[E, A] {
VDynamic(getter)
}
///|
/// Create a handler attribute value
pub fn[E, A] attr_handler(handler : EventHandler[E]) -> Attr[E, A] {
VHandler(handler)
}
///|
/// Create a style attribute value (string form, e.g. "color: red; margin: 10px")
/// Note: For Web (A = String), pass the style string directly
pub fn[E] attr_style(style : String) -> Attr[E, String] {
attr_static(style)
}
///|
/// Create a dynamic style attribute value
/// Note: For Web (A = String), the getter returns a style string
pub fn[E] attr_dynamic_style(getter : () -> String) -> Attr[E, String] {
attr_dynamic(getter)
}
///|
/// Create an action attribute value - dispatches named action on event
/// Used for declarative event handling with enum types:
/// ("onclick", action(Increment)) // requires derive(Show)
///
/// Example:
/// ```
/// pub enum MyAction { Increment; Decrement } derive(Show)
/// h("button", [("onclick", action(Increment))], [...])
/// ```
pub fn[E, V, Act : Show] action(a : Act) -> Attr[E, V] {
VAction(a.to_string())
}