add: tools/languages + minor themes refactor

This commit is contained in:
Franek 2025-02-09 22:46:19 +01:00
parent dbd634c3f3
commit e3d0b1565b
20 changed files with 218 additions and 86 deletions

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="nonzero" clip-rule="nonzero" d="M3 1.60001C2.86193 1.60001 2.75 1.71193 2.75 1.85001V11.4003C2.75 11.4896 2.79769 11.5722 2.87509 11.6168L7.73381 14.4194C7.80942 14.463 7.90231 14.464 7.97886 14.4221L13.1201 11.6048C13.2002 11.5609 13.25 11.4769 13.25 11.3856V1.85001C13.25 1.71193 13.1381 1.60001 13 1.60001H3ZM1.25 1.85001C1.25 0.883508 2.0335 0.100006 3 0.100006H13C13.9665 0.100006 14.75 0.883509 14.75 1.85001V11.3856C14.75 12.0248 14.4015 12.6131 13.841 12.9203L8.69968 15.7375C8.16383 16.0311 7.51363 16.024 6.98434 15.7187L2.12562 12.9162C1.58382 12.6037 1.25 12.0258 1.25 11.4003V1.85001ZM5 4.35001C5 3.93579 5.33579 3.60001 5.75 3.60001H10.3654C10.7796 3.60001 11.1154 3.93579 11.1154 4.35001V10.4462C11.1154 10.7302 10.9549 10.9899 10.7008 11.117L8.3931 12.2708C8.18196 12.3764 7.93343 12.3764 7.72228 12.2708L5.41459 11.117C5.1605 10.9899 5 10.7302 5 10.4462V9.86924C5 9.45502 5.33579 9.11924 5.75 9.11924C6.16421 9.11924 6.5 9.45502 6.5 9.86924V9.98263L8.05769 10.7615L9.61539 9.98263V8.31154H7C6.58579 8.31154 6.25 7.97576 6.25 7.56154C6.25 7.14733 6.58579 6.81154 7 6.81154H9.61539V5.10001H5.75C5.33579 5.10001 5 4.76422 5 4.35001Z" fill="#000000"/>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg fill="#000000" width="800px" height="800px" viewBox="0 0 24 24" role="img" xmlns="http://www.w3.org/2000/svg"><path d="M1.811 10.231c-.047 0-.058-.023-.035-.059l.246-.315c.023-.035.081-.058.128-.058h4.172c.046 0 .058.035.035.07l-.199.303c-.023.036-.082.07-.117.07zM.047 11.306c-.047 0-.059-.023-.035-.058l.245-.316c.023-.035.082-.058.129-.058h5.328c.047 0 .07.035.058.07l-.093.28c-.012.047-.058.07-.105.07zm2.828 1.075c-.047 0-.059-.035-.035-.07l.163-.292c.023-.035.07-.07.117-.07h2.337c.047 0 .07.035.07.082l-.023.28c0 .047-.047.082-.082.082zm12.129-2.36c-.736.187-1.239.327-1.963.514-.176.046-.187.058-.34-.117-.174-.199-.303-.327-.548-.444-.737-.362-1.45-.257-2.115.175-.795.514-1.204 1.274-1.192 2.22.011.935.654 1.706 1.577 1.835.795.105 1.46-.175 1.987-.77.105-.13.198-.27.315-.434H10.47c-.245 0-.304-.152-.222-.35.152-.362.432-.97.596-1.274a.315.315 0 0 1 .292-.187h4.253c-.023.316-.023.631-.07.947a4.983 4.983 0 0 1-.958 2.29c-.841 1.11-1.94 1.8-3.33 1.986-1.145.152-2.209-.07-3.143-.77-.865-.655-1.356-1.52-1.484-2.595-.152-1.274.222-2.419.993-3.424.83-1.086 1.928-1.776 3.272-2.02 1.098-.2 2.15-.07 3.096.571.62.41 1.063.97 1.356 1.648.07.105.023.164-.117.2m3.868 6.461c-1.064-.024-2.034-.328-2.852-1.029a3.665 3.665 0 0 1-1.262-2.255c-.21-1.32.152-2.489.947-3.529.853-1.122 1.881-1.706 3.272-1.95 1.192-.21 2.314-.095 3.33.595.923.63 1.496 1.484 1.648 2.605.198 1.578-.257 2.863-1.344 3.962-.771.783-1.718 1.273-2.805 1.495-.315.06-.63.07-.934.106zm2.78-4.72c-.011-.153-.011-.27-.034-.387-.21-1.157-1.274-1.81-2.384-1.554-1.087.245-1.788.935-2.045 2.033-.21.912.234 1.835 1.075 2.21.643.28 1.285.244 1.905-.07.923-.48 1.425-1.228 1.484-2.233z"/></svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="nonzero" clip-rule="nonzero" d="M3 1.5C2.86193 1.5 2.75 1.61193 2.75 1.75V11.3003C2.75 11.3896 2.79769 11.4722 2.87509 11.5168L7.73381 14.3194C7.80942 14.363 7.90231 14.364 7.97886 14.3221L13.1201 11.5048C13.2002 11.4609 13.25 11.3769 13.25 11.2856V1.75C13.25 1.61193 13.1381 1.5 13 1.5H3ZM1.25 1.75C1.25 0.783502 2.0335 0 3 0H13C13.9665 0 14.75 0.783503 14.75 1.75V11.2856C14.75 11.9248 14.4015 12.5131 13.841 12.8203L8.69968 15.6375C8.16383 15.9311 7.51363 15.924 6.98434 15.6187L2.12562 12.8162C1.58382 12.5037 1.25 11.9258 1.25 11.3003V1.75ZM5 4.25C5 3.83579 5.33579 3.5 5.75 3.5H10.3654C10.7796 3.5 11.1154 3.83579 11.1154 4.25C11.1154 4.66421 10.7796 5 10.3654 5H6.5V6.71154H10.3654C10.7796 6.71154 11.1154 7.04732 11.1154 7.46154V10.3462C11.1154 10.6302 10.9549 10.8899 10.7008 11.017L8.3931 12.1708C8.18196 12.2764 7.93343 12.2764 7.72228 12.1708L5.41459 11.017C5.1605 10.8899 5 10.6302 5 10.3462V9.76923C5 9.35502 5.33579 9.01923 5.75 9.01923C6.16421 9.01923 6.5 9.35502 6.5 9.76923V9.88263L8.05769 10.6615L9.61539 9.88263V8.21154H5.75C5.33579 8.21154 5 7.87575 5 7.46154V4.25Z" fill="#000000"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="nonzero" clip-rule="nonzero" d="M0 1.75C0 0.783501 0.783502 0 1.75 0H14.25C15.2165 0 16 0.783502 16 1.75V3.75C16 4.16421 15.6642 4.5 15.25 4.5C14.8358 4.5 14.5 4.16421 14.5 3.75V1.75C14.5 1.61193 14.3881 1.5 14.25 1.5H1.75C1.61193 1.5 1.5 1.61193 1.5 1.75V14.25C1.5 14.3881 1.61193 14.5 1.75 14.5H15.25C15.6642 14.5 16 14.8358 16 15.25C16 15.6642 15.6642 16 15.25 16H1.75C0.783501 16 0 15.2165 0 14.25V1.75ZM4.75 6.5C4.75 6.08579 5.08579 5.75 5.5 5.75H9.25C9.66421 5.75 10 6.08579 10 6.5C10 6.91421 9.66421 7.25 9.25 7.25H8.25V12.5C8.25 12.9142 7.91421 13.25 7.5 13.25C7.08579 13.25 6.75 12.9142 6.75 12.5V7.25H5.5C5.08579 7.25 4.75 6.91421 4.75 6.5ZM11.2757 6.58011C11.6944 6.08164 12.3507 5.75 13.25 5.75C14.0849 5.75 14.7148 6.03567 15.1394 6.48481C15.4239 6.78583 15.4105 7.26052 15.1095 7.54505C14.8085 7.82958 14.3338 7.81621 14.0493 7.51519C13.9394 7.39898 13.7204 7.25 13.25 7.25C12.7493 7.25 12.5306 7.41836 12.4243 7.54489C12.2934 7.70065 12.25 7.896 12.25 8C12.25 8.104 12.2934 8.29935 12.4243 8.45511C12.5306 8.58164 12.7493 8.75 13.25 8.75C13.3257 8.75 13.3988 8.76121 13.4676 8.78207C14.1307 8.87646 14.6319 9.17251 14.9743 9.58011C15.3684 10.0493 15.5 10.604 15.5 11C15.5 11.396 15.3684 11.9507 14.9743 12.4199C14.5556 12.9184 13.8993 13.25 13 13.25C12.1651 13.25 11.5352 12.9643 11.1106 12.5152C10.8261 12.2142 10.8395 11.7395 11.1405 11.4549C11.4415 11.1704 11.9162 11.1838 12.2007 11.4848C12.3106 11.601 12.5296 11.75 13 11.75C13.5007 11.75 13.7194 11.5816 13.8257 11.4551C13.9566 11.2993 14 11.104 14 11C14 10.896 13.9566 10.7007 13.8257 10.5449C13.7194 10.4184 13.5007 10.25 13 10.25C12.9243 10.25 12.8512 10.2388 12.7824 10.2179C12.1193 10.1235 11.6181 9.82749 11.2757 9.41989C10.8816 8.95065 10.75 8.396 10.75 8C10.75 7.604 10.8816 7.04935 11.2757 6.58011Z" fill="#000000"/>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M9 1H6V3H2V5H0V8.5C0 11.5376 2.46243 14 5.5 14H6.02786C8.85368 14 11.4456 12.4603 12.802 10H15V8.5C15 7.67157 14.3284 7 13.5 7H13V6.5C13 5.67157 12.3284 5 11.5 5H9V1ZM1 7H2V6H1V7ZM3 7H4V6H3V7ZM5 7H6V6H5V7ZM7 7H8V6H7V7ZM9 7H10V6H9V7ZM8 3V2H7V3H8ZM6 4H5V5H6V4ZM7 5V4H8V5H7ZM4 5V4H3V5H4ZM3 10H4V9H3V10Z" fill="#000000"/>
</svg>

After

Width:  |  Height:  |  Size: 594 B

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg fill="#000000" width="800px" height="800px" viewBox="0 0 24 24" role="img" xmlns="http://www.w3.org/2000/svg"><title>NixOS icon</title><path d="M7.352 1.592l-1.364.002L5.32 2.75l1.557 2.713-3.137-.008-1.32 2.34H14.11l-1.353-2.332-3.192-.006-2.214-3.865zm6.175 0l-2.687.025 5.846 10.127 1.341-2.34-1.59-2.765 2.24-3.85-.683-1.182h-1.336l-1.57 2.705-1.56-2.72zm6.887 4.195l-5.846 10.125 2.696-.008 1.601-2.76 4.453.016.682-1.183-.666-1.157-3.13-.008L21.778 8.1l-1.365-2.313zM9.432 8.086l-2.696.008-1.601 2.76-4.453-.016L0 12.02l.666 1.157 3.13.008-1.575 2.71 1.365 2.315L9.432 8.086zM7.33 12.25l-.006.01-.002-.004-1.342 2.34 1.59 2.765-2.24 3.85.684 1.182H7.35l.004-.006h.001l1.567-2.698 1.558 2.72 2.688-.026-.004-.006h.01L7.33 12.25zm2.55 3.93l1.354 2.332 3.192.006 2.215 3.865 1.363-.002.668-1.156-1.557-2.713 3.137.008 1.32-2.34H9.881Z"/></svg>

After

Width:  |  Height:  |  Size: 970 B

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="nonzero" clip-rule="nonzero" d="M4.84989 2.37195C4.59895 2.51683 4.33488 2.91636 4.30424 3.78785C4.28968 4.20181 3.9423 4.52559 3.52835 4.51103C3.11439 4.49647 2.79061 4.1491 2.80516 3.73514C2.84273 2.66673 3.1806 1.60366 4.09989 1.07291C5.02179 0.540653 6.11484 0.782356 7.06128 1.28727C7.42674 1.48224 7.56495 1.93656 7.36998 2.30201C7.17501 2.66747 6.72069 2.80568 6.35524 2.61072C5.5818 2.1981 5.10158 2.22663 4.84989 2.37195ZM8.87139 3.67284C9.19036 3.40858 9.66315 3.45293 9.92741 3.7719C10.4818 4.44103 11.0136 5.20405 11.4963 6.04018C12.5366 7.84191 13.178 9.68785 13.3509 11.2362C13.4372 12.0091 13.4108 12.7446 13.2303 13.3754C13.0484 14.011 12.6941 14.5863 12.0999 14.9293C11.381 15.3444 10.5509 15.2855 9.79114 15.0089C9.02868 14.7313 8.24395 14.2056 7.49586 13.5228C7.18993 13.2435 7.16831 12.7691 7.44756 12.4632C7.72681 12.1573 8.20119 12.1356 8.50712 12.4149C9.16624 13.0165 9.78567 13.4105 10.3043 13.5994C10.8257 13.7892 11.1537 13.7436 11.3499 13.6303C11.5143 13.5354 11.6797 13.342 11.7882 12.9627C11.8981 12.5787 11.9328 12.0529 11.8602 11.4026C11.7152 10.1045 11.1591 8.45607 10.1973 6.79018C9.75492 6.02396 9.27081 5.33055 8.77232 4.72886C8.50807 4.40989 8.55242 3.93709 8.87139 3.67284Z" fill="#000000"/>
<path fill-rule="nonzero" clip-rule="nonzero" d="M14.5 8.20557C14.5 7.91581 14.286 7.48735 13.5466 7.02507C13.1954 6.80549 13.0887 6.34276 13.3083 5.99154C13.5279 5.64032 13.9906 5.53361 14.3418 5.75319C15.2483 6.31993 16 7.14407 16 8.20557C16 9.27009 15.2442 10.0958 14.3337 10.663C13.9821 10.882 13.5195 10.7746 13.3005 10.423C13.0815 10.0714 13.189 9.60887 13.5405 9.38985C14.2846 8.92635 14.5 8.4962 14.5 8.20557ZM11.3626 11.0378C11.432 11.4462 11.1572 11.8335 10.7488 11.9029C9.89219 12.0484 8.96547 12.1274 8 12.1274C5.91954 12.1274 4.00018 11.76 2.57286 11.1355C1.86032 10.8238 1.23659 10.4332 0.780529 9.9615C0.320977 9.48616 0 8.89166 0 8.20557C0 7.37549 0.466082 6.68599 1.08548 6.16636C1.70712 5.64485 2.55471 5.22808 3.52013 4.92164C3.91494 4.79633 4.33657 5.01479 4.46189 5.40959C4.5872 5.80439 4.36874 6.22603 3.97394 6.35135C3.12334 6.62134 2.4724 6.96078 2.04954 7.31553C1.62442 7.67217 1.5 7.97899 1.5 8.20557C1.5 8.39536 1.58476 8.6353 1.85895 8.91891C2.13663 9.20613 2.57464 9.49905 3.17409 9.76131C4.37076 10.2848 6.07639 10.6274 8 10.6274C8.88475 10.6274 9.72732 10.5549 10.4976 10.424C10.906 10.3547 11.2933 10.6295 11.3626 11.0378Z" fill="#000000"/>
<path fill-rule="nonzero" clip-rule="nonzero" d="M4.87192 13.6303C5.12286 13.7752 5.6009 13.8041 6.37095 13.3949C6.73673 13.2005 7.19082 13.3395 7.38519 13.7052C7.57957 14.071 7.44062 14.5251 7.07484 14.7195C6.13079 15.2211 5.04121 15.4601 4.12192 14.9293C3.20003 14.3971 2.86282 13.3296 2.82687 12.2575C2.81299 11.8435 3.13733 11.4967 3.55131 11.4828C3.96529 11.4689 4.31215 11.7932 4.32603 12.2072C4.35541 13.0834 4.62023 13.485 4.87192 13.6303ZM3.98778 9.49712C3.59944 9.35301 3.40145 8.92138 3.54556 8.53304C3.84786 7.71839 4.24274 6.8763 4.72548 6.04018C5.76571 4.23845 7.04361 2.75996 8.29806 1.83609C8.92431 1.37487 9.57441 1.02999 10.211 0.870901C10.8524 0.71059 11.5278 0.729863 12.1219 1.07291C12.8408 1.48795 13.2049 2.23634 13.3452 3.03257C13.486 3.83168 13.4232 4.77409 13.2058 5.7634C13.1169 6.16796 12.7169 6.42388 12.3124 6.33501C11.9078 6.24613 11.6519 5.84612 11.7408 5.44155C11.9322 4.56992 11.9637 3.83647 11.868 3.29288C11.7717 2.7464 11.5681 2.48524 11.3719 2.37195C11.2076 2.27705 10.9574 2.23049 10.5747 2.32614C10.1871 2.42301 9.71442 2.65588 9.18757 3.04388C8.13584 3.81846 6.98632 5.12428 6.02452 6.79018C5.58214 7.55639 5.22369 8.32235 4.95185 9.0549C4.80774 9.44323 4.37611 9.64122 3.98778 9.49712Z" fill="#000000"/>
<path d="M9.45925 8.06618C9.45925 8.81694 8.85063 9.42556 8.09987 9.42556C7.34911 9.42556 6.7405 8.81694 6.7405 8.06618C6.7405 7.31542 7.34911 6.70681 8.09987 6.70681C8.85063 6.70681 9.45925 7.31542 9.45925 8.06618Z" fill="#000000"/>
</svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7 1H1V4H2V14H5.74031L14 3.67539V1H8V4H9.43248L6 8.11898V4H7V1Z" fill="#000000"/>
</svg>

After

Width:  |  Height:  |  Size: 318 B

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0.228341 8.36915C0.228341 8.36915 -0.356212 7.94324 0.345251 7.37453L1.97956 5.89736C1.97956 5.89736 2.44721 5.40004 2.94164 5.83334L18.0231 17.375V22.9094C18.0231 22.9094 18.0158 23.7785 16.9124 23.6825L0.228341 8.36915Z" fill="#000000"/>
<path d="M4.11555 11.9367L0.228273 15.5089C0.228273 15.5089 -0.171172 15.8093 0.228273 16.346L2.03308 18.0053C2.03308 18.0053 2.46175 18.4706 3.09502 17.9413L7.21611 14.7827L4.11555 11.9367Z" fill="#000000"/>
<path d="M10.94 11.9661L18.0691 6.46362L18.0228 0.95865C18.0228 0.95865 17.7183 -0.242793 16.7027 0.382548L7.21589 9.11025L10.94 11.9661Z" fill="#000000"/>
<path d="M16.9121 23.69C17.3261 24.1183 17.8279 23.978 17.8279 23.978L23.3838 21.2108C24.0951 20.7208 23.9952 20.1127 23.9952 20.1127V3.58803C23.9952 2.86175 23.2596 2.61063 23.2596 2.61063L18.4441 0.264377C17.3919 -0.392968 16.7027 0.382548 16.7027 0.382548C16.7027 0.382548 17.5892 -0.262484 18.0228 0.95865L18.0228 22.8086C18.0228 22.9588 17.9911 23.1065 17.9278 23.2394C17.8011 23.4979 17.5259 23.7392 16.8658 23.6383L16.9121 23.69Z" fill="#000000"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -2,6 +2,7 @@ import styled, { ThemeProvider } from "styled-components";
import { useTheme } from "./style/themes.tsx";
import About from "./sections/about.tsx";
import Tools from "./sections/tools.tsx";
const App: React.FC = () => {
const { theme } = useTheme();
@ -9,18 +10,20 @@ const App: React.FC = () => {
return <ThemeProvider theme={theme}>
<Container>
<About />
<Tools />
</Container>
</ThemeProvider>;
}
const Container = styled.div`
background-color: ${({ theme }) => theme.primary};
transition: 0.2s background-color ease-in-out;
background-color: ${({ theme }) => theme.primary};
color: ${({ theme }) => theme.text};
height: 100%;
display: grid;
text-align: center;
place-content: center;
padding: 1rem 0;
@media (max-width: 768px) {
padding: 1rem;

View File

@ -1,9 +1,23 @@
import styled from "styled-components";
import { classes } from "../utils/logic";
export type Props = { content?: string, icon?: string, link?: string }
const Button: React.FC<React.ComponentProps<'div'> & Props> = ({ content, icon, link, children, ...props }) => {
const item = <ButtonStyled {...props} className={link && "link"}>
{icon && <img src={icon} alt="Button icon"/>}
export type Props = {
content?: string,
icon?: string,
link?: string,
primary?: boolean
} & React.ComponentProps<'div'>;
const Button: React.FC<Props> = ({
content,
icon,
link,
primary,
children,
...props
}) => {
const item = <ButtonStyled {...props} className={classes({ link, primary })}>
{icon && <img src={icon} alt="Button icon" />}
{content || children}
</ButtonStyled>;
@ -11,44 +25,41 @@ const Button: React.FC<React.ComponentProps<'div'> & Props> = ({ content, icon,
}
const ButtonStyled = styled.div`
gap: ${({ theme }) => theme.gap};
display: flex;
align-items: center;
border-radius: 10px;
gap: ${({ theme }) => theme.gap};
padding: 0.5rem 1rem;
transition: 0.2s ease-in-out;
border: 1px solid ${({ theme }) => theme.border};
border-radius: 10px;
transition: 0.2s ease-in-out;
cursor: default;
&.link { cursor: pointer; }
&:hover {
background: ${({ theme }) => theme.text};
color: ${({ theme }) => theme.secondary};
img {
filter: invert();
}
}
${({ theme }) => theme.type === 'dark' && `
img {
filter: invert();
}
&:hover img {
filter: none;
}
`}
&:active {
transform: scale(0.9);
}
&:active { transform: scale(0.9); }
img {
max-width: 20px;
max-height: 20px;
transition-delay: 0.1s;
transition: filter 0.1s;
${({ theme }) => theme.type === 'dark' && 'filter: invert();'}
}
&:hover, &.primary {
background: ${({ theme }) => theme.text};
color: ${({ theme }) => theme.secondary};
img {
filter: ${({ theme }) => (theme.type === 'dark' ? 'none' : 'invert()')};
}
}
&.primary:hover {
background: ${({ theme }) => theme.secondary};
color: ${({ theme }) => theme.text};
img {
filter: ${({ theme }) => (theme.type === 'dark' ? 'invert()' : 'none')};
}
}
`;

View File

@ -1,13 +1,10 @@
import styled from "styled-components";
import Button from "./button";
import Button, { Props as Item } from "./button";
export type Item = { content: string, icon?: string, link?: string }
const CardStack: React.FC<{ items: Item[] }> = ({ items }) => <Stack>
{items.map((item, index) => <Button
key={index}
content={item.content}
icon={item.icon}
link={item.link}
{...item}
/>)}
</Stack>;
@ -29,4 +26,14 @@ const Stack = styled.div`
}
`;
export const asCardStack = (items: Array<Item | string>) => (
<CardStack
items={items.map(item =>
typeof item === "string"
? { content: item }
: item
)}
/>
);
export default CardStack;

View File

@ -2,34 +2,24 @@ import styled from "styled-components";
import { useTheme } from "../style/themes";
import { calculateAge } from "../utils/math";
import CardStack, { Item } from "../components/card-stack";
import Button from "../components/button";
const asCardStack = (items: Array<Item | string>) => (
<CardStack
items={items.map(item =>
typeof item === "string"
? { content: item }
: item
)}
/>
);
import { asCardStack } from "../components/card-stack";
const About: React.FC = () => {
const { years, months, days } = calculateAge(new Date(2007, 6, 25));
const { theme, toggleTheme } = useTheme();
return <AboutSection>
<h1>Hello.</h1>
return <>
<Heading>Hello.</Heading>
<p>My name is Franek. I'm {years} years, {months} months and {days} days old.</p>
<div id="margin-auto">
<Button
onClick={toggleTheme}
content={`switch theme to ${theme.type === 'light' ? 'dark' : 'light'}`}
icon={'/icons/' + (theme.type === 'light' ? 'moon' : 'sun') + '.svg'}
/>
</div>
{asCardStack([
{
content: `switch theme to ${theme.type === "light" ? "dark" : "light"}`,
icon: "/icons/" + (theme.type === "light" ? "moon" : "sun") + ".svg",
primary: theme.type === "light",
onClick: toggleTheme
}
])}
<h2>Some facts about me</h2>
{asCardStack([
"introvert",
@ -74,27 +64,19 @@ const About: React.FC = () => {
<h2>Some links...</h2>
{asCardStack(LINKS)}
</AboutSection>;
</>;
}
const AboutSection = styled.div`
color: ${({ theme }) => theme.text};
&>h1 {
font-family: "Pacifico", serif;
}
&>#margin-auto {
margin: 0 auto;
width: max-content;
}
const Heading = styled.h1`
font-family: "Pacifico", serif;
`;
const LINKS = [
{
content: "PGP",
icon: "/icons/pgp.svg",
link: "/pgp.asc"
link: "/pgp.asc",
primary: true
},
{
content: "E-mail",

59
src/sections/tools.tsx Normal file
View File

@ -0,0 +1,59 @@
import { asCardStack } from "../components/card-stack";
const Tools: React.FC = () => {
return <>
<h2>Languages that I use the most:</h2>
{asCardStack(LANGUAGES)}
<h2>My favourite tools...</h2>
{asCardStack(TOOLS)}
</>;
}
const LANGUAGES = [
{
content: "CSS3",
icon: "/icons/languages/css3.svg"
},
{
content: "Go",
icon: "/icons/languages/golang.svg"
},
{
content: "HTML5",
icon: "/icons/languages/html5.svg"
},
{
content: "Rust",
icon: "/icons/languages/rust.svg"
},
{
content: "TypeScript",
icon: "/icons/languages/typescript.svg"
}
];
const TOOLS = [
{
content: "Docker",
icon: "/icons/tools/docker.svg"
},
{
content: "NixOS",
icon: "/icons/tools/nixos.svg"
},
{
content: "React",
icon: "/icons/tools/react.svg"
},
{
content: "Vim",
icon: "/icons/tools/vim.svg"
},
{
content: "VSCodium",
icon: "/icons/tools/vscode.svg"
},
];
export default Tools;

View File

@ -23,27 +23,29 @@ export const darkTheme: Theme = {
type Props = {
theme: Theme,
toggleTheme: () => void
toggleTheme: () => void,
};
const ThemeContext = createContext<Props>({
theme: lightTheme,
toggleTheme: () => {}
toggleTheme: () => {},
});
const ThemeProvider: React.FC<React.PropsWithChildren> = ({ children }: React.PropsWithChildren) => {
const [theme, setTheme] = useState(localStorage.getItem("theme") === "light" ? lightTheme : darkTheme);
const toggleTheme = () => setTheme(previous => previous === lightTheme ? darkTheme : lightTheme);
const ThemeProvider: React.FC<React.PropsWithChildren> = ({ children }) => {
const [isLightTheme, setIsLightTheme] = useState(() => localStorage.getItem("theme") === "light");
useEffect(() => {
if (theme) {
localStorage.setItem("theme", theme.type)
}
}, [theme]);
localStorage.setItem("theme", isLightTheme ? "light" : "dark");
}, [isLightTheme]);
return <ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
const theme = isLightTheme ? lightTheme : darkTheme;
const toggleTheme = () => setIsLightTheme(prev => !prev);
return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
};
const useTheme = () => useContext<Props>(ThemeContext);

18
src/tests/tools.test.js Normal file
View File

@ -0,0 +1,18 @@
import { render, screen } from "@testing-library/react";
import App from "../App";
describe("all sub-sections of tools are visible", () => {
test("'languages that i use'", () => {
render(<App />);
const section = screen.getByText(/languages that i use/i);
expect(section).toBeInTheDocument();
})
test("'my favourite tools'", () => {
render(<App />);
const section = screen.getByText(/my favourite tools/i);
expect(section).toBeInTheDocument();
})
})

2
src/types.d.ts vendored
View File

@ -7,7 +7,7 @@ declare module "styled-components" {
secondary: string,
border: string,
text: string,
gap: ${({ theme }) => theme.gap};
gap: string;
}
export interface DefaultTheme extends Theme {}

6
src/utils/logic.ts Normal file
View File

@ -0,0 +1,6 @@
export const classes = (classes: Record<string, unknown>) => {
return Object.entries(classes)
.filter(([_, value]) => value)
.map(([key]) => key)
.join(' ');
};