diff --git a/flake.nix b/flake.nix index 95ba412..0524df4 100644 --- a/flake.nix +++ b/flake.nix @@ -17,16 +17,17 @@ elems = nixite.elems; site = nixite.site; md = nixite.md; + style = nixite.style; packages.${system} = { - default = with self; - mkSite (site.applyStyle ./testing/src/style.css { - "index.html" = with elems; (doc + default = + nixite.mkSite (nixite.site.applyStyle ./testing/src/style.css { + "index.html" = with nixite.elems; (doc [ (title "Nixite") ] (main [ - (md.readMd ./testing/src/index.md) + (nixite.md.readMd ./testing/src/index.md) (link "/blog" "blog") (list [ "item 1" @@ -35,7 +36,7 @@ ]) ])); blog = { - "index.html" = with elems; (doc + "index.html" = with nixite.elems; (doc [ (title "A post") ] @@ -58,6 +59,7 @@ ${test ./testing/html.test.nix} ${test ./testing/elems.test.nix} ${test ./testing/site.test.nix} + ${test ./testing/style.test.nix} ''; }; }; diff --git a/nixite/default.nix b/nixite/default.nix index bd111bf..c258162 100644 --- a/nixite/default.nix +++ b/nixite/default.nix @@ -7,4 +7,5 @@ html = import ./html.nix; elems = import ./elems.nix; site = import ./site.nix; + style = import ./style.nix; } diff --git a/nixite/html.nix b/nixite/html.nix index 79b52d4..4c780b4 100644 --- a/nixite/html.nix +++ b/nixite/html.nix @@ -8,11 +8,11 @@ rec { writeAttrs = attrs: toString (builtins.attrValues ( - builtins.mapAttrs (key: value: ''${key}="${value}"'') attrs + builtins.mapAttrs (key: value: ''${key}="${toString value}"'') attrs )); tag = tag: attrs: child: { - inherit tag child attrs; + inherit tag attrs child; __toString = toHTML; }; diff --git a/nixite/style.nix b/nixite/style.nix new file mode 100644 index 0000000..a434d8c --- /dev/null +++ b/nixite/style.nix @@ -0,0 +1,39 @@ +let + html = import ./html.nix; + + join = { + __functor = self: new: self // new // + { style = self.style + new.style; }; + }; + + mkStyle = identifier: styles: '' + ${identifier} { + ${toString (builtins.attrValues ( + builtins.mapAttrs (key: value: + ''${key}: ${value};'' + ) styles + ))} + } + ''; + + mkIdentifier = tag: { class ? [], id ? "", ... }: "${tag}" + + builtins.concatStringsSep "" (map (c: "." + c) class) + + ( if id != "" then "#" else "" ) + id; + +in +{ + styled = name: tag: cprops: styles: { + + ${name} = props: child: + (html.tag tag (props // cprops) child); + + style = mkStyle (mkIdentifier tag cprops) styles; + + } // join; + + style = identifier: styles: { + + style = mkStyle identifier styles; + + } // join; +} diff --git a/testing/html.test.nix b/testing/html.test.nix index e4b2448..8a72ca2 100644 --- a/testing/html.test.nix +++ b/testing/html.test.nix @@ -13,6 +13,11 @@ in }; }) + (it "concatinates classes" { + actual = toString (tag "p" {class = ["class1" "class2"];} "Hello"); + expected = ''
Hello
''; + }) + (it "applies style" (let page = tag "html" {} [(tag "head" {} ["foo"])]; in { diff --git a/testing/style.test.nix b/testing/style.test.nix new file mode 100644 index 0000000..bbb5880 --- /dev/null +++ b/testing/style.test.nix @@ -0,0 +1,64 @@ +let + style = import ../nixite/style.nix; + html = import ../nixite/html.nix; + it = import ./it.nix; + + my = + (style.styled "p" "p" {} { + some-style = "some value"; + }) + (style.styled "div" "div" { class = ["something"]; } { + this = "that"; + }) + (style.styled "s" "div" { id = "s"; class = ["something"]; } { + s = "yes"; + }) + (style.styled "foobar" "div" { class = ["foo" "bar"]; } { + something = "something"; + }) + (style.style "body" { + foo = "bar"; + }); + +in [ + (it "makes a p component" ({ + expected = (html.tag "p" {} "yes"); + actual = my.p {} "yes"; + })) + (it "makes a component" ({ + expected = (html.tag "div" { class = ["something"]; } "foobar"); + actual = my.div {} "foobar"; + })) + (it "makes special components" ({ + expected = (html.tag "div" { id = "s"; class = ["something"]; } "foobar"); + actual = my.s {} "foobar"; + })) + (it "works on many classes" ({ + expected = (html.tag "div" { class = ["foo" "bar"]; } "foobar"); + actual = my.foobar {} "foobar"; + })) + (it "combines attrs" ({ + expected = (html.tag "div" { id = "foo"; class = ["something"]; } "foobar"); + actual = my.div { id = "foo"; } "foobar"; + })) + (it "makes a style" ({ + expected = '' + p { + some-style: some value; + } + div.something { + this: that; + } + div.something#s { + s: yes; + } + div.foo.bar { + something: something; + } + body { + foo: bar; + } + ''; + actual = my.style; + })) + ]