Merge pull request 'UI: new Loader component; Button and Icon v2' (#3908) from ui/button into main

Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3908
This commit is contained in:
brianmcgee
2025-06-12 15:52:17 +00:00
46 changed files with 4244 additions and 364 deletions

View File

@@ -45,10 +45,10 @@ let
}; };
}; };
firaCode = fetchzip { commitMono = fetchzip {
url = "https://github.com/tonsky/FiraCode/releases/download/6.2/Fira_Code_v6.2.zip"; url = "https://github.com/eigilnikolajsen/commit-mono/releases/download/v1.143/CommitMono-1.143.zip";
stripRoot = false; stripRoot = false;
hash = "sha256-UHOwZL9WpCHk6vZaqI/XfkZogKgycs5lWg1p0XdQt0A="; hash = "sha256-JTyPgWfbWq+lXQU/rgnyvPG6+V3f+FB5QUkd+I1oFKE=";
}; };
in in
@@ -63,5 +63,5 @@ runCommand "" { } ''
cp ${archivoSemi.medium} $out/ArchivoSemiCondensed-Medium.woff2 cp ${archivoSemi.medium} $out/ArchivoSemiCondensed-Medium.woff2
cp ${archivoSemi.semiBold} $out/ArchivoSemiCondensed-SemiBold.woff2 cp ${archivoSemi.semiBold} $out/ArchivoSemiCondensed-SemiBold.woff2
cp ${firaCode}/woff2/FiraCode-Regular.woff2 $out/FiraCode-Regular.woff2 cp ${commitMono}/CommitMono-1.143/CommitMono-400-Regular.otf $out/CommitMono-400-Regular.otf
'' ''

View File

@@ -1,8 +1,8 @@
import type { Preview } from "@kachurun/storybook-solid"; import type { Preview } from "@kachurun/storybook-solid";
import "@/src/components/v2/index.css"; import "@/src/components/v2/index.css";
import "./preview.css";
import "../src/index.css"; import "../src/index.css";
import "./preview.css";
export const preview: Preview = { export const preview: Preview = {
tags: ["autodocs"], tags: ["autodocs"],

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48" fill="none">
<path d="M27 38H6V17H10V13H13.5V9H37.5V13H41V24H27V27H34V31H30.5V34.5H27V38ZM16.5 20.5H20V17H16.5V20.5Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 226 B

View File

@@ -1 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" fill="currentColor"><path d="M36.888 11H41.3v4.413h-4.412zm-4.413 8.825v-4.412h4.413v4.412zm-4.413 4.413v-4.413h4.413v4.413zM23.65 28.65h4.413v-4.412H23.65zm-4.412 4.413h4.412V28.65h-4.412zm-4.413 0v4.412h4.413v-4.413zm-4.412-4.413h4.412v4.413h-4.412zm0 0H6v-4.412h4.413z"/></svg> <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" fill="currentColor">
<path d="M36.888 11H41.3v4.413h-4.412zm-4.413 8.825v-4.412h4.413v4.412zm-4.413 4.413v-4.413h4.413v4.413zM23.65 28.65h4.413v-4.412H23.65zm-4.412 4.413h4.412V28.65h-4.412zm-4.413 0v4.412h4.413v-4.413zm-4.412-4.413h4.412v4.413h-4.412zm0 0H6v-4.412h4.413z"/>
</svg>

Before

Width:  |  Height:  |  Size: 343 B

After

Width:  |  Height:  |  Size: 349 B

View File

@@ -1 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" width="72" height="89" fill="currentColor"><g clip-path="url(#a)"><path d="M57.709 20.105H68.62c1.157 0 2.099-.94 2.099-2.095V9.632a2.1 2.1 0 0 0-2.099-2.095h-3.439c-1.111 0-2.014-.9-2.014-2.01V2.095A2.1 2.1 0 0 0 61.07 0H30.02a2.1 2.1 0 0 0-2.098 2.095v3.432c0 1.11-.903 2.01-2.014 2.01H22.47c-1.157 0-2.098.94-2.098 2.095v3.432c0 1.11-.903 2.01-2.014 2.01h-3.439c-1.157 0-2.099.94-2.099 2.094 0 0-.503-1.272-.503 22.493 0 21.247.503 19.38.503 19.38 0 1.156.942 2.096 2.1 2.096h3.438c1.111 0 2.014.9 2.014 2.01v3.517c0 1.109.902 2.01 2.013 2.01h3.524c1.111 0 2.014.9 2.014 2.01v3.432a2.1 2.1 0 0 0 2.098 2.094h30.211c1.157 0 2.099-.94 2.099-2.094v-3.433c0-1.11.902-2.01 2.013-2.01h5.557c1.158 0 2.099-.94 2.099-2.094v-9.984a2.1 2.1 0 0 0-2.099-2.095h-13.03c-1.157 0-2.098.94-2.098 2.095v5.044c0 1.11-.902 2.01-2.014 2.01H37.488c-1.111 0-2.013-.9-2.013-2.01v-5.11a2.1 2.1 0 0 0-2.099-2.094h-5.119c-1.111 0-1.739.163-2.014-2.01-.085-.698-.13-1.553-.196-2.695-.163-2.878-.307-1.723-.307-10.369 0-12.085.314-15.563.503-17.24.19-1.677.903-2.01 2.014-2.01h5.12c1.156 0 2.098-.94 2.098-2.094v-3.433c0-1.109.902-2.01 2.013-2.01h16.116c1.111 0 2.014.901 2.014 2.01v3.433c0 1.155.94 2.094 2.098 2.094zM18.626 73.757h-2.478a.87.87 0 0 1-.87-.868v-2.473c0-.96-.777-1.743-1.745-1.743H6.838c-.96 0-1.745.777-1.745 1.743v2.473a.87.87 0 0 1-.87.868H1.746c-.961 0-1.746.776-1.746 1.742v6.682c0 .96.778 1.742 1.746 1.742h2.477c.484 0 .87.392.87.868v2.473c0 .96.778 1.743 1.745 1.743h6.695c.961 0 1.746-.777 1.746-1.743v-2.473c0-.483.392-.868.87-.868h2.477c.961 0 1.746-.776 1.746-1.742v-6.682c0-.96-.778-1.742-1.746-1.742"/></g><defs><clipPath id="a"><path d="M0 0h72v89H0z"/></clipPath></defs></svg> <svg xmlns="http://www.w3.org/2000/svg" width="72" height="89" fill="currentColor">
<g clip-path="url(#a)">
<path d="M57.709 20.105H68.62c1.157 0 2.099-.94 2.099-2.095V9.632a2.1 2.1 0 0 0-2.099-2.095h-3.439c-1.111 0-2.014-.9-2.014-2.01V2.095A2.1 2.1 0 0 0 61.07 0H30.02a2.1 2.1 0 0 0-2.098 2.095v3.432c0 1.11-.903 2.01-2.014 2.01H22.47c-1.157 0-2.098.94-2.098 2.095v3.432c0 1.11-.903 2.01-2.014 2.01h-3.439c-1.157 0-2.099.94-2.099 2.094 0 0-.503-1.272-.503 22.493 0 21.247.503 19.38.503 19.38 0 1.156.942 2.096 2.1 2.096h3.438c1.111 0 2.014.9 2.014 2.01v3.517c0 1.109.902 2.01 2.013 2.01h3.524c1.111 0 2.014.9 2.014 2.01v3.432a2.1 2.1 0 0 0 2.098 2.094h30.211c1.157 0 2.099-.94 2.099-2.094v-3.433c0-1.11.902-2.01 2.013-2.01h5.557c1.158 0 2.099-.94 2.099-2.094v-9.984a2.1 2.1 0 0 0-2.099-2.095h-13.03c-1.157 0-2.098.94-2.098 2.095v5.044c0 1.11-.902 2.01-2.014 2.01H37.488c-1.111 0-2.013-.9-2.013-2.01v-5.11a2.1 2.1 0 0 0-2.099-2.094h-5.119c-1.111 0-1.739.163-2.014-2.01-.085-.698-.13-1.553-.196-2.695-.163-2.878-.307-1.723-.307-10.369 0-12.085.314-15.563.503-17.24.19-1.677.903-2.01 2.014-2.01h5.12c1.156 0 2.098-.94 2.098-2.094v-3.433c0-1.109.902-2.01 2.013-2.01h16.116c1.111 0 2.014.901 2.014 2.01v3.433c0 1.155.94 2.094 2.098 2.094zM18.626 73.757h-2.478a.87.87 0 0 1-.87-.868v-2.473c0-.96-.777-1.743-1.745-1.743H6.838c-.96 0-1.745.777-1.745 1.743v2.473a.87.87 0 0 1-.87.868H1.746c-.961 0-1.746.776-1.746 1.742v6.682c0 .96.778 1.742 1.746 1.742h2.477c.484 0 .87.392.87.868v2.473c0 .96.778 1.743 1.745 1.743h6.695c.961 0 1.746-.777 1.746-1.743v-2.473c0-.483.392-.868.87-.868h2.477c.961 0 1.746-.776 1.746-1.742v-6.682c0-.96-.778-1.742-1.746-1.742"/>
</g>
<defs>
<clipPath id="a">
<path d="M0 0h72v89H0z"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -1 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" width="223" height="89" fill="currentColor"><g clip-path="url(#a)"><path d="M55.503 18.696h10.104a1.946 1.946 0 0 0 1.943-1.948v-7.79c0-1.075-.87-1.947-1.943-1.947h-3.186a1.863 1.863 0 0 1-1.866-1.87V1.947C60.555.872 59.685 0 58.612 0h-27.98a1.946 1.946 0 0 0-1.944 1.947v3.194c0 1.036-.832 1.87-1.865 1.87h-3.187a1.946 1.946 0 0 0-1.943 1.947v3.194c0 1.036-.832 1.87-1.866 1.87h-3.186a1.946 1.946 0 0 0-1.943 1.947s-.467 1.153-.467 23.253c0 19.763.467 21.913.467 21.913 0 1.075.87 1.948 1.943 1.948h3.186c1.034 0 1.866.833 1.866 1.87v3.271c0 1.036.831 1.87 1.865 1.87h3.265c1.033 0 1.865.833 1.865 1.87v3.193c0 1.075.87 1.948 1.943 1.948h27.981a1.946 1.946 0 0 0 1.943-1.948v-3.194c0-1.036.832-1.87 1.866-1.87h5.145a1.946 1.946 0 0 0 1.943-1.947v-9.285c0-1.075-.87-1.948-1.943-1.948H55.503a1.946 1.946 0 0 0-1.943 1.948v4.69c0 1.035-.832 1.869-1.866 1.869H37.55a1.863 1.863 0 0 1-1.866-1.87v-4.752c0-1.075-.87-1.947-1.943-1.947H29c-1.034 0-1.609.148-1.865-1.87-.078-.646-.125-1.44-.18-2.508-.147-2.68-.287-5.5-.287-13.539 0-11.24.288-16.81.466-18.369.18-1.558.832-1.87 1.866-1.87h4.741a1.946 1.946 0 0 0 1.943-1.947v-3.193c0-1.037.832-1.87 1.866-1.87h14.145c1.034 0 1.866.833 1.866 1.87v3.193c0 1.075.87 1.948 1.943 1.948M20.247 74.822h-2.293a.814.814 0 0 1-.808-.81v-2.298c0-.896-.723-1.62-1.617-1.62H9.327c-.894 0-1.617.724-1.617 1.62v2.298c0 .444-.365.81-.808.81H4.609c-.894 0-1.617.725-1.617 1.62v6.217c0 .896.723 1.62 1.617 1.62h2.293c.443 0 .808.366.808.81v2.299c0 .895.723 1.62 1.617 1.62h6.202c.894 0 1.617-.725 1.617-1.62v-2.299c0-.444.365-.81.808-.81h2.293c.894 0 1.617-.724 1.617-1.62v-6.216c0-.896-.723-1.62-1.617-1.62M221.135 35.04h-1.71a1.863 1.863 0 0 1-1.866-1.87v-3.272c0-1.036-.831-1.87-1.865-1.87h-3.265a1.863 1.863 0 0 1-1.865-1.87v-3.271c0-1.036-.832-1.87-1.865-1.87h-20.971a1.863 1.863 0 0 0-1.865 1.87v3.965c0 .514-.42.935-.933.935h-3.559c-.513 0-.84-.32-.933-.935l-.622-3.918c-.148-1.099-.676-1.777-1.788-1.777l-3.653-.14h-2.052a3.736 3.736 0 0 0-3.73 3.74V61.68a3.736 3.736 0 0 1-3.731 3.739h-8.394a1.863 1.863 0 0 1-1.866-1.87V36.714c0-11.825-7.461-18.813-22.556-18.813-13.718 0-20.325 5.04-21.203 14.443-.109 1.153.552 1.815 1.702 1.815l7.757.569c1.143.1 1.594-.554 1.811-1.652.77-3.74 4.174-5.827 9.933-5.827 7.081 0 10.042 3.358 10.042 9.076v3.014c0 1.036-.831 1.87-1.865 1.87l-.342-.024h-9.715c-15.421 0-22.984 5.983-22.984 17.956 0 3.802.778 7.058 2.254 9.738h-.59c-1.765-1.27-2.457-2.236-3.055-2.93-.256-.295-.653-.537-1.345-.537h-1.717l-5.993.008h-3.264a3.736 3.736 0 0 1-3.731-3.74V1.769C89.74.654 89.072 0 87.969 0H79.55c-1.034 0-1.865.732-1.865 1.768l-.024 54.304v13.554c0 4.13 3.343 7.479 7.462 7.479h50.84c8.448-.429 8.604-3.42 9.436-4.542.645 3.56 1.865 4.347 4.71 4.518 8.137.117 18.343.032 18.49.024h4.975c4.119 0 6.684-3.35 6.684-7.479l.777-27.264c0-1.036.832-1.87 1.866-1.87h2.021a1.56 1.56 0 0 0 1.554-1.558v-3.583c0-1.036.832-1.87 1.866-1.87h11.868a3.37 3.37 0 0 1 3.366 3.373v3.249c0 1.075.87 1.947 1.943 1.947h4.119c.513 0 .933.42.933.935v32.25c0 1.036.831 1.87 1.865 1.87h6.84a3.736 3.736 0 0 0 3.731-3.74V36.91c0-1.036-.832-1.87-1.866-1.87zM142.64 54.225c0 8.927-6.132 14.715-15.335 14.715-6.606 0-9.793-2.953-9.793-8.748 0-6.442 3.832-9.636 11.62-9.636h13.508v3.669"/></g><defs><clipPath id="a"><path d="M0 0h223v89H0z"/></clipPath></defs></svg> <svg xmlns="http://www.w3.org/2000/svg" width="223" height="89" fill="currentColor">
<g clip-path="url(#a)">
<path d="M55.503 18.696h10.104a1.946 1.946 0 0 0 1.943-1.948v-7.79c0-1.075-.87-1.947-1.943-1.947h-3.186a1.863 1.863 0 0 1-1.866-1.87V1.947C60.555.872 59.685 0 58.612 0h-27.98a1.946 1.946 0 0 0-1.944 1.947v3.194c0 1.036-.832 1.87-1.865 1.87h-3.187a1.946 1.946 0 0 0-1.943 1.947v3.194c0 1.036-.832 1.87-1.866 1.87h-3.186a1.946 1.946 0 0 0-1.943 1.947s-.467 1.153-.467 23.253c0 19.763.467 21.913.467 21.913 0 1.075.87 1.948 1.943 1.948h3.186c1.034 0 1.866.833 1.866 1.87v3.271c0 1.036.831 1.87 1.865 1.87h3.265c1.033 0 1.865.833 1.865 1.87v3.193c0 1.075.87 1.948 1.943 1.948h27.981a1.946 1.946 0 0 0 1.943-1.948v-3.194c0-1.036.832-1.87 1.866-1.87h5.145a1.946 1.946 0 0 0 1.943-1.947v-9.285c0-1.075-.87-1.948-1.943-1.948H55.503a1.946 1.946 0 0 0-1.943 1.948v4.69c0 1.035-.832 1.869-1.866 1.869H37.55a1.863 1.863 0 0 1-1.866-1.87v-4.752c0-1.075-.87-1.947-1.943-1.947H29c-1.034 0-1.609.148-1.865-1.87-.078-.646-.125-1.44-.18-2.508-.147-2.68-.287-5.5-.287-13.539 0-11.24.288-16.81.466-18.369.18-1.558.832-1.87 1.866-1.87h4.741a1.946 1.946 0 0 0 1.943-1.947v-3.193c0-1.037.832-1.87 1.866-1.87h14.145c1.034 0 1.866.833 1.866 1.87v3.193c0 1.075.87 1.948 1.943 1.948M20.247 74.822h-2.293a.814.814 0 0 1-.808-.81v-2.298c0-.896-.723-1.62-1.617-1.62H9.327c-.894 0-1.617.724-1.617 1.62v2.298c0 .444-.365.81-.808.81H4.609c-.894 0-1.617.725-1.617 1.62v6.217c0 .896.723 1.62 1.617 1.62h2.293c.443 0 .808.366.808.81v2.299c0 .895.723 1.62 1.617 1.62h6.202c.894 0 1.617-.725 1.617-1.62v-2.299c0-.444.365-.81.808-.81h2.293c.894 0 1.617-.724 1.617-1.62v-6.216c0-.896-.723-1.62-1.617-1.62M221.135 35.04h-1.71a1.863 1.863 0 0 1-1.866-1.87v-3.272c0-1.036-.831-1.87-1.865-1.87h-3.265a1.863 1.863 0 0 1-1.865-1.87v-3.271c0-1.036-.832-1.87-1.865-1.87h-20.971a1.863 1.863 0 0 0-1.865 1.87v3.965c0 .514-.42.935-.933.935h-3.559c-.513 0-.84-.32-.933-.935l-.622-3.918c-.148-1.099-.676-1.777-1.788-1.777l-3.653-.14h-2.052a3.736 3.736 0 0 0-3.73 3.74V61.68a3.736 3.736 0 0 1-3.731 3.739h-8.394a1.863 1.863 0 0 1-1.866-1.87V36.714c0-11.825-7.461-18.813-22.556-18.813-13.718 0-20.325 5.04-21.203 14.443-.109 1.153.552 1.815 1.702 1.815l7.757.569c1.143.1 1.594-.554 1.811-1.652.77-3.74 4.174-5.827 9.933-5.827 7.081 0 10.042 3.358 10.042 9.076v3.014c0 1.036-.831 1.87-1.865 1.87l-.342-.024h-9.715c-15.421 0-22.984 5.983-22.984 17.956 0 3.802.778 7.058 2.254 9.738h-.59c-1.765-1.27-2.457-2.236-3.055-2.93-.256-.295-.653-.537-1.345-.537h-1.717l-5.993.008h-3.264a3.736 3.736 0 0 1-3.731-3.74V1.769C89.74.654 89.072 0 87.969 0H79.55c-1.034 0-1.865.732-1.865 1.768l-.024 54.304v13.554c0 4.13 3.343 7.479 7.462 7.479h50.84c8.448-.429 8.604-3.42 9.436-4.542.645 3.56 1.865 4.347 4.71 4.518 8.137.117 18.343.032 18.49.024h4.975c4.119 0 6.684-3.35 6.684-7.479l.777-27.264c0-1.036.832-1.87 1.866-1.87h2.021a1.56 1.56 0 0 0 1.554-1.558v-3.583c0-1.036.832-1.87 1.866-1.87h11.868a3.37 3.37 0 0 1 3.366 3.373v3.249c0 1.075.87 1.947 1.943 1.947h4.119c.513 0 .933.42.933.935v32.25c0 1.036.831 1.87 1.865 1.87h6.84a3.736 3.736 0 0 0 3.731-3.74V36.91c0-1.036-.832-1.87-1.866-1.87zM142.64 54.225c0 8.927-6.132 14.715-15.335 14.715-6.606 0-9.793-2.953-9.793-8.748 0-6.442 3.832-9.636 11.62-9.636h13.508v3.669"/>
</g>
<defs>
<clipPath id="a">
<path d="M0 0h223v89H0z"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@@ -0,0 +1,25 @@
<svg xmlns="http://www.w3.org/2000/svg" width="35" height="42" viewBox="0 0 35 42" fill="none">
<rect y="6" width="6" height="6" fill="black"/>
<rect x="6" y="6" width="6" height="6" fill="black"/>
<rect x="12" y="6" width="6" height="6" fill="black"/>
<rect x="6" y="12" width="6" height="6" fill="black"/>
<rect x="18" y="18" width="6" height="6" fill="black"/>
<rect x="18" y="12" width="6" height="6" fill="black"/>
<rect x="12" y="24" width="6" height="6" fill="black"/>
<rect x="12" y="18" width="6" height="6" fill="black"/>
<rect x="12" y="12" width="6" height="6" fill="black"/>
<rect width="6" height="6" fill="black"/>
<rect x="6" width="6" height="6" fill="black"/>
<rect x="24" y="18" width="6" height="6" fill="black"/>
<rect y="12" width="6" height="6" fill="black"/>
<rect x="6" y="18" width="6" height="6" fill="black"/>
<rect y="18" width="6" height="6" fill="black"/>
<rect y="24" width="6" height="6" fill="black"/>
<rect y="30" width="6" height="6" fill="black"/>
<rect y="36" width="6" height="6" fill="black"/>
<rect x="6" y="24" width="6" height="6" fill="black"/>
<rect x="18" y="24" width="6" height="6" fill="black"/>
<rect x="24" y="24" width="6" height="6" fill="black"/>
<rect x="29" y="24" width="6" height="6" fill="black"/>
<rect x="6" y="30" width="6" height="6" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="9" height="37" viewBox="0 0 9 37" fill="none">
<rect width="9" height="9" fill="black"/>
<rect y="14" width="9" height="9" fill="black"/>
<rect y="28" width="9" height="9" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 252 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48" fill="none">
<path d="M20.2002 12.7998H23V15.5996H25.8008V14.2002H28.6006V10H34.2002V12.7998H37V15.5996H39.8008V24H37V26.7998H34.2002V29.5996H31.4004V32.4004H28.6006V35.2002H25.8008V38H23V35.2002H20.2002V32.4004H17.4004V29.5996H14.6006V26.7998H11.8008V24H9V15.5996H11.8008V12.7998H14.6006V10H20.2002V12.7998Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 418 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48" fill="none">
<path d="M38.666 5V39.667H38.667V5H43V44H4V5H38.666ZM12.666 35.334H16.999V31H12.666V35.334ZM29.999 35.334H34.333V31H29.999V35.334ZM21.333 26.667H25.666V22.334H21.333V26.667ZM12.666 18H16.999V13.667H12.666V18ZM29.999 18H34.333V13.667H29.999V18Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 366 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48" fill="none">
<path d="M38 42H10V38H6V10H10V6H38V10H42V38H38V42ZM18 32H30V28H18V32ZM14 28H18V24H14V28ZM30 28H34V24H30V28ZM16 20H20V16H16V20ZM28 20H32V16H28V20Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 268 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48" fill="none">
<path d="M42 42H14V38H38V14H42V42ZM34 6V34H6V6H34ZM18 18H14V22H18V26H22V22H26V18H22V14H18V18Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 216 B

View File

@@ -0,0 +1,13 @@
<svg xmlns="http://www.w3.org/2000/svg" width="38" height="27" viewBox="0 0 38 27" fill="none">
<rect x="4.46155" y="4.15381" width="4.15385" height="4.15385" fill="black"/>
<rect x="29.3846" y="4.15381" width="4.15385" height="4.15385" fill="black"/>
<rect x="8.61539" width="4.15385" height="4.15385" fill="black"/>
<rect x="33.5385" width="4.15385" height="4.15385" fill="black"/>
<rect x="0.307678" width="4.15385" height="4.15385" fill="black"/>
<rect x="25.2308" width="4.15385" height="4.15385" fill="black"/>
<rect x="0.307678" y="8.30762" width="4.15385" height="4.15385" fill="black"/>
<rect x="25.2308" y="8.30762" width="4.15385" height="4.15385" fill="black"/>
<rect x="8.61539" y="8.30762" width="4.15385" height="4.15385" fill="black"/>
<rect x="33.5385" y="8.30762" width="4.15385" height="4.15385" fill="black"/>
<rect x="4" y="23" width="30" height="4" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 936 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48" fill="none">
<path d="M39.2002 39.2002H43V43H39.2002V39.2021H35.3994V35.4014H39.2002V39.2002ZM27.7998 8.80078H31.5996V31.6016H27.7998V35.4004H12.6006V12.6016H20.2002V8.80078H12.6006V5H27.7998V8.80078ZM35.4004 35.4004H31.6006V31.6006H35.4004V35.4004ZM12.5996 12.5996H8.7998V20.2002H12.5996V31.6016H8.7998V27.8008H5V12.5996H8.7998V8.80078H12.5996V12.5996ZM35.4004 27.8008H31.6006V12.5996H35.4004V27.8008Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 512 B

View File

@@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" width="36" height="23" viewBox="0 0 36 23" fill="none">
<rect x="27" width="22.5" height="4.5" transform="rotate(90 27 0)" fill="black"/>
<rect x="31.5" y="4.5" width="13.5" height="4.5" transform="rotate(90 31.5 4.5)" fill="black"/>
<rect x="36" y="9" width="4.5" height="4.5" transform="rotate(90 36 9)" fill="black"/>
<rect width="22.5" height="4.5" transform="matrix(-4.37114e-08 1 1 4.37114e-08 9 0)" fill="black"/>
<rect width="13.5" height="4.5" transform="matrix(-4.37114e-08 1 1 4.37114e-08 4.5 4.5)" fill="black"/>
<rect width="4.5" height="4.5" transform="matrix(-4.37114e-08 1 1 4.37114e-08 0 9)" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 694 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48" fill="none">
<path d="M39.4004 31.2002H35.7998V34.7998H32.2002V38.3994H28.5996V42H25V38.3994H21.4004V34.7998H17.7998V31.2002H14.2002V27.6006H39.4004V31.2002ZM28.5996 13.2002H32.2002V16.7998H35.7998V20.3994H39.4004V24H43V27.5996H10.5996V24H7V9.60059H28.5996V13.2002ZM14.2002 13.2002V16.7998H17.7998V13.2002H14.2002ZM25 9.59961H7V6H25V9.59961Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 451 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48" fill="none">
<path fill-rule="evenodd" clip-rule="evenodd" d="M18.8 0H28.4V9.6H18.8V0ZM11.6 12H35.6V16.8H30.8V33.6V48H26V33.6H21.2V48H16.4V33.6V16.8H11.6V12ZM6.8 7.2V12H11.6V7.2H6.8ZM6.8 7.2L2 7.2V2.4H6.8V7.2ZM40.4 7.2V12H35.6V7.2H40.4ZM40.4 7.2L40.4 2.4H45.2V7.2L40.4 7.2Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 383 B

View File

Before

Width:  |  Height:  |  Size: 218 B

After

Width:  |  Height:  |  Size: 218 B

File diff suppressed because it is too large Load Diff

View File

@@ -47,6 +47,7 @@
"prettier": "^3.2.5", "prettier": "^3.2.5",
"solid-devtools": "^0.34.0", "solid-devtools": "^0.34.0",
"storybook": "^8.6.14", "storybook": "^8.6.14",
"storybook-addon-pseudo-states": "^4.0.3",
"tailwindcss": "^3.4.3", "tailwindcss": "^3.4.3",
"typescript": "^5.4.5", "typescript": "^5.4.5",
"typescript-eslint": "^8.32.1", "typescript-eslint": "^8.32.1",
@@ -58,9 +59,12 @@
}, },
"dependencies": { "dependencies": {
"@floating-ui/dom": "^1.6.8", "@floating-ui/dom": "^1.6.8",
"@kobalte/core": "^0.13.10",
"@kobalte/tailwindcss": "^0.9.0",
"@modular-forms/solid": "^0.25.1", "@modular-forms/solid": "^0.25.1",
"@solid-primitives/storage": "^4.3.2", "@solid-primitives/storage": "^4.3.2",
"@solidjs/router": "^0.15.3", "@solidjs/router": "^0.15.3",
"@storybook/test": "^8.6.14",
"@tanstack/eslint-plugin-query": "^5.51.12", "@tanstack/eslint-plugin-query": "^5.51.12",
"@tanstack/solid-query": "^5.76.0", "@tanstack/solid-query": "^5.76.0",
"corvu": "^0.7.1", "corvu": "^0.7.1",

View File

@@ -27,5 +27,5 @@
} }
.button--dark-active:active { .button--dark-active:active {
@apply active:border-secondary-900 active:shadow-inner-primary-active; @apply active:border-secondary-900 active:shadow-button-primary-active;
} }

View File

@@ -7,5 +7,5 @@
} }
.button--ghost-active:active { .button--ghost-active:active {
@apply active:bg-secondary-200 active:text-secondary-900 active:shadow-inner-primary-active; @apply active:bg-secondary-200 active:text-secondary-900 active:shadow-button-primary-active;
} }

View File

@@ -27,7 +27,7 @@
} }
.button--light-active:active { .button--light-active:active {
@apply active:bg-secondary-200 border-secondary-600 active:text-secondary-900 active:shadow-inner-primary-active; @apply active:bg-secondary-200 border-secondary-600 active:text-secondary-900 active:shadow-button-primary-active;
box-shadow: inset 2px 2px theme(backgroundColor.secondary.300); box-shadow: inset 2px 2px theme(backgroundColor.secondary.300);

View File

@@ -1,36 +0,0 @@
import type { Meta, StoryObj } from "@kachurun/storybook-solid";
import { TagList, TagListProps } from "./TagList";
const meta: Meta<TagListProps> = {
title: "Components/TagList",
component: TagList,
decorators: [
// wrap in a fixed width div so we can check that it wraps
(Story) => {
return (
<div style={{ width: "20em" }}>
<Story />
</div>
);
},
],
};
export default meta;
type Story = StoryObj<TagListProps>;
export const Default: Story = {
args: {
values: [
"Titan",
"Enceladus",
"Mimas",
"Dione",
"Iapetus",
"Tethys",
"Hyperion",
"Epimetheus",
],
},
};

View File

@@ -1,32 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Components/TagList Default smoke-test 1`] = `
<div style="width: 20em;">
<div class="tag-list">
<span class="fnt-clr-primary fnt-clr--inverted fnt-label-s fnt-weight-normal tag">
Titan
</span>
<span class="fnt-clr-primary fnt-clr--inverted fnt-label-s fnt-weight-normal tag">
Enceladus
</span>
<span class="fnt-clr-primary fnt-clr--inverted fnt-label-s fnt-weight-normal tag">
Mimas
</span>
<span class="fnt-clr-primary fnt-clr--inverted fnt-label-s fnt-weight-normal tag">
Dione
</span>
<span class="fnt-clr-primary fnt-clr--inverted fnt-label-s fnt-weight-normal tag">
Iapetus
</span>
<span class="fnt-clr-primary fnt-clr--inverted fnt-label-s fnt-weight-normal tag">
Tethys
</span>
<span class="fnt-clr-primary fnt-clr--inverted fnt-label-s fnt-weight-normal tag">
Hyperion
</span>
<span class="fnt-clr-primary fnt-clr--inverted fnt-label-s fnt-weight-normal tag">
Epimetheus
</span>
</div>
</div>
`;

View File

@@ -33,7 +33,7 @@ import Search from "@/icons/search.svg";
import Settings from "@/icons/settings.svg"; import Settings from "@/icons/settings.svg";
import Trash from "@/icons/trash.svg"; import Trash from "@/icons/trash.svg";
import Update from "@/icons/update.svg"; import Update from "@/icons/update.svg";
import Warning from "@/icons/warning.svg"; import Warning from "@/icons/warning-filled.svg";
const icons = { const icons = {
ArrowBottom, ArrowBottom,

View File

@@ -33,6 +33,7 @@ export const InputBase = (props: InputBaseProps) => {
const [internal, inputProps] = splitProps(props, ["class", "divRef"]); const [internal, inputProps] = splitProps(props, ["class", "divRef"]);
return ( return (
<div <div
// eslint-disable-next-line tailwindcss/no-custom-classname
class={cx( class={cx(
// Layout // Layout
"flex px-2 py-[0.375rem] flex-shrink-0 items-center justify-center gap-2 text-sm leading-6", "flex px-2 py-[0.375rem] flex-shrink-0 items-center justify-center gap-2 text-sm leading-6",
@@ -58,6 +59,7 @@ export const InputBase = (props: InputBaseProps) => {
props.class, props.class,
)} )}
classList={{ classList={{
// eslint-disable-next-line tailwindcss/no-custom-classname
[cx("!border !border-semantic-1 !outline-semantic-1")]: !!props.error, [cx("!border !border-semantic-1 !outline-semantic-1")]: !!props.error,
}} }}
aria-invalid={props.error} aria-invalid={props.error}

View File

@@ -0,0 +1,134 @@
.button {
@apply flex gap-2 shrink-0 items-center justify-center;
@apply px-4 py-2;
height: theme(height.9);
border-radius: 3px;
/* Add transition for smooth width animation */
transition: width 0.5s ease 0.1s;
&.s {
@apply px-3 py-1.5;
height: theme(height.7);
border-radius: 2px;
&:has(> .icon-start):has(> .label) {
@apply pl-2;
}
&:has(> .icon-end):has(> .label) {
@apply pr-2;
}
}
&.primary {
@apply bg-inv-acc-4 fg-inv-1;
@apply border border-solid border-inv-4;
@apply shadow-button-primary;
&.ghost {
@apply bg-transparent border-none shadow-none;
}
&:hover {
@apply bg-inv-acc-3 border-solid shadow-button-primary-hover;
border-color: theme(backgroundColor.secondary.700);
}
&:active {
@apply bg-inv-acc-4 border-solid border-inv-3 shadow-button-primary-active;
}
&:focus-visible {
@apply bg-inv-acc-4 border-solid border-inv-3 shadow-button-primary-focus;
}
&:disabled {
@apply bg-def-acc-3 border-solid border-def-3 fg-def-3 shadow-none;
}
& > .icon {
@apply fg-inv-1;
}
}
&.secondary {
@apply bg-def-acc-2 fg-def-1;
@apply border border-solid border-inv-2;
@apply shadow-button-secondary;
&.ghost {
@apply bg-transparent border-none shadow-none;
}
&:hover {
@apply bg-def-acc-3 border-solid shadow-button-secondary-hover;
border-color: theme(backgroundColor.secondary.700);
}
&:focus-visible {
@apply bg-def-acc-3 border-solid border-inv-3 shadow-button-secondary-focus;
}
&:active {
@apply bg-def-acc-3 border-solid border-inv-4 shadow-button-secondary-active;
}
&:disabled {
@apply bg-def-2 border-solid border-def-2 fg-def-3 shadow-none;
}
& > .icon {
@apply fg-def-1;
&.icon-loading {
color: #0051ff;
}
}
}
&.icon {
@apply p-2;
}
&:has(> .icon-start):has(> .label) {
@apply pl-3.5;
}
&:has(> .icon-end):has(> .label) {
@apply pr-3.5;
}
& > div.loader {
@apply w-0 opacity-0;
@apply top-0 left-0 -mr-2;
transition: all 0.5s ease;
}
&.loading {
@apply cursor-wait;
& > div.loader {
@apply w-4 opacity-100;
margin-right: revert;
transition: all 0.5s ease;
}
}
}
/* button group */
.button-group .button:first-child {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
.button-group .button:first-child {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
.button-group .button:last-child {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}

View File

@@ -0,0 +1,43 @@
import { DocsStory, Meta, Canvas } from "@storybook/blocks";
import * as ButtonStories from "./Button.stories";
<Meta of={ButtonStories} />
# Button
Buttons have a simple hierarchy, `primary` or `secondary`, and two sizes, `default` and `s`.
A `Button` can also have a label with a `startIcon`, an `endIcon` or both:
```tsx
<Button hierarchy="primary">Label</>
<Button hierarchy="secondary" size="s">Label</>
<Button hierarchy="primary" startIcon="Flash">Label</>
<Button hierarchy="primary" size="s" endIcon="Flash">Label</>
<Button hierarchy="primary" startIcon="Flash" endIcon="Flash">Label</>
```
To create a `Button` which is just an icon:
```tsx
<Button icon="Flash"/>
<Button icon="User" size="s"/>
```
<DocsStory of={ButtonStories.Primary} />
<DocsStory of={ButtonStories.Secondary} />
## Ghost Mode
Buttons in ghost mode have all the same states as normal buttons, except for their initial state has no background,
outline or box shadow.
```tsx
<Button hierarchy="primary" ghost={true}>Label</>
```
<DocsStory of={ButtonStories.GhostPrimary} />
<DocsStory of={ButtonStories.GhostSecondary} />

View File

@@ -0,0 +1,251 @@
import type { Meta, StoryObj } from "@kachurun/storybook-solid";
import { Button, ButtonProps } from "./Button";
import { Component } from "solid-js";
import { expect, fn, userEvent, waitFor, within } from "@storybook/test";
const getCursorStyle = (el: Element) => window.getComputedStyle(el).cursor;
const ButtonExamples: Component<ButtonProps> = (props) => (
<>
<div class="grid w-fit grid-cols-4 gap-8">
<div>
<Button data-testid="default" {...props}>
Label
</Button>
</div>
<div>
<Button data-testid="small" size="s" {...props}>
Label
</Button>
</div>
<div>
<Button data-testid="default-disabled" {...props} disabled={true}>
Disabled
</Button>
</div>
<div>
<Button
data-testid="small-disabled"
{...props}
disabled={true}
size="s"
>
Disabled
</Button>
</div>
<div>
<Button data-testid="default-start-icon" {...props} startIcon="Flash">
Label
</Button>
</div>
<div>
<Button
data-testid="small-start-icon"
{...props}
startIcon="Flash"
size="s"
>
Label
</Button>
</div>
<div>
<Button
data-testid="default-disabled-start-icon"
{...props}
startIcon="Flash"
disabled={true}
>
Disabled
</Button>
</div>
<div>
<Button
data-testid="small-disabled-start-icon"
{...props}
startIcon="Flash"
size="s"
disabled={true}
>
Disabled
</Button>
</div>
<div>
<Button data-testid="default-end-icon" {...props} endIcon="Flash">
Label
</Button>
</div>
<div>
<Button
data-testid="small-end-icon"
{...props}
endIcon="Flash"
size="s"
>
Label
</Button>
</div>
<div>
<Button
data-testid="default-disabled-end-icon"
{...props}
endIcon="Flash"
disabled={true}
>
Disabled
</Button>
</div>
<div>
<Button
data-testid="small-disabled-end-icon"
{...props}
endIcon="Flash"
size="s"
disabled={true}
>
Disabled
</Button>
</div>
<div>
<Button data-testid="default-icon" {...props} icon="Flash" />
</div>
<div>
<Button data-testid="small-icon" {...props} icon="Flash" size="s" />
</div>
<div>
<Button
data-testid="default-disabled-icon"
{...props}
icon="Flash"
disabled={true}
/>
</div>
<div>
<Button
data-testid="small-disabled-icon"
{...props}
icon="Flash"
disabled={true}
size="s"
/>
</div>
</div>
</>
);
const meta: Meta<ButtonProps> = {
title: "Components/Button",
component: ButtonExamples,
};
export default meta;
type Story = StoryObj<ButtonProps>;
export const Primary: Story = {
args: {
hierarchy: "primary",
onAction: fn(async () => {
// wait 500 ms to simulate an action
await new Promise((resolve) => setTimeout(resolve, 500));
// randomly fail to check that the loading state still returns to normal
if (Math.random() > 0.5) {
throw new Error("Action failure");
}
}),
},
parameters: {
test: {
mockTimers: true,
},
},
play: async ({ args, canvasElement, step }) => {
const canvas = within(canvasElement);
const buttons = await canvas.findAllByRole("button");
for (const button of buttons) {
const testID = button.getAttribute("data-testid");
// skip disabled buttons
if (button.hasAttribute("disabled")) {
continue;
}
await step(`Click on ${testID}`, async () => {
// check for the loader
const loaders = button.getElementsByClassName("loader");
await expect(loaders.length).toEqual(1);
// assert its width is 0 before we click
const [loader] = loaders;
await expect(loader.clientWidth).toEqual(0);
// move the mouse over the button
await userEvent.hover(button);
// the pointer should be normal
await expect(getCursorStyle(button)).toEqual("pointer");
// click the button
await userEvent.click(button);
// check the button has changed
await waitFor(async () => {
// the action handler should have been called
await expect(args.onAction).toHaveBeenCalled();
// the button should have a loading class
await expect(button).toHaveClass("loading");
// the loader should be visible
await expect(loader.clientWidth).toBeGreaterThan(0);
// the pointer should have changed to wait
await expect(getCursorStyle(button)).toEqual("wait");
});
// wait for the action handler to finish
await waitFor(async () => {
// the loading class should be removed
await expect(button).not.toHaveClass("loading");
// the loader should be hidden
await expect(loader.clientWidth).toEqual(0);
// the pointer should be normal
await expect(getCursorStyle(button)).toEqual("pointer");
});
});
}
},
};
export const Secondary: Story = {
args: {
...Primary.args,
hierarchy: "secondary",
},
play: Primary.play,
};
export const GhostPrimary: Story = {
args: {
...Primary.args,
hierarchy: "primary",
ghost: true,
},
play: Primary.play,
decorators: [
(Story) => (
<div class="bg-def-3 p-10">
<Story />
</div>
),
],
};
export const GhostSecondary: Story = {
args: {
...Primary.args,
hierarchy: "secondary",
ghost: true,
},
play: Primary.play,
};

View File

@@ -0,0 +1,116 @@
import { splitProps, type JSX, createSignal, Show } from "solid-js";
import cx from "classnames";
import { Typography } from "../Typography/Typography";
import { Button as KobalteButton } from "@kobalte/core/button";
import "./Button.css";
import Icon, { IconVariant } from "@/src/components/v2/Icon/Icon";
import { Loader } from "@/src/components/v2/Loader/Loader";
export type Size = "default" | "s";
export type Hierarchy = "primary" | "secondary";
export type Action = () => Promise<void>;
export interface ButtonProps
extends JSX.ButtonHTMLAttributes<HTMLButtonElement> {
hierarchy?: Hierarchy;
size?: Size;
ghost?: boolean;
children?: JSX.Element;
icon?: IconVariant;
startIcon?: IconVariant;
endIcon?: IconVariant;
class?: string;
onAction?: Action;
}
const iconSizes: Record<Size, string> = {
default: "1rem",
s: "0.8125rem",
};
export const Button = (props: ButtonProps) => {
const [local, other] = splitProps(props, [
"children",
"hierarchy",
"size",
"ghost",
"icon",
"startIcon",
"endIcon",
"class",
"onAction",
]);
const size = local.size || "default";
const hierarchy = local.hierarchy || "primary";
const [loading, setLoading] = createSignal(false);
const onClick = async () => {
if (!local.onAction) {
console.error("this should not be possible");
return;
}
setLoading(true);
try {
await local.onAction();
} catch (error) {
console.error("Error while executing action", error);
}
setLoading(false);
};
const iconSize = iconSizes[local.size || "default"];
return (
<KobalteButton
class={cx(
local.class,
"button", // default button class
size,
hierarchy,
{
icon: local.icon,
loading: loading(),
ghost: local.ghost,
},
)}
onClick={local.onAction ? onClick : undefined}
{...other}
>
<Loader hierarchy={hierarchy} />
{local.startIcon && (
<Icon icon={local.startIcon} class="icon-start" size={iconSize} />
)}
{local.icon && !local.children && (
<Icon icon={local.icon} class="icon" size={iconSize} />
)}
{local.children && !local.icon && (
<Typography
class="label"
hierarchy="label"
family="mono"
size={local.size || "default"}
color="inherit"
inverted={local.hierarchy === "secondary"}
weight="bold"
tag="span"
>
{local.children}
</Typography>
)}
{local.endIcon && (
<Icon icon={local.endIcon} class="icon-end" size={iconSize} />
)}
</KobalteButton>
);
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,75 @@
import type { Meta, StoryObj } from "@kachurun/storybook-solid";
import { Component, For } from "solid-js";
import Icon, { IconProps, IconVariant } from "./Icon";
const iconVariants: IconVariant[] = [
"ClanIcon",
"Checkmark",
"Paperclip",
"Expand",
"Plus",
"Trash",
"Folder",
"CaretRight",
"CaretLeft",
"CaretUp",
"CaretDown",
"Close",
"Flash",
"EyeClose",
"EyeOpen",
"Settings",
"Grid",
"List",
"Edit",
"Load",
"ArrowRight",
"ArrowLeft",
"ArrowTop",
"ArrowBottom",
"Info",
"Update",
"Reload",
"Search",
"Report",
"Cursor",
"More",
"Filter",
"Download",
"Attention",
"User",
"WarningFilled",
"Modules",
"NewMachine",
"AI",
"Heart",
"SearchFilled",
"Offline",
"Switch",
"Tag",
"Machine",
];
const IconExamples: Component<IconProps> = (props) => (
<div class="inline-flex flex-wrap gap-2">
<For each={iconVariants}>{(item) => <Icon {...props} icon={item} />}</For>
</div>
);
const meta: Meta<IconProps> = {
title: "Components/Icon",
component: IconExamples,
};
export default meta;
type Story = StoryObj<IconProps>;
export const Default: Story = {};
export const Large: Story = {
args: {
width: "2rem",
height: "2rem",
},
};

View File

@@ -0,0 +1,126 @@
import cx from "classnames";
import { Component, JSX, Show, splitProps } from "solid-js";
import ArrowBottom from "@/icons/arrow-bottom.svg";
import ArrowLeft from "@/icons/arrow-left.svg";
import ArrowRight from "@/icons/arrow-right.svg";
import ArrowTop from "@/icons/arrow-top.svg";
import Attention from "@/icons/attention.svg";
import CaretDown from "@/icons/caret-down.svg";
import CaretLeft from "@/icons/caret-left.svg";
import CaretRight from "@/icons/caret-right.svg";
import CaretUp from "@/icons/caret-up.svg";
import Checkmark from "@/icons/checkmark.svg";
import ClanIcon from "@/icons/clan-icon.svg";
import Cursor from "@/icons/cursor.svg";
import Close from "@/icons/close.svg";
import Download from "@/icons/download.svg";
import Edit from "@/icons/edit.svg";
import Expand from "@/icons/expand.svg";
import EyeClose from "@/icons/eye-close.svg";
import EyeOpen from "@/icons/eye-open.svg";
import Filter from "@/icons/filter.svg";
import Flash from "@/icons/flash.svg";
import Folder from "@/icons/folder.svg";
import Grid from "@/icons/grid.svg";
import Info from "@/icons/info.svg";
import List from "@/icons/list.svg";
import Load from "@/icons/load.svg";
import More from "@/icons/more.svg";
import Paperclip from "@/icons/paperclip.svg";
import Plus from "@/icons/plus.svg";
import Reload from "@/icons/reload.svg";
import Report from "@/icons/report.svg";
import Search from "@/icons/search.svg";
import Settings from "@/icons/settings.svg";
import Trash from "@/icons/trash.svg";
import Update from "@/icons/update.svg";
import WarningFilled from "@/icons/warning-filled.svg";
import Modules from "@/icons/modules.svg";
import NewMachine from "@/icons/new-machine.svg";
import AI from "@/icons/ai.svg";
import User from "@/icons/user.svg";
import Heart from "@/icons/heart.svg";
import SearchFilled from "@/icons/search-filled.svg";
import Offline from "@/icons/offline.svg";
import Switch from "@/icons/switch.svg";
import Tag from "@/icons/tag.svg";
import Machine from "@/icons/machine.svg";
import Loader from "@/icons/loader.svg";
import { Dynamic } from "solid-js/web";
const icons = {
AI,
ArrowBottom,
ArrowLeft,
ArrowRight,
ArrowTop,
Attention,
CaretDown,
CaretLeft,
CaretRight,
CaretUp,
Checkmark,
ClanIcon,
Close,
Cursor,
Download,
Edit,
Expand,
EyeClose,
EyeOpen,
Filter,
Flash,
Folder,
Grid,
Heart,
Info,
List,
Load,
Machine,
Modules,
More,
NewMachine,
Offline,
Paperclip,
Plus,
Reload,
Report,
Search,
SearchFilled,
Settings,
Switch,
Tag,
Trash,
Update,
User,
WarningFilled,
};
export type IconVariant = keyof typeof icons;
export interface IconProps extends JSX.SvgSVGAttributes<SVGElement> {
icon: IconVariant;
class?: string;
size?: number | string;
}
const Icon: Component<IconProps> = (props) => {
const [local, iconProps] = splitProps(props, ["icon", "class"]);
const IconComponent = () => icons[local.icon];
return IconComponent() ? (
<Dynamic
component={IconComponent()}
class={cx("icon", local.class)}
width={iconProps.size || "1em"}
height={iconProps.size || "1em"}
viewBox="0 0 48 48"
// @ts-expect-error: dont know, fix this type nit later
ref={iconProps.ref}
{...iconProps}
/>
) : undefined;
};
export default Icon;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,104 @@
.loader {
@apply relative;
@apply w-4 h-4;
&.primary {
& > div.wrapper > div.parent,
& > div.child {
background: #00ff57;
}
}
&.secondary {
& > div.wrapper > div.parent,
& > div.child {
background: #0051ff;
}
}
& > div.wrapper {
@apply absolute top-0 left-0 w-full h-full;
transform: translate(0%, 0%) rotate(-45deg);
animation: moveLoaderWrapper 1.8s ease-in-out infinite;
& > div.parent {
@apply absolute top-1/2 left-1/2;
@apply w-2/3 h-2/3;
border-radius: 50%;
animation: moveLoaderParent 1.8s ease-in-out infinite;
transform: translateX(-50%) translateY(-50%);
}
}
& > .child {
@apply absolute z-10 top-1/2 left-1/2 w-1/2 h-1/2;
border-radius: 50%;
transform: translate(-50%, -50%);
animation: moveLoaderChild 1.8s ease-in-out infinite;
}
}
@keyframes moveLoaderWrapper {
0% {
transform: translate(0%, 0%) rotate(-45deg);
}
35% {
transform: translate(-25%, 0%) rotate(-45deg);
}
50% {
transform: translate(0%, 0%) rotate(-45deg);
}
85% {
transform: translate(25%, 0%) rotate(-45deg);
}
}
@keyframes moveLoaderParent {
0% {
animation-timing-function: ease-in-out;
transform: translateX(-50%) translateY(-50%);
}
35% {
animation-timing-function: cubic-bezier(0.7, -0.9, 0.3, 3.2);
transform: translateX(-50%) translateY(-50%) skew(20deg, 20deg);
}
50% {
animation-timing-function: ease-in-out;
transform: translateX(-50%) translateY(-50%) skew(0deg, 0deg);
}
85% {
animation-timing-function: cubic-bezier(0.7, -0.9, 0.3, 3.2);
transform: translateX(-50%) translateY(-50%) skew(20deg, 20deg);
}
}
@keyframes moveLoaderChild {
0% {
animation-timing-function: ease-in-out;
transform: translateX(-50%) translateY(-50%);
}
35% {
animation-timing-function: cubic-bezier(0.7, -0.9, 0.3, 3.2);
transform: translateX(50%) translateY(-50%) scale(0.56);
}
50% {
animation-timing-function: ease-in-out;
transform: translateX(-50%) translateY(-50%);
}
85% {
animation-timing-function: cubic-bezier(0.7, -0.9, 0.3, 3.2);
transform: translateX(-150%) translateY(-50%) scale(0.56);
}
}

View File

@@ -0,0 +1,23 @@
import type { Meta, StoryObj } from "@kachurun/storybook-solid";
import { Loader, LoaderProps } from "@/src/components/v2/Loader/Loader";
const meta: Meta<LoaderProps> = {
title: "Components/Loader",
component: Loader,
};
export default meta;
type Story = StoryObj<LoaderProps>;
export const Primary: Story = {
args: {
hierarchy: "primary",
},
};
export const Secondary: Story = {
args: {
hierarchy: "secondary",
},
};

View File

@@ -0,0 +1,19 @@
import "./Loader.css";
import cx from "classnames";
export type Hierarchy = "primary" | "secondary";
export interface LoaderProps {
hierarchy?: Hierarchy;
}
export const Loader = (props: LoaderProps) => {
return (
<div class={cx("loader", props.hierarchy || "primary")}>
<div class="wrapper">
<div class="parent"></div>
</div>
<div class="child"></div>
</div>
);
};

View File

@@ -0,0 +1,23 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Components/Loader Primary smoke-test 1`] = `
<div class="loader primary">
<div class="wrapper">
<div class="parent">
</div>
</div>
<div class="child">
</div>
</div>
`;
exports[`Components/Loader Secondary smoke-test 1`] = `
<div class="loader secondary">
<div class="wrapper">
<div class="parent">
</div>
</div>
<div class="child">
</div>
</div>
`;

View File

@@ -23,25 +23,25 @@
&.font-size-default { &.font-size-default {
font-size: 1rem; font-size: 1rem;
line-height: 132%; line-height: 1.32;
letter-spacing: 0.02rem; letter-spacing: 0.02rem;
} }
&.font-size-s { &.font-size-s {
font-size: 0.875rem; font-size: 0.875rem;
line-height: 132%; line-height: 1.32;
letter-spacing: 0.0175rem; letter-spacing: 0.0175rem;
} }
&.font-size-xs { &.font-size-xs {
font-size: 0.75rem; font-size: 0.75rem;
line-height: 132%; line-height: 1.32;
letter-spacing: 0.0225rem; letter-spacing: 0.0225rem;
} }
&.font-size-xxs { &.font-size-xxs {
font-size: 0.6875rem; font-size: 0.6875rem;
line-height: 132%; line-height: 1.32;
letter-spacing: 0.00688rem; letter-spacing: 0.00688rem;
} }
} }
@@ -52,38 +52,41 @@
&.font-size-default { &.font-size-default {
font-size: 0.875rem; font-size: 0.875rem;
line-height: 132%; line-height: 1.32;
letter-spacing: 0.0175rem; letter-spacing: 0.0175rem;
} }
&.font-size-s { &.font-size-s {
font-size: 0.8125rem; font-size: 0.8125rem;
line-height: 132%; line-height: 1.32;
letter-spacing: 0.0175rem; letter-spacing: 0.0175rem;
} }
&.font-size-xs { &.font-size-xs {
font-size: 0.75rem; font-size: 0.75rem;
line-height: 132%; line-height: 1.32;
letter-spacing: 0.0075rem; letter-spacing: 0.0075rem;
} }
} }
&.font-family-mono { &.font-family-mono {
font-family: "Fira Code", monospace; font-family: "Commit Mono", monospace;
&.font-size-default { &.font-size-default {
font-size: 0.8125rem; font-size: 0.8125rem;
line-height: 0;
letter-spacing: normal; letter-spacing: normal;
} }
&.font-size-s { &.font-size-s {
font-size: 0.75rem; font-size: 0.75rem;
line-height: 0;
letter-spacing: normal; letter-spacing: normal;
} }
&.font-size-xs { &.font-size-xs {
font-size: 0.6875rem; font-size: 0.6875rem;
line-height: 0;
letter-spacing: normal; letter-spacing: normal;
} }
} }

View File

@@ -90,26 +90,6 @@ const sizeHierarchyMap: SizeForHierarchy = {
}, },
}; };
interface FamilyForHierarchy {
body: {
regular: string;
condensed: string;
};
label: {
condensed: string;
mono: string;
};
title: {
condensed: string;
};
headline: {
regular: string;
};
teaser: {
regular: string;
};
}
const defaultFamilyMap: Record<Hierarchy, Family> = { const defaultFamilyMap: Record<Hierarchy, Family> = {
body: "condensed", body: "condensed",
label: "condensed", label: "condensed",
@@ -144,7 +124,7 @@ export const Typography = <H extends Hierarchy>(props: _TypographyProps<H>) => {
const color = () => colorFor(props.color, props.inverted); const color = () => colorFor(props.color, props.inverted);
const classList = mergeProps(props.classList, { const classList = mergeProps(props.classList, {
"font-body": props.hierarchy === "body" || !!props.hierarchy, "font-body": props.hierarchy === "body" || !props.hierarchy,
"font-label": props.hierarchy === "label", "font-label": props.hierarchy === "label",
"font-title": props.hierarchy === "title", "font-title": props.hierarchy === "title",
"font-headline": props.hierarchy === "headline", "font-headline": props.hierarchy === "headline",

View File

@@ -713,51 +713,51 @@ exports[`Components/Typography Headline smoke-test 1`] = `
<tbody> <tbody>
<tr class="border-b border-def-3 even:bg-def-2"> <tr class="border-b border-def-3 even:bg-def-2">
<td class="px-6 py-2 "> <td class="px-6 py-2 ">
<span class="typography fg-def-1 font-family-regular font-weight-normal font-size-default font-body font-headline"> <span class="typography fg-def-1 font-family-regular font-weight-normal font-size-default font-headline">
headline / default / normal headline / default / normal
</span> </span>
</td> </td>
<td class="px-6 py-2 "> <td class="px-6 py-2 ">
<span class="typography fg-def-1 font-family-regular font-weight-medium font-size-default font-body font-headline"> <span class="typography fg-def-1 font-family-regular font-weight-medium font-size-default font-headline">
headline / default / medium headline / default / medium
</span> </span>
</td> </td>
<td class="px-6 py-2 "> <td class="px-6 py-2 ">
<span class="typography fg-def-1 font-family-regular font-weight-bold font-size-default font-body font-headline"> <span class="typography fg-def-1 font-family-regular font-weight-bold font-size-default font-headline">
headline / default / bold headline / default / bold
</span> </span>
</td> </td>
</tr> </tr>
<tr class="border-b border-def-3 even:bg-def-2"> <tr class="border-b border-def-3 even:bg-def-2">
<td class="px-6 py-2 "> <td class="px-6 py-2 ">
<span class="typography fg-def-1 font-family-regular font-weight-normal font-size-m font-body font-headline"> <span class="typography fg-def-1 font-family-regular font-weight-normal font-size-m font-headline">
headline / m / normal headline / m / normal
</span> </span>
</td> </td>
<td class="px-6 py-2 "> <td class="px-6 py-2 ">
<span class="typography fg-def-1 font-family-regular font-weight-medium font-size-m font-body font-headline"> <span class="typography fg-def-1 font-family-regular font-weight-medium font-size-m font-headline">
headline / m / medium headline / m / medium
</span> </span>
</td> </td>
<td class="px-6 py-2 "> <td class="px-6 py-2 ">
<span class="typography fg-def-1 font-family-regular font-weight-bold font-size-m font-body font-headline"> <span class="typography fg-def-1 font-family-regular font-weight-bold font-size-m font-headline">
headline / m / bold headline / m / bold
</span> </span>
</td> </td>
</tr> </tr>
<tr class="border-b border-def-3 even:bg-def-2"> <tr class="border-b border-def-3 even:bg-def-2">
<td class="px-6 py-2 "> <td class="px-6 py-2 ">
<span class="typography fg-def-1 font-family-regular font-weight-normal font-size-l font-body font-headline"> <span class="typography fg-def-1 font-family-regular font-weight-normal font-size-l font-headline">
headline / l / normal headline / l / normal
</span> </span>
</td> </td>
<td class="px-6 py-2 "> <td class="px-6 py-2 ">
<span class="typography fg-def-1 font-family-regular font-weight-medium font-size-l font-body font-headline"> <span class="typography fg-def-1 font-family-regular font-weight-medium font-size-l font-headline">
headline / l / medium headline / l / medium
</span> </span>
</td> </td>
<td class="px-6 py-2 "> <td class="px-6 py-2 ">
<span class="typography fg-def-1 font-family-regular font-weight-bold font-size-l font-body font-headline"> <span class="typography fg-def-1 font-family-regular font-weight-bold font-size-l font-headline">
headline / l / bold headline / l / bold
</span> </span>
</td> </td>
@@ -771,51 +771,51 @@ exports[`Components/Typography LabelCondensed smoke-test 1`] = `
<tbody> <tbody>
<tr class="border-b border-def-3 even:bg-def-2"> <tr class="border-b border-def-3 even:bg-def-2">
<td class="px-6 py-2 "> <td class="px-6 py-2 ">
<span class="typography fg-def-1 font-family-condensed font-weight-normal font-size-default font-body font-label"> <span class="typography fg-def-1 font-family-condensed font-weight-normal font-size-default font-label">
label / default / normal label / default / normal
</span> </span>
</td> </td>
<td class="px-6 py-2 "> <td class="px-6 py-2 ">
<span class="typography fg-def-1 font-family-condensed font-weight-medium font-size-default font-body font-label"> <span class="typography fg-def-1 font-family-condensed font-weight-medium font-size-default font-label">
label / default / medium label / default / medium
</span> </span>
</td> </td>
<td class="px-6 py-2 "> <td class="px-6 py-2 ">
<span class="typography fg-def-1 font-family-condensed font-weight-bold font-size-default font-body font-label"> <span class="typography fg-def-1 font-family-condensed font-weight-bold font-size-default font-label">
label / default / bold label / default / bold
</span> </span>
</td> </td>
</tr> </tr>
<tr class="border-b border-def-3 even:bg-def-2"> <tr class="border-b border-def-3 even:bg-def-2">
<td class="px-6 py-2 "> <td class="px-6 py-2 ">
<span class="typography fg-def-1 font-family-condensed font-weight-normal font-size-s font-body font-label"> <span class="typography fg-def-1 font-family-condensed font-weight-normal font-size-s font-label">
label / s / normal label / s / normal
</span> </span>
</td> </td>
<td class="px-6 py-2 "> <td class="px-6 py-2 ">
<span class="typography fg-def-1 font-family-condensed font-weight-medium font-size-s font-body font-label"> <span class="typography fg-def-1 font-family-condensed font-weight-medium font-size-s font-label">
label / s / medium label / s / medium
</span> </span>
</td> </td>
<td class="px-6 py-2 "> <td class="px-6 py-2 ">
<span class="typography fg-def-1 font-family-condensed font-weight-bold font-size-s font-body font-label"> <span class="typography fg-def-1 font-family-condensed font-weight-bold font-size-s font-label">
label / s / bold label / s / bold
</span> </span>
</td> </td>
</tr> </tr>
<tr class="border-b border-def-3 even:bg-def-2"> <tr class="border-b border-def-3 even:bg-def-2">
<td class="px-6 py-2 "> <td class="px-6 py-2 ">
<span class="typography fg-def-1 font-family-condensed font-weight-normal font-size-xs font-body font-label"> <span class="typography fg-def-1 font-family-condensed font-weight-normal font-size-xs font-label">
label / xs / normal label / xs / normal
</span> </span>
</td> </td>
<td class="px-6 py-2 "> <td class="px-6 py-2 ">
<span class="typography fg-def-1 font-family-condensed font-weight-medium font-size-xs font-body font-label"> <span class="typography fg-def-1 font-family-condensed font-weight-medium font-size-xs font-label">
label / xs / medium label / xs / medium
</span> </span>
</td> </td>
<td class="px-6 py-2 "> <td class="px-6 py-2 ">
<span class="typography fg-def-1 font-family-condensed font-weight-bold font-size-xs font-body font-label"> <span class="typography fg-def-1 font-family-condensed font-weight-bold font-size-xs font-label">
label / xs / bold label / xs / bold
</span> </span>
</td> </td>
@@ -829,51 +829,51 @@ exports[`Components/Typography LabelMono smoke-test 1`] = `
<tbody> <tbody>
<tr class="border-b border-def-3 even:bg-def-2"> <tr class="border-b border-def-3 even:bg-def-2">
<td class="px-6 py-2 "> <td class="px-6 py-2 ">
<span class="typography fg-def-1 font-family-mono font-weight-normal font-size-default font-body font-label"> <span class="typography fg-def-1 font-family-mono font-weight-normal font-size-default font-label">
label / default / normal label / default / normal
</span> </span>
</td> </td>
<td class="px-6 py-2 "> <td class="px-6 py-2 ">
<span class="typography fg-def-1 font-family-mono font-weight-medium font-size-default font-body font-label"> <span class="typography fg-def-1 font-family-mono font-weight-medium font-size-default font-label">
label / default / medium label / default / medium
</span> </span>
</td> </td>
<td class="px-6 py-2 "> <td class="px-6 py-2 ">
<span class="typography fg-def-1 font-family-mono font-weight-bold font-size-default font-body font-label"> <span class="typography fg-def-1 font-family-mono font-weight-bold font-size-default font-label">
label / default / bold label / default / bold
</span> </span>
</td> </td>
</tr> </tr>
<tr class="border-b border-def-3 even:bg-def-2"> <tr class="border-b border-def-3 even:bg-def-2">
<td class="px-6 py-2 "> <td class="px-6 py-2 ">
<span class="typography fg-def-1 font-family-mono font-weight-normal font-size-s font-body font-label"> <span class="typography fg-def-1 font-family-mono font-weight-normal font-size-s font-label">
label / s / normal label / s / normal
</span> </span>
</td> </td>
<td class="px-6 py-2 "> <td class="px-6 py-2 ">
<span class="typography fg-def-1 font-family-mono font-weight-medium font-size-s font-body font-label"> <span class="typography fg-def-1 font-family-mono font-weight-medium font-size-s font-label">
label / s / medium label / s / medium
</span> </span>
</td> </td>
<td class="px-6 py-2 "> <td class="px-6 py-2 ">
<span class="typography fg-def-1 font-family-mono font-weight-bold font-size-s font-body font-label"> <span class="typography fg-def-1 font-family-mono font-weight-bold font-size-s font-label">
label / s / bold label / s / bold
</span> </span>
</td> </td>
</tr> </tr>
<tr class="border-b border-def-3 even:bg-def-2"> <tr class="border-b border-def-3 even:bg-def-2">
<td class="px-6 py-2 "> <td class="px-6 py-2 ">
<span class="typography fg-def-1 font-family-mono font-weight-normal font-size-xs font-body font-label"> <span class="typography fg-def-1 font-family-mono font-weight-normal font-size-xs font-label">
label / xs / normal label / xs / normal
</span> </span>
</td> </td>
<td class="px-6 py-2 "> <td class="px-6 py-2 ">
<span class="typography fg-def-1 font-family-mono font-weight-medium font-size-xs font-body font-label"> <span class="typography fg-def-1 font-family-mono font-weight-medium font-size-xs font-label">
label / xs / medium label / xs / medium
</span> </span>
</td> </td>
<td class="px-6 py-2 "> <td class="px-6 py-2 ">
<span class="typography fg-def-1 font-family-mono font-weight-bold font-size-xs font-body font-label"> <span class="typography fg-def-1 font-family-mono font-weight-bold font-size-xs font-label">
label / xs / bold label / xs / bold
</span> </span>
</td> </td>
@@ -887,7 +887,7 @@ exports[`Components/Typography Teaser smoke-test 1`] = `
<tbody> <tbody>
<tr class="border-b border-def-3 even:bg-def-2"> <tr class="border-b border-def-3 even:bg-def-2">
<td class="px-6 py-2 "> <td class="px-6 py-2 ">
<span class="typography fg-def-1 font-family-regular font-weight-bold font-size-default font-body font-teaser"> <span class="typography fg-def-1 font-family-regular font-weight-bold font-size-default font-teaser">
teaser / default / bold teaser / default / bold
</span> </span>
</td> </td>
@@ -901,51 +901,51 @@ exports[`Components/Typography Title smoke-test 1`] = `
<tbody> <tbody>
<tr class="border-b border-def-3 even:bg-def-2"> <tr class="border-b border-def-3 even:bg-def-2">
<td class="px-6 py-2 "> <td class="px-6 py-2 ">
<span class="typography fg-def-1 font-family-regular font-weight-normal font-size-default font-body font-title"> <span class="typography fg-def-1 font-family-regular font-weight-normal font-size-default font-title">
title / default / normal title / default / normal
</span> </span>
</td> </td>
<td class="px-6 py-2 "> <td class="px-6 py-2 ">
<span class="typography fg-def-1 font-family-regular font-weight-medium font-size-default font-body font-title"> <span class="typography fg-def-1 font-family-regular font-weight-medium font-size-default font-title">
title / default / medium title / default / medium
</span> </span>
</td> </td>
<td class="px-6 py-2 "> <td class="px-6 py-2 ">
<span class="typography fg-def-1 font-family-regular font-weight-bold font-size-default font-body font-title"> <span class="typography fg-def-1 font-family-regular font-weight-bold font-size-default font-title">
title / default / bold title / default / bold
</span> </span>
</td> </td>
</tr> </tr>
<tr class="border-b border-def-3 even:bg-def-2"> <tr class="border-b border-def-3 even:bg-def-2">
<td class="px-6 py-2 "> <td class="px-6 py-2 ">
<span class="typography fg-def-1 font-family-regular font-weight-normal font-size-m font-body font-title"> <span class="typography fg-def-1 font-family-regular font-weight-normal font-size-m font-title">
title / m / normal title / m / normal
</span> </span>
</td> </td>
<td class="px-6 py-2 "> <td class="px-6 py-2 ">
<span class="typography fg-def-1 font-family-regular font-weight-medium font-size-m font-body font-title"> <span class="typography fg-def-1 font-family-regular font-weight-medium font-size-m font-title">
title / m / medium title / m / medium
</span> </span>
</td> </td>
<td class="px-6 py-2 "> <td class="px-6 py-2 ">
<span class="typography fg-def-1 font-family-regular font-weight-bold font-size-m font-body font-title"> <span class="typography fg-def-1 font-family-regular font-weight-bold font-size-m font-title">
title / m / bold title / m / bold
</span> </span>
</td> </td>
</tr> </tr>
<tr class="border-b border-def-3 even:bg-def-2"> <tr class="border-b border-def-3 even:bg-def-2">
<td class="px-6 py-2 "> <td class="px-6 py-2 ">
<span class="typography fg-def-1 font-family-regular font-weight-normal font-size-l font-body font-title"> <span class="typography fg-def-1 font-family-regular font-weight-normal font-size-l font-title">
title / l / normal title / l / normal
</span> </span>
</td> </td>
<td class="px-6 py-2 "> <td class="px-6 py-2 ">
<span class="typography fg-def-1 font-family-regular font-weight-medium font-size-l font-body font-title"> <span class="typography fg-def-1 font-family-regular font-weight-medium font-size-l font-title">
title / l / medium title / l / medium
</span> </span>
</td> </td>
<td class="px-6 py-2 "> <td class="px-6 py-2 ">
<span class="typography fg-def-1 font-family-regular font-weight-bold font-size-l font-body font-title"> <span class="typography fg-def-1 font-family-regular font-weight-bold font-size-l font-title">
title / l / bold title / l / bold
</span> </span>
</td> </td>

View File

@@ -43,9 +43,50 @@
} }
@font-face { @font-face {
font-family: "Fira Code"; font-family: "Commit Mono";
font-weight: 400; font-weight: 400;
src: url(../../../.fonts/FiraCode-Regular.woff2) format("woff2"); src: url(../../../.fonts/CommitMono-400-Regular.otf) format("otf");
}
:root {
--clr-bg-def-1: theme(colors.white);
--clr-bg-def-2: theme(colors.primary.50);
--clr-bg-def-3: theme(colors.secondary.100);
--clr-bg-def-4: theme(colors.secondary.200);
--clr-border-def-1: theme(colors.secondary.50);
--clr-border-def-2: theme(colors.secondary.100);
--clr-border-def-3: theme(colors.secondary.200);
--clr-border-def-4: theme(colors.secondary.300);
--clr-border-def-sem-inf-1: theme(colors.info.500);
--clr-border-def-sem-inf-2: theme(colors.info.600);
--clr-border-def-sem-inf-3: theme(colors.info.700);
--clr-border-def-sem-inf-4: theme(colors.info.800);
--clr-bg-inv-1: theme(colors.primary.600);
--clr-bg-inv-2: theme(colors.primary.700);
--clr-bg-inv-3: theme(colors.primary.800);
--clr-bg-inv-4: theme(colors.primary.900);
--clr-border-inv-1: theme(colors.secondary.700);
--clr-border-inv-2: theme(colors.secondary.800);
--clr-border-inv-3: theme(colors.secondary.900);
--clr-border-inv-4: theme(colors.secondary.950);
--clr-bg-inv-acc-1: theme(colors.secondary.500);
--clr-bg-inv-acc-2: theme(colors.secondary.600);
--clr-bg-inv-acc-3: theme(colors.secondary.700);
--clr-fg-def-1: theme(colors.secondary.950);
--clr-fg-def-2: theme(colors.secondary.900);
--clr-fg-def-3: theme(colors.secondary.700);
--clr-fg-def-4: theme(colors.secondary.400);
--clr-fg-inv-1: theme(colors.white);
--clr-fg-inv-2: theme(colors.secondary.100);
--clr-fg-inv-3: theme(colors.secondary.300);
--clr-fg-inv-4: theme(colors.secondary.400);
} }
html { html {

View File

@@ -1,11 +1,12 @@
import typography from "@tailwindcss/typography"; import typography from "@tailwindcss/typography";
import kobalte from "@kobalte/tailwindcss";
import core from "./tailwind/core-plugin"; import core from "./tailwind/core-plugin";
/** @type {import('tailwindcss').Config} */ /** @type {import('tailwindcss').Config} */
const config = { const config = {
content: ["./src/**/*.{js,jsx,ts,tsx}"], content: ["./src/**/*.{js,jsx,ts,tsx}"],
theme: {}, theme: {},
plugins: [typography, core], plugins: [typography, core, kobalte],
}; };
export default config; export default config;

View File

@@ -25,6 +25,19 @@ const mkBorderUtils = (
[`.${prefix}-def-4`]: { [`.${prefix}-def-4`]: {
[cssProperty]: theme("colors.secondary.400"), [cssProperty]: theme("colors.secondary.400"),
}, },
// - def acc colors
[`.${prefix}-def-acc-1`]: {
[cssProperty]: theme("colors.secondary.500"),
},
[`.${prefix}-def-acc-2`]: {
[cssProperty]: theme("colors.secondary.900"),
},
[`.${prefix}-def-acc-3`]: {
[cssProperty]: theme("colors.secondary.900"),
},
[`.${prefix}-def-acc-4`]: {
[cssProperty]: theme("colors.secondary.950"),
},
// - inverse colors // - inverse colors
[`.${prefix}-inv-1`]: { [`.${prefix}-inv-1`]: {
[cssProperty]: theme("colors.secondary.700"), [cssProperty]: theme("colors.secondary.700"),
@@ -38,7 +51,19 @@ const mkBorderUtils = (
[`.${prefix}-inv-4`]: { [`.${prefix}-inv-4`]: {
[cssProperty]: theme("colors.secondary.950"), [cssProperty]: theme("colors.secondary.950"),
}, },
// - inverse acc
[`.${prefix}-inv-acc-1`]: {
[cssProperty]: theme("colors.secondary.300"),
},
[`.${prefix}-inv-acc-2`]: {
[cssProperty]: theme("colors.secondary.200"),
},
[`.${prefix}-inv-acc-3`]: {
[cssProperty]: theme("colors.secondary.100"),
},
[`.${prefix}-inv-acc-4`]: {
[cssProperty]: theme("colors.secondary.50"),
},
[`.${prefix}-int-1`]: { [`.${prefix}-int-1`]: {
[cssProperty]: theme("colors.info.500"), [cssProperty]: theme("colors.info.500"),
}, },
@@ -191,7 +216,6 @@ export default plugin.withOptions(
...mkBorderUtils(theme, "border-t", "borderTop"), ...mkBorderUtils(theme, "border-t", "borderTop"),
...mkBorderUtils(theme, "border-l", "borderLeft"), ...mkBorderUtils(theme, "border-l", "borderLeft"),
...mkBorderUtils(theme, "border-r", "borderRight"), ...mkBorderUtils(theme, "border-r", "borderRight"),
...mkBorderUtils(theme, "outline", "outlineColor"),
// Example: dark mode utilities (all elements within <html class="dark"> ) // Example: dark mode utilities (all elements within <html class="dark"> )
// ".dark .bg-def-1": { // ".dark .bg-def-1": {
@@ -274,13 +298,21 @@ export default plugin.withOptions(
}, },
boxShadow: { boxShadow: {
"input-active": "0px 0px 0px 1px #FFF, 0px 0px 0px 2px #203637", "input-active": "0px 0px 0px 1px #FFF, 0px 0px 0px 2px #203637",
"inner-primary": "button-primary":
"2px 2px 0px 0px var(--clr-bg-inv-acc-3, #415E63) inset", "2px 2px 0px 0px var(--clr-bg-inv-acc-3, #415E63) inset",
"inner-primary-active": "button-primary-hover":
"0px 0px 0px 1px #FFF, 0px 0px 0px 2px var(--clr-bg-inv-acc-4, #203637)", "2px 2px 0px 0px var(--clr-bg-inv-acc-2, #4F747A) inset",
"inner-secondary": "button-primary-focus":
"0px 0px 0px 1px #FFF, 0px 0px 0px 2px var(--clr-border-def-sem-inf-1, #06AAF1), 2px 2px 0px 0px var(--clr-bg-inv-acc-2, #4F747A) inset",
"button-primary-active":
"0px 0px 0px 1px #FFF, 0px 0px 0px 2px var(--clr-bg-inv-acc-4, #203637), -2px -2px 0px 0px var(--clr-bg-inv-acc-1, #7B9B9F) inset",
"button-secondary":
"-2px -2px 0px 0px #CEDFE2 inset, 2px 2px 0px 0px white inset", "-2px -2px 0px 0px #CEDFE2 inset, 2px 2px 0px 0px white inset",
"inner-secondary-active": "button-secondary-hover":
"-2px -2px 0px 0px #CEDFE2 inset, 2px 2px 0px 0px #FFF inset",
"button-secondary-focus":
"0px 0px 0px 1px #FFF, 0px 0px 0px 2px var(--clr-border-def-sem-inf-1, #06AAF1), -2px -2px 0px 0px #CEDFE2 inset, 2px 2px 0px 0px #FFF inset",
"button-secondary-active":
"0px 0px 0px 1px white, 0px 0px 0px 2px var(--clr-bg-inv-acc-4, #203637), 2px 2px 0px 0px var(--clr-bg-inv-acc-2, #4F747A) inset", "0px 0px 0px 1px white, 0px 0px 0px 2px var(--clr-bg-inv-acc-4, #203637), 2px 2px 0px 0px var(--clr-bg-inv-acc-2, #4F747A) inset",
}, },
}, },

View File

@@ -13,7 +13,7 @@ pkgs.writeShellApplication {
text = '' text = ''
REPO_ROOT="$(git rev-parse --show-toplevel)" REPO_ROOT="$(git rev-parse --show-toplevel)"
OUT_DIR="$(realpath "$REPO_ROOT"/pkgs/clan-app/ui/app/icons)" OUT_DIR="$(realpath "$REPO_ROOT"/pkgs/clan-app/ui/src/icons)"
export OUT_DIR export OUT_DIR
deno run --allow-all ${src}/main.ts deno run --allow-all ${src}/main.ts
''; '';