homework 1: components

This commit is contained in:
2023-07-29 12:47:02 +02:00
parent e0792c6b6f
commit 06afed2826
35 changed files with 1343 additions and 14 deletions

View File

@@ -14,6 +14,9 @@
}, },
"dependencies": { "dependencies": {
"@fontsource/roboto": "^5.0.5", "@fontsource/roboto": "^5.0.5",
"@radix-ui/react-checkbox": "^1.0.4",
"@radix-ui/react-label": "^2.0.2",
"clsx": "^2.0.0",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0" "react-dom": "^18.2.0"
}, },

234
pnpm-lock.yaml generated
View File

@@ -8,6 +8,15 @@ dependencies:
'@fontsource/roboto': '@fontsource/roboto':
specifier: ^5.0.5 specifier: ^5.0.5
version: 5.0.5 version: 5.0.5
'@radix-ui/react-checkbox':
specifier: ^1.0.4
version: 1.0.4(@types/react-dom@18.2.7)(@types/react@18.2.15)(react-dom@18.2.0)(react@18.2.0)
'@radix-ui/react-label':
specifier: ^2.0.2
version: 2.0.2(@types/react-dom@18.2.7)(@types/react@18.2.15)(react-dom@18.2.0)(react@18.2.0)
clsx:
specifier: ^2.0.0
version: 2.0.0
react: react:
specifier: ^18.2.0 specifier: ^18.2.0
version: 18.2.0 version: 18.2.0
@@ -1396,7 +1405,6 @@ packages:
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dependencies: dependencies:
regenerator-runtime: 0.13.11 regenerator-runtime: 0.13.11
dev: true
/@babel/template@7.22.5: /@babel/template@7.22.5:
resolution: {integrity: sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==} resolution: {integrity: sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==}
@@ -1979,6 +1987,219 @@ packages:
tslib: 2.6.1 tslib: 2.6.1
dev: true dev: true
/@radix-ui/primitive@1.0.1:
resolution: {integrity: sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==}
dependencies:
'@babel/runtime': 7.22.6
dev: false
/@radix-ui/react-checkbox@1.0.4(@types/react-dom@18.2.7)(@types/react@18.2.15)(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-CBuGQa52aAYnADZVt/KBQzXrwx6TqnlwtcIPGtVt5JkkzQwMOLJjPukimhfKEr4GQNd43C+djUh5Ikopj8pSLg==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
react: ^16.8 || ^17.0 || ^18.0
react-dom: ^16.8 || ^17.0 || ^18.0
peerDependenciesMeta:
'@types/react':
optional: true
'@types/react-dom':
optional: true
dependencies:
'@babel/runtime': 7.22.6
'@radix-ui/primitive': 1.0.1
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.15)(react@18.2.0)
'@radix-ui/react-context': 1.0.1(@types/react@18.2.15)(react@18.2.0)
'@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.7)(@types/react@18.2.15)(react-dom@18.2.0)(react@18.2.0)
'@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.7)(@types/react@18.2.15)(react-dom@18.2.0)(react@18.2.0)
'@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.15)(react@18.2.0)
'@radix-ui/react-use-previous': 1.0.1(@types/react@18.2.15)(react@18.2.0)
'@radix-ui/react-use-size': 1.0.1(@types/react@18.2.15)(react@18.2.0)
'@types/react': 18.2.15
'@types/react-dom': 18.2.7
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
dev: false
/@radix-ui/react-compose-refs@1.0.1(@types/react@18.2.15)(react@18.2.0):
resolution: {integrity: sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==}
peerDependencies:
'@types/react': '*'
react: ^16.8 || ^17.0 || ^18.0
peerDependenciesMeta:
'@types/react':
optional: true
dependencies:
'@babel/runtime': 7.22.6
'@types/react': 18.2.15
react: 18.2.0
dev: false
/@radix-ui/react-context@1.0.1(@types/react@18.2.15)(react@18.2.0):
resolution: {integrity: sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==}
peerDependencies:
'@types/react': '*'
react: ^16.8 || ^17.0 || ^18.0
peerDependenciesMeta:
'@types/react':
optional: true
dependencies:
'@babel/runtime': 7.22.6
'@types/react': 18.2.15
react: 18.2.0
dev: false
/@radix-ui/react-label@2.0.2(@types/react-dom@18.2.7)(@types/react@18.2.15)(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-N5ehvlM7qoTLx7nWPodsPYPgMzA5WM8zZChQg8nyFJKnDO5WHdba1vv5/H6IO5LtJMfD2Q3wh1qHFGNtK0w3bQ==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
react: ^16.8 || ^17.0 || ^18.0
react-dom: ^16.8 || ^17.0 || ^18.0
peerDependenciesMeta:
'@types/react':
optional: true
'@types/react-dom':
optional: true
dependencies:
'@babel/runtime': 7.22.6
'@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.7)(@types/react@18.2.15)(react-dom@18.2.0)(react@18.2.0)
'@types/react': 18.2.15
'@types/react-dom': 18.2.7
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
dev: false
/@radix-ui/react-presence@1.0.1(@types/react-dom@18.2.7)(@types/react@18.2.15)(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
react: ^16.8 || ^17.0 || ^18.0
react-dom: ^16.8 || ^17.0 || ^18.0
peerDependenciesMeta:
'@types/react':
optional: true
'@types/react-dom':
optional: true
dependencies:
'@babel/runtime': 7.22.6
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.15)(react@18.2.0)
'@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.15)(react@18.2.0)
'@types/react': 18.2.15
'@types/react-dom': 18.2.7
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
dev: false
/@radix-ui/react-primitive@1.0.3(@types/react-dom@18.2.7)(@types/react@18.2.15)(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
react: ^16.8 || ^17.0 || ^18.0
react-dom: ^16.8 || ^17.0 || ^18.0
peerDependenciesMeta:
'@types/react':
optional: true
'@types/react-dom':
optional: true
dependencies:
'@babel/runtime': 7.22.6
'@radix-ui/react-slot': 1.0.2(@types/react@18.2.15)(react@18.2.0)
'@types/react': 18.2.15
'@types/react-dom': 18.2.7
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
dev: false
/@radix-ui/react-slot@1.0.2(@types/react@18.2.15)(react@18.2.0):
resolution: {integrity: sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==}
peerDependencies:
'@types/react': '*'
react: ^16.8 || ^17.0 || ^18.0
peerDependenciesMeta:
'@types/react':
optional: true
dependencies:
'@babel/runtime': 7.22.6
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.15)(react@18.2.0)
'@types/react': 18.2.15
react: 18.2.0
dev: false
/@radix-ui/react-use-callback-ref@1.0.1(@types/react@18.2.15)(react@18.2.0):
resolution: {integrity: sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==}
peerDependencies:
'@types/react': '*'
react: ^16.8 || ^17.0 || ^18.0
peerDependenciesMeta:
'@types/react':
optional: true
dependencies:
'@babel/runtime': 7.22.6
'@types/react': 18.2.15
react: 18.2.0
dev: false
/@radix-ui/react-use-controllable-state@1.0.1(@types/react@18.2.15)(react@18.2.0):
resolution: {integrity: sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA==}
peerDependencies:
'@types/react': '*'
react: ^16.8 || ^17.0 || ^18.0
peerDependenciesMeta:
'@types/react':
optional: true
dependencies:
'@babel/runtime': 7.22.6
'@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.15)(react@18.2.0)
'@types/react': 18.2.15
react: 18.2.0
dev: false
/@radix-ui/react-use-layout-effect@1.0.1(@types/react@18.2.15)(react@18.2.0):
resolution: {integrity: sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ==}
peerDependencies:
'@types/react': '*'
react: ^16.8 || ^17.0 || ^18.0
peerDependenciesMeta:
'@types/react':
optional: true
dependencies:
'@babel/runtime': 7.22.6
'@types/react': 18.2.15
react: 18.2.0
dev: false
/@radix-ui/react-use-previous@1.0.1(@types/react@18.2.15)(react@18.2.0):
resolution: {integrity: sha512-cV5La9DPwiQ7S0gf/0qiD6YgNqM5Fk97Kdrlc5yBcrF3jyEZQwm7vYFqMo4IfeHgJXsRaMvLABFtd0OVEmZhDw==}
peerDependencies:
'@types/react': '*'
react: ^16.8 || ^17.0 || ^18.0
peerDependenciesMeta:
'@types/react':
optional: true
dependencies:
'@babel/runtime': 7.22.6
'@types/react': 18.2.15
react: 18.2.0
dev: false
/@radix-ui/react-use-size@1.0.1(@types/react@18.2.15)(react@18.2.0):
resolution: {integrity: sha512-ibay+VqrgcaI6veAojjofPATwledXiSmX+C0KrBk/xgpX9rBzPV3OsfwlhQdUOFbh+LKQorLYT+xTXW9V8yd0g==}
peerDependencies:
'@types/react': '*'
react: ^16.8 || ^17.0 || ^18.0
peerDependenciesMeta:
'@types/react':
optional: true
dependencies:
'@babel/runtime': 7.22.6
'@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.15)(react@18.2.0)
'@types/react': 18.2.15
react: 18.2.0
dev: false
/@rollup/pluginutils@5.0.2: /@rollup/pluginutils@5.0.2:
resolution: {integrity: sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==} resolution: {integrity: sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==}
engines: {node: '>=14.0.0'} engines: {node: '>=14.0.0'}
@@ -3109,7 +3330,6 @@ packages:
/@types/prop-types@15.7.5: /@types/prop-types@15.7.5:
resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==}
dev: true
/@types/qs@6.9.7: /@types/qs@6.9.7:
resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==} resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==}
@@ -3123,7 +3343,6 @@ packages:
resolution: {integrity: sha512-GRaAEriuT4zp9N4p1i8BDBYmEyfo+xQ3yHjJU4eiK5NDa1RmUZG+unZABUTK4/Ox/M+GaHwb6Ow8rUITrtjszA==} resolution: {integrity: sha512-GRaAEriuT4zp9N4p1i8BDBYmEyfo+xQ3yHjJU4eiK5NDa1RmUZG+unZABUTK4/Ox/M+GaHwb6Ow8rUITrtjszA==}
dependencies: dependencies:
'@types/react': 18.2.15 '@types/react': 18.2.15
dev: true
/@types/react@18.2.15: /@types/react@18.2.15:
resolution: {integrity: sha512-oEjE7TQt1fFTFSbf8kkNuc798ahTUzn3Le67/PWjE8MAfYAD/qB7O8hSTcromLFqHCt9bcdOg5GXMokzTjJ5SA==} resolution: {integrity: sha512-oEjE7TQt1fFTFSbf8kkNuc798ahTUzn3Le67/PWjE8MAfYAD/qB7O8hSTcromLFqHCt9bcdOg5GXMokzTjJ5SA==}
@@ -3131,11 +3350,9 @@ packages:
'@types/prop-types': 15.7.5 '@types/prop-types': 15.7.5
'@types/scheduler': 0.16.3 '@types/scheduler': 0.16.3
csstype: 3.1.2 csstype: 3.1.2
dev: true
/@types/scheduler@0.16.3: /@types/scheduler@0.16.3:
resolution: {integrity: sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==} resolution: {integrity: sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==}
dev: true
/@types/semver@7.5.0: /@types/semver@7.5.0:
resolution: {integrity: sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==} resolution: {integrity: sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==}
@@ -4046,6 +4263,11 @@ packages:
engines: {node: '>=0.8'} engines: {node: '>=0.8'}
dev: true dev: true
/clsx@2.0.0:
resolution: {integrity: sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==}
engines: {node: '>=6'}
dev: false
/color-convert@1.9.3: /color-convert@1.9.3:
resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
dependencies: dependencies:
@@ -4215,7 +4437,6 @@ packages:
/csstype@3.1.2: /csstype@3.1.2:
resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==} resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==}
dev: true
/debug@2.6.9: /debug@2.6.9:
resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==}
@@ -7459,7 +7680,6 @@ packages:
/regenerator-runtime@0.13.11: /regenerator-runtime@0.13.11:
resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==}
dev: true
/regenerator-transform@0.15.1: /regenerator-transform@0.15.1:
resolution: {integrity: sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==} resolution: {integrity: sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==}

View File

@@ -0,0 +1,21 @@
import { SVGProps, Ref, forwardRef, memo } from 'react'
const SvgComponent = (props: SVGProps<SVGSVGElement>, ref: Ref<SVGSVGElement>) => (
<svg xmlns="http://www.w3.org/2000/svg" width={32} height={32} fill="none" ref={ref} {...props}>
<circle cx={16} cy={16} r={15.5} fill="gray" stroke="#fff" />
<path
fill="#fff"
fillRule="evenodd"
d="M16 18.84a2.49 2.49 0 1 0 0-4.97 2.49 2.49 0 0 0 0 4.97Zm0-.62a1.87 1.87 0 1 0 0-3.73 1.87 1.87 0 0 0 0 3.73Z"
clipRule="evenodd"
/>
<path
fill="#fff"
fillRule="evenodd"
d="M19 11.38a3.86 3.86 0 0 0-3.02-1.25c-1.59 0-2.28.56-3.02 1.25H10.4c-1.03 0-1.87.83-1.87 1.86v6.23c0 1.03.84 1.86 1.87 1.86h11.2c1.03 0 1.87-.83 1.87-1.86v-6.23c0-1.03-.84-1.86-1.87-1.86H19Zm-.25.62-.06-.06-.18-.17a5.4 5.4 0 0 0-.67-.53 3.15 3.15 0 0 0-1.86-.48c-.92 0-1.44.2-1.87.48a5.4 5.4 0 0 0-.66.53l-.18.17-.07.06h-2.8c-.69 0-1.24.56-1.24 1.24v6.23c0 .68.55 1.24 1.24 1.24h11.2c.69 0 1.24-.56 1.24-1.24v-6.23c0-.68-.55-1.24-1.24-1.24h-2.85Z"
clipRule="evenodd"
/>
</svg>
)
const ForwardRef = forwardRef(SvgComponent)
export default memo(ForwardRef)

View File

@@ -0,0 +1,20 @@
import { SVGProps, Ref, forwardRef, memo } from 'react'
const SvgComponent = (props: SVGProps<SVGSVGElement>, ref: Ref<SVGSVGElement>) => (
<svg
width={18}
height={18}
viewBox="0 0 18 18"
fill="none"
xmlns="http://www.w3.org/2000/svg"
ref={ref}
{...props}
>
<path
d="M16 0H2a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2V2a2 2 0 00-2-2zM7 14L2 9l1.41-1.41L7 11.17l7.59-7.59L16 5l-9 9z"
fill="currentColor"
/>
</svg>
)
const ForwardRef = forwardRef(SvgComponent)
export default memo(ForwardRef)

View File

@@ -0,0 +1,28 @@
import { SVGProps, Ref, forwardRef, memo } from 'react'
const ChevronUp = (props: SVGProps<SVGSVGElement>, ref: Ref<SVGSVGElement>) => (
<svg
width={12}
height={12}
viewBox="0 0 12 12"
fill="none"
xmlns="http://www.w3.org/2000/svg"
ref={ref}
{...props}
>
<g clipPath="url(#clip0_9209_3250)">
<path
d="M9.77084 7.25705C9.77107 7.37388 9.73039 7.4871 9.65584 7.57705C9.61387 7.62768 9.56232 7.66953 9.50415 7.70021C9.44597 7.73089 9.38232 7.74978 9.31683 7.75582C9.25134 7.76186 9.18531 7.75492 9.1225 7.7354C9.0597 7.71588 9.00137 7.68416 8.95084 7.64205L6.27084 5.40205L3.58584 7.56205C3.5347 7.60359 3.47585 7.6346 3.41268 7.65332C3.34951 7.67203 3.28327 7.67808 3.21775 7.67111C3.15224 7.66414 3.08875 7.64429 3.03093 7.61271C2.97311 7.58112 2.92211 7.53842 2.88084 7.48705C2.83533 7.43532 2.80099 7.37474 2.78 7.30911C2.759 7.24348 2.7518 7.17421 2.75884 7.10567C2.76589 7.03712 2.78702 6.97077 2.82092 6.91078C2.85482 6.85079 2.90076 6.79845 2.95584 6.75705L5.95584 4.34205C6.04531 4.26851 6.15753 4.22831 6.27334 4.22831C6.38916 4.22831 6.50138 4.26851 6.59084 4.34205L9.59084 6.84205C9.65135 6.89221 9.69918 6.95593 9.73046 7.02803C9.76173 7.10014 9.77557 7.1786 9.77084 7.25705Z"
fill="white"
/>
</g>
<defs>
<clipPath id="clip0_9209_3250">
<rect width={12} height={12} fill="white" />
</clipPath>
</defs>
</svg>
)
const ForwardRef = forwardRef(ChevronUp)
const Memo = memo(ForwardRef)
export default Memo

View File

@@ -0,0 +1,30 @@
import { SVGProps, Ref, forwardRef, memo } from 'react'
const SvgComponent = (props: SVGProps<SVGSVGElement>, ref: Ref<SVGSVGElement>) => (
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
ref={ref}
{...props}
>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
<g clipPath="url(#clip0_9883_2381)">
<path
d="M19 6.41L17.59 5L12 10.59L6.41 5L5 6.41L10.59 12L5 17.59L6.41 19L12 13.41L17.59 19L19 17.59L13.41 12L19 6.41Z"
fill="white"
/>
</g>
<defs>
<clipPath id="clip0_9883_2381">
<rect width="24" height="24" fill="white" />
</clipPath>
</defs>
</svg>
</svg>
)
const ForwardRef = forwardRef(SvgComponent)
export default memo(ForwardRef)

32
src/assets/icons/edit.tsx Normal file
View File

@@ -0,0 +1,32 @@
import { SVGProps, Ref, forwardRef, memo } from 'react'
const SvgComponent = (props: SVGProps<SVGSVGElement>, ref: Ref<SVGSVGElement>) => (
<svg
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
ref={ref}
{...props}
>
<g clipPath="url(#clip0_5918_2436)">
<path
d="M12.6666 13.3334H3.33329C3.15648 13.3334 2.98691 13.4036 2.86189 13.5286C2.73686 13.6537 2.66663 13.8232 2.66663 14C2.66663 14.1769 2.73686 14.3464 2.86189 14.4714C2.98691 14.5965 3.15648 14.6667 3.33329 14.6667H12.6666C12.8434 14.6667 13.013 14.5965 13.138 14.4714C13.2631 14.3464 13.3333 14.1769 13.3333 14C13.3333 13.8232 13.2631 13.6537 13.138 13.5286C13.013 13.4036 12.8434 13.3334 12.6666 13.3334Z"
fill="white"
/>
<path
d="M3.33329 12H3.39329L6.17329 11.7467C6.47782 11.7163 6.76264 11.5821 6.97995 11.3667L12.98 5.36665C13.2128 5.12063 13.3387 4.79233 13.3299 4.45368C13.3212 4.11503 13.1786 3.79366 12.9333 3.55999L11.1066 1.73332C10.8682 1.50938 10.5558 1.38089 10.2288 1.37229C9.90187 1.36368 9.58314 1.47557 9.33329 1.68665L3.33329 7.68665C3.1178 7.90396 2.98362 8.18879 2.95329 8.49332L2.66662 11.2733C2.65764 11.371 2.67031 11.4694 2.70373 11.5616C2.73715 11.6538 2.79049 11.7374 2.85995 11.8067C2.92225 11.8684 2.99612 11.9173 3.07735 11.9505C3.15857 11.9837 3.24555 12.0005 3.33329 12ZM10.18 2.66665L12 4.48665L10.6666 5.78665L8.87995 3.99999L10.18 2.66665ZM4.24662 8.60665L7.99995 4.87999L9.79995 6.67999L6.06662 10.4133L4.06662 10.6L4.24662 8.60665Z"
fill="white"
/>
</g>
<defs>
<clipPath id="clip0_5918_2436">
<rect width="16" height="16" fill="white" />
</clipPath>
</defs>
</svg>
)
const ForwardRef = forwardRef(SvgComponent)
const Memo = memo(ForwardRef)
export default Memo

View File

@@ -0,0 +1,74 @@
import { SVGProps, Ref, forwardRef, memo } from 'react'
const SvgComponent = (props: SVGProps<SVGSVGElement>, ref: Ref<SVGSVGElement>) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width={96}
height={96}
fill="none"
viewBox="0 0 96 96"
ref={ref}
{...props}
>
<path
fill="#8C61FF"
fillOpacity={0.05}
stroke="#BEA6FF"
d="M95.5 48c0 26.234-21.266 47.5-47.5 47.5C21.767 95.5.5 74.234.5 48 .5 21.767 21.767.5 48 .5 74.234.5 95.5 21.767 95.5 48z"
/>
<path
fill="#BEA6FF"
d="M77.889 54.454a.651.651 0 0 1-.643-.643v-9.24a.643.643 0 0 1 1.285 0v9.25a.643.643 0 0 1-.641.633zM77.889 41.777a.643.643 0 0 1-.643-.643V39.24a.643.643 0 0 1 1.285 0v1.903a.634.634 0 0 1-.641.634zM25.786 32.503h-3.559a.668.668 0 0 1 0-1.335h3.56a.667.667 0 0 1 0 1.335z"
/>
<path
fill="#BEA6FF"
d="M24.007 34.282a.668.668 0 0 1-.667-.667v-3.559a.668.668 0 0 1 1.335 0v3.56c0 .367-.3.666-.668.666zM36.857 73.714a.857.857 0 1 1 0 1.715.857.857 0 0 1 0-1.715zM31.714 73.714a.857.857 0 1 1 0 1.715.857.857 0 0 1 0-1.715zM26.571 73.714a.857.857 0 1 1 0 1.715.857.857 0 0 1 0-1.715z"
/>
<path fill="#333" d="M47.864 23.242l-24.1 19.799 24.1 19.808 24.1-19.808-24.1-19.8z" />
<path
fill="#BEA6FF"
d="M47.865 63.544a.667.667 0 0 1-.417-.195l-24.1-19.808a.698.698 0 0 1-.183-.833.725.725 0 0 1 .183-.242l24.1-19.799a.695.695 0 0 1 .926 0l24.1 19.799a.725.725 0 0 1 .25.537.695.695 0 0 1-.25.538l-24.1 19.808a.668.668 0 0 1-.51.195zM24.859 43.04l23.006 18.91L70.87 43.04l-23.006-18.9-23.006 18.9z"
/>
<path fill="#333" d="M65.013 28.803H30.717v40.784h34.296V28.803z" />
<path fill="#333" d="M55.41 40.853l-11.716 9.63v19.104h21.319V40.853H55.41z" />
<path
fill="#BEA6FF"
d="M65.059 70.282H30.763a.704.704 0 0 1-.695-.695V28.803a.695.695 0 0 1 .695-.677H65.06a.695.695 0 0 1 .695.696v40.784a.705.705 0 0 1-.695.676zM31.412 68.91h32.905V29.517H31.412V68.91z"
/>
<path
fill="#BEA6FF"
d="M58.987 35.06H48.17a.695.695 0 0 1 0-1.39h10.817a.696.696 0 0 1 0 1.39zM44.463 35.06h-7.721a.696.696 0 0 1 0-1.39h7.72a.696.696 0 0 1 0 1.39zM58.987 39.694h-7.11a.695.695 0 0 1 0-1.39h7.11a.695.695 0 1 1 0 1.39zM48.17 39.694H36.742a.695.695 0 0 1 0-1.39H48.17a.695.695 0 1 1 0 1.39zM58.988 44.329H46.317a.696.696 0 0 1 0-1.39h12.67a.696.696 0 0 1 0 1.39zM42.609 44.329h-5.867a.696.696 0 0 1 0-1.39h5.867a.696.696 0 0 1 0 1.39zM58.987 48.964h-6.182a.695.695 0 0 1 0-1.39h6.182a.695.695 0 1 1 0 1.39zM49.097 48.964H36.742a.695.695 0 0 1 0-1.39h12.355a.695.695 0 1 1 0 1.39zM54.047 53.598H41.682a.695.695 0 1 1 0-1.39h12.365a.695.695 0 1 1 0 1.39z"
/>
<path
fill="#333"
d="M23.765 43.04v26.547l16.147-13.273L23.765 43.04zM55.818 56.314l16.146 13.273V43.04L55.818 56.315z"
/>
<path
fill="#333"
d="M47.864 62.849l-7.952-6.535-16.147 13.273h48.2L55.816 56.314l-7.953 6.535z"
/>
<path
fill="#333"
d="M28.4 50.493v15.284l9.297-7.637-9.297-7.647zM63.196 57.88l8.768 7.212V50.678l-8.768 7.202z"
/>
<path
fill="#BEA6FF"
d="M23.765 70.282a.67.67 0 0 1-.296-.074.686.686 0 0 1-.399-.62V43.04a.685.685 0 0 1 .399-.62.695.695 0 0 1 .741.083l16.147 13.273a.704.704 0 0 1 0 1.075L24.21 70.115a.686.686 0 0 1-.445.167zm.695-25.768v23.6l14.358-11.8-14.358-11.8z"
/>
<path fill="#333" d="M60.424 60.095l-10.15 8.343-7.08-5.821-8.473 6.97h37.243l-11.54-9.492z" />
<path
fill="#BEA6FF"
d="M71.964 70.282a.686.686 0 0 1-.445-.167L55.373 56.861a.703.703 0 0 1 0-1.076l16.174-13.282a.696.696 0 0 1 .742-.084.687.687 0 0 1 .398.621v26.547a.686.686 0 0 1-.398.621.668.668 0 0 1-.325.074zM56.911 56.314l14.358 11.8v-23.6l-14.358 11.8z"
/>
<path
fill="#BEA6FF"
d="M71.964 70.282h-48.2a.704.704 0 0 1-.657-.463.705.705 0 0 1 .213-.77l16.147-13.273a.695.695 0 0 1 .927 0l7.508 6.173 7.508-6.174a.695.695 0 0 1 .927 0L72.483 69.05a.705.705 0 0 1 .213.77.704.704 0 0 1-.732.463zm-46.262-1.371h44.325L55.79 57.212l-7.508 6.173a.695.695 0 0 1-.927 0l-7.508-6.173L25.702 68.91zM46.358 75.36h-3.56a.668.668 0 0 1 0-1.335h3.56a.668.668 0 0 1 0 1.335z"
/>
<path
fill="#BEA6FF"
d="M44.579 77.14a.668.668 0 0 1-.668-.668v-3.559a.668.668 0 0 1 1.335 0v3.56a.667.667 0 0 1-.667.666z"
/>
</svg>
)
const ForwardRef = forwardRef(SvgComponent)
export default memo(ForwardRef)

22
src/assets/icons/eye.tsx Normal file
View File

@@ -0,0 +1,22 @@
import { SVGProps, Ref, forwardRef, memo } from 'react'
const SvgComponent = (props: SVGProps<SVGSVGElement>, ref: Ref<SVGSVGElement>) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width={20}
height={20}
fill="none"
viewBox="0 0 24 24"
ref={ref}
{...props}
>
<path
fill="#fff"
fillRule="evenodd"
d="M12 4.5C7 4.5 2.73 7.6 1 12a11.83 11.83 0 0 0 22 0c-1.73-4.39-6-7.5-11-7.5zM12 17a5 5 0 1 1 0-10 5 5 0 0 1 0 10zm0-8a3 3 0 1 0 0 6 3 3 0 0 0 0-6z"
clipRule="evenodd"
/>
</svg>
)
const ForwardRef = forwardRef(SvgComponent)
export default memo(ForwardRef)

11
src/assets/icons/index.ts Normal file
View File

@@ -0,0 +1,11 @@
export { default as Eye } from './eye'
export { default as VisibilityOff } from './visibility-off'
export { default as Check } from './check'
export { default as Email } from './email'
export { default as Camera } from './camera'
export { default as Logout } from './logout'
export { default as Edit } from './edit'
export { default as Logo } from './logo'
export { default as PersonOutline } from './person-outline'
export { default as ChevronUp } from './chevron-up'
export { default as Close } from './close'

30
src/assets/icons/logo.tsx Normal file
View File

@@ -0,0 +1,30 @@
import { SVGProps } from 'react'
const SvgComponent = (props: SVGProps<SVGSVGElement>) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width={157}
height={36}
fill="none"
viewBox="0 0 157 36"
{...props}
>
<path
fill="#fff"
d="M70.99 24.72a7.34 7.34 0 0 1-3.5-.83 6.43 6.43 0 0 1-2.44-2.33c-.6-1-.89-2.13-.89-3.38s.3-2.37.89-3.36c.6-1 1.41-1.77 2.45-2.32a7.25 7.25 0 0 1 3.5-.85c1.1 0 2.08.19 2.96.57.89.39 1.63.94 2.23 1.66l-1.87 1.74a4.02 4.02 0 0 0-3.17-1.48c-.78 0-1.48.17-2.09.52-.6.34-1.09.81-1.44 1.43-.33.61-.5 1.3-.5 2.1 0 .77.17 1.47.5 2.09.35.6.83 1.1 1.44 1.44.61.34 1.31.5 2.1.5a4 4 0 0 0 3.16-1.5l1.87 1.74c-.6.73-1.34 1.3-2.23 1.68a7.4 7.4 0 0 1-2.97.58zM83.66 24.72c-1.8 0-3.2-.5-4.22-1.5-1-1-1.5-2.43-1.5-4.28v-7.08h2.93v6.97c0 2.26.93 3.4 2.8 3.4.92 0 1.61-.28 2.1-.82.47-.55.71-1.41.71-2.58v-6.97h2.89v7.08c0 1.85-.5 3.28-1.52 4.28-1 1-2.4 1.5-4.2 1.5zM101.5 17.93a3.13 3.13 0 0 1 2.3 3.12c0 1.1-.42 1.96-1.29 2.56-.84.6-2.09.9-3.73.9h-6.52V11.86h6.16c1.53 0 2.7.3 3.53.89a2.8 2.8 0 0 1 1.24 2.4 3.04 3.04 0 0 1-1.68 2.78zm-6.35-3.86v2.97h2.9c.72 0 1.26-.12 1.63-.38.38-.25.56-.62.56-1.11 0-.5-.18-.86-.56-1.1a2.92 2.92 0 0 0-1.63-.38h-2.9zm3.4 8.23c.77 0 1.34-.13 1.73-.38.4-.25.6-.65.6-1.18 0-1.04-.78-1.57-2.33-1.57h-3.4v3.13h3.4zM114.32 21.8h-5.85l-1.12 2.7h-2.99l5.62-12.64h2.88l5.64 12.64h-3.07l-1.11-2.7zm-.92-2.23l-2-4.84-2 4.84h4zM121.78 14.25h-4.03v-2.39h10.98v2.39h-4.03V24.5h-2.92V14.25zM136.23 24.72a7.4 7.4 0 0 1-3.55-.85 6.39 6.39 0 0 1-2.47-2.33 6.5 6.5 0 0 1-.88-3.36 6.34 6.34 0 0 1 3.35-5.69 7.4 7.4 0 0 1 3.55-.84c1.3 0 2.48.28 3.53.85a6.35 6.35 0 0 1 3.37 5.68 6.4 6.4 0 0 1-.9 3.36 6.4 6.4 0 0 1-2.47 2.33 7.29 7.29 0 0 1-3.53.85zm0-2.5a3.69 3.69 0 0 0 3.42-1.95c.35-.6.52-1.3.52-2.09 0-.78-.17-1.48-.52-2.1a3.56 3.56 0 0 0-1.4-1.42 3.94 3.94 0 0 0-2.02-.52 3.94 3.94 0 0 0-3.44 1.95c-.34.61-.5 1.3-.5 2.1 0 .77.16 1.47.5 2.09a3.82 3.82 0 0 0 3.44 1.94zM153.35 24.5l-2.43-3.52H148.24v3.52h-2.92V11.86h5.45c1.12 0 2.09.19 2.9.56.83.38 1.47.9 1.91 1.6.44.68.67 1.49.67 2.43a4.3 4.3 0 0 1-.69 2.44 4.25 4.25 0 0 1-1.9 1.55l2.82 4.06h-3.13zm-.06-8.05c0-.71-.22-1.25-.68-1.63-.45-.38-1.11-.57-1.99-.57h-2.36v4.4h2.37c.88 0 1.54-.2 2-.58a2 2 0 0 0 .68-1.62zM0 11.88h2.91v12.6H0v-12.6zM8.5 14.25H4.49v-2.37h10.97v2.37h-4.03v10.22H8.5V14.25zM33.74 11.88h2.92v12.6h-2.92v-12.6zM51.2 11.88v12.6h-2.39l-6.28-7.65v7.64h-2.88v-12.6h2.41l6.27 7.65v-7.64h2.88z"
/>
<path
fill="#FF0808"
fillRule="evenodd"
d="M34.99 6.53a1.96 1.96 0 1 1 0 3.93 1.96 1.96 0 0 1 0-3.93z"
clipRule="evenodd"
/>
<path
fill="#fff"
fillRule="evenodd"
d="M19.5 16.04A2 2 0 0 1 21.5 18a2 2 0 0 1-2 1.96A2 2 0 0 1 17.46 18a2 2 0 0 1 2.02-1.96zM42.48 34.5a16.5 16.5 0 1 0 0-33 16.5 16.5 0 0 0 0 33zm0 1.5a18 18 0 1 0 0-36 18 18 0 0 0 0 36z"
clipRule="evenodd"
/>
</svg>
)
export default SvgComponent

View File

@@ -0,0 +1,31 @@
import { SVGProps, Ref, forwardRef, memo } from 'react'
const SvgComponent = (props: SVGProps<SVGSVGElement>, ref: Ref<SVGSVGElement>) => (
<svg
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
ref={ref}
{...props}
>
<g clipPath="url(#clip0_6627_107)">
<path
d="M4.66663 3.99996C4.84344 3.99996 5.01301 3.92972 5.13803 3.8047C5.26305 3.67967 5.33329 3.5101 5.33329 3.33329C5.33329 3.15648 5.26305 2.98691 5.13803 2.86189C5.01301 2.73686 4.84344 2.66663 4.66663 2.66663H3.33329C3.15648 2.66663 2.98691 2.73686 2.86189 2.86189C2.73686 2.98691 2.66663 3.15648 2.66663 3.33329V12.6666C2.66663 12.8434 2.73686 13.013 2.86189 13.138C2.98691 13.2631 3.15648 13.3333 3.33329 13.3333H4.66663C4.84344 13.3333 5.01301 13.2631 5.13803 13.138C5.26305 13.013 5.33329 12.8434 5.33329 12.6666C5.33329 12.4898 5.26305 12.3202 5.13803 12.1952C5.01301 12.0702 4.84344 12 4.66663 12H3.99996V3.99996H4.66663Z"
fill="white"
/>
<path
d="M13.88 7.61338L12 4.94672C11.898 4.80299 11.7433 4.70548 11.5697 4.67549C11.396 4.64551 11.2176 4.6855 11.0733 4.78672C11.0012 4.83724 10.9399 4.90154 10.8927 4.97592C10.8456 5.05029 10.8137 5.13326 10.7988 5.22004C10.784 5.30681 10.7864 5.39568 10.8061 5.4815C10.8257 5.56732 10.8622 5.64839 10.9133 5.72005L12.06 7.33338H6.66667C6.48986 7.33338 6.32029 7.40362 6.19526 7.52864C6.07024 7.65367 6 7.82324 6 8.00005C6 8.17686 6.07024 8.34643 6.19526 8.47145C6.32029 8.59648 6.48986 8.66672 6.66667 8.66672H12L10.8 10.2667C10.7475 10.3368 10.7093 10.4165 10.6875 10.5013C10.6658 10.5861 10.661 10.6743 10.6734 10.761C10.6857 10.8477 10.7151 10.931 10.7597 11.0064C10.8043 11.0817 10.8633 11.1475 10.9333 11.2C11.0487 11.2866 11.1891 11.3334 11.3333 11.3334C11.4368 11.3334 11.5389 11.3093 11.6315 11.263C11.724 11.2167 11.8046 11.1495 11.8667 11.0667L13.8667 8.40005C13.952 8.28729 13.9994 8.15031 14.0018 8.00889C14.0041 7.86748 13.9615 7.72897 13.88 7.61338Z"
fill="white"
/>
</g>
<defs>
<clipPath id="clip0_6627_107">
<rect width="16" height="16" fill="white" />
</clipPath>
</defs>
</svg>
)
const ForwardRef = forwardRef(SvgComponent)
export default memo(ForwardRef)

View File

@@ -0,0 +1,22 @@
import { SVGProps } from 'react'
const SvgComponent = (props: SVGProps<SVGSVGElement>) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width={16}
height={16}
fill="none"
viewBox="0 0 16 16"
{...props}
>
<g fill="#fff" clipPath="url(#clip0_6693_1154)">
<path d="M8 7.334a2.667 2.667 0 1 0 0-5.333 2.667 2.667 0 0 0 0 5.334zm0-4a1.333 1.333 0 1 1 0 2.667 1.333 1.333 0 0 1 0-2.666zM8 8.668a4.667 4.667 0 0 0-4.667 4.666.667.667 0 1 0 1.334 0 3.333 3.333 0 0 1 6.666 0 .667.667 0 1 0 1.334 0A4.667 4.667 0 0 0 8 8.668z" />
</g>
<defs>
<clipPath id="clip0_6693_1154">
<path fill="#fff" d="M0 0h16v16H0z" />
</clipPath>
</defs>
</svg>
)
export default SvgComponent

View File

@@ -0,0 +1,20 @@
import { SVGProps, Ref, forwardRef, memo } from 'react'
const SvgComponent = (props: SVGProps<SVGSVGElement>, ref: Ref<SVGSVGElement>) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width={20}
height={20}
fill="none"
viewBox="0 0 24 24"
ref={ref}
{...props}
>
<path
fill="#fff"
d="M12 5.975a9.77 9.77 0 0 1 8.82 5.5 9.647 9.647 0 0 1-2.41 3.12l1.41 1.41c1.39-1.23 2.49-2.77 3.18-4.53-1.73-4.39-6-7.5-11-7.5-1.27 0-2.49.2-3.64.57l1.65 1.65c.65-.13 1.31-.22 1.99-.22zm-1.07 1.14L13 9.185c.57.25 1.03.71 1.28 1.28l2.07 2.07c.08-.34.14-.7.14-1.07.01-2.48-2.01-4.49-4.49-4.49-.37 0-.72.05-1.07.14zm-8.92-3.27l2.68 2.68A11.738 11.738 0 0 0 1 11.475c1.73 4.39 6 7.5 11 7.5 1.52 0 2.98-.29 4.32-.82l3.42 3.42 1.41-1.41L3.42 2.425l-1.41 1.42zm7.5 7.5l2.61 2.61c-.04.01-.08.02-.12.02a2.5 2.5 0 0 1-2.5-2.5c0-.05.01-.08.01-.13zm-3.4-3.4l1.75 1.75a4.6 4.6 0 0 0-.36 1.78 4.507 4.507 0 0 0 6.27 4.14l.98.98c-.88.24-1.8.38-2.75.38a9.77 9.77 0 0 1-8.82-5.5c.7-1.43 1.72-2.61 2.93-3.53z"
/>
</svg>
)
const ForwardRef = forwardRef(SvgComponent)
export default memo(ForwardRef)

1
src/assets/index.ts Normal file
View File

@@ -0,0 +1 @@
export * from './icons'

View File

@@ -1,19 +1,102 @@
@mixin button {
all: unset;
cursor: pointer;
user-select: none;
display: inline-flex;
flex-shrink: 0;
gap: 0.625rem;
align-items: center;
justify-content: center;
box-sizing: border-box;
padding: 0.375rem 1.75rem;
font-size: 1rem;
font-weight: 600;
line-height: 24px;
text-align: center;
text-decoration: none;
background-color: transparent;
border: none;
border-radius: 0.25rem;
transition:
var(--transition-duration-basic) background-color,
var(--transition-duration-basic) color;
&:focus-visible {
outline: 2px solid var(--color-info-700);
}
&:disabled {
cursor: default;
opacity: 0.5;
}
&.fullWidth {
justify-content: center;
width: 100%;
}
}
.primary { .primary {
background-color: red; @include button;
color: var(--color-light-100);
background-color: var(--color-accent-500);
box-shadow: 0 4px 18px rgb(140 97 255 / 35%);
&:hover:enabled {
background-color: var(--color-accent-300);
}
&:active:enabled {
background-color: var(--color-accent-700);
}
} }
.secondary { .secondary {
background-color: green; @include button;
color: var(--color-light-100);
background-color: var(--color-dark-300);
box-shadow: 0 2px 10px 0 #6d6d6d40;
&:hover:enabled {
background-color: var(--color-dark-100);
}
&:active:enabled {
background-color: var(--color-dark-500);
}
} }
.tertiary { .tertiary {
background-color: blue; @include button;
color: var(--color-accent-500);
background-color: var(--color-dark-900);
border: 1px solid var(--color-accent-700);
&:hover:enabled {
background-color: var(--color-dark-500);
}
&:active:enabled {
background-color: var(--color-accent-900);
}
} }
.link { .link {
background-color: yellow; @include button;
}
.fullWidth { padding: 0.375rem 0;
width: 100%;
font-weight: var(--font-weight-bold);
line-height: var(--line-height-m);
color: var(--color-accent-500);
text-decoration-line: underline;
} }

View File

@@ -0,0 +1,7 @@
.root {
background-color: var(--color-dark-700);
border-radius: 2px;
box-shadow:
1px 1px 2px rgb(0 0 0 / 10%),
-1px -1px 2px rgb(0 0 0 / 10%);
}

View File

@@ -0,0 +1,25 @@
import type { Meta, StoryObj } from '@storybook/react'
import { Card } from './'
import { Typography } from '@/components'
const meta = {
title: 'Components/Card',
component: Card,
tags: ['autodocs'],
} satisfies Meta<typeof Card>
export default meta
type Story = StoryObj<typeof meta>
export const Default: Story = {
args: {
children: <Typography variant={'large'}>Card</Typography>,
style: {
width: '300px',
height: '300px',
padding: '24px',
},
},
}

View File

@@ -0,0 +1,15 @@
import { ComponentPropsWithoutRef, forwardRef } from 'react'
import { clsx } from 'clsx'
import s from './card.module.scss'
export type CardProps = {} & ComponentPropsWithoutRef<'div'>
export const Card = forwardRef<HTMLDivElement, CardProps>(({ className, ...restProps }, ref) => {
const classNames = {
root: clsx(s.root, className),
}
return <div ref={ref} className={classNames.root} {...restProps}></div>
})

View File

@@ -0,0 +1 @@
export * from './card'

View File

@@ -0,0 +1,80 @@
.container {
display: flex;
align-items: center;
}
.label {
cursor: pointer;
display: flex;
align-items: center;
&.disabled {
cursor: initial;
color: var(--color-dark-100);
}
}
.root {
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
width: 18px;
height: 18px;
background-color: var(--color-dark-900);
border: 2px solid var(--color-light-900);
border-radius: 2px;
&:focus {
background-color: var(--color-bg-focus);
}
&:disabled {
cursor: initial;
border-color: var(--color-dark-100);
}
&[data-state='checked']:disabled {
background-color: var(--color-checkbox-disabled);
}
}
.buttonWrapper {
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
width: 36px;
height: 36px;
background-color: var(--color-dark-900);
border-radius: 50%;
&.disabled {
cursor: initial;
}
&:focus-within,
&:hover:not(.disabled),
&:hover .root:not([data-state='checked']) {
background-color: var(--color-dark-500);
}
&:active:not(.disabled) {
background-color: var(--color-dark-100);
}
&.left {
margin-left: -9px;
}
}
.indicator {
width: 18px;
height: 18px;
}

View File

@@ -0,0 +1,35 @@
import { useState } from 'react'
import { Meta, StoryObj } from '@storybook/react'
import { Checkbox } from './checkbox'
const meta = {
title: 'Components/Checkbox',
component: Checkbox,
tags: ['autodocs'],
} satisfies Meta<typeof Checkbox>
export default meta
type Story = StoryObj<typeof meta>
export const Uncontrolled: Story = {
args: {
label: 'Click here',
disabled: false,
},
}
export const Controlled: Story = {
render: args => {
const [checked, setChecked] = useState(false)
return (
<Checkbox
{...args}
label="Click here"
checked={checked}
onChange={() => setChecked(!checked)}
/>
)
},
}

View File

@@ -0,0 +1,66 @@
import { FC } from 'react'
import * as CheckboxRadix from '@radix-ui/react-checkbox'
import * as LabelRadix from '@radix-ui/react-label'
import { clsx } from 'clsx'
import s from './checkbox.module.scss'
import { Check } from '@/assets/icons'
import { Typography } from '@/components'
export type CheckboxProps = {
className?: string
checked?: boolean
onChange?: (checked: boolean) => void
disabled?: boolean
required?: boolean
label?: string
id?: string
position?: 'left'
}
export const Checkbox: FC<CheckboxProps> = ({
checked,
onChange,
position,
disabled,
required,
label,
id,
className,
}) => {
const classNames = {
container: clsx(s.container, className),
buttonWrapper: clsx(s.buttonWrapper, disabled && s.disabled, position === 'left' && s.left),
root: s.root,
indicator: s.indicator,
label: clsx(s.label, disabled && s.disabled),
}
return (
<div className={classNames.container}>
<LabelRadix.Root asChild>
<Typography variant="body2" className={classNames.label} as={'label'}>
<div className={classNames.buttonWrapper}>
<CheckboxRadix.Root
className={classNames.root}
checked={checked}
onCheckedChange={onChange}
disabled={disabled}
required={required}
id={id}
>
{checked && (
<CheckboxRadix.Indicator className={classNames.indicator} forceMount>
<Check />
</CheckboxRadix.Indicator>
)}
</CheckboxRadix.Root>
</div>
{label}
</Typography>
</LabelRadix.Root>
</div>
)
}

View File

@@ -0,0 +1 @@
export * from './checkbox'

View File

@@ -1 +1,4 @@
export * from './button' export * from './button'
export * from './card'
export * from './typography'
export * from './checkbox'

View File

@@ -0,0 +1 @@
export * from './text-field'

View File

@@ -0,0 +1,71 @@
.root {
width: 100%;
}
.fieldContainer {
position: relative;
width: 100%;
}
.field {
width: 100%;
padding: 6px 12px;
font-family: inherit;
font-size: 16px;
font-weight: 400;
line-height: 24px;
color: var(--color-light-100);
background: transparent;
border: 1px solid var(--color-dark-300);
outline: 0;
transition: border-color 0.2s;
&::placeholder {
color: var(--color-dark-100);
}
&:focus-visible {
border-color: var(--color-info-700);
outline: 1px solid var(--color-info-700);
}
&:hover {
background: var(--color-dark-700);
}
&.error {
color: var(--color-danger-300);
border-color: var(--color-danger-300);
}
}
.label {
margin-bottom: 1px;
color: var(--color-dark-100);
}
.showPassword {
cursor: pointer;
position: absolute;
top: 50%;
right: 0;
bottom: 50%;
transform: translateY(-50%);
width: 20px;
height: 20px;
margin-right: 12px;
padding: 0;
background: transparent;
border: 0;
outline: 0;
&:focus-visible {
outline: var(--outline-focus);
}
}

View File

@@ -0,0 +1,35 @@
import type { Meta, StoryObj } from '@storybook/react'
import { TextField } from './'
const meta = {
title: 'Components/TextField',
component: TextField,
tags: ['autodocs'],
} satisfies Meta<typeof TextField>
export default meta
type Story = StoryObj<typeof meta>
export const Default: Story = {
args: {
label: 'Label',
placeholder: 'Placeholder',
},
}
export const Password: Story = {
args: {
label: 'Label',
placeholder: 'Password',
type: 'password',
},
}
export const Error: Story = {
args: {
label: 'Input with error',
value: 'Wrong value',
errorMessage: 'Error message',
},
}

View File

@@ -0,0 +1,94 @@
import { ChangeEvent, ComponentProps, ComponentPropsWithoutRef, forwardRef, useState } from 'react'
import { clsx } from 'clsx'
import s from './text-field.module.scss'
import { VisibilityOff, Eye } from '@/assets'
import { Typography } from '@/components'
export type TextFieldProps = {
onValueChange?: (value: string) => void
containerProps?: ComponentProps<'div'>
labelProps?: ComponentProps<'label'>
errorMessage?: string
label?: string
} & ComponentPropsWithoutRef<'input'>
export const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
(
{
className,
errorMessage,
placeholder,
type,
containerProps,
labelProps,
label,
onChange,
onValueChange,
...restProps
},
ref
) => {
const [showPassword, setShowPassword] = useState(false)
const isShowPasswordButtonShown = type === 'password'
const finalType = getFinalType(type, showPassword)
function handleChange(e: ChangeEvent<HTMLInputElement>) {
onChange?.(e)
onValueChange?.(e.target.value)
}
const classNames = {
root: clsx(s.root, containerProps?.className),
fieldContainer: clsx(s.fieldContainer),
field: clsx(s.field, !!errorMessage && s.error, className),
label: clsx(s.label, labelProps?.className),
error: clsx(s.error),
}
return (
<div className={classNames.root}>
{label && (
<Typography variant="body2" as="label" className={classNames.label}>
{label}
</Typography>
)}
<div className={classNames.fieldContainer}>
<input
className={classNames.field}
placeholder={placeholder}
ref={ref}
type={finalType}
onChange={handleChange}
{...restProps}
/>
{isShowPasswordButtonShown && (
<button
className={s.showPassword}
type={'button'}
onClick={() => setShowPassword(prev => !prev)}
>
{showPassword ? <VisibilityOff /> : <Eye />}
</button>
)}
</div>
<Typography variant="error" className={classNames.error}>
{errorMessage}
</Typography>
</div>
)
}
)
function getFinalType(type: ComponentProps<'input'>['type'], showPassword: boolean) {
if (type === 'password' && showPassword) {
return 'text'
}
return type
}

View File

@@ -0,0 +1 @@
export * from './typography'

View File

@@ -0,0 +1,72 @@
@mixin typography($fontSize, $lineHeight, $fontWeight) {
margin: 0;
font-size: $fontSize;
font-weight: $fontWeight;
line-height: $lineHeight;
color: var(--color-text-primary);
}
.large {
@include typography(var(--font-size-xxl), var(--line-height-l), var(--font-weight-bold));
}
.h1 {
@include typography(var(--font-size-xl), var(--line-height-l), var(--font-weight-bold));
}
.h2 {
@include typography(var(--font-size-l), var(--line-height-m), var(--font-weight-bold));
}
.h3 {
@include typography(var(--font-size-m), var(--line-height-m), var(--font-weight-bold));
}
.body1 {
@include typography(var(--font-size-m), var(--line-height-m), var(--font-weight-regular));
}
.subtitle1 {
@include typography(var(--font-size-m), var(--line-height-m), var(--font-weight-bold));
}
.body2 {
@include typography(var(--font-size-s), var(--line-height-m), var(--font-weight-regular));
}
.subtitle2 {
@include typography(var(--font-size-s), var(--line-height-m), var(--font-weight-bold));
}
.overline {
@include typography(var(--font-size-xs), var(--line-height-s), var(--font-weight-bold));
}
.caption {
@include typography(var(--font-size-xs), var(--line-height-s), var(--font-weight-regular));
}
.link1,
.link1:visited {
@include typography(var(--font-size-s), var(--line-height-m), var(--font-weight-regular));
cursor: pointer;
color: var(--color-text-link);
text-decoration: underline;
}
.link2,
.link2:visited {
@include typography(var(--font-size-xs), var(--line-height-s), var(--font-weight-regular));
cursor: pointer;
color: var(--color-text-link);
text-decoration: underline;
}
.error {
@include typography(var(--font-size-xs), var(--line-height-m), var(--font-weight-regular));
color: var(--color-danger-300);
}

View File

@@ -0,0 +1,123 @@
import type { Meta, StoryObj } from '@storybook/react'
import { Typography } from './'
const meta = {
title: 'Components/Typography',
component: Typography,
tags: ['autodocs'],
argTypes: {
variant: {
options: [
'large',
'h1',
'h2',
'h3',
'body1',
'body2',
'subtitle1',
'subtitle2',
'caption',
'overline',
'link1',
'link2',
'error',
],
control: { type: 'radio' },
},
},
} satisfies Meta<typeof Typography>
export default meta
type Story = StoryObj<typeof meta>
export const Large: Story = {
args: {
children: 'Card content',
variant: 'large',
},
}
export const H1: Story = {
args: {
children: 'Card content',
variant: 'h1',
},
}
export const H2: Story = {
args: {
children: 'Card content',
variant: 'h2',
},
}
export const H3: Story = {
args: {
children: 'Card content',
variant: 'h3',
},
}
export const Body1: Story = {
args: {
children: 'Card content',
variant: 'body1',
},
}
export const Body2: Story = {
args: {
children: 'Card content',
variant: 'body2',
},
}
export const Subtitle1: Story = {
args: {
children: 'Card content',
variant: 'subtitle1',
},
}
export const Subtitle2: Story = {
args: {
children: 'Card content',
variant: 'subtitle2',
},
}
export const Caption: Story = {
args: {
children: 'Card content',
variant: 'caption',
},
}
export const Overline: Story = {
args: {
children: 'Card content',
variant: 'overline',
},
}
export const Link1: Story = {
args: {
children: 'Card content',
variant: 'link1',
},
}
export const Link2: Story = {
args: {
children: 'Card content',
variant: 'link2',
},
}
export const Error: Story = {
args: {
children: 'Card content',
variant: 'error',
},
}

View File

@@ -0,0 +1,37 @@
import { ComponentPropsWithoutRef, ElementType, ReactNode } from 'react'
import { clsx } from 'clsx'
import s from './typography.module.scss'
export interface TextProps<T extends ElementType> {
as?: T
variant?:
| 'large'
| 'h1'
| 'h2'
| 'h3'
| 'body1'
| 'body2'
| 'subtitle1'
| 'subtitle2'
| 'caption'
| 'overline'
| 'link1'
| 'link2'
| 'error'
children?: ReactNode
className?: string
}
export function Typography<T extends ElementType = 'p'>({
as,
className,
variant = 'body1',
...restProps
}: TextProps<T> & Omit<ComponentPropsWithoutRef<T>, keyof TextProps<T>>) {
const classNames = clsx(s.text, s[variant], className)
const Component = as || 'p'
return <Component className={classNames} {...restProps} />
}

13
src/styles/_tokens.scss Normal file
View File

@@ -0,0 +1,13 @@
:root {
/* outlines */
--outline-focus: 2px solid var(--color-outline-focus);
/* transitions */
--transition-duration-basic: 200ms;
/* border-radius */
--border-radius-s: 0.25rem;
/* header */
--header-height: 60px;
}

View File

@@ -1,3 +1,4 @@
@forward 'colors'; @forward 'colors';
@forward 'typography'; @forward 'typography';
@forward 'boilerplate'; @forward 'boilerplate';
@forward 'tokens';