refactor(starter): upgrade and move to typescript

This commit is contained in:
Alexander Shelepenok 2022-04-16 14:25:55 +00:00
parent 67ebabbaac
commit 50a99f57f7
156 changed files with 5350 additions and 7173 deletions

View File

@ -12,12 +12,12 @@ jobs:
- checkout
- restore_cache:
keys:
- dependencies-{{ checksum "yarn.lock" }}
- run: yarn install --frozen-lockfile
- dependencies-{{ checksum "package-lock.json" }}
- run: npm ci
- save_cache:
paths:
- node_modules
key: dependencies-{{ checksum "yarn.lock" }}
key: dependencies-{{ checksum "package-lock.json" }}
lint:
<<: *defaults
@ -25,8 +25,8 @@ jobs:
- checkout
- restore_cache:
keys:
- dependencies-{{ checksum "yarn.lock" }}
- run: yarn lint
- dependencies-{{ checksum "package-lock.json" }}
- run: npm run lint
test:
<<: *defaults
@ -34,8 +34,8 @@ jobs:
- checkout
- restore_cache:
keys:
- dependencies-{{ checksum "yarn.lock" }}
- run: yarn test --runInBand --no-cache
- dependencies-{{ checksum "package-lock.json" }}
- run: npm run test --runInBand --no-cache
coverage:
<<: *defaults
@ -43,8 +43,8 @@ jobs:
- checkout
- restore_cache:
keys:
- dependencies-{{ checksum "yarn.lock" }}
- run: yarn test:coverage --runInBand --no-cache
- dependencies-{{ checksum "package-lock.json" }}
- run: npm run test:coverage --runInBand --no-cache
- save_cache:
key: coverage-{{ .Environment.CIRCLE_SHA1 }}
paths:
@ -56,12 +56,11 @@ jobs:
- checkout
- restore_cache:
keys:
- dependencies-{{ checksum "yarn.lock" }}
- dependencies-{{ checksum "package-lock.json" }}
- restore_cache:
keys:
- coverage-{{ .Environment.CIRCLE_SHA1 }}
- run: yarn global add codecov
- run: yarn codecov
- run: npx codecov
workflows:
version: 2

View File

@ -7,3 +7,4 @@ indent_size = 2
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
css

View File

@ -39,15 +39,17 @@
"import/no-named-as-default": ["off"],
"import/prefer-default-export": ["off"],
"sort-keys": ["off"],
"camelcase": ["off"],
"comma-dangle": ["error", "always-multiline"],
"sort-imports": ["off"],
"no-restricted-globals": ["off"],
"@typescript-eslint/no-unused-vars": ["off"],
"@typescript-eslint/no-use-before-define": ["off"],
"@typescript-eslint/quotes": ["error", "double"],
"@typescript-eslint/naming-convention": ["error", {
"format": ["camelCase", "UPPER_CASE", "PascalCase"],
"selector": "parameter",
"leadingUnderscore": "allow"
"format": ["camelCase", "UPPER_CASE", "snake_case", "PascalCase"],
"leadingUnderscore": "allow",
"selector": "parameter"
}],
"react/static-property-placement": ["off"],
"react/prop-types": ["off"],
@ -55,7 +57,7 @@
"error",
{
"groups": [
["react"],
["react|path"],
["^\\u0000"],
["^@?\\w"],
["^[^. ]"],

3
.gitignore vendored
View File

@ -15,6 +15,9 @@ pids
# build
public
# cache
.cache
# directory for instrumented libs generated by jscoverage
lib-cov

View File

@ -1,5 +1,4 @@
*.*
!*.scss
!*.json
!*.md
!*.mdx

View File

@ -4,7 +4,6 @@ All notable changes to this project will be documented in this file.
## [4.0.0] - 2021-10-24
- Remove Netlify CMS
- Upgrade to Gatsby 4.0
## [3.0.3] - 2019-07-25

View File

@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2016-2021 Alexander Shelepenok
Copyright (c) 2016-2022 Alexander Shelepenok
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

134
README.md
View File

@ -1,5 +1,5 @@
<h1 align="center">
<img alt="Lumen" title="Lumen" src="https://github.com/alxshelepenok/gatsby-starter-lumen/blob/gatsby-v2/.github/logo.png" width="140"> </br>
<img alt="Lumen" title="Lumen" src="https://github.com/alxshelepenok/gatsby-starter-lumen/blob/master/.github/logo.png" width="140"> </br>
Lumen
</h1>
@ -14,9 +14,7 @@
## Table of contents
- [Features](http://github.com/alxshelepenok/gatsby-starter-lumen#features)
- [Web Performance Tests](http://github.com/alxshelepenok/gatsby-starter-lumen#web-performance-tests)
- [Quick Start](http://github.com/alxshelepenok/gatsby-starter-lumen#quick-start)
- [Deploy with Netlify](http://github.com/alxshelepenok/gatsby-starter-lumen#deploy-with-netlify)
- [Folder Structure](http://github.com/alxshelepenok/gatsby-starter-lumen#folder-structure)
- [Sponsors](http://github.com/alxshelepenok/gatsby-starter-lumen#sponsors)
- [Contributors](http://github.com/alxshelepenok/gatsby-starter-lumen#contributors)
@ -24,89 +22,40 @@
## Features
- [Lost Grid](http://lostgrid.org).
- [Modern font stack](https://bitsofco.de/the-new-system-font-stack).
- Beautiful typography inspired by [matejlatin/Gutenberg](https://github.com/matejlatin/Gutenberg).
- Syntax highlighting in code blocks using [PrismJS](http://prismjs.com).
- [Mobile-First](https://medium.com/@mrmrs_/mobile-first-css-48bc4cc3f60f) approach in development.
- Archive organized by tags and categories.
- Beautiful typography.
- Mobile-First approach in development.
- Syntax highlighting in code blocks using PrismJS.
- Pagination support.
- Google Analytics.
- Disqus Comments.
- [Flow](https://flow.org/) static type checking.
## Web Performance Tests
- Lighthouse Report - [WebPageTest](https://www.webpagetest.org/result/190510_FE_3f2b13d0beed320f477467d433f56f43/)
- Visual Comparison - [WebPageTest](https://www.webpagetest.org/video/compare.php?tests=190510_KZ_1228c343ccf04148619a5d0b89a41f71,190510_RE_b3bfad442f32c690a9f420fe46025b8d,190510_RS_3b5f0bff2d95161351dc6934cadbf1cf,190510_SC_5c458c451941f81b12911ccf4171a817,190510_63_52d5edd8743773815fbacb2e9c66d228,190510_AS_741b29f5af5a6e54980d82826d7bb5bb)
## Quick Start
#### Create a Gatsby site
Use the Gatsby CLI to create a new site, specifying the Lumen starter.
```sh
# Create a new Gatsby site using the Lumen starter
gatsby new blog https://github.com/alxshelepenok/gatsby-starter-lumen
```
#### Start Developing
Navigate into your new sites directory and start it up.
```sh
cd blog
gatsby develop
```
#### Open the source code and start editing!
Your site is now running at `http://localhost:8000`!
Note: You'll also see a second link: `http://localhost:8000/___graphql`. This is a tool you can use to experiment with querying your data. Learn more about using this tool in the [Gatsby tutorial](https://www.gatsbyjs.org/tutorial/part-five/#introducing-graphiql).
Open the `blog` directory in your code editor of choice and edit `src/templates/index-template.js`. Save your changes and the browser will update in real time!
```sh
yarn deploy
```
#### Access Locally
```
$ git clone https://github.com/[GITHUB_USERNAME]/[REPO_NAME].git
$ cd [REPO_NAME]
$ yarn
$ yarn develop
```
To test the CMS locally, you'll need run a production build of the site:
```
$ yarn build
$ gatsby serve
$ npm install
$ npm run start
```
## Folder Structure
```
└── content
├── pages
└── posts
└── static
├── admin
└── media
.
├── internal
│   ├── definitions
│   ├── gatsby
│   │   ├── constants
│   │   ├── queries
│   │   ├── types
│   │   └── utils
│   └── testing
│   └── __mocks__
└── src
├── assets
│   └── scss
│   ├── base
│   └── mixins
├── cms
│   └── preview-templates
├── components
│   ├── Feed
│   ├── Icon
│   ├── Image
│   ├── Layout
│   ├── Page
│   ├── Pagination
@ -122,9 +71,18 @@ $ gatsby serve
│   ├── Copyright
│   └── Menu
├── constants
├── hooks
├── templates
│   ├── CategoriesTemplate
│   ├── CategoryTemplate
│   ├── IndexTemplate
│   ├── NotFoundTemplate
│   ├── PageTemplate
│   ├── PostTemplate
│   ├── TagsTemplate
│   └── TagTemplate
├── types
└── utils
```
## Sponsors
@ -136,33 +94,37 @@ Development efforts are supported by the sponsors. I'm very grateful for their d
## Contributors
Thanks goes to these wonderful people!
Thanks to these wonderful people!
| [<img alt="vzhou842" src="https://avatars3.githubusercontent.com/u/10209814?v=4&s=117" width="117">](https://github.com/vzhou842) | [<img alt="alehel" src="https://avatars2.githubusercontent.com/u/22277624?v=4&s=117" width="117">](https://github.com/alehel) | [<img alt="abisz" src="https://avatars3.githubusercontent.com/u/7287780?v=4&s=117" width="117">](https://github.com/abisz) | [<img alt="remi-bruguier" src="https://avatars0.githubusercontent.com/u/7031328?v=4&s=117" width="117">](https://github.com/remi-bruguier) | [<img alt="mariolopjr" src="https://avatars3.githubusercontent.com/u/2067324?v=4&s=117" width="117">](https://github.com/mariolopjr) | [<img alt="ihororlovskyi" src="https://avatars3.githubusercontent.com/u/7969737?v=4&s=117" width="117">](https://github.com/ihororlovskyi) |
| :-------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------: |
| [vzhou842](https://github.com/vzhou842) | [alehel](https://github.com/alehel) | [abisz](https://github.com/abisz) | [remi-bruguier](https://github.com/remi-bruguier) | [mariolopjr](https://github.com/mariolopjr) | [ihororlovskyi](https://github.com/ihororlovskyi) |
[<img alt="vzhou842" src="https://avatars.githubusercontent.com/u/10209814?v=4&s=117" width="117">](https://github.com/vzhou842) |[<img alt="abisz" src="https://avatars.githubusercontent.com/u/7287780?v=4&s=117" width="117">](https://github.com/abisz) |[<img alt="remi-bruguier" src="https://avatars.githubusercontent.com/u/7031328?v=4&s=117" width="117">](https://github.com/remi-bruguier) |[<img alt="sparklesam" src="https://avatars.githubusercontent.com/u/10287995?v=4&s=117" width="117">](https://github.com/sparklesam) |[<img alt="vinnymac" src="https://avatars.githubusercontent.com/u/1832781?v=4&s=117" width="117">](https://github.com/vinnymac) |[<img alt="mariolopjr" src="https://avatars.githubusercontent.com/u/2067324?v=4&s=117" width="117">](https://github.com/mariolopjr) |
:---: |:---: |:---: |:---: |:---: |:---: |
[vzhou842](https://github.com/vzhou842) |[abisz](https://github.com/abisz) |[remi-bruguier](https://github.com/remi-bruguier) |[sparklesam](https://github.com/sparklesam) |[vinnymac](https://github.com/vinnymac) |[mariolopjr](https://github.com/mariolopjr) |
| [<img alt="timbroder" src="https://avatars2.githubusercontent.com/u/121503?v=4&s=117" width="117">](https://github.com/timbroder) | [<img alt="vinnymac" src="https://avatars0.githubusercontent.com/u/1832781?v=4&s=117" width="117">](https://github.com/vinnymac) | [<img alt="yodahuang" src="https://avatars2.githubusercontent.com/u/11242657?v=4&s=117" width="117">](https://github.com/yodahuang) | [<img alt="axelclark" src="https://avatars1.githubusercontent.com/u/16856928?v=4&s=117" width="117">](https://github.com/axelclark) | [<img alt="BigTony666" src="https://avatars2.githubusercontent.com/u/29159357?v=4&s=117" width="117">](https://github.com/BigTony666) | [<img alt="stigrune" src="https://avatars0.githubusercontent.com/u/1052748?v=4&s=117" width="117">](https://github.com/stigrune) |
| :-------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------: |
| [timbroder](https://github.com/timbroder) | [vinnymac](https://github.com/vinnymac) | [yodahuang](https://github.com/yodahuang) | [axelclark](https://github.com/axelclark) | [BigTony666](https://github.com/BigTony666) | [stigrune](https://github.com/stigrune) |
[<img alt="ihororlovskyi" src="https://avatars.githubusercontent.com/u/7969737?v=4&s=117" width="117">](https://github.com/ihororlovskyi) |[<img alt="rtveitch" src="https://avatars.githubusercontent.com/u/25228001?v=4&s=117" width="117">](https://github.com/rtveitch) |[<img alt="timbroder" src="https://avatars.githubusercontent.com/u/121503?v=4&s=117" width="117">](https://github.com/timbroder) |[<img alt="yodahuang" src="https://avatars.githubusercontent.com/u/11242657?v=4&s=117" width="117">](https://github.com/yodahuang) |[<img alt="axelclark" src="https://avatars.githubusercontent.com/u/16856928?v=4&s=117" width="117">](https://github.com/axelclark) |[<img alt="tonyz0x0" src="https://avatars.githubusercontent.com/u/29159357?v=4&s=117" width="117">](https://github.com/tonyz0x0) |
:---: |:---: |:---: |:---: |:---: |:---: |
[ihororlovskyi](https://github.com/ihororlovskyi) |[rtveitch](https://github.com/rtveitch) |[timbroder](https://github.com/timbroder) |[yodahuang](https://github.com/yodahuang) |[axelclark](https://github.com/axelclark) |[tonyz0x0](https://github.com/tonyz0x0) |
| [<img alt="ybbarng" src="https://avatars2.githubusercontent.com/u/1793950?v=4&s=117" width="117">](https://github.com/ybbarng) | [<img alt="marktani" src="https://avatars1.githubusercontent.com/u/1780597?v=4&s=117" width="117">](https://github.com/marktani) | [<img alt="concreted" src="https://avatars2.githubusercontent.com/u/4016897?v=4&s=117" width="117">](https://github.com/concreted) | [<img alt="chmac" src="https://avatars0.githubusercontent.com/u/690997?v=4&s=117" width="117">](https://github.com/chmac) | [<img alt="charandas" src="https://avatars2.githubusercontent.com/u/542168?v=4&s=117" width="117">](https://github.com/charandas) | [<img alt="marcelabomfim" src="https://avatars0.githubusercontent.com/u/6224547?v=4&s=117" width="117">](https://github.com/marcelabomfim) |
| :----------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------: |
| [ybbarng](https://github.com/ybbarng) | [marktani](https://github.com/marktani) | [concreted](https://github.com/concreted) | [chmac](https://github.com/chmac) | [charandas](https://github.com/charandas) | [marcelabomfim](https://github.com/marcelabomfim) |
[<img alt="tranlehaiquan" src="https://avatars.githubusercontent.com/u/17347993?v=4&s=117" width="117">](https://github.com/tranlehaiquan) |[<img alt="seandearnaley" src="https://avatars.githubusercontent.com/u/5084762?v=4&s=117" width="117">](https://github.com/seandearnaley) |[<img alt="stigrune" src="https://avatars.githubusercontent.com/u/1052748?v=4&s=117" width="117">](https://github.com/stigrune) |[<img alt="ybbarng" src="https://avatars.githubusercontent.com/u/1793950?v=4&s=117" width="117">](https://github.com/ybbarng) |[<img alt="marktani" src="https://avatars.githubusercontent.com/u/1780597?v=4&s=117" width="117">](https://github.com/marktani) |[<img alt="concreted" src="https://avatars.githubusercontent.com/u/4016897?v=4&s=117" width="117">](https://github.com/concreted) |
:---: |:---: |:---: |:---: |:---: |:---: |
[tranlehaiquan](https://github.com/tranlehaiquan) |[seandearnaley](https://github.com/seandearnaley) |[stigrune](https://github.com/stigrune) |[ybbarng](https://github.com/ybbarng) |[marktani](https://github.com/marktani) |[concreted](https://github.com/concreted) |
| [<img alt="zollillo" src="https://avatars3.githubusercontent.com/u/8833904?v=4&s=117" width="117">](https://github.com/zollillo) | [<img alt="codejet" src="https://avatars3.githubusercontent.com/u/802203?v=4&s=117" width="117">](https://github.com/codejet) | [<img alt="reed-jones" src="https://avatars0.githubusercontent.com/u/11511864?v=4&s=117" width="117">](https://github.com/reed-jones) | [<img alt="rtveitch" src="https://avatars3.githubusercontent.com/u/25228001?v=4&s=117" width="117">](https://github.com/rtveitch) | [<img alt="SayakaOno" src="https://avatars0.githubusercontent.com/u/33141219?v=4&s=117" width="117">](https://github.com/SayakaOno) | [<img alt="swapnilmishra" src="https://avatars2.githubusercontent.com/u/875450?v=4&s=117" width="117">](https://github.com/swapnilmishra) |
| :------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------: |
| [zollillo](https://github.com/zollillo) | [codejet](https://github.com/codejet) | [reed-jones](https://github.com/reed-jones) | [rtveitch](https://github.com/rtveitch) | [SayakaOno](https://github.com/SayakaOno) | [swapnilmishra](https://github.com/swapnilmishra) |
[<img alt="gipcompany" src="https://avatars.githubusercontent.com/u/130989?v=4&s=117" width="117">](https://github.com/gipcompany) |[<img alt="chmac" src="https://avatars.githubusercontent.com/u/690997?v=4&s=117" width="117">](https://github.com/chmac) |[<img alt="charandas" src="https://avatars.githubusercontent.com/u/542168?v=4&s=117" width="117">](https://github.com/charandas) |[<img alt="ibraheemdev" src="https://avatars.githubusercontent.com/u/34988408?v=4&s=117" width="117">](https://github.com/ibraheemdev) |[<img alt="sladinji" src="https://avatars.githubusercontent.com/u/8300799?v=4&s=117" width="117">](https://github.com/sladinji) |[<img alt="marcelabomfim" src="https://avatars.githubusercontent.com/u/6224547?v=4&s=117" width="117">](https://github.com/marcelabomfim) |
:---: |:---: |:---: |:---: |:---: |:---: |
[gipcompany](https://github.com/gipcompany) |[chmac](https://github.com/chmac) |[charandas](https://github.com/charandas) |[ibraheemdev](https://github.com/ibraheemdev) |[sladinji](https://github.com/sladinji) |[marcelabomfim](https://github.com/marcelabomfim) |
| [<img alt="vvasiloud" src="https://avatars1.githubusercontent.com/u/5891530?v=4&s=117" width="117">](https://github.com/vvasiloud) | [<img alt="vstoms" src="https://avatars2.githubusercontent.com/u/22646173?v=4&s=117" width="117">](https://github.com/vstoms) | [<img alt="wichopy" src="https://avatars2.githubusercontent.com/u/24414632?v=4&s=117" width="117">](https://github.com/wichopy) | [<img alt="yairmark" src="https://avatars1.githubusercontent.com/u/28291977?v=4&s=117" width="117">](https://github.com/yairmark) |
| :--------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------: |
| [vvasiloud](https://github.com/vvasiloud) | [vstoms](https://github.com/vstoms) | [wichopy](https://github.com/wichopy) | [yairmark](https://github.com/yairmark) |
[<img alt="zollillo" src="https://avatars.githubusercontent.com/u/8833904?v=4&s=117" width="117">](https://github.com/zollillo) |[<img alt="codejet" src="https://avatars.githubusercontent.com/u/802203?v=4&s=117" width="117">](https://github.com/codejet) |[<img alt="reed-jones" src="https://avatars.githubusercontent.com/u/11511864?v=4&s=117" width="117">](https://github.com/reed-jones) |[<img alt="SayakaOno" src="https://avatars.githubusercontent.com/u/33141219?v=4&s=117" width="117">](https://github.com/SayakaOno) |[<img alt="Puterism" src="https://avatars.githubusercontent.com/u/2542730?v=4&s=117" width="117">](https://github.com/Puterism) |[<img alt="swapnilmishra" src="https://avatars.githubusercontent.com/u/875450?v=4&s=117" width="117">](https://github.com/swapnilmishra) |
:---: |:---: |:---: |:---: |:---: |:---: |
[zollillo](https://github.com/zollillo) |[codejet](https://github.com/codejet) |[reed-jones](https://github.com/reed-jones) |[SayakaOno](https://github.com/SayakaOno) |[Puterism](https://github.com/Puterism) |[swapnilmishra](https://github.com/swapnilmishra) |
[<img alt="vvasiloud" src="https://avatars.githubusercontent.com/u/5891530?v=4&s=117" width="117">](https://github.com/vvasiloud) |[<img alt="lune-sta" src="https://avatars.githubusercontent.com/u/1887764?v=4&s=117" width="117">](https://github.com/lune-sta) |[<img alt="yaaooo" src="https://avatars.githubusercontent.com/u/16640310?v=4&s=117" width="117">](https://github.com/yaaooo) |[<img alt="vstoms" src="https://avatars.githubusercontent.com/u/22646173?v=4&s=117" width="117">](https://github.com/vstoms) |[<img alt="wichopy" src="https://avatars.githubusercontent.com/u/24414632?v=4&s=117" width="117">](https://github.com/wichopy) |[<img alt="yairmark" src="https://avatars.githubusercontent.com/u/28291977?v=4&s=117" width="117">](https://github.com/yairmark) |
:---: |:---: |:---: |:---: |:---: |:---: |
[vvasiloud](https://github.com/vvasiloud) |[lune-sta](https://github.com/lune-sta) |[yaaooo](https://github.com/yaaooo) |[vstoms](https://github.com/vstoms) |[wichopy](https://github.com/wichopy) |[yairmark](https://github.com/yairmark) |
## License
The MIT License (MIT)
Copyright (c) 2016-2021 Alexander Shelepenok
Copyright (c) 2016-2022 Alexander Shelepenok
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -1,11 +1,11 @@
{
"title": "Blog by John Doe",
"url": "https://lumen.netlify.com",
"url": "https://lumen.alxshelepenok.com",
"subtitle": "Pellentesque odio nisi, euismod in, pharetra a, ultricies in, diam. Sed arcu.",
"copyright": "© All rights reserved.",
"googleAnalyticsId": "UA-73379983-2",
"disqusShortname": "",
"postsPerPage": "4",
"postsLimit": 4,
"pathPrefix": "/",
"menu": [
{
@ -32,7 +32,6 @@
"facebook": "#",
"telegram": "#",
"twitter": "#",
"vkontakte": "",
"linkedin": "#",
"instagram": "#",
"line": "",

View File

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Svg Vector Icons : http://www.onlinewebfonts.com/icon -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1000 1000" enable-background="new 0 0 1000 1000" xml:space="preserve">
<metadata> Svg Vector Icons : http://www.onlinewebfonts.com/icon </metadata>
<g><path d="M418.3,91.7h-81.7V10h81.7V91.7L418.3,91.7z M91.7,581.7H10v81.7h81.7V581.7z M91.7,459.2H10v81.7h81.7V459.2z M91.7,336.7H10v81.7h81.7V336.7z M91.7,132.5c0-22.5,18.3-40.8,40.8-40.8h163.3V10H132.5C64.8,10,10,64.9,10,132.5v163.3h81.7V132.5z M540.8,10h-81.7v81.7h81.7V10z M663.3,10h-81.7v81.7h81.7V10z M527.4,484.1c0-13.3-8.7-16.2-22-16.2h-19v32.4h19C518.7,500.2,527.4,497.4,527.4,484.1z M173.3,173.3h653.3v653.3H173.3V173.3z M583.4,524.3c0,38.6,22.4,57.3,60.7,57.3c37.4,0,60.9-18.7,60.9-57.3v-86.9h-37v86.9c0,19.5-6.6,25.2-23.8,25.2c-18.1,0-23.8-8.6-23.8-25.2v-86.9h-36.9V524.3z M449.3,578.7h37v-47.9h27c32.2,0,50-19.4,50-46.7c0-27.8-18.3-46.7-50-46.7h-64.1V578.7L449.3,578.7z M296.7,508.6c0,41.2,26.4,73.1,69.5,73.1c33.7,0,59.1-19.5,62.9-62.1h-36c-6,44.8-59.4,39.3-59.4-10.9c0-23,9.3-42.1,32.5-42.1c12.5,0,23.5,7.6,25.8,23.4h36c-3.7-37.6-29.8-55.7-61.8-55.7C323.3,434.2,296.7,466.4,296.7,508.6z M908.3,540.8H990v-81.7h-81.7V540.8L908.3,540.8z M91.7,867.5V704.2H10v163.3C10,935.1,64.8,990,132.5,990h163.3v-81.7H132.5C110,908.3,91.7,890,91.7,867.5z M908.3,867.5c0,22.5-18.3,40.8-40.8,40.8H704.2V990h163.3c67.7,0,122.5-54.9,122.5-122.5V704.2h-81.7V867.5L908.3,867.5z M908.3,663.3H990v-81.7h-81.7V663.3L908.3,663.3z M908.3,418.3H990v-81.7h-81.7V418.3L908.3,418.3z M867.5,10H704.2v81.7h163.3c22.5,0,40.8,18.3,40.8,40.8v163.3H990V132.5C990,64.9,935.2,10,867.5,10z M336.7,990h81.7v-81.7h-81.7V990L336.7,990z M581.7,990h81.7v-81.7h-81.7V990z M459.2,990h81.7v-81.7h-81.7V990L459.2,990z"/></g>
</svg>

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 383 KiB

View File

@ -1,12 +1,12 @@
---
title: "About me"
template: "page"
socialImage: "/media/image-2.jpg"
socialImage: "/notebook.jpg"
---
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante.
![Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi.](/media/image-2.jpg)
![Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi.](/notebook.jpg)
_Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi._

View File

Before

Width:  |  Height:  |  Size: 97 KiB

After

Width:  |  Height:  |  Size: 97 KiB

View File

Before

Width:  |  Height:  |  Size: 112 KiB

After

Width:  |  Height:  |  Size: 112 KiB

View File

@ -1,14 +1,14 @@
---
title: "Contact me"
template: "page"
socialImage: "/media/image-4.jpg"
socialImage: "/book.jpg"
---
Morbi in sem quis dui placerat ornare. Pellentesque odio nisi, euismod in, pharetra a, ultricies in, diam. Sed arcu. Cras consequat.
Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui.
![Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi.](/media/image-4.jpg)
![Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi.](/book.jpg)
_Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi._

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 32 KiB

View File

@ -9,12 +9,12 @@ tags:
- "Handwriting"
- "Learning to write"
description: "Quisque cursus, metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue eget diam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi lacinia molestie dui. Praesent blandit dolor. Sed non quam. In vel mi sit amet augue congue elementum."
socialImage: "/media/image-2.jpg"
socialImage: "/media/notebook.jpg"
---
Quisque cursus, metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue eget diam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi lacinia molestie dui. Praesent blandit dolor. Sed non quam. In vel mi sit amet augue congue elementum.
![Nulla faucibus vestibulum eros in tempus. Vestibulum tempor imperdiet velit nec dapibus](/media/image-2.jpg)
![Nulla faucibus vestibulum eros in tempus. Vestibulum tempor imperdiet velit nec dapibus](/media/notebook.jpg)
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis.

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

View File

@ -6,14 +6,14 @@ draft: false
slug: "the-origins-of-social-stationery-lettering"
category: "Design Culture"
description: "Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante."
socialImage: "/media/image-3.jpg"
socialImage: "/media/square.jpg"
---
**Pellentesque habitant morbi tristique** senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. _Aenean ultricies mi vitae est._ Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra.
Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. [Donec non enim](#) in turpis pulvinar facilisis.
![Nulla faucibus vestibulum eros in tempus. Vestibulum tempor imperdiet velit nec dapibus](/media/image-3.jpg)
![Nulla faucibus vestibulum eros in tempus. Vestibulum tempor imperdiet velit nec dapibus](/media/square.jpg)
## Header Level 2
@ -48,4 +48,4 @@ Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac tu
Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus.
![Test SVG](/media/cpu.svg)
![Test SVG](/media/logo.svg)

View File

@ -0,0 +1,50 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100%" height="100%" viewBox="0 0 300 300">
<title>SVG Logo</title>
<desc>Designed for the SVG Logo Contest in 2006 by Harvey Rayner, and adopted by W3C in 2009. It is available under the Creative Commons license for those who have an SVG product or who are using SVG on their site.</desc>
<metadata id="license">
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/">
<cc:Work rdf:about="">
<dc:title>SVG Logo</dc:title>
<dc:date>14-08-2009</dc:date>
<dc:creator>
<cc:Agent><dc:title>W3C</dc:title></cc:Agent>
<cc:Agent><dc:title>Harvey Rayner, designer</dc:title></cc:Agent>
</dc:creator>
<dc:description>See document description</dc:description>
<cc:license rdf:resource="http://creativecommons.org/licenses/by-nc-sa/2.5/"/>
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
</cc:Work>
<cc:License rdf:about="http://creativecommons.org/licenses/by-nc-sa/2.5/">
<cc:permits rdf:resource="http://web.resource.org/cc/Reproduction"/>
<cc:permits rdf:resource="http://web.resource.org/cc/Distribution"/>
<cc:requires rdf:resource="http://web.resource.org/cc/Notice"/>
<cc:requires rdf:resource="http://web.resource.org/cc/Attribution"/>
<cc:prohibits rdf:resource="http://web.resource.org/cc/CommercialUse"/>
<cc:permits rdf:resource="http://web.resource.org/cc/DerivativeWorks"/>
<cc:requires rdf:resource="http://web.resource.org/cc/ShareAlike"/>
</cc:License>
</rdf:RDF>
</metadata>
<defs>
<g id="SVG" fill="#ffffff" transform="scale(2) translate(20,79)">
<path id="S" d="M 5.482,31.319 C2.163,28.001 0.109,23.419 0.109,18.358 C0.109,8.232 8.322,0.024 18.443,0.024 C28.569,0.024 36.782,8.232 36.782,18.358 L26.042,18.358 C26.042,14.164 22.638,10.765 18.443,10.765 C14.249,10.765 10.850,14.164 10.850,18.358 C10.850,20.453 11.701,22.351 13.070,23.721 L13.075,23.721 C14.450,25.101 15.595,25.500 18.443,25.952 L18.443,25.952 C23.509,26.479 28.091,28.006 31.409,31.324 L31.409,31.324 C34.728,34.643 36.782,39.225 36.782,44.286 C36.782,54.412 28.569,62.625 18.443,62.625 C8.322,62.625 0.109,54.412 0.109,44.286 L10.850,44.286 C10.850,48.480 14.249,51.884 18.443,51.884 C22.638,51.884 26.042,48.480 26.042,44.286 C26.042,42.191 25.191,40.298 23.821,38.923 L23.816,38.923 C22.441,37.548 20.468,37.074 18.443,36.697 L18.443,36.692 C13.533,35.939 8.800,34.638 5.482,31.319 L5.482,31.319 L5.482,31.319 Z"/>
<path id="V" d="M 73.452,0.024 L60.482,62.625 L49.742,62.625 L36.782,0.024 L47.522,0.024 L55.122,36.687 L62.712,0.024 L73.452,0.024 Z"/>
<path id="G" d="M 91.792,25.952 L110.126,25.952 L110.126,44.286 L110.131,44.286 C110.131,54.413 101.918,62.626 91.792,62.626 C81.665,62.626 73.458,54.413 73.458,44.286 L73.458,44.286 L73.458,18.359 L73.453,18.359 C73.453,8.233 81.665,0.025 91.792,0.025 C101.913,0.025 110.126,8.233 110.126,18.359 L99.385,18.359 C99.385,14.169 95.981,10.765 91.792,10.765 C87.597,10.765 84.198,14.169 84.198,18.359 L84.198,44.286 L84.198,44.286 C84.198,48.481 87.597,51.880 91.792,51.880 C95.981,51.880 99.380,48.481 99.385,44.291 L99.385,44.286 L99.385,36.698 L91.792,36.698 L91.792,25.952 L91.792,25.952 Z"/>
</g>
</defs>
<path id="base" fill="#000" d="M8.5,150 H291.5 V250 C291.5,273.5 273.5,291.5 250,291.5 H50 C26.5,291.5 8.5,273.5 8.5,250 Z"/>
<g stroke-width="38.0086" stroke="#000">
<g id="svgstar" transform="translate(150, 150)">
<path id="svgbar" fill="#ffb13b" d="M-84.1487,-15.8513 a22.4171,22.4171 0 1 0 0,31.7026 h168.2974 a22.4171,22.4171 0 1 0 0,-31.7026 Z"/>
<use xlink:href="#svgbar" transform="rotate(45)"/>
<use xlink:href="#svgbar" transform="rotate(90)"/>
<use xlink:href="#svgbar" transform="rotate(135)"/>
</g>
</g>
<use xlink:href="#svgstar"/>
<use xlink:href="#base" opacity="0.85"/>
<use xlink:href="#SVG"/>
</svg>

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

Before

Width:  |  Height:  |  Size: 350 KiB

After

Width:  |  Height:  |  Size: 350 KiB

View File

@ -7,18 +7,17 @@ slug: "a-brief-history-of-typography"
category: "Design Inspiration"
tags:
- "Linotype"
- "Monotype"
- "History of typography"
- "Helvetica"
- "History of typography"
description: "Morbi in sem quis dui placerat ornare. Pellentesque odio nisi, euismod in, pharetra a, ultricies in, diam. Sed arcu. Cras consequat."
socialImage: "/media/image-0.jpg"
socialImage: "/media/cherry.jpg"
---
**Pellentesque habitant morbi tristique** senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. _Aenean ultricies mi vitae est._ Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra.
Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. [Donec non enim](#) in turpis pulvinar facilisis.
![Nulla faucibus vestibulum eros in tempus. Vestibulum tempor imperdiet velit nec dapibus](/media/image-0.jpg)
![Nulla faucibus vestibulum eros in tempus. Vestibulum tempor imperdiet velit nec dapibus](/media/cherry.jpg)
## Header Level 2

View File

Before

Width:  |  Height:  |  Size: 645 KiB

After

Width:  |  Height:  |  Size: 645 KiB

View File

Before

Width:  |  Height:  |  Size: 151 KiB

After

Width:  |  Height:  |  Size: 151 KiB

View File

Before

Width:  |  Height:  |  Size: 546 KiB

After

Width:  |  Height:  |  Size: 546 KiB

View File

Before

Width:  |  Height:  |  Size: 273 KiB

After

Width:  |  Height:  |  Size: 273 KiB

View File

Before

Width:  |  Height:  |  Size: 656 KiB

After

Width:  |  Height:  |  Size: 656 KiB

View File

Before

Width:  |  Height:  |  Size: 115 KiB

After

Width:  |  Height:  |  Size: 115 KiB

1
gatsby-browser.ts Normal file
View File

@ -0,0 +1 @@
import "./src/assets/scss/main.scss";

View File

@ -1,23 +1,26 @@
const config = require("./content/config.json");
import path from "path";
module.exports = {
import config from "./content/config.json";
import * as types from "./internal/gatsby/types";
export default {
pathPrefix: config.pathPrefix,
siteMetadata: {
url: config.url,
menu: config.menu,
title: config.title,
author: config.author,
subtitle: config.subtitle,
copyright: config.copyright,
postsLimit: config.postsLimit,
disqusShortname: config.disqusShortname,
postsPerPage: config.postsPerPage,
menu: config.menu,
author: config.author,
},
plugins: [
{
resolve: "gatsby-source-filesystem",
options: {
path: `${__dirname}/content`,
name: "content",
path: path.resolve("content"),
},
},
{
@ -28,22 +31,33 @@ module.exports = {
site {
siteMetadata {
url
title
subtitle
}
}
}
`,
feeds: [
{
serialize: ({ query: { site, allMarkdownRemark } }) =>
allMarkdownRemark.edges.map(edge => ({
...edge.node.frontmatter,
description: edge.node.frontmatter.description,
date: edge.node.frontmatter.date,
url: site.siteMetadata.url + edge.node.fields.slug,
guid: site.siteMetadata.url + edge.node.fields.slug,
custom_elements: [{ "content:encoded": edge.node.html }],
serialize: ({
query: { site, allMarkdownRemark },
}: {
query: {
site: {
siteMetadata: {
url: string;
};
};
allMarkdownRemark: {
edges: Array<types.Edge>;
};
};
}) =>
allMarkdownRemark.edges.map(({ node }) => ({
...node.frontmatter,
date: node?.frontmatter?.date,
description: node?.frontmatter?.description,
url: site.siteMetadata.url + node?.fields?.slug,
guid: site.siteMetadata.url + node?.fields?.slug,
custom_elements: [{ "content:encoded": node.html }],
})),
query: `
{
@ -59,10 +73,8 @@ module.exports = {
slug
}
frontmatter {
title
date
template
draft
title
description
}
}
@ -125,21 +137,12 @@ module.exports = {
path: { regex: "/^(?!/404/|/404.html|/dev-404-page/)/" }
}
) {
edges {
node {
nodes {
path
}
}
}
}
`,
output: "/sitemap.xml",
serialize: ({ site, allSitePage }) =>
allSitePage.edges.map(edge => ({
url: site.siteMetadata.siteUrl + edge.node.path,
changefreq: "daily",
priority: 0.7,
})),
},
},
{
@ -147,11 +150,11 @@ module.exports = {
options: {
name: config.title,
short_name: config.title,
start_url: "/",
background_color: "#FFF",
theme_color: "#F7A046",
display: "standalone",
theme_color: "hsl(31, 92%, 62%)",
background_color: "hsl(0, 0%, 100%)",
icon: "content/photo.jpg",
display: "standalone",
start_url: "/",
},
},
{
@ -180,17 +183,6 @@ module.exports = {
},
},
},
"gatsby-plugin-catch-links",
"gatsby-plugin-react-helmet",
{
resolve: "gatsby-plugin-sass",
options: {
implementation: require("sass"),
cssLoaderOptions: {
camelCase: false,
},
},
},
{
resolve: "@sentry/gatsby",
options: {
@ -198,6 +190,10 @@ module.exports = {
tracesSampleRate: 1,
},
},
"gatsby-plugin-image",
"gatsby-plugin-catch-links",
"gatsby-plugin-react-helmet",
"gatsby-plugin-optimize-svgs",
"gatsby-plugin-sass",
],
};

View File

@ -1,9 +0,0 @@
"use strict";
require("source-map-support").install();
require("ts-node").register();
const { createPages } = require("./internal/gatsby/create-pages");
const { onCreateNode } = require("./internal/gatsby/on-create-node");
module.exports = { createPages, onCreateNode };

3
gatsby-node.ts Normal file
View File

@ -0,0 +1,3 @@
export { createPages } from "./internal/gatsby/create-pages";
export { onCreateNode } from "./internal/gatsby/on-create-node";
export { onCreateWebpackConfig } from "./internal/gatsby/on-create-webpack-config";

View File

@ -1,8 +1,8 @@
const routes = Object.freeze({
notFoundRoute: "/404",
categoriesListRoute: "/categories",
categoryRoute: "/category",
tagsListRoute: "/tags",
notFoundRoute: "/404",
tagRoute: "/tag",
indexRoute: "/",
});

View File

@ -1,12 +1,22 @@
import path from "path";
const templates = Object.freeze({
categoriesTemplate: path.resolve("./src/templates/categories-template.tsx"),
notFoundTemplate: path.resolve("./src/templates/not-found-template.tsx"),
indexTemplate: path.resolve("./src/templates/index-template.tsx"),
tagsTemplate: path.resolve("./src/templates/tags-template.tsx"),
pageTemplate: path.resolve("./src/templates/page-template.tsx"),
postTemplate: path.resolve("./src/templates/post-template.tsx"),
indexTemplate: path.resolve(
"./src/templates/IndexTemplate/IndexTemplate.tsx",
),
notFoundTemplate: path.resolve(
"./src/templates/NotFoundTemplate/NotFoundTemplate.tsx",
),
categoryTemplate: path.resolve(
"./src/templates/CategoryTemplate/CategoryTemplate.tsx",
),
categoriesTemplate: path.resolve(
"./src/templates/CategoriesTemplate/CategoriesTemplate.tsx",
),
tagTemplate: path.resolve("./src/templates/TagTemplate/TagTemplate.tsx"),
tagsTemplate: path.resolve("./src/templates/TagsTemplate/TagsTemplate.tsx"),
pageTemplate: path.resolve("./src/templates/PageTemplate/PageTemplate.tsx"),
postTemplate: path.resolve("./src/templates/PostTemplate/PostTemplate.tsx"),
});
export default templates;

View File

@ -5,6 +5,7 @@ import * as queries from "./queries";
import * as utils from "./utils";
type CreateWithPagination = (parameters: {
limit: number;
group?: string;
template: string;
total: number;
@ -13,7 +14,7 @@ type CreateWithPagination = (parameters: {
}) => void;
const getPaginationPath = (basePath: string, page: number): string =>
[basePath, "page", page].join("/");
[basePath === "/" ? "" : basePath, "page", page].join("/");
const createPages: GatsbyNode["createPages"] = async ({ graphql, actions }) => {
const { createPage } = actions;
@ -62,12 +63,15 @@ const createPages: GatsbyNode["createPages"] = async ({ graphql, actions }) => {
page,
path,
total,
limit,
}) => {
createPage({
component: template,
path: page === 0 ? path : getPaginationPath(path, page),
context: {
group,
limit,
offset: page * limit,
pagination: {
currentPage: page,
prevPagePath:
@ -94,8 +98,9 @@ const createPages: GatsbyNode["createPages"] = async ({ graphql, actions }) => {
for (let page = 0; page < total; page += 1) {
createWithPagination({
limit: postsLimit,
group: category.fieldValue,
template: constants.templates.categoriesTemplate,
template: constants.templates.categoryTemplate,
total,
page,
path,
@ -116,8 +121,9 @@ const createPages: GatsbyNode["createPages"] = async ({ graphql, actions }) => {
for (let page = 0; page < total; page += 1) {
createWithPagination({
limit: postsLimit,
group: tag.fieldValue,
template: constants.templates.categoriesTemplate,
template: constants.templates.tagTemplate,
total,
page,
path,
@ -126,12 +132,14 @@ const createPages: GatsbyNode["createPages"] = async ({ graphql, actions }) => {
});
const path = constants.routes.indexRoute;
const template = constants.templates.indexTemplate;
const posts = await queries.postsQuery(graphql);
const total = Math.ceil(posts?.edges?.length ?? 0 / postsLimit);
const total = Math.ceil((posts?.edges?.length ?? 0) / postsLimit);
for (let page = 0; page < total; page += 1) {
createWithPagination({
template: constants.templates.indexTemplate,
limit: postsLimit,
template,
total,
page,
path,

View File

@ -0,0 +1,25 @@
import path from "path";
import { CreateWebpackConfigArgs } from "gatsby";
import { CompilerOptions } from "typescript";
import { compilerOptions } from "../../tsconfig.json";
const onCreateWebpackConfig = (
(options: Pick<CompilerOptions, "paths">) =>
({ actions }: CreateWebpackConfigArgs) => {
actions.setWebpackConfig({
resolve: {
alias: Object.entries(options.paths || []).reduce(
(aliases, [name, [target]]) => ({
...aliases,
[name]: path.resolve(target),
}),
{},
),
},
});
}
)(compilerOptions);
export { onCreateWebpackConfig };

View File

@ -12,9 +12,11 @@ const metadataQuery = async (graphql: CreatePagesArgs["graphql"]) => {
const result = await graphql<MetadataQueryResult>(`
query SiteMetaData {
site {
siteMetadata {
postsLimit
}
}
}
`);
return result?.data?.site.siteMetadata ?? {};

View File

@ -1,9 +1,11 @@
import { Node as GatsbyNode } from "gatsby";
interface Frontmatter {
date?: string;
slug?: string;
template?: string;
category?: string;
description?: string;
tags?: Array<string>;
}

View File

@ -1,6 +1,10 @@
const toKebabCase = (str: string = ""): string => str.toLowerCase()
const toKebabCase = (str: string = ""): string =>
str
.toLowerCase()
.replace(/[^\w\s]/gi, "")
.split(" ").join("-")
.split("_").join("-");
.split(" ")
.join("-")
.split("_")
.join("-");
export default toKebabCase;

View File

@ -1,52 +1,4 @@
export default {
allMarkdownRemark: {
group: [
{
fieldValue: "typography",
totalCount: 1,
},
{
fieldValue: "design inspiration",
totalCount: 1,
},
],
edges: [
{
node: {
id: "08870ea6-bdc8-4ec6-bf72-1e7d4488eb72",
fields: {
slug: "/posts/perfecting-the-art-of-perfection",
categorySlug: "/typography",
},
frontmatter: {
date: "2016-09-01",
description:
"An Essay on Typography by Eric Gill takes the reader back to the year 1930. The year when a conflict between two worlds came to its term. The machines of the industrial world finally took over the handicrafts.",
category: "typography",
title: "Perfecting the Art of Perfection",
template: "post",
},
html: "",
},
},
{
node: {
id: "066adc91-f87a-4e57-9fef-7a677baf5c1d",
fields: {
slug: "/posts/the-birth-of-movable-type",
categorySlug: "/design-inspiration",
},
frontmatter: {
date: "2016-09-01",
description:
"German inventor Johannes Gutenberg developed a method of movable type and used it to create one of the western worlds first major printed books, the “FortyTwoLine” Bible.",
category: "design inspiration",
title: "Johannes Gutenberg: The Birth of Movable Type",
template: "post",
},
html: "",
},
},
],
},
};
import edges from "./edges";
import group from "./group";
export default { group, edges };

View File

@ -1,7 +1,7 @@
import contacts from "./contacts";
export default {
photo: "/static/photo.jpg",
photo: "/photo.jpg",
bio: "Pellentesque odio nisi, euismod in, pharetra a, ultricies in, diam. Sed arcu.",
name: "John Doe",
contacts,

View File

@ -4,5 +4,4 @@ export default {
github: "#",
twitter: "#",
telegram: "#",
vkontakte: "#",
};

View File

@ -0,0 +1,38 @@
export default [
{
node: {
id: "08870ea6-bdc8-4ec6-bf72-1e7d4488eb72",
fields: {
slug: "/posts/perfecting-the-art-of-perfection",
categorySlug: "/typography",
},
frontmatter: {
date: "2016-09-01",
description:
"An Essay on Typography by Eric Gill takes the reader back to the year 1930. The year when a conflict between two worlds came to its term. The machines of the industrial world finally took over the handicrafts.",
category: "typography",
title: "Perfecting the Art of Perfection",
template: "post",
},
html: "<p>An Essay on Typography by Eric Gill takes the reader back to the year 1930. The year when a conflict between two worlds came to its term. The machines of the industrial world finally took over the handicrafts.</p>",
},
},
{
node: {
id: "066adc91-f87a-4e57-9fef-7a677baf5c1d",
fields: {
slug: "/posts/the-birth-of-movable-type",
categorySlug: "/design-inspiration",
},
frontmatter: {
date: "2016-09-01",
description:
"German inventor Johannes Gutenberg developed a method of movable type and used it to create one of the western worlds first major printed books, the “FortyTwoLine” Bible.",
category: "design inspiration",
title: "Johannes Gutenberg: The Birth of Movable Type",
template: "post",
},
html: "<p>German inventor Johannes Gutenberg developed a method of movable type and used it to create one of the western worlds first major printed books, the “FortyTwoLine” Bible.</p>",
},
},
];

View File

@ -0,0 +1,10 @@
export default [
{
fieldValue: "typography",
totalCount: 1,
},
{
fieldValue: "design inspiration",
totalCount: 1,
},
];

View File

@ -5,3 +5,4 @@ export { default as pageContext } from "./page-context";
export { default as contacts } from "./contacts";
export { default as author } from "./author";
export { default as menu } from "./menu";
export { default as edges } from "./edges";

View File

@ -2,15 +2,17 @@ export default {
id: "08870ea6-bdc8-4ec6-bf72-1e7d4488eb72",
fields: {
slug: "/posts/perfecting-the-art-of-perfection",
tagsSlugs: ["/handwriting", "/helvetica"],
categorySlug: "/typography",
},
frontmatter: {
date: "2016-09-01",
description:
"An Essay on Typography by Eric Gill takes the reader back to the year 1930. The year when a conflict between two worlds came to its term. The machines of the industrial world finally took over the handicrafts.",
category: "typography",
category: "Typography",
tags: ["Handwriting", "Helvetica"],
title: "Perfecting the Art of Perfection",
template: "post",
},
html: "",
html: "<p>An Essay on Typography by Eric Gill takes the reader back to the year 1930. The year when a conflict between two worlds came to its term. The machines of the industrial world finally took over the handicrafts.</p>",
};

View File

@ -1,5 +1,4 @@
export default {
pageContext: {
group: "typography",
pagination: {
currentPage: 2,
@ -8,5 +7,4 @@ export default {
hasNextPage: true,
hasPrevPage: true,
},
},
};

View File

@ -20,6 +20,12 @@ const jestConfig: Config.InitialOptions = {
".+\\.(css|sass|scss)$": "identity-obj-proxy",
".+\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$":
"identity-obj-proxy",
"^gatsby-page-utils/(.*)$": "gatsby-page-utils/dist/$1",
"^gatsby-core-utils/(.*)$": "gatsby-core-utils/dist/$1",
"^gatsby-plugin-utils/(.*)$": [
"gatsby-plugin-utils/dist/$1",
"gatsby-plugin-utils/$1",
],
},
transform: { "^.+\\.(t)sx?$": ["@swc/jest", swc] },
setupFiles: ["<rootDir>/internal/testing/jest-setup.ts"],

8922
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
{
"name": "gatsby-starter-lumen",
"version": "4.0.0",
"description": "A minimal, lightweight and mobile-first starter for creating blazing-fast static blogs",
"description": "A minimal, lightweight and mobile-first starter for creating static blogs.",
"keywords": [
"gatsby",
"graphql",
@ -14,7 +14,6 @@
},
"license": "MIT",
"author": "Alexander Shelepenok <alxshelepenok@gmail.com>",
"main": "n/a",
"scripts": {
"build": "npm run clean && gatsby build",
"clean": "rimraf .cache public",
@ -25,96 +24,93 @@
"lint:scss": "stylelint \"src/**/*.scss\"",
"lint:ts": "eslint \"src\" --ext .tsx,.ts && prettier --check .",
"start": "npm run clean && gatsby develop",
"serve": "gatsby serve",
"test": "jest --config ./internal/testing/jest-config.ts",
"test:coverage": "jest --coverage --config ./jest/jest-config.js",
"test:watch": "jest --watch --config ./jest/jest-config.js"
"test:coverage": "jest --coverage --config ./internal/testing/jest-config.ts",
"test:watch": "jest --watch --config ./internal/testing/jest-config.ts"
},
"dependencies": {
"@sentry/gatsby": "^6.16.1",
"@sentry/tracing": "^6.16.1",
"@sentry/gatsby": "^6.19.6",
"@sentry/tracing": "^6.19.6",
"classnames": "^2.3.1",
"codecov": "^3.8.3",
"cross-env": "^7.0.3",
"eslint-plugin-jest": "^25.3.4",
"gatsby": "^4.4.0",
"gatsby-link": "^4.4.0",
"gatsby-plugin-catch-links": "^4.4.0",
"gatsby-plugin-feed": "^4.4.0",
"gatsby-plugin-flow": "^3.4.0",
"gatsby-plugin-google-gtag": "^4.4.0",
"gatsby-plugin-manifest": "^4.4.0",
"gatsby-plugin-offline": "^5.4.0",
"gatsby": "^4.12.1",
"gatsby-link": "^4.12.1",
"gatsby-plugin-catch-links": "^4.12.1",
"gatsby-plugin-feed": "^4.12.1",
"gatsby-plugin-flow": "^3.12.1",
"gatsby-plugin-google-gtag": "^4.12.1",
"gatsby-plugin-image": "^2.12.1",
"gatsby-plugin-manifest": "^4.12.1",
"gatsby-plugin-offline": "^5.12.1",
"gatsby-plugin-optimize-svgs": "^1.0.5",
"gatsby-plugin-react-helmet": "^5.4.0",
"gatsby-plugin-sass": "^5.4.0",
"gatsby-plugin-sharp": "^4.4.0",
"gatsby-plugin-sitemap": "^5.4.0",
"gatsby-remark-autolink-headers": "^5.4.0",
"gatsby-remark-copy-linked-files": "^5.4.0",
"gatsby-plugin-react-helmet": "^5.12.1",
"gatsby-plugin-sass": "^5.12.1",
"gatsby-plugin-sharp": "^4.12.1",
"gatsby-plugin-sitemap": "^5.12.1",
"gatsby-remark-autolink-headers": "^5.12.1",
"gatsby-remark-copy-linked-files": "^5.12.1",
"gatsby-remark-external-links": "0.0.4",
"gatsby-remark-images": "^6.4.0",
"gatsby-remark-prismjs": "^6.4.0",
"gatsby-remark-responsive-iframe": "^5.4.0",
"gatsby-remark-smartypants": "^5.4.0",
"gatsby-source-filesystem": "^4.4.0",
"gatsby-transformer-remark": "^5.4.0",
"gatsby-transformer-sharp": "^4.4.0",
"invariant": "^2.2.4",
"lodash": "^4.17.21",
"node-sass": "^7.0.1",
"normalize-scss": "^7.0.1",
"postcss": "^8.4.5",
"postcss-scss": "^4.0.2",
"prismjs": "^1.26.0",
"react": "^17.0.2",
"gatsby-remark-images": "^6.12.1",
"gatsby-remark-prismjs": "^6.12.1",
"gatsby-remark-responsive-iframe": "^5.12.1",
"gatsby-remark-smartypants": "^5.12.1",
"gatsby-source-filesystem": "^4.12.1",
"gatsby-transformer-remark": "^5.12.1",
"gatsby-transformer-sharp": "^4.12.1",
"prismjs": "^1.27.0",
"react": "^18.0.0",
"react-disqus-comments": "^1.4.0",
"react-dom": "^17.0.2",
"react-helmet": "^6.1.0",
"sass": "^1.47.0"
"react-dom": "^18.0.0",
"react-helmet": "^6.1.0"
},
"devDependencies": {
"@alxshelepenok/eslint-config": "^1.0.20",
"@jest/globals": "^27.4.6",
"@swc/core": "^1.2.127",
"@swc/jest": "^0.2.15",
"@alxshelepenok/eslint-config": "^1.0.27",
"@jest/globals": "^27.5.1",
"@swc/core": "^1.2.165",
"@swc/jest": "^0.2.20",
"@types/gatsby-transformer-remark": "^2.9.1",
"@types/jest": "^27.4.0",
"@types/node": "^17.0.8",
"@types/react": "^17.0.38",
"@types/react-dom": "^17.0.11",
"@types/jest": "^27.4.1",
"@types/node": "^17.0.24",
"@types/react": "^18.0.5",
"@types/react-dom": "^18.0.1",
"@types/react-helmet": "^6.1.5",
"@types/react-test-renderer": "^17.0.1",
"@types/react-test-renderer": "^18.0.0",
"@types/sass": "^1.43.1",
"@typescript-eslint/eslint-plugin": "^5.9.0",
"@typescript-eslint/parser": "^5.9.0",
"autoprefixer": "^10.4.2",
"browserslist": "^4.19.1",
"concurrently": "^7.0.0",
"eslint": "^8.6.0",
"@typescript-eslint/eslint-plugin": "^5.19.0",
"@typescript-eslint/parser": "^5.19.0",
"autoprefixer": "^10.4.4",
"browserslist": "^4.20.2",
"codecov": "^3.8.3",
"concurrently": "^7.1.0",
"eslint": "^8.13.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-airbnb-typescript": "^16.1.0",
"eslint-config-prettier": "^8.1.0",
"eslint-import-resolver-typescript": "^2.5.0",
"eslint-plugin-import": "^2.25.4",
"eslint-config-airbnb-typescript": "^17.0.0",
"eslint-config-prettier": "^8.5.0",
"eslint-import-resolver-typescript": "^2.7.1",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jest": "^26.1.4",
"eslint-plugin-jsx-a11y": "^6.5.1",
"eslint-plugin-react": "^7.28.0",
"eslint-plugin-react-hooks": "^4.3.0",
"eslint-plugin-react": "^7.29.4",
"eslint-plugin-react-hooks": "^4.4.0",
"eslint-plugin-simple-import-sort": "^7.0.0",
"identity-obj-proxy": "3.0.0",
"jest": "^27.4.7",
"jest-cli": "^27.4.7",
"jest": "^27.5.1",
"jest-cli": "^27.5.1",
"jest-svg-transformer": "^1.0.0",
"lost": "8.3.1",
"prettier": "^2.5.1",
"prettier-plugin-packagejson": "^2.2.15",
"react-test-renderer": "17.0.2",
"postcss": "^8.4.12",
"postcss-scss": "^4.0.3",
"prettier": "^2.6.2",
"prettier-plugin-packagejson": "^2.2.17",
"react-test-renderer": "^18.0.0",
"rimraf": "3.0.2",
"sass": "^1.50.0",
"source-map-support": "^0.5.21",
"stylelint": "^14.2.0",
"stylelint-config-recommended-scss": "^5.0.2",
"stylelint": "^14.7.0",
"stylelint-config-recommended-scss": "^6.0.0",
"stylelint-order": "^5.0.0",
"stylelint-scss": "^4.1.0",
"ts-node": "^10.4.0",
"typescript": "^4.5.4"
"stylelint-scss": "^4.2.0",
"ts-node": "^10.7.0",
"typescript": "^4.6.3"
}
}

View File

@ -1,17 +1,16 @@
@use "sass:math";
@use "sass:color";
$color-base: #222222;
$color-primary: #5d93ff;
$color-secondary: #f7a046;
$color-base: hsl(0, 0%, 13%);
$color-primary: hsl(220, 100%, 68%);
$color-secondary: hsl(31, 92%, 62%);
$color-white: #ffffff;
$color-gray: color.adjust($color-base, 40%);
$color-gray-border: color.adjust($color-base, 77%);
$color-gray-bg: color.adjust($color-base, 79%);
$color-white: hsl(0, 0%, 100%);
$color-gray: color.adjust($color-base, $lightness: 40%);
$color-gray-border: color.adjust($color-base, $lightness: 77%);
$color-gray-bg: color.adjust($color-base, $lightness: 79%);
$typographic-font-family: -apple-system, "BlinkMacSystemFont", "Segoe UI",
"Roboto", "Oxygen-Sans", "Ubuntu", "Cantarell", "Helvetica Neue", sans-serif;
$typographic-font-family: -apple-system, "BlinkMacSystemFont", "Segoe UI", "Roboto", "Oxygen-Sans", "Ubuntu", "Cantarell", "Helvetica Neue", sans-serif;
$typographic-root-font-size: 100;
$typographic-base-font-size: 16px;
@ -23,10 +22,7 @@ $typographic-base-font-color: $color-base;
$typographic-link-p-font-color: $color-primary;
$typographic-link-s-font-color: $color-secondary;
$typographic-leading: math.round(
16 * math.div($typographic-root-font-size, 100) *
$typographic-base-line-height
);
$typographic-leading: math.round(16 * math.div($typographic-root-font-size, 100) * $typographic-base-line-height);
$button-height: 35px;
$button-border-radius: 20px;

View File

@ -13,7 +13,7 @@ body {
-moz-osx-font-smoothing: grayscale;
line-height: $typographic-base-line-height;
margin: 0 0 0 calc(100vw - 100%);
text-rendering: optimizeLegibility;
text-rendering: optimizelegibility;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
}
@ -148,11 +148,6 @@ figcaption {
text-align: center;
}
.anchor {
margin-left: -30px !important;
padding-right: 14px !important;
}
@include breakpoint-sm {
figure.float-left,
figure.float-right {

View File

@ -101,8 +101,8 @@ pre[class*="language-"]::selection {
color: #b58900;
}
.token.important,
.token.regex,
.token.important,
.token.variable {
color: #cb4b16;
}

View File

@ -1,5 +1,17 @@
@import "../variables";
@mixin margin-auto($number: 0) {
margin: #{$number * $typographic-leading + "px"} auto;
}
@mixin margin-left($number) {
margin-left: #{$number * $typographic-leading + "px"};
}
@mixin margin-right($number) {
margin-right: #{$number * $typographic-leading + "px"};
}
@mixin margin-top($number) {
margin-top: #{$number * $typographic-leading + "px"};
}
@ -8,36 +20,25 @@
margin-bottom: #{$number * $typographic-leading + "px"};
}
@mixin margin-equal($number) {
margin: #{$number * $typographic-leading + "px"};
}
@mixin margin($top, $right, $bottom: null, $left: null) {
@if not $left and not $bottom {
margin: #{$top *
$typographic-leading +
"px"}
#{$right *
$typographic-leading +
"px"};
margin:
#{$top * $typographic-leading + "px"}
#{$right * $typographic-leading + "px"};
} @else if not $left or $left == $right {
margin: #{$top *
$typographic-leading +
"px"}
#{$right *
$typographic-leading +
"px"}
#{$bottom *
$typographic-leading +
"px"};
margin:
#{$top * $typographic-leading + "px"}
#{$right * $typographic-leading + "px"}
#{$bottom * $typographic-leading + "px"};
} @else {
margin: #{$top *
$typographic-leading +
"px"}
#{$right *
$typographic-leading +
"px"}
#{$bottom *
$typographic-leading +
"px"}
#{$left *
$typographic-leading +
"px"};
margin:
#{$top * $typographic-leading + "px"}
#{$right * $typographic-leading + "px"}
#{$bottom * $typographic-leading + "px"}
#{$left * $typographic-leading + "px"};
}
}

View File

@ -1,39 +1,40 @@
@import "../variables";
@mixin padding($top, $right, $bottom: null, $left: null) {
@if not $left and not $bottom {
padding: #{$top *
$typographic-leading +
"px"}
#{$right *
$typographic-leading +
"px"};
} @else if not $left or $left == $right {
padding: #{$top *
$typographic-leading +
"px"}
#{$right *
$typographic-leading +
"px"}
#{$bottom *
$typographic-leading +
"px"};
} @else {
padding: #{$top *
$typographic-leading +
"px"}
#{$right *
$typographic-leading +
"px"}
#{$bottom *
$typographic-leading +
"px"}
#{$left *
$typographic-leading +
"px"};
}
@mixin padding-left($number) {
padding-left: #{$number * $typographic-leading + "px"};
}
@mixin padding-right($number) {
padding-right: #{$number * $typographic-leading + "px"};
}
@mixin padding-top($number) {
padding-top: #{$number * $typographic-leading + "px"};
}
@mixin padding-bottom($number) {
padding-bottom: #{$number * $typographic-leading + "px"};
}
@mixin padding-equal($number) {
padding: #{$number * $typographic-leading + "px"};
}
@mixin padding($top, $right, $bottom: null, $left: null) {
@if not $left and not $bottom {
padding:
#{$top * $typographic-leading + "px"}
#{$right * $typographic-leading + "px"};
} @else if not $left or $left == $right {
padding:
#{$top * $typographic-leading + "px"}
#{$right * $typographic-leading + "px"}
#{$bottom * $typographic-leading + "px"};
} @else {
padding:
#{$top * $typographic-leading + "px"}
#{$right * $typographic-leading + "px"}
#{$bottom * $typographic-leading + "px"}
#{$left * $typographic-leading + "px"};
}
}

View File

@ -2,20 +2,20 @@
@import "../../assets/scss/mixins";
.feed {
&__item {
.item {
@include margin-bottom(1.25);
&:last-child {
@include margin-bottom(0.5);
}
&-title {
.title {
font-size: $typographic-base-font-size * 1.6875;
@include line-height(1.5);
@include margin-top(0);
@include margin-bottom(0.5);
&-link {
.link {
color: $color-base;
&:hover,
@ -26,26 +26,26 @@
}
}
&-description {
.description {
font-size: $typographic-base-font-size;
@include line-height(1);
@include margin-bottom(0.75);
}
&-meta {
&-time {
.meta {
.time {
color: $color-base;
font-size: $typographic-small-font-size;
font-weight: 600;
text-transform: uppercase;
}
&-divider {
margin: 0 5px;
.divider {
@include margin(0, 0.5);
}
&-category {
&-link {
.category {
.link {
color: $color-secondary;
font-size: $typographic-small-font-size;
font-weight: 600;
@ -59,7 +59,7 @@
}
}
&-more {
.more {
color: $color-primary;
font-size: $typographic-base-font-size;

View File

@ -2,52 +2,11 @@ import React from "react";
import renderer from "react-test-renderer";
import { Feed } from "@/components/Feed";
import * as mocks from "@/mocks";
describe("Feed", () => {
const props = {
edges: [
{
node: {
fields: {
slug: "/test_0",
categorySlug: "/test_0",
tagSlugs: ["/test-1", "/test-2"],
},
frontmatter: {
template: "post",
date: "2016-09-01",
description: "test_0",
category: "test_0",
tags: ["test-1", "test-2"],
title: "test_0",
},
id: "test-123",
html: "<p>test</p>",
},
},
{
node: {
fields: {
slug: "/test_1",
categorySlug: "/test_1",
tagSlugs: ["/test-1", "/test-2"],
},
frontmatter: {
template: "post",
date: "2016-09-01",
description: "test_1",
category: "test_1",
tags: ["test-1", "test-2"],
title: "test_1",
},
id: "test-321",
html: "<p>test</p>",
},
},
],
};
it("renders correctly", () => {
const props = { edges: mocks.edges };
const tree = renderer.create(<Feed {...props} />).toJSON();
expect(tree).toMatchSnapshot();
});

View File

@ -4,7 +4,7 @@ import { Link } from "gatsby";
import { Edge } from "@/types";
import styles from "./Feed.module.scss";
import * as styles from "./Feed.module.scss";
type Props = {
edges: Array<Edge>;
@ -13,10 +13,10 @@ type Props = {
const Feed: React.FC<Props> = ({ edges }: Props) => (
<div className={styles.feed}>
{edges.map(edge => (
<div className={styles.feed__item} key={edge.node.fields.slug}>
<div className={styles["feed__item-meta"]}>
<div className={styles.item} key={edge.node.fields.slug}>
<div className={styles.meta}>
<time
className={styles["feed__item-meta-time"]}
className={styles.time}
dateTime={new Date(edge.node.frontmatter.date).toLocaleDateString(
"en-US",
{ year: "numeric", month: "long", day: "numeric" },
@ -27,28 +27,22 @@ const Feed: React.FC<Props> = ({ edges }: Props) => (
month: "long",
})}
</time>
<span className={styles["feed__item-meta-divider"]} />
<span className={styles["feed__item-meta-category"]}>
<Link
to={edge.node.fields.categorySlug}
className={styles["feed__item-meta-category-link"]}
>
<span className={styles.divider} />
<span className={styles.category}>
<Link to={edge.node.fields.categorySlug} className={styles.link}>
{edge.node.frontmatter.category}
</Link>
</span>
</div>
<h2 className={styles["feed__item-title"]}>
<Link
className={styles["feed__item-title-link"]}
to={edge.node.fields.slug}
>
<h2 className={styles.title}>
<Link className={styles.link} to={edge.node.fields.slug}>
{edge.node.frontmatter.title}
</Link>
</h2>
<p className={styles["feed__item-description"]}>
<p className={styles.description}>
{edge.node.frontmatter.description}
</p>
<Link className={styles["feed__item-more"]} to={edge.node.fields.slug}>
<Link className={styles.more} to={edge.node.fields.slug}>
Read
</Link>
</div>

View File

@ -1,101 +1,67 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Feed renders correctly 1`] = `
<div
className="feed"
>
<div
className="feed__item"
>
<div
className="feed__item-meta"
>
<div>
<div>
<div>
<time
className="feed__item-meta-time"
dateTime="September 1, 2016"
>
September 2016
</time>
<span
className="feed__item-meta-divider"
/>
<span
className="feed__item-meta-category"
>
<span />
<span>
<a
className="feed__item-meta-category-link"
href="/test_0"
href="/typography"
>
test_0
typography
</a>
</span>
</div>
<h2
className="feed__item-title"
>
<h2>
<a
className="feed__item-title-link"
href="/test_0"
href="/posts/perfecting-the-art-of-perfection"
>
test_0
Perfecting the Art of Perfection
</a>
</h2>
<p
className="feed__item-description"
>
test_0
<p>
An Essay on Typography by Eric Gill takes the reader back to the year 1930. The year when a conflict between two worlds came to its term. The machines of the industrial world finally took over the handicrafts.
</p>
<a
className="feed__item-more"
href="/test_0"
href="/posts/perfecting-the-art-of-perfection"
>
Read
</a>
</div>
<div
className="feed__item"
>
<div
className="feed__item-meta"
>
<div>
<div>
<time
className="feed__item-meta-time"
dateTime="September 1, 2016"
>
September 2016
</time>
<span
className="feed__item-meta-divider"
/>
<span
className="feed__item-meta-category"
>
<span />
<span>
<a
className="feed__item-meta-category-link"
href="/test_1"
href="/design-inspiration"
>
test_1
design inspiration
</a>
</span>
</div>
<h2
className="feed__item-title"
>
<h2>
<a
className="feed__item-title-link"
href="/test_1"
href="/posts/the-birth-of-movable-type"
>
test_1
Johannes Gutenberg: The Birth of Movable Type
</a>
</h2>
<p
className="feed__item-description"
>
test_1
<p>
German inventor Johannes Gutenberg developed a method of movable type and used it to create one of the western worlds first major printed books, the “FortyTwoLine” Bible.
</p>
<a
className="feed__item-more"
href="/test_1"
href="/posts/the-birth-of-movable-type"
>
Read
</a>

View File

@ -1,6 +1,6 @@
.icon {
display: inline-block;
fill: currentColor;
fill: currentcolor;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
font-style: normal;
@ -8,10 +8,8 @@
font-weight: normal;
height: 1em;
line-height: 1em;
margin-left: 0.2em;
margin-right: 0.2em;
speak: none;
stroke: currentColor;
stroke: currentcolor;
stroke-width: 0;
text-align: center;
text-transform: none;

View File

@ -2,17 +2,13 @@ import React from "react";
import renderer from "react-test-renderer";
import { Icon } from "@/components/Icon";
import { ICONS } from "@/constants";
import { getIcon } from "@/utils";
describe("Icon", () => {
const props = {
name: "test",
icon: {
viewBox: "0 0 0 0",
path: "",
},
};
it("renders correctly", () => {
const [github] = Object.keys(ICONS) as Array<keyof typeof ICONS>;
const props = { name: github, icon: getIcon(github) };
const tree = renderer.create(<Icon {...props} />).toJSON();
expect(tree).toMatchSnapshot();
});

View File

@ -1,12 +1,14 @@
import React from "react";
import styles from "./Icon.module.scss";
import { ICONS } from "@/constants";
import * as styles from "./Icon.module.scss";
interface Props {
name: string;
name: keyof typeof ICONS;
icon: {
path?: string;
viewBox?: string;
path?: string;
};
}

View File

@ -2,14 +2,13 @@
exports[`Icon renders correctly 1`] = `
<svg
className="icon"
viewBox="0 0 0 0"
viewBox="0 0 26 28"
>
<title>
test
github
</title>
<path
d=""
d="M10 19c0 1.141-0.594 3-2 3s-2-1.859-2-3 0.594-3 2-3 2 1.859 2 3zM20 19c0 1.141-0.594 3-2 3s-2-1.859-2-3 0.594-3 2-3 2 1.859 2 3zM22.5 19c0-2.391-1.453-4.5-4-4.5-1.031 0-2.016 0.187-3.047 0.328-0.812 0.125-1.625 0.172-2.453 0.172s-1.641-0.047-2.453-0.172c-1.016-0.141-2.016-0.328-3.047-0.328-2.547 0-4 2.109-4 4.5 0 4.781 4.375 5.516 8.188 5.516h2.625c3.813 0 8.188-0.734 8.188-5.516zM26 16.25c0 1.734-0.172 3.578-0.953 5.172-2.063 4.172-7.734 4.578-11.797 4.578-4.125 0-10.141-0.359-12.281-4.578-0.797-1.578-0.969-3.437-0.969-5.172 0-2.281 0.625-4.438 2.125-6.188-0.281-0.859-0.422-1.766-0.422-2.656 0-1.172 0.266-2.344 0.797-3.406 2.469 0 4.047 1.078 5.922 2.547 1.578-0.375 3.203-0.547 4.828-0.547 1.469 0 2.953 0.156 4.375 0.5 1.859-1.453 3.437-2.5 5.875-2.5 0.531 1.062 0.797 2.234 0.797 3.406 0 0.891-0.141 1.781-0.422 2.625 1.5 1.766 2.125 3.938 2.125 6.219z"
/>
</svg>
`;

View File

@ -0,0 +1,62 @@
import React, { FC } from "react";
import { graphql, StaticQuery } from "gatsby";
import {
GatsbyImage,
GatsbyImageProps,
IGatsbyImageData,
} from "gatsby-plugin-image";
import { FileSystemNode } from "gatsby-source-filesystem";
interface Props extends Omit<GatsbyImageProps, "image"> {
path: string;
}
interface Data {
images: {
edges: Array<{
node: FileSystemNode & {
childImageSharp: {
gatsbyImageData: IGatsbyImageData;
};
};
}>;
};
}
const Image: FC<Props> = ({ path, ...rest }: Props) => (
<StaticQuery
query={graphql`
query {
images: allFile(
filter: { ext: { regex: "/png|jpg|jpeg|webp|tif|tiff/" } }
) {
edges {
node {
absolutePath
childImageSharp {
gatsbyImageData(formats: [AUTO, WEBP, AVIF])
}
}
}
}
}
`}
render={(data: Data) => {
const { images: { edges = [] } = {} } = data;
const image = edges.find(({ node }) => node.absolutePath.includes(path));
if (!image) {
return null;
}
const {
node: { childImageSharp },
} = image;
return <GatsbyImage {...rest} image={childImageSharp.gatsbyImageData} />;
}}
/>
);
export default Image;

View File

@ -0,0 +1 @@
export { default as Image } from "./Image";

View File

@ -12,12 +12,11 @@ const mockedUseStaticQuery = useStaticQuery as jest.Mock;
describe("Layout", () => {
const props = {
...mocks.siteMetadata,
description: "test",
title: "test",
title: mocks.siteMetadata.site.siteMetadata.title,
description: mocks.siteMetadata.site.siteMetadata.subtitle,
};
beforeEach(() => {
console.log(mockedStaticQuery);
mockedStaticQuery.mockImplementationOnce(({ render }) => render(props));
mockedUseStaticQuery.mockReturnValue(props);
});

View File

@ -3,7 +3,7 @@ import Helmet from "react-helmet";
import { useSiteMetadata } from "@/hooks";
import styles from "./Layout.module.scss";
import * as styles from "./Layout.module.scss";
interface Props {
title: string;
@ -12,7 +12,12 @@ interface Props {
children: React.ReactNode;
}
const Layout: React.FC<Props> = ({ children, title, description, socialImage = "" }: Props) => {
const Layout: React.FC<Props> = ({
children,
title,
description,
socialImage = "",
}: Props) => {
const { author, url } = useSiteMetadata();
const metaImage = socialImage || author.photo;
const metaImageUrl = url + metaImage;

View File

@ -1,9 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Layout renders correctly 1`] = `
<div
className="layout"
>
<div>
test
</div>
`;

View File

@ -4,11 +4,11 @@
.page {
@include margin-bottom(2);
&__inner {
padding: 25px 20px;
.inner {
@include padding(1, 0.75, 0);
}
&__title {
.title {
font-size: $typographic-base-font-size * 2.5;
font-weight: 600;
@include line-height(2);
@ -16,7 +16,7 @@
@include margin-bottom(1.45);
}
&__body {
.body {
font-size: $typographic-base-font-size;
@include line-height(1);
@include margin(0, 0, 1);
@ -27,8 +27,8 @@
.page {
lost-column: 7/12;
&__inner {
padding: 30px 20px;
.inner {
@include padding(1.25, 0.75, 0);
}
}
}
@ -37,8 +37,8 @@
.page {
lost-column: 2/3;
&__inner {
padding: 40px 35px;
.inner {
@include padding(1.5, 1, 0);
}
}
}

View File

@ -1,15 +1,16 @@
import React from "react";
import renderer from "react-test-renderer";
import Page from "./Page";
import { Page } from "@/components/Page";
import * as mocks from "@/mocks";
describe("Page", () => {
it("renders correctly", () => {
const props = {
children: "test",
title: "test",
children: mocks.markdownRemark.html,
title: mocks.markdownRemark.frontmatter.title,
};
it("renders correctly", () => {
const tree = renderer
.create(<Page {...props}>{props.children}</Page>)
.toJSON();

View File

@ -2,7 +2,7 @@ import React, { useEffect, useRef } from "react";
import type { Nullable } from "@/types";
import styles from "./Page.module.scss";
import * as styles from "./Page.module.scss";
interface Props {
title?: string;
@ -20,9 +20,9 @@ const Page: React.FC<Props> = ({ title, children }: Props) => {
return (
<div ref={pageRef} className={styles.page}>
<div className={styles.page__inner}>
{title && <h1 className={styles.page__title}>{title}</h1>}
<div className={styles.page__body}>{children}</div>
<div className={styles.inner}>
{title && <h1 className={styles.title}>{title}</h1>}
<div className={styles.body}>{children}</div>
</div>
</div>
);

View File

@ -1,21 +1,13 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Page renders correctly 1`] = `
<div
className="page"
>
<div
className="page__inner"
>
<h1
className="page__title"
>
test
<div>
<div>
<h1>
Perfecting the Art of Perfection
</h1>
<div
className="page__body"
>
test
<div>
&lt;p&gt;An Essay on Typography by Eric Gill takes the reader back to the year 1930. The year when a conflict between two worlds came to its term. The machines of the industrial world finally took over the handicrafts.&lt;/p&gt;
</div>
</div>
</div>

View File

@ -4,14 +4,14 @@
@import "../../assets/scss/mixins";
.pagination {
@include margin-top(2);
display: flex;
@include margin-top(2);
&__prev {
.previous {
text-align: left;
width: 50%;
&-link {
.previousLink {
color: $color-secondary;
font-size: 26px;
font-weight: bold;
@ -21,18 +21,18 @@
color: $color-primary;
}
&--disable {
color: color.adjust($color-gray, 20%);
&.disable {
color: color.adjust($color-gray, $whiteness: 20%);
pointer-events: none;
}
}
}
&__next {
.next {
text-align: right;
width: 50%;
&-link {
.nextLink {
color: $color-secondary;
font-size: 26px;
font-weight: bold;
@ -42,8 +42,8 @@
color: $color-primary;
}
&--disable {
color: color.adjust($color-gray, 20%);
&.disable {
color: color.adjust($color-gray, $whiteness: 20%);
pointer-events: none;
}
}

View File

@ -1,16 +1,12 @@
import React from "react";
import renderer from "react-test-renderer";
import Pagination from "./Pagination";
import { Pagination } from "@/components/Pagination";
import * as mocks from "@/mocks";
describe("Pagination", () => {
const props = {
prevPagePath: "/page/1",
nextPagePath: "/page/3",
hasNextPage: true,
hasPrevPage: true,
};
it("renders correctly", () => {
const props = { ...mocks.pageContext.pagination };
const tree = renderer.create(<Pagination {...props} />).toJSON();
expect(tree).toMatchSnapshot();
});

View File

@ -1,11 +1,11 @@
import React from "react";
import classNames from "classnames/bind";
import classNames from "classnames";
import { Link } from "gatsby";
import { PAGINATION } from "@/constants";
import styles from "./Pagination.module.scss";
import * as styles from "./Pagination.module.scss";
type Props = {
prevPagePath: string;
@ -14,27 +14,23 @@ type Props = {
hasPrevPage: boolean;
};
const cx = classNames.bind(styles);
const Pagination = ({
prevPagePath,
nextPagePath,
hasNextPage,
hasPrevPage,
}: Props) => {
const prevClassName = cx({
"pagination__prev-link": true,
"pagination__prev-link--disable": !hasPrevPage,
const prevClassName = classNames(styles.previousLink, {
[styles.disable]: !hasPrevPage,
});
const nextClassName = cx({
"pagination__next-link": true,
"pagination__next-link--disable": !hasNextPage,
const nextClassName = classNames(styles.nextLink, {
[styles.disable]: !hasNextPage,
});
return (
<div className={styles["pagination"]}>
<div className={styles["pagination__prev"]}>
<div className={styles.pagination}>
<div className={styles.previous}>
<Link
rel="prev"
to={hasPrevPage ? prevPagePath : "/"}
@ -43,7 +39,7 @@ const Pagination = ({
{PAGINATION.PREV_PAGE}
</Link>
</div>
<div className={styles["pagination__next"]}>
<div className={styles.next}>
<Link
rel="next"
to={hasNextPage ? nextPagePath : "/"}

View File

@ -1,26 +1,20 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Pagination renders correctly 1`] = `
<div
className="pagination"
>
<div
className="pagination__prev"
>
<div>
<div>
<a
className="pagination__prev-link"
href="/page/1"
className=""
href="/typography/page/1"
rel="prev"
>
← PREV
</a>
</div>
<div
className="pagination__next"
>
<div>
<a
className="pagination__next-link"
href="/page/3"
className=""
href="/typography/page/3"
rel="next"
>
→ NEXT

View File

@ -4,13 +4,13 @@
.author {
border-top: 1px solid $color-gray-border;
max-width: $layout-post-width;
padding-top: 20px;
@include padding-top(1);
@include line-height(1);
@include margin-top(1);
@include margin-bottom(2);
&__bio {
&-twitter {
.bio {
.twitter {
display: block;
text-decoration: underline;
}

View File

@ -10,11 +10,11 @@ const mockedStaticQuery = StaticQuery as jest.Mock;
const mockedUseStaticQuery = useStaticQuery as jest.Mock;
describe("Author", () => {
console.log(mockedStaticQuery);
beforeEach(() => {
mockedStaticQuery.mockImplementationOnce(({ render }) =>
render(mocks.siteMetadata),
);
mockedUseStaticQuery.mockReturnValue(mocks.siteMetadata);
});

View File

@ -3,17 +3,17 @@ import React from "react";
import { useSiteMetadata } from "@/hooks";
import { getContactHref } from "@/utils";
import styles from "./Author.module.scss";
import * as styles from "./Author.module.scss";
const Author = () => {
const { author } = useSiteMetadata();
return (
<div className={styles.author}>
<p className={styles.author__bio}>
<p className={styles.bio}>
{author.bio}
<a
className={styles["author__bio-twitter"]}
className={styles.twitter}
href={getContactHref("twitter", author.contacts.twitter)}
rel="noopener noreferrer"
target="_blank"

View File

@ -1,15 +1,10 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Author renders correctly 1`] = `
<div
className="author"
>
<p
className="author__bio"
>
<div>
<p>
Pellentesque odio nisi, euismod in, pharetra a, ultricies in, diam. Sed arcu.
<a
className="author__bio-twitter"
href="https://www.twitter.com/#"
rel="noopener noreferrer"
target="_blank"

View File

@ -14,15 +14,16 @@ describe("Comments", () => {
mockedStaticQuery.mockImplementationOnce(({ render }) =>
render(mocks.siteMetadata),
);
mockedUseStaticQuery.mockReturnValue(mocks.siteMetadata);
});
it("renders correctly", () => {
const props = {
postTitle: "test",
postSlug: "/test",
postTitle: mocks.markdownRemark.frontmatter.title,
postSlug: mocks.markdownRemark.fields.slug,
};
it("renders correctly", () => {
const tree = renderer.create(<Comments {...props} />).toJSON();
expect(tree).toMatchSnapshot();
});

View File

@ -2,11 +2,11 @@
@import "../../../assets/scss/mixins";
.content {
margin: 0 auto;
@include margin-auto();
max-width: $layout-post-single-width;
padding: 0 15px;
@include padding(0, 0.5);
&__title {
.title {
font-size: $typographic-base-font-size * 2;
font-weight: 600;
margin-left: auto;
@ -18,37 +18,41 @@
@include margin-bottom(0);
}
&__body {
& figure {
.body {
figure {
@include margin-bottom(1);
& blockquote {
blockquote {
font-style: italic;
margin-top: 0;
text-align: center;
@include margin-top(0);
@include padding(1, 0);
& p {
p {
font-size: $typographic-base-font-size * 1.6817;
margin-top: 0;
max-width: $layout-post-width;
@include margin-top(0);
@include margin-bottom(1);
@include line-height(1.5);
}
}
}
& a {
a {
text-decoration: underline;
}
& * {
* {
margin-left: auto;
margin-right: auto;
max-width: $layout-post-width;
}
& img {
h2 > a {
visibility: hidden;
}
img {
max-width: 100%;
}
}
@ -56,25 +60,30 @@
@include breakpoint-md {
.content {
padding: 0;
@include padding-equal(0);
&__title {
.title {
font-size: $typographic-base-font-size * 3;
@include line-height(2.25);
@include margin-top(2.25);
@include margin-bottom(1.5);
}
&__body {
.body {
font-size: $typographic-base-font-size * 1.125;
@include line-height(1.125);
@include margin-bottom(1.125);
& p {
p {
font-size: $typographic-base-font-size * 1.125;
@include line-height(1.125);
@include margin-bottom(1.125);
}
h2 > a {
visibility: unset;
@include padding-right(1);
}
}
}
}

View File

@ -2,10 +2,15 @@ import React from "react";
import renderer from "react-test-renderer";
import { Content } from "@/components/Post/Content";
import * as mocks from "@/mocks";
describe("Content", () => {
it("renders correctly", () => {
const props = { title: "test", body: "<p>test</p>" };
const props = {
title: mocks.markdownRemark.frontmatter.title,
body: mocks.markdownRemark.html,
};
const tree = renderer.create(<Content {...props} />).toJSON();
expect(tree).toMatchSnapshot();
});

View File

@ -1,6 +1,6 @@
import React from "react";
import styles from "./Content.module.scss";
import * as styles from "./Content.module.scss";
interface Props {
title: string;
@ -9,11 +9,8 @@ interface Props {
const Content: React.FC<Props> = ({ body, title }: Props) => (
<div className={styles.content}>
<h1 className={styles.content__title}>{title}</h1>
<div
className={styles.content__body}
dangerouslySetInnerHTML={{ __html: body }}
/>
<h1 className={styles.title}>{title}</h1>
<div className={styles.body} dangerouslySetInnerHTML={{ __html: body }} />
</div>
);

View File

@ -1,19 +1,14 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Content renders correctly 1`] = `
<div
className="content"
>
<h1
className="content__title"
>
test
<div>
<h1>
Perfecting the Art of Perfection
</h1>
<div
className="content__body"
dangerouslySetInnerHTML={
Object {
"__html": "<p>test</p>",
"__html": "<p>An Essay on Typography by Eric Gill takes the reader back to the year 1930. The year when a conflict between two worlds came to its term. The machines of the industrial world finally took over the handicrafts.</p>",
}
}
/>

View File

@ -2,7 +2,7 @@
@import "../../../assets/scss/mixins";
.meta {
&__date {
.date {
font-style: italic;
}
}

View File

@ -2,10 +2,13 @@ import React from "react";
import renderer from "react-test-renderer";
import { Meta } from "@/components/Post/Meta";
import * as mocks from "@/mocks";
describe("Meta", () => {
it("renders correctly", () => {
const props = { date: "2016-09-01" };
const props = {
date: mocks.markdownRemark.frontmatter.date,
};
const tree = renderer.create(<Meta {...props} />).toJSON();
expect(tree).toMatchSnapshot();

View File

@ -1,6 +1,6 @@
import React from "react";
import styles from "./Meta.module.scss";
import * as styles from "./Meta.module.scss";
interface Props {
date: string;
@ -8,7 +8,7 @@ interface Props {
const Meta: React.FC<Props> = ({ date }: Props) => (
<div className={styles.meta}>
<p className={styles.meta__date}>
<p className={styles.date}>
Published{" "}
{new Date(date).toLocaleDateString("en-US", {
year: "numeric",

View File

@ -1,12 +1,8 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Meta renders correctly 1`] = `
<div
className="meta"
>
<p
className="meta__date"
>
<div>
<p>
Published
Sep 1, 2016

View File

@ -2,19 +2,23 @@
@import "../../assets/scss/mixins";
.post {
&__footer {
margin: 0 auto;
max-width: $layout-post-width;
padding: 0 15px;
.content {
@include margin-auto();
}
&__comments {
margin: 0 auto;
.footer {
max-width: $layout-post-width;
padding: 0 15px;
@include padding(0, 0.5);
@include margin-auto();
}
&__home-button {
.comments {
max-width: $layout-post-width;
@include padding(0, 0.5);
@include margin-auto();
}
.button {
border: 1px solid $color-gray-border;
border-radius: $button-border-radius;
color: $color-base;
@ -26,8 +30,8 @@
margin-left: auto;
margin-right: auto;
max-width: 90px;
padding: 0 24px;
text-align: center;
@include padding(0, 1);
@include margin-top(1);
&:hover,
@ -39,20 +43,20 @@
@include breakpoint-md {
.post {
&__footer {
padding: 0;
.footer {
@include padding-equal(0);
}
&__comments {
padding: 0;
.comments {
@include padding-equal(0);
}
&__home-button {
.button {
left: 30px;
margin: 0;
max-width: auto;
max-width: none;
position: fixed;
top: 30px;
@include margin-equal(0);
}
}
}

View File

@ -17,24 +17,8 @@ describe("Post", () => {
mockedUseStaticQuery.mockReturnValue(mocks.siteMetadata);
});
const props = {
post: {
id: "test-123",
html: "<p>test</p>",
fields: {
slug: "/test",
categorySlug: "/test-category",
tagSlugs: ["/test_0", "/test_1"],
},
frontmatter: {
date: "2016-09-01",
tags: ["test_0", "test_1"],
title: "test",
},
},
};
it("renders correctly", () => {
const props = { post: mocks.markdownRemark };
const tree = renderer.create(<Post {...props} />).toJSON();
expect(tree).toMatchSnapshot();
});

View File

@ -10,7 +10,7 @@ import { Content } from "./Content";
import { Meta } from "./Meta";
import { Tags } from "./Tags";
import styles from "./Post.module.scss";
import * as styles from "./Post.module.scss";
interface Props {
post: Node;
@ -23,21 +23,21 @@ const Post: React.FC<Props> = ({ post }: Props) => {
return (
<div className={styles.post}>
<Link className={styles["post__home-button"]} to="/">
<Link className={styles.button} to="/">
All Articles
</Link>
<div className={styles.post__content}>
<div className={styles.content}>
<Content body={html} title={title} />
</div>
<div className={styles.post__footer}>
<div className={styles.footer}>
<Meta date={date} />
{tags && tagSlugs && <Tags tags={tags} tagSlugs={tagSlugs} />}
<Author />
</div>
<div className={styles.post__comments}>
<div className={styles.comments}>
<Comments postSlug={slug} postTitle={post.frontmatter.title} />
</div>
</div>

View File

@ -4,24 +4,30 @@
.tags {
@include margin-bottom(0.5);
&__list {
.list {
list-style: none;
margin: 0 -10px;
padding: 0;
@include padding-equal(0);
&-item {
.item {
display: inline-block;
margin: 10px 5px;
@include margin(0.5, 0.125);
&-link {
@include breakpoint-sm {
&:first-child {
@include margin-left(0);
@include padding-left(0);
}
}
.link {
border: 1px solid $color-gray-border;
border-radius: $button-border-radius;
color: $color-base;
display: inline-block;
height: $button-height;
line-height: $button-height;
padding: 0 24px;
text-decoration: none;
@include padding(0, 0.75);
&:hover,
&:focus {

View File

@ -2,13 +2,15 @@ import React from "react";
import renderer from "react-test-renderer";
import { Tags } from "@/components/Post/Tags";
import * as mocks from "@/mocks";
describe("Tags", () => {
it("renders correctly", () => {
const props = {
tags: ["test_0", "test_1"],
tagSlugs: ["/test_0", "/test_1"],
tags: mocks.markdownRemark.frontmatter.tags,
tagSlugs: mocks.markdownRemark.fields.tagsSlugs,
};
const tree = renderer.create(<Tags {...props} />).toJSON();
expect(tree).toMatchSnapshot();
});

View File

@ -1,6 +1,8 @@
import React from "react";
import { Link } from "gatsby";
import styles from "./Tags.module.scss";
import * as styles from "./Tags.module.scss";
type Props = {
tags: string[];
@ -8,16 +10,17 @@ type Props = {
};
const Tags = ({ tags, tagSlugs }: Props) => (
<div className={styles["tags"]}>
<ul className={styles["tags__list"]}>
{tagSlugs &&
tagSlugs.map((slug, i) => (
<li className={styles["tags__list-item"]} key={tags[i]}>
<Link to={slug} className={styles["tags__list-item-link"]}>
<div className={styles.tags}>
<ul className={styles.list}>
{tagSlugs
? tagSlugs.map((slug, i) => (
<li className={styles.item} key={slug}>
<Link to={slug} className={styles.link}>
{tags[i]}
</Link>
</li>
))}
))
: null}
</ul>
</div>
);

View File

@ -1,30 +1,20 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Tags renders correctly 1`] = `
<div
className="tags"
>
<ul
className="tags__list"
>
<li
className="tags__list-item"
>
<div>
<ul>
<li>
<a
className="tags__list-item-link"
href="/test_0"
href="/handwriting"
>
test_0
Handwriting
</a>
</li>
<li
className="tags__list-item"
>
<li>
<a
className="tags__list-item-link"
href="/test_1"
href="/helvetica"
>
test_1
Helvetica
</a>
</li>
</ul>

View File

@ -1,87 +1,38 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Post renders correctly 1`] = `
<div
className="post"
>
<div>
<a
className="post__home-button"
href="/"
>
All Articles
</a>
<div
className="post__content"
>
<div
className="content"
>
<h1
className="content__title"
>
test
<div>
<div>
<h1>
Perfecting the Art of Perfection
</h1>
<div
className="content__body"
dangerouslySetInnerHTML={
Object {
"__html": "<p>test</p>",
"__html": "<p>An Essay on Typography by Eric Gill takes the reader back to the year 1930. The year when a conflict between two worlds came to its term. The machines of the industrial world finally took over the handicrafts.</p>",
}
}
/>
</div>
</div>
<div
className="post__footer"
>
<div
className="meta"
>
<p
className="meta__date"
>
<div>
<div>
<p>
Published
Sep 1, 2016
</p>
</div>
<div
className="tags"
>
<ul
className="tags__list"
>
<li
className="tags__list-item"
>
<a
className="tags__list-item-link"
href="/test_0"
>
test_0
</a>
</li>
<li
className="tags__list-item"
>
<a
className="tags__list-item-link"
href="/test_1"
>
test_1
</a>
</li>
</ul>
</div>
<div
className="author"
>
<p
className="author__bio"
>
<div>
<p>
Pellentesque odio nisi, euismod in, pharetra a, ultricies in, diam. Sed arcu.
<a
className="author__bio-twitter"
href="https://www.twitter.com/#"
rel="noopener noreferrer"
target="_blank"
@ -94,8 +45,6 @@ exports[`Post renders correctly 1`] = `
</p>
</div>
</div>
<div
className="post__comments"
/>
<div />
</div>
`;

View File

@ -2,20 +2,22 @@
@import "../../../assets/scss/mixins";
.author {
&__photo {
.photo {
background-clip: padding-box;
border-radius: 50%;
display: inline-block;
margin-bottom: 0;
height: 75px;
width: 75px;
@include margin-bottom(0);
}
&__title {
.title {
font-size: $typographic-base-font-size * 1.125;
font-weight: 600;
@include line-height(1.125);
@include margin(0.5, 0, 0.5, 0);
&-link {
.link {
color: $color-base;
&:hover,
@ -25,7 +27,7 @@
}
}
&__subtitle {
.subtitle {
color: $color-gray;
@include line-height(1);
@include margin-bottom(1);

Some files were not shown because too many files have changed in this diff Show More