mirror of
https://github.com/kremalicious/blog.git
synced 2024-12-22 17:23:50 +01:00
refactor
This commit is contained in:
parent
c35e26ea14
commit
273adeecb4
32669
package-lock.json
generated
32669
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
13
package.json
13
package.json
@ -54,7 +54,8 @@
|
||||
"gatsby-plugin-sharp": "^3.0.1",
|
||||
"gatsby-plugin-sitemap": "^3.0.0",
|
||||
"gatsby-plugin-svgr": "^3.0.0-beta.0",
|
||||
"gatsby-plugin-webpack-size": "^1.0.0",
|
||||
"gatsby-plugin-webpack-bundle-analyser-v2": "^1.1.21",
|
||||
"gatsby-plugin-webpack-size": "^2.0.1",
|
||||
"gatsby-redirect-from": "^0.3.0",
|
||||
"gatsby-remark-autolink-headers": "^3.0.0",
|
||||
"gatsby-remark-breaks": "^1.0.0",
|
||||
@ -99,7 +100,7 @@
|
||||
"@types/shortid": "^0.0.29",
|
||||
"@typescript-eslint/eslint-plugin": "^4.17.0",
|
||||
"@typescript-eslint/parser": "^4.17.0",
|
||||
"@welldone-software/why-did-you-render": "^6.1.0",
|
||||
"@welldone-software/why-did-you-render": "^6.1.1",
|
||||
"eslint": "^7.22.0",
|
||||
"eslint-config-prettier": "^8.1.0",
|
||||
"eslint-plugin-graphql": "^4.0.0",
|
||||
@ -108,10 +109,9 @@
|
||||
"eslint-plugin-react": "^7.22.0",
|
||||
"eslint-plugin-testing-library": "^3.10.1",
|
||||
"fs-extra": "^9.1.0",
|
||||
"gatsby-plugin-webpack-bundle-analyser-v2": "^1.1.21",
|
||||
"identity-obj-proxy": "^3.0.0",
|
||||
"jest": "^26.6.3",
|
||||
"markdownlint-cli": "^0.26.0",
|
||||
"markdownlint-cli": "^0.27.1",
|
||||
"node-iptc": "^1.0.5",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"ora": "^5.3.0",
|
||||
@ -121,10 +121,11 @@
|
||||
"stylelint": "^13.12.0",
|
||||
"stylelint-config-css-modules": "^2.2.0",
|
||||
"stylelint-config-prettier": "^8.0.2",
|
||||
"stylelint-config-standard": "^20.0.0",
|
||||
"stylelint-config-standard": "^21.0.0",
|
||||
"stylelint-prettier": "^1.2.0",
|
||||
"ts-node": "^9.1.1",
|
||||
"typescript": "^4.2.3"
|
||||
"typescript": "^4.2.3",
|
||||
"typescript-plugin-css-modules": "^3.2.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -2,7 +2,7 @@ import React, { ReactElement } from 'react'
|
||||
import Typekit from './atoms/Typekit'
|
||||
import Header from './organisms/Header'
|
||||
import Footer from './organisms/Footer'
|
||||
import * as styles from './Layout.module.css'
|
||||
import { document, content } from './Layout.module.css'
|
||||
|
||||
// if (process.env.NODE_ENV !== 'production') {
|
||||
// // eslint-disable-next-line
|
||||
@ -16,8 +16,8 @@ export default function Layout({ children }: { children: any }): ReactElement {
|
||||
<Typekit />
|
||||
<Header />
|
||||
|
||||
<main className={styles.document} id="document">
|
||||
<div className={styles.content}>{children}</div>
|
||||
<main className={document} id="document">
|
||||
<div className={content}>{children}</div>
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
|
@ -2,7 +2,7 @@ import React, { ReactElement } from 'react'
|
||||
import { graphql, useStaticQuery } from 'gatsby'
|
||||
import remark from 'remark'
|
||||
import remarkReact from 'remark-react'
|
||||
import * as styles from './Changelog.module.css'
|
||||
import { title, content, source } from './Changelog.module.css'
|
||||
import { GitHub, GitHubRepo } from '../../@types/GitHub'
|
||||
|
||||
export function PureChangelog({
|
||||
@ -30,20 +30,20 @@ export function PureChangelog({
|
||||
const filePathDisplay = `${owner.login}/${repo}:CHANGELOG.md`
|
||||
|
||||
return (
|
||||
<div className={styles.changelog}>
|
||||
<h2 className={styles.title} id="changelog">
|
||||
<>
|
||||
<h2 className={title} id="changelog">
|
||||
Changelog
|
||||
</h2>
|
||||
<div className={styles.content}>
|
||||
<div className={content}>
|
||||
{changelogHtml}
|
||||
<p className={styles.source}>
|
||||
<p className={source}>
|
||||
sourced from{' '}
|
||||
<a href={filePathUrl}>
|
||||
<code>{filePathDisplay}</code>
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -6,5 +6,6 @@
|
||||
}
|
||||
|
||||
.wide {
|
||||
composes: container;
|
||||
max-width: none;
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
import React, { ReactElement } from 'react'
|
||||
import loadable from '@loadable/component'
|
||||
import * as styles from './Copy.module.css'
|
||||
import { copied, button } from './Copy.module.css'
|
||||
import Icon from './Icon'
|
||||
|
||||
const Clipboard = loadable(() => import('react-clipboard.js'))
|
||||
|
||||
const onCopySuccess = (e: any) => {
|
||||
e.trigger.classList.add(styles.copied)
|
||||
e.trigger.classList.add(copied)
|
||||
}
|
||||
|
||||
export default function Copy({ text }: { text: string }): ReactElement {
|
||||
@ -15,7 +15,7 @@ export default function Copy({ text }: { text: string }): ReactElement {
|
||||
data-clipboard-text={text}
|
||||
button-title="Copy to clipboard"
|
||||
onSuccess={(e: ClipboardJS.Event) => onCopySuccess(e)}
|
||||
className={styles.button}
|
||||
className={button}
|
||||
>
|
||||
<Icon name="Copy" />
|
||||
</Clipboard>
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { ReactElement } from 'react'
|
||||
import ExifMap from './ExifMap'
|
||||
import * as styles from './Exif.module.css'
|
||||
import { exif as styleExif, data, map } from './Exif.module.css'
|
||||
import { Exif as ExifMeta } from '../../@types/Image'
|
||||
import Icon from './Icon'
|
||||
|
||||
@ -31,8 +31,8 @@ export default function Exif({ exif }: { exif: ExifMeta }): ReactElement {
|
||||
} = exif.formatted
|
||||
|
||||
return (
|
||||
<aside className={styles.exif}>
|
||||
<div className={styles.data}>
|
||||
<aside className={styleExif}>
|
||||
<div className={data}>
|
||||
{model && <ExifData title="Camera model" value={model} icon="Camera" />}
|
||||
{focalLength && (
|
||||
<ExifData title="Focal length" value={focalLength} icon="Crosshair" />
|
||||
@ -49,7 +49,7 @@ export default function Exif({ exif }: { exif: ExifMeta }): ReactElement {
|
||||
{iso && <ExifData title="ISO" value={iso} icon="Maximize" />}
|
||||
</div>
|
||||
{gps && gps.latitude && (
|
||||
<div className={styles.map}>
|
||||
<div className={map}>
|
||||
<ExifMap gps={gps} />
|
||||
</div>
|
||||
)}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { ReactElement } from 'react'
|
||||
import * as styles from './Hamburger.module.css'
|
||||
import { button, hamburger, line } from './Hamburger.module.css'
|
||||
|
||||
export default function Hamburger({
|
||||
onClick
|
||||
@ -7,16 +7,11 @@ export default function Hamburger({
|
||||
onClick(): void
|
||||
}): ReactElement {
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
title="Menu"
|
||||
className={styles.button}
|
||||
onClick={onClick}
|
||||
>
|
||||
<span className={styles.hamburger}>
|
||||
<span className={styles.line} />
|
||||
<span className={styles.line} />
|
||||
<span className={styles.line} />
|
||||
<button type="button" title="Menu" className={button} onClick={onClick}>
|
||||
<span className={hamburger}>
|
||||
<span className={line} />
|
||||
<span className={line} />
|
||||
<span className={line} />
|
||||
</span>
|
||||
</button>
|
||||
)
|
||||
|
@ -27,7 +27,7 @@ import {
|
||||
import { ReactComponent as Jsonfeed } from '../../images/jsonfeed.svg'
|
||||
import { ReactComponent as Bitcoin } from '../../images/bitcoin.svg'
|
||||
import { ReactComponent as Stopwatch } from '../../images/stopwatch.svg'
|
||||
import * as styles from './Icon.module.css'
|
||||
import { icon } from './Icon.module.css'
|
||||
|
||||
const components: any = {
|
||||
Download: ArrowDownCircle,
|
||||
@ -55,12 +55,12 @@ const components: any = {
|
||||
Crosshair
|
||||
}
|
||||
|
||||
const Icon = ({ name }: { name: string }): ReactElement => {
|
||||
const Icon = ({ name, ...props }: { name: string }): ReactElement => {
|
||||
const IconMapped = components[name]
|
||||
// const IconFeather = (Feather as any)[name]
|
||||
if (!IconMapped) return null
|
||||
|
||||
return <IconMapped className={styles.icon} />
|
||||
return <IconMapped className={icon} {...props} />
|
||||
}
|
||||
|
||||
export default Icon
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { ReactElement } from 'react'
|
||||
import * as styles from './Input.module.css'
|
||||
import { input } from './Input.module.css'
|
||||
|
||||
export default function Input({ className, ...props }: any): ReactElement {
|
||||
return <input className={`${styles.input} ${className || ''}`} {...props} />
|
||||
return <input className={`${input} ${className || ''}`} {...props} />
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { ReactElement } from 'react'
|
||||
import { QRCode } from 'react-qr-svg'
|
||||
import * as styles from './Qr.module.css'
|
||||
import { qr, code } from './Qr.module.css'
|
||||
import Copy from './Copy'
|
||||
|
||||
export default function Qr({
|
||||
@ -19,10 +19,10 @@ export default function Qr({
|
||||
level="Q"
|
||||
style={{ width: 120 }}
|
||||
value={address}
|
||||
className={styles.qr}
|
||||
className={qr}
|
||||
/>
|
||||
|
||||
<pre className={styles.code}>
|
||||
<pre className={code}>
|
||||
<code>{address}</code>
|
||||
<Copy text={address} />
|
||||
</pre>
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { ReactElement } from 'react'
|
||||
import { Link } from 'gatsby'
|
||||
import * as styles from './Tag.module.css'
|
||||
import { tag, count as styleCount } from './Tag.module.css'
|
||||
|
||||
export default function Tag({
|
||||
name,
|
||||
@ -14,9 +14,9 @@ export default function Tag({
|
||||
style?: any
|
||||
}): ReactElement {
|
||||
return (
|
||||
<Link className={styles.tag} to={url} style={style}>
|
||||
<Link className={tag} to={url} style={style}>
|
||||
{name}
|
||||
{count && <span className={styles.count}>{count}</span>}
|
||||
{count && <span className={styleCount}>{count}</span>}
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ import React, { ReactElement, useState } from 'react'
|
||||
import { Helmet } from 'react-helmet'
|
||||
import { Link } from 'gatsby'
|
||||
import Hamburger from '../atoms/Hamburger'
|
||||
import * as styles from './Menu.module.css'
|
||||
import { menu as styleMenu } from './Menu.module.css'
|
||||
import { useSiteMetadata } from '../../hooks/use-site-metadata'
|
||||
import { MenuItem } from '../../@types/Site'
|
||||
|
||||
@ -28,7 +28,7 @@ export default function Menu(): ReactElement {
|
||||
<html className={menuOpen ? 'has-menu-open' : undefined} lang="en" />
|
||||
</Helmet>
|
||||
<Hamburger onClick={toggleMenu} />
|
||||
<nav className={styles.menu}>
|
||||
<nav className={styleMenu}>
|
||||
<ul>{MenuItems}</ul>
|
||||
</nav>
|
||||
</>
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { ReactElement } from 'react'
|
||||
import Icon from '../atoms/Icon'
|
||||
import * as styles from './Networks.module.css'
|
||||
import { link as styleLink } from './Networks.module.css'
|
||||
|
||||
function NetworkIcon({ link }: { link: string }) {
|
||||
let IconComp
|
||||
@ -28,7 +28,7 @@ export default function IconLinks({
|
||||
return (
|
||||
<p>
|
||||
{links.map((link: string) => (
|
||||
<a key={link} className={styles.link} href={link} title={link}>
|
||||
<a key={link} className={styleLink} href={link} title={link}>
|
||||
<NetworkIcon link={link} />
|
||||
</a>
|
||||
))}
|
||||
|
@ -1,9 +1,13 @@
|
||||
import React, { ReactElement } from 'react'
|
||||
import { Link } from 'gatsby'
|
||||
import * as styles from './Pagination.module.css'
|
||||
import shortid from 'shortid'
|
||||
import { PageContext } from '../../@types/Post'
|
||||
import Icon from '../atoms/Icon'
|
||||
import {
|
||||
current as styleCurrent,
|
||||
number,
|
||||
pagination
|
||||
} from './Pagination.module.css'
|
||||
|
||||
const PageNumber = ({
|
||||
i,
|
||||
@ -14,7 +18,7 @@ const PageNumber = ({
|
||||
slug: string
|
||||
current?: boolean
|
||||
}) => {
|
||||
const classes = current ? styles.current : styles.number
|
||||
const classes = current ? styleCurrent : number
|
||||
const link = i === 0 ? slug : `${slug}page/${i + 1}`
|
||||
|
||||
return (
|
||||
@ -62,7 +66,7 @@ export default function Pagination({
|
||||
const isLast = currentPageNumber === numPages
|
||||
|
||||
return (
|
||||
<div className={styles.pagination}>
|
||||
<div className={pagination}>
|
||||
{!isFirst && <PrevNext prevPagePath={prevPagePath} />}
|
||||
{Array.from({ length: numPages }, (_, i) => (
|
||||
<PageNumber
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { ReactElement } from 'react'
|
||||
import Time from '../atoms/Time'
|
||||
import * as styles from './PostDate.module.css'
|
||||
import { time } from './PostDate.module.css'
|
||||
|
||||
export default function PostDate({
|
||||
date,
|
||||
@ -10,7 +10,7 @@ export default function PostDate({
|
||||
updated?: string
|
||||
}): ReactElement {
|
||||
return (
|
||||
<div className={styles.time}>
|
||||
<div className={time}>
|
||||
<Time date={date} />
|
||||
{updated && ' • updated '}
|
||||
{updated && <Time date={updated} />}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { ReactElement, useState } from 'react'
|
||||
import { graphql, useStaticQuery } from 'gatsby'
|
||||
import PostTeaser from './PostTeaser'
|
||||
import * as styles from './RelatedPosts.module.css'
|
||||
import { relatedPosts, title, button } from './RelatedPosts.module.css'
|
||||
import { Post, Frontmatter } from '../../@types/Post'
|
||||
import { PhotoThumb } from '../templates/Photos'
|
||||
|
||||
@ -78,10 +78,10 @@ export default function RelatedPosts({
|
||||
}
|
||||
|
||||
return (
|
||||
<aside className={styles.relatedPosts}>
|
||||
<h1 className={styles.title}>
|
||||
<aside className={relatedPosts}>
|
||||
<h1 className={title}>
|
||||
Related {isPhotos ? 'Photos' : 'Posts'}{' '}
|
||||
<button className={styles.button} onClick={() => refreshPosts()}>
|
||||
<button className={button} onClick={() => refreshPosts()}>
|
||||
Refresh
|
||||
</button>
|
||||
</h1>
|
||||
|
@ -1,14 +1,9 @@
|
||||
import React, { ReactElement } from 'react'
|
||||
import * as styles from './SearchButton.module.css'
|
||||
import { searchButton } from './SearchButton.module.css'
|
||||
import Icon from '../../atoms/Icon'
|
||||
|
||||
const SearchButton = (props: any): ReactElement => (
|
||||
<button
|
||||
type="button"
|
||||
title="Search"
|
||||
className={styles.searchButton}
|
||||
{...props}
|
||||
>
|
||||
<button type="button" title="Search" className={searchButton} {...props}>
|
||||
<Icon name="Search" />
|
||||
</button>
|
||||
)
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { ReactElement } from 'react'
|
||||
import Input from '../../atoms/Input'
|
||||
import Icon from '../../atoms/Icon'
|
||||
import * as styles from './SearchInput.module.css'
|
||||
import { searchInput, searchInputClose } from './SearchInput.module.css'
|
||||
|
||||
export default function SearchInput({
|
||||
value,
|
||||
@ -15,7 +15,7 @@ export default function SearchInput({
|
||||
return (
|
||||
<>
|
||||
<Input
|
||||
className={styles.searchInput}
|
||||
className={searchInput}
|
||||
type="search"
|
||||
placeholder="Search everything"
|
||||
autoFocus // eslint-disable-line
|
||||
@ -23,7 +23,7 @@ export default function SearchInput({
|
||||
onChange={onChange}
|
||||
/>
|
||||
<button
|
||||
className={styles.searchInputClose}
|
||||
className={searchInputClose}
|
||||
onClick={onToggle}
|
||||
title="Close search"
|
||||
>
|
||||
|
@ -1,5 +1,9 @@
|
||||
import React, { ReactElement } from 'react'
|
||||
import * as styles from './SearchResultsEmpty.module.css'
|
||||
import {
|
||||
empty,
|
||||
emptyMessage,
|
||||
emptyMessageText
|
||||
} from './SearchResultsEmpty.module.css'
|
||||
import { Results } from './SearchResults'
|
||||
|
||||
const SearchResultsEmpty = ({
|
||||
@ -9,9 +13,9 @@ const SearchResultsEmpty = ({
|
||||
searchQuery: string
|
||||
results: Results[]
|
||||
}): ReactElement => (
|
||||
<div className={styles.empty}>
|
||||
<header className={styles.emptyMessage}>
|
||||
<p className={styles.emptyMessageText}>
|
||||
<div className={empty}>
|
||||
<header className={emptyMessage}>
|
||||
<p className={emptyMessageText}>
|
||||
{searchQuery.length > 0 && results.length === 0
|
||||
? 'No results found'
|
||||
: 'Awaiting your input'}
|
||||
|
@ -2,7 +2,7 @@ import React, { ReactElement } from 'react'
|
||||
import { graphql, useStaticQuery } from 'gatsby'
|
||||
import { getSrc } from 'gatsby-plugin-image'
|
||||
import IconLinks from './Networks'
|
||||
import * as styles from './Vcard.module.css'
|
||||
import { avatar as styleAvatar, description } from './Vcard.module.css'
|
||||
import { useSiteMetadata } from '../../hooks/use-site-metadata'
|
||||
|
||||
const query = graphql`
|
||||
@ -34,13 +34,13 @@ export default function Vcard(): ReactElement {
|
||||
return (
|
||||
<>
|
||||
<img
|
||||
className={styles.avatar}
|
||||
className={styleAvatar}
|
||||
src={avatar}
|
||||
width="80"
|
||||
height="80"
|
||||
alt="avatar"
|
||||
/>
|
||||
<p className={styles.description}>
|
||||
<p className={description}>
|
||||
Blog of designer & developer{' '}
|
||||
<a className="fn" rel="author" href={uri}>
|
||||
{name}
|
||||
|
@ -2,7 +2,11 @@ import React, { ReactElement, useState, useEffect } from 'react'
|
||||
import { toDataUrl } from 'ethereum-blockies'
|
||||
import { formatEther } from '@ethersproject/units'
|
||||
import useWeb3 from '../../../hooks/use-web3'
|
||||
import * as styles from './Account.module.css'
|
||||
import {
|
||||
accountWrap,
|
||||
blockies as styleBlockies,
|
||||
balance
|
||||
} from './Account.module.css'
|
||||
|
||||
export default function Account(): ReactElement {
|
||||
const { library, account } = useWeb3()
|
||||
@ -26,12 +30,12 @@ export default function Account(): ReactElement {
|
||||
ethBalance && `Ξ${parseFloat(formatEther(ethBalance)).toPrecision(4)}`
|
||||
|
||||
return (
|
||||
<div className={styles.accountWrap} title={account}>
|
||||
<span className={styles.account}>
|
||||
<img className={styles.blockies} src={blockies} alt="Blockies" />
|
||||
<div className={accountWrap} title={account}>
|
||||
<span>
|
||||
<img className={styleBlockies} src={blockies} alt="Blockies" />
|
||||
{accountDisplay}
|
||||
</span>
|
||||
<span className={styles.balance}>{balanceDisplay}</span>
|
||||
<span className={balance}>{balanceDisplay}</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { ReactElement } from 'react'
|
||||
import * as styles from './Alert.module.css'
|
||||
import { success, error, alert } from './Alert.module.css'
|
||||
|
||||
export function getTransactionMessage(
|
||||
transactionHash?: string
|
||||
@ -24,11 +24,7 @@ const constructMessage = (
|
||||
: message && message.text
|
||||
|
||||
const classes = (status: string) =>
|
||||
status === 'success'
|
||||
? styles.success
|
||||
: status === 'error'
|
||||
? styles.error
|
||||
: styles.alert
|
||||
status === 'success' ? success : status === 'error' ? error : alert
|
||||
|
||||
export default function Alert({
|
||||
transactionHash,
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { useState, useEffect, ReactElement } from 'react'
|
||||
import fetch from 'node-fetch'
|
||||
import * as styles from './Conversion.module.css'
|
||||
import { conversion as styleConversion } from './Conversion.module.css'
|
||||
|
||||
export async function getFiat(
|
||||
amount: number
|
||||
@ -43,7 +43,7 @@ export default function Conversion({
|
||||
}, [amount])
|
||||
|
||||
return (
|
||||
<div className={styles.conversion}>
|
||||
<div className={styleConversion}>
|
||||
<span>{dollar !== '0.00' && `= $ ${dollar}`}</span>
|
||||
<span>{euro !== '0.00' && `= € ${euro}`}</span>
|
||||
</div>
|
||||
|
@ -2,7 +2,7 @@ import React, { ReactElement, useState } from 'react'
|
||||
import Input from '../../atoms/Input'
|
||||
import Account from './Account'
|
||||
import Conversion from './Conversion'
|
||||
import * as styles from './InputGroup.module.css'
|
||||
import { inputGroup, input, currency } from './InputGroup.module.css'
|
||||
|
||||
export default function InputGroup({
|
||||
sendTransaction
|
||||
@ -18,8 +18,8 @@ export default function InputGroup({
|
||||
return (
|
||||
<div>
|
||||
<Account />
|
||||
<div className={styles.inputGroup}>
|
||||
<div className={styles.input}>
|
||||
<div className={inputGroup}>
|
||||
<div className={input}>
|
||||
<Input
|
||||
type="number"
|
||||
value={amount}
|
||||
@ -27,7 +27,7 @@ export default function InputGroup({
|
||||
min="0"
|
||||
step="0.01"
|
||||
/>
|
||||
<div className={styles.currency}>
|
||||
<div className={currency}>
|
||||
<span>ETH</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -3,7 +3,7 @@ import { parseEther } from '@ethersproject/units'
|
||||
import useWeb3, { connectors, getErrorMessage } from '../../../hooks/use-web3'
|
||||
import InputGroup from './InputGroup'
|
||||
import Alert, { getTransactionMessage } from './Alert'
|
||||
import * as styles from './index.module.css'
|
||||
import { web3 } from './index.module.css'
|
||||
|
||||
export default function Web3Donation({
|
||||
address
|
||||
@ -67,7 +67,7 @@ export default function Web3Donation({
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.web3}>
|
||||
<div className={web3}>
|
||||
{!active && !message ? (
|
||||
<button className="link" onClick={() => activate(connectors.MetaMask)}>
|
||||
Activate Web3
|
||||
|
@ -3,14 +3,14 @@ import { Link } from 'gatsby'
|
||||
import Icon from '../atoms/Icon'
|
||||
import Vcard from '../molecules/Vcard'
|
||||
import { useSiteMetadata } from '../../hooks/use-site-metadata'
|
||||
import * as styles from './Footer.module.css'
|
||||
import { copyright, btc, footer } from './Footer.module.css'
|
||||
|
||||
function Copyright() {
|
||||
const { name, uri, github } = useSiteMetadata().author
|
||||
const year = new Date().getFullYear()
|
||||
|
||||
return (
|
||||
<section className={styles.copyright}>
|
||||
<section className={copyright}>
|
||||
<p>
|
||||
© 2005–
|
||||
{year + ' '}
|
||||
@ -21,7 +21,7 @@ function Copyright() {
|
||||
<Icon name="GitHub" />
|
||||
View source
|
||||
</a>
|
||||
<Link to="/thanks" className={styles.btc}>
|
||||
<Link to="/thanks" className={btc}>
|
||||
<Icon name="Bitcoin" />
|
||||
Say Thanks
|
||||
</Link>
|
||||
@ -33,7 +33,7 @@ function Copyright() {
|
||||
export default class Footer extends PureComponent {
|
||||
render(): ReactElement {
|
||||
return (
|
||||
<footer role="contentinfo" className={styles.footer}>
|
||||
<footer role="contentinfo" className={footer}>
|
||||
<Vcard />
|
||||
<Copyright />
|
||||
</footer>
|
||||
|
@ -4,20 +4,20 @@ import Search from '../molecules/Search'
|
||||
import Menu from '../molecules/Menu'
|
||||
import ThemeSwitch from '../molecules/ThemeSwitch'
|
||||
import { ReactComponent as Logo } from '../../images/logo.svg'
|
||||
import * as styles from './Header.module.css'
|
||||
import { header, headerContent, title, logo, nav } from './Header.module.css'
|
||||
|
||||
export default class Header extends PureComponent {
|
||||
render(): ReactElement {
|
||||
return (
|
||||
<header role="banner" className={styles.header}>
|
||||
<div className={styles.headerContent}>
|
||||
<h1 className={styles.title}>
|
||||
<header role="banner" className={header}>
|
||||
<div className={headerContent}>
|
||||
<h1 className={title}>
|
||||
<Link to="/">
|
||||
<Logo className={styles.logo} /> kremalicious
|
||||
<Logo className={logo} /> kremalicious
|
||||
</Link>
|
||||
</h1>
|
||||
|
||||
<nav role="navigation" className={styles.nav}>
|
||||
<nav role="navigation" className={nav}>
|
||||
<ThemeSwitch />
|
||||
<Search />
|
||||
<Menu />
|
||||
|
@ -2,9 +2,9 @@ import React, { ReactElement } from 'react'
|
||||
import { graphql } from 'gatsby'
|
||||
import { Post, PageContext } from '../../@types/Post'
|
||||
import Pagination from '../molecules/Pagination'
|
||||
import * as styles from './Archive.module.css'
|
||||
import PostTeaser from '../molecules/PostTeaser'
|
||||
import Page from './Page'
|
||||
import { posts } from './Archive.module.css'
|
||||
|
||||
export default function Archive({
|
||||
data,
|
||||
@ -40,7 +40,7 @@ export default function Archive({
|
||||
post={page}
|
||||
pathname={pageContext.slug}
|
||||
>
|
||||
<div className={styles.posts}>{PostsList}</div>
|
||||
<div className={posts}>{PostsList}</div>
|
||||
{numPages > 1 && <Pagination pageContext={pageContext} />}
|
||||
</Page>
|
||||
)
|
||||
|
@ -2,7 +2,7 @@ import React, { ReactElement, ReactNode } from 'react'
|
||||
import { Helmet } from 'react-helmet'
|
||||
import { Post } from '../../@types/Post'
|
||||
import SEO from '../atoms/SEO'
|
||||
import * as styles from './Page.module.css'
|
||||
import { pagetitle } from './Page.module.css'
|
||||
|
||||
export default function Page({
|
||||
title,
|
||||
@ -22,7 +22,7 @@ export default function Page({
|
||||
<Helmet title={title} />
|
||||
<SEO slug={pathname} postSEO post={post} />
|
||||
|
||||
<h1 className={styles.pagetitle}>{title}</h1>
|
||||
<h1 className={pagetitle}>{title}</h1>
|
||||
{section ? <section className={section}>{children}</section> : children}
|
||||
</>
|
||||
)
|
||||
|
@ -1,10 +1,10 @@
|
||||
import React, { ReactElement } from 'react'
|
||||
import { graphql, Link, PageProps } from 'gatsby'
|
||||
import Page from './Page'
|
||||
import { Post, PageContext } from '../../@types/Post'
|
||||
import { Image } from '../atoms/Image'
|
||||
import { photo as stylePhoto, photos as stylePhotos } from './Photos.module.css'
|
||||
import Pagination from '../molecules/Pagination'
|
||||
import Page from './Page'
|
||||
import { photo as stylePhoto, photos as stylePhotos } from './Photos.module.css'
|
||||
|
||||
export const PhotoThumb = ({ photo }: { photo: Post }): ReactElement => {
|
||||
const { title, image } = photo.frontmatter
|
||||
|
@ -1,30 +1,22 @@
|
||||
import React, { ReactElement } from 'react'
|
||||
import { useSiteMetadata } from '../../../hooks/use-site-metadata'
|
||||
import * as styles from './Actions.module.css'
|
||||
import { action, actionTitle, actionText, actions } from './Actions.module.css'
|
||||
import Icon from '../../atoms/Icon'
|
||||
|
||||
interface ActionProps {
|
||||
title: string
|
||||
text: string
|
||||
icon: string
|
||||
url?: string
|
||||
onClick?(): void
|
||||
}
|
||||
|
||||
const IconComp = ({ text }: { text: string }) =>
|
||||
text.includes('GitHub') ? (
|
||||
<Icon name="GitHub" />
|
||||
) : text.includes('Bitcoin') ? (
|
||||
<Icon name="Bitcoin" />
|
||||
) : (
|
||||
<Icon name="Twitter" />
|
||||
)
|
||||
|
||||
const Action = ({ title, text, url, onClick }: ActionProps) => {
|
||||
const Action = ({ title, text, url, icon, onClick }: ActionProps) => {
|
||||
return (
|
||||
<a className={styles.action} href={url} onClick={onClick}>
|
||||
<IconComp text={text} />
|
||||
<h1 className={styles.actionTitle}>{title}</h1>
|
||||
<p className={styles.actionText}>{text}</p>
|
||||
<a className={action} href={url} onClick={onClick}>
|
||||
<Icon name={icon} />
|
||||
<h1 className={actionTitle}>{title}</h1>
|
||||
<p className={actionText}>{text}</p>
|
||||
</a>
|
||||
)
|
||||
}
|
||||
@ -40,21 +32,24 @@ export default function PostActions({
|
||||
const urlTwitter = `https://twitter.com/intent/tweet?text=@kremalicious&url=${siteUrl}${slug}`
|
||||
|
||||
return (
|
||||
<aside className={styles.actions}>
|
||||
<aside className={actions}>
|
||||
<Action
|
||||
title="Have a comment?"
|
||||
text="Hit me up @kremalicious"
|
||||
url={urlTwitter}
|
||||
icon="Twitter"
|
||||
/>
|
||||
<Action
|
||||
title="Found something useful?"
|
||||
text="Say thanks with BTC or ETH"
|
||||
url="/thanks"
|
||||
icon="Bitcoin"
|
||||
/>
|
||||
<Action
|
||||
title="Edit on GitHub"
|
||||
text="Contribute to this post"
|
||||
url={githubLink}
|
||||
icon="GitHub"
|
||||
/>
|
||||
</aside>
|
||||
)
|
||||
|
@ -2,7 +2,7 @@ import React, { ReactElement } from 'react'
|
||||
import Changelog from '../../atoms/Changelog'
|
||||
import { Post } from '../../../@types/Post'
|
||||
import PostToc from './Toc'
|
||||
import * as styles from './Content.module.css'
|
||||
import { content as styleContent } from './Content.module.css'
|
||||
|
||||
export default function PostContent({ post }: { post: Post }): ReactElement {
|
||||
const separator = '<!-- more -->'
|
||||
@ -27,7 +27,7 @@ export default function PostContent({ post }: { post: Post }): ReactElement {
|
||||
)}
|
||||
<div
|
||||
dangerouslySetInnerHTML={{ __html: content }}
|
||||
className={styles.content}
|
||||
className={styleContent}
|
||||
/>
|
||||
{changelog && <Changelog repo={changelog} />}
|
||||
</>
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { ReactElement } from 'react'
|
||||
import * as styles from './Lead.module.css'
|
||||
import { lead as styleLead } from './Lead.module.css'
|
||||
import { Post } from '../../../@types/Post'
|
||||
|
||||
// Extract lead paragraph from content
|
||||
@ -23,7 +23,7 @@ const PostLead = ({
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`${styles.lead} ${className && className}`}
|
||||
className={`${styleLead} ${className && className}`}
|
||||
dangerouslySetInnerHTML={{ __html: lead }}
|
||||
/>
|
||||
)
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { ReactElement } from 'react'
|
||||
import { Link } from 'gatsby'
|
||||
import stylesPostMore from './More.module.css'
|
||||
import * as styles from './LinkActions.module.css'
|
||||
import { postMore } from './More.module.css'
|
||||
import { postLinkActions } from './LinkActions.module.css'
|
||||
import Icon from '../../atoms/Icon'
|
||||
|
||||
const PostLinkActions = ({
|
||||
@ -11,8 +11,8 @@ const PostLinkActions = ({
|
||||
linkurl?: string
|
||||
slug: string
|
||||
}): ReactElement => (
|
||||
<aside className={styles.postLinkActions}>
|
||||
<a className={stylesPostMore.postMore} href={linkurl}>
|
||||
<aside className={postLinkActions}>
|
||||
<a className={postMore} href={linkurl}>
|
||||
Go to source <Icon name="ExternalLink" />
|
||||
</a>
|
||||
<Link to={slug} rel="tooltip" title="Permalink">
|
||||
|
@ -3,7 +3,13 @@ import { Link } from 'gatsby'
|
||||
import slugify from 'slugify'
|
||||
import Tag from '../../atoms/Tag'
|
||||
import { useSiteMetadata } from '../../../hooks/use-site-metadata'
|
||||
import * as styles from './Meta.module.css'
|
||||
import {
|
||||
entryMeta,
|
||||
byline,
|
||||
by,
|
||||
type as styleType,
|
||||
tags as styleTags
|
||||
} from './Meta.module.css'
|
||||
import { Post } from '../../../@types/Post'
|
||||
import shortid from 'shortid'
|
||||
import PostDate from '../../molecules/PostDate'
|
||||
@ -14,9 +20,9 @@ export default function PostMeta({ post }: { post: Post }): ReactElement {
|
||||
const { date, type } = post.fields
|
||||
|
||||
return (
|
||||
<footer className={styles.entryMeta}>
|
||||
<div className={styles.byline}>
|
||||
<span className={styles.by}>by</span>
|
||||
<footer className={entryMeta}>
|
||||
<div className={byline}>
|
||||
<span className={by}>by</span>
|
||||
<a className="fn" rel="author" href={siteMeta.author.uri}>
|
||||
{author || siteMeta.author.name}
|
||||
</a>
|
||||
@ -25,13 +31,13 @@ export default function PostMeta({ post }: { post: Post }): ReactElement {
|
||||
<PostDate date={date} updated={updated} />
|
||||
|
||||
{type && type === 'photo' && (
|
||||
<div className={styles.type}>
|
||||
<div className={styleType}>
|
||||
<Link to={`/${slugify(type)}s/`}>{type}s</Link>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{tags && (
|
||||
<div className={styles.tags}>
|
||||
<div className={styleTags}>
|
||||
{tags.map((tag: string) => {
|
||||
const url = `/archive/${slugify(tag)}/`
|
||||
return <Tag key={shortid.generate()} name={tag} url={url} />
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { ReactElement } from 'react'
|
||||
import { Link } from 'gatsby'
|
||||
import Icon from '../../atoms/Icon'
|
||||
import * as styles from './More.module.css'
|
||||
import { postMore } from './More.module.css'
|
||||
|
||||
const PostMore = ({
|
||||
to,
|
||||
@ -10,7 +10,7 @@ const PostMore = ({
|
||||
to: string
|
||||
children: string
|
||||
}): ReactElement => (
|
||||
<Link className={styles.postMore} to={to}>
|
||||
<Link className={postMore} to={to}>
|
||||
{children}
|
||||
<Icon name="ChevronRight" />
|
||||
</Link>
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { ReactElement } from 'react'
|
||||
import { Link } from 'gatsby'
|
||||
import Icon from '../../atoms/Icon'
|
||||
import * as styles from './PrevNext.module.css'
|
||||
import { prevnext, label, title } from './PrevNext.module.css'
|
||||
|
||||
interface Node {
|
||||
title: string
|
||||
@ -14,21 +14,21 @@ interface PrevNextProps {
|
||||
}
|
||||
|
||||
const PrevNext = ({ prev, next }: PrevNextProps): ReactElement => (
|
||||
<nav className={styles.prevnext}>
|
||||
<nav className={prevnext}>
|
||||
<div>
|
||||
{prev && (
|
||||
<Link to={prev.slug}>
|
||||
<Icon name="ChevronLeft" />
|
||||
<p className={styles.label}>Newer</p>
|
||||
<h3 className={styles.title}>{prev.title}</h3>
|
||||
<p className={label}>Newer</p>
|
||||
<h3 className={title}>{prev.title}</h3>
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
{next && (
|
||||
<Link to={next.slug}>
|
||||
<p className={styles.label}>Older</p>
|
||||
<h3 className={styles.title}>{next.title}</h3>
|
||||
<p className={label}>Older</p>
|
||||
<h3 className={title}>{next.title}</h3>
|
||||
<Icon name="ChevronRight" />
|
||||
</Link>
|
||||
)}
|
||||
|
@ -3,11 +3,11 @@
|
||||
margin-bottom: calc(var(--spacer) / 8);
|
||||
}
|
||||
|
||||
.title__link {
|
||||
.titleLink {
|
||||
font-size: var(--font-size-h3);
|
||||
}
|
||||
|
||||
.title__link svg {
|
||||
.titleLink svg {
|
||||
width: var(--font-size-base);
|
||||
height: var(--font-size-base);
|
||||
display: inline-block;
|
||||
|
@ -1,5 +1,9 @@
|
||||
import React, { ReactElement } from 'react'
|
||||
import * as styles from './Title.module.css'
|
||||
import {
|
||||
title as styleTitle,
|
||||
titleLink,
|
||||
linkurl as styleLinkurl
|
||||
} from './Title.module.css'
|
||||
import Icon from '../../atoms/Icon'
|
||||
import PostDate from '../../molecules/PostDate'
|
||||
|
||||
@ -20,20 +24,16 @@ export default function PostTitle({
|
||||
|
||||
return linkurl ? (
|
||||
<>
|
||||
<h1
|
||||
className={`${styles.title} ${styles.title__link} ${
|
||||
className && className
|
||||
}`}
|
||||
>
|
||||
<h1 className={`${styleTitle} ${titleLink} ${className && className}`}>
|
||||
<a href={linkurl} title={`Go to source: ${linkurl}`}>
|
||||
{title} <Icon name="ExternalLink" />
|
||||
</a>
|
||||
</h1>
|
||||
<div className={styles.linkurl}>{linkHostname}</div>
|
||||
<div className={styleLinkurl}>{linkHostname}</div>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<h1 className={`${styles.title} ${className && className}`}>{title}</h1>
|
||||
<h1 className={`${styleTitle} ${className && className}`}>{title}</h1>
|
||||
{date && <PostDate date={date} updated={updated} />}
|
||||
</>
|
||||
)
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { ReactElement } from 'react'
|
||||
import * as styles from './Toc.module.css'
|
||||
import { toc } from './Toc.module.css'
|
||||
|
||||
const PostToc = ({
|
||||
tableOfContents
|
||||
@ -8,7 +8,7 @@ const PostToc = ({
|
||||
}): ReactElement => {
|
||||
return (
|
||||
<nav
|
||||
className={styles.toc}
|
||||
className={toc}
|
||||
dangerouslySetInnerHTML={{ __html: tableOfContents }}
|
||||
/>
|
||||
)
|
||||
|
@ -12,7 +12,7 @@ import PostActions from './Actions'
|
||||
import PostLinkActions from './LinkActions'
|
||||
import PostMeta from './Meta'
|
||||
import PrevNext from './PrevNext'
|
||||
import * as styles from './index.module.css'
|
||||
import { hentry, image as styleImage } from './index.module.css'
|
||||
import { Image } from '../../atoms/Image'
|
||||
|
||||
export default function Post({
|
||||
@ -37,7 +37,7 @@ export default function Post({
|
||||
|
||||
<SEO slug={slug} post={post} postSEO />
|
||||
|
||||
<article className={styles.hentry}>
|
||||
<article className={hentry}>
|
||||
<header>
|
||||
<PostTitle
|
||||
linkurl={linkurl}
|
||||
@ -52,7 +52,7 @@ export default function Post({
|
||||
|
||||
{image && (
|
||||
<Image
|
||||
className={styles.image}
|
||||
className={styleImage}
|
||||
image={(image as any).childImageSharp.gatsbyImageData}
|
||||
alt={title}
|
||||
/>
|
||||
|
@ -1,5 +1,5 @@
|
||||
.section {
|
||||
composes: container.wide from '../components/atoms/Container.module.css';
|
||||
composes: wide from '../components/atoms/Container.module.css';
|
||||
}
|
||||
|
||||
.section:not(:first-child) {
|
||||
|
@ -10,7 +10,8 @@
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"sourceMap": true,
|
||||
"noImplicitAny": true
|
||||
"noImplicitAny": true,
|
||||
"plugins": [{ "name": "typescript-plugin-css-modules" }]
|
||||
},
|
||||
"exclude": ["node_modules", "public", ".cache", "*.js"],
|
||||
"include": ["./src/**/*", "./scripts/*.ts", "./jest/**/*"]
|
||||
|
Loading…
Reference in New Issue
Block a user