├── .editorconfig
├── .eslintignore
├── .eslintrc.js
├── .gitignore
├── .prettierrc
├── .storybook
├── main.js
└── preview.js
├── LICENSE
├── README.md
├── __mocks__
├── file-mock.js
└── gatsby.js
├── gatsby-browser.js
├── gatsby-config.js
├── gatsby-node.js
├── jest-loadershim.ts
├── jest-preprocess.ts
├── jest.config.js
├── package-lock.json
├── package.json
├── src
├── @types
│ └── index.d.ts
├── components
│ ├── button
│ │ ├── __tests__
│ │ │ ├── __snapshots__
│ │ │ │ └── button.test.tsx.snap
│ │ │ └── button.test.tsx
│ │ ├── button.tsx
│ │ └── index.ts
│ ├── code
│ │ ├── __tests__
│ │ │ ├── __snapshots__
│ │ │ │ └── code.test.tsx.snap
│ │ │ └── code.test.tsx
│ │ ├── code.tsx
│ │ └── index.ts
│ ├── css-debugger
│ │ ├── css-debugger.tsx
│ │ └── index.tsx
│ ├── footer
│ │ ├── footer.tsx
│ │ └── index.ts
│ ├── github-icon
│ │ ├── __tests__
│ │ │ ├── __snapshots__
│ │ │ │ └── github-icon.test.tsx.snap
│ │ │ └── github-icon.test.tsx
│ │ ├── github-icon.tsx
│ │ └── index.ts
│ ├── layout
│ │ ├── index.ts
│ │ └── layout.tsx
│ ├── link
│ │ ├── __tests__
│ │ │ ├── __snapshots__
│ │ │ │ └── link.test.tsx.snap
│ │ │ └── link.test.tsx
│ │ ├── index.ts
│ │ └── link.tsx
│ └── seo
│ │ ├── __tests__
│ │ ├── __snapshots__
│ │ │ └── seo.test.tsx.snap
│ │ └── seo.test.tsx
│ │ ├── index.ts
│ │ └── seo.tsx
├── images
│ ├── github-icon.png
│ └── icon.png
├── pages
│ ├── 404.tsx
│ ├── about.tsx
│ └── index.tsx
├── stories
│ └── index.stories.tsx
└── styles
│ ├── global-styles.tsx
│ ├── index.ts
│ └── theme.tsx
├── static
├── favicon.ico
└── icons
│ ├── apple-touch-icon.png
│ ├── icon_192x192.png
│ └── icon_512x512.png
└── tsconfig.json
/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | end_of_line = lf
7 | indent_size = 2
8 | indent_style = space
9 | insert_final_newline = true
10 | max_line_length = 80
11 | trim_trailing_whitespace = true
12 |
13 | [*.md]
14 | max_line_length = 0
15 | trim_trailing_whitespace = false
16 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | # gatsby files
2 | .cache/*
3 | node_modules/*
4 | public/*
5 | .storybook/*
6 | @types
7 | __mocks__
8 | __tests__
9 |
10 | gatsby-*.js
11 | loadershim.ts
12 | stories/*
13 |
14 | jest*.js
15 | gatsby*.ts
16 | jest*.ts
17 | *.test.*
18 | *.spec.*
19 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: [
3 | "react-app", // See below
4 | "plugin:functional/recommended",
5 | "plugin:prettier/recommended", // Should always be last. Enables eslint-plugin-prettier and eslint-config-prettier. This will display prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array.
6 | ],
7 | plugins: ["functional"],
8 | rules: {
9 | "@typescript-eslint/explicit-function-return-type": "off", // This rule prevents you from letting React component return types be inferred.
10 | "functional/no-expression-statement": "off", // This rule causes an error with ReactDOM.render()
11 | "functional/prefer-readonly-type": "off", // Off for now. Do we want to have to annotate everything with readonly? To be discussed.
12 | "functional/functional-parameters": "off", // This rule breaks things like the useEffect, which takes a callback with no parameters.
13 | "functional/no-mixed-type": "off", // This rules doesn't allow you to create a type alias for a component that mixes methods and values.
14 | "functional/prefer-type-literal": "off", // Interfaces are fine. Some people prefer to extend.
15 | "functional/no-conditional-statement": "off", // if statements are useful and quite nice for conditional component rendering logic.
16 | "functional/no-return-void": "off", // In React, you are often returning void. i.e. useState setters
17 | "functional/no-try-statement": "off", // What's wrong with a try/catch? They are very useful with async/await.
18 | },
19 | };
20 |
21 | /**
22 | * eslint-config-react-app
23 | * Docs:
24 | * https://www.npmjs.com/package/eslint-config-react-app
25 | *
26 | * Source:
27 | * https://github.com/facebook/create-react-app/blob/master/packages/eslint-config-react-app/index.js
28 | * This is a default eslint configuration created and maintained the Facebook team,
29 | * primarily for use with create-react-app.
30 | * This default configuration is well thought-out and actively maintained. It includes sensible rules for
31 | * React-specific apps, including hooks usage. It also includes accessibility rules via react-a11y as
32 | * well as rules for import statements and a few other niceties.
33 | */
34 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 | *.pid.lock
13 |
14 | # Directory for instrumented libs generated by jscoverage/JSCover
15 | lib-cov
16 |
17 | # Coverage directory used by tools like istanbul
18 | coverage
19 |
20 | # nyc test coverage
21 | .nyc_output
22 |
23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24 | .grunt
25 |
26 | # Bower dependency directory (https://bower.io/)
27 | bower_components
28 |
29 | # node-waf configuration
30 | .lock-wscript
31 |
32 | # Compiled binary addons (http://nodejs.org/api/addons.html)
33 | build/Release
34 |
35 | # Dependency directories
36 | node_modules/
37 | jspm_packages/
38 |
39 | # Typescript v1 declaration files
40 | typings/
41 |
42 | # Optional npm cache directory
43 | .npm
44 |
45 | # Optional eslint cache
46 | .eslintcache
47 |
48 | # Optional REPL history
49 | .node_repl_history
50 |
51 | # Output of 'npm pack'
52 | *.tgz
53 |
54 | # dotenv environment variables file
55 | .env
56 |
57 | # gatsby files
58 | .cache/
59 | public
60 |
61 | # Mac files
62 | .DS_Store
63 |
64 | .pnp/
65 | .pnp.js
66 | # Yarn Integrity file
67 | .yarn-integrity
68 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "endOfLine": "lf",
3 | "semi": true,
4 | "singleQuote": false,
5 | "tabWidth": 2,
6 | "trailingComma": "es5"
7 | }
8 |
--------------------------------------------------------------------------------
/.storybook/main.js:
--------------------------------------------------------------------------------
1 |
2 | module.exports = {
3 | stories: ['../**/*.stories.tsx'],
4 | addons: [
5 | "@storybook/addon-links",
6 | "@storybook/addon-knobs",
7 | "@storybook/addon-actions"
8 | ],
9 | webpackFinal: async (config, { configType }) => {
10 | // `configType` has a value of 'DEVELOPMENT' or 'PRODUCTION'
11 | // You can change the configuration based on that.
12 | // 'PRODUCTION' is used when building the static version of storybook.
13 |
14 | // Make whatever fine-grained changes you need
15 | // Transpile Gatsby module because Gatsby includes un-transpiled ES6 code.
16 | config.module.rules[0].exclude = [/node_modules\/(?!(gatsby)\/)/];
17 |
18 | // use installed babel-loader which is v8.0-beta (which is meant to work with @babel/core@7)
19 | config.module.rules[0].use[0].loader = require.resolve("babel-loader");
20 |
21 | // use @babel/preset-react for JSX and env (instead of staged presets)
22 | config.module.rules[0].use[0].options.presets = [
23 | require.resolve("babel-preset-gatsby"),
24 | require.resolve("@babel/preset-react"),
25 | require.resolve("@babel/preset-env"),
26 | ];
27 |
28 | // use @babel/plugin-proposal-class-properties for class arrow functions
29 | config.module.rules[0].use[0].options.plugins = [
30 | require.resolve("@babel/plugin-proposal-class-properties"),
31 | ];
32 |
33 | // Prefer Gatsby ES6 entrypoint (module) over commonjs (main) entrypoint
34 | config.resolve.mainFields = ["browser", "module", "main"];
35 | config.module.rules.push({
36 | test: /\.(ts|tsx)$/,
37 | loader: require.resolve("babel-loader"),
38 | options: {
39 | presets: [["react-app", { flow: false, typescript: true }]],
40 | plugins: ["babel-plugin-styled-components"],
41 | },
42 | });
43 |
44 | config.resolve.extensions.push(".ts", ".tsx");
45 | return config;
46 | // Return the altered config
47 | return config;
48 | },
49 | }
50 |
--------------------------------------------------------------------------------
/.storybook/preview.js:
--------------------------------------------------------------------------------
1 | import { action } from "@storybook/addon-actions";
2 |
3 | // Gatsby's Link overrides:
4 | // Gatsby defines a global called ___loader to prevent its method calls from creating console errors you override it here
5 | global.___loader = {
6 | enqueue: () => {},
7 | hovering: () => {},
8 | };
9 | // Gatsby internal mocking to prevent unnecessary errors in storybook testing environment
10 | global.__PATH_PREFIX__ = "";
11 | // This is to utilized to override the window.___navigate method Gatsby defines and uses to report what path a Link would be taking us to if it wasn't inside a storybook
12 | window.___navigate = pathname => {
13 | action("NavigateTo:")(pathname);
14 | };
15 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 gatsbyjs
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # gatsby-starter-typescript-deluxe 🌟
2 |
3 | ### An opinionated starter library for creating React applications with Gatsby and TypeScript.
4 |
5 | ### [View Demo](https://gatsby-starter-typescript-deluxe.netlify.com) [](https://app.netlify.com/sites/gatsby-starter-typescript-deluxe/deploys)
6 |
7 | This starter library is pre-configured with the following integrations:
8 |
9 | - **TypeScript** for type-safe code.
10 | - **Styled-Components** for all your styles.
11 | - **modern-css-reset** for a reset of sensible default styles.
12 | - **Framer Motion** for awesome animations.
13 | - **gatsby-image and gatsby-transformer-sharp** for optimized images.
14 | - **gatsby-plugin-manifest / SEO component** for an SEO-friendly PWA.
15 | - **Storybook with add-ons** for showing off your awesome components.
16 | - **Jest and React Testing library** for snapshots and unit tests.
17 | - **ESLint with an emphasis on functional patterns (with Prettier and TypeScript integration)** to make your code look its best.
18 | - **React Axe and React A11y for accessibility** so that your site is awesome for everyone.
19 |
20 | ## Installation
21 |
22 | You will need to have `node` and `npm` installed on your computer.
23 |
24 | You can either use `npx` or install the `gatsby-cli` globally.
25 |
26 | The `npx` way:
27 |
28 | ```sh
29 | npx gatsby new my-site https://github.com/gojutin/gatsby-starter-typescript-deluxe
30 | ```
31 |
32 | or the global way:
33 |
34 | ```sh
35 | npm i -g gatsby-cli
36 | gatsby new my-site https://github.com/gojutin/gatsby-starter-typescript-deluxe
37 | ```
38 |
39 | ## Usage
40 |
41 | To start the development servers:
42 |
43 | ```sh
44 | npm run develop
45 | ```
46 |
47 | If all was successful, you should see links to two development servers in the Node terminal. You can open these url in any browser that you would like.
48 |
49 | 1. [http://localhost:8080](http://localhost:8080):
50 |
51 | This is the development server that allows you to preview your website. It comes with hot-module reloading, which means that you should see your changes almost immediately without having to refresh the browser tab.
52 |
53 | 2. [http://localhost:8000/\_\_\_graphql](http://localhost:8000/___graphql):
54 |
55 | This is the development server that allows you to interact with the your site's GraphQL data via the GraphiQL IDE.
56 |
57 | ### Available Scripts
58 |
59 | | Script | Description |
60 | | ----------------- | :---------------------------------------------------------------------------------- |
61 | | `develop` | Start the development server with hot module reloading. |
62 | | `dev` | Alias for `develop`. |
63 | | `format` | Format your code with Prettier. |
64 | | `clean` | Delete the `.cache` and `public` directories. |
65 | | `test` | Run your Jest tests once. |
66 | | `test:watch` | Run your Jest tests in watch mode. |
67 | | `lint` | Lint your code with ESLint. |
68 | | `lint:watch` | Lint your code with ESLint in watch mode. |
69 | | `lint:fix` | Lint your code with ESLint and attempt to fix linting issues. |
70 | | `serve` | Serve the production build of your site for testing. |
71 | | `build` | Compile your application and make it ready for deployment |
72 | | `storybook` | Starts Storybook. |
73 | | `build-storybook` | Compiles your stories and makes them ready for deployment. |
74 | | `update` | Updates the package.json to the latest dependency versions using npm-check-updates. |
75 |
76 | ## Styling
77 |
78 | This library is pre-configured with [styled-components](https://www.styled-components.com/).
79 |
80 | #### Global Styles
81 |
82 | Global styles are defined in the `src/styles/global-styles.tsx` file using the `createGlobalStyle` function provided by styled-components. The global styles are injected in the `Layout` component via the component that is provided from the `createGlobalStyle` function.
83 |
84 | The global style also includes the styles from [css-modern-reset](https://github.com/hankchizljaw/modern-css-reset), which aims to provide a sensible reset of browser styles.
85 |
86 | #### Theme
87 |
88 | You can define your theme styles in the `/src/styles/theme` file. The theme will be available in any styled-component via `props.theme` and to any other component via the `useTheme` hook.
89 |
90 | #### Handling Media Queries
91 |
92 | The theme utilizes the [use-media](https://github.com/streamich/use-media) library, which allows you to track the state of a CSS media queries. This works by passing a boolean for each screen size that you defined in your theme. Just define your screen sizes in `src/styles/theme`.
93 |
94 | #### Styling Examples
95 |
96 | **`src/pages/about.tsx` includes various examples (with comments) of using styled-components and framer-motion with the theme provider.**
97 |
98 | #### The CSS Prop
99 |
100 | This starter is also preconfigured to work with the `css` prop:
101 |
102 | ```jsx
103 | import styled from "styled-components";
104 |
105 | const MyComponent = () => (
106 |
107 |
112 | Hello World!
113 |
114 |
115 | );
116 | ```
117 |
118 | _Note: The `css` prop does not play nicely with the `jsx-no-multiline-js` ESLint rule. You may want to disable the rule if you plan on using the `css` prop. This can be done in the `.eslintrc.js` file._
119 |
120 | I personally do not use the `css` prop and prefer to define styled-components outside of the component definition. My general rule is if the component that is using a styled-component is the only component that uses it, I define the styled-component in the same file. Otherwise, I will move it out to a `components/common` directory.
121 |
122 | ```tsx
123 | import styled from "styled-components";
124 |
125 | const Heading = styled.h1`
126 | color: #333;
127 | `;
128 |
129 | const MyComponent = () => (
130 |