From a7c1a1c7de2563ec796b488fc2744d3b55c66e61 Mon Sep 17 00:00:00 2001 From: tristan Date: Sun, 31 Dec 2023 17:51:21 +0000 Subject: [PATCH] merge styles with attrs in styled components --- flake.nix | 2 +- nixite/elems.nix | 24 ++++++++++++------------ nixite/html.nix | 12 ++++++++---- nixite/style.nix | 8 ++++---- testing/elems.test.nix | 20 ++++++++++++++++---- testing/it.nix | 5 ++++- testing/style.test.nix | 36 +++++++++++++++++++++++------------- 7 files changed, 68 insertions(+), 39 deletions(-) diff --git a/flake.nix b/flake.nix index 179b364..d3901d4 100644 --- a/flake.nix +++ b/flake.nix @@ -35,7 +35,7 @@ }) ); - serve = self.serve self.packages.${system}.default; + serve = nixite.serve self.packages.${system}.default; test = let test = import ./testing/import.nix; diff --git a/nixite/elems.nix b/nixite/elems.nix index b194850..b10ffdc 100644 --- a/nixite/elems.nix +++ b/nixite/elems.nix @@ -2,20 +2,20 @@ let html = import ./html.nix; s = import ./style.nix; in - (s.styled "p" "p" {} {}) - (s.styled "div" "div" {} {}) - (s.styled "section" "section" {} {}) - (s.styled "span" "span" {} {}) - (s.styled "main" "main" {} {}) - (s.styled "article" "article" {} {}) - (s.styled "title" "title" {class = [];} {}) - (s.styled "h1" "h1" {} {}) - (s.styled "h2" "h2" {} {}) - (s.styled "h3" "h3" {} {}) + (s.styled "p" "p" {}) + (s.styled "div" "div" {}) + (s.styled "section" "section" {}) + (s.styled "span" "span" {}) + (s.styled "main" "main" {}) + (s.styled "article" "article" {}) + (s.styled "title" "title" {class = [];}) + (s.styled "h1" "h1" {}) + (s.styled "h2" "h2" {}) + (s.styled "h3" "h3" {}) (s.styled "list" "ul" { __child = child: assert builtins.isList child; (map (html.tag "li" {}) child); - } {}) + }) (s.styled "doc" "html" { __child = child: assert builtins.isList child; @@ -26,7 +26,7 @@ in ]; lang = "en"; class = []; - } {}) + }) // { h = v: child: html.tag "h${toString v}" {} child; diff --git a/nixite/html.nix b/nixite/html.nix index d6b74fc..e87a5cd 100644 --- a/nixite/html.nix +++ b/nixite/html.nix @@ -1,5 +1,8 @@ let - keyvalue = key: value: ''${key}="${toString value}"''; + keyvalue = key: value: + assert builtins.isString key; + if value == "" || value == [] || value == {} then "" else + ''${key}="${toString value}"''; in rec { toHTML = elem: if builtins.typeOf elem == "string" @@ -9,15 +12,16 @@ in rec { else ''<${elem.tag} ${writeAttrs elem.attrs}>${toHTML elem.child}''; writeAttrs = attrs: - toString (builtins.attrValues ( + toString (builtins.filter (value: value != "") (builtins.attrValues ( builtins.mapAttrs (key: value: if (builtins.isPath value) then keyvalue key (baseNameOf value) - else if (builtins.substring 0 2 key) == "__" + else + if (builtins.substring 0 2 key) == "__" then "" else keyvalue key value) attrs - )); + ))); tag = tag: attrs: child: { inherit tag attrs child; diff --git a/nixite/style.nix b/nixite/style.nix index 1417eb8..a525a73 100644 --- a/nixite/style.nix +++ b/nixite/style.nix @@ -36,18 +36,18 @@ let ) + id; in { - styled = name: tag: cprops: styles: let + styled = name: tag: cprops: let custom = cprops.__child or (child: child); in { ${name} = props: if builtins.isAttrs props - then (child: (html.tag tag (props // {class = [name];} // cprops) (custom child))) + then (child: (html.tag tag (props // {class = [name];} // cprops // {style = "";}) (custom child))) else if builtins.isString props || builtins.isList props - then (html.tag tag ({class = [name];} // cprops) (custom props)) + then (html.tag tag ({class = [name];} // cprops // {style = "";}) (custom props)) else throw "Call element with attributes and child."; - style = mkStyle (mkIdentifier name tag cprops) styles; + style = mkStyle (mkIdentifier name tag cprops) ( cprops.style or {} ); } // join; diff --git a/testing/elems.test.nix b/testing/elems.test.nix index 59b0c09..705a434 100644 --- a/testing/elems.test.nix +++ b/testing/elems.test.nix @@ -7,38 +7,47 @@ in (it "makes a p tag" { expected = html.tag "p" {class = ["p"];} "foobar"; actual = p {} "foobar"; + asString = true; }) (it "makes a div tag" { expected = html.tag "div" {class = ["div"];} "foobar"; actual = div {} "foobar"; + asString = true; }) (it "makes a section tag" { expected = html.tag "section" {class = ["section"];} "foobar"; actual = section {} "foobar"; + asString = true; }) (it "makes a span tag" { expected = html.tag "span" {class = ["span"];} "foobar"; actual = span {} "foobar"; + asString = true; }) (it "makes a main tag" { expected = html.tag "main" {class = ["main"];} ["yeet"]; actual = main {} ["yeet"]; + asString = true; }) (it "makes an h1 tag" { expected = html.tag "h1" {} "foobar"; actual = h 1 "foobar"; + asString = true; }) (it "makes an h2 tag" { expected = html.tag "h2" {} "foobar"; actual = h 2 "foobar"; + asString = true; }) (it "makes a title tag" { expected = html.tag "title" {class = [];} "foobar"; actual = title {} "foobar"; + asString = true; }) (it "makes an a tag" { expected = html.tag "a" {href = "https://example.com";} "example"; actual = link "https://example.com" "example"; + asString = true; }) (it "makes a stylesheet link" { expected = html.tag "link" { @@ -46,9 +55,10 @@ in rel = "stylesheet"; } ""; actual = stylesheet "/style"; + asString = true; }) (it "makes a list" { - expected = toString (html.tag "ul" { + expected = (html.tag "ul" { __ = ""; class = ["list"]; } [ @@ -56,10 +66,11 @@ in (html.tag "li" {} "bar") (html.tag "li" {} "baz") ]); - actual = toString (list {} ["foo" "bar" "baz"]); + actual = (list {} ["foo" "bar" "baz"]); + asString = true; }) (it "makes an html doc" { - expected = toString (html.tag "html" { + expected = (html.tag "html" { __child = ""; class = []; lang = "en"; @@ -67,6 +78,7 @@ in (html.tag "head" {} ["foo"]) (html.tag "body" {} "bar") ]); - actual = toString (doc {} [["foo"] "bar"]); + actual = (doc {} [["foo"] "bar"]); + asString = true; }) ] diff --git a/testing/it.nix b/testing/it.nix index c6da567..1726b20 100644 --- a/testing/it.nix +++ b/testing/it.nix @@ -1,8 +1,11 @@ msg: { actual, expected, + asString ? false, }: -if actual == expected +if ( + if asString then toString actual == toString expected + else actual == expected ) then '' echo 'it ${msg}' '' diff --git a/testing/style.test.nix b/testing/style.test.nix index 9ea5188..437f993 100644 --- a/testing/style.test.nix +++ b/testing/style.test.nix @@ -4,40 +4,46 @@ let it = import ./it.nix; my = - (style.styled "p" "p" {} { + (style.styled "p" "p" {style = { some-style = "some value"; - }) - (style.styled "div" "div" {class = ["something"];} { + };}) + (style.styled "div" "div" {class = ["something"]; style = { this = "that"; - }) + };}) (style.styled "s" "div" { id = "s"; class = ["something"]; - } { - s = "yes"; - }) - (style.styled "foobar" "div" {class = ["foo" "bar"];} { - something = "something"; - }) + style = { + s = "yes"; + };}) + (style.styled "foobar" "div" { + class = ["foo" "bar"]; + style = { + something = "something"; + }; + } ) (style.style "body" { foo = "bar"; }) (style.styled "list" "ul" { __child = child: assert builtins.isList child; (map (html.tag "li" {}) child); - } {}); + }); in [ (it "makes a p component" { expected = html.tag "p" {class = ["p"];} "yes"; actual = my.p {} "yes"; + asString = true; }) (it "does not error without attrs" { expected = html.tag "p" {class = ["p"];} "yes"; actual = my.p "yes"; + asString = true; }) (it "makes a component" { expected = html.tag "div" {class = ["something"];} "foobar"; actual = my.div {} "foobar"; + asString = true; }) (it "makes special components" { expected = html.tag "div" { @@ -45,20 +51,23 @@ in [ class = ["something"]; } "foobar"; actual = my.s {} "foobar"; + asString = true; }) (it "works on many classes" { expected = html.tag "div" {class = ["foo" "bar"];} "foobar"; actual = my.foobar {} "foobar"; + asString = true; }) (it "does custom behavour" { - expected = toString (html.tag "ul" { + expected = (html.tag "ul" { __ = ""; class = ["list"]; } [ (html.tag "li" {} "1") (html.tag "li" {} "2") ]); - actual = toString (my.list {} ["1" "2"]); + actual = (my.list {} ["1" "2"]); + asString = true; }) (it "combines attrs" { expected = html.tag "div" { @@ -66,6 +75,7 @@ in [ class = ["something"]; } "foobar"; actual = my.div {id = "foo";} "foobar"; + asString = true; }) (it "makes a style" { expected = ''