refactor(starter): upgrade and move to typescript
@ -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,13 +56,12 @@ 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
|
||||
test:
|
||||
|
@ -7,3 +7,4 @@ indent_size = 2
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
css
|
||||
|
10
.eslintrc
@ -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
@ -15,6 +15,9 @@ pids
|
||||
# build
|
||||
public
|
||||
|
||||
# cache
|
||||
.cache
|
||||
|
||||
# directory for instrumented libs generated by jscoverage
|
||||
lib-cov
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
*.*
|
||||
!*.scss
|
||||
!*.json
|
||||
!*.md
|
||||
!*.mdx
|
||||
|
@ -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
|
||||
|
2
LICENSE
@ -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
@ -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 site’s 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
|
||||
|
@ -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": "",
|
||||
|
@ -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 |
Before Width: | Height: | Size: 383 KiB |
@ -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._
|
||||
|
Before Width: | Height: | Size: 97 KiB After Width: | Height: | Size: 97 KiB |
Before Width: | Height: | Size: 112 KiB After Width: | Height: | Size: 112 KiB |
@ -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._
|
||||
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 32 KiB |
@ -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.
|
||||
|
After Width: | Height: | Size: 97 KiB |
@ -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)
|
@ -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 |
Before Width: | Height: | Size: 350 KiB After Width: | Height: | Size: 350 KiB |
@ -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
|
||||
|
Before Width: | Height: | Size: 645 KiB After Width: | Height: | Size: 645 KiB |
Before Width: | Height: | Size: 151 KiB After Width: | Height: | Size: 151 KiB |
Before Width: | Height: | Size: 546 KiB After Width: | Height: | Size: 546 KiB |
Before Width: | Height: | Size: 273 KiB After Width: | Height: | Size: 273 KiB |
Before Width: | Height: | Size: 656 KiB After Width: | Height: | Size: 656 KiB |
Before Width: | Height: | Size: 115 KiB After Width: | Height: | Size: 115 KiB |
1
gatsby-browser.ts
Normal file
@ -0,0 +1 @@
|
||||
import "./src/assets/scss/main.scss";
|
@ -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 {
|
||||
path
|
||||
}
|
||||
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",
|
||||
],
|
||||
};
|
@ -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
@ -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";
|
@ -1,8 +1,8 @@
|
||||
const routes = Object.freeze({
|
||||
notFoundRoute: "/404",
|
||||
categoriesListRoute: "/categories",
|
||||
categoryRoute: "/category",
|
||||
tagsListRoute: "/tags",
|
||||
notFoundRoute: "/404",
|
||||
tagRoute: "/tag",
|
||||
indexRoute: "/",
|
||||
});
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
25
internal/gatsby/on-create-webpack-config.ts
Normal 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 };
|
@ -12,7 +12,9 @@ const metadataQuery = async (graphql: CreatePagesArgs["graphql"]) => {
|
||||
const result = await graphql<MetadataQueryResult>(`
|
||||
query SiteMetaData {
|
||||
site {
|
||||
postsLimit
|
||||
siteMetadata {
|
||||
postsLimit
|
||||
}
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
@ -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>;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,10 @@
|
||||
const toKebabCase = (str: string = ""): string => str.toLowerCase()
|
||||
.replace(/[^\w\s]/gi, "")
|
||||
.split(" ").join("-")
|
||||
.split("_").join("-");
|
||||
const toKebabCase = (str: string = ""): string =>
|
||||
str
|
||||
.toLowerCase()
|
||||
.replace(/[^\w\s]/gi, "")
|
||||
.split(" ")
|
||||
.join("-")
|
||||
.split("_")
|
||||
.join("-");
|
||||
|
||||
export default toKebabCase;
|
||||
|
@ -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 world’s first major printed books, the “Forty–Two–Line” 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 };
|
||||
|
@ -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,
|
||||
|
@ -4,5 +4,4 @@ export default {
|
||||
github: "#",
|
||||
twitter: "#",
|
||||
telegram: "#",
|
||||
vkontakte: "#",
|
||||
};
|
||||
|
38
internal/testing/__mocks__/edges.ts
Normal 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 world’s first major printed books, the “Forty–Two–Line” 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 world’s first major printed books, the “Forty–Two–Line” Bible.</p>",
|
||||
},
|
||||
},
|
||||
];
|
10
internal/testing/__mocks__/group.ts
Normal file
@ -0,0 +1,10 @@
|
||||
export default [
|
||||
{
|
||||
fieldValue: "typography",
|
||||
totalCount: 1,
|
||||
},
|
||||
{
|
||||
fieldValue: "design inspiration",
|
||||
totalCount: 1,
|
||||
},
|
||||
];
|
@ -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";
|
||||
|
@ -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>",
|
||||
};
|
||||
|
@ -1,12 +1,10 @@
|
||||
export default {
|
||||
pageContext: {
|
||||
group: "typography",
|
||||
pagination: {
|
||||
currentPage: 2,
|
||||
prevPagePath: "/typography/page/1",
|
||||
nextPagePath: "/typography/page/3",
|
||||
hasNextPage: true,
|
||||
hasPrevPage: true,
|
||||
},
|
||||
group: "typography",
|
||||
pagination: {
|
||||
currentPage: 2,
|
||||
prevPagePath: "/typography/page/1",
|
||||
nextPagePath: "/typography/page/3",
|
||||
hasNextPage: true,
|
||||
hasPrevPage: true,
|
||||
},
|
||||
};
|
||||
|
@ -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"],
|
||||
|
8962
package-lock.json
generated
140
package.json
@ -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"
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -101,8 +101,8 @@ pre[class*="language-"]::selection {
|
||||
color: #b58900;
|
||||
}
|
||||
|
||||
.token.important,
|
||||
.token.regex,
|
||||
.token.important,
|
||||
.token.variable {
|
||||
color: #cb4b16;
|
||||
}
|
||||
|
@ -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"};
|
||||
}
|
||||
}
|
||||
|
@ -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"};
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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();
|
||||
});
|
||||
|
@ -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>
|
||||
|
@ -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 world’s first major printed books, the “Forty–Two–Line” Bible.
|
||||
</p>
|
||||
<a
|
||||
className="feed__item-more"
|
||||
href="/test_1"
|
||||
href="/posts/the-birth-of-movable-type"
|
||||
>
|
||||
Read
|
||||
</a>
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
});
|
||||
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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>
|
||||
`;
|
||||
|
62
src/components/Image/Image.tsx
Normal 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;
|
1
src/components/Image/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export { default as Image } from "./Image";
|
@ -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);
|
||||
});
|
||||
|
@ -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;
|
||||
|
@ -1,9 +1,7 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Layout renders correctly 1`] = `
|
||||
<div
|
||||
className="layout"
|
||||
>
|
||||
<div>
|
||||
test
|
||||
</div>
|
||||
`;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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", () => {
|
||||
const props = {
|
||||
children: "test",
|
||||
title: "test",
|
||||
};
|
||||
|
||||
it("renders correctly", () => {
|
||||
const props = {
|
||||
children: mocks.markdownRemark.html,
|
||||
title: mocks.markdownRemark.frontmatter.title,
|
||||
};
|
||||
|
||||
const tree = renderer
|
||||
.create(<Page {...props}>{props.children}</Page>)
|
||||
.toJSON();
|
||||
|
@ -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>
|
||||
);
|
||||
|
@ -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>
|
||||
<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>
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
});
|
||||
|
@ -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 : "/"}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
});
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -14,15 +14,16 @@ describe("Comments", () => {
|
||||
mockedStaticQuery.mockImplementationOnce(({ render }) =>
|
||||
render(mocks.siteMetadata),
|
||||
);
|
||||
|
||||
mockedUseStaticQuery.mockReturnValue(mocks.siteMetadata);
|
||||
});
|
||||
|
||||
const props = {
|
||||
postTitle: "test",
|
||||
postSlug: "/test",
|
||||
};
|
||||
|
||||
it("renders correctly", () => {
|
||||
const props = {
|
||||
postTitle: mocks.markdownRemark.frontmatter.title,
|
||||
postSlug: mocks.markdownRemark.fields.slug,
|
||||
};
|
||||
|
||||
const tree = renderer.create(<Comments {...props} />).toJSON();
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
});
|
||||
|
@ -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>
|
||||
);
|
||||
|
||||
|
@ -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>",
|
||||
}
|
||||
}
|
||||
/>
|
||||
|
@ -2,7 +2,7 @@
|
||||
@import "../../../assets/scss/mixins";
|
||||
|
||||
.meta {
|
||||
&__date {
|
||||
.date {
|
||||
font-style: italic;
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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",
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
});
|
||||
|
@ -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>
|
||||
|
@ -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 {
|
||||
|
@ -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();
|
||||
});
|
||||
|
@ -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"]}>
|
||||
{tags[i]}
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
<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>
|
||||
);
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
`;
|
||||
|
@ -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);
|
||||
|