styled components

This commit is contained in:
tristan 2023-12-31 03:08:05 +00:00
parent 24cfbe8727
commit ff2f68c907
6 changed files with 118 additions and 7 deletions

View file

@ -17,16 +17,17 @@
elems = nixite.elems; elems = nixite.elems;
site = nixite.site; site = nixite.site;
md = nixite.md; md = nixite.md;
style = nixite.style;
packages.${system} = { packages.${system} = {
default = with self; default =
mkSite (site.applyStyle ./testing/src/style.css { nixite.mkSite (nixite.site.applyStyle ./testing/src/style.css {
"index.html" = with elems; (doc "index.html" = with nixite.elems; (doc
[ [
(title "Nixite") (title "Nixite")
] ]
(main [ (main [
(md.readMd ./testing/src/index.md) (nixite.md.readMd ./testing/src/index.md)
(link "/blog" "blog") (link "/blog" "blog")
(list [ (list [
"item 1" "item 1"
@ -35,7 +36,7 @@
]) ])
])); ]));
blog = { blog = {
"index.html" = with elems; (doc "index.html" = with nixite.elems; (doc
[ [
(title "A post") (title "A post")
] ]
@ -58,6 +59,7 @@
${test ./testing/html.test.nix} ${test ./testing/html.test.nix}
${test ./testing/elems.test.nix} ${test ./testing/elems.test.nix}
${test ./testing/site.test.nix} ${test ./testing/site.test.nix}
${test ./testing/style.test.nix}
''; '';
}; };
}; };

View file

@ -7,4 +7,5 @@
html = import ./html.nix; html = import ./html.nix;
elems = import ./elems.nix; elems = import ./elems.nix;
site = import ./site.nix; site = import ./site.nix;
style = import ./style.nix;
} }

View file

@ -8,11 +8,11 @@ rec {
writeAttrs = attrs: writeAttrs = attrs:
toString (builtins.attrValues ( toString (builtins.attrValues (
builtins.mapAttrs (key: value: ''${key}="${value}"'') attrs builtins.mapAttrs (key: value: ''${key}="${toString value}"'') attrs
)); ));
tag = tag: attrs: child: { tag = tag: attrs: child: {
inherit tag child attrs; inherit tag attrs child;
__toString = toHTML; __toString = toHTML;
}; };

39
nixite/style.nix Normal file
View file

@ -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;
}

View file

@ -13,6 +13,11 @@ in
}; };
}) })
(it "concatinates classes" {
actual = toString (tag "p" {class = ["class1" "class2"];} "Hello");
expected = ''<p class="class1 class2">Hello</p>'';
})
(it "applies style" (let (it "applies style" (let
page = tag "html" {} [(tag "head" {} ["foo"])]; page = tag "html" {} [(tag "head" {} ["foo"])];
in { in {

64
testing/style.test.nix Normal file
View file

@ -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;
}))
]