-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
task: add hero icon and catalogue sections to home
- Loading branch information
Showing
6 changed files
with
353 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,202 @@ | ||
import { FC, PropsWithChildren } from 'hono/jsx'; | ||
import { iconNames } from '../icons/index.ts'; | ||
import { kebabToName } from '../utils/icons.ts'; | ||
import { dirname, fromFileUrl, join } from '@std/path'; | ||
import { encodeBase64 } from '@std/encoding'; | ||
import Counter from './Counter.tsx'; | ||
import { containerClass } from './styles.ts'; | ||
import { css } from 'hono/css'; | ||
|
||
const CURRENT_DIR = dirname(fromFileUrl(import.meta.url)); | ||
const ICON_CATALOGUE = iconNames.reduce((acc, icon) => { | ||
const f = icon[0]; | ||
if (!acc?.[f]) { | ||
acc[f] = []; | ||
} | ||
acc[f].push(icon); | ||
return acc; | ||
}, {} as Record<string, string[]>); | ||
|
||
const catalogueSort = (a: string, b: string) => { | ||
const aNumber = Number.parseInt(a); | ||
const bNumber = Number.parseInt(b); | ||
if (Number.isNaN(aNumber) && Number.isNaN(bNumber)) return 0; | ||
if (Number.isNaN(bNumber)) return +1; | ||
if (Number.isNaN(aNumber)) return -1; | ||
return aNumber < bNumber ? -1 : 1; | ||
}; | ||
|
||
interface IconProps { | ||
icon: string; | ||
} | ||
|
||
interface HeaderProps { | ||
letter: string; | ||
} | ||
|
||
interface EntryProps { | ||
letter: string; | ||
icons: string[]; | ||
} | ||
|
||
const catalogueEntryIcon = css` | ||
display: flex; | ||
gap: 2rem; | ||
align-items: center; | ||
cursor: pointer; | ||
& + & { | ||
margin-top: 2rem; | ||
} | ||
h4 { | ||
font-size: 1.5rem; | ||
} | ||
&:hover { | ||
img { | ||
transform: scale(1.15); | ||
filter: brightness(1.1); | ||
} | ||
h4 { | ||
text-decoration: underline; | ||
text-underline-offset: 4px; | ||
text-decoration-thickness: 2px; | ||
} | ||
} | ||
`; | ||
|
||
const catalogueEntryIconImage = css` | ||
width: 90px; | ||
height: 90px; | ||
border-radius: var(--rounded); | ||
overflow: hidden; | ||
img { | ||
transition: all 150ms ease-in; | ||
width: 100%; height: 100%; object-fit: cover; | ||
} | ||
`; | ||
|
||
const Icon = async ({ icon }: PropsWithChildren<IconProps>) => { | ||
return ( | ||
<div class={catalogueEntryIcon}> | ||
<div class={catalogueEntryIconImage}> | ||
<img | ||
src={'data:image/svg+xml;base64,' + encodeBase64( | ||
await Deno.readFile(join(CURRENT_DIR, `../icons/${icon}.svg`)), | ||
)} | ||
/> | ||
</div> | ||
<h4>{kebabToName(icon)}</h4> | ||
</div> | ||
); | ||
}; | ||
|
||
const headerClass = css` | ||
padding-left: .75rem; | ||
padding-bottom: .25rem; | ||
margin-bottom: 1.5rem; | ||
position: sticky; | ||
top: 0; | ||
background-color: var(--dark-blue); | ||
border-bottom: 2px solid rgba(255, 255, 255, 0.35); | ||
cursor: pointer; | ||
&:hover { | ||
span { | ||
display: block; | ||
} | ||
} | ||
a { | ||
display: flex; | ||
align-items: center; | ||
width: 100%; | ||
text-decoration: none; | ||
position: relative; | ||
} | ||
span { | ||
font-size: 2rem; | ||
left: -2rem; | ||
position: absolute; | ||
display: none; | ||
} | ||
h3 { | ||
font-size: 2.5rem; | ||
margin-bottom: 0; | ||
} | ||
`; | ||
|
||
const Header = ({ letter }: PropsWithChildren<HeaderProps>) => ( | ||
<header class={headerClass} id={`${letter}-icons`}> | ||
<a href={`/#${letter}-icons`}> | ||
<span class='text-color__yellow'>#</span> | ||
<h3>{letter.toUpperCase()}</h3> | ||
</a> | ||
</header> | ||
); | ||
|
||
const cataloguEntryClass = (iconCount: number = 1) => | ||
css` | ||
position: relative; | ||
grid-row: span ${iconCount + 1}; | ||
`; | ||
|
||
const Entry = ({ letter, icons }: PropsWithChildren<EntryProps>) => ( | ||
<section class={cataloguEntryClass(icons.length)}> | ||
<Header letter={letter} /> | ||
{icons.map((i) => <Icon icon={i} />)} | ||
</section> | ||
); | ||
|
||
const catalogueIntroductionClass = css` | ||
display: grid; | ||
width: 100%; | ||
grid-template-columns: 1fr 1fr; | ||
gap: 2rem; | ||
margin-bottom: 4rem; | ||
`; | ||
|
||
const catalogueMessageClass = css` | ||
p {font-size: 1.3rem; line-height: 1.5;} | ||
`; | ||
|
||
const catalogueEntriesGridClass = css` | ||
display: grid; | ||
grid-template-columns: 1fr 1fr; | ||
gap: 3rem; | ||
grid-auto-rows: 80px; | ||
`; | ||
|
||
const Catalogue: FC = () => { | ||
return ( | ||
<> | ||
<div class={containerClass}> | ||
<div class={catalogueIntroductionClass}> | ||
<div class={catalogueMessageClass}> | ||
<h2>Current Catalogue</h2> | ||
<p> | ||
We're always adding new icons to our collection. However we might | ||
be missing that one icon you need. Feel free to submit a PR to | ||
{' '} | ||
<a | ||
class='text-color__yellow' | ||
href='https://github.com/NOMADE55/picto' | ||
> | ||
the repository | ||
</a>{' '} | ||
or open an issue to request it! | ||
</p> | ||
</div> | ||
<div class='catalogue-introduction--counter'> | ||
<Counter /> | ||
</div> | ||
</div> | ||
<div className={catalogueEntriesGridClass}> | ||
{Object.keys(ICON_CATALOGUE).sort(catalogueSort) | ||
.map((letter) => ( | ||
<Entry letter={letter} icons={ICON_CATALOGUE[letter]} /> | ||
))} | ||
</div> | ||
</div> | ||
</> | ||
); | ||
}; | ||
|
||
export default Catalogue; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import { FC } from 'hono/jsx'; | ||
import { containerClass } from './styles.ts'; | ||
import { css, cx } from 'hono/css'; | ||
|
||
const logoClass = css` | ||
padding-top: 12rem; | ||
margin-bottom: 3rem; | ||
`; | ||
|
||
const headlineClass = css` | ||
font-size: 3rem; | ||
font-weight: bold; | ||
text-align: center; | ||
`; | ||
|
||
const headerClass = css` | ||
margin-bottom: 4rem; | ||
`; | ||
|
||
const Hero: FC = () => ( | ||
<> | ||
<header class={cx(containerClass, headerClass)}> | ||
<h1 class={logoClass}> | ||
<svg | ||
version='1.1' | ||
xmlns='http://www.w3.org/2000/svg' | ||
xmlns:xlink='http://www.w3.org/1999/xlink' | ||
x='0px' | ||
y='0px' | ||
viewBox='0 0 724 188' | ||
xml:space='preserve' | ||
overflow='visible' | ||
> | ||
<g> | ||
<path | ||
fill='transparent' | ||
stroke-width='3' | ||
stroke-dashoffset='-3' | ||
stroke='#fff' | ||
d='M210.4,94.4c0-53.2,43-94.1,99-94.1c23.2,0.3,48.1,10.5,66.5,27.2l-27.4,35.2c-11-10-25.6-16.6-38.9-16.6 | ||
c-27.7,0-50.7,21.1-50.7,48.6c0,27.9,24.1,48.4,49.7,48.4c15.1,0,28.5-7.1,40.1-17.5l27.2,36.2c-17.2,15.6-40,26.4-67.3,26.4 | ||
C257.8,188.3,210.4,150.8,210.4,94.4z' | ||
/> | ||
<polygon | ||
fill='transparent' | ||
stroke-width='3' | ||
stroke-dashoffset='-3' | ||
stroke='#fff' | ||
points='525.1,45.7 481.2,45.7 481.2,188.3 432.5,188.3 432.5,45.7 388.6,45.7 388.6,0.3 525.1,0.3 ' | ||
/> | ||
<path | ||
fill='transparent' | ||
stroke-width='3' | ||
stroke-dashoffset='-3' | ||
stroke='#fff' | ||
d='M528.2,94.6c0-53.7,42.6-94.3,98.1-94.3c55.5,0,98.1,40.7,98.1,94.3c0,53.2-42.6,93.7-98.2,93.7 | ||
C570.7,188.3,528.2,147.8,528.2,94.6z M676.4,94.3c0-27.6-21.7-48.9-50.1-48.9c-28.4,0-50.1,21.3-50.1,48.9 | ||
c0,27.5,21.7,48.7,50.1,48.7C654.7,142.9,676.4,121.8,676.4,94.3z' | ||
/> | ||
<path | ||
fill='transparent' | ||
stroke-width='3' | ||
stroke-dashoffset='-3' | ||
stroke='#fff' | ||
d='M186.5,188.3h-48.6V0.3h48.6V188.3z' | ||
/> | ||
<path | ||
fill='var(--yellow)' | ||
stroke-width='3' | ||
stroke-dashoffset='-3' | ||
stroke='var(--yellow)' | ||
d='M26.9,139.6h48.7v48.7H26.9V139.6z M27.1,109c0-18.8,11.6-30.9,34.1-44.4c4.4-2.7,9-7.1,9-12.4 | ||
c0-8.7-6.7-14-19.1-14c-14.8,0-27.4,8-32.7,18L0.4,23.5C3.5,19.2,13.8,0.3,54.2,0.3c38.4,0,62.8,24.8,62.8,43.9 | ||
c0,16.4-3.4,25.4-17.1,36.1c-11.2,8.9-24.9,13.4-24.9,27.4c0,5.8,0.1,7.3,0.6,8.9l-48.3,0.1C27.1,115.5,27.1,114.2,27.1,109z' | ||
/> | ||
</g> | ||
</svg> | ||
<div class='sr-only'>Picto</div> | ||
</h1> | ||
<p class={headlineClass}> | ||
Showcase your skills with flare 🔥 | ||
</p> | ||
</header> | ||
</> | ||
); | ||
|
||
export default Hero; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import { css } from 'hono/css'; | ||
|
||
export const pageClass = css` | ||
:-hono-global { | ||
:root { | ||
--yellow: #f3c922; | ||
--dark-blue: #1a2b35; | ||
--rounded: 12px; | ||
font-size: 14px; | ||
line-height: 1.2; | ||
font-family: 'Fira Mono'; | ||
} | ||
body { | ||
background-color: var(--dark-blue); | ||
color: #fff; | ||
margin: 0; | ||
} | ||
* { | ||
box-sizing: border-box; | ||
&::selection { | ||
background-color: var(--yellow); | ||
} | ||
} | ||
p, input, button, blockquote { | ||
margin: 0; | ||
} | ||
h1, h2, h3, h4, h5, h6 { | ||
margin: 0; | ||
font-family: Rubik; | ||
margin-bottom: 1rem; | ||
} | ||
a { | ||
text-decoration-thickness: 2px; | ||
text-underline-offset: 4px; | ||
color: inherit; | ||
} | ||
.sr-only { | ||
display: none; | ||
} | ||
.text-color__yellow { | ||
color: var(--yellow); | ||
} | ||
.text-color__blue { | ||
color: var(--dark-blue); | ||
} | ||
} | ||
`; | ||
|
||
export const containerClass = css` | ||
max-width: 1000px; | ||
margin: auto; | ||
padding: 1rem; | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters