aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDanielle Maywood <danielle@maywood.me>2023-10-02 11:29:39 +0100
committerGitHub <noreply@github.com>2023-10-02 11:29:39 +0100
commit1240874302ec172b1018934ef5a8cba23397bc51 (patch)
treee249618b798b6cc095792f9ff66c3b95bc70c75b
parentc33d49b08f73b00fbedbf79b7772912e0064a939 (diff)
downloadlustre-1240874302ec172b1018934ef5a8cba23397bc51.tar.gz
lustre-1240874302ec172b1018934ef5a8cba23397bc51.zip
🔀 Combine class and style attributes (#15)
* Create initial implementation for merging class and style attrs * Make changes according to feedback * Handle boolean attributes properly
-rw-r--r--src/lustre/attribute.gleam17
-rw-r--r--src/lustre/element.gleam37
2 files changed, 43 insertions, 11 deletions
diff --git a/src/lustre/attribute.gleam b/src/lustre/attribute.gleam
index 6540713..a5ed765 100644
--- a/src/lustre/attribute.gleam
+++ b/src/lustre/attribute.gleam
@@ -7,6 +7,7 @@ import gleam/dynamic.{Dynamic}
import gleam/function
import gleam/int
import gleam/list
+import gleam/option.{None, Option, Some}
import gleam/result
import gleam/string
import gleam/string_builder.{StringBuilder}
@@ -53,27 +54,29 @@ pub fn map(attr: Attribute(a), f: fn(a) -> b) -> Attribute(b) {
///
///
-pub fn to_string(attr: Attribute(msg)) -> String {
+pub fn to_string_parts(
+ attr: Attribute(msg),
+) -> Option(#(String, Option(String))) {
case attr {
Attribute(name, value, as_property: False) -> {
case dynamic.classify(value) {
- "String" -> name <> "=\"" <> dynamic.unsafe_coerce(value) <> "\""
+ "String" -> Some(#(name, Some(dynamic.unsafe_coerce(value))))
// Boolean attributes are determined based on their presence, eg we don't
// want to render `disabled="false"` if the value is `false` we simply
// want to omit the attribute altogether.
"Boolean" ->
case dynamic.unsafe_coerce(value) {
- True -> name
- False -> ""
+ True -> Some(#(name, None))
+ False -> None
}
// For everything else we'll just make a best-effort serialisation.
- _ -> name <> "=\"" <> string.inspect(value) <> "\""
+ _ -> Some(#(name, Some(string.inspect(value))))
}
}
- Attribute(_, _, as_property: True) -> ""
- Event(on, _) -> "data-lustre-on:" <> on
+ Attribute(_, _, as_property: True) -> None
+ Event(on, _) -> Some(#("data-lustre-on", Some(on)))
}
}
diff --git a/src/lustre/element.gleam b/src/lustre/element.gleam
index 21191ff..83fce9a 100644
--- a/src/lustre/element.gleam
+++ b/src/lustre/element.gleam
@@ -4,6 +4,7 @@
// IMPORTS ---------------------------------------------------------------------
import gleam/list
+import gleam/option.{None, Some}
import gleam/string
import gleam/string_builder.{StringBuilder}
import lustre/attribute.{Attribute}
@@ -141,10 +142,38 @@ fn attrs_to_string_builder(
html: StringBuilder,
attrs: List(Attribute(msg)),
) -> StringBuilder {
- use html, attr <- list.fold(attrs, html)
- html
- |> string_builder.append(" ")
- |> string_builder.append_builder(attribute.to_string_builder(attr))
+ let #(html, class, style) = {
+ use #(html, class, style), attr <- list.fold(attrs, #(html, "", ""))
+
+ case attribute.to_string_parts(attr) {
+ Some(#("class", Some(val))) if class == "" -> #(html, val, style)
+ Some(#("class", Some(val))) -> #(html, class <> " " <> val, style)
+ Some(#("style", Some(val))) if style == "" -> #(html, class, val)
+ Some(#("style", Some(val))) -> #(html, class, style <> " " <> val)
+ Some(#(key, Some(val))) -> #(
+ string_builder.append(html, " " <> key <> "=\"" <> val <> "\""),
+ class,
+ style,
+ )
+ Some(#(key, None)) -> #(
+ string_builder.append(html, " " <> key),
+ class,
+ style,
+ )
+ None -> #(html, class, style)
+ }
+ }
+
+ case class, style {
+ "", "" -> html
+ _, "" -> string_builder.append(html, " class=\"" <> class <> "\"")
+ "", _ -> string_builder.append(html, " style=\"" <> style <> "\"")
+ _, _ ->
+ string_builder.append(
+ html,
+ " class=\"" <> class <> "\" style=\"" <> style <> "\"",
+ )
+ }
}
fn children_to_string_builder(