diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index f894c59..f9ff945 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,8 +1,6 @@ -# Team Lead -* @carryall - -# Team Members -* @bterone @hanam1ni @hoangmirs @malparty @rosle @tyrro +# Team +# @carryall is the Team Lead and the others are team members +* @carryall @bterone @hanam1ni @hoangmirs @malparty @rosle @tyrro # Engineering Leads CODEOWNERS @nimblehq/engineering-leads diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..10ed800 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,40 @@ +name: Test + +on: push + +jobs: + test: + name: Bootstrap app, run linters and tests with Node ${{ matrix.node }} + runs-on: ubuntu-latest + strategy: + matrix: + node: [14, 16] + steps: + - name: Cancel Previous Runs + uses: styfle/cancel-workflow-action@0.9.1 + with: + access_token: ${{ github.token }} + + - name: Checkout + uses: actions/checkout@v2 + + - name: Setup node and restore cached dependencies + uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node }} + cache: 'npm' + + - name: Bootstrap React App + run: npx create-react-app test-app --template file:./ + + - name: Run linters + working-directory: ./test-app + run: npm run codebase:lint + + - name: Run unit tests + working-directory: ./test-app + run: npm run test + + - name: Run integration tests + working-directory: ./test-app + run: npm run cypress diff --git a/.gitignore b/.gitignore index 9f11b75..db1db1b 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,6 @@ +# dependencies +/node_modules + +# misc .idea/ +.DS_Store diff --git a/README.md b/README.md index fb0bff1..77bdda0 100644 --- a/README.md +++ b/README.md @@ -29,10 +29,6 @@ To use this template, add `--template nimble` when creating a new app from the ` ```sh npx create-react-app my-app --template nimble - -# or - -yarn create react-app my-app --template nimble ``` For more information about `create-react-app`, please refer to: @@ -67,10 +63,6 @@ To test the template locally, simply run the template install command with the p ```sh npx create-react-app my-app --template file:{../path/to/your/local/template/repo} - -# or - -yarn create react-app my-app --template file:{../path/to/your/local/template/repo} ``` ## License diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..5326de6 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,16 @@ +{ + "name": "cra-template-nimble", + "version": "2.1.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "cra-template-nimble", + "version": "2.1.0", + "license": "MIT", + "engines": { + "node": "^14.18.2 || ^16 || ^17" + } + } + } +} diff --git a/package.json b/package.json index 315933a..5754d9e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cra-template-nimble", - "version": "2.1.0", + "version": "2.2.0", "keywords": [ "react", "create-react-app", diff --git a/template.json b/template.json index bb1e541..d9c2a19 100644 --- a/template.json +++ b/template.json @@ -2,67 +2,68 @@ "package": { "dependencies": { "@cypress/code-coverage": "3.9.12", - "@nimblehq/eslint-config-nimble": "2.2.1", + "@nimblehq/eslint-config-nimble-react": "^1.0.0", + "@nimblehq/stylelint-config-nimble": "^1.0.0", "@testing-library/cypress": "8.0.2", - "@testing-library/jest-dom": "5.11.4", - "@testing-library/react": "12.1.4", - "@testing-library/user-event": "13.5.0", + "@testing-library/jest-dom": "5.16.4", + "@testing-library/react": "13.1.1", + "@testing-library/user-event": "14.1.1", "@types/jest": "27.4.1", "@types/node": "17.0.21", "@types/react": "17.0.40", "@types/react-dom": "17.0.13", - "@typescript-eslint/eslint-plugin": "5.15.0", - "@typescript-eslint/parser": "5.15.0", "axios": "0.21.1", "cypress": "9.5.2", "cypress-react-selector": "2.3.16", "eslint": "8.11.0", - "eslint-config-prettier": "8.5.0", - "eslint-import-resolver-typescript": "2.5.0", - "eslint-plugin-cypress": "2.12.1", - "eslint-plugin-import": "2.25.4", - "eslint-plugin-jest": "26.1.1", - "eslint-plugin-jsx-a11y": "6.5.1", - "eslint-plugin-prettier": "4.0.0", - "eslint-plugin-react": "7.29.4", - "eslint-plugin-react-hooks": "4.3.0", "i18next": "21.6.14", "i18next-browser-languagedetector": "6.1.3", "i18next-http-backend": "1.4.0", - "node-sass": "7.0.1", "prettier": "2.6.0", "react-i18next": "11.16.1", + "react-router-dom": "6.3.0", + "sass": "1.49.11", "stylelint": "14.6.0", - "stylelint-config-property-sort-order-smacss": "9.0.0", - "stylelint-config-sass-guidelines": "9.0.1", - "stylelint-order": "5.0.0", - "stylelint-scss": "4.2.0", "typescript": "4.6.2", "web-vitals": "2.1.4" }, "scripts": { "start": "react-scripts -r @cypress/instrument-cra start", - "test:coverage": "react-scripts test --coverage --watchAll=false && yarn cypress:run && node ./scripts/coverage-merge.js && nyc report", + "test:coverage": "react-scripts test --coverage --watchAll=false && npm run cypress:run && node ./scripts/coverage-merge.js && nyc report", + "test:merge-coverage": "node ./scripts/coverage-merge.js", "lint": "eslint ./src ./cypress --ext .ts,.tsx", "lint:fix": "eslint ./src ./cypress --ext .ts,.tsx --fix", "stylelint": "stylelint '**/*.scss'", "stylelint:fix": "stylelint '**/*.scss' --fix", - "codebase:lint": "yarn lint && yarn stylelint", - "codebase:fix": "yarn lint:fix && yarn stylelint:fix", + "codebase:lint": "npm run lint && npm run stylelint", + "codebase:fix": "npm run lint:fix && npm run stylelint:fix", + "cypress": "start-server-and-test start 3000 cypress:run", "cypress:run": "cypress run", "cypress:open": "cypress open" }, "jest": { - "collectCoverageFrom": ["src/**/*.{js,jsx,ts,tsx}", "!src/**/*.d.ts"], - "coverageReporters": ["json"] + "collectCoverageFrom": [ + "src/**/*.{js,jsx,ts,tsx}", + "!src/**/*.d.ts" + ], + "coverageReporters": [ + "json" + ] }, "nyc": { "report-dir": "coverage/cypress", - "exclude": ["src/reportWebVitals.ts"], + "exclude": [ + "src/reportWebVitals.ts" + ], "excludeAfterRemap": true }, "devDependencies": { - "@cypress/instrument-cra": "1.4.0" + "@cypress/instrument-cra": "1.4.0", + "danger": "10.9.0", + "danger-plugin-code-coverage": "1.1.9", + "danger-plugin-istanbul-coverage": "1.6.2", + "danger-plugin-jest-codecov": "0.0.8", + "start-server-and-test": "1.14.0" } } } diff --git a/template/.eslintrc.js b/template/.eslintrc.js index 47df027..af73112 100644 --- a/template/.eslintrc.js +++ b/template/.eslintrc.js @@ -1,94 +1,3 @@ module.exports = { - env: { - es6: true, - browser: true, - node: true, - jest: true, - }, - extends: [ - '@nimblehq/eslint-config-nimble', - 'plugin:react/recommended', - 'plugin:react-hooks/recommended', - 'plugin:@typescript-eslint/recommended', - 'plugin:jsx-a11y/recommended', - 'plugin:import/errors', - 'plugin:prettier/recommended', - ], - overrides: [ - { - files: 'src/tests/**/*.test.ts', - extends: ['plugin:jest/recommended', 'plugin:jest/style'], - }, - { - files: 'cypress/**/*.ts', - extends: ['plugin:cypress/recommended'], - }, - ], - parser: '@typescript-eslint/parser', - parserOptions: { - ecmaVersion: 6, - sourceType: 'module', - ecmaFeatures: { - jsx: true, - }, - }, - rules: { - 'react-hooks/rules-of-hooks': 'error', - 'react-hooks/exhaustive-deps': 'warn', - 'react/jsx-filename-extension': [2, { extensions: ['.tsx'] }], - 'import/order': [ - 'error', - { - groups: ['builtin', 'external', 'internal'], - pathGroups: [ - { - pattern: 'react*', - group: 'external', - position: 'before', - }, - { - pattern: 'css/*|*.scss|*.svg|.png', - group: 'internal', - position: 'after', - }, - ], - pathGroupsExcludedImportTypes: ['react'], - 'newlines-between': 'always', - alphabetize: { - order: 'asc', - caseInsensitive: true, - }, - }, - ], - 'import/extensions': [ - 'error', - 'never', - { - scss: 'always', - svg: 'always', - png: 'always', - json: 'always', - spec: 'always', - }, - ], - 'no-use-before-define': 'off', - 'no-unused-vars': 'off', - 'no-shadow': 'off', - '@typescript-eslint/no-shadow': 'error', - '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }], - '@typescript-eslint/no-use-before-define': ['error'], - 'prettier/prettier': ['error'], - }, - settings: { - react: { - version: 'detect', - }, - 'import/resolver': { - typescript: {}, - node: { - extensions: ['.js', '.jsx', '.ts', '.tsx'], - moduleDirectory: ['node_modules', 'src/'], - }, - }, - }, -} + extends: ['@nimblehq/eslint-config-nimble-react'], +}; diff --git a/template/.github/workflows/deploy.yml b/template/.github/workflows/deploy.yml new file mode 100644 index 0000000..185b30b --- /dev/null +++ b/template/.github/workflows/deploy.yml @@ -0,0 +1,40 @@ +name: Deploy to Netlify + +on: + push: + branches: ['main', 'master'] + workflow_dispatch: + inputs: + deploy-msg: + description: 'Deploy Message (visible in Netlify)' + required: true + +jobs: + deploy: + name: Build and Deploy to Netlify + runs-on: ubuntu-18.04 + steps: + - name: Cancel Previous Runs + uses: styfle/cancel-workflow-action@0.9.1 + with: + access_token: ${{ github.token }} + + - uses: actions/checkout@v2 + + - name: Install modules + run: npm ci + + - name: Build + run: npm run build + + - name: Deploy to Netlify + uses: nwtgck/actions-netlify@v1.2 + with: + publish-dir: './build' + deploy-message: "Deploy from GitHub Actions: ${{ github.event.inputs.deploy-msg }}" + production-deploy: true + github-token: ${{ secrets.GITHUB_TOKEN }} + env: + NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} + NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }} + timeout-minutes: 1 diff --git a/template/.github/workflows/deploy_preview.yml b/template/.github/workflows/deploy_preview.yml new file mode 100644 index 0000000..fa61929 --- /dev/null +++ b/template/.github/workflows/deploy_preview.yml @@ -0,0 +1,32 @@ +name: Deploy Preview to Netlify + +on: [pull_request, workflow_dispatch] + +jobs: + deploy-preview: + name: Build and Deploy preview on Netlify + runs-on: ubuntu-18.04 + steps: + - name: Cancel Previous Runs + uses: styfle/cancel-workflow-action@0.9.1 + with: + access_token: ${{ github.token }} + + - uses: actions/checkout@v2 + + - name: Install modules + run: npm ci + + - name: Build + run: npm run build + + - name: Deploy to Netlify + uses: nwtgck/actions-netlify@v1.2 + with: + publish-dir: './build' + deploy-message: '#${{ github.event.pull_request.number }} - ${{ github.event.pull_request.title }}' + github-token: ${{ secrets.GITHUB_TOKEN }} + env: + NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} + NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }} + timeout-minutes: 1 diff --git a/template/.github/workflows/test.yml b/template/.github/workflows/test.yml new file mode 100644 index 0000000..2fdc703 --- /dev/null +++ b/template/.github/workflows/test.yml @@ -0,0 +1,42 @@ +name: Test + +on: pull_request + +jobs: + test: + name: Run linters and tests + runs-on: ubuntu-latest + steps: + - name: Cancel Previous Runs + uses: styfle/cancel-workflow-action@0.9.1 + with: + access_token: ${{ github.token }} + + - name: Checkout + uses: actions/checkout@v2 + + - name: Setup node and restore cached dependencies + uses: actions/setup-node@v2 + with: + node-version: '16' + cache: 'npm' + + - name: Install dependencies + run: npm ci + + - name: Run linter + run: npm run codebase:lint + + - name: Run unit tests + run: npm test -- --coverage + + - name: Run integration tests + run: npm run cypress + + - name: Merge code coverage reports + run: npm run test:merge-coverage + + - name: Danger + run: npx danger ci + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/template/.gitlab/merge_request_templates/Default.md b/template/.gitlab/merge_request_templates/Default.md new file mode 100644 index 0000000..feb41aa --- /dev/null +++ b/template/.gitlab/merge_request_templates/Default.md @@ -0,0 +1,20 @@ +{COPY THE TASK URL HERE} + +## What happened 👀 + +Describe the big picture of your changes here to communicate to the team why we should accept this pull request. + +## Insight 📝 + +Describe in detail how to test the changes, which solution you tried but did not go with, referenced documentation is welcome as well. + +## Proof Of Work 📹 + +Show us the implementation: screenshots, GIFs, etc. + +## Reviewers ✅ + +Mention the reviewers here once the merge request is ready for review. + + +/label ~"status : wip" diff --git a/template/.gitlab/merge_request_templates/Release.md b/template/.gitlab/merge_request_templates/Release.md new file mode 100644 index 0000000..fbc43e3 --- /dev/null +++ b/template/.gitlab/merge_request_templates/Release.md @@ -0,0 +1,22 @@ +## Features + +Provide the ID and title of each issue in the section for each type (feature, chore and bug). The link is optional. + +- [{ISSUE ID}] {ISSUE TITLE} +or +- [[{ISSUE ID}]]({ISSUE LINK})] {ISSUE TITLE} + +## Chores + +- Same structure as in ## Feature + +## Bugs + +- Same structure as in ## Feature + +## Reviewers ✅ + +Mention the reviewers here once the merge request is ready for review. + + +/label ~"type : release" diff --git a/template/.tool-versions b/template/.tool-versions new file mode 100644 index 0000000..0094556 --- /dev/null +++ b/template/.tool-versions @@ -0,0 +1 @@ +nodejs 16.14.2 diff --git a/template/README.md b/template/README.md index 63ea4b0..c217219 100644 --- a/template/README.md +++ b/template/README.md @@ -6,40 +6,40 @@ This project was bootstrapped with [Nimble React template](https://github.com/ni In the project directory, you can run: -`yarn start`: Runs the app in the development mode. Open [http://localhost:3000](http://localhost:3000) to view it in the browser. +`npm start`: Runs the app in the development mode. Open [http://localhost:3000](http://localhost:3000) to view it in the browser. -`yarn test`: Launches the test runner in the interactive watch mode. See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. +`npm test`: Launches the test runner in the interactive watch mode. See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. -`yarn test:coverage`: Both Unit Tests (Jest) and UI Tests (cypress) generate test coverage analytics. The below command runs all tests and merges both coverage files into a single report. +`npm run test:coverage`: Both Unit Tests (Jest) and UI Tests (cypress) generate test coverage analytics. The below command runs all tests and merges both coverage files into a single report. > Use the `.nyc_output/out.json` artefact in your CI/CD pipeline to reuse the code coverage data. -`yarn build`: Builds the app for production to the `build` folder. It correctly bundles React in production mode and +`npm run build`: Builds the app for production to the `build` folder. It correctly bundles React in production mode and optimizes the build for the best performance. The build is minified and the filenames include the hashes. Your app is ready to be deployed! See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. -`yarn eject`: If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This +`npm run eject`: If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. **Note: this is a one-way operation. Once you `eject`, you can’t go back!** -`yarn lint`: Run ESLint in the project. +`npm run lint`: Run ESLint in the project. -`yarn lint:fix`: Fix auto-correctable ESLint errors in the project. +`npm run lint:fix`: Fix auto-correctable ESLint errors in the project. -`yarn stylelint`: Run Stylelint in the project. +`npm run stylelint`: Run Stylelint in the project. -`yarn stylelint:fix`: Fix auto-correctable Stylelint errors in the project. +`npm run stylelint:fix`: Fix auto-correctable Stylelint errors in the project. -`yarn codebase:lint`: Run ESLint and Stylelint together in the project. +`npm run codebase:lint`: Run ESLint and Stylelint together in the project. -`yarn codebase:fix`: Fix auto-correctable ESLint and Stylelint errors together in the project. +`npm run codebase:fix`: Fix auto-correctable ESLint and Stylelint errors together in the project. -`yarn cypress:run`: Runs Cypress tests to completion. By default, cypress run will run all tests headlessly in the Electron browser. [Check options](https://docs.cypress.io/guides/guides/command-line#cypress-run) +`npm run cypress:run`: Runs Cypress tests to completion. By default, cypress run will run all tests headlessly in the Electron browser. [Check options](https://docs.cypress.io/guides/guides/command-line#cypress-run) -`yarn cypress:open`: Opens the Cypress Test Runner. [Check options](https://docs.cypress.io/guides/guides/command-line#cypress-open) +`npm run cypress:open`: Opens the Cypress Test Runner. [Check options](https://docs.cypress.io/guides/guides/command-line#cypress-open) ## Localization @@ -55,6 +55,24 @@ To change the default fallback language - Either edit the value of the environment variable `REACT_APP_DEFAULT_LANGUAGE` (cf. the `env.example` file) - Either directly edit the const `DEFAULT_FALLBACK_LANGUAGE` in `src/i18n.ts` +## Deployment + +### GitHub Actions for Netlify + +The `.github/workflows` folder already includes GitHub Actions to deploy previews and releases of your app in Netlify. + +How to use it? + +1. Create a new empty application in Netlify (use Drag&Drop and drop their demo project) +2. Configure the following action secrets in the Github repository: + - `NETLIFY_SITE_ID` available in the `Site settings` tab. + - `NETLIFY_AUTH_TOKEN`: created under `User settings, Applications, Personal access tokens` +3. Push your code to the repository. + +Any push under `main` or `master` triggers a release in production. +Any push under another branch triggers a preview deployment. +Once a preview is deployed, the Preview URL is displayed in the Pull Request thread. + ## Learn More You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). diff --git a/template/dangerfile.ts b/template/dangerfile.ts new file mode 100644 index 0000000..caf6b5f --- /dev/null +++ b/template/dangerfile.ts @@ -0,0 +1,39 @@ +import { schedule } from 'danger'; +import { istanbulCoverage } from 'danger-plugin-istanbul-coverage'; + +schedule( + istanbulCoverage({ + // Set a custom success message + customSuccessMessage: 'Congrats, coverage is good', + + // Set a custom failure message + customFailureMessage: 'Coverage is a little low, take a look', + + // How to sort the entries in the table + entrySortMethod: 'least-coverage', // || 'alphabetically' || 'most-coverage' || 'largest-file-size' ||'smallest-file-size' || 'uncovered-lines' + + // Add a maximum number of entries to display + numberOfEntries: 15, + + // The location of the istanbul coverage file. + // coveragePath: './.nyc_output/out.json', // The merged JSON coverage data + // Alternatively, if you have multiple coverage summaries, you can merge them into one report + // coveragePaths: ["./coverage/reports/from-cypress.json", "./coverage/reports/from-jest.json"], + // You can also specify the format, instead of letting it be inferred from the file name + coveragePath: { path: './coverage/merged/lcov.info', type: 'lcov' /* || "json-summary" */ }, + + // Which set of files to summarise from the coverage file. + reportFileSet: 'all', // || "modified" || "created" || "createdOrModified" + + // What to do when the PR doesn't meet the minimum code coverage threshold + reportMode: 'message', // || "warn" || "fail" + + // Minimum coverage threshold percentages. Compared against the cumulative coverage of the reportFileSet. + threshold: { + statements: 80, + branches: 80, + functions: 80, + lines: 80, + }, + }) +); diff --git a/template/gitignore b/template/gitignore index 8f34940..e223f6b 100644 --- a/template/gitignore +++ b/template/gitignore @@ -22,8 +22,6 @@ .env.production.local npm-debug.log* -yarn-debug.log* -yarn-error.log* # editors .vscode diff --git a/template/public/index.html b/template/public/index.html index aa069f2..7e9a060 100644 --- a/template/public/index.html +++ b/template/public/index.html @@ -36,8 +36,8 @@ You can add webfonts, meta tags, or analytics to this file. The build step will place the bundled scripts into the tag. - To begin the development, run `npm start` or `yarn start`. - To create a production bundle, use `npm run build` or `yarn build`. + To begin the development, run `npm start`. + To create a production bundle, use `npm run build`. --> diff --git a/template/src/App.tsx b/template/src/App.tsx index e83b49b..c2ad7fe 100644 --- a/template/src/App.tsx +++ b/template/src/App.tsx @@ -1,24 +1,15 @@ import React from 'react'; -import { useTranslation } from 'react-i18next'; +import { useRoutes } from 'react-router-dom'; -import logo from './assets/images/logo.svg'; -import './dummy.scss'; -import './assets/stylesheets/application.scss'; +import 'dummy.scss'; +import 'assets/stylesheets/application.scss'; + +import routes from 'routes'; const App = (): JSX.Element => { - const { t } = useTranslation(); + const appRoutes = useRoutes(routes); - return ( -
-
- logo -

{t('sample_page.message', { codeSample: 'src/App.tsx' })}

- - {t('sample_page.learn_react')} - -
-
- ); + return <>{appRoutes}; }; export default App; diff --git a/template/src/index.tsx b/template/src/index.tsx index 5742c3d..a1465c2 100644 --- a/template/src/index.tsx +++ b/template/src/index.tsx @@ -1,5 +1,7 @@ import React, { Suspense } from 'react'; -import ReactDOM from 'react-dom'; +import { BrowserRouter } from 'react-router-dom'; + +import { createRoot } from 'react-dom/client'; import App from './App'; import configureI18n from './i18n'; @@ -7,13 +9,16 @@ import reportWebVitals from './reportWebVitals'; configureI18n(); -ReactDOM.render( +const container = document.getElementById('root') as HTMLElement; +const root = createRoot(container); +root.render( - + + + - , - document.getElementById('root') + ); // If you want to start measuring performance in your app, pass a function diff --git a/template/src/routes/index.tsx b/template/src/routes/index.tsx new file mode 100644 index 0000000..2e5b21a --- /dev/null +++ b/template/src/routes/index.tsx @@ -0,0 +1,13 @@ +import React from 'react'; +import { RouteObject } from 'react-router-dom'; + +import HomeScreen from 'screens/Home'; + +const routes: RouteObject[] = [ + { + path: '/', + element: , + }, +]; + +export default routes; diff --git a/template/src/screens/.keep b/template/src/screens/.keep deleted file mode 100644 index e69de29..0000000 diff --git a/template/src/App.test.tsx b/template/src/screens/Home.test.tsx similarity index 77% rename from template/src/App.test.tsx rename to template/src/screens/Home.test.tsx index 7551bb7..3a3202e 100644 --- a/template/src/App.test.tsx +++ b/template/src/screens/Home.test.tsx @@ -2,11 +2,11 @@ import React from 'react'; import { render, screen } from '@testing-library/react'; -import App from './App'; +import HomeScreen from './Home'; -describe('App', () => { +describe('HomeScreen', () => { it('renders learn react link', () => { - render(); + render(); const linkElement = screen.getByTestId('app-link'); diff --git a/template/src/screens/Home.tsx b/template/src/screens/Home.tsx new file mode 100644 index 0000000..472866a --- /dev/null +++ b/template/src/screens/Home.tsx @@ -0,0 +1,22 @@ +import React from 'react'; +import { useTranslation } from 'react-i18next'; + +import logo from 'assets/images/logo.svg'; + +const HomeScreen = (): JSX.Element => { + const { t } = useTranslation(); + + return ( +
+
+ logo +

{t('sample_page.message', { codeSample: 'src/App.tsx' })}

+ + {t('sample_page.learn_react')} + +
+
+ ); +}; + +export default HomeScreen; diff --git a/template/src/types/react-i18next.d.ts b/template/src/types/react-i18next.d.ts index 4eea285..49f9877 100644 --- a/template/src/types/react-i18next.d.ts +++ b/template/src/types/react-i18next.d.ts @@ -1,4 +1,3 @@ -import 'react-i18next'; import { TFuncKey } from 'react-i18next'; import defaultRes from '../../public/locales/en/translation.json'; diff --git a/template/stylelint.config.js b/template/stylelint.config.js index c3b2213..b5f47e8 100644 --- a/template/stylelint.config.js +++ b/template/stylelint.config.js @@ -1,11 +1,3 @@ -// eslint-disable-next-line @typescript-eslint/no-var-requires -const sortOrderSmacss = require('stylelint-config-property-sort-order-smacss/generate') - module.exports = { - extends: ['stylelint-config-sass-guidelines'], - plugins: ['stylelint-scss', 'stylelint-order'], - rules: { - 'order/properties-alphabetical-order': null, - 'order/properties-order': [sortOrderSmacss({ emptyLineBefore: 'always' })] - } -} + extends: ['@nimblehq/stylelint-config-nimble'], +}; diff --git a/template/tsconfig.json b/template/tsconfig.json new file mode 100644 index 0000000..a74041b --- /dev/null +++ b/template/tsconfig.json @@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "baseUrl": "src", + } +}