├── .editorconfig ├── .eslintrc.cjs ├── .gitignore ├── .prettierrc ├── .storybook ├── main.ts ├── manager.ts └── preview.ts ├── .vscode ├── cs.code-snippets ├── extensions.json ├── fc.code-snippets └── sb.code-snippets ├── README.md ├── index.html ├── package.json ├── postcss.config.js ├── public └── vite.svg ├── src ├── App.tsx ├── assets │ └── react.svg ├── components │ └── .txt ├── contexts │ └── .txt ├── helpers │ └── .txt ├── index.css ├── main.tsx ├── pages │ └── home.tsx ├── routes.tsx ├── services │ └── .txt ├── types │ └── .txt └── vite-env.d.ts ├── tailwind.config.js ├── tsconfig.json ├── tsconfig.node.json ├── vite.config.ts └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: https://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | [*] 7 | indent_style = tab 8 | indent_size = 2 9 | end_of_line = lf 10 | charset = utf-8 11 | trim_trailing_whitespace = true 12 | insert_final_newline = false -------------------------------------------------------------------------------- /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { browser: true, es2020: true }, 4 | extends: ["@rocketseat/eslint-config/react", "plugin:storybook/recommended"], 5 | ignorePatterns: ['node_modules', 'dist', '.eslintrc.cjs'], 6 | parser: '@typescript-eslint/parser', 7 | plugins: ['react-refresh'], 8 | rules: { 9 | 'react-refresh/only-export-components': [ 10 | 'warn', 11 | { allowConstantExport: true }, 12 | ] 13 | }, 14 | } 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | .yarn 15 | 16 | # Editor directories and files 17 | .idea 18 | .DS_Store 19 | *.suo 20 | *.ntvs* 21 | *.njsproj 22 | *.sln 23 | *.sw? 24 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["prettier-plugin-tailwindcss"] 3 | } -------------------------------------------------------------------------------- /.storybook/main.ts: -------------------------------------------------------------------------------- 1 | import type { StorybookConfig } from '@storybook/react-vite'; 2 | 3 | const config: StorybookConfig = { 4 | "stories": [ 5 | "../src/**/*.mdx", 6 | "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)" 7 | ], 8 | "addons": [ 9 | "@storybook/addon-links", 10 | "@storybook/addon-essentials", 11 | "@storybook/addon-onboarding", 12 | "@storybook/addon-interactions" 13 | ], 14 | "framework": { 15 | "name": "@storybook/react-vite", 16 | "options": {} 17 | }, 18 | "docs": { 19 | "autodocs": "tag" 20 | } 21 | }; 22 | export default config; -------------------------------------------------------------------------------- /.storybook/manager.ts: -------------------------------------------------------------------------------- 1 | import { addons } from '@storybook/manager-api'; 2 | import { themes } from '@storybook/theming'; 3 | 4 | addons.setConfig({ 5 | theme: themes.dark, 6 | }); -------------------------------------------------------------------------------- /.storybook/preview.ts: -------------------------------------------------------------------------------- 1 | import '@/index.css' 2 | 3 | import type { Preview } from '@storybook/react' 4 | import { themes } from '@storybook/theming' 5 | 6 | const preview: Preview = { 7 | parameters: { 8 | actions: { argTypesRegex: '^on[A-Z].*' }, 9 | controls: { 10 | matchers: { 11 | color: /(background|color)$/i, 12 | date: /Date$/i, 13 | }, 14 | }, 15 | docs: { 16 | theme: themes.dark 17 | } 18 | }, 19 | }; 20 | 21 | export default preview; -------------------------------------------------------------------------------- /.vscode/cs.code-snippets: -------------------------------------------------------------------------------- 1 | { 2 | "Create Functional Component File Setup": { 3 | "scope": "javascript, typescript, typescriptreact, javascriptreact", 4 | "prefix": "cs", 5 | "body": [ 6 | "const [$1, set${2:$1}] = useState<$3>($4)", 7 | ], 8 | "description": "Snippet to initial setup to functional component file" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "editorconfig.editorconfig", 4 | "dbaeumer.vscode-eslint", 5 | "bradlc.vscode-tailwindcss" 6 | ] 7 | } -------------------------------------------------------------------------------- /.vscode/fc.code-snippets: -------------------------------------------------------------------------------- 1 | { 2 | "Create Functional Component File Setup": { 3 | "scope": "javascript, typescript, typescriptreact", 4 | "prefix": "fc", 5 | "body": [ 6 | "export interface ${1:${TM_FILENAME_BASE}}Props {}", 7 | "", 8 | "export const ${1:${TM_FILENAME_BASE}}: React.FC<${1:${TM_FILENAME_BASE}}Props> = () => {", 9 | " return (", 10 | "
", 11 | "

$1

", 12 | "
", 13 | " )", 14 | "}", 15 | "" 16 | ], 17 | "description": "Snippet to initial setup to functional component file" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /.vscode/sb.code-snippets: -------------------------------------------------------------------------------- 1 | { 2 | "Create StoryBook Initial Setup": { 3 | "scope": "javascript, typescript, typescriptreact, javascriptreact", 4 | "prefix": "sb", 5 | "body": [ 6 | "import { Meta, StoryObj } from '@storybook/react'", 7 | "", 8 | "export default {", 9 | " title: 'Component/${1:ComponentName}',", 10 | " component: ${2:ComponentName},", 11 | "} as Meta", 12 | "", 13 | "export const Default: StoryObj = {}" 14 | ], 15 | "description": "Snippet to initial setup StorybookFile" 16 | }, 17 | 18 | "Create StoryBook Variant": { 19 | "scope": "javascript, typescript, typescriptreact, javascriptreact", 20 | "prefix": "sbv", 21 | "body": [ 22 | "export const ${1:Default}: StoryObj = {}" 23 | ], 24 | "description": "Snippet create an storybook variant" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React + Tailwind + Eslint/Prettier 2 | 3 | This template provides a basic setup for working with `React` (Vite). Here we use `tailwind` for styles, `Axios` and `tanstack/react-query` for data fetching and we use `rocketseat/eslint-config` for eslint (with prettier plugin) to promote better code standardization. 4 |
5 | 6 | Additionally, we provide some `aliases` to make it easier to import folders. 7 | 8 | - [@vite](https://vitejs.dev/) 9 | - [@tailwind](https://tailwindcss.com/docs/guides/vite) 10 | - [@Axios](https://axios-http.com/ptbr/docs/intro) 11 | - [@React Query](https://tanstack.com/query/latest/docs/react/overview) 12 | - [@Storybook](https://storybook.js.org/docs/react/get-started/install/) 13 | - [@eslint](https://eslint.org/) 14 | - [@prettier](https://prettier.io/) 15 | - [@rocketseat-eslint-config](https://github.com/Rocketseat/eslint-config-rocketseat.git) 16 | 17 |
18 | 19 | ## To use this template you need to follow the next steps 20 | 21 | ```bash 22 | git clone https://github.com/Bkuste2/react-tailwind-template.git 23 | cd react-tailwind-template 24 | yarn install 25 | yarn dev 26 | ``` 27 | 28 |
29 | 30 | ## Aliases 31 | 32 | These aliases are pre-configured in the project to help you with development 33 | 34 | - @ 35 | - @pages 36 | - @components 37 | - @services 38 | - @contexts 39 | - @helpers 40 | - @types 41 | 42 | If you want to create any alias, just follow the example below: 43 | 44 | - `vite.config.ts` 45 | 46 | ```javascript 47 | export default defineConfig({ 48 | /* rest of your defineConfig function */ 49 | resolve: { 50 | alias: { 51 | '@': resolve(__dirname, './src'), // example 52 | 'your_alias': resolve(__dirname, 'folder_path'), 53 | }, 54 | }, 55 | 56 | }) 57 | ``` 58 | 59 | - `tsconfig.json` 60 | 61 | ```json 62 | { 63 | "compilerOptions": { 64 | "paths": { 65 | "@/*": ["./src/*"], // example 66 | "your_alias/*": ["folder_path/*"] 67 | } 68 | } 69 | } 70 | ``` 71 | 72 |
73 | 74 | ## Snippets 75 | 76 | ### fc 77 | 78 | Create a simple functional component initial setup 79 | 80 | ```javascript 81 | export interface FilenameProps {} 82 | 83 | export const Filename: React.FC = () => { 84 | return ( 85 |
86 |

Filename

87 |
88 | ) 89 | } 90 | ``` 91 | 92 |
93 | 94 | ### cs 95 | 96 | Create all useState structure 97 | 98 | ```javascript 99 | const [$1, set${2:$1}] = useState<$3>($4) 100 | ``` 101 | 102 |
103 | 104 | ### sb 105 | 106 | Snippet to initial setup StorybookFile 107 | 108 | ```javascript 109 | import { Meta, StoryObj } from '@storybook/react' 110 | 111 | export default { 112 | title: 'Component/ComponentName', 113 | component: ComponentName, 114 | } as Meta 115 | 116 | export const Default: StoryObj = {} 117 | ``` 118 | 119 |
120 | 121 | ### sbv 122 | 123 | Snippet create an storybook variant 124 | 125 | ```javascript 126 | export const ${1:Default}: StoryObj = {} 127 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + React + TS 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-tailwind-template", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "tsc && vite build", 9 | "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", 10 | "preview": "vite preview", 11 | "storybook": "storybook dev -p 6006", 12 | "build-storybook": "storybook build" 13 | }, 14 | "dependencies": { 15 | "@tanstack/react-query": "^5.7.0", 16 | "axios": "^1.6.0", 17 | "react": "^18.2.0", 18 | "react-dom": "^18.2.0", 19 | "react-router-dom": "^6.18.0" 20 | }, 21 | "@rocketseat/eslint-config": "^2.1.0", 22 | "devDependencies": { 23 | "@storybook/addon-essentials": "7.5.3", 24 | "@storybook/addon-interactions": "7.5.3", 25 | "@storybook/addon-links": "7.5.3", 26 | "@storybook/addon-onboarding": "1.0.8", 27 | "@storybook/blocks": "7.5.3", 28 | "@storybook/react": "7.5.3", 29 | "@storybook/react-vite": "7.5.3", 30 | "@storybook/testing-library": "0.2.2", 31 | "@types/node": "^20.8.10", 32 | "@types/react": "^18.2.15", 33 | "@types/react-dom": "^18.2.7", 34 | "@typescript-eslint/eslint-plugin": "^6.0.0", 35 | "@typescript-eslint/parser": "^6.0.0", 36 | "@vitejs/plugin-react": "^4.0.3", 37 | "autoprefixer": "^10.4.16", 38 | "eslint": "^8.52.0", 39 | "eslint-plugin-import": "^2.29.0", 40 | "eslint-plugin-react-hooks": "^4.6.0", 41 | "eslint-plugin-react-refresh": "^0.4.3", 42 | "eslint-plugin-storybook": "^0.6.15", 43 | "postcss": "^8.4.31", 44 | "prettier": "^3.0.3", 45 | "prettier-plugin-tailwindcss": "^0.5.6", 46 | "storybook": "7.5.3", 47 | "tailwindcss": "^3.3.5", 48 | "typescript": "^5.0.2", 49 | "vite": "^4.4.5" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/App.tsx: -------------------------------------------------------------------------------- 1 | import { QueryClient, QueryClientProvider } from '@tanstack/react-query' 2 | import { RouterProvider } from 'react-router-dom' 3 | import { router } from '@/routes' 4 | 5 | const queryClient = new QueryClient() 6 | 7 | export const App: React.FC = () => { 8 | return ( 9 | 10 | 11 | 12 | ) 13 | } 14 | -------------------------------------------------------------------------------- /src/assets/react.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bkuste2/react-tailwind-template/cd8f60f149cc3b7338ba76cc7abbb04975c846b0/src/components/.txt -------------------------------------------------------------------------------- /src/contexts/.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bkuste2/react-tailwind-template/cd8f60f149cc3b7338ba76cc7abbb04975c846b0/src/contexts/.txt -------------------------------------------------------------------------------- /src/helpers/.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bkuste2/react-tailwind-template/cd8f60f149cc3b7338ba76cc7abbb04975c846b0/src/helpers/.txt -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | * { 6 | @apply p-0 m-0 box-border; 7 | } 8 | 9 | html, body, #root { 10 | @apply h-full w-full; 11 | } -------------------------------------------------------------------------------- /src/main.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import './index.css' 4 | import { App } from '@/App' 5 | 6 | 7 | ReactDOM.createRoot(document.getElementById('root')!).render( 8 | 9 | 10 | , 11 | ) 12 | -------------------------------------------------------------------------------- /src/pages/home.tsx: -------------------------------------------------------------------------------- 1 | import { useQuery } from '@tanstack/react-query' 2 | import axios from 'axios' 3 | 4 | export interface HomeProps {} 5 | 6 | export const Home: React.FC = () => { 7 | const getTodo = async () => { 8 | return axios 9 | .get('https://jsonplaceholder.typicode.com/todos/1') 10 | .then((res) => res.data) 11 | } 12 | 13 | const { data, isFetched } = useQuery({ 14 | queryKey: ['getTodo'], 15 | queryFn: getTodo, 16 | }) 17 | 18 | return ( 19 |
20 |

Home

21 | {isFetched &&
{JSON.stringify(data, null, 2)}
} 22 |
23 | ) 24 | } 25 | -------------------------------------------------------------------------------- /src/routes.tsx: -------------------------------------------------------------------------------- 1 | import { createBrowserRouter } from 'react-router-dom' 2 | import { Home } from '@pages/home' 3 | 4 | /* v6 https://reactrouter.com/en/main/upgrading/v6-data */ 5 | 6 | export const router = createBrowserRouter([ 7 | { path: '/', Component: Home }, 8 | /* ... all other routes */ 9 | ]) 10 | -------------------------------------------------------------------------------- /src/services/.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bkuste2/react-tailwind-template/cd8f60f149cc3b7338ba76cc7abbb04975c846b0/src/services/.txt -------------------------------------------------------------------------------- /src/types/.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bkuste2/react-tailwind-template/cd8f60f149cc3b7338ba76cc7abbb04975c846b0/src/types/.txt -------------------------------------------------------------------------------- /src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | export default { 3 | content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'], 4 | theme: { 5 | extend: {}, 6 | }, 7 | plugins: [], 8 | } 9 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "noEmit": true, 15 | "jsx": "react-jsx", 16 | 17 | /* Linting */ 18 | "strict": true, 19 | "noUnusedLocals": true, 20 | "noUnusedParameters": true, 21 | "noFallthroughCasesInSwitch": true, 22 | 23 | /* Aliases */ 24 | "paths": { 25 | "@/*": ["./src/*"], 26 | "@pages/*": ["./src/pages/*"], 27 | "@components/*": ["./src/components/*"], 28 | "@services": ["./src/services/*"], 29 | "@contexts": ["./src/contexts/*"], 30 | "@helpers/*": ["./src/helpers/*"], 31 | "@types/*": ["./src/types/*"], 32 | } 33 | }, 34 | "include": ["src"], 35 | "references": [{ "path": "./tsconfig.node.json" }] 36 | } 37 | -------------------------------------------------------------------------------- /tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "skipLibCheck": true, 5 | "module": "ESNext", 6 | "moduleResolution": "bundler", 7 | "allowSyntheticDefaultImports": true 8 | }, 9 | "include": ["vite.config.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | import { resolve } from 'path' 4 | 5 | // https://vitejs.dev/config/ 6 | export default defineConfig({ 7 | resolve: { 8 | alias: { 9 | '@': resolve(__dirname, './src'), 10 | '@pages': resolve(__dirname, './src/pages'), 11 | '@components': resolve(__dirname, './src/components'), 12 | '@services': resolve(__dirname, './src/services'), 13 | '@contexts': resolve(__dirname, './src/contexts'), 14 | '@helpers': resolve(__dirname, './src/helpers'), 15 | '@types': resolve(__dirname, './src/types'), 16 | }, 17 | }, 18 | plugins: [react()], 19 | }) 20 | --------------------------------------------------------------------------------