├── .editorconfig
├── .eslintignore
├── .eslintrc.json
├── .github
├── dependabot.yml
└── workflows
│ └── ci.yml
├── .gitignore
├── .husky
└── pre-commit
├── .jest
└── setup.ts
├── .prettierignore
├── .prettierrc
├── .storybook
├── main.js
└── preview.js
├── .vscode
└── settings.json
├── README.md
├── generators
├── plopfile.js
└── templates
│ ├── Component.tsx.hbs
│ ├── stories.tsx.hbs
│ ├── styles.ts.hbs
│ └── test.tsx.hbs
├── jest.config.js
├── next-env.d.ts
├── next.config.js
├── package.json
├── public
├── img
│ ├── hero-illustration.svg
│ ├── icon-192.png
│ ├── icon-512.png
│ ├── logo-gh.svg
│ └── logo.svg
└── manifest.json
├── src
├── components
│ └── Main
│ │ ├── __snapshots__
│ │ └── test.tsx.snap
│ │ ├── index.tsx
│ │ ├── stories.tsx
│ │ ├── styles.ts
│ │ └── test.tsx
├── pages
│ ├── _app.tsx
│ ├── _document.tsx
│ └── index.tsx
├── styles
│ └── global.ts
└── types
│ └── jest-styled-components.d.ts
├── tsconfig.json
└── yarn.lock
/.editorconfig:
--------------------------------------------------------------------------------
1 | # editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | charset = utf-8
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | !.storybook
2 | !.jest
3 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": true,
4 | "es2020": true,
5 | "jest": true,
6 | "node": true
7 | },
8 | "settings": {
9 | "react": {
10 | "version": "detect"
11 | }
12 | },
13 | "extends": [
14 | "eslint:recommended",
15 | "plugin:react/recommended",
16 | "plugin:@typescript-eslint/eslint-recommended",
17 | "plugin:@typescript-eslint/recommended",
18 | "plugin:prettier/recommended",
19 | "plugin:@next/next/recommended"
20 | ],
21 | "parser": "@typescript-eslint/parser",
22 | "parserOptions": {
23 | "ecmaFeatures": {
24 | "jsx": true
25 | },
26 | "ecmaVersion": 11,
27 | "sourceType": "module"
28 | },
29 | "plugins": ["react", "react-hooks", "@typescript-eslint"],
30 | "rules": {
31 | "react-hooks/rules-of-hooks": "error",
32 | "react-hooks/exhaustive-deps": "warn",
33 | "react/prop-types": "off",
34 | "react/react-in-jsx-scope": "off",
35 | "@typescript-eslint/explicit-module-boundary-types": "off"
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: npm
4 | directory: "/"
5 | schedule:
6 | interval: daily
7 | open-pull-requests-limit: 10
8 | ignore:
9 | - dependency-name: "@types/node"
10 | versions:
11 | - 14.14.22
12 | - 14.14.24
13 | - 14.14.25
14 | - 14.14.26
15 | - 14.14.28
16 | - 14.14.30
17 | - 14.14.31
18 | - 14.14.32
19 | - 14.14.33
20 | - 14.14.34
21 | - 14.14.35
22 | - 14.14.36
23 | - 14.14.37
24 | - 14.14.39
25 | - 14.14.41
26 | - 15.0.0
27 | - dependency-name: eslint-config-prettier
28 | versions:
29 | - 8.0.0
30 | - 8.1.0
31 | - 8.2.0
32 | - 8.3.0
33 | - dependency-name: next-pwa
34 | versions:
35 | - 5.0.4
36 | - 5.0.5
37 | - 5.0.6
38 | - 5.1.4
39 | - 5.2.1
40 | - 5.2.14
41 | - 5.2.15
42 | - 5.2.3
43 | - 5.2.5
44 | - 5.2.9
45 | - dependency-name: eslint
46 | versions:
47 | - 7.21.0
48 | - 7.22.0
49 | - 7.25.0
50 | - dependency-name: "@storybook/addon-essentials"
51 | versions:
52 | - 6.1.15
53 | - 6.1.16
54 | - 6.1.17
55 | - 6.1.18
56 | - 6.1.19
57 | - 6.1.20
58 | - 6.1.21
59 | - 6.2.1
60 | - 6.2.2
61 | - 6.2.3
62 | - 6.2.4
63 | - 6.2.5
64 | - 6.2.7
65 | - 6.2.8
66 | - 6.2.9
67 | - dependency-name: "@storybook/react"
68 | versions:
69 | - 6.1.18
70 | - 6.1.19
71 | - 6.1.20
72 | - 6.1.21
73 | - 6.2.1
74 | - 6.2.2
75 | - 6.2.3
76 | - 6.2.4
77 | - 6.2.5
78 | - 6.2.7
79 | - 6.2.8
80 | - 6.2.9
81 | - dependency-name: "@testing-library/jest-dom"
82 | versions:
83 | - 5.11.10
84 | - 5.12.0
85 | - dependency-name: "@babel/core"
86 | versions:
87 | - 7.12.17
88 | - 7.13.1
89 | - 7.13.10
90 | - 7.13.16
91 | - 7.13.8
92 | - dependency-name: jest-styled-components
93 | versions:
94 | - 7.0.4
95 | - dependency-name: eslint-plugin-prettier
96 | versions:
97 | - 3.3.1
98 | - 3.4.0
99 | - dependency-name: y18n
100 | versions:
101 | - 4.0.1
102 | - 4.0.2
103 | - dependency-name: "@typescript-eslint/parser"
104 | versions:
105 | - 4.14.1
106 | - 4.14.2
107 | - 4.15.0
108 | - 4.15.1
109 | - 4.15.2
110 | - 4.16.1
111 | - 4.17.0
112 | - 4.18.0
113 | - 4.19.0
114 | - 4.21.0
115 | - dependency-name: styled-components
116 | versions:
117 | - 5.2.2
118 | - dependency-name: next
119 | versions:
120 | - 10.0.5
121 | - 10.0.6
122 | - 10.0.7
123 | - 10.1.2
124 | - dependency-name: husky
125 | versions:
126 | - 4.3.8
127 | - 5.0.9
128 | - 5.1.0
129 | - 5.1.1
130 | - 5.2.0
131 | - 6.0.0
132 | - dependency-name: "@types/jest"
133 | versions:
134 | - 26.0.20
135 | - 26.0.22
136 | - dependency-name: eslint-plugin-react
137 | versions:
138 | - 7.23.0
139 | - 7.23.1
140 | - dependency-name: react-dom
141 | versions:
142 | - 17.0.2
143 | - dependency-name: react
144 | versions:
145 | - 17.0.2
146 | - dependency-name: "@typescript-eslint/eslint-plugin"
147 | versions:
148 | - 4.14.1
149 | - 4.14.2
150 | - 4.15.0
151 | - 4.15.1
152 | - 4.15.2
153 | - 4.16.1
154 | - 4.17.0
155 | - 4.18.0
156 | - 4.19.0
157 | - dependency-name: "@types/styled-components"
158 | versions:
159 | - 5.1.8
160 | - 5.1.9
161 | - dependency-name: "@types/react"
162 | versions:
163 | - 17.0.3
164 | - dependency-name: typescript
165 | versions:
166 | - 4.2.2
167 | - 4.2.3
168 | - dependency-name: "@babel/preset-typescript"
169 | versions:
170 | - 7.12.17
171 | - 7.13.0
172 | - dependency-name: "@testing-library/react"
173 | versions:
174 | - 11.2.3
175 | - 11.2.5
176 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: ci
2 | on: [pull_request]
3 |
4 | jobs:
5 | build:
6 | runs-on: ubuntu-latest
7 | steps:
8 | - name: Checkout Repository
9 | uses: actions/checkout@v2
10 |
11 | - name: Setup Node
12 | uses: actions/setup-node@v1
13 | with:
14 | node-version: 14.x
15 |
16 | - uses: actions/cache@v2
17 | id: yarn-cache
18 | with:
19 | path: |
20 | ~/cache
21 | !~/cache/exclude
22 | **/node_modules
23 | key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
24 | restore-keys: |
25 | ${{ runner.os }}-yarn-
26 |
27 | - name: Install dependencies
28 | run: yarn install
29 |
30 | - name: Linting
31 | run: yarn lint
32 |
33 | - name: Test
34 | run: yarn test:ci
35 |
36 | - name: Build
37 | run: yarn build
38 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 |
21 | # debug
22 | npm-debug.log*
23 | yarn-debug.log*
24 | yarn-error.log*
25 |
26 | # local env files
27 | .env.local
28 | .env.development.local
29 | .env.test.local
30 | .env.production.local
31 |
32 | # sw stuff
33 | public/sw.js
34 | public/workbox-*.js
35 |
36 | # storybook
37 | storybook-static
38 |
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | . "$(dirname "$0")/_/husky.sh"
3 |
4 | npx --no-install lint-staged
5 |
--------------------------------------------------------------------------------
/.jest/setup.ts:
--------------------------------------------------------------------------------
1 | import '@testing-library/jest-dom'
2 | import 'jest-styled-components'
3 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | !.storybook
2 | !.jest
3 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "trailingComma": "none",
3 | "semi": false,
4 | "singleQuote": true
5 | }
6 |
--------------------------------------------------------------------------------
/.storybook/main.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | staticDirs: ['../public'],
3 | stories: ['../src/components/**/stories.tsx'],
4 | addons: ['@storybook/addon-essentials', 'storybook-addon-next-router'],
5 | core: {
6 | builder: 'webpack5'
7 | },
8 | webpackFinal: (config) => {
9 | config.resolve.modules.push(`${process.cwd()}/src`)
10 | return config
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/.storybook/preview.js:
--------------------------------------------------------------------------------
1 | import { RouterContext } from 'next/dist/shared/lib/router-context'
2 | import GlobalStyles from '../src/styles/global'
3 |
4 | export const parameters = {
5 | nextRouter: {
6 | Provider: RouterContext.Provider
7 | }
8 | }
9 |
10 | export const decorators = [
11 | (Story) => (
12 | <>
13 |
14 |
15 | >
16 | )
17 | ]
18 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "editor.formatOnSave": false,
3 | "editor.codeActionsOnSave": {
4 | "source.fixAll.eslint": true
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | 
3 |
4 | This is a [Next.js](https://nextjs.org/) boilerplate to be used in a course called [React Avançado](https://reactavancado.com.br/).
5 | 
6 | ## What is inside?
7 |
8 | This project uses lot of stuff as:
9 |
10 | - [TypeScript](https://www.typescriptlang.org/)
11 | - [NextJS](https://nextjs.org/)
12 | - [Styled Components](https://styled-components.com/)
13 | - [Jest](https://jestjs.io/)
14 | - [React Testing Library](https://testing-library.com/docs/react-testing-library/intro)
15 | - [Storybook](https://storybook.js.org/)
16 | - [Eslint](https://eslint.org/)
17 | - [Prettier](https://prettier.io/)
18 | - [Husky](https://github.com/typicode/husky)
19 |
20 | ## Getting Started
21 |
22 | First, run the development server:
23 |
24 | ```bash
25 | npm run dev
26 | # or
27 | yarn dev
28 | ```
29 |
30 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
31 |
32 | You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file.
33 |
34 | ## Commands
35 |
36 | - `dev`: runs your application on `localhost:3000`
37 | - `build`: creates the production build version
38 | - `start`: starts a simple server with the build production code
39 | - `lint`: runs the linter in all components and pages
40 | - `test`: runs jest to test all components and pages
41 | - `test:watch`: runs jest in watch mode
42 | - `storybook`: runs storybook on `localhost:6006`
43 | - `build-storybook`: create the build version of storybook
44 |
45 | ## Learn More
46 |
47 | To learn more about Next.js, take a look at the following resources:
48 |
49 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
50 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
51 |
52 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
53 |
54 | ## Deploy on Vercel
55 |
56 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/import?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
57 |
58 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
59 |
--------------------------------------------------------------------------------
/generators/plopfile.js:
--------------------------------------------------------------------------------
1 | module.exports = (plop) => {
2 | plop.setGenerator('component', {
3 | description: 'Create a component',
4 | prompts: [
5 | {
6 | type: 'input',
7 | name: 'name',
8 | message: 'What is your component name?'
9 | }
10 | ],
11 | actions: [
12 | {
13 | type: 'add',
14 | path: '../src/components/{{pascalCase name}}/index.tsx',
15 | templateFile: 'templates/Component.tsx.hbs'
16 | },
17 | {
18 | type: 'add',
19 | path: '../src/components/{{pascalCase name}}/styles.ts',
20 | templateFile: 'templates/styles.ts.hbs'
21 | },
22 | {
23 | type: 'add',
24 | path: '../src/components/{{pascalCase name}}/stories.tsx',
25 | templateFile: 'templates/stories.tsx.hbs'
26 | },
27 | {
28 | type: 'add',
29 | path: '../src/components/{{pascalCase name}}/test.tsx',
30 | templateFile: 'templates/test.tsx.hbs'
31 | }
32 | ]
33 | })
34 | }
35 |
--------------------------------------------------------------------------------
/generators/templates/Component.tsx.hbs:
--------------------------------------------------------------------------------
1 | import * as S from './styles'
2 |
3 | const {{pascalCase name}} = () => (
4 |
5 | {{pascalCase name}}
6 |
7 | )
8 |
9 | export default {{pascalCase name}}
10 |
--------------------------------------------------------------------------------
/generators/templates/stories.tsx.hbs:
--------------------------------------------------------------------------------
1 | import { Story, Meta } from '@storybook/react'
2 | import {{pascalCase name}} from '.'
3 |
4 | export default {
5 | title: '{{pascalCase name}}',
6 | component: {{pascalCase name}}
7 | } as Meta
8 |
9 | export const Default: Story = () => <{{pascalCase name}} />
10 |
--------------------------------------------------------------------------------
/generators/templates/styles.ts.hbs:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components'
2 |
3 | export const Wrapper = styled.main``
4 |
--------------------------------------------------------------------------------
/generators/templates/test.tsx.hbs:
--------------------------------------------------------------------------------
1 | import { render, screen } from '@testing-library/react'
2 |
3 | import {{pascalCase name}} from '.'
4 |
5 | describe('<{{pascalCase name}} />', () => {
6 | it('should render the heading', () => {
7 | const { container } = render(<{{pascalCase name}} />)
8 |
9 | expect(screen.getByRole('heading', { name: /{{pascalCase name}}/i })).toBeInTheDocument()
10 |
11 | expect(container.firstChild).toMatchSnapshot()
12 | })
13 | })
14 |
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | testEnvironment: 'jsdom',
3 | testPathIgnorePatterns: ['/node_modules/', '/.next/'],
4 | collectCoverage: true,
5 | collectCoverageFrom: ['src/**/*.ts(x)?', '!src/**/stories.tsx'],
6 | setupFilesAfterEnv: ['/.jest/setup.ts'],
7 | modulePaths: ['/src/'],
8 | transform: {
9 | '^.+\\.(js|jsx|ts|tsx)$': ['babel-jest', { presets: ['next/babel'] }]
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
4 | // NOTE: This file should not be edited
5 | // see https://nextjs.org/docs/basic-features/typescript for more information.
6 |
--------------------------------------------------------------------------------
/next.config.js:
--------------------------------------------------------------------------------
1 | // eslint-disable-next-line @typescript-eslint/no-var-requires
2 | const withPWA = require('next-pwa')
3 | const isProd = process.env.NODE_ENV === 'production'
4 |
5 | module.exports = withPWA({
6 | swcMinify: true,
7 | experimental: {
8 | // Enables the styled-components SWC transform
9 | styledComponents: true
10 | },
11 | pwa: {
12 | dest: 'public',
13 | disable: !isProd
14 | }
15 | })
16 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-avancado-boilerplate",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start",
9 | "lint": "eslint src --max-warnings=0",
10 | "test": "jest --maxWorkers=50%",
11 | "test:watch": "jest --watch --maxWorkers=25%",
12 | "test:ci": "jest --runInBand",
13 | "generate": "yarn plop --plopfile generators/plopfile.js",
14 | "storybook": "start-storybook -p 6006",
15 | "build-storybook": "build-storybook",
16 | "postinstall": "husky install",
17 | "prepare": "husky install"
18 | },
19 | "lint-staged": {
20 | "src/**/*": [
21 | "yarn lint --fix",
22 | "yarn test --findRelatedTests --bail"
23 | ]
24 | },
25 | "dependencies": {
26 | "next": "12.0.10",
27 | "next-pwa": "^5.3.1",
28 | "react": "17.0.2",
29 | "react-dom": "17.0.2",
30 | "styled-components": "5.3.3"
31 | },
32 | "devDependencies": {
33 | "@storybook/addon-essentials": "6.4.17",
34 | "@storybook/builder-webpack5": "^6.4.17",
35 | "@storybook/manager-webpack5": "^6.4.17",
36 | "@storybook/react": "6.4.17",
37 | "@testing-library/jest-dom": "^5.14.1",
38 | "@testing-library/react": "^12.1.2",
39 | "@types/jest": "^27.4.0",
40 | "@types/node": "^17.0.14",
41 | "@types/react": "^17.0.27",
42 | "@types/styled-components": "^5.1.21",
43 | "@typescript-eslint/eslint-plugin": "5.10.2",
44 | "@typescript-eslint/parser": "5.10.2",
45 | "eslint": "^8.8.0",
46 | "eslint-config-next": "^12.0.10",
47 | "eslint-config-prettier": "^8.3.0",
48 | "eslint-plugin-prettier": "^4.0.0",
49 | "eslint-plugin-react": "^7.26.1",
50 | "eslint-plugin-react-hooks": "^4.2.0",
51 | "husky": "^7.0.2",
52 | "jest": "^27.4.7",
53 | "jest-styled-components": "^7.0.5",
54 | "lint-staged": "^12.3.3",
55 | "plop": "^3.0.5",
56 | "prettier": "^2.4.1",
57 | "storybook-addon-next-router": "^3.0.8",
58 | "typescript": "^4.5.5",
59 | "webpack": "5.68.0"
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/public/img/hero-illustration.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/public/img/icon-192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/React-Avancado/boilerplate/abf8aa4cbd17476aad69de369f4bbb2548fb4902/public/img/icon-192.png
--------------------------------------------------------------------------------
/public/img/icon-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/React-Avancado/boilerplate/abf8aa4cbd17476aad69de369f4bbb2548fb4902/public/img/icon-512.png
--------------------------------------------------------------------------------
/public/img/logo-gh.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/public/img/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "React Avançado - Boilerplate",
3 | "short_name": "React Avançado",
4 | "icons": [
5 | {
6 | "src": "/img/icon-192.png",
7 | "type": "image/png",
8 | "sizes": "192x192"
9 | },
10 | {
11 | "src": "/img/icon-512.png",
12 | "type": "image/png",
13 | "sizes": "512x512"
14 | }
15 | ],
16 | "background_color": "#06092B",
17 | "description": "Boilerplate utilizando Typescript, React, NextJS e Styled Components!",
18 | "display": "fullscreen",
19 | "start_url": "/",
20 | "theme_color": "#06092B"
21 | }
22 |
--------------------------------------------------------------------------------
/src/components/Main/__snapshots__/test.tsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[` should render the heading 1`] = `
4 | .c0 {
5 | background-color: #06092b;
6 | color: #fff;
7 | width: 100%;
8 | height: 100%;
9 | padding: 3rem;
10 | text-align: center;
11 | display: -webkit-box;
12 | display: -webkit-flex;
13 | display: -ms-flexbox;
14 | display: flex;
15 | -webkit-flex-direction: column;
16 | -ms-flex-direction: column;
17 | flex-direction: column;
18 | -webkit-align-items: center;
19 | -webkit-box-align: center;
20 | -ms-flex-align: center;
21 | align-items: center;
22 | -webkit-box-pack: center;
23 | -webkit-justify-content: center;
24 | -ms-flex-pack: center;
25 | justify-content: center;
26 | }
27 |
28 | .c1 {
29 | width: 25rem;
30 | margin-bottom: 2rem;
31 | }
32 |
33 | .c2 {
34 | font-size: 2.5rem;
35 | }
36 |
37 | .c3 {
38 | font-size: 2rem;
39 | font-weight: 400;
40 | }
41 |
42 | .c4 {
43 | margin-top: 3rem;
44 | width: min(30rem,100%);
45 | }
46 |
47 |
50 |
55 |
58 | React Avançado
59 |
60 |
63 | TypeScript, ReactJS, NextJS e Styled Components
64 |
65 |
70 |
71 | `
72 |
--------------------------------------------------------------------------------
/src/components/Main/index.tsx:
--------------------------------------------------------------------------------
1 | import * as S from './styles'
2 |
3 | const Main = ({
4 | title = 'React Avançado',
5 | description = 'TypeScript, ReactJS, NextJS e Styled Components'
6 | }) => (
7 |
8 |
12 | {title}
13 | {description}
14 |
18 |
19 | )
20 |
21 | export default Main
22 |
--------------------------------------------------------------------------------
/src/components/Main/stories.tsx:
--------------------------------------------------------------------------------
1 | import { Story, Meta } from '@storybook/react'
2 | import Main from '.'
3 |
4 | export default {
5 | title: 'Main',
6 | component: Main,
7 | args: {
8 | title: 'title default',
9 | description: 'description default'
10 | }
11 | } as Meta
12 |
13 | export const Basic: Story = (args) =>
14 | Basic.args = {
15 | title: 'title basic',
16 | description: 'description basic'
17 | }
18 |
19 | export const Default: Story = (args) =>
20 |
--------------------------------------------------------------------------------
/src/components/Main/styles.ts:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components'
2 |
3 | export const Wrapper = styled.main`
4 | background-color: #06092b;
5 | color: #fff;
6 | width: 100%;
7 | height: 100%;
8 | padding: 3rem;
9 | text-align: center;
10 | display: flex;
11 | flex-direction: column;
12 | align-items: center;
13 | justify-content: center;
14 | `
15 |
16 | export const Logo = styled.img`
17 | width: 25rem;
18 | margin-bottom: 2rem;
19 | `
20 |
21 | export const Title = styled.h1`
22 | font-size: 2.5rem;
23 | `
24 |
25 | export const Description = styled.h2`
26 | font-size: 2rem;
27 | font-weight: 400;
28 | `
29 |
30 | export const Illustration = styled.img`
31 | margin-top: 3rem;
32 | width: min(30rem, 100%);
33 | `
34 |
--------------------------------------------------------------------------------
/src/components/Main/test.tsx:
--------------------------------------------------------------------------------
1 | import { render, screen } from '@testing-library/react'
2 |
3 | import Main from '.'
4 |
5 | describe('', () => {
6 | it('should render the heading', () => {
7 | const { container } = render()
8 |
9 | expect(
10 | screen.getByRole('heading', { name: /react avançado/i })
11 | ).toBeInTheDocument()
12 |
13 | expect(container.firstChild).toMatchSnapshot()
14 | })
15 |
16 | it('should render the colors correctly', () => {
17 | const { container } = render()
18 |
19 | expect(container.firstChild).toHaveStyle({ 'background-color': '#06092b' })
20 | })
21 | })
22 |
--------------------------------------------------------------------------------
/src/pages/_app.tsx:
--------------------------------------------------------------------------------
1 | import { AppProps } from 'next/app'
2 | import Head from 'next/head'
3 |
4 | import GlobalStyles from 'styles/global'
5 |
6 | function App({ Component, pageProps }: AppProps) {
7 | return (
8 | <>
9 |
10 | React Avançado - Boilerplate
11 |
12 |
13 |
14 |
15 |
19 |
20 |
21 |
22 | >
23 | )
24 | }
25 |
26 | export default App
27 |
--------------------------------------------------------------------------------
/src/pages/_document.tsx:
--------------------------------------------------------------------------------
1 | import Document, {
2 | Html,
3 | Head,
4 | Main,
5 | NextScript,
6 | DocumentContext
7 | } from 'next/document'
8 | import { ServerStyleSheet } from 'styled-components'
9 |
10 | export default class MyDocument extends Document {
11 | static async getInitialProps(ctx: DocumentContext) {
12 | const sheet = new ServerStyleSheet()
13 | const originalRenderPage = ctx.renderPage
14 |
15 | try {
16 | ctx.renderPage = () =>
17 | originalRenderPage({
18 | enhanceApp: (App) =>
19 | function enhance(props) {
20 | return sheet.collectStyles()
21 | }
22 | })
23 |
24 | const initialProps = await Document.getInitialProps(ctx)
25 | return {
26 | ...initialProps,
27 | styles: (
28 | <>
29 | {initialProps.styles}
30 | {sheet.getStyleElement()}
31 | >
32 | )
33 | }
34 | } finally {
35 | sheet.seal()
36 | }
37 | }
38 |
39 | render() {
40 | return (
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | )
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/pages/index.tsx:
--------------------------------------------------------------------------------
1 | import Main from 'components/Main'
2 |
3 | export default function Home() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/src/styles/global.ts:
--------------------------------------------------------------------------------
1 | import { createGlobalStyle } from 'styled-components'
2 |
3 | const GlobalStyles = createGlobalStyle`
4 | * {
5 | margin: 0;
6 | padding: 0;
7 | box-sizing: border-box;
8 | }
9 |
10 | html {
11 | font-size: 62.5%;
12 | }
13 |
14 | html, body, #__next {
15 | height: 100%;
16 | }
17 |
18 | body {
19 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif
20 | }
21 | `
22 |
23 | export default GlobalStyles
24 |
--------------------------------------------------------------------------------
/src/types/jest-styled-components.d.ts:
--------------------------------------------------------------------------------
1 | // Types provided from the official repo:
2 | // https://github.com/styled-components/jest-styled-components/blob/master/typings/index.d.ts
3 |
4 | /* eslint-disable @typescript-eslint/no-explicit-any */
5 | /* eslint-disable @typescript-eslint/ban-types */
6 | import { Plugin, NewPlugin } from 'pretty-format'
7 |
8 | declare global {
9 | namespace jest {
10 | interface AsymmetricMatcher {
11 | $$typeof: symbol
12 | sample?: string | RegExp | object | Array | Function
13 | }
14 |
15 | type Value = string | number | RegExp | AsymmetricMatcher | undefined
16 |
17 | interface Options {
18 | media?: string
19 | modifier?: string
20 | supports?: string
21 | }
22 |
23 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
24 | interface Matchers {
25 | toHaveStyleRule(property: string, value?: Value, options?: Options): R
26 | }
27 | }
28 | }
29 |
30 | export declare const styleSheetSerializer: Exclude
31 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "baseUrl": "src",
4 | "target": "es5",
5 | "lib": [
6 | "dom",
7 | "dom.iterable",
8 | "esnext"
9 | ],
10 | "allowJs": true,
11 | "skipLibCheck": true,
12 | "strict": true,
13 | "forceConsistentCasingInFileNames": true,
14 | "noEmit": true,
15 | "esModuleInterop": true,
16 | "module": "esnext",
17 | "moduleResolution": "node",
18 | "resolveJsonModule": true,
19 | "isolatedModules": true,
20 | "jsx": "preserve",
21 | "incremental": true
22 | },
23 | "exclude": [
24 | "node_modules"
25 | ],
26 | "include": [
27 | "next-env.d.ts",
28 | "**/*.ts",
29 | "**/*.tsx"
30 | ]
31 | }
32 |
--------------------------------------------------------------------------------