From b2cbd947c58e58cb462b3b271b53145200fbe0ea Mon Sep 17 00:00:00 2001 From: Patrick Alvin Alcala Date: Thu, 4 Sep 2025 12:05:03 +0800 Subject: [PATCH] Added fwt components --- fwt/components/Background/Background.sass | 1 + fwt/components/Background/Background.tsx | 50 ++++ fwt/components/Box/Box.sass | 6 + fwt/components/Box/Box.tsx | 20 ++ fwt/components/Button/Button.sass | 223 ++++++++++++++++++ fwt/components/Button/Button.tsx | 82 +++++++ fwt/components/Column/Column.sass | 39 +++ fwt/components/Column/Column.tsx | 18 ++ fwt/components/Copyright/Copyright.tsx | 14 ++ fwt/components/Footer/Footer.sass | 7 + fwt/components/Footer/Footer.tsx | 16 ++ fwt/components/Form/Form.sass | 0 fwt/components/Form/Form.tsx | 16 ++ fwt/components/HTML/HTML.sass | 25 ++ fwt/components/HTML/HTML.tsx | 35 +++ fwt/components/Image/Image.tsx | 19 ++ fwt/components/Input/Input.sass | 27 +++ fwt/components/Input/Input.tsx | 27 +++ fwt/components/Link/Link.sass | 3 + fwt/components/Link/Link.tsx | 16 ++ fwt/components/Logo/Logo.tsx | 19 ++ fwt/components/Navbar/Navbar.sass | 7 + fwt/components/Navbar/Navbar.tsx | 18 ++ .../Optimizer/OptimizeBackground.tsx | 17 ++ fwt/components/Optimizer/OptimizeImage.tsx | 21 ++ fwt/components/Optimizer/OptimizeLogo.tsx | 21 ++ fwt/components/Page/Page.sass | 14 ++ fwt/components/Page/Page.tsx | 20 ++ fwt/components/Row/Row.sass | 47 ++++ fwt/components/Row/Row.tsx | 24 ++ 30 files changed, 852 insertions(+) create mode 100644 fwt/components/Background/Background.sass create mode 100644 fwt/components/Background/Background.tsx create mode 100644 fwt/components/Box/Box.sass create mode 100644 fwt/components/Box/Box.tsx create mode 100644 fwt/components/Button/Button.sass create mode 100644 fwt/components/Button/Button.tsx create mode 100644 fwt/components/Column/Column.sass create mode 100644 fwt/components/Column/Column.tsx create mode 100644 fwt/components/Copyright/Copyright.tsx create mode 100644 fwt/components/Footer/Footer.sass create mode 100644 fwt/components/Footer/Footer.tsx create mode 100644 fwt/components/Form/Form.sass create mode 100644 fwt/components/Form/Form.tsx create mode 100644 fwt/components/HTML/HTML.sass create mode 100644 fwt/components/HTML/HTML.tsx create mode 100644 fwt/components/Image/Image.tsx create mode 100644 fwt/components/Input/Input.sass create mode 100644 fwt/components/Input/Input.tsx create mode 100644 fwt/components/Link/Link.sass create mode 100644 fwt/components/Link/Link.tsx create mode 100644 fwt/components/Logo/Logo.tsx create mode 100644 fwt/components/Navbar/Navbar.sass create mode 100644 fwt/components/Navbar/Navbar.tsx create mode 100644 fwt/components/Optimizer/OptimizeBackground.tsx create mode 100644 fwt/components/Optimizer/OptimizeImage.tsx create mode 100644 fwt/components/Optimizer/OptimizeLogo.tsx create mode 100644 fwt/components/Page/Page.sass create mode 100644 fwt/components/Page/Page.tsx create mode 100644 fwt/components/Row/Row.sass create mode 100644 fwt/components/Row/Row.tsx diff --git a/fwt/components/Background/Background.sass b/fwt/components/Background/Background.sass new file mode 100644 index 0000000..1e0b5bc --- /dev/null +++ b/fwt/components/Background/Background.sass @@ -0,0 +1 @@ +@use '/src/styles/classes.sass' diff --git a/fwt/components/Background/Background.tsx b/fwt/components/Background/Background.tsx new file mode 100644 index 0000000..12e21b2 --- /dev/null +++ b/fwt/components/Background/Background.tsx @@ -0,0 +1,50 @@ +import './Background.sass' +import { Show, createSignal } from 'solid-js' +import fs from 'fs' +import webpPath from '../../images/background.webp' +import avifPath from '../../images/background.avif' +import noBackground from '../../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 ( + <> + + + + + + + An image background + + + + + + An alternative background if found no image background + + + + + +
+ + + ) +} diff --git a/fwt/components/Box/Box.sass b/fwt/components/Box/Box.sass new file mode 100644 index 0000000..17165bb --- /dev/null +++ b/fwt/components/Box/Box.sass @@ -0,0 +1,6 @@ +.box + padding: 1rem + +.curvedbox + @extend .box + border-radius: 8px diff --git a/fwt/components/Box/Box.tsx b/fwt/components/Box/Box.tsx new file mode 100644 index 0000000..dc71de3 --- /dev/null +++ b/fwt/components/Box/Box.tsx @@ -0,0 +1,20 @@ +import type { ImageMetadata } from 'astro' +import './Box.sass' +import { Show, type JSXElement, createMemo } from 'solid-js' + +interface Props { + thickness: number + color?: string + children: JSXElement + curved?: boolean +} + +export default (props: Props) => { + const boxClass = createMemo(() => (props.curved ? 'curvedbox' : 'box')) + + return ( +
+ {props.children} +
+ ) +} diff --git a/fwt/components/Button/Button.sass b/fwt/components/Button/Button.sass new file mode 100644 index 0000000..329ba1d --- /dev/null +++ b/fwt/components/Button/Button.sass @@ -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 diff --git a/fwt/components/Button/Button.tsx b/fwt/components/Button/Button.tsx new file mode 100644 index 0000000..2de125f --- /dev/null +++ b/fwt/components/Button/Button.tsx @@ -0,0 +1,82 @@ +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' + submit?: boolean +} + +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 ( + <> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) +} diff --git a/fwt/components/Column/Column.sass b/fwt/components/Column/Column.sass new file mode 100644 index 0000000..b26f108 --- /dev/null +++ b/fwt/components/Column/Column.sass @@ -0,0 +1,39 @@ +.column-top + display: flex + flex-direction: column + flex-wrap: wrap + justify-content: flex-start + align-items: center + align-content: center + +.column-center + display: flex + flex-direction: column + flex-wrap: wrap + justify-content: center + align-items: center + align-content: center + +.column-right + display: flex + flex-direction: column + flex-wrap: wrap + justify-content: flex-end + align-items: center + align-content: center + +.column-split + display: flex + flex-direction: column + flex-wrap: wrap + justify-content: space-between + align-items: center + align-content: center + +.column-spaced + display: flex + flex-direction: column + flex-wrap: wrap + justify-content: space-around + align-items: center + align-content: center diff --git a/fwt/components/Column/Column.tsx b/fwt/components/Column/Column.tsx new file mode 100644 index 0000000..3f5c786 --- /dev/null +++ b/fwt/components/Column/Column.tsx @@ -0,0 +1,18 @@ +import type { JSXElement } from 'solid-js' +import './Column.sass' + +interface Props { + children: JSXElement + content?: 'top' | 'center' | 'right' | 'split' | 'spaced' + gap?: number +} + +export default (props: Props) => { + return ( + <> +
+ {props.children} +
+ + ) +} diff --git a/fwt/components/Copyright/Copyright.tsx b/fwt/components/Copyright/Copyright.tsx new file mode 100644 index 0000000..b8338d7 --- /dev/null +++ b/fwt/components/Copyright/Copyright.tsx @@ -0,0 +1,14 @@ +interface Props { + year: string + name: string +} + +export default (props: Props) => { + return ( + <> + + Copyright © {props.year} {props.name} All Rights Reserved. + + + ) +} diff --git a/fwt/components/Footer/Footer.sass b/fwt/components/Footer/Footer.sass new file mode 100644 index 0000000..70cd207 --- /dev/null +++ b/fwt/components/Footer/Footer.sass @@ -0,0 +1,7 @@ +.footer + padding: 1rem 0 + margin: 0 2rem + position: fixed + bottom: 0 + width: 100% + opacity: 0.8 diff --git a/fwt/components/Footer/Footer.tsx b/fwt/components/Footer/Footer.tsx new file mode 100644 index 0000000..2c47f07 --- /dev/null +++ b/fwt/components/Footer/Footer.tsx @@ -0,0 +1,16 @@ +import './Footer.sass' +import type { JSXElement } from 'solid-js' + +interface Props { + children: JSXElement +} + +export default (props: Props) => { + return ( + <> +
+ {props.children} +
+ + ) +} diff --git a/fwt/components/Form/Form.sass b/fwt/components/Form/Form.sass new file mode 100644 index 0000000..e69de29 diff --git a/fwt/components/Form/Form.tsx b/fwt/components/Form/Form.tsx new file mode 100644 index 0000000..a498c76 --- /dev/null +++ b/fwt/components/Form/Form.tsx @@ -0,0 +1,16 @@ +import './Form.sass' +import type { JSXElement } from 'solid-js' + +interface Props { + children: JSXElement +} + +export default (props: Props) => { + return ( + <> +
+ {props.children} +
+ + ) +} diff --git a/fwt/components/HTML/HTML.sass b/fwt/components/HTML/HTML.sass new file mode 100644 index 0000000..92e9d1c --- /dev/null +++ b/fwt/components/HTML/HTML.sass @@ -0,0 +1,25 @@ +@use '/src/styles/variables.sass' as vars +@use '/src/styles/fonts.sass' as fonts + +.body + color: vars.$textColor + +.inter + @extend .body + font-family: fonts.$Inter + +.roboto + @extend .body + font-family: fonts.$Roboto + +.montserrat + @extend .body + font-family: fonts.$Montserrat + +.open-sans + @extend .body + font-family: fonts.$OpenSans + +.public-sans + @extend .body + font-family: fonts.$PublicSans diff --git a/fwt/components/HTML/HTML.tsx b/fwt/components/HTML/HTML.tsx new file mode 100644 index 0000000..ccee123 --- /dev/null +++ b/fwt/components/HTML/HTML.tsx @@ -0,0 +1,35 @@ +import './HTML.sass' +import { type JSXElement, Show } from 'solid-js' + +interface Props { + title: string + name: string + description: string + children: JSXElement + font?: 'roboto' | 'inter' | 'montserrat' | 'open-sans' | 'public-sans' +} + +export default (props: Props) => { + return ( + <> + + + + + + + + + + + + + {props.title} + + + {props.children} + + s + + ) +} diff --git a/fwt/components/Image/Image.tsx b/fwt/components/Image/Image.tsx new file mode 100644 index 0000000..d885641 --- /dev/null +++ b/fwt/components/Image/Image.tsx @@ -0,0 +1,19 @@ +interface Props { + avif: string + webp: string + size?: number + alt?: string + radius?: number +} + +export default (props: Props) => { + return ( + <> + + + + {props.alt} + + + ) +} diff --git a/fwt/components/Input/Input.sass b/fwt/components/Input/Input.sass new file mode 100644 index 0000000..391937c --- /dev/null +++ b/fwt/components/Input/Input.sass @@ -0,0 +1,27 @@ +.input + font-size: 1rem + padding: 0.5rem 1rem + width: 100% + border: 2px solid #ccc + border-radius: 4px + outline: none + transition: border-color 0.3s, box-shadow 0.3s + + &:focus + border-color: #3377AC + box-shadow: 0 0 5px rgba(51, 119, 168, 0.3) + + &::placeholder + color: #888 + font-style: italic + + &:disabled + background-color: #f0f0f0 + border-color: #ddd + + &--error + border-color: #ff4d4f + box-shadow: 0 0 5px rgba(255, 77, 79, 0.3) + + &:focus + border-color: #e81123 diff --git a/fwt/components/Input/Input.tsx b/fwt/components/Input/Input.tsx new file mode 100644 index 0000000..c0f7c97 --- /dev/null +++ b/fwt/components/Input/Input.tsx @@ -0,0 +1,27 @@ +import './Input.sass' +import { createSignal } from 'solid-js' + +interface Props { + placeholder?: string + value?: string + onChange?: (value: string) => void +} + +export default (props: Props) => { + const [inputValue, setInputValue] = createSignal(props.value || '') + + const handleChange = (event: Event) => { + const target = event.target as HTMLInputElement + const newValue = target.value + setInputValue(newValue) + if (props.onChange) { + props.onChange(newValue) + } + } + + return ( + <> + + + ) +} diff --git a/fwt/components/Link/Link.sass b/fwt/components/Link/Link.sass new file mode 100644 index 0000000..efc3b4f --- /dev/null +++ b/fwt/components/Link/Link.sass @@ -0,0 +1,3 @@ +a + text-decoration: none + color: inherit diff --git a/fwt/components/Link/Link.tsx b/fwt/components/Link/Link.tsx new file mode 100644 index 0000000..1e7e337 --- /dev/null +++ b/fwt/components/Link/Link.tsx @@ -0,0 +1,16 @@ +import './Link.sass' + +interface Props { + to: string + children?: any +} + +export default (props: Props) => { + return ( + <> + + {props.children} + + + ) +} diff --git a/fwt/components/Logo/Logo.tsx b/fwt/components/Logo/Logo.tsx new file mode 100644 index 0000000..5d1af4c --- /dev/null +++ b/fwt/components/Logo/Logo.tsx @@ -0,0 +1,19 @@ +import webpPath from '../../images/logo.webp' +import avifPath from '../../images/logo.avif' + +interface Props { + size?: number + alt?: string +} + +export default (props: Props) => { + return ( + <> + + + + logo + + + ) +} diff --git a/fwt/components/Navbar/Navbar.sass b/fwt/components/Navbar/Navbar.sass new file mode 100644 index 0000000..edbda91 --- /dev/null +++ b/fwt/components/Navbar/Navbar.sass @@ -0,0 +1,7 @@ +.nav + position: fixed + top: 0 + width: 100% + padding: 1rem 0 + // margin: 5rem + diff --git a/fwt/components/Navbar/Navbar.tsx b/fwt/components/Navbar/Navbar.tsx new file mode 100644 index 0000000..3b0c688 --- /dev/null +++ b/fwt/components/Navbar/Navbar.tsx @@ -0,0 +1,18 @@ +import './Navbar.sass' +import { Show } from 'solid-js' +import Row from '../Row/Row' + +interface Props { + transparent?: boolean + children: HTMLElement +} + +export default (props: Props) => { + return ( + <> + + + ) +} diff --git a/fwt/components/Optimizer/OptimizeBackground.tsx b/fwt/components/Optimizer/OptimizeBackground.tsx new file mode 100644 index 0000000..1c27caf --- /dev/null +++ b/fwt/components/Optimizer/OptimizeBackground.tsx @@ -0,0 +1,17 @@ +import sharp from 'sharp' + +const convertBackground = async () => { + const inputSrc = 'src/assets/images/background.png' + const webpOutput = 'fwt/images/background.webp' + const avifOutput = 'fwt/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() +} diff --git a/fwt/components/Optimizer/OptimizeImage.tsx b/fwt/components/Optimizer/OptimizeImage.tsx new file mode 100644 index 0000000..00afd77 --- /dev/null +++ b/fwt/components/Optimizer/OptimizeImage.tsx @@ -0,0 +1,21 @@ +import sharp from 'sharp' + +interface Props { + src: string + size?: number +} + +const convertImage = async (props: Props) => { + const avifOutputPath = `fwt/images/${props.src.split('.').slice(0, -1).join('.')}.avif` + const webpOutputPath = `fwt/images/${props.src.split('.').slice(0, -1).join('.')}.webp` + + 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) => { + convertImage(props) +} diff --git a/fwt/components/Optimizer/OptimizeLogo.tsx b/fwt/components/Optimizer/OptimizeLogo.tsx new file mode 100644 index 0000000..e3e8014 --- /dev/null +++ b/fwt/components/Optimizer/OptimizeLogo.tsx @@ -0,0 +1,21 @@ +import sharp from 'sharp' + +interface Props { + size?: number +} + +const convertLogo = async (props: Props) => { + const inputSrc = 'src/assets/images/logo.png' + const webpImage = 'fwt/images/logo.webp' + const avifImage = 'fwt/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) +} diff --git a/fwt/components/Page/Page.sass b/fwt/components/Page/Page.sass new file mode 100644 index 0000000..af99849 --- /dev/null +++ b/fwt/components/Page/Page.sass @@ -0,0 +1,14 @@ +.page + margin: 2rem + height: auto + min-height: 90vh + +.column + @extend .page + display: flex + flex-direction: column + align-items: center + +.row + @extend .column + flex-direction: row diff --git a/fwt/components/Page/Page.tsx b/fwt/components/Page/Page.tsx new file mode 100644 index 0000000..62d9a73 --- /dev/null +++ b/fwt/components/Page/Page.tsx @@ -0,0 +1,20 @@ +import './Page.sass' +import { Show } from 'solid-js' + +interface Props { + children?: any + alignment?: 'row' | 'column' +} + +export default (props: Props) => { + return ( + <> + +
{props.children}
+
+ +
{props.children}
+
+ + ) +} diff --git a/fwt/components/Row/Row.sass b/fwt/components/Row/Row.sass new file mode 100644 index 0000000..6162bbe --- /dev/null +++ b/fwt/components/Row/Row.sass @@ -0,0 +1,47 @@ +.row-left + display: flex + flex-direction: row + flex-wrap: wrap + justify-content: flex-start + align-items: center + align-content: center + +.row-center + display: flex + flex-direction: row + flex-wrap: wrap + justify-content: center + align-items: center + align-content: center + +.row-right + display: flex + flex-direction: row + flex-wrap: wrap + justify-content: flex-end + align-items: center + align-content: center + +.row-split + display: flex + flex-direction: row + flex-wrap: wrap + justify-content: space-between + align-items: center + align-content: center + +.row-spaced + display: flex + flex-direction: row + flex-wrap: wrap + justify-content: space-around + align-items: center + align-content: center + +.row-even + display: flex + flex-direction: row + flex-wrap: wrap + justify-content: space-evenly + align-items: center + align-content: center diff --git a/fwt/components/Row/Row.tsx b/fwt/components/Row/Row.tsx new file mode 100644 index 0000000..5255e9c --- /dev/null +++ b/fwt/components/Row/Row.tsx @@ -0,0 +1,24 @@ +import './Row.sass' +import { Show, type JSXElement } from 'solid-js' + +interface Props { + children: JSXElement + content?: 'left' | 'center' | 'right' | 'split' | 'spaced' | 'even' + gap?: number +} + +export default (props: Props) => { + return ( + <> + +
+ {props.children} +
+
+ + +
{props.children}
+
+ + ) +}