├── .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 | ![React Avançado](https://raw.githubusercontent.com/React-Avancado/boilerplate/master/public/img/logo-gh.svg) 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 | ![ci](https://github.com/React-Avancado/boilerplate/workflows/ci/badge.svg) 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 | Imagem de um átomo e React Avançado escrito ao lado. 55 |

58 | React Avançado 59 |

60 |

63 | TypeScript, ReactJS, NextJS e Styled Components 64 |

65 | Um desenvolvedor de frente para uma tela com código. 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 | --------------------------------------------------------------------------------