Merge pull request 'coporate color system: init' (#388) from feat/corp-theme into main
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
./clan-cli/flake-module.nix
|
||||
./installer/flake-module.nix
|
||||
./ui/flake-module.nix
|
||||
./theme/flake-module.nix
|
||||
];
|
||||
|
||||
perSystem = { pkgs, config, ... }: {
|
||||
|
||||
3
pkgs/theme/.editorconfig
Normal file
3
pkgs/theme/.editorconfig
Normal file
@@ -0,0 +1,3 @@
|
||||
[*.{js,jsx,ts,tsx,json}]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
12
pkgs/theme/.envrc
Normal file
12
pkgs/theme/.envrc
Normal file
@@ -0,0 +1,12 @@
|
||||
# Because we depend on nixpkgs sources, uploading to builders takes a long time
|
||||
|
||||
source_up
|
||||
|
||||
files=(flake-module.nix package.json package-lock.json)
|
||||
if type nix_direnv_watch_file &>/dev/null; then
|
||||
nix_direnv_watch_file "${files[@]}"
|
||||
else
|
||||
watch_file "${files[@]}"
|
||||
fi
|
||||
|
||||
use flake .#theme --builders ''
|
||||
43
pkgs/theme/.gitignore
vendored
Normal file
43
pkgs/theme/.gitignore
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# nix
|
||||
.floco
|
||||
src/fonts
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# next.js
|
||||
/.next/
|
||||
/out/
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
*.pem
|
||||
|
||||
# debug
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# local env files
|
||||
.env*.local
|
||||
|
||||
# vercel
|
||||
.vercel
|
||||
|
||||
# typescript
|
||||
*.tsbuildinfo
|
||||
next-env.d.ts
|
||||
|
||||
# Generated api code
|
||||
openapi.json
|
||||
api/
|
||||
41
pkgs/theme/default.nix
Normal file
41
pkgs/theme/default.nix
Normal file
@@ -0,0 +1,41 @@
|
||||
{ floco
|
||||
, system
|
||||
, pkgs
|
||||
, clanPkgs
|
||||
}:
|
||||
let
|
||||
|
||||
lib = floco.lib;
|
||||
|
||||
pjs =
|
||||
let
|
||||
msg = "default.nix: Expected to find `package.json' to lookup " +
|
||||
"package name/version, but no such file exists at: " +
|
||||
(toString ./package.json);
|
||||
in
|
||||
if builtins.pathExists ./package.json then lib.importJSON ./package.json
|
||||
else throw msg;
|
||||
ident = pjs.name;
|
||||
inherit (pjs) version;
|
||||
|
||||
|
||||
fmod = lib.evalModules {
|
||||
modules = [
|
||||
floco.nixosModules.floco
|
||||
{ config.floco.settings = { inherit system; basedir = ./.; }; }
|
||||
./nix/floco-cfg.nix
|
||||
];
|
||||
specialArgs = {
|
||||
inherit pkgs clanPkgs;
|
||||
};
|
||||
};
|
||||
|
||||
# This attrset holds a few derivations related to our package.
|
||||
# We'll expose these below to the CLI.
|
||||
pkg = fmod.config.floco.packages.${ident}.${version};
|
||||
|
||||
|
||||
in
|
||||
{
|
||||
inherit pkg fmod;
|
||||
}
|
||||
18
pkgs/theme/flake-module.nix
Normal file
18
pkgs/theme/flake-module.nix
Normal file
@@ -0,0 +1,18 @@
|
||||
{ self, ... }:
|
||||
{
|
||||
perSystem = { self', pkgs, ... }:
|
||||
let
|
||||
inherit (self.inputs) floco;
|
||||
base = pkgs.callPackage ./default.nix { inherit floco; clanPkgs = self'.packages; };
|
||||
in
|
||||
{
|
||||
packages = {
|
||||
theme = base.pkg.global;
|
||||
};
|
||||
devShells.theme = pkgs.callPackage ./shell.nix {
|
||||
inherit pkgs;
|
||||
inherit (base) fmod pkg;
|
||||
clanPkgs = self'.packages;
|
||||
};
|
||||
};
|
||||
}
|
||||
962
pkgs/theme/index.html
Normal file
962
pkgs/theme/index.html
Normal file
@@ -0,0 +1,962 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<meta charset="UTF-8" />
|
||||
<title>Page Title</title>
|
||||
<style></style>
|
||||
<body>
|
||||
<div
|
||||
style="
|
||||
display: grid;
|
||||
grid-template-columns: repeat(13, minmax(0, 1fr));
|
||||
gap: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
"
|
||||
>
|
||||
<div
|
||||
style="
|
||||
background-color: #000000;
|
||||
color: #fff;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
neutral0
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #1f1926;
|
||||
color: #fff;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
neutral10
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #342e3c;
|
||||
color: #fff;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
neutral20
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #4b4453;
|
||||
color: #fff;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
neutral30
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #635b6b;
|
||||
color: #fff;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
neutral40
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #7d7485;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
neutral50
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #807788;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
neutral51
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #978d9f;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
neutral60
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #b2a7ba;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
neutral70
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #cec2d5;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
neutral80
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #eadef2;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
neutral90
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #fff7ff;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
neutral98
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #ffffff;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
neutral100
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
display: grid;
|
||||
grid-template-columns: repeat(13, minmax(0, 1fr));
|
||||
gap: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
"
|
||||
>
|
||||
<div
|
||||
style="
|
||||
background-color: #000000;
|
||||
color: #fff;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
red0
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #410006;
|
||||
color: #fff;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
red10
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #680010;
|
||||
color: #fff;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
red20
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #93001a;
|
||||
color: #fff;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
red30
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #bf0026;
|
||||
color: #fff;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
red40
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #e82439;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
red50
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #ff5358;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
red60
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #ff8986;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
red70
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #ffb3b0;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
red80
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #ffdad8;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
red90
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #ffedeb;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
red95
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #ffffff;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
red100
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
display: grid;
|
||||
grid-template-columns: repeat(13, minmax(0, 1fr));
|
||||
gap: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
"
|
||||
>
|
||||
<div
|
||||
style="
|
||||
background-color: #000000;
|
||||
color: #fff;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
green0
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #0f2000;
|
||||
color: #fff;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
green10
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #1d3700;
|
||||
color: #fff;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
green20
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #2d5000;
|
||||
color: #fff;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
green30
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #3d6a00;
|
||||
color: #fff;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
green40
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #4e8500;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
green50
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #60a100;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
green60
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #74be11;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
green70
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #7ac51b;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
green72
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #8edb34;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
green80
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #a9f850;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
green90
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #efffd8;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
green98
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #ffffff;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
green100
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
display: grid;
|
||||
grid-template-columns: repeat(13, minmax(0, 1fr));
|
||||
gap: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
"
|
||||
>
|
||||
<div
|
||||
style="
|
||||
background-color: #000000;
|
||||
color: #fff;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
yellow0
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #1d1d00;
|
||||
color: #fff;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
yellow10
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #323200;
|
||||
color: #fff;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
yellow20
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #494900;
|
||||
color: #fff;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
yellow30
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #626200;
|
||||
color: #fff;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
yellow40
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #7b7b00;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
yellow50
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #969600;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
yellow60
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #b1b100;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
yellow70
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #cdcd00;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
yellow80
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #e0e01f;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
yellow87
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #eaea2c;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
yellow90
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #fffeac;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
yellow98
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #ffffff;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
yellow100
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
display: grid;
|
||||
grid-template-columns: repeat(13, minmax(0, 1fr));
|
||||
gap: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
"
|
||||
>
|
||||
<div
|
||||
style="
|
||||
background-color: #000000;
|
||||
color: #fff;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
purple0
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #270057;
|
||||
color: #fff;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
purple10
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #42008a;
|
||||
color: #fff;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
purple20
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #5e07bd;
|
||||
color: #fff;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
purple30
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #661bc5;
|
||||
color: #fff;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
purple33
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #7734d6;
|
||||
color: #fff;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
purple40
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #9152f1;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
purple50
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #a974ff;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
purple60
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #bf98ff;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
purple70
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #d5baff;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
purple80
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #ecdcff;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
purple90
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #ffffff;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
purple100
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
display: grid;
|
||||
grid-template-columns: repeat(13, minmax(0, 1fr));
|
||||
gap: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
"
|
||||
>
|
||||
<div
|
||||
style="
|
||||
background-color: #000000;
|
||||
color: #fff;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
blue0
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #001d36;
|
||||
color: #fff;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
blue10
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #003258;
|
||||
color: #fff;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
blue20
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #00497c;
|
||||
color: #fff;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
blue30
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #0061a3;
|
||||
color: #fff;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
blue40
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #1b7ac5;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
blue50
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #4395e2;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
blue60
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #62b0fe;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
blue70
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #9ecaff;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
blue80
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #d1e4ff;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
blue90
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #e9f1ff;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
blue95
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background-color: #ffffff;
|
||||
color: #000;
|
||||
height: 10rem;
|
||||
border: solid 1px grey;
|
||||
display: grid;
|
||||
place-items: end;
|
||||
"
|
||||
>
|
||||
blue100
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
26
pkgs/theme/nix/floco-cfg.nix
Normal file
26
pkgs/theme/nix/floco-cfg.nix
Normal file
@@ -0,0 +1,26 @@
|
||||
# ============================================================================ #
|
||||
#
|
||||
# Aggregates configs making them available to `default.nix', `flake.nix',
|
||||
# or other projects that want to consume this module/package as a dependency.
|
||||
#
|
||||
# ---------------------------------------------------------------------------- #
|
||||
{
|
||||
_file = "theme/nix/floco-cfg.nix";
|
||||
imports =
|
||||
let
|
||||
ifExist = builtins.filter builtins.pathExists [
|
||||
./pdefs.nix # Generated `pdefs.nix'
|
||||
./foverrides.nix # Explicit config
|
||||
];
|
||||
in
|
||||
ifExist
|
||||
++ [
|
||||
|
||||
];
|
||||
}
|
||||
# ---------------------------------------------------------------------------- #
|
||||
#
|
||||
#
|
||||
#
|
||||
# ============================================================================ #
|
||||
|
||||
12
pkgs/theme/nix/foverrides.nix
Normal file
12
pkgs/theme/nix/foverrides.nix
Normal file
@@ -0,0 +1,12 @@
|
||||
{ lib, config, ... }:
|
||||
let
|
||||
pjs = lib.importJSON ../package.json;
|
||||
ident = pjs.name;
|
||||
inherit (pjs) version;
|
||||
in
|
||||
{
|
||||
config.floco.packages.${ident}.${version} =
|
||||
{
|
||||
source = lib.libfloco.cleanLocalSource ../.;
|
||||
};
|
||||
}
|
||||
90
pkgs/theme/nix/pdefs.nix
Normal file
90
pkgs/theme/nix/pdefs.nix
Normal file
@@ -0,0 +1,90 @@
|
||||
{
|
||||
floco = {
|
||||
pdefs = {
|
||||
"@clan/colors" = {
|
||||
"1.0.0" = {
|
||||
depInfo = {
|
||||
"@material/material-color-utilities" = {
|
||||
descriptor = "^0.2.6";
|
||||
pin = "0.2.7";
|
||||
};
|
||||
"@types/node" = {
|
||||
descriptor = "^20.3.2";
|
||||
pin = "20.8.2";
|
||||
};
|
||||
typescript = {
|
||||
descriptor = "^5.1.5";
|
||||
pin = "5.2.2";
|
||||
};
|
||||
};
|
||||
fetchInfo = "path:..";
|
||||
ident = "@clan/colors";
|
||||
lifecycle = {
|
||||
build = true;
|
||||
};
|
||||
ltype = "dir";
|
||||
treeInfo = {
|
||||
"node_modules/@material/material-color-utilities" = {
|
||||
dev = true;
|
||||
key = "@material/material-color-utilities/0.2.7";
|
||||
};
|
||||
"node_modules/@types/node" = {
|
||||
dev = true;
|
||||
key = "@types/node/20.8.2";
|
||||
};
|
||||
"node_modules/typescript" = {
|
||||
dev = true;
|
||||
key = "typescript/5.2.2";
|
||||
};
|
||||
};
|
||||
version = "1.0.0";
|
||||
};
|
||||
};
|
||||
"@material/material-color-utilities" = {
|
||||
"0.2.7" = {
|
||||
fetchInfo = {
|
||||
narHash = "sha256-hRYXqtkoXHoB30v1hstWz7dO7dNeBb6EJqZG66hHi94=";
|
||||
type = "tarball";
|
||||
url = "https://registry.npmjs.org/@material/material-color-utilities/-/material-color-utilities-0.2.7.tgz";
|
||||
};
|
||||
ident = "@material/material-color-utilities";
|
||||
ltype = "file";
|
||||
treeInfo = { };
|
||||
version = "0.2.7";
|
||||
};
|
||||
};
|
||||
"@types/node" = {
|
||||
"20.8.2" = {
|
||||
fetchInfo = {
|
||||
narHash = "sha256-o4hyob1kLnm0OE8Rngm0d6XJxobpMlYSoquusktmLPk=";
|
||||
type = "tarball";
|
||||
url = "https://registry.npmjs.org/@types/node/-/node-20.8.2.tgz";
|
||||
};
|
||||
ident = "@types/node";
|
||||
ltype = "file";
|
||||
treeInfo = { };
|
||||
version = "20.8.2";
|
||||
};
|
||||
};
|
||||
typescript = {
|
||||
"5.2.2" = {
|
||||
binInfo = {
|
||||
binPairs = {
|
||||
tsc = "bin/tsc";
|
||||
tsserver = "bin/tsserver";
|
||||
};
|
||||
};
|
||||
fetchInfo = {
|
||||
narHash = "sha256-io9rXH9RLRLB0484ZdvcqblLQquLFUBGxDuwSixWxus=";
|
||||
type = "tarball";
|
||||
url = "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz";
|
||||
};
|
||||
ident = "typescript";
|
||||
ltype = "file";
|
||||
treeInfo = { };
|
||||
version = "5.2.2";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
63
pkgs/theme/package-lock.json
generated
Normal file
63
pkgs/theme/package-lock.json
generated
Normal file
@@ -0,0 +1,63 @@
|
||||
{
|
||||
"name": "@clan/colors",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@clan/colors",
|
||||
"version": "1.0.0",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"@material/material-color-utilities": "^0.2.6",
|
||||
"@types/node": "^20.3.2",
|
||||
"typescript": "^5.1.5"
|
||||
}
|
||||
},
|
||||
"node_modules/@material/material-color-utilities": {
|
||||
"version": "0.2.7",
|
||||
"resolved": "https://registry.npmjs.org/@material/material-color-utilities/-/material-color-utilities-0.2.7.tgz",
|
||||
"integrity": "sha512-0FCeqG6WvK4/Cc06F/xXMd/pv4FeisI0c1tUpBbfhA2n9Y8eZEv4Karjbmf2ZqQCPUWMrGp8A571tCjizxoTiQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "20.8.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.2.tgz",
|
||||
"integrity": "sha512-Vvycsc9FQdwhxE3y3DzeIxuEJbWGDsnrxvMADzTDF/lcdR9/K+AQIeAghTQsHtotg/q0j3WEOYS/jQgSdWue3w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.2.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
|
||||
"integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.17"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@material/material-color-utilities": {
|
||||
"version": "0.2.7",
|
||||
"resolved": "https://registry.npmjs.org/@material/material-color-utilities/-/material-color-utilities-0.2.7.tgz",
|
||||
"integrity": "sha512-0FCeqG6WvK4/Cc06F/xXMd/pv4FeisI0c1tUpBbfhA2n9Y8eZEv4Karjbmf2ZqQCPUWMrGp8A571tCjizxoTiQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "20.8.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.2.tgz",
|
||||
"integrity": "sha512-Vvycsc9FQdwhxE3y3DzeIxuEJbWGDsnrxvMADzTDF/lcdR9/K+AQIeAghTQsHtotg/q0j3WEOYS/jQgSdWue3w==",
|
||||
"dev": true
|
||||
},
|
||||
"typescript": {
|
||||
"version": "5.2.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
|
||||
"integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
}
|
||||
23
pkgs/theme/package.json
Normal file
23
pkgs/theme/package.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "@clan/colors",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"type": "module",
|
||||
"files": [
|
||||
"colors.json"
|
||||
],
|
||||
"scripts": {
|
||||
"typecheck": "./node_modules/.bin/tsc -p ./tsconfig.json --noEmit",
|
||||
"build": "tsc --build --clean && tsc && node ./build/main.js",
|
||||
"html": "tsc --build --clean && tsc && node ./build/generate.js",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"@material/material-color-utilities": "^0.2.6",
|
||||
"typescript": "^5.1.5",
|
||||
"@types/node": "^20.3.2"
|
||||
}
|
||||
}
|
||||
24
pkgs/theme/shell.nix
Normal file
24
pkgs/theme/shell.nix
Normal file
@@ -0,0 +1,24 @@
|
||||
{ fmod
|
||||
, pkg
|
||||
, pkgs
|
||||
, clanPkgs
|
||||
}:
|
||||
pkgs.mkShell {
|
||||
buildInputs = [
|
||||
fmod.config.floco.settings.nodePackage
|
||||
];
|
||||
shellHook = ''
|
||||
ID=${pkg.built.tree}
|
||||
currID=$(cat .floco/.node_modules_id 2> /dev/null)
|
||||
|
||||
mkdir -p .floco
|
||||
if [[ "$ID" != "$currID" || ! -d "node_modules" ]];
|
||||
then
|
||||
${pkgs.rsync}/bin/rsync -a --chmod=ug+w --delete ${pkg.built.tree}/node_modules/ ./node_modules/
|
||||
echo -n $ID > .floco/.node_modules_id
|
||||
echo "floco ok: node_modules updated"
|
||||
fi
|
||||
|
||||
export PATH="$PATH:$(realpath ./node_modules)/.bin"
|
||||
'';
|
||||
}
|
||||
1507
pkgs/theme/src/colors.json
Normal file
1507
pkgs/theme/src/colors.json
Normal file
File diff suppressed because it is too large
Load Diff
78
pkgs/theme/src/config.ts
Normal file
78
pkgs/theme/src/config.ts
Normal file
@@ -0,0 +1,78 @@
|
||||
import { AliasMap, BaseColors, HexString } from "./types.js";
|
||||
|
||||
export type PaletteConfig = {
|
||||
baseColors: BaseColors;
|
||||
tones: number[];
|
||||
aliases: AliasMap<"primary" | "secondary" | "error">;
|
||||
common: {
|
||||
// Black and white is always constant
|
||||
// We declare this on the type level
|
||||
white: "#ffffff";
|
||||
black: "#000000";
|
||||
// Some other color constants/reservation
|
||||
[id: string]: HexString;
|
||||
};
|
||||
};
|
||||
|
||||
export const config: PaletteConfig = {
|
||||
/** All color shades that are available
|
||||
* This colors are used as "key colors" to generate a tonal palette from 0 to 100
|
||||
* Steps are defined in 'tones'
|
||||
*/
|
||||
baseColors: {
|
||||
neutral: {
|
||||
keyColor: "#807788",
|
||||
tones: [98],
|
||||
},
|
||||
red: {
|
||||
keyColor: "#e82439",
|
||||
tones: [95],
|
||||
},
|
||||
green: {
|
||||
keyColor: "#7AC51B",
|
||||
tones: [98],
|
||||
},
|
||||
yellow: {
|
||||
keyColor: "#E0E01F",
|
||||
tones: [98],
|
||||
},
|
||||
purple: {
|
||||
keyColor: "#661bc5",
|
||||
tones: [],
|
||||
},
|
||||
blue: {
|
||||
keyColor: "#1B7AC5",
|
||||
tones: [95],
|
||||
},
|
||||
},
|
||||
|
||||
/** Common tones to generate out of all the baseColors
|
||||
* number equals to the amount of light present in the color (HCT Color Space)
|
||||
*/
|
||||
tones: [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100],
|
||||
|
||||
/** create aliases from the color palette
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* primary: "blue"
|
||||
* ->
|
||||
* ...
|
||||
* primary40 -> blue40
|
||||
* primary50 -> blue50
|
||||
* ...
|
||||
*/
|
||||
aliases: {
|
||||
primary: "purple",
|
||||
secondary: "green",
|
||||
error: "red",
|
||||
},
|
||||
/** some color names are reserved
|
||||
* typically those colors do not change when switching theme
|
||||
* or are other types of constant in the UI
|
||||
*/
|
||||
common: {
|
||||
white: "#ffffff",
|
||||
black: "#000000",
|
||||
},
|
||||
};
|
||||
46
pkgs/theme/src/generate.ts
Normal file
46
pkgs/theme/src/generate.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { writeFile } from "fs";
|
||||
import palette from "./colors.json" assert { type: "json" };
|
||||
import { config } from "./config.js";
|
||||
|
||||
type PaletteFile = typeof palette;
|
||||
|
||||
const html = (palette: PaletteFile): string => {
|
||||
const colors = Object.keys(config.baseColors).map((baseName) => {
|
||||
const colors = Object.entries(palette.ref.palette)
|
||||
.filter(([name, _]) => name.includes(baseName))
|
||||
.sort((a, b) => {
|
||||
return a[1].meta.color.shade - b[1].meta.color.shade;
|
||||
})
|
||||
.map(([key, color]) => {
|
||||
console.log({ key, color });
|
||||
return `<div style="background-color:${color.value}; color:${
|
||||
color.meta.color.shade < 48 ? "#fff" : "#000"
|
||||
}; height: 10rem; border:solid 1px grey; display:grid; place-items:end;">${key}</div>`;
|
||||
});
|
||||
return `<div style="display: grid; grid-template-columns: repeat(${13}, minmax(0, 1fr)); gap: 1rem; margin-bottom: 1rem">${colors.join(
|
||||
"\n",
|
||||
)}</div>`;
|
||||
});
|
||||
|
||||
return `<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<meta charset="UTF-8">
|
||||
<title>Page Title</title>
|
||||
<style>
|
||||
</style>
|
||||
<body>
|
||||
|
||||
${colors.join("\n")}
|
||||
|
||||
</body>
|
||||
</html>
|
||||
`;
|
||||
};
|
||||
|
||||
writeFile("index.html", html(palette), (err) => {
|
||||
if (err) {
|
||||
console.error({ err });
|
||||
} else {
|
||||
console.log("Exported colors to html");
|
||||
}
|
||||
});
|
||||
182
pkgs/theme/src/main.ts
Normal file
182
pkgs/theme/src/main.ts
Normal file
@@ -0,0 +1,182 @@
|
||||
#!usr/bin/node
|
||||
import * as fs from "fs";
|
||||
import {
|
||||
argbFromHex,
|
||||
Hct,
|
||||
hexFromArgb,
|
||||
} from "@material/material-color-utilities";
|
||||
import {
|
||||
AliasTokenMap,
|
||||
ColorDesignToken,
|
||||
ColorSet,
|
||||
HexString,
|
||||
RefTokenSystem,
|
||||
TonalPalette,
|
||||
TonalPaletteConfig,
|
||||
TonalPaletteItem,
|
||||
} from "./types.js";
|
||||
import { config } from "./config.js";
|
||||
|
||||
const { baseColors, tones, aliases, common } = config;
|
||||
|
||||
/** Takes a color, tone and name
|
||||
* If a tone is given adjust the lightning level accordingly
|
||||
*
|
||||
* @returns TonalPaletteItem (meta wrapper around HCT)
|
||||
*/
|
||||
const getTonalPaletteItem = (
|
||||
value: HexString,
|
||||
name: string,
|
||||
tone?: number,
|
||||
): TonalPaletteItem => {
|
||||
const aRGB = argbFromHex(value);
|
||||
const color = Hct.fromInt(aRGB);
|
||||
if (tone !== undefined) {
|
||||
color.tone = tone;
|
||||
}
|
||||
return {
|
||||
shade: color.tone,
|
||||
name: `${name || color.chroma}${Math.round(color.tone)}`,
|
||||
baseName: name,
|
||||
value: color,
|
||||
};
|
||||
};
|
||||
|
||||
/** create a flat list of the cross product from all colors and all tones.
|
||||
*
|
||||
* every color is mapped in the range from 0 to 100
|
||||
* with the steps configure in `config.tones'
|
||||
* additionally the key color is added unmodified
|
||||
* lightning levels are rounded to the next natural number to form the 'name'
|
||||
* Example:
|
||||
*
|
||||
* "blue" x [20.1, 30.3]
|
||||
* ->
|
||||
* [blue20, blue30]
|
||||
*/
|
||||
const mkTonalPalette =
|
||||
(config: TonalPaletteConfig) =>
|
||||
(name: string) =>
|
||||
(keyTone: HexString): TonalPalette => {
|
||||
const { tones } = config;
|
||||
const aRGB = argbFromHex(keyTone);
|
||||
const HctColor = Hct.fromInt(aRGB);
|
||||
const roundedTone = Math.round(HctColor.tone * 100) / 100;
|
||||
|
||||
const localTones = [...tones, roundedTone];
|
||||
|
||||
return localTones.map((t) => getTonalPaletteItem(keyTone, name, t));
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts a PaletteItem into a hex color. (Wrapped)
|
||||
* Adding meta attributes which avoids any information loss.
|
||||
*/
|
||||
const toDesignTokenContent = (color: TonalPaletteItem): ColorDesignToken => {
|
||||
const { value } = color;
|
||||
return {
|
||||
type: "color",
|
||||
value: hexFromArgb(value.toInt()),
|
||||
meta: {
|
||||
color,
|
||||
date: new Date(),
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const color: ColorSet = Object.entries(baseColors)
|
||||
.map(([name, baseColor]) => ({
|
||||
name,
|
||||
baseColor,
|
||||
tones: mkTonalPalette({
|
||||
tones: [...tones, ...baseColor.tones].sort((a, b) => a - b),
|
||||
})(name)(baseColor.keyColor),
|
||||
}))
|
||||
.reduce((acc, curr) => {
|
||||
let currTones = curr.tones.reduce(
|
||||
(o, v) => ({
|
||||
...o,
|
||||
[v.name]: toDesignTokenContent(v),
|
||||
}),
|
||||
{},
|
||||
);
|
||||
return {
|
||||
...acc,
|
||||
...currTones,
|
||||
};
|
||||
}, {});
|
||||
|
||||
/** Generate a set of tokens from a given alias mapping
|
||||
*
|
||||
* @param alias A string e.g. Primary -> Blue (Primary is the alias)
|
||||
* @param name A string; Basename of the referenced value (e.g. Blue)
|
||||
* @param colors A set of colors
|
||||
* @returns All aliases from the given color set
|
||||
*/
|
||||
function resolveAlias(
|
||||
alias: string,
|
||||
name: string,
|
||||
colors: ColorSet,
|
||||
): AliasTokenMap {
|
||||
// All colors from the color map belonging to that single alias
|
||||
// Example:
|
||||
// Primary -> "blue"
|
||||
// =>
|
||||
// [ (blue0) , (blue10) , ..., (blue100) ]
|
||||
const all = Object.values(colors)
|
||||
.filter((n) => n.meta.color.name.includes(name))
|
||||
.filter((n) => !n.meta.color.name.includes("."));
|
||||
|
||||
const tokens = all
|
||||
.map((shade) => {
|
||||
const shadeNumber = shade.meta.color.shade;
|
||||
return {
|
||||
name: `${alias}${Math.round(shadeNumber)}`,
|
||||
value: { value: `{ref.palette.${shade.meta.color.name}}` },
|
||||
// propagate the meta attribute of the actual value
|
||||
meta: shade.meta,
|
||||
};
|
||||
})
|
||||
// sort by tone
|
||||
.sort((a, b) => a.meta.color.value.tone - b.meta.color.value.tone)
|
||||
.reduce((acc, { name, value }) => ({ ...acc, [name]: value }), {});
|
||||
return tokens;
|
||||
}
|
||||
|
||||
const aliasMap = Object.entries(aliases).reduce(
|
||||
(prev, [key, value]) => ({
|
||||
...prev,
|
||||
...resolveAlias(key, value, color),
|
||||
}),
|
||||
{},
|
||||
);
|
||||
|
||||
const commonColors = Object.entries(common)
|
||||
.map(([name, value]) =>
|
||||
toDesignTokenContent(getTonalPaletteItem(value, name)),
|
||||
)
|
||||
.reduce(
|
||||
(acc, val) => ({ ...acc, [val.meta.color.baseName]: val }),
|
||||
{},
|
||||
) as ColorSet;
|
||||
|
||||
const toPaletteToken = (color: ColorSet): RefTokenSystem => ({
|
||||
ref: {
|
||||
palette: color,
|
||||
alias: aliasMap,
|
||||
common: commonColors,
|
||||
},
|
||||
});
|
||||
|
||||
// Dump tokens to json file
|
||||
fs.writeFile(
|
||||
"colors.json",
|
||||
JSON.stringify(toPaletteToken(color), null, 2),
|
||||
(err) => {
|
||||
if (err) {
|
||||
console.error({ err });
|
||||
} else {
|
||||
console.log("tokens successfully exported");
|
||||
}
|
||||
},
|
||||
);
|
||||
90
pkgs/theme/src/types.ts
Normal file
90
pkgs/theme/src/types.ts
Normal file
@@ -0,0 +1,90 @@
|
||||
import { Hct } from "@material/material-color-utilities";
|
||||
|
||||
export type BaseColors = {
|
||||
neutral: BaseColor;
|
||||
red: BaseColor;
|
||||
green: BaseColor;
|
||||
yellow: BaseColor;
|
||||
purple: BaseColor;
|
||||
blue: BaseColor;
|
||||
};
|
||||
|
||||
export type BaseColor = {
|
||||
keyColor: HexString;
|
||||
tones: number[];
|
||||
follows?: string;
|
||||
};
|
||||
|
||||
export type ColorSet = { [key: string]: ColorDesignToken };
|
||||
|
||||
/** The resolved alias tokens
|
||||
*
|
||||
* @example
|
||||
* {
|
||||
* primary: "blue"
|
||||
* ...
|
||||
* }
|
||||
*
|
||||
*/
|
||||
export type AliasMap<T extends string> = {
|
||||
[alias in T]: keyof BaseColors;
|
||||
};
|
||||
|
||||
/** The resolved alias tokens
|
||||
*
|
||||
* @example
|
||||
* {
|
||||
* primary0: "blue40"
|
||||
* primary10: "blue40"
|
||||
* ...
|
||||
* primary100: "blue100"
|
||||
* }
|
||||
*
|
||||
* Unfortunately My Typescript skills lack the ability to express this type any narrower :/
|
||||
*/
|
||||
export type AliasTokenMap = {
|
||||
[alias: string]: { value: string };
|
||||
};
|
||||
|
||||
export type TonalPaletteConfig = {
|
||||
tones: number[];
|
||||
};
|
||||
|
||||
export type HexString = string;
|
||||
|
||||
export type TonalPaletteItem = {
|
||||
/**
|
||||
* @example
|
||||
* 20
|
||||
*/
|
||||
shade: number;
|
||||
/**
|
||||
* @example
|
||||
* "blue20"
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* @example
|
||||
* "blue"
|
||||
*/
|
||||
baseName: string;
|
||||
value: Hct;
|
||||
};
|
||||
export type TonalPalette = TonalPaletteItem[];
|
||||
|
||||
export type ColorDesignToken = {
|
||||
type: "color";
|
||||
value: HexString;
|
||||
meta: {
|
||||
color: TonalPaletteItem;
|
||||
date: Date;
|
||||
};
|
||||
};
|
||||
|
||||
export type RefTokenSystem = {
|
||||
ref: {
|
||||
palette: ColorSet;
|
||||
common: ColorSet;
|
||||
alias: AliasTokenMap;
|
||||
};
|
||||
};
|
||||
41
pkgs/theme/tsconfig.json
Normal file
41
pkgs/theme/tsconfig.json
Normal file
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"include": ["src"],
|
||||
"compilerOptions": {
|
||||
"target": "ESNext" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
|
||||
|
||||
"lib": [
|
||||
"ESNext",
|
||||
"dom"
|
||||
] /* Specify a set of bundled library declaration files that describe the target runtime environment. */,
|
||||
"module": "NodeNext" /* Specify what module code is generated. */,
|
||||
"rootDir": "src" /* Specify the root folder within your source files. */,
|
||||
"moduleResolution": "nodenext" /* Specify how TypeScript looks up a file from a given module specifier. */,
|
||||
"resolveJsonModule": true /* Enable importing .json files. */,
|
||||
"outDir": "build",
|
||||
|
||||
"esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
|
||||
|
||||
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
|
||||
|
||||
/* Type Checking */
|
||||
"strict": true /* Enable all strict type-checking options. */,
|
||||
"noImplicitAny": true /* Enable error reporting for expressions and declarations with an implied 'any' type. */,
|
||||
"strictNullChecks": true /* When type checking, take into account 'null' and 'undefined'. */,
|
||||
"strictFunctionTypes": true /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */,
|
||||
"strictBindCallApply": true /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */,
|
||||
"strictPropertyInitialization": true /* Check for class properties that are declared but not set in the constructor. */,
|
||||
"noImplicitThis": true /* Enable error reporting when 'this' is given the type 'any'. */,
|
||||
// "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
|
||||
"alwaysStrict": true /* Ensure 'use strict' is always emitted. */,
|
||||
"noUnusedLocals": true /* Enable error reporting when local variables aren't read. */,
|
||||
"noUnusedParameters": true /* Raise an error when a function parameter isn't read. */,
|
||||
"exactOptionalPropertyTypes": true /* Interpret optional property types as written, rather than adding 'undefined'. */,
|
||||
"noImplicitReturns": true /* Enable error reporting for codepaths that do not explicitly return in a function. */,
|
||||
"noFallthroughCasesInSwitch": true /* Enable error reporting for fallthrough cases in switch statements. */,
|
||||
"noUncheckedIndexedAccess": true /* Add 'undefined' to a type when accessed using an index. */,
|
||||
"noImplicitOverride": true /* Ensure overriding members in derived classes are marked with an override modifier. */,
|
||||
"noPropertyAccessFromIndexSignature": true /* Enforces using indexed accessors for keys declared using an indexed type. */
|
||||
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
|
||||
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
|
||||
}
|
||||
}
|
||||
@@ -2,5 +2,6 @@
|
||||
imports = [
|
||||
./pdefs.nix
|
||||
./foverrides.nix
|
||||
../../theme/nix/floco-cfg.nix
|
||||
];
|
||||
}
|
||||
|
||||
@@ -100,6 +100,12 @@ in
|
||||
optional = false;
|
||||
dev = true;
|
||||
};
|
||||
"node_modules/@clan/colors" = {
|
||||
key = "@clan/colors/1.0.0";
|
||||
link = false;
|
||||
optional = false;
|
||||
dev = true;
|
||||
};
|
||||
};
|
||||
});
|
||||
in
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { createTheme } from "@mui/material/styles";
|
||||
|
||||
import colors from "@clan/colors/colors.json";
|
||||
|
||||
export const darkTheme = createTheme({
|
||||
breakpoints: {
|
||||
values: {
|
||||
@@ -15,6 +17,7 @@ export const darkTheme = createTheme({
|
||||
},
|
||||
});
|
||||
|
||||
const { palette, common } = colors.ref;
|
||||
export const lightTheme = createTheme({
|
||||
breakpoints: {
|
||||
values: {
|
||||
@@ -27,5 +30,27 @@ export const lightTheme = createTheme({
|
||||
},
|
||||
palette: {
|
||||
mode: "light",
|
||||
background: {
|
||||
default: common.white.value,
|
||||
paper: palette.neutral98.value,
|
||||
},
|
||||
primary: {
|
||||
main: palette.green50.value,
|
||||
},
|
||||
secondary: {
|
||||
main: palette.green50.value,
|
||||
},
|
||||
error: {
|
||||
main: palette.red50.value,
|
||||
},
|
||||
warning: {
|
||||
main: palette.yellow50.value,
|
||||
},
|
||||
success: {
|
||||
main: palette.green50.value,
|
||||
},
|
||||
info: {
|
||||
main: palette.red50.value,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user