feat(ui): new loader component; button and icon v2
@@ -45,10 +45,10 @@ let
|
||||
};
|
||||
};
|
||||
|
||||
firaCode = fetchzip {
|
||||
url = "https://github.com/tonsky/FiraCode/releases/download/6.2/Fira_Code_v6.2.zip";
|
||||
commitMono = fetchzip {
|
||||
url = "https://github.com/eigilnikolajsen/commit-mono/releases/download/v1.143/CommitMono-1.143.zip";
|
||||
stripRoot = false;
|
||||
hash = "sha256-UHOwZL9WpCHk6vZaqI/XfkZogKgycs5lWg1p0XdQt0A=";
|
||||
hash = "sha256-JTyPgWfbWq+lXQU/rgnyvPG6+V3f+FB5QUkd+I1oFKE=";
|
||||
};
|
||||
|
||||
in
|
||||
@@ -63,5 +63,5 @@ runCommand "" { } ''
|
||||
cp ${archivoSemi.medium} $out/ArchivoSemiCondensed-Medium.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
|
||||
''
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import type { Preview } from "@kachurun/storybook-solid";
|
||||
|
||||
import "@/src/components/v2/index.css";
|
||||
import "./preview.css";
|
||||
import "../src/index.css";
|
||||
import "./preview.css";
|
||||
|
||||
export const preview: Preview = {
|
||||
tags: ["autodocs"],
|
||||
|
||||
3
pkgs/clan-app/ui/icons/ai.svg
Normal 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 |
@@ -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 |
@@ -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 |
@@ -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 |
25
pkgs/clan-app/ui/icons/cursor.svg
Normal 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 |
5
pkgs/clan-app/ui/icons/dots.svg
Normal 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 |
3
pkgs/clan-app/ui/icons/heart.svg
Normal 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 |
3
pkgs/clan-app/ui/icons/machine.svg
Normal 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 |
3
pkgs/clan-app/ui/icons/modules.svg
Normal 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 |
3
pkgs/clan-app/ui/icons/new-machine.svg
Normal 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 |
13
pkgs/clan-app/ui/icons/offline.svg
Normal 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 |
3
pkgs/clan-app/ui/icons/search-filled.svg
Normal 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 |
8
pkgs/clan-app/ui/icons/switch.svg
Normal 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 |
3
pkgs/clan-app/ui/icons/tag.svg
Normal 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 |
3
pkgs/clan-app/ui/icons/user.svg
Normal 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 |
|
Before Width: | Height: | Size: 218 B After Width: | Height: | Size: 218 B |
356
pkgs/clan-app/ui/package-lock.json
generated
@@ -47,6 +47,7 @@
|
||||
"prettier": "^3.2.5",
|
||||
"solid-devtools": "^0.34.0",
|
||||
"storybook": "^8.6.14",
|
||||
"storybook-addon-pseudo-states": "^4.0.3",
|
||||
"tailwindcss": "^3.4.3",
|
||||
"typescript": "^5.4.5",
|
||||
"typescript-eslint": "^8.32.1",
|
||||
@@ -58,9 +59,12 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@floating-ui/dom": "^1.6.8",
|
||||
"@kobalte/core": "^0.13.10",
|
||||
"@kobalte/tailwindcss": "^0.9.0",
|
||||
"@modular-forms/solid": "^0.25.1",
|
||||
"@solid-primitives/storage": "^4.3.2",
|
||||
"@solidjs/router": "^0.15.3",
|
||||
"@storybook/test": "^8.6.14",
|
||||
"@tanstack/eslint-plugin-query": "^5.51.12",
|
||||
"@tanstack/solid-query": "^5.76.0",
|
||||
"corvu": "^0.7.1",
|
||||
|
||||
@@ -27,5 +27,5 @@
|
||||
}
|
||||
|
||||
.button--dark-active:active {
|
||||
@apply active:border-secondary-900 active:shadow-inner-primary-active;
|
||||
@apply active:border-secondary-900 active:shadow-button-primary-active;
|
||||
}
|
||||
|
||||
@@ -7,5 +7,5 @@
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
}
|
||||
|
||||
.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);
|
||||
|
||||
|
||||
@@ -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",
|
||||
],
|
||||
},
|
||||
};
|
||||
@@ -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>
|
||||
`;
|
||||
@@ -33,7 +33,7 @@ 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 Warning from "@/icons/warning.svg";
|
||||
import Warning from "@/icons/warning-filled.svg";
|
||||
|
||||
const icons = {
|
||||
ArrowBottom,
|
||||
|
||||
@@ -33,6 +33,7 @@ export const InputBase = (props: InputBaseProps) => {
|
||||
const [internal, inputProps] = splitProps(props, ["class", "divRef"]);
|
||||
return (
|
||||
<div
|
||||
// eslint-disable-next-line tailwindcss/no-custom-classname
|
||||
class={cx(
|
||||
// Layout
|
||||
"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,
|
||||
)}
|
||||
classList={{
|
||||
// eslint-disable-next-line tailwindcss/no-custom-classname
|
||||
[cx("!border !border-semantic-1 !outline-semantic-1")]: !!props.error,
|
||||
}}
|
||||
aria-invalid={props.error}
|
||||
|
||||
134
pkgs/clan-app/ui/src/components/v2/Button/Button.css
Normal 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;
|
||||
}
|
||||
43
pkgs/clan-app/ui/src/components/v2/Button/Button.mdx
Normal 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} />
|
||||
251
pkgs/clan-app/ui/src/components/v2/Button/Button.stories.tsx
Normal 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,
|
||||
};
|
||||
116
pkgs/clan-app/ui/src/components/v2/Button/Button.tsx
Normal 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>
|
||||
);
|
||||
};
|
||||
75
pkgs/clan-app/ui/src/components/v2/Icon/Icon.stories.tsx
Normal 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",
|
||||
},
|
||||
};
|
||||
126
pkgs/clan-app/ui/src/components/v2/Icon/Icon.tsx
Normal 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;
|
||||
104
pkgs/clan-app/ui/src/components/v2/Loader/Loader.css
Normal 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);
|
||||
}
|
||||
}
|
||||
23
pkgs/clan-app/ui/src/components/v2/Loader/Loader.stories.tsx
Normal 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",
|
||||
},
|
||||
};
|
||||
19
pkgs/clan-app/ui/src/components/v2/Loader/Loader.tsx
Normal 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>
|
||||
);
|
||||
};
|
||||
@@ -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>
|
||||
`;
|
||||
@@ -23,25 +23,25 @@
|
||||
|
||||
&.font-size-default {
|
||||
font-size: 1rem;
|
||||
line-height: 132%;
|
||||
line-height: 1.32;
|
||||
letter-spacing: 0.02rem;
|
||||
}
|
||||
|
||||
&.font-size-s {
|
||||
font-size: 0.875rem;
|
||||
line-height: 132%;
|
||||
line-height: 1.32;
|
||||
letter-spacing: 0.0175rem;
|
||||
}
|
||||
|
||||
&.font-size-xs {
|
||||
font-size: 0.75rem;
|
||||
line-height: 132%;
|
||||
line-height: 1.32;
|
||||
letter-spacing: 0.0225rem;
|
||||
}
|
||||
|
||||
&.font-size-xxs {
|
||||
font-size: 0.6875rem;
|
||||
line-height: 132%;
|
||||
line-height: 1.32;
|
||||
letter-spacing: 0.00688rem;
|
||||
}
|
||||
}
|
||||
@@ -52,38 +52,41 @@
|
||||
|
||||
&.font-size-default {
|
||||
font-size: 0.875rem;
|
||||
line-height: 132%;
|
||||
line-height: 1.32;
|
||||
letter-spacing: 0.0175rem;
|
||||
}
|
||||
|
||||
&.font-size-s {
|
||||
font-size: 0.8125rem;
|
||||
line-height: 132%;
|
||||
line-height: 1.32;
|
||||
letter-spacing: 0.0175rem;
|
||||
}
|
||||
|
||||
&.font-size-xs {
|
||||
font-size: 0.75rem;
|
||||
line-height: 132%;
|
||||
line-height: 1.32;
|
||||
letter-spacing: 0.0075rem;
|
||||
}
|
||||
}
|
||||
|
||||
&.font-family-mono {
|
||||
font-family: "Fira Code", monospace;
|
||||
font-family: "Commit Mono", monospace;
|
||||
|
||||
&.font-size-default {
|
||||
font-size: 0.8125rem;
|
||||
line-height: 0;
|
||||
letter-spacing: normal;
|
||||
}
|
||||
|
||||
&.font-size-s {
|
||||
font-size: 0.75rem;
|
||||
line-height: 0;
|
||||
letter-spacing: normal;
|
||||
}
|
||||
|
||||
&.font-size-xs {
|
||||
font-size: 0.6875rem;
|
||||
line-height: 0;
|
||||
letter-spacing: normal;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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> = {
|
||||
body: "condensed",
|
||||
label: "condensed",
|
||||
@@ -144,7 +124,7 @@ export const Typography = <H extends Hierarchy>(props: _TypographyProps<H>) => {
|
||||
const color = () => colorFor(props.color, props.inverted);
|
||||
|
||||
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-title": props.hierarchy === "title",
|
||||
"font-headline": props.hierarchy === "headline",
|
||||
|
||||
@@ -713,51 +713,51 @@ exports[`Components/Typography Headline smoke-test 1`] = `
|
||||
<tbody>
|
||||
<tr class="border-b border-def-3 even:bg-def-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
|
||||
</span>
|
||||
</td>
|
||||
<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
|
||||
</span>
|
||||
</td>
|
||||
<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
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="border-b border-def-3 even:bg-def-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
|
||||
</span>
|
||||
</td>
|
||||
<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
|
||||
</span>
|
||||
</td>
|
||||
<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
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="border-b border-def-3 even:bg-def-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
|
||||
</span>
|
||||
</td>
|
||||
<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
|
||||
</span>
|
||||
</td>
|
||||
<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
|
||||
</span>
|
||||
</td>
|
||||
@@ -771,51 +771,51 @@ exports[`Components/Typography LabelCondensed smoke-test 1`] = `
|
||||
<tbody>
|
||||
<tr class="border-b border-def-3 even:bg-def-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
|
||||
</span>
|
||||
</td>
|
||||
<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
|
||||
</span>
|
||||
</td>
|
||||
<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
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="border-b border-def-3 even:bg-def-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
|
||||
</span>
|
||||
</td>
|
||||
<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
|
||||
</span>
|
||||
</td>
|
||||
<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
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="border-b border-def-3 even:bg-def-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
|
||||
</span>
|
||||
</td>
|
||||
<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
|
||||
</span>
|
||||
</td>
|
||||
<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
|
||||
</span>
|
||||
</td>
|
||||
@@ -829,51 +829,51 @@ exports[`Components/Typography LabelMono smoke-test 1`] = `
|
||||
<tbody>
|
||||
<tr class="border-b border-def-3 even:bg-def-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
|
||||
</span>
|
||||
</td>
|
||||
<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
|
||||
</span>
|
||||
</td>
|
||||
<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
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="border-b border-def-3 even:bg-def-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
|
||||
</span>
|
||||
</td>
|
||||
<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
|
||||
</span>
|
||||
</td>
|
||||
<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
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="border-b border-def-3 even:bg-def-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
|
||||
</span>
|
||||
</td>
|
||||
<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
|
||||
</span>
|
||||
</td>
|
||||
<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
|
||||
</span>
|
||||
</td>
|
||||
@@ -887,7 +887,7 @@ exports[`Components/Typography Teaser smoke-test 1`] = `
|
||||
<tbody>
|
||||
<tr class="border-b border-def-3 even:bg-def-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
|
||||
</span>
|
||||
</td>
|
||||
@@ -901,51 +901,51 @@ exports[`Components/Typography Title smoke-test 1`] = `
|
||||
<tbody>
|
||||
<tr class="border-b border-def-3 even:bg-def-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
|
||||
</span>
|
||||
</td>
|
||||
<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
|
||||
</span>
|
||||
</td>
|
||||
<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
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="border-b border-def-3 even:bg-def-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
|
||||
</span>
|
||||
</td>
|
||||
<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
|
||||
</span>
|
||||
</td>
|
||||
<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
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="border-b border-def-3 even:bg-def-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
|
||||
</span>
|
||||
</td>
|
||||
<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
|
||||
</span>
|
||||
</td>
|
||||
<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
|
||||
</span>
|
||||
</td>
|
||||
|
||||
@@ -43,9 +43,50 @@
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Fira Code";
|
||||
font-family: "Commit Mono";
|
||||
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 {
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import typography from "@tailwindcss/typography";
|
||||
import kobalte from "@kobalte/tailwindcss";
|
||||
import core from "./tailwind/core-plugin";
|
||||
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
const config = {
|
||||
content: ["./src/**/*.{js,jsx,ts,tsx}"],
|
||||
theme: {},
|
||||
plugins: [typography, core],
|
||||
plugins: [typography, core, kobalte],
|
||||
};
|
||||
|
||||
export default config;
|
||||
|
||||
@@ -25,6 +25,19 @@ const mkBorderUtils = (
|
||||
[`.${prefix}-def-4`]: {
|
||||
[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
|
||||
[`.${prefix}-inv-1`]: {
|
||||
[cssProperty]: theme("colors.secondary.700"),
|
||||
@@ -38,7 +51,19 @@ const mkBorderUtils = (
|
||||
[`.${prefix}-inv-4`]: {
|
||||
[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`]: {
|
||||
[cssProperty]: theme("colors.info.500"),
|
||||
},
|
||||
@@ -191,7 +216,6 @@ export default plugin.withOptions(
|
||||
...mkBorderUtils(theme, "border-t", "borderTop"),
|
||||
...mkBorderUtils(theme, "border-l", "borderLeft"),
|
||||
...mkBorderUtils(theme, "border-r", "borderRight"),
|
||||
...mkBorderUtils(theme, "outline", "outlineColor"),
|
||||
|
||||
// Example: dark mode utilities (all elements within <html class="dark"> )
|
||||
// ".dark .bg-def-1": {
|
||||
@@ -274,13 +298,21 @@ export default plugin.withOptions(
|
||||
},
|
||||
boxShadow: {
|
||||
"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",
|
||||
"inner-primary-active":
|
||||
"0px 0px 0px 1px #FFF, 0px 0px 0px 2px var(--clr-bg-inv-acc-4, #203637)",
|
||||
"inner-secondary":
|
||||
"button-primary-hover":
|
||||
"2px 2px 0px 0px var(--clr-bg-inv-acc-2, #4F747A) inset",
|
||||
"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",
|
||||
"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",
|
||||
},
|
||||
},
|
||||
|
||||
@@ -13,7 +13,7 @@ pkgs.writeShellApplication {
|
||||
|
||||
text = ''
|
||||
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
|
||||
deno run --allow-all ${src}/main.ts
|
||||
'';
|
||||
|
||||