Packages
lustre
4.1.1
5.7.1
5.7.0
5.6.0
5.5.2
5.5.1
5.5.0
5.4.0
5.3.5
5.3.4
5.3.3
5.3.2
5.3.1
5.3.0
5.2.1
5.2.0
5.1.1
5.1.0
5.0.3
5.0.2
5.0.1
5.0.0
4.6.4
4.6.3
4.6.2
4.6.1
4.6.0
4.5.1
4.5.0
4.4.4
4.4.3
4.4.1
4.4.0
4.3.6
4.3.5
4.3.4
4.3.3
4.3.2
4.3.1
4.3.0
4.2.6
4.2.5
4.2.4
4.2.3
4.2.2
4.2.1
4.2.0
4.1.8
4.1.7
4.1.6
4.1.5
4.1.4
4.1.3
4.1.2
4.1.1
4.1.0
4.0.0
4.0.0-rc1
4.0.0-rc.2
3.1.4
3.1.3
3.1.2
3.1.1
3.1.0
3.0.12
3.0.11
3.0.10
3.0.9
3.0.8
3.0.7
3.0.6
3.0.5
3.0.4
3.0.3
3.0.2
3.0.1
3.0.0
3.0.0-rc.8
3.0.0-rc.7
3.0.0-rc.6
3.0.0-rc.5
3.0.0-rc.4
3.0.0-rc.3
3.0.0-rc.2
3.0.0-rc.1
2.0.1
2.0.0
1.3.0
1.2.0
1.1.0
1.0.0
Create HTML templates, single page applications, Web Components, and real-time server components in Gleam!
Current section
Files
Jump to
Current section
Files
src/lustre/attribute.gleam
// IMPORTS ---------------------------------------------------------------------
import gleam/dynamic.{type Decoder}
import gleam/int
import gleam/list
import gleam/result
import gleam/string
import lustre/internals/vdom.{Attribute, Event}
// TYPES -----------------------------------------------------------------------
/// The `Attribute` type encompasses HTML attributes, DOM properties, and
/// event listeners.
///
pub type Attribute(msg) =
vdom.Attribute(msg)
// CONSTRUCTORS ----------------------------------------------------------------
/// Create an HTML attribute. This is like saying `element.setAttribute("class", "wibble")`
/// in JavaScript. Attributes will be rendered when calling [`element.to_string`](./element.html#to_string).
///
/// **Note**: there is a subtle difference between attributes and properties. You
/// can read more about the implications of this [here](https://javascript.info/dom-attributes-and-properties).
///
pub fn attribute(name: String, value: String) -> Attribute(msg) {
Attribute(name, dynamic.from(value), as_property: False)
}
/// Create a DOM property. This is like saying `element.className = "wibble"` in
/// JavaScript. Properties will be **not** be rendered when calling
/// [`element.to_string`](./element.html#to_string).
///
/// **Note**: there is a subtle difference between attributes and properties. You
/// can read more about the implications of this [here](https://javascript.info/dom-attributes-and-properties).
///
pub fn property(name: String, value: any) -> Attribute(msg) {
Attribute(name, dynamic.from(value), as_property: True)
}
///
pub fn on(name: String, handler: Decoder(msg)) -> Attribute(msg) {
Event("on" <> name, handler)
}
/// Create an empty attribute. This is not added to the DOM and not rendered when
/// calling [`element.to_string`](./element.html#to_string), but it is useful for
/// _conditionally_ adding attributes to an element.
///
pub fn none() -> Attribute(msg) {
class("")
}
// MANIPULATIONS ---------------------------------------------------------------
/// The `Attribute` type is parameterised by the type of messages it can produce
/// from events handlers. Sometimes you might end up with an attribute from a
/// library or module that produces a different type of message: this function lets
/// you map the messages produced from one type to another.
///
pub fn map(attr: Attribute(a), f: fn(a) -> b) -> Attribute(b) {
case attr {
Attribute(name, value, as_property) -> Attribute(name, value, as_property)
Event(on, handler) -> Event(on, fn(e) { result.map(handler(e), f) })
}
}
// COMMON ATTRIBUTES -----------------------------------------------------------
///
///
/// > **Note**: unlike most attributes, multiple `style` attributes are merged
/// > with any existing other styles on an element. Styles added _later_ in the
/// > list will override styles added earlier.
///
pub fn style(properties: List(#(String, String))) -> Attribute(msg) {
attribute("style", {
use styles, #(name, value) <- list.fold(properties, "")
styles <> name <> ":" <> value <> ";"
})
}
///
///
/// > **Note**: unlike most attributes, multiple `class` attributes are merged
/// > with any existing other classes on an element.
///
pub fn class(name: String) -> Attribute(msg) {
attribute("class", name)
}
///
pub fn classes(names: List(#(String, Bool))) -> Attribute(msg) {
attribute(
"class",
names
|> list.filter_map(fn(class) {
case class.1 {
True -> Ok(class.0)
False -> Error(Nil)
}
})
|> string.join(" "),
)
}
///
pub fn id(name: String) -> Attribute(msg) {
attribute("id", name)
}
///
pub fn role(name: String) -> Attribute(msg) {
attribute("role", name)
}
// INPUTS ----------------------------------------------------------------------
///
pub fn type_(name: String) -> Attribute(msg) {
attribute("type", name)
}
///
pub fn value(val: String) -> Attribute(msg) {
property("value", dynamic.from(val))
}
///
pub fn checked(is_checked: Bool) -> Attribute(msg) {
property("checked", is_checked)
}
///
pub fn placeholder(text: String) -> Attribute(msg) {
attribute("placeholder", text)
}
///
pub fn selected(is_selected: Bool) -> Attribute(msg) {
property("selected", is_selected)
}
// INPUT HELPERS ---------------------------------------------------------------
///
pub fn accept(types: List(String)) -> Attribute(msg) {
attribute("accept", string.join(types, " "))
}
///
pub fn accept_charset(types: List(String)) -> Attribute(msg) {
attribute("acceptCharset", string.join(types, " "))
}
///
pub fn msg(uri: String) -> Attribute(msg) {
attribute("msg", uri)
}
///
pub fn autocomplete(name: String) -> Attribute(msg) {
attribute("autocomplete", name)
}
///
pub fn autofocus(should_autofocus: Bool) -> Attribute(msg) {
property("autofocus", should_autofocus)
}
///
pub fn disabled(is_disabled: Bool) -> Attribute(msg) {
property("disabled", is_disabled)
}
///
pub fn name(name: String) -> Attribute(msg) {
attribute("name", name)
}
///
pub fn pattern(regex: String) -> Attribute(msg) {
attribute("pattern", regex)
}
///
pub fn readonly(is_readonly: Bool) -> Attribute(msg) {
property("readonly", is_readonly)
}
///
pub fn required(is_required: Bool) -> Attribute(msg) {
property("required", is_required)
}
///
pub fn for(id: String) -> Attribute(msg) {
attribute("for", id)
}
// INPUT RANGES ----------------------------------------------------------------
///
pub fn max(val: String) -> Attribute(msg) {
attribute("max", val)
}
///
pub fn min(val: String) -> Attribute(msg) {
attribute("min", val)
}
///
pub fn step(val: String) -> Attribute(msg) {
attribute("step", val)
}
// INPUT TEXT AREAS ------------------------------------------------------------
///
pub fn cols(val: Int) -> Attribute(msg) {
attribute("cols", int.to_string(val))
}
///
pub fn rows(val: Int) -> Attribute(msg) {
attribute("rows", int.to_string(val))
}
///
pub fn wrap(mode: String) -> Attribute(msg) {
attribute("wrap", mode)
}
// LINKS AND AREAS -------------------------------------------------------------
///
pub fn href(uri: String) -> Attribute(msg) {
attribute("href", uri)
}
///
pub fn target(target: String) -> Attribute(msg) {
attribute("target", target)
}
///
pub fn download(filename: String) -> Attribute(msg) {
attribute("download", filename)
}
///
pub fn rel(relationship: String) -> Attribute(msg) {
attribute("rel", relationship)
}
// EMBEDDED CONTENT ------------------------------------------------------------
///
pub fn src(uri: String) -> Attribute(msg) {
attribute("src", uri)
}
///
pub fn height(val: Int) -> Attribute(msg) {
property("height", int.to_string(val))
}
///
pub fn width(val: Int) -> Attribute(msg) {
property("width", int.to_string(val))
}
///
pub fn alt(text: String) -> Attribute(msg) {
attribute("alt", text)
}
// AUDIO AND VIDEO -------------------------------------------------------------
///
pub fn autoplay(should_autoplay: Bool) -> Attribute(msg) {
property("autoplay", should_autoplay)
}
///
pub fn controls(visible: Bool) -> Attribute(msg) {
property("controls", visible)
}
///
pub fn loop(should_loop: Bool) -> Attribute(msg) {
property("loop", should_loop)
}
// FORMS -----------------------------------------------------------------------
///
pub fn action(url: String) -> Attribute(msg) {
attribute("action", url)
}
///
pub fn enctype(value: String) -> Attribute(msg) {
attribute("enctype", value)
}
///
pub fn method(method: String) -> Attribute(msg) {
attribute("method", method)
}
///
pub fn novalidate(value: Bool) -> Attribute(msg) {
property("novalidate", value)
}
///
pub fn form_action(action: String) -> Attribute(msg) {
attribute("formaction", action)
}
///
pub fn form_enctype(value: String) -> Attribute(msg) {
attribute("formenctype", value)
}
///
pub fn form_method(method: String) -> Attribute(msg) {
attribute("formmethod", method)
}
///
pub fn form_novalidate(value: Bool) -> Attribute(msg) {
property("formnovalidate", value)
}
///
pub fn form_target(target: String) -> Attribute(msg) {
attribute("formtarget", target)
}