diff options
author | flu0r1ne <flu0r1ne@flu0r1ne.net> | 2023-09-07 21:28:37 -0500 |
---|---|---|
committer | flu0r1ne <flu0r1ne@flu0r1ne.net> | 2023-09-07 21:28:37 -0500 |
commit | d67f3514eff4f45ad1ca84cde6465e622acd4dcc (patch) | |
tree | 55f9c8e4f68f1269300b937fb14ae76e3446d621 /components | |
parent | ef4fb0a5277ee99bd0f1747b77e733ef7f02460d (diff) | |
download | homepage-d67f3514eff4f45ad1ca84cde6465e622acd4dcc.tar.xz homepage-d67f3514eff4f45ad1ca84cde6465e622acd4dcc.zip |
Scoped global styling to all markdown
Make React compatible with markdown-style HTML by added components
with identical styling to markdown. This is done while CSS scoping
is maintained. Additional style is loaded through the markdown loader
by injecting default-styling tags into the components. This allows
default-margin to be added to these elements in addition to the styling
found in the React elements. The homepage reflects the domain, as defined
by an environmental variable.
Diffstat (limited to 'components')
-rw-r--r-- | components/Box/index.tsx | 14 | ||||
-rw-r--r-- | components/BreadCrumbs/index.tsx | 6 | ||||
-rw-r--r-- | components/Code/index.tsx | 10 | ||||
-rw-r--r-- | components/Link/index.tsx | 23 | ||||
-rw-r--r-- | components/Link/link.module.scss | 11 | ||||
-rw-r--r-- | components/List/index.tsx | 52 | ||||
-rw-r--r-- | components/List/list.module.scss | 41 | ||||
-rw-r--r-- | components/Markdown/index.tsx | 16 | ||||
-rw-r--r-- | components/Markdown/markdown.module.scss | 111 | ||||
-rw-r--r-- | components/Markdown/markdown.scss | 418 | ||||
-rw-r--r-- | components/PathCrumbs/index.tsx | 7 | ||||
-rw-r--r-- | components/Typ/index.tsx (renamed from components/Typography/index.tsx) | 8 | ||||
-rw-r--r-- | components/Typ/typo.module.scss | 3 | ||||
-rw-r--r-- | components/Typography/typo.module.scss | 64 | ||||
-rw-r--r-- | components/ViewPort/index.tsx | 33 |
15 files changed, 607 insertions, 210 deletions
diff --git a/components/Box/index.tsx b/components/Box/index.tsx index 32866b2..f81fa5b 100644 --- a/components/Box/index.tsx +++ b/components/Box/index.tsx @@ -3,15 +3,23 @@ import { getSystemStyle, SystemProps } from '../utils/systemProps'; interface BoxProps extends SystemProps { style?: React.CSSProperties; children?: React.ReactNode; + el?: keyof React.ReactHTML; }; -const Box: React.FC<BoxProps> = ({ style, children, ...props}) => { +const Box: React.FC<BoxProps> = ({ el, style, children, ...props}) => { const systemStyle = getSystemStyle(props, style); + let Tag = el; + + if(!el) { + Tag = 'div' as keyof React.ReactHTML; + } + return ( - <div style={systemStyle}> + // @ts-ignore + <Tag style={systemStyle}> { children } - </div> + </Tag> ); }; diff --git a/components/BreadCrumbs/index.tsx b/components/BreadCrumbs/index.tsx index 693a9d0..98b20b4 100644 --- a/components/BreadCrumbs/index.tsx +++ b/components/BreadCrumbs/index.tsx @@ -1,5 +1,5 @@ import React, { Children, FC } from "react"; -import Link from "next/link"; +import Link from '../Link'; import styles from './breadcrumbs.module.scss'; import clsx from 'clsx'; @@ -9,8 +9,8 @@ export type BreadCrumbsProps = { children: React.ReactNode; }; -const BreadCrumbs : FC<BreadCrumbsProps> = ({children, className, ...props}) => ( - <span className={clsx(styles.breadcrumbs, className)} {...props}> +const BreadCrumbs : FC<BreadCrumbsProps> = ({children, className, style, ...props}) => ( + <span style={{ whiteSpace: 'nowrap', ...style }} className={clsx(styles.breadcrumbs, className)} {...props}> {Children.map(children, (child, index) => { return ( <> diff --git a/components/Code/index.tsx b/components/Code/index.tsx new file mode 100644 index 0000000..23e7a8b --- /dev/null +++ b/components/Code/index.tsx @@ -0,0 +1,10 @@ +import React, { FC, CSSProperties } from 'react'; + +interface CodeProps extends React.HTMLProps<HTMLSpanElement> { + style?: CSSProperties; +} +const Code: FC<CodeProps> = ({ children, style }) => { + return <code className='md-codespan' style={style}>{children}</code>; +}; + +export default Code; diff --git a/components/Link/index.tsx b/components/Link/index.tsx new file mode 100644 index 0000000..e6477c2 --- /dev/null +++ b/components/Link/index.tsx @@ -0,0 +1,23 @@ +import React, { ReactNode } from 'react'; +import NextLink from 'next/link'; +import styles from './link.module.scss'; +import clsx from 'clsx'; + +interface LinkProps { + href: string; + children: ReactNode; + className?: string; +} + +const Link: React.FC<LinkProps> = ({ href, className, children }) => { + return ( + <NextLink + href={href} + className={clsx('md-a', className)} + > + {children} + </NextLink> + ); +}; + +export default Link; diff --git a/components/Link/link.module.scss b/components/Link/link.module.scss new file mode 100644 index 0000000..b6ef943 --- /dev/null +++ b/components/Link/link.module.scss @@ -0,0 +1,11 @@ +.link { + text-decoration: none; +} + +.link:hover { + text-decoration: underline; +} + +.link, .link:visited, .link:active, .link:hover { + color: #0716ea; +} diff --git a/components/List/index.tsx b/components/List/index.tsx new file mode 100644 index 0000000..ae5c190 --- /dev/null +++ b/components/List/index.tsx @@ -0,0 +1,52 @@ +import React, { FC } from 'react'; +import { getSystemStyle, SystemProps } from '../utils/systemProps'; +import clsx from 'clsx'; + +interface ListProps extends SystemProps { + style?: React.CSSProperties; + variant : 'ordered' | 'unordered'; + children?: React.ReactNode; + className?: string; +}; + +const List : FC<ListProps> = ({ style, className, variant, children, ...props }) => { + + const systemStyle = getSystemStyle(props, style); + + const Tag = { + 'ordered': 'ol', + 'unordered': 'ul' + }[variant] as keyof React.ReactHTML; + + const styleClass = 'md-' + Tag; + + return ( + <Tag + className={clsx(styleClass, 'md-list', className)} + children={children} + style={systemStyle} + /> + ); +}; + +interface ListItemProps extends SystemProps { + style?: React.CSSProperties; + children?: React.ReactNode; + className?: string; +}; + +const ListItem : FC<ListItemProps> = ({ style, className, children, ...props }) => { + const systemStyle = getSystemStyle(props, style); + + return ( + <li + className={clsx('md-li', className)} + style={systemStyle} + >{children}</li> + ); +} + +export { + List, + ListItem +}; diff --git a/components/List/list.module.scss b/components/List/list.module.scss new file mode 100644 index 0000000..87ec3a3 --- /dev/null +++ b/components/List/list.module.scss @@ -0,0 +1,41 @@ +.list-li { + font-size: 1rem; + letter-spacing: 0.00938em; + + line-height: 1.4; + margin-left: 1em; + + list-style-image: none; + list-style-position: inside; + list-style-type: none; + + box-sizing: border-box; + + font-size: 1rem; +} + +.list-unordered li:not(:first-child) { + margin-top: 0.15rem; +} + +.list { + .list li:first-child { + margin-top: 0.15rem !important; + } +} + +.list-unordered li { + list-style-type: disc; +} + +.list .list-unordered li { + list-style-type: circle; +} + +.list .list .list-unordered li { + list-style-type: square; +} + +.list-ordered li { + list-style-type: decimal; +} diff --git a/components/Markdown/index.tsx b/components/Markdown/index.tsx index 1a71330..b6def4f 100644 --- a/components/Markdown/index.tsx +++ b/components/Markdown/index.tsx @@ -1,24 +1,24 @@ import React, { FC } from 'react'; -import styles from './markdown.module.scss'; + import clsx from 'clsx'; interface MarkdownProps { md: string; className?: string; - props?: object; } -const Markdown : FC<MarkdownProps> = ({md, className, ...props}) => ( - <div - className={clsx(styles.markdownContainer, className)} +const Markdown : FC<MarkdownProps> = ({md, className}) => { + const prerendered = ( + <div dangerouslySetInnerHTML={{ __html: md }} - - {...props} /> -); + ); + + return prerendered; +}; export type { MarkdownProps diff --git a/components/Markdown/markdown.module.scss b/components/Markdown/markdown.module.scss deleted file mode 100644 index e1debd1..0000000 --- a/components/Markdown/markdown.module.scss +++ /dev/null @@ -1,111 +0,0 @@ -.markdownContainer { - strong { - font-weight: 600; - } - - h1 { - font-size: 2.8rem; - font-weight: 300; - line-height: 1.167; - letter-spacing: -0.01562em; - margin-top: 1.0rem; - margin-bottom: 1rem; - - padding-bottom: 0.4rem; - border-bottom: 0.12rem solid rgb(53, 53, 53); - } - - h2 { - font-size: 2.3rem; - font-weight: 300; - line-height: 1.2; - letter-spacing: -0.00833em; - - margin-top: 1.6rem; - margin-bottom: 0.8rem; - } - - h3 { - font-size: 1.3rem; - font-weight: 400; - line-height: 1.167; - letter-spacing: 0em; - - margin-top: 1.3rem; - margin-bottom: 0.5rem; - } - - h4 { - font-size: 1.25rem; - } - - h5 { - font-size: 1.15rem; - } - - h6 { - font-size: 1.10rem; - } - - h4, h5, h6 { - margin-top: 0.8rem; - margin-bottom: 0.6rem; - } - - p, li { - font-size: 1rem; - letter-spacing: 0.00938em; - font-weight: 300; - } - - p { - font-size: 1rem; - line-height: 1.5; - margin-bottom: 1em; - } - - code { - font-size: 1rem; - line-height: 1.5; - padding: 0.05rem 0.2rem; - } - - pre { - padding: 0.5rem 1.0rem; - margin: 0.5rem 0; - box-sizing: border-box; - } - pre > code { - padding: 0; - } - - code, pre { - background-color: #f2f4f7; - border-radius: 5px; - } - - pre { - overflow: auto; - box-sizing: border-box; - } - - @media screen and (max-width: 700px) { - pre { - padding-bottom: 0.7rem; - } - } - - li { - line-height: 1.15; - margin-left: 1em; - margin-top: 0.3em; - list-style-image: none; - list-style-position: outside; - list-style-type: circle; - } - - img { - max-width: 95%; - margin: 2em 2.5%; - } -} diff --git a/components/Markdown/markdown.scss b/components/Markdown/markdown.scss new file mode 100644 index 0000000..e529e66 --- /dev/null +++ b/components/Markdown/markdown.scss @@ -0,0 +1,418 @@ +/* AUTOMATIC MARGIN APPLIED WHEN md-dl */ + +.md-dl.md-h1, .md-dl.md-h2, .md-dl.md-h3, .md-dl.md-h4, .md-dl.md-h5, .md-dl.md-h6 { + margin-top: 20px; + margin-bottom: 14px; +} + +.md-dl.md-list, .md-dl.md-pre, .md-dl.md-p, .md-dl.md-table, .md-dl.md-blockquote { + margin-bottom: 14px; +} + +.md-dl.md-list .md-list { + margin-bottom: 0; +} + +.md-dl.md-blockquote > :last-child { + margin-bottom: 0; +} + +.md-dl.md-wrapper > :first-child { + margin-top: 0; +} + +/* LINKS */ + +.md-a { + text-decoration: none; +} + +.md-a:hover { + text-decoration: underline; +} + +.md-a, .md-a:visited, .md-a:active, .md-a:hover { + color: #0716ea; +} + +/* TEXT */ + +.md-blockquote, .md-p, .md-li { + font-size: 1rem; + letter-spacing: 0.00938em; + line-height: 1.5; +} + +.md-code { + font-size: 1rem; + line-height: 1.25; +} + +.md-strong { + font-weight: bold; +} + +.md-em { + font-style: italic; +} + +/* LISTS */ + +.md-li { + line-height: 1.25; + margin-left: 1em; + + list-style-image: none; + list-style-position: inside; + list-style-type: none; +} + +// allow wrapping with inside list-style-position elements +.md-li > p { + display: inline; +} + +.md-dl.md-li > p { + margin-bottom: 0; + + &::after { + content: ""; + display: block; + margin-bottom: 14px; + } +} + +.md-li-checkbox { + list-style-type: none !important; +} + +.md-checkbox { + margin: 0; + margin-right: 0.5em; +} + +// UP TO FOUR LEVELS OF DECORATORS + +.md-ol > li { + list-style-type: decimal; +} + +.md-ul > li { + list-style-type: disc; +} + +.md-list .md-ul > li { + list-style-type: circle; +} + +.md-list .md-list .md-ul > li { + list-style-type: square; +} + +.md-list .md-list .md-list .md-ul > li { + list-style-type: disc; +} + +// ADD SLIGHT MARGIN TO SPACE ELEMENTS EXCEPT THE FIRST + +.md-list > li:not(:first-child) { + margin-top: 0.15rem; +} + +.md-list .md-list > li:first-child { + margin-top: 0.15rem; +} + +/* HEADINGS */ + +.md-h1 { + font-size: 3rem; + font-weight: 300; + line-height: 1.167; + letter-spacing: -0.01562em; + + padding-bottom: 0.4rem; + border-bottom: 0.12rem solid rgb(53, 53, 53); +} + +.md-h2 { + font-size: 2.5rem; + font-weight: 300; + line-height: 1.2; + letter-spacing: -0.00833em; +} + +.md-h3 { + font-size: 1.4rem; + font-weight: 400; + line-height: 1.167; + letter-spacing: 0em; +} + +.md-h4 { + font-size: 1.38rem; +} + +.md-h5 { + font-size: 1.26rem; +} + +.md-h6 { + font-size: 1.2rem; +} + + +/* CODE */ + +.md-codespan { + background-color: #f2f4f7; + border-radius: 5px; + padding: 0.05rem 0.2rem; +} + +/* BLOCKQUOTE */ + +.md-blockquote { + box-sizing: border-box; + + position: relative; + padding-left: 1.2rem; + padding-top: 0.05rem; + padding-bottom: 0.05rem; + + &::before { + content: ""; + position: absolute; + left: 0; + top: 0; + bottom: 0; + width: 3px; + background-color: grey; + } +} + +/* CODE */ + +.md-pre { + background-color: #f2f4f7; + border-radius: 5px; + padding: 12px; + overflow: scroll; +} + +/* MD LINE / SEP */ + +.md-hr { + font-size: 300; +} + +/* TABLES */ + +.md-table { + width: 100%; + border-collapse: collapse; + margin: 1rem 0; +} + +.md-thead { + background-color: #f2f4f7; + font-size: 1.10rem; + + .md-th { + padding: 0.5rem 0.75rem; + text-align: left; + border-bottom: 2px solid #545454; + } +} + + +.md-tbody { + .md-tr { + &:nth-child(even) { + background-color: #f8f8f8; + } + + &:nth-child(odd) { + background-color: #ffffff; + } + } + + .md-td { + padding: 0.5rem 0.75rem; + border-bottom: 1px solid #ddd; + } +} + +/* IMAGE */ + +.md-img { + max-width: 95%; + margin: 2em 2.5%; +} + +/* DEL */ + +.md-del { } + +.markdownContainer { + /* Strong */ + + strong { + font-weight: 600; + } + + /* Headings */ + + h1 { + font-size: 2.8rem; + font-weight: 300; + line-height: 1.167; + letter-spacing: -0.01562em; + margin-top: 1.0rem; + margin-bottom: 1rem; + + padding-bottom: 0.4rem; + border-bottom: 0.12rem solid rgb(53, 53, 53); + } + + h2 { + font-size: 2.3rem; + font-weight: 300; + line-height: 1.2; + letter-spacing: -0.00833em; + + margin-top: 1.6rem; + margin-bottom: 0.8rem; + } + + h3 { + font-size: 1.3rem; + font-weight: 400; + line-height: 1.167; + letter-spacing: 0em; + + margin-top: 1.3rem; + margin-bottom: 0.5rem; + } + + h4 { + font-size: 1.25rem; + } + + h5 { + font-size: 1.15rem; + } + + h6 { + font-size: 1.10rem; + } + + h4, h5, h6 { + margin-top: 0.8rem; + margin-bottom: 0.6rem; + } + + p, li { + font-size: 1rem; + letter-spacing: 0.00938em; + } + + p { + font-size: 1rem; + line-height: 1.5; + margin-bottom: 1em; + } + + code { + font-size: 1rem; + line-height: 1.5; + padding: 0.05rem 0.2rem; + } + + pre { + padding: 0.5rem 1.0rem; + margin: 0.5rem 0; + box-sizing: border-box; + } + pre > code { + padding: 0; + } + + code, pre { + background-color: #f2f4f7; + border-radius: 5px; + } + + pre { + overflow: auto; + box-sizing: border-box; + } + + @media screen and (max-width: 700px) { + pre { + padding-bottom: 0.7rem; + } + } + + /* LISTS */ + + // li { + // font-size: 1rem; + // letter-spacing: 0.00938em; + + // line-height: 1.4; + // margin-left: 1em; + + // list-style-image: none; + // list-style-position: inside; + // list-style-type: none; + + // box-sizing: border-box; + + // font-size: 1rem; + // } + + // ul, ol { + // li:not(:first-child) { + // margin-top: 0.15rem; + // } + // } + + // ul ol li, ol li { + // list-style-type: decimal; + // } + + // ul li { + // list-style-type: disc; + // } + + // ul, ol { + // ul li:first-child, ol li:first-child { + // margin-top: 0.15rem !important; + // } + + // ul li { + // list-style-type: circle; + // } + + // ul, ol { + // ul li { + // list-style-type: square; + // } + // } + // } + + // li { + // line-height: 1.15; + // margin-left: 1em; + // margin-bottom: 0.3em; + // list-style-image: none; + // list-style-position: outside; + // list-style-type: circle; + // } + + img { + max-width: 95%; + margin: 2em 2.5%; + } +} diff --git a/components/PathCrumbs/index.tsx b/components/PathCrumbs/index.tsx index 1c87344..41875ec 100644 --- a/components/PathCrumbs/index.tsx +++ b/components/PathCrumbs/index.tsx @@ -34,12 +34,13 @@ const urlPathComponentsToFullPath = (urlPathComponents : string[]): string[] => }; export type PathCrumbsProps = { - path: string + path: string; + style?: React.CSSProperties; }; import { BreadCrumbs , LinkCrumb } from '../../components/BreadCrumbs'; -const PathCrumbs: FC<PathCrumbsProps> = ({ path }) => { +const PathCrumbs: FC<PathCrumbsProps> = ({ path, style }) => { const pathComponents = urlPathComponents(path); const fullPaths = urlPathComponentsToFullPath(pathComponents); @@ -51,7 +52,7 @@ const PathCrumbs: FC<PathCrumbsProps> = ({ path }) => { )); return ( - <BreadCrumbs> + <BreadCrumbs style={style}> {linksComponents} </BreadCrumbs> ); diff --git a/components/Typography/index.tsx b/components/Typ/index.tsx index b9babc0..43d7673 100644 --- a/components/Typography/index.tsx +++ b/components/Typ/index.tsx @@ -6,7 +6,7 @@ import clsx from 'clsx'; type Variant = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'body'; type Align = 'inherit' | 'left' | 'center' | 'right'; -interface TypographyProps extends React.HTMLAttributes<HTMLElement> { +interface TypProps extends React.HTMLAttributes<HTMLElement> { variant?: Variant; align?: Align; gutter?: boolean; @@ -22,7 +22,7 @@ const variantTagMap: Record<Variant, keyof JSX.IntrinsicElements> = { body: 'p' }; -const Typography: React.FC<TypographyProps> = ({ +const Typ: React.FC<TypProps> = ({ variant = 'body', align = 'inherit', gutter = false, @@ -32,7 +32,7 @@ const Typography: React.FC<TypographyProps> = ({ const Tag = variantTagMap[variant] as keyof React.ReactHTML; const typographyClassName = clsx( - styles[`typo-${variant}`], + `md-${variantTagMap[variant]}`, { [`align-${align}`]: align !== 'inherit', [styles['typo-gutter']]: gutter @@ -43,5 +43,5 @@ const Typography: React.FC<TypographyProps> = ({ return <Tag className={typographyClassName} {...props} />; }; -export default Typography; +export default Typ; diff --git a/components/Typ/typo.module.scss b/components/Typ/typo.module.scss new file mode 100644 index 0000000..48a5b10 --- /dev/null +++ b/components/Typ/typo.module.scss @@ -0,0 +1,3 @@ +.typo-gutter { + margin-bottom: 0.35em; +} diff --git a/components/Typography/typo.module.scss b/components/Typography/typo.module.scss deleted file mode 100644 index 934333d..0000000 --- a/components/Typography/typo.module.scss +++ /dev/null @@ -1,64 +0,0 @@ -.typo-h1 { - font-size: 2.8rem; - font-weight: 300; - line-height: 1.167; - letter-spacing: -0.01562em; - // margin-top: 1.0rem; - // margin-bottom: 1rem; - - padding-bottom: 0.4rem; - border-bottom: 0.12rem solid rgb(53, 53, 53); -} - -.typo-h2 { - font-size: 2.3rem; - font-weight: 300; - line-height: 1.2; - letter-spacing: -0.00833em; - - // margin-top: 1.6rem; - // margin-bottom: 0.8rem; -} - -.typo-h3 { - font-size: 1.3rem; - font-weight: 400; - line-height: 1.167; - letter-spacing: 0em; - - // margin-top: 1.3rem; - // margin-bottom: 0.5rem; -} - -.typo-h4 { - font-size: 1.25rem; -} - -.typo-h5 { - font-size: 1.15rem; -} - -.typo-h6 { - font-size: 1.10rem; -} - -.typo-h4, .typo-h5, .typo-h6 { - // margin-top: 0.8rem; - // margin-bottom: 0.6rem; -} - -.typo-p { - font-size: 1rem; - letter-spacing: 0.00938em; - font-weight: 300; -} - -.typo-p { - font-size: 1rem; - line-height: 1.5; - // margin-bottom: 1em; -} - -.typo-gutter { - margin-bottom: 0.35em; -} diff --git a/components/ViewPort/index.tsx b/components/ViewPort/index.tsx index 29191a1..08b4c7e 100644 --- a/components/ViewPort/index.tsx +++ b/components/ViewPort/index.tsx @@ -1,24 +1,29 @@ import React, { FC } from "react" import styles from './index.module.scss'; +import { getSystemStyle, SystemProps } from '../utils/systemProps'; import clsx from 'clsx'; -export type Props = { - size?: "sm" | "md" | "lg"; - className?: string; - children?: React.ReactNode; +interface Props extends SystemProps { + size?: "sm" | "md" | "lg"; + className?: string; + children?: React.ReactNode; + style?: React.CSSProperties; }; -const Viewport : FC<Props> = ({children, className, size}) => { - const _size : string = size || "md"; - const sizeClass : string = styles['viewport-' + _size]; +const Viewport : FC<Props> = ({children, className, style, size, ...systemProps}) => { + style = getSystemStyle(systemProps, style); - return ( - <div - className={clsx(sizeClass, className)} - > - {children} - </div> - ) + const _size : string = size || "md"; + const sizeClass : string = styles['viewport-' + _size]; + + return ( + <div + className={clsx(sizeClass, className)} + style={style} + > + {children} + </div> + ) }; export default Viewport; |