├── .github └── workflows │ └── publish.yaml ├── LICENSE ├── README.md ├── package.json ├── template.json └── template ├── .editorconfig ├── .github └── workflows │ ├── lint.yml │ └── test.yml ├── .stylelintrc.json ├── LICENSE ├── Makefile ├── README.md ├── cypress.config.ts ├── gitignore ├── jest.config.js ├── public └── index.html ├── src ├── App.tsx ├── assets │ └── styles │ │ └── sakura.scss ├── index.tsx ├── react-app-env.d.ts └── sections │ └── users │ ├── UserCard.module.scss │ ├── UserCard.tsx │ └── useUsers.ts ├── tests ├── App.spec.tsx ├── e2e │ ├── support │ │ ├── commands.ts │ │ └── e2e.ts │ ├── tests │ │ └── home.spec.ts │ └── tsconfig.json └── setupTests.ts └── tsconfig.json /.github/workflows/publish.yaml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - 'main' 5 | 6 | jobs: 7 | publish: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v3 11 | - uses: actions/setup-node@v3 12 | with: 13 | node-version: 12 14 | - run: npm install 15 | - uses: JS-DevTools/npm-publish@v1 16 | with: 17 | token: ${{ secrets.NPM_TOKEN }} 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Codely Enseña y Entretiene SL 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. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | Codely logo 4 | 5 |

6 | 7 |

8 | <🌱⚛️> Create React App Codely template 9 |

10 | 11 |

12 | Build status 13 | Codely Open Source 14 | CodelyTV Courses 15 |

16 | 17 |

18 | Template for creating your React apps with TypeScript following best practices: Unit and end-to-end tests, Continuous Integration, and linting. 19 |
20 |
21 | Stars are welcome 😊 22 |

23 | 24 | ## 🚀 Using this CRA template 25 | 26 | ### 🤔 CRA introduction 27 | 28 | React officially support to create your custom templates for the Create React App (CRA) utility. 29 | 30 | This Codely template is just a way to optimize even more the default CRA template adding the bare minimum [features we consider necessary on every React project](https://github.com/CodelyTV/cra-template-codely#-template-features). 31 | 32 | ### ⚡ How to create your React app 33 | 34 | Create your React app with TypeScript and taking advantage of the scaffolding provided by this template executing this `npx` command in your terminal: 35 | 36 | ```bash 37 | npx create-react-app my-app --template @codelytv/cra-template-codely 38 | ``` 39 | 40 | Or, if you prefer to use Yarn instead of npm: 41 | 42 | ```bash 43 | yarn create react-app --template @codelytv/cra-template-codely my-app 44 | ``` 45 | 46 | It will create a `my-app` folder inside the directory where you execute the command. You will find a `README.md` in the root of your generated project with the instructions on how to build, test, and run your application 🤟 47 | 48 | ### 🌩️ What does CRA do while creating the project 49 | 50 | The `my-app` created with the `npx` command will contain a ready-to-use application thanks to the magic CRA does behind the scenes: 51 | 52 | - Copy everything inside [this CRA `template` folder](template) into your project root directory 53 | - Create the project `package.json` based on the dependencies that CRA needs such as React itself _in the latest version possible_, plus the dependencies added by Codely in the [`template.json`](template.json) 54 | - Create the project `.gitignore` file based on the [`template/gitignore`](template/gitignore) 55 | - Depending on if you have used Yarn or npm while creating the project, it will have available the corresponding commands and config files in order to run the generated app 56 | - Install all the dependencies 57 | 58 | ## 🌈 Template Features 59 | 60 | - [TypeScript](https://www.typescriptlang.org) 61 | - [ESLint](https://eslint.org) and [Prettier](https://prettier.io) already configured with the [🤏 Codely's configuration](https://github.com/CodelyTV/eslint-config-codely) 62 | - [Jest](https://jestjs.io) with [React Testing Library](https://testing-library.com/docs/react-testing-library/intro) for the unit tests 63 | - [Cypress](https://www.cypress.io) with [Testing Library](https://testing-library.com/docs/cypress-testing-library) for the end-to-end tests 64 | - [GitHub Action Workflows](https://github.com/features/actions) set up to run tests and linting on push 65 | - [Makefile](https://github.com/CodelyTV/cra-template-codely/blob/main/template/Makefile) for standardize how to run projects 66 | - [Sass](https://sass-lang.com) to supercharge CSS with nested classes and more fun 67 | - [.editorconfig](https://editorconfig.org) for sharing the IDE config 68 | 69 | 70 | ## 💻 Improving this CRA template 71 | 72 | You can improve this CRA and make Pull Requests to this repository. In order to locally test how your improvements generate a new project, you can specify a local template file with the following command: 73 | 74 | ```bash 75 | npx create-react-app my-app --template file:../path/to/cra-template-codely 76 | ``` 77 | 78 | ## 👌 Codely Code Quality Standards 79 | 80 | Publishing this package we are committing ourselves to the following code quality standards: 81 | 82 | - 🤝 Respect **Semantic Versioning**: No breaking changes in patch or minor versions 83 | - 🤏 No surprises in transitive dependencies: Use the **bare minimum dependencies** needed to meet the purpose 84 | - 🎯 **One specific purpose** to meet without having to carry a bunch of unnecessary other utilities 85 | - ✅ **Tests** as documentation and usage examples 86 | - 📖 **Well documented ReadMe** showing how to install and use 87 | - ⚖️ **License favoring Open Source** and collaboration 88 | 89 | ## 🔀 Related templates 90 | 91 | Opinionated TypeScript skeletons ready for different purposes: 92 | 93 | - [🔷🌱 TypeScript Basic Skeleton](https://github.com/CodelyTV/typescript-basic-skeleton) 94 | - [🔷🕸️ TypeScript Web Skeleton](https://github.com/CodelyTV/typescript-web-skeleton) 95 | - [🔷🌍 TypeScript API Skeleton](https://github.com/CodelyTV/typescript-api-skeleton) 96 | - [🔷✨ TypeScript DDD Skeleton](https://github.com/CodelyTV/typescript-ddd-skeleton) 97 | 98 | This same skeleton philosophy implemented in other programming languages: 99 | 100 | - [✨ JavaScript Basic Skeleton](https://github.com/CodelyTV/javascript-basic-skeleton) 101 | - [☕ Java Basic Skeleton](https://github.com/CodelyTV/java-basic-skeleton) 102 | - [📍 Kotlin Basic Skeleton](https://github.com/CodelyTV/kotlin-basic-skeleton) 103 | - [🧬 Scala Basic Skeleton](https://github.com/CodelyTV/scala-basic-skeleton) 104 | - [🦈 C# Basic Skeleton](https://github.com/CodelyTV/csharp-basic-skeleton) 105 | - [🐘 PHP Basic Skeleton](https://github.com/CodelyTV/php-basic-skeleton) 106 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@codelytv/cra-template-codely", 3 | "version": "1.0.3", 4 | "keywords": [ 5 | "react", 6 | "create-react-app", 7 | "template", 8 | "typescript" 9 | ], 10 | "description": "Template for creating your React apps with TypeScript following best practices: Unit and end-to-end tests, Continuous Integration, and linting.", 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/CodelyTV/cra-template-codely" 14 | }, 15 | "author": "codelytv", 16 | "license": "MIT", 17 | "files": [ 18 | "template", 19 | "template.json" 20 | ], 21 | "engines": { 22 | "node": ">=14" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /template.json: -------------------------------------------------------------------------------- 1 | { 2 | "package": { 3 | "scripts": { 4 | "cy:open": "cypress open", 5 | "cy:run": "cypress run", 6 | "test": "jest --watch --config=jest.config.js", 7 | "lint": "eslint --ignore-path .gitignore . && stylelint **/*.scss", 8 | "lint:fix": "eslint --fix --ignore-path .gitignore . && stylelint --fix **/*.scss" 9 | }, 10 | "devDependencies": { 11 | "@swc/core": "^1.3.6", 12 | "@swc/jest": "^0.2.23", 13 | "@testing-library/jest-dom": "^5.14.1", 14 | "@testing-library/react": "^13.0.0", 15 | "@testing-library/user-event": "^13.2.1", 16 | "@types/jest": "^27.0.1", 17 | "@types/node": "^16.7.13", 18 | "@types/react": "^18.0.0", 19 | "@types/react-dom": "^18.0.0", 20 | "typescript": "^4.4.2", 21 | "eslint-config-codely": "^2.1.1", 22 | "identity-obj-proxy": "^3.0.0", 23 | "jest-transform-stub": "^2.0.0", 24 | "cypress": "10.3.0", 25 | "@testing-library/cypress": "^8.0.2", 26 | "stylelint": "^14.1.0", 27 | "stylelint-config-rational-order": "^0.1.2", 28 | "stylelint-config-standard-scss": "^3.0.0", 29 | "stylelint-order": "^5.0.0", 30 | "sass": "^1.55.0" 31 | }, 32 | "dependencies": {}, 33 | "eslintConfig": { 34 | "extends": [ 35 | "react-app", 36 | "react-app/jest", 37 | "eslint-config-codely/typescript" 38 | ], 39 | "parserOptions": { 40 | "project": ["./tsconfig.json"] 41 | }, 42 | "settings": { 43 | "import/resolver": { 44 | "node": { 45 | "extensions": [".js", ".jsx", ".ts", ".tsx"] 46 | } 47 | } 48 | }, 49 | "overrides": [ 50 | { 51 | "files": ["**/tests/e2e/**/*.spec.ts"], 52 | "rules": { 53 | "testing-library/await-async-query": 0, 54 | "@typescript-eslint/no-unsafe-member-access": 0, 55 | "@typescript-eslint/no-unsafe-call": 0, 56 | "testing-library/prefer-screen-queries": 0 57 | } 58 | } 59 | ] 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /template/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true 6 | max_line_length = 100 7 | indent_style = tab 8 | -------------------------------------------------------------------------------- /template/.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: lint 2 | 3 | on: push 4 | 5 | jobs: 6 | lint: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/checkout@v3 11 | 12 | - uses: actions/setup-node@v3 13 | with: 14 | node-version: 16 15 | cache: 'npm' 16 | 17 | - name: Install Dependencies 18 | run: npm install 19 | 20 | - name: Lint 21 | run: npm run lint 22 | -------------------------------------------------------------------------------- /template/.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: test 2 | 3 | on: push 4 | 5 | jobs: 6 | unit: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/checkout@v3 11 | 12 | - uses: actions/setup-node@v3 13 | with: 14 | node-version: 16 15 | cache: 'npm' 16 | 17 | - name: Install Dependencies 18 | run: npm install 19 | 20 | - name: Test 21 | run: npx jest --config=jest.config.js 22 | e2e: 23 | runs-on: ubuntu-latest 24 | 25 | steps: 26 | - uses: actions/checkout@v3 27 | 28 | - uses: actions/setup-node@v3 29 | with: 30 | node-version: 16 31 | cache: 'npm' 32 | 33 | - name: Install Dependencies 34 | run: npm install 35 | 36 | - name: Cypress run 37 | uses: cypress-io/github-action@v4 38 | with: 39 | build: npm run build 40 | start: npm run start 41 | wait-on: "http://localhost:3000" 42 | -------------------------------------------------------------------------------- /template/.stylelintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "overrides": [ 3 | { 4 | "files": ["**/*.scss"], 5 | "customSyntax": "postcss-scss" 6 | } 7 | ], 8 | "extends": ["stylelint-config-standard-scss", "stylelint-config-rational-order"], 9 | "rules": { 10 | "scss/dollar-variable-pattern": null, 11 | "scss/dollar-variable-empty-line-before": null, 12 | "selector-id-pattern": null, 13 | "selector-class-pattern": null 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /template/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) ${Year} ${Company} 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. -------------------------------------------------------------------------------- /template/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: build 2 | build: deps compile 3 | 4 | .PHONY: deps 5 | deps: 6 | npm install 7 | 8 | .PHONY: compile 9 | compile: 10 | npm run build 11 | 12 | .PHONY: start 13 | start: 14 | npm start 15 | 16 | .PHONY: test 17 | test: 18 | npm test 19 | 20 | .PHONY: lint 21 | lint: 22 | npm run lint 23 | 24 | .PHONY: lint-fix 25 | lint-fix: 26 | npm run lint:fix -------------------------------------------------------------------------------- /template/README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | Codely logo 4 | 5 |

6 | 7 |

8 | 👋️ Create React App Codely template example 9 |

10 | 11 |

12 | Build status 13 | Codely Open Source 14 | CodelyTV Courses 15 |

16 | 17 |

18 | App created with the 🌱⚛️ Create React App Codely template 19 |
20 |
21 | Stars are welcome 😊 22 |

23 | 24 | ## 🚀 Run the app 25 | 26 | - `npm install`: Install dependencies 27 | - `cp .env.example .env`: Create the environment variables file based on the example template 28 | - `vim .env`: Specify your GitHub Personal access token ([how to get it](https://docs.github.com/en/enterprise-server@3.4/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) -> [your tokens](https://github.com/settings/tokens) -> Enable `Repo.public_repo`) 29 | - `vim src/devdash_config.ts`: Set the repository URLs you want to show on your *DevDash_* 30 | - `npm start`: Run in dev mode on [localhost:3000](http://localhost:3000) 31 | - `npm run build`: Generate production build 32 | 33 | ## ✅ Testing 34 | 35 | ### Unit tests 36 | 37 | `npm run test`: Run unit tests with Jest and React Testing Library 38 | 39 | ### End-to-end tests 40 | 41 | - `npm start`: Run in dev mode on [localhost:3000](http://localhost:3000) 42 | - Run end-to-end tests with Cypress choosing one of the following options: 43 | - `npm run cy:open`: Open Cypress in dev mode 44 | - `npm run cy:run`: Execute Cypress in CLI 45 | 46 | ## 🔦 Linting 47 | 48 | - `npm run lint`: Run linter 49 | - `npm run lint:fix`: Fix lint issues 50 | 51 | ## 🌈 Tech Stack 52 | 53 | - [TypeScript](https://www.typescriptlang.org) 54 | - [ESLint](https://eslint.org) and [Prettier](https://prettier.io) already configured with the [🤏 Codely's configuration](https://github.com/CodelyTV/eslint-config-codely) 55 | - [Jest](https://jestjs.io) with [React Testing Library](https://testing-library.com/docs/react-testing-library/intro) for the unit tests 56 | - [Cypress](https://www.cypress.io) with [Testing Library](https://testing-library.com/docs/cypress-testing-library) for the end-to-end tests 57 | - [GitHub Action Workflows](https://github.com/features/actions) set up to run tests and linting on push 58 | - [Makefile](https://github.com/CodelyTV/cra-template-codely/blob/main/template/Makefile) for standardize how to run projects 59 | - [Sass](https://sass-lang.com) to supercharge CSS with nested classes and more fun 60 | - [.editorconfig](https://editorconfig.org) for sharing the IDE config 61 | 62 | ## 👌 Codely Code Quality Standards 63 | 64 | Publishing this package we are committing ourselves to the following code quality standards: 65 | 66 | - 🤝 Respect **Semantic Versioning**: No breaking changes in patch or minor versions 67 | - 🤏 No surprises in transitive dependencies: Use the **bare minimum dependencies** needed to meet the purpose 68 | - 🎯 **One specific purpose** to meet without having to carry a bunch of unnecessary other utilities 69 | - ✅ **Tests** as documentation and usage examples 70 | - 📖 **Well documented ReadMe** showing how to install and use 71 | - ⚖️ **License favoring Open Source** and collaboration 72 | 73 | ## 🔀 Related information 74 | 75 | This application was generated using the [🌱⚛️ Create React App Codely template](https://github.com/CodelyTV/cra-template-codely). Feel free to check it out and star the repo! 🌟😊🙌 76 | -------------------------------------------------------------------------------- /template/cypress.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "cypress"; 2 | 3 | export default defineConfig({ 4 | video: false, 5 | e2e: { 6 | baseUrl: "http://localhost:3000", 7 | specPattern: "tests/e2e/tests/**/*.spec.{js,jsx,ts,tsx}", 8 | screenshotOnRunFailure: false, 9 | video: false, 10 | viewportWidth: 1920, 11 | viewportHeight: 1080, 12 | supportFile: "tests/e2e/support/e2e.ts", 13 | }, 14 | }); 15 | -------------------------------------------------------------------------------- /template/gitignore: -------------------------------------------------------------------------------- 1 | # Dependency directories 2 | node_modules/ 3 | 4 | # Optional npm cache directory 5 | .npm 6 | 7 | # dotenv environment variables file 8 | .env 9 | .env.test 10 | 11 | # Build output 12 | build 13 | -------------------------------------------------------------------------------- /template/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | testEnvironment: "jsdom", 3 | setupFilesAfterEnv: ["/tests/setupTests.ts"], 4 | testMatch: ["/tests/**/*.(spec).(ts|tsx)"], 5 | testPathIgnorePatterns: ["/tests/e2e/"], 6 | transform: { 7 | "^.+\\.(js|jsx|ts|tsx)$": [ 8 | "@swc/jest", 9 | { 10 | sourceMaps: true, 11 | jsc: { 12 | parser: { 13 | syntax: "typescript", 14 | tsx: true, 15 | }, 16 | transform: { 17 | react: { 18 | runtime: "automatic", 19 | }, 20 | }, 21 | }, 22 | }, 23 | ], 24 | }, 25 | moduleNameMapper: { 26 | "\\.(css|less|scss|sass)$": "identity-obj-proxy", 27 | "\\.(jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": 28 | "jest-transform-stub", 29 | }, 30 | }; 31 | -------------------------------------------------------------------------------- /template/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 🌱⚛️ Create React App Codely template example 8 | 9 | 10 | 11 |
12 | 13 | 14 | -------------------------------------------------------------------------------- /template/src/App.tsx: -------------------------------------------------------------------------------- 1 | import { UserCard } from "./sections/users/UserCard"; 2 | import { useUsers } from "./sections/users/useUsers"; 3 | 4 | export function App() { 5 | const users = useUsers(); 6 | 7 | return ( 8 |
9 |

🌱⚛️ Create React App Codely template example

10 |

Current users

11 | 12 | {users.map((user) => ( 13 | 14 | ))} 15 |
16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /template/src/assets/styles/sakura.scss: -------------------------------------------------------------------------------- 1 | /* stylelint-disable */ 2 | /* Sakura.css v1.4.1 3 | * ================ 4 | * Minimal css theme. 5 | * Project: https://github.com/oxalorg/sakura/ 6 | */ 7 | /* Body */ 8 | html { 9 | font-size: 62.5%; 10 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif; 11 | } 12 | 13 | body { 14 | font-size: 1.8rem; 15 | line-height: 1.618; 16 | max-width: 38em; 17 | margin: auto; 18 | color: #4a4a4a; 19 | background-color: #f9f9f9; 20 | padding: 13px; 21 | } 22 | 23 | @media (max-width: 684px) { 24 | body { 25 | font-size: 1.53rem; 26 | } 27 | } 28 | @media (max-width: 382px) { 29 | body { 30 | font-size: 1.35rem; 31 | } 32 | } 33 | h1, 34 | h2, 35 | h3, 36 | h4, 37 | h5, 38 | h6 { 39 | line-height: 1.1; 40 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif; 41 | font-weight: 700; 42 | margin-top: 3rem; 43 | margin-bottom: 1.5rem; 44 | overflow-wrap: break-word; 45 | word-wrap: break-word; 46 | -ms-word-break: break-all; 47 | word-break: break-word; 48 | } 49 | 50 | h1 { 51 | font-size: 2.35em; 52 | } 53 | 54 | h2 { 55 | font-size: 2em; 56 | } 57 | 58 | h3 { 59 | font-size: 1.75em; 60 | } 61 | 62 | h4 { 63 | font-size: 1.5em; 64 | } 65 | 66 | h5 { 67 | font-size: 1.25em; 68 | } 69 | 70 | h6 { 71 | font-size: 1em; 72 | } 73 | 74 | p { 75 | margin-top: 0px; 76 | margin-bottom: 2.5rem; 77 | } 78 | 79 | small, 80 | sub, 81 | sup { 82 | font-size: 75%; 83 | } 84 | 85 | hr { 86 | border-color: #1d7484; 87 | } 88 | 89 | a { 90 | text-decoration: none; 91 | color: #1d7484; 92 | } 93 | a:visited { 94 | color: #144f5a; 95 | } 96 | a:hover { 97 | color: #982c61; 98 | border-bottom: 2px solid #4a4a4a; 99 | } 100 | 101 | ul { 102 | padding-left: 1.4em; 103 | margin-top: 0px; 104 | margin-bottom: 2.5rem; 105 | } 106 | 107 | li { 108 | margin-bottom: 0.4em; 109 | } 110 | 111 | blockquote { 112 | margin-left: 0px; 113 | margin-right: 0px; 114 | padding-left: 1em; 115 | padding-top: 0.8em; 116 | padding-bottom: 0.8em; 117 | padding-right: 0.8em; 118 | border-left: 5px solid #1d7484; 119 | margin-bottom: 2.5rem; 120 | background-color: #f1f1f1; 121 | } 122 | 123 | blockquote p { 124 | margin-bottom: 0; 125 | } 126 | 127 | img, 128 | video { 129 | height: auto; 130 | max-width: 100%; 131 | margin-top: 0px; 132 | margin-bottom: 2.5rem; 133 | } 134 | 135 | /* Pre and Code */ 136 | pre { 137 | background-color: #f1f1f1; 138 | display: block; 139 | padding: 1em; 140 | overflow-x: auto; 141 | margin-top: 0px; 142 | margin-bottom: 2.5rem; 143 | font-size: 0.9em; 144 | } 145 | 146 | code, 147 | kbd, 148 | samp { 149 | font-size: 0.9em; 150 | padding: 0 0.5em; 151 | background-color: #f1f1f1; 152 | white-space: pre-wrap; 153 | } 154 | 155 | pre > code { 156 | padding: 0; 157 | background-color: transparent; 158 | white-space: pre; 159 | font-size: 1em; 160 | } 161 | 162 | /* Tables */ 163 | table { 164 | text-align: justify; 165 | width: 100%; 166 | border-collapse: collapse; 167 | } 168 | 169 | td, 170 | th { 171 | padding: 0.5em; 172 | border-bottom: 1px solid #f1f1f1; 173 | } 174 | 175 | /* Buttons, forms and input */ 176 | input, 177 | textarea { 178 | border: 1px solid #4a4a4a; 179 | } 180 | input:focus, 181 | textarea:focus { 182 | border: 1px solid #1d7484; 183 | } 184 | 185 | textarea { 186 | width: 100%; 187 | } 188 | 189 | .button, 190 | button, 191 | input[type="submit"], 192 | input[type="reset"], 193 | input[type="button"] { 194 | display: inline-block; 195 | padding: 5px 10px; 196 | text-align: center; 197 | text-decoration: none; 198 | white-space: nowrap; 199 | background-color: #1d7484; 200 | color: #f9f9f9; 201 | border-radius: 1px; 202 | border: 1px solid #1d7484; 203 | cursor: pointer; 204 | box-sizing: border-box; 205 | } 206 | .button[disabled], 207 | button[disabled], 208 | input[type="submit"][disabled], 209 | input[type="reset"][disabled], 210 | input[type="button"][disabled] { 211 | cursor: default; 212 | opacity: 0.5; 213 | } 214 | .button:focus:enabled, 215 | .button:hover:enabled, 216 | button:focus:enabled, 217 | button:hover:enabled, 218 | input[type="submit"]:focus:enabled, 219 | input[type="submit"]:hover:enabled, 220 | input[type="reset"]:focus:enabled, 221 | input[type="reset"]:hover:enabled, 222 | input[type="button"]:focus:enabled, 223 | input[type="button"]:hover:enabled { 224 | background-color: #982c61; 225 | border-color: #982c61; 226 | color: #f9f9f9; 227 | outline: 0; 228 | } 229 | 230 | textarea, 231 | select, 232 | input { 233 | color: #4a4a4a; 234 | padding: 6px 10px; /* The 6px vertically centers text on FF, ignored by Webkit */ 235 | margin-bottom: 10px; 236 | background-color: #f1f1f1; 237 | border: 1px solid #f1f1f1; 238 | border-radius: 4px; 239 | box-shadow: none; 240 | box-sizing: border-box; 241 | } 242 | textarea:focus, 243 | select:focus, 244 | input:focus { 245 | border: 1px solid #1d7484; 246 | outline: 0; 247 | } 248 | 249 | input[type="checkbox"]:focus { 250 | outline: 1px dotted #1d7484; 251 | } 252 | 253 | label, 254 | legend, 255 | fieldset { 256 | display: block; 257 | margin-bottom: 0.5rem; 258 | font-weight: 600; 259 | } 260 | -------------------------------------------------------------------------------- /template/src/index.tsx: -------------------------------------------------------------------------------- 1 | import "./assets/styles/sakura.scss"; 2 | 3 | import React from "react"; 4 | import ReactDOM from "react-dom/client"; 5 | 6 | import { App } from "./App"; 7 | 8 | const root = ReactDOM.createRoot(document.getElementById("root") as HTMLElement); 9 | root.render( 10 | 11 | 12 | 13 | ); 14 | -------------------------------------------------------------------------------- /template/src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /template/src/sections/users/UserCard.module.scss: -------------------------------------------------------------------------------- 1 | .userCard { 2 | margin-bottom: 1rem; 3 | padding: 0.5rem; 4 | border: 1px solid #c9c2c2; 5 | border-radius: 0.25rem; 6 | 7 | &:hover { 8 | background-color: #e5e5e5; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /template/src/sections/users/UserCard.tsx: -------------------------------------------------------------------------------- 1 | import styles from "./UserCard.module.scss"; 2 | import { User } from "./useUsers"; 3 | 4 | export function UserCard({ user }: { user: User }) { 5 | return
{user.name}
; 6 | } 7 | -------------------------------------------------------------------------------- /template/src/sections/users/useUsers.ts: -------------------------------------------------------------------------------- 1 | export interface User { 2 | name: string; 3 | } 4 | 5 | export function useUsers(): User[] { 6 | return [{ name: "Javi" }, { name: "Isma" }]; 7 | } 8 | -------------------------------------------------------------------------------- /template/tests/App.spec.tsx: -------------------------------------------------------------------------------- 1 | import { render, screen } from "@testing-library/react"; 2 | 3 | import { App } from "../src/App"; 4 | 5 | test("App component display header", () => { 6 | render(); 7 | 8 | const heading = screen.getByText(/🌱⚛️ Create React App Codely template example/i); 9 | 10 | expect(heading).toBeInTheDocument(); 11 | }); 12 | -------------------------------------------------------------------------------- /template/tests/e2e/support/commands.ts: -------------------------------------------------------------------------------- 1 | // *********************************************** 2 | // This example commands.js shows you how to 3 | // create various custom commands and overwrite 4 | // existing commands. 5 | // 6 | // For more comprehensive examples of custom 7 | // commands please read more here: 8 | // https://on.cypress.io/custom-commands 9 | // *********************************************** 10 | // 11 | // 12 | // -- This is a parent command -- 13 | // Cypress.Commands.add('login', (email, password) => { ... }) 14 | // 15 | // 16 | // -- This is a child command -- 17 | // Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... }) 18 | // 19 | // 20 | // -- This is a dual command -- 21 | // Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... }) 22 | // 23 | // 24 | // -- This will overwrite an existing command -- 25 | // Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) 26 | 27 | import "@testing-library/cypress/add-commands"; 28 | -------------------------------------------------------------------------------- /template/tests/e2e/support/e2e.ts: -------------------------------------------------------------------------------- 1 | // *********************************************************** 2 | // This example support/index.js is processed and 3 | // loaded automatically before your test files. 4 | // 5 | // This is a great place to put global configuration and 6 | // behavior that modifies Cypress. 7 | // 8 | // You can change the location of this file or turn off 9 | // automatically serving support files with the 10 | // 'supportFile' configuration option. 11 | // 12 | // You can read more here: 13 | // https://on.cypress.io/configuration 14 | // *********************************************************** 15 | 16 | // Import commands.js using ES2015 syntax: 17 | import "./commands"; 18 | -------------------------------------------------------------------------------- /template/tests/e2e/tests/home.spec.ts: -------------------------------------------------------------------------------- 1 | describe("The Home Page", () => { 2 | it("successfully loads", () => { 3 | cy.visit("/"); 4 | cy.findByRole("heading", { name: /🌱⚛️ Create React App Codely template example/i }).should( 5 | "exist" 6 | ); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /template/tests/e2e/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "noEmit": true, 5 | "types": ["cypress", "@testing-library/cypress"], 6 | "isolatedModules": false 7 | }, 8 | "include": ["../../node_modules/cypress", "./**/*.ts"] 9 | } 10 | -------------------------------------------------------------------------------- /template/tests/setupTests.ts: -------------------------------------------------------------------------------- 1 | import "@testing-library/jest-dom"; 2 | -------------------------------------------------------------------------------- /template/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": [ 5 | "dom", 6 | "dom.iterable", 7 | "esnext" 8 | ], 9 | "types": ["cypress"], 10 | "allowJs": true, 11 | "skipLibCheck": true, 12 | "esModuleInterop": true, 13 | "allowSyntheticDefaultImports": true, 14 | "strict": true, 15 | "forceConsistentCasingInFileNames": true, 16 | "noFallthroughCasesInSwitch": true, 17 | "module": "esnext", 18 | "moduleResolution": "node", 19 | "resolveJsonModule": true, 20 | "isolatedModules": true, 21 | "noEmit": true, 22 | "jsx": "react-jsx" 23 | }, 24 | "include": [ 25 | "src", 26 | "tests", 27 | "jest.config.js", 28 | "cypress.config.ts" 29 | ] 30 | } 31 | --------------------------------------------------------------------------------