Moved files
This commit is contained in:
parent
0e6ed89a08
commit
39d01e7a55
12 changed files with 482 additions and 0 deletions
1
src/templates/components/Background/Background.sass
Normal file
1
src/templates/components/Background/Background.sass
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
@use '/src/styles/classes.sass'
|
||||||
50
src/templates/components/Background/Background.tsx
Normal file
50
src/templates/components/Background/Background.tsx
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
import './Background.sass'
|
||||||
|
import { Show, createSignal } from 'solid-js'
|
||||||
|
import fs from 'fs'
|
||||||
|
import webpPath from '../../../templates/images/background.webp'
|
||||||
|
import avifPath from '../../../templates/images/background.avif'
|
||||||
|
import noBackground from '../../../templates/images/no-background.webp'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
image?: boolean
|
||||||
|
color?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
let [imageLoaded, setImageLoaded] = createSignal(false)
|
||||||
|
|
||||||
|
const checkBackground = () => {
|
||||||
|
if (!fs.existsSync(avifPath.src) && !fs.existsSync(webpPath.src)) {
|
||||||
|
setImageLoaded(true)
|
||||||
|
} else {
|
||||||
|
setImageLoaded(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default (props: Props) => {
|
||||||
|
checkBackground()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Show when={props.image}>
|
||||||
|
<Show when={imageLoaded()}>
|
||||||
|
<picture class="fullscreen">
|
||||||
|
<source srcset={avifPath.src} type="image/avif" />
|
||||||
|
<source srcset={webpPath.src} type="image/webp" />
|
||||||
|
<source srcset={noBackground.src} type="image/webp" />
|
||||||
|
<img width="1920" height="auto" decoding="async" loading="lazy" alt="An image background" />
|
||||||
|
</picture>
|
||||||
|
</Show>
|
||||||
|
<Show when={!imageLoaded()}>
|
||||||
|
<picture class="fullscreen">
|
||||||
|
<source srcset={noBackground.src} type="image/webp" />
|
||||||
|
<img width="1920" height="auto" decoding="async" loading="lazy" alt="An alternative background if found no image background" />
|
||||||
|
</picture>
|
||||||
|
</Show>
|
||||||
|
</Show>
|
||||||
|
|
||||||
|
<Show when={!props.image}>
|
||||||
|
<div style={{ background: props.color }} class="fullscreen" />
|
||||||
|
</Show>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
223
src/templates/components/Button/Button.sass
Normal file
223
src/templates/components/Button/Button.sass
Normal file
|
|
@ -0,0 +1,223 @@
|
||||||
|
@use '/src/styles/variables.sass' as vars
|
||||||
|
@use '/src/styles/fonts.sass' as fonts
|
||||||
|
@use 'sass:color'
|
||||||
|
|
||||||
|
$bulmaPrimary: rgb(0, 235, 199)
|
||||||
|
$bulmaPrimaryText: rgb(0, 31, 26)
|
||||||
|
$bulmaLink: rgb(92, 111, 255)
|
||||||
|
$bulmaLinkText: rgb(245, 246, 255)
|
||||||
|
$bulmaInfo: rgb(128, 217, 255)
|
||||||
|
$bulmaInfoText: rgb(0, 36, 51)
|
||||||
|
$bulmaSuccess: rgb(91, 205, 154)
|
||||||
|
$bulmaSuccessText: rgb(10, 31, 21)
|
||||||
|
$bulmaWarning: rgb(255, 191, 41)
|
||||||
|
$bulmaWarningText: rgb(41, 29, 0)
|
||||||
|
$bulmaDanger: rgb(255, 128, 153)
|
||||||
|
$bulmaDangerText: rgb(26, 0, 5)
|
||||||
|
$bulmaLight: rgb(255, 255, 255)
|
||||||
|
$bulmaLightText: rgb(46, 51, 61)
|
||||||
|
$bulmaDark: rgb(57, 63, 76)
|
||||||
|
$bulmaDarkText: rgb(243, 244, 246)
|
||||||
|
$bulmaText: rgb(31, 34, 41)
|
||||||
|
$bulmaTextText: rgb(235, 236, 240)
|
||||||
|
$bulmaGhost: rgba(0,0,0,0)
|
||||||
|
$bulmaGhostText: rgb(66, 88, 255)
|
||||||
|
|
||||||
|
$bootstrapTextLight: rgb(255, 255, 253)
|
||||||
|
$bootstrapTextDark: rgb(0, 0, 2)
|
||||||
|
$bootstrapTextLink: rgb(139, 185, 254)
|
||||||
|
$bootstrapPrimary: rgb(13, 110, 253)
|
||||||
|
$bootstrapSecondary: rgb(92, 99, 106)
|
||||||
|
$bootstrapSuccess: rgb(21, 115, 71)
|
||||||
|
$bootstrapDanger: rgb(187, 45, 59)
|
||||||
|
$bootstrapWarning: rgb(255, 202, 44)
|
||||||
|
$bootstrapInfo: rgb(49, 210, 242)
|
||||||
|
$bootstrapLight: rgb(211, 212, 213)
|
||||||
|
$bootstrapDark: rgb(33, 37, 41)
|
||||||
|
|
||||||
|
.button
|
||||||
|
background-color: vars.$primaryColor
|
||||||
|
border: none
|
||||||
|
color: white
|
||||||
|
padding: 0.5rem 1.25rem
|
||||||
|
text-align: center
|
||||||
|
text-decoration: none
|
||||||
|
display: inline-block
|
||||||
|
font-size: 1rem
|
||||||
|
font-weight: 500
|
||||||
|
cursor: pointer
|
||||||
|
transition: all 0.2s ease-out
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
background-color: color.adjust(vars.$primaryColor, $blackness: 20%)
|
||||||
|
|
||||||
|
&:active
|
||||||
|
transform: scale(0.95)
|
||||||
|
|
||||||
|
.bu-primary
|
||||||
|
@extend .button
|
||||||
|
font-family: fonts.$Inter
|
||||||
|
background-color: $bulmaPrimary
|
||||||
|
color: $bulmaPrimaryText
|
||||||
|
border: none
|
||||||
|
font-size: 1rem
|
||||||
|
border-radius: 0.375rem
|
||||||
|
font-weight: 500
|
||||||
|
padding: 0.5rem 1.25rem
|
||||||
|
height: 2.5rem
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
background-color: color.adjust($bulmaPrimary, $lightness: 10%)
|
||||||
|
|
||||||
|
.bu-link
|
||||||
|
@extend .bu-primary
|
||||||
|
background-color: $bulmaLink
|
||||||
|
color: $bulmaLinkText
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
background-color: color.adjust($bulmaLink, $lightness: 5%)
|
||||||
|
|
||||||
|
.bu-info
|
||||||
|
@extend .bu-primary
|
||||||
|
background-color: $bulmaInfo
|
||||||
|
color: $bulmaInfoText
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
background-color: color.adjust($bulmaInfo, $lightness: 5%)
|
||||||
|
|
||||||
|
.bu-success
|
||||||
|
@extend .bu-primary
|
||||||
|
background-color: $bulmaSuccess
|
||||||
|
color: $bulmaSuccessText
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
background-color: color.adjust($bulmaSuccess, $lightness: 5%)
|
||||||
|
|
||||||
|
.bu-warning
|
||||||
|
@extend .bu-primary
|
||||||
|
background-color: $bulmaWarning
|
||||||
|
color: $bulmaWarningText
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
background-color: color.adjust($bulmaWarning, $lightness: 5%)
|
||||||
|
|
||||||
|
.bu-danger
|
||||||
|
@extend .bu-primary
|
||||||
|
background-color: $bulmaDanger
|
||||||
|
color: $bulmaDangerText
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
background-color: color.adjust($bulmaDanger, $lightness: 5%)
|
||||||
|
|
||||||
|
.bu-light
|
||||||
|
@extend .bu-primary
|
||||||
|
background-color: $bulmaLight
|
||||||
|
color: $bulmaLightText
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
background-color: color.adjust($bulmaLight, $lightness: 5%)
|
||||||
|
|
||||||
|
.bu-dark
|
||||||
|
@extend .bu-primary
|
||||||
|
background-color: $bulmaDark
|
||||||
|
color: $bulmaDarkText
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
background-color: color.adjust($bulmaDark, $lightness: 5%)
|
||||||
|
|
||||||
|
.bu-text
|
||||||
|
@extend .bu-primary
|
||||||
|
background-color: rgba(0,0,0,0)
|
||||||
|
color: $bulmaTextText
|
||||||
|
text-decoration: underline
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
background-color: hsl(221,14%,14%)
|
||||||
|
|
||||||
|
.bu-ghost
|
||||||
|
@extend .bu-primary
|
||||||
|
background-color: $bulmaGhost
|
||||||
|
color: $bulmaGhostText
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
background-color: transparent
|
||||||
|
text-decoration: underline
|
||||||
|
|
||||||
|
.bo-primary
|
||||||
|
@extend .button
|
||||||
|
font-family: 'Segoe UI', fonts.$Roboto
|
||||||
|
background-color: $bootstrapPrimary
|
||||||
|
color: $bootstrapTextLight
|
||||||
|
border: none
|
||||||
|
font-size: 1rem
|
||||||
|
border-radius: 0.375rem
|
||||||
|
font-weight: 400
|
||||||
|
padding: 0.5rem 1.25rem
|
||||||
|
height: 2.5rem
|
||||||
|
margin: 0.25rem 0.125rem
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
background-color: color.adjust($bootstrapPrimary, $blackness: 10%)
|
||||||
|
|
||||||
|
.bo-secondary
|
||||||
|
@extend .bo-primary
|
||||||
|
background-color: $bootstrapSecondary
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
background-color: color.adjust($bootstrapSecondary, $blackness: 10%)
|
||||||
|
|
||||||
|
.bo-success
|
||||||
|
@extend .bo-primary
|
||||||
|
background-color: $bootstrapSuccess
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
background-color: color.adjust($bootstrapSuccess, $blackness: 10%)
|
||||||
|
|
||||||
|
.bo-danger
|
||||||
|
@extend .bo-primary
|
||||||
|
background-color: $bootstrapDanger
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
background-color: color.adjust($bootstrapDanger, $blackness: 10%)
|
||||||
|
|
||||||
|
.bo-warning
|
||||||
|
@extend .bo-primary
|
||||||
|
background-color: $bootstrapWarning
|
||||||
|
color: $bootstrapTextDark
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
background-color: color.adjust($bootstrapWarning, $lightness: 5%)
|
||||||
|
|
||||||
|
.bo-info
|
||||||
|
@extend .bo-primary
|
||||||
|
background-color: $bootstrapInfo
|
||||||
|
color: $bootstrapTextDark
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
background-color: color.adjust($bootstrapInfo, $lightness: 5%)
|
||||||
|
|
||||||
|
.bo-light
|
||||||
|
@extend .bo-primary
|
||||||
|
background-color: $bootstrapLight
|
||||||
|
color: $bootstrapTextDark
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
background-color: color.adjust($bootstrapLight, $blackness: 10%)
|
||||||
|
|
||||||
|
.bo-dark
|
||||||
|
@extend .bo-primary
|
||||||
|
background-color: $bootstrapDark
|
||||||
|
// color: $bootstrapTextDark
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
background-color: color.adjust($bootstrapDark, $lightness: 10%)
|
||||||
|
|
||||||
|
.bo-link
|
||||||
|
@extend .bo-primary
|
||||||
|
background-color: transparent
|
||||||
|
color: $bootstrapTextLink
|
||||||
|
text-decoration: underline
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
color: color.adjust($bootstrapTextLink, $lightness: 5%)
|
||||||
|
background-color: transparent
|
||||||
65
src/templates/components/Button/Button.tsx
Normal file
65
src/templates/components/Button/Button.tsx
Normal file
|
|
@ -0,0 +1,65 @@
|
||||||
|
import './Button.sass'
|
||||||
|
import { Show, Switch, Match } from 'solid-js'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
label?: string
|
||||||
|
to?: string
|
||||||
|
onClick?: () => void
|
||||||
|
edges?: 'curved' | 'rounded' | 'flat'
|
||||||
|
design?: 'bu-primary' | 'bu-link' | 'bu-info' | 'bu-success' | 'bu-warning' | 'bu-danger' | 'bu-dark' | 'bu-light' | 'bu-text' | 'bu-ghost' | 'bo-primary' | 'bo-secondary' | 'bo-success' | 'bo-danger' | 'bo-warning' | 'bo-info' | 'bo-light' | 'bo-dark' | 'bo-link'
|
||||||
|
}
|
||||||
|
|
||||||
|
const getBorderRadius = (edge: Props['edges']) => {
|
||||||
|
switch (edge) {
|
||||||
|
case 'curved':
|
||||||
|
return 'border-radius: 6px'
|
||||||
|
case 'rounded':
|
||||||
|
return 'border-radius: 32px'
|
||||||
|
case 'flat':
|
||||||
|
return 'border-radius: 0'
|
||||||
|
default:
|
||||||
|
return 'border-radius: 0'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default (props: Props) => {
|
||||||
|
const borderRadius = getBorderRadius(props.edges)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Show when={props.to}>
|
||||||
|
<Switch>
|
||||||
|
<Match when={props.design}>
|
||||||
|
<a href={props.to} aria-label={props.label}>
|
||||||
|
<button class={props.design} style={borderRadius}>
|
||||||
|
{props.label || 'Click Me!'}
|
||||||
|
</button>
|
||||||
|
</a>
|
||||||
|
</Match>
|
||||||
|
<Match when={!props.design}>
|
||||||
|
<a href={props.to} aria-label={props.label}>
|
||||||
|
<button class="button" style={borderRadius}>
|
||||||
|
{props.label || 'Click Me!'}
|
||||||
|
</button>
|
||||||
|
</a>
|
||||||
|
</Match>
|
||||||
|
</Switch>
|
||||||
|
</Show>
|
||||||
|
|
||||||
|
<Show when={!props.to}>
|
||||||
|
<Switch>
|
||||||
|
<Match when={props.design}>
|
||||||
|
<button class={props.design} onClick={props.onClick} style={borderRadius}>
|
||||||
|
{props.label || 'Click Me!'}
|
||||||
|
</button>
|
||||||
|
</Match>
|
||||||
|
<Match when={!props.design}>
|
||||||
|
<button class="button" onClick={props.onClick} style={borderRadius}>
|
||||||
|
{props.label || 'Click Me!'}
|
||||||
|
</button>
|
||||||
|
</Match>
|
||||||
|
</Switch>
|
||||||
|
</Show>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
36
src/templates/components/Image/Image.tsx
Normal file
36
src/templates/components/Image/Image.tsx
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
import sharp from 'sharp'
|
||||||
|
import fs from 'fs'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
src: string
|
||||||
|
size?: number
|
||||||
|
alt?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const convertImage = async (props: Props) => {
|
||||||
|
const avifOutputPath = `src/assets/optimized/${props.src.split('.').slice(0, -1).join('.')}.avif`
|
||||||
|
const webpOutputPath = `src/assets/optimized/${props.src.split('.').slice(0, -1).join('.')}.webp`
|
||||||
|
|
||||||
|
if (!fs.existsSync(webpOutputPath) || !fs.existsSync(avifOutputPath)) {
|
||||||
|
const avifBuffer = await sharp(`src/assets/images/${props.src}`).avif({ quality: 60 }).resize(props.size).toBuffer()
|
||||||
|
await sharp(avifBuffer).toFile(avifOutputPath)
|
||||||
|
|
||||||
|
const webpBuffer = await sharp(`src/assets/images/${props.src}`).webp({ quality: 75 }).resize(props.size).toBuffer()
|
||||||
|
await sharp(webpBuffer).toFile(webpOutputPath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default (props: Props) => {
|
||||||
|
const imageSrc = `src/assets/optimized/${props.src.split('.').slice(0, -1).join('.')}.webp`
|
||||||
|
convertImage(props)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<picture>
|
||||||
|
<source srcset={imageSrc.replace(/\.webp$/, '.avif')} type="image/avif" />
|
||||||
|
<source srcset={imageSrc} type="image/webp" />
|
||||||
|
<img src={imageSrc} width={props.size} height="auto" decoding="async" loading="lazy" alt={props.alt} />
|
||||||
|
</picture>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
14
src/templates/components/Link/Link.tsx
Normal file
14
src/templates/components/Link/Link.tsx
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
interface Props {
|
||||||
|
to: string
|
||||||
|
children?: any
|
||||||
|
}
|
||||||
|
|
||||||
|
export default (props: Props) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<a href={props.to} aria-label={`Go to ${props.to}`}>
|
||||||
|
{props.children}
|
||||||
|
</a>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
19
src/templates/components/Logo/Logo.tsx
Normal file
19
src/templates/components/Logo/Logo.tsx
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
import webpPath from '../../../templates/images/logo.webp'
|
||||||
|
import avifPath from '../../../templates/images/logo.avif'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
size?: number
|
||||||
|
alt?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export default (props: Props) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<picture>
|
||||||
|
<source srcset={avifPath.src} type="image/avif" />
|
||||||
|
<source srcset={webpPath.src} type="image/webp" />
|
||||||
|
<img width={props.size} height="auto" decoding="async" loading="lazy" alt="logo" />
|
||||||
|
</picture>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
17
src/templates/components/Optimizer/OptimizeBackground.tsx
Normal file
17
src/templates/components/Optimizer/OptimizeBackground.tsx
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
import sharp from 'sharp'
|
||||||
|
|
||||||
|
const convertBackground = async () => {
|
||||||
|
const inputSrc = 'src/assets/images/background.png'
|
||||||
|
const webpOutput = 'src/templates/images/background.webp'
|
||||||
|
const avifOutput = 'src/templates/images/background.avif'
|
||||||
|
|
||||||
|
const avifBuffer = await sharp(inputSrc).avif({ quality: 60 }).resize(1920).toBuffer()
|
||||||
|
await sharp(avifBuffer).toFile(avifOutput)
|
||||||
|
|
||||||
|
const webpBuffer = await sharp(inputSrc).webp({ quality: 75 }).resize(1920).toBuffer()
|
||||||
|
await sharp(webpBuffer).toFile(webpOutput)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default () => {
|
||||||
|
convertBackground()
|
||||||
|
}
|
||||||
22
src/templates/components/Optimizer/OptimizeLogo.tsx
Normal file
22
src/templates/components/Optimizer/OptimizeLogo.tsx
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
import sharp from 'sharp'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
size?: number
|
||||||
|
alt?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const convertLogo = async (props: Props) => {
|
||||||
|
const inputSrc = 'src/assets/images/logo.png'
|
||||||
|
const webpImage = 'src/templates/images/logo.webp'
|
||||||
|
const avifImage = 'src/templates/images/logo.avif'
|
||||||
|
|
||||||
|
const avifBuffer = await sharp(inputSrc).avif({ quality: 60 }).resize(props.size).toBuffer()
|
||||||
|
await sharp(avifBuffer).toFile(avifImage)
|
||||||
|
|
||||||
|
const webpBuffer = await sharp(inputSrc).webp({ quality: 75 }).resize(props.size).toBuffer()
|
||||||
|
await sharp(webpBuffer).toFile(webpImage)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default (props: Props) => {
|
||||||
|
convertLogo(props)
|
||||||
|
}
|
||||||
15
src/templates/components/Page/Page.sass
Normal file
15
src/templates/components/Page/Page.sass
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
.page
|
||||||
|
margin: 2rem
|
||||||
|
height: auto
|
||||||
|
|
||||||
|
.column
|
||||||
|
@extend .page
|
||||||
|
display: flex
|
||||||
|
flex-direction: column
|
||||||
|
text-align: center
|
||||||
|
justify-content: center
|
||||||
|
align-items: center
|
||||||
|
|
||||||
|
.row
|
||||||
|
@extend .column
|
||||||
|
flex-direction: row
|
||||||
20
src/templates/components/Page/Page.tsx
Normal file
20
src/templates/components/Page/Page.tsx
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
import './Page.sass'
|
||||||
|
import { Show, Switch, Match } from 'solid-js'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
children?: any
|
||||||
|
alignment?: 'row' | 'column'
|
||||||
|
}
|
||||||
|
|
||||||
|
export default (props: Props) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Show when={props.alignment}>
|
||||||
|
<main class={props.alignment}>{props.children}</main>
|
||||||
|
</Show>
|
||||||
|
<Show when={!props.alignment}>
|
||||||
|
<main class="page">{props.children}</main>
|
||||||
|
</Show>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
BIN
src/templates/images/no-background.webp
Normal file
BIN
src/templates/images/no-background.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
Loading…
Add table
Add a link
Reference in a new issue