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
@@ -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
|
||||||
''
|
''
|
||||||
|
|||||||
@@ -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"],
|
||||||
|
|||||||
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",
|
"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",
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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 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,
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
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-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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -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
|
||||||
'';
|
'';
|
||||||
|
|||||||