├── .editorconfig
├── .gitignore
├── .vscode
└── settings.json
├── @types
└── tailwind.macro.d.ts
├── README.md
├── babel-plugin-macros.config.ts
├── babel.config.ts
├── package.json
├── prettier.config.js
├── public
├── favicon.ico
├── index.html
├── logo192.png
├── logo512.png
├── manifest.json
└── robots.txt
├── src
├── App.test.tsx
├── App.tsx
├── index.tsx
├── react-app-env.d.ts
├── screens
│ └── Landing.tsx
├── serviceWorker.ts
└── styles
│ └── tailwind.config.js
├── tsconfig.json
└── yarn.lock
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | end_of_line = lf
5 | indent_style = tab
6 | indent_size = 2
7 | trim_trailing_whitespace = true
8 | insert_final_newline = true
9 | charset = utf-8
10 |
11 | [*.js]
12 | max_line_length = 100
13 |
--------------------------------------------------------------------------------
/.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 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "editor.formatOnSave": true,
3 | "editor.tabSize": 2
4 | // using https://github.com/prettier/prettier-vscode
5 | }
6 |
--------------------------------------------------------------------------------
/@types/tailwind.macro.d.ts:
--------------------------------------------------------------------------------
1 | declare module 'tailwind.macro'
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # React + TypeScript + Styled-Components + TailwindCSS Boilerplate
2 |
3 | > Boilerplate for getting started with a TypeScript based React ([CRA](https://github.com/facebook/create-react-app)) project with Tailwind and Styled-Components. Also includes editorconfig, prettier and HMR.
4 |
5 | This is the setup I used to start an old project of mine using these technologies. There were no tutorials available on the Internet so it took some time to get up and running. I hope this repository helps anyone looking to use the same tech.
6 |
7 | **Check out the [commits](https://github.com/aviaryan/react-typescript-tailwind-styled-components/commits/master) to understand individual steps.**
8 |
9 | ### Running the project
10 |
11 | ```sh
12 | yarn start
13 | ```
14 |
--------------------------------------------------------------------------------
/babel-plugin-macros.config.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | tailwind: {
3 | config: './src/styles/tailwind.config.js',
4 | format: 'auto',
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/babel.config.ts:
--------------------------------------------------------------------------------
1 | export const plugins = ['react-hot-loader/babel', 'syntax-object-rest-spread', 'macros']
2 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "baas-frontend",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "react": "^16.10.1",
7 | "react-dom": "^16.10.1",
8 | "react-scripts": "3.2.0",
9 | "styled-components": "^4.4.0"
10 | },
11 | "scripts": {
12 | "start": "react-scripts start",
13 | "build": "react-scripts build",
14 | "test": "react-scripts test",
15 | "eject": "react-scripts eject"
16 | },
17 | "eslintConfig": {
18 | "extends": "react-app"
19 | },
20 | "browserslist": {
21 | "production": [
22 | ">0.2%",
23 | "not dead",
24 | "not op_mini all"
25 | ],
26 | "development": [
27 | "last 1 chrome version",
28 | "last 1 firefox version",
29 | "last 1 safari version"
30 | ]
31 | },
32 | "devDependencies": {
33 | "@babel/plugin-syntax-object-rest-spread": "^7.2.0",
34 | "@types/jest": "24.0.18",
35 | "@types/node": "12.7.9",
36 | "@types/react": "16.9.4",
37 | "@types/react-dom": "16.9.1",
38 | "@types/styled-components": "^4.1.19",
39 | "babel-plugin-macros": "^2.6.1",
40 | "react-hot-loader": "^4.12.15",
41 | "tailwind.macro": "^1.0.0-alpha.10",
42 | "tailwindcss": "^1.1.2",
43 | "typescript": "3.6.3"
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/prettier.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | endOfLine: "lf",
3 | semi: false,
4 | singleQuote: true,
5 | useTabs: true,
6 | tabWidth: 2,
7 | jsxSingleQuote: true,
8 | printWidth: 100,
9 | bracketSpacing: true,
10 | trailingComma: "es5"
11 | };
12 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aviaryan/react-typescript-tailwind-styled-components/2d01c480c73481ce4a66c55df2b7328d3ab758c5/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
14 |
15 |
24 | React App
25 |
26 |
27 |
28 |
29 |
39 |
40 |
--------------------------------------------------------------------------------
/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aviaryan/react-typescript-tailwind-styled-components/2d01c480c73481ce4a66c55df2b7328d3ab758c5/public/logo192.png
--------------------------------------------------------------------------------
/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aviaryan/react-typescript-tailwind-styled-components/2d01c480c73481ce4a66c55df2b7328d3ab758c5/public/logo512.png
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 |
--------------------------------------------------------------------------------
/src/App.test.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import ReactDOM from 'react-dom'
3 | import App from './App'
4 |
5 | it('renders without crashing', () => {
6 | const div = document.createElement('div')
7 | ReactDOM.render(, div)
8 | ReactDOM.unmountComponentAtNode(div)
9 | })
10 |
--------------------------------------------------------------------------------
/src/App.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { createGlobalStyle } from 'styled-components'
3 | import Landing from './screens/Landing'
4 |
5 | const GlobalStyle = createGlobalStyle`
6 | body {
7 | margin: 0;
8 | padding: 0;
9 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;
10 | -webkit-font-smoothing: antialiased;
11 | -moz-osx-font-smoothing: grayscale;
12 | font-size: 20px;
13 | }
14 | `
15 |
16 | const App: React.FC = () => {
17 | return (
18 |
19 |
20 |
21 |
22 | )
23 | }
24 |
25 | export default App
26 |
--------------------------------------------------------------------------------
/src/index.tsx:
--------------------------------------------------------------------------------
1 | import { hot } from 'react-hot-loader/root'
2 | import React from 'react'
3 | import ReactDOM from 'react-dom'
4 | import App from './App'
5 | import * as serviceWorker from './serviceWorker'
6 |
7 | const HotApp = hot(App)
8 |
9 | ReactDOM.render(, document.getElementById('root'))
10 |
11 | // If you want your app to work offline and load faster, you can change
12 | // unregister() to register() below. Note this comes with some pitfalls.
13 | // Learn more about service workers: https://bit.ly/CRA-PWA
14 | serviceWorker.unregister()
15 |
--------------------------------------------------------------------------------
/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/src/screens/Landing.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import styled from 'styled-components'
3 | import tw from 'tailwind.macro'
4 |
5 | const Container = styled.div`
6 | ${tw`font-mono text-blue-700 flex h-screen w-100 items-center flex-col justify-center`}
7 | `
8 |
9 | const Landing: React.FC = () => (
10 |
11 | Hello World
12 | React, TypeScript, Styled-Components + TailwindCSS - all up now
13 |
14 | )
15 |
16 | export default Landing
17 |
--------------------------------------------------------------------------------
/src/serviceWorker.ts:
--------------------------------------------------------------------------------
1 | // This optional code is used to register a service worker.
2 | // register() is not called by default.
3 |
4 | // This lets the app load faster on subsequent visits in production, and gives
5 | // it offline capabilities. However, it also means that developers (and users)
6 | // will only see deployed updates on subsequent visits to a page, after all the
7 | // existing tabs open on the page have been closed, since previously cached
8 | // resources are updated in the background.
9 |
10 | // To learn more about the benefits of this model and instructions on how to
11 | // opt-in, read https://bit.ly/CRA-PWA
12 |
13 | const isLocalhost = Boolean(
14 | window.location.hostname === 'localhost' ||
15 | // [::1] is the IPv6 localhost address.
16 | window.location.hostname === '[::1]' ||
17 | // 127.0.0.1/8 is considered localhost for IPv4.
18 | window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/)
19 | )
20 |
21 | type Config = {
22 | onSuccess?: (registration: ServiceWorkerRegistration) => void
23 | onUpdate?: (registration: ServiceWorkerRegistration) => void
24 | }
25 |
26 | export function register(config?: Config) {
27 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
28 | // The URL constructor is available in all browsers that support SW.
29 | const publicUrl = new URL(
30 | (process as { env: { [key: string]: string } }).env.PUBLIC_URL,
31 | window.location.href
32 | )
33 | if (publicUrl.origin !== window.location.origin) {
34 | // Our service worker won't work if PUBLIC_URL is on a different origin
35 | // from what our page is served on. This might happen if a CDN is used to
36 | // serve assets; see https://github.com/facebook/create-react-app/issues/2374
37 | return
38 | }
39 |
40 | window.addEventListener('load', () => {
41 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`
42 |
43 | if (isLocalhost) {
44 | // This is running on localhost. Let's check if a service worker still exists or not.
45 | checkValidServiceWorker(swUrl, config)
46 |
47 | // Add some additional logging to localhost, pointing developers to the
48 | // service worker/PWA documentation.
49 | navigator.serviceWorker.ready.then(() => {
50 | console.log(
51 | 'This web app is being served cache-first by a service ' +
52 | 'worker. To learn more, visit https://bit.ly/CRA-PWA'
53 | )
54 | })
55 | } else {
56 | // Is not localhost. Just register service worker
57 | registerValidSW(swUrl, config)
58 | }
59 | })
60 | }
61 | }
62 |
63 | function registerValidSW(swUrl: string, config?: Config) {
64 | navigator.serviceWorker
65 | .register(swUrl)
66 | .then(registration => {
67 | registration.onupdatefound = () => {
68 | const installingWorker = registration.installing
69 | if (installingWorker == null) {
70 | return
71 | }
72 | installingWorker.onstatechange = () => {
73 | if (installingWorker.state === 'installed') {
74 | if (navigator.serviceWorker.controller) {
75 | // At this point, the updated precached content has been fetched,
76 | // but the previous service worker will still serve the older
77 | // content until all client tabs are closed.
78 | console.log(
79 | 'New content is available and will be used when all ' +
80 | 'tabs for this page are closed. See https://bit.ly/CRA-PWA.'
81 | )
82 |
83 | // Execute callback
84 | if (config && config.onUpdate) {
85 | config.onUpdate(registration)
86 | }
87 | } else {
88 | // At this point, everything has been precached.
89 | // It's the perfect time to display a
90 | // "Content is cached for offline use." message.
91 | console.log('Content is cached for offline use.')
92 |
93 | // Execute callback
94 | if (config && config.onSuccess) {
95 | config.onSuccess(registration)
96 | }
97 | }
98 | }
99 | }
100 | }
101 | })
102 | .catch(error => {
103 | console.error('Error during service worker registration:', error)
104 | })
105 | }
106 |
107 | function checkValidServiceWorker(swUrl: string, config?: Config) {
108 | // Check if the service worker can be found. If it can't reload the page.
109 | fetch(swUrl)
110 | .then(response => {
111 | // Ensure service worker exists, and that we really are getting a JS file.
112 | const contentType = response.headers.get('content-type')
113 | if (
114 | response.status === 404 ||
115 | (contentType != null && contentType.indexOf('javascript') === -1)
116 | ) {
117 | // No service worker found. Probably a different app. Reload the page.
118 | navigator.serviceWorker.ready.then(registration => {
119 | registration.unregister().then(() => {
120 | window.location.reload()
121 | })
122 | })
123 | } else {
124 | // Service worker found. Proceed as normal.
125 | registerValidSW(swUrl, config)
126 | }
127 | })
128 | .catch(() => {
129 | console.log('No internet connection found. App is running in offline mode.')
130 | })
131 | }
132 |
133 | export function unregister() {
134 | if ('serviceWorker' in navigator) {
135 | navigator.serviceWorker.ready.then(registration => {
136 | registration.unregister()
137 | })
138 | }
139 | }
140 |
--------------------------------------------------------------------------------
/src/styles/tailwind.config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | prefix: '',
3 | important: false,
4 | separator: ':',
5 | theme: {
6 | screens: {
7 | sm: '640px',
8 | md: '768px',
9 | lg: '1024px',
10 | xl: '1280px',
11 | },
12 | colors: {
13 | transparent: 'transparent',
14 |
15 | black: '#000',
16 | white: '#fff',
17 |
18 | gray: {
19 | 100: '#f7fafc',
20 | 200: '#edf2f7',
21 | 300: '#e2e8f0',
22 | 400: '#cbd5e0',
23 | 500: '#a0aec0',
24 | 600: '#718096',
25 | 700: '#4a5568',
26 | 800: '#2d3748',
27 | 900: '#1a202c',
28 | },
29 | red: {
30 | 100: '#fff5f5',
31 | 200: '#fed7d7',
32 | 300: '#feb2b2',
33 | 400: '#fc8181',
34 | 500: '#f56565',
35 | 600: '#e53e3e',
36 | 700: '#c53030',
37 | 800: '#9b2c2c',
38 | 900: '#742a2a',
39 | },
40 | orange: {
41 | 100: '#fffaf0',
42 | 200: '#feebc8',
43 | 300: '#fbd38d',
44 | 400: '#f6ad55',
45 | 500: '#ed8936',
46 | 600: '#dd6b20',
47 | 700: '#c05621',
48 | 800: '#9c4221',
49 | 900: '#7b341e',
50 | },
51 | yellow: {
52 | 100: '#fffff0',
53 | 200: '#fefcbf',
54 | 300: '#faf089',
55 | 400: '#f6e05e',
56 | 500: '#ecc94b',
57 | 600: '#d69e2e',
58 | 700: '#b7791f',
59 | 800: '#975a16',
60 | 900: '#744210',
61 | },
62 | green: {
63 | 100: '#f0fff4',
64 | 200: '#c6f6d5',
65 | 300: '#9ae6b4',
66 | 400: '#68d391',
67 | 500: '#48bb78',
68 | 600: '#38a169',
69 | 700: '#2f855a',
70 | 800: '#276749',
71 | 900: '#22543d',
72 | },
73 | teal: {
74 | 100: '#e6fffa',
75 | 200: '#b2f5ea',
76 | 300: '#81e6d9',
77 | 400: '#4fd1c5',
78 | 500: '#38b2ac',
79 | 600: '#319795',
80 | 700: '#2c7a7b',
81 | 800: '#285e61',
82 | 900: '#234e52',
83 | },
84 | blue: {
85 | 100: '#ebf8ff',
86 | 200: '#bee3f8',
87 | 300: '#90cdf4',
88 | 400: '#63b3ed',
89 | 500: '#4299e1',
90 | 600: '#3182ce',
91 | 700: '#2b6cb0',
92 | 800: '#2c5282',
93 | 900: '#2a4365',
94 | },
95 | indigo: {
96 | 100: '#ebf4ff',
97 | 200: '#c3dafe',
98 | 300: '#a3bffa',
99 | 400: '#7f9cf5',
100 | 500: '#667eea',
101 | 600: '#5a67d8',
102 | 700: '#4c51bf',
103 | 800: '#434190',
104 | 900: '#3c366b',
105 | },
106 | purple: {
107 | 100: '#faf5ff',
108 | 200: '#e9d8fd',
109 | 300: '#d6bcfa',
110 | 400: '#b794f4',
111 | 500: '#9f7aea',
112 | 600: '#805ad5',
113 | 700: '#6b46c1',
114 | 800: '#553c9a',
115 | 900: '#44337a',
116 | },
117 | pink: {
118 | 100: '#fff5f7',
119 | 200: '#fed7e2',
120 | 300: '#fbb6ce',
121 | 400: '#f687b3',
122 | 500: '#ed64a6',
123 | 600: '#d53f8c',
124 | 700: '#b83280',
125 | 800: '#97266d',
126 | 900: '#702459',
127 | },
128 | },
129 | spacing: {
130 | px: '1px',
131 | '0': '0',
132 | '1': '0.25rem',
133 | '2': '0.5rem',
134 | '3': '0.75rem',
135 | '4': '1rem',
136 | '5': '1.25rem',
137 | '6': '1.5rem',
138 | '8': '2rem',
139 | '10': '2.5rem',
140 | '12': '3rem',
141 | '16': '4rem',
142 | '20': '5rem',
143 | '24': '6rem',
144 | '32': '8rem',
145 | '40': '10rem',
146 | '48': '12rem',
147 | '56': '14rem',
148 | '64': '16rem',
149 | },
150 | backgroundColor: theme => theme('colors'),
151 | backgroundPosition: {
152 | bottom: 'bottom',
153 | center: 'center',
154 | left: 'left',
155 | 'left-bottom': 'left bottom',
156 | 'left-top': 'left top',
157 | right: 'right',
158 | 'right-bottom': 'right bottom',
159 | 'right-top': 'right top',
160 | top: 'top',
161 | },
162 | backgroundSize: {
163 | auto: 'auto',
164 | cover: 'cover',
165 | contain: 'contain',
166 | },
167 | borderColor: theme => ({
168 | ...theme('colors'),
169 | default: theme('colors.gray.300', 'currentColor'),
170 | }),
171 | borderRadius: {
172 | none: '0',
173 | sm: '0.125rem',
174 | default: '0.25rem',
175 | lg: '0.5rem',
176 | full: '9999px',
177 | },
178 | borderWidth: {
179 | default: '1px',
180 | '0': '0',
181 | '2': '2px',
182 | '4': '4px',
183 | '8': '8px',
184 | },
185 | boxShadow: {
186 | default: '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)',
187 | md: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)',
188 | lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',
189 | xl: '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',
190 | '2xl': '0 25px 50px -12px rgba(0, 0, 0, 0.25)',
191 | inner: 'inset 0 2px 4px 0 rgba(0, 0, 0, 0.06)',
192 | outline: '0 0 0 3px rgba(66, 153, 225, 0.5)',
193 | none: 'none',
194 | },
195 | container: {},
196 | cursor: {
197 | auto: 'auto',
198 | default: 'default',
199 | pointer: 'pointer',
200 | wait: 'wait',
201 | text: 'text',
202 | move: 'move',
203 | 'not-allowed': 'not-allowed',
204 | },
205 | fill: {
206 | current: 'currentColor',
207 | },
208 | flex: {
209 | '1': '1 1 0%',
210 | auto: '1 1 auto',
211 | initial: '0 1 auto',
212 | none: 'none',
213 | },
214 | flexGrow: {
215 | '0': '0',
216 | default: '1',
217 | },
218 | flexShrink: {
219 | '0': '0',
220 | default: '1',
221 | },
222 | fontFamily: {
223 | sans: [
224 | '-apple-system',
225 | 'BlinkMacSystemFont',
226 | '"Segoe UI"',
227 | 'Roboto',
228 | '"Helvetica Neue"',
229 | 'Arial',
230 | '"Noto Sans"',
231 | 'sans-serif',
232 | '"Apple Color Emoji"',
233 | '"Segoe UI Emoji"',
234 | '"Segoe UI Symbol"',
235 | '"Noto Color Emoji"',
236 | ],
237 | serif: [
238 | 'Georgia',
239 | 'Cambria',
240 | '"Times New Roman"',
241 | 'Times',
242 | 'serif',
243 | ],
244 | mono: [
245 | 'Menlo',
246 | 'Monaco',
247 | 'Consolas',
248 | '"Liberation Mono"',
249 | '"Courier New"',
250 | 'monospace',
251 | ],
252 | },
253 | fontSize: {
254 | xs: '0.75rem',
255 | sm: '0.875rem',
256 | base: '1rem',
257 | lg: '1.125rem',
258 | xl: '1.25rem',
259 | '2xl': '1.5rem',
260 | '3xl': '1.875rem',
261 | '4xl': '2.25rem',
262 | '5xl': '3rem',
263 | '6xl': '4rem',
264 | },
265 | fontWeight: {
266 | hairline: '100',
267 | thin: '200',
268 | light: '300',
269 | normal: '400',
270 | medium: '500',
271 | semibold: '600',
272 | bold: '700',
273 | extrabold: '800',
274 | black: '900',
275 | },
276 | height: theme => ({
277 | auto: 'auto',
278 | ...theme('spacing'),
279 | full: '100%',
280 | screen: '100vh',
281 | }),
282 | inset: {
283 | '0': '0',
284 | auto: 'auto',
285 | },
286 | letterSpacing: {
287 | tighter: '-0.05em',
288 | tight: '-0.025em',
289 | normal: '0',
290 | wide: '0.025em',
291 | wider: '0.05em',
292 | widest: '0.1em',
293 | },
294 | lineHeight: {
295 | none: '1',
296 | tight: '1.25',
297 | snug: '1.375',
298 | normal: '1.5',
299 | relaxed: '1.625',
300 | loose: '2',
301 | },
302 | listStyleType: {
303 | none: 'none',
304 | disc: 'disc',
305 | decimal: 'decimal',
306 | },
307 | margin: (theme, { negative }) => ({
308 | auto: 'auto',
309 | ...theme('spacing'),
310 | ...negative(theme('spacing')),
311 | }),
312 | maxHeight: {
313 | full: '100%',
314 | screen: '100vh',
315 | },
316 | maxWidth: {
317 | xs: '20rem',
318 | sm: '24rem',
319 | md: '28rem',
320 | lg: '32rem',
321 | xl: '36rem',
322 | '2xl': '42rem',
323 | '3xl': '48rem',
324 | '4xl': '56rem',
325 | '5xl': '64rem',
326 | '6xl': '72rem',
327 | full: '100%',
328 | },
329 | minHeight: {
330 | '0': '0',
331 | full: '100%',
332 | screen: '100vh',
333 | },
334 | minWidth: {
335 | '0': '0',
336 | full: '100%',
337 | },
338 | objectPosition: {
339 | bottom: 'bottom',
340 | center: 'center',
341 | left: 'left',
342 | 'left-bottom': 'left bottom',
343 | 'left-top': 'left top',
344 | right: 'right',
345 | 'right-bottom': 'right bottom',
346 | 'right-top': 'right top',
347 | top: 'top',
348 | },
349 | opacity: {
350 | '0': '0',
351 | '25': '0.25',
352 | '50': '0.5',
353 | '75': '0.75',
354 | '100': '1',
355 | },
356 | order: {
357 | first: '-9999',
358 | last: '9999',
359 | none: '0',
360 | '1': '1',
361 | '2': '2',
362 | '3': '3',
363 | '4': '4',
364 | '5': '5',
365 | '6': '6',
366 | '7': '7',
367 | '8': '8',
368 | '9': '9',
369 | '10': '10',
370 | '11': '11',
371 | '12': '12',
372 | },
373 | padding: theme => theme('spacing'),
374 | placeholderColor: theme => theme('colors'),
375 | stroke: {
376 | current: 'currentColor',
377 | },
378 | textColor: theme => theme('colors'),
379 | width: theme => ({
380 | auto: 'auto',
381 | ...theme('spacing'),
382 | '1/2': '50%',
383 | '1/3': '33.333333%',
384 | '2/3': '66.666667%',
385 | '1/4': '25%',
386 | '2/4': '50%',
387 | '3/4': '75%',
388 | '1/5': '20%',
389 | '2/5': '40%',
390 | '3/5': '60%',
391 | '4/5': '80%',
392 | '1/6': '16.666667%',
393 | '2/6': '33.333333%',
394 | '3/6': '50%',
395 | '4/6': '66.666667%',
396 | '5/6': '83.333333%',
397 | '1/12': '8.333333%',
398 | '2/12': '16.666667%',
399 | '3/12': '25%',
400 | '4/12': '33.333333%',
401 | '5/12': '41.666667%',
402 | '6/12': '50%',
403 | '7/12': '58.333333%',
404 | '8/12': '66.666667%',
405 | '9/12': '75%',
406 | '10/12': '83.333333%',
407 | '11/12': '91.666667%',
408 | full: '100%',
409 | screen: '100vw',
410 | }),
411 | zIndex: {
412 | auto: 'auto',
413 | '0': '0',
414 | '10': '10',
415 | '20': '20',
416 | '30': '30',
417 | '40': '40',
418 | '50': '50',
419 | },
420 | },
421 | variants: {
422 | accessibility: ['responsive', 'focus'],
423 | alignContent: ['responsive'],
424 | alignItems: ['responsive'],
425 | alignSelf: ['responsive'],
426 | appearance: ['responsive'],
427 | backgroundAttachment: ['responsive'],
428 | backgroundColor: ['responsive', 'hover', 'focus'],
429 | backgroundPosition: ['responsive'],
430 | backgroundRepeat: ['responsive'],
431 | backgroundSize: ['responsive'],
432 | borderCollapse: ['responsive'],
433 | borderColor: ['responsive', 'hover', 'focus'],
434 | borderRadius: ['responsive'],
435 | borderStyle: ['responsive'],
436 | borderWidth: ['responsive'],
437 | boxShadow: ['responsive', 'hover', 'focus'],
438 | cursor: ['responsive'],
439 | display: ['responsive'],
440 | fill: ['responsive'],
441 | flex: ['responsive'],
442 | flexDirection: ['responsive'],
443 | flexGrow: ['responsive'],
444 | flexShrink: ['responsive'],
445 | flexWrap: ['responsive'],
446 | float: ['responsive'],
447 | fontFamily: ['responsive'],
448 | fontSize: ['responsive'],
449 | fontSmoothing: ['responsive'],
450 | fontStyle: ['responsive'],
451 | fontWeight: ['responsive', 'hover', 'focus'],
452 | height: ['responsive'],
453 | inset: ['responsive'],
454 | justifyContent: ['responsive'],
455 | letterSpacing: ['responsive'],
456 | lineHeight: ['responsive'],
457 | listStylePosition: ['responsive'],
458 | listStyleType: ['responsive'],
459 | margin: ['responsive'],
460 | maxHeight: ['responsive'],
461 | maxWidth: ['responsive'],
462 | minHeight: ['responsive'],
463 | minWidth: ['responsive'],
464 | objectFit: ['responsive'],
465 | objectPosition: ['responsive'],
466 | opacity: ['responsive', 'hover', 'focus'],
467 | order: ['responsive'],
468 | outline: ['responsive', 'focus'],
469 | overflow: ['responsive'],
470 | padding: ['responsive'],
471 | placeholderColor: ['responsive', 'focus'],
472 | pointerEvents: ['responsive'],
473 | position: ['responsive'],
474 | resize: ['responsive'],
475 | stroke: ['responsive'],
476 | tableLayout: ['responsive'],
477 | textAlign: ['responsive'],
478 | textColor: ['responsive', 'hover', 'focus'],
479 | textDecoration: ['responsive', 'hover', 'focus'],
480 | textTransform: ['responsive'],
481 | userSelect: ['responsive'],
482 | verticalAlign: ['responsive'],
483 | visibility: ['responsive'],
484 | whitespace: ['responsive'],
485 | width: ['responsive'],
486 | wordBreak: ['responsive'],
487 | zIndex: ['responsive'],
488 | },
489 | corePlugins: {},
490 | plugins: [],
491 | }
492 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "esModuleInterop": true,
8 | "allowSyntheticDefaultImports": true,
9 | "strict": true,
10 | "forceConsistentCasingInFileNames": true,
11 | "module": "esnext",
12 | "moduleResolution": "node",
13 | "resolveJsonModule": true,
14 | "isolatedModules": true,
15 | "noEmit": true,
16 | "jsx": "react"
17 | },
18 | "include": ["src", "@types"]
19 | }
20 |
--------------------------------------------------------------------------------