From 45c65fa8451702fb7cf4c15265ed02c83f3e0601 Mon Sep 17 00:00:00 2001 From: Dima Vyshniakov Date: Fri, 17 May 2024 15:22:33 +0200 Subject: [PATCH] Enable Styled Components --- additional.d.ts | 10 ++ app/index.css | 8 - app/layout.tsx | 16 +- generate-react-cli.json | 4 +- next.config.js | 5 +- package.json | 8 +- pnpm-lock.yaml | 141 ++++++++++++++---- src/components/Counter/Counter.spec.tsx | 3 +- .../Counter.style.ts} | 33 ++-- src/components/Counter/Counter.tsx | 12 +- .../__snapshots__/Counter.spec.tsx.snap | 7 +- src/components/Random/Random.spec.tsx | 2 +- .../components/Random/Random.style.ts | 31 ++-- src/components/Random/Random.tsx | 16 +- .../Random/__snapshots__/Random.spec.tsx.snap | 48 +++--- ...avHeader.module.css => NavHeader.style.ts} | 24 ++- src/layout/NavHeader/NavHeader.tsx | 14 +- src/layout/NavLink/NavLink.module.css | 15 -- src/layout/NavLink/NavLink.style.ts | 23 +++ src/layout/NavLink/NavLink.tsx | 17 +-- src/style/GlobalStyle.ts | 14 ++ src/style/StyledComponentsRegistry.tsx | 29 ++++ src/style/ThemeProvider.tsx | 10 ++ src/style/index.ts | 4 + src/style/theme.ts | 5 + src/testUtils.tsx | 21 +++ stylelint.config.js | 30 ++-- .../TemplateName.style.ts} | 33 ++-- templates/Component/TemplateName.tsx | 12 +- .../Loading/TemplateName.style.ts | 31 ++-- templates/Loading/TemplateName.tsx | 18 ++- 31 files changed, 410 insertions(+), 234 deletions(-) delete mode 100644 app/index.css rename src/components/{Random/Random.module.css => Counter/Counter.style.ts} (58%) rename templates/Component/TemplateName.module.css => src/components/Random/Random.style.ts (50%) rename src/layout/NavHeader/{NavHeader.module.css => NavHeader.style.ts} (63%) delete mode 100644 src/layout/NavLink/NavLink.module.css create mode 100644 src/layout/NavLink/NavLink.style.ts create mode 100644 src/style/GlobalStyle.ts create mode 100644 src/style/StyledComponentsRegistry.tsx create mode 100644 src/style/ThemeProvider.tsx create mode 100644 src/style/index.ts create mode 100644 src/style/theme.ts create mode 100644 src/testUtils.tsx rename templates/{Loading/TemplateName.module.css => Component/TemplateName.style.ts} (58%) rename src/components/Counter/Counter.module.css => templates/Loading/TemplateName.style.ts (50%) diff --git a/additional.d.ts b/additional.d.ts index 60260a3..2083be8 100644 --- a/additional.d.ts +++ b/additional.d.ts @@ -1 +1,11 @@ +import 'styled-components'; +import type {theme} from '@/src/style'; + declare module '*.module.css'; + +type CustomTheme = typeof theme; + +declare module 'styled-components' { + /* eslint-disable-next-line @typescript-eslint/consistent-type-definitions */ + export interface DefaultTheme extends CustomTheme {} +} diff --git a/app/index.css b/app/index.css deleted file mode 100644 index 43ac7ad..0000000 --- a/app/index.css +++ /dev/null @@ -1,8 +0,0 @@ -body { - font-family: system-ui; - margin: 0; -} - -main { - padding: 36px; -} diff --git a/app/layout.tsx b/app/layout.tsx index 75cd6e9..46d304b 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,7 +1,7 @@ import type {ReactNode} from 'react'; import {StoreProvider} from '@/src/state/StoreProvider'; -import './index.css'; +import {StyledComponentsRegistry, ThemeProvider} from '@/src/style'; type Props = { readonly children: ReactNode; @@ -9,10 +9,14 @@ type Props = { export default function RootLayout({children}: Props) { return ( - - - {children} - - + + + + + {children} + + + + ); } diff --git a/generate-react-cli.json b/generate-react-cli.json index e8e0cd9..05ac386 100644 --- a/generate-react-cli.json +++ b/generate-react-cli.json @@ -17,7 +17,7 @@ "withHookTest": false, "customTemplates": { "component": "templates/Component/TemplateName.tsx", - "style": "templates/Component/TemplateName.module.css", + "style": "templates/Component/TemplateName.style.ts", "index": "templates/Component/index.ts", "test": "templates/Component/TemplateName.spec.tsx" } @@ -34,7 +34,7 @@ "withHookTest": false, "customTemplates": { "component": "templates/Loading/TemplateName.tsx", - "style": "templates/Loading/TemplateName.module.css", + "style": "templates/Loading/TemplateName.style.ts", "index": "templates/Loading/index.ts", "test": "templates/Loading/TemplateName.spec.tsx" } diff --git a/next.config.js b/next.config.js index 65be271..e0dab2b 100644 --- a/next.config.js +++ b/next.config.js @@ -9,7 +9,10 @@ module.exports = withBundleAnalyzer({ reactStrictMode: true, swcMinify: true, distDir: 'build', - output: process.env.PAGES_BUILD === 'true' ? 'export' : undefined, cleanDistDir: true, + output: process.env.PAGES_BUILD === 'true' ? 'export' : undefined, basePath: process.env.PAGES_BUILD === 'true' ? '/ts-redux-next' : undefined, + compiler: { + styledComponents: true, + }, }); diff --git a/package.json b/package.json index 7677c34..91a3188 100644 --- a/package.json +++ b/package.json @@ -18,8 +18,8 @@ "start": "next start", "lint:code": "eslint src/** --report-unused-disable-directives", "fix:code": "run-s 'lint:code --fix'", - "lint:style": "stylelint 'src/**/*.css'", - "fix:style": "stylelint 'src/**/*.css' --fix", + "lint:style": "stylelint 'src/**/*.{ts,tsx}'", + "fix:style": "stylelint 'src/**/*.{ts,tsx}' --fix", "lint:tsc": "tsc --pretty --noEmit", "prepare": "is-ci || husky", "test": "jest", @@ -36,6 +36,7 @@ "react-dom": "18.3.1", "react-redux": "9.1.2", "redux": "5.0.1", + "styled-components": "6.1.13", "uniqid": "5.4.0" }, "devDependencies": { @@ -70,13 +71,12 @@ "npm-run-all2": "6.2.3", "postcss": "8.4.47", "postcss-preset-env": "10.0.6", + "postcss-styled-syntax": "0.6.4", "prettier": "3.3.3", "redux-mock-store": "1.5.4", "stylelint": "16.9.0", - "stylelint-config-prettier": "9.0.5", "stylelint-config-standard": "36.0.1", "stylelint-order": "6.0.4", - "stylelint-prettier": "5.0.2", "typescript": "5.6.2", "typescript-eslint": "8.8.0" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8ea6cdf..f2585a4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -29,6 +29,9 @@ importers: redux: specifier: 5.0.1 version: 5.0.1 + styled-components: + specifier: 6.1.13 + version: 6.1.13(react-dom@18.3.1(react@18.3.1))(react@18.3.1) uniqid: specifier: 5.4.0 version: 5.4.0 @@ -126,6 +129,9 @@ importers: postcss-preset-env: specifier: 10.0.6 version: 10.0.6(postcss@8.4.47) + postcss-styled-syntax: + specifier: 0.6.4 + version: 0.6.4(postcss@8.4.47) prettier: specifier: 3.3.3 version: 3.3.3 @@ -135,18 +141,12 @@ importers: stylelint: specifier: 16.9.0 version: 16.9.0(typescript@5.6.2) - stylelint-config-prettier: - specifier: 9.0.5 - version: 9.0.5(stylelint@16.9.0(typescript@5.6.2)) stylelint-config-standard: specifier: 36.0.1 version: 36.0.1(stylelint@16.9.0(typescript@5.6.2)) stylelint-order: specifier: 6.0.4 version: 6.0.4(stylelint@16.9.0(typescript@5.6.2)) - stylelint-prettier: - specifier: 5.0.2 - version: 5.0.2(prettier@3.3.3)(stylelint@16.9.0(typescript@5.6.2)) typescript: specifier: 5.6.2 version: 5.6.2 @@ -1214,6 +1214,15 @@ packages: '@dual-bundle/import-meta-resolve@4.1.0': resolution: {integrity: sha512-+nxncfwHM5SgAtrVzgpzJOI1ol0PkumhVo469KCf9lUi21IGcY90G98VuHm9VRrUypmAzawAHO9bs6hqeADaVg==} + '@emotion/is-prop-valid@1.2.2': + resolution: {integrity: sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==} + + '@emotion/memoize@0.8.1': + resolution: {integrity: sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==} + + '@emotion/unitless@0.8.1': + resolution: {integrity: sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==} + '@eslint-community/eslint-utils@4.4.0': resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -1622,6 +1631,9 @@ packages: '@types/stack-utils@2.0.3': resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} + '@types/stylis@4.2.5': + resolution: {integrity: sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw==} + '@types/tough-cookie@4.0.5': resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} @@ -2020,6 +2032,9 @@ packages: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} + camelize@1.0.1: + resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==} + caniuse-lite@1.0.30001639: resolution: {integrity: sha512-eFHflNTBIlFwP2AIKaYuBQN/apnUoKNhBdza8ZnW/h2di4LCZ4xFqYlxUxo+LQ76KFI1PGcC1QDxMbxTZpSCAg==} @@ -2175,6 +2190,10 @@ packages: peerDependencies: postcss: ^8.4 + css-color-keywords@1.0.0: + resolution: {integrity: sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==} + engines: {node: '>=4'} + css-functions-list@3.2.2: resolution: {integrity: sha512-c+N0v6wbKVxTu5gOBBFkr9BEdBWaqqjQeiJ8QvSRIJOf+UxlJh930m8e6/WNeODIK0mYLFkoONrnj16i2EcvfQ==} engines: {node: '>=12 || >=16'} @@ -2191,6 +2210,9 @@ packages: peerDependencies: postcss: ^8.4 + css-to-react-native@3.2.0: + resolution: {integrity: sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==} + css-tree@2.3.1: resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} @@ -2219,6 +2241,9 @@ packages: csstype@3.1.2: resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==} + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + damerau-levenshtein@1.0.8: resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} @@ -3938,6 +3963,12 @@ packages: peerDependencies: postcss: ^8.4.20 + postcss-styled-syntax@0.6.4: + resolution: {integrity: sha512-uWiLn+9rKgIghUYmTHvXMR6MnyPULMe9Gv3bV537Fg4FH6CA6cn21WMjKss2Qb98LUhT847tKfnRGG3FhSOgUQ==} + engines: {node: '>=14.17'} + peerDependencies: + postcss: ^8.4.21 + postcss-value-parser@4.2.0: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} @@ -3945,6 +3976,10 @@ packages: resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} engines: {node: ^10 || ^12 || >=14} + postcss@8.4.38: + resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==} + engines: {node: ^10 || ^12 || >=14} + postcss@8.4.47: resolution: {integrity: sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==} engines: {node: ^10 || ^12 || >=14} @@ -4202,6 +4237,9 @@ packages: resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} engines: {node: '>= 0.4'} + shallowequal@1.1.0: + resolution: {integrity: sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==} + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -4357,6 +4395,13 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} + styled-components@6.1.13: + resolution: {integrity: sha512-M0+N2xSnAtwcVAQeFEsGWFFxXDftHUD7XrKla06QbpUMmbmtFBMMTcKWvFXtWxuD5qQkB8iU5gk6QASlx2ZRMw==} + engines: {node: '>= 16'} + peerDependencies: + react: '>= 16.8.0' + react-dom: '>= 16.8.0' + styled-jsx@5.1.1: resolution: {integrity: sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==} engines: {node: '>= 12.0.0'} @@ -4370,13 +4415,6 @@ packages: babel-plugin-macros: optional: true - stylelint-config-prettier@9.0.5: - resolution: {integrity: sha512-U44lELgLZhbAD/xy/vncZ2Pq8sh2TnpiPvo38Ifg9+zeioR+LAkHu0i6YORIOxFafZoVg0xqQwex6e6F25S5XA==} - engines: {node: '>= 12'} - hasBin: true - peerDependencies: - stylelint: '>= 11.x < 15' - stylelint-config-recommended@14.0.1: resolution: {integrity: sha512-bLvc1WOz/14aPImu/cufKAZYfXs/A/owZfSMZ4N+16WGXLoX5lOir53M6odBxvhgmgdxCVnNySJmZKx73T93cg==} engines: {node: '>=18.12.0'} @@ -4394,18 +4432,14 @@ packages: peerDependencies: stylelint: ^14.0.0 || ^15.0.0 || ^16.0.1 - stylelint-prettier@5.0.2: - resolution: {integrity: sha512-qJ+BN+1T2ZcKz9WIrv0x+eFGHzSUnXfXd5gL///T6XoJvr3D8/ztzz2fhtmXef7Vb8P33zBXmLTTveByr0nwBw==} - engines: {node: '>=18.12.0'} - peerDependencies: - prettier: '>=3.0.0' - stylelint: '>=16.0.0' - stylelint@16.9.0: resolution: {integrity: sha512-31Nm3WjxGOBGpQqF43o3wO9L5AC36TPIe6030Lnm13H3vDMTcS21DrLh69bMX+DBilKqMMVLian4iG6ybBoNRQ==} engines: {node: '>=18.12.0'} hasBin: true + stylis@4.3.2: + resolution: {integrity: sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==} + supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} @@ -4804,7 +4838,7 @@ snapshots: '@babel/code-frame@7.24.2': dependencies: '@babel/highlight': 7.24.5 - picocolors: 1.0.1 + picocolors: 1.1.0 '@babel/compat-data@7.23.3': {} @@ -6094,6 +6128,14 @@ snapshots: '@dual-bundle/import-meta-resolve@4.1.0': {} + '@emotion/is-prop-valid@1.2.2': + dependencies: + '@emotion/memoize': 0.8.1 + + '@emotion/memoize@0.8.1': {} + + '@emotion/unitless@0.8.1': {} + '@eslint-community/eslint-utils@4.4.0(eslint@9.12.0)': dependencies: eslint: 9.12.0 @@ -6595,6 +6637,8 @@ snapshots: '@types/stack-utils@2.0.3': {} + '@types/stylis@4.2.5': {} + '@types/tough-cookie@4.0.5': {} '@types/uniqid@5.3.4': {} @@ -7126,6 +7170,8 @@ snapshots: camelcase@6.3.0: {} + camelize@1.0.1: {} + caniuse-lite@1.0.30001639: {} chalk@2.4.2: @@ -7286,6 +7332,8 @@ snapshots: postcss: 8.4.47 postcss-selector-parser: 6.1.2 + css-color-keywords@1.0.0: {} + css-functions-list@3.2.2: {} css-has-pseudo@7.0.0(postcss@8.4.47): @@ -7299,6 +7347,12 @@ snapshots: dependencies: postcss: 8.4.47 + css-to-react-native@3.2.0: + dependencies: + camelize: 1.0.1 + css-color-keywords: 1.0.0 + postcss-value-parser: 4.2.0 + css-tree@2.3.1: dependencies: mdn-data: 2.0.30 @@ -7320,6 +7374,8 @@ snapshots: csstype@3.1.2: {} + csstype@3.1.3: {} + damerau-levenshtein@1.0.8: {} data-urls@3.0.2: @@ -9518,13 +9574,24 @@ snapshots: dependencies: postcss: 8.4.47 + postcss-styled-syntax@0.6.4(postcss@8.4.47): + dependencies: + postcss: 8.4.47 + typescript: 5.6.2 + postcss-value-parser@4.2.0: {} postcss@8.4.31: dependencies: nanoid: 3.3.7 - picocolors: 1.0.1 - source-map-js: 1.2.0 + picocolors: 1.1.0 + source-map-js: 1.2.1 + + postcss@8.4.38: + dependencies: + nanoid: 3.3.7 + picocolors: 1.1.0 + source-map-js: 1.2.1 postcss@8.4.47: dependencies: @@ -9792,6 +9859,8 @@ snapshots: functions-have-names: 1.2.3 has-property-descriptors: 1.0.2 + shallowequal@1.1.0: {} + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 @@ -9954,6 +10023,20 @@ snapshots: strip-json-comments@3.1.1: {} + styled-components@6.1.13(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@emotion/is-prop-valid': 1.2.2 + '@emotion/unitless': 0.8.1 + '@types/stylis': 4.2.5 + css-to-react-native: 3.2.0 + csstype: 3.1.3 + postcss: 8.4.38 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + shallowequal: 1.1.0 + stylis: 4.3.2 + tslib: 2.6.2 + styled-jsx@5.1.1(@babel/core@7.24.5)(babel-plugin-macros@3.1.0)(react@18.3.1): dependencies: client-only: 0.0.1 @@ -9962,10 +10045,6 @@ snapshots: '@babel/core': 7.24.5 babel-plugin-macros: 3.1.0 - stylelint-config-prettier@9.0.5(stylelint@16.9.0(typescript@5.6.2)): - dependencies: - stylelint: 16.9.0(typescript@5.6.2) - stylelint-config-recommended@14.0.1(stylelint@16.9.0(typescript@5.6.2)): dependencies: stylelint: 16.9.0(typescript@5.6.2) @@ -9981,12 +10060,6 @@ snapshots: postcss-sorting: 8.0.2(postcss@8.4.47) stylelint: 16.9.0(typescript@5.6.2) - stylelint-prettier@5.0.2(prettier@3.3.3)(stylelint@16.9.0(typescript@5.6.2)): - dependencies: - prettier: 3.3.3 - prettier-linter-helpers: 1.0.0 - stylelint: 16.9.0(typescript@5.6.2) - stylelint@16.9.0(typescript@5.6.2): dependencies: '@csstools/css-parser-algorithms': 3.0.1(@csstools/css-tokenizer@3.0.1) @@ -10032,6 +10105,8 @@ snapshots: - supports-color - typescript + stylis@4.3.2: {} + supports-color@5.5.0: dependencies: has-flag: 3.0.0 diff --git a/src/components/Counter/Counter.spec.tsx b/src/components/Counter/Counter.spec.tsx index 89b4670..c42b111 100644 --- a/src/components/Counter/Counter.spec.tsx +++ b/src/components/Counter/Counter.spec.tsx @@ -1,8 +1,9 @@ import {Provider} from 'react-redux'; -import {render, fireEvent} from '@testing-library/react'; +import {fireEvent} from '@testing-library/react'; import configureStore from 'redux-mock-store'; import {Actions} from '@/src/features/counter/actionTypes'; +import {render} from '@/src/testUtils'; import Counter from './Counter'; diff --git a/src/components/Random/Random.module.css b/src/components/Counter/Counter.style.ts similarity index 58% rename from src/components/Random/Random.module.css rename to src/components/Counter/Counter.style.ts index a806b74..bc3aa92 100644 --- a/src/components/Random/Random.module.css +++ b/src/components/Counter/Counter.style.ts @@ -1,19 +1,21 @@ -.random { +import {styled} from 'styled-components'; + +export const Wrapper = styled.div` border: 1px solid lightgray; margin-bottom: 24px; padding: 24px; + text-align: center; width: 240px; -} +`; -.header { +export const Header = styled.h2` font-size: 24px; font-weight: normal; margin: 0 0 12px; - text-align: center; -} +`; -.button { - background: lightseagreen; +export const Button = styled.button` + background: ${props => props.theme.colors.brand}; border: none; border-radius: 5px; color: white; @@ -23,15 +25,10 @@ margin: 0 auto 24px; padding: 12px 24px; text-shadow: 1px 1px 1px rgb(0 0 0 / 50%); -} - -.button:disabled { - background: lightgray; - cursor: not-allowed; -} -.button:active:not(:disabled) { - left: 1px; - position: relative; - top: 1px; -} + &:active { + left: 1px; + position: relative; + top: 1px; + } +`; diff --git a/src/components/Counter/Counter.tsx b/src/components/Counter/Counter.tsx index ed2cbe5..ea487ee 100644 --- a/src/components/Counter/Counter.tsx +++ b/src/components/Counter/Counter.tsx @@ -4,7 +4,7 @@ import type {FC} from 'react'; import {useCountValue, useIncrementCounter} from '@/src/features/counter'; -import classes from './Counter.module.css'; +import {Wrapper, Header, Button} from './Counter.style'; const Counter: FC = () => { /** @@ -18,15 +18,13 @@ const Counter: FC = () => { const incrementCounter = useIncrementCounter(); return ( -
-

Sync counter

- + +
Sync counter
+
Total value: {count}
-
+ ); }; diff --git a/src/components/Counter/__snapshots__/Counter.spec.tsx.snap b/src/components/Counter/__snapshots__/Counter.spec.tsx.snap index eb9dbb3..b8e3510 100644 --- a/src/components/Counter/__snapshots__/Counter.spec.tsx.snap +++ b/src/components/Counter/__snapshots__/Counter.spec.tsx.snap @@ -3,16 +3,15 @@ exports[`components > Counter renders without crashing 1`] = `

Sync counter

diff --git a/src/components/Random/Random.spec.tsx b/src/components/Random/Random.spec.tsx index 829faf0..e434ba7 100644 --- a/src/components/Random/Random.spec.tsx +++ b/src/components/Random/Random.spec.tsx @@ -1,7 +1,6 @@ import {Provider} from 'react-redux'; import type {Store, Action} from 'redux'; import { - render, fireEvent, waitFor, screen, @@ -9,6 +8,7 @@ import { } from '@testing-library/react'; import configureStore from 'redux-mock-store'; +import {render} from '@/src/testUtils'; import {GET_RANDOM_NUMBER} from '@/src/features/random/actionTypes'; import {makeStore} from '@/src/state/store'; import {promiseResolverMiddleware} from '@/src/state/promiseResolverMiddleware'; diff --git a/templates/Component/TemplateName.module.css b/src/components/Random/Random.style.ts similarity index 50% rename from templates/Component/TemplateName.module.css rename to src/components/Random/Random.style.ts index 14a17b8..f2d369f 100644 --- a/templates/Component/TemplateName.module.css +++ b/src/components/Random/Random.style.ts @@ -1,19 +1,21 @@ -.templateName { +import {styled} from 'styled-components'; + +export const Wrapper = styled.div` border: 1px solid lightgray; margin-bottom: 24px; padding: 24px; text-align: center; width: 240px; -} +`; -.header { +export const Header = styled.h2` font-size: 24px; font-weight: normal; margin: 0 0 12px; -} +`; -.button { - background: lightseagreen; +export const Button = styled.button` + background: ${props => props.theme.colors.brand}; border: none; border-radius: 5px; color: white; @@ -23,10 +25,15 @@ margin: 0 auto 24px; padding: 12px 24px; text-shadow: 1px 1px 1px rgb(0 0 0 / 50%); -} -.button:active { - left: 1px; - position: relative; - top: 1px; -} + &:disabled { + background: lightgray; + cursor: not-allowed; + } + + &:active:not(:disabled) { + left: 1px; + position: relative; + top: 1px; + } +`; diff --git a/src/components/Random/Random.tsx b/src/components/Random/Random.tsx index d53731b..369dce0 100644 --- a/src/components/Random/Random.tsx +++ b/src/components/Random/Random.tsx @@ -6,7 +6,7 @@ import { useLoadingState, } from '@/src/features/random'; -import classes from './Random.module.css'; +import {Wrapper, Header, Button} from './Random.style'; const Random = () => { /** Loading state of random.org request from Redux store */ @@ -22,15 +22,11 @@ const Random = () => { const isPristine = !isLoading && !hasError && !isFulfilled; return ( -
-

Async Random

- + {isPristine &&
Click the button to get random number
} {isLoading &&
Getting number
} {isFulfilled && ( @@ -39,7 +35,7 @@ const Random = () => {
)} {hasError &&
Ups...
} -
+ ); }; diff --git a/src/components/Random/__snapshots__/Random.spec.tsx.snap b/src/components/Random/__snapshots__/Random.spec.tsx.snap index aaa60fd..0d2a20f 100644 --- a/src/components/Random/__snapshots__/Random.spec.tsx.snap +++ b/src/components/Random/__snapshots__/Random.spec.tsx.snap @@ -3,15 +3,15 @@ exports[`components > Random handles rejected request 1`] = `

Async Random

+ +
Sync counter
+
Total value: {count}
-
+ ); }; diff --git a/src/components/Counter/Counter.module.css b/templates/Loading/TemplateName.style.ts similarity index 50% rename from src/components/Counter/Counter.module.css rename to templates/Loading/TemplateName.style.ts index dc20593..f2d369f 100644 --- a/src/components/Counter/Counter.module.css +++ b/templates/Loading/TemplateName.style.ts @@ -1,19 +1,21 @@ -.counter { +import {styled} from 'styled-components'; + +export const Wrapper = styled.div` border: 1px solid lightgray; margin-bottom: 24px; padding: 24px; text-align: center; width: 240px; -} +`; -.header { +export const Header = styled.h2` font-size: 24px; font-weight: normal; margin: 0 0 12px; -} +`; -.button { - background: lightseagreen; +export const Button = styled.button` + background: ${props => props.theme.colors.brand}; border: none; border-radius: 5px; color: white; @@ -23,10 +25,15 @@ margin: 0 auto 24px; padding: 12px 24px; text-shadow: 1px 1px 1px rgb(0 0 0 / 50%); -} -.button:active { - left: 1px; - position: relative; - top: 1px; -} + &:disabled { + background: lightgray; + cursor: not-allowed; + } + + &:active:not(:disabled) { + left: 1px; + position: relative; + top: 1px; + } +`; diff --git a/templates/Loading/TemplateName.tsx b/templates/Loading/TemplateName.tsx index 6e546ab..0d1d40a 100644 --- a/templates/Loading/TemplateName.tsx +++ b/templates/Loading/TemplateName.tsx @@ -2,9 +2,13 @@ import React from 'react'; -import {useGetRandomNumberQuery, useRandomNumber, useLoadingState} from '@/src/features/random'; +import { + useGetRandomNumberQuery, + useRandomNumber, + useLoadingState, +} from '@/src/features/random'; -import classes from './TemplateName.module.css'; +import {Wrapper, Header, Button} from './TemplateName.style'; export const TemplateName = () => { /** Loading state of random.org request from Redux store */ @@ -20,11 +24,11 @@ export const TemplateName = () => { const isPristine = !isLoading && !hasError && !isFulfilled; return ( -
-

Async Random

- + {isPristine &&
Click the button to get random number
} {isLoading &&
Getting number
} {isFulfilled && ( @@ -33,6 +37,6 @@ export const TemplateName = () => {
)} {hasError &&
Ups...
} - + ); };