From bcf17cde13647dce51ca7d4f7f95cc3b69a362e9 Mon Sep 17 00:00:00 2001 From: Josh Habdas Date: Thu, 18 Mar 2021 23:39:08 +0800 Subject: [PATCH 1/2] feat: add typescript support Signed-off-by: Josh Habdas --- .eslintignore | 1 + .prettierrc | 8 ++ components/Header/Header.js | 93 ------------------------ components/Header/Header.tsx | 90 +++++++++++++++++++++++ components/Header/{index.js => index.ts} | 0 package.json | 27 +++++-- tsconfig.json | 21 ++++++ types/material.d.ts | 10 +++ types/reaction.d.ts | 1 + yarn.lock | 24 ++++++ 10 files changed, 176 insertions(+), 99 deletions(-) create mode 100644 .prettierrc delete mode 100644 components/Header/Header.js create mode 100644 components/Header/Header.tsx rename components/Header/{index.js => index.ts} (100%) create mode 100644 tsconfig.json create mode 100644 types/material.d.ts create mode 100644 types/reaction.d.ts diff --git a/.eslintignore b/.eslintignore index 89158ea68c..4914bfe7f8 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,3 +1,4 @@ build/* node_modules/* reports/* +/**/*.d.ts diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000000..a03c2b9706 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,8 @@ +{ + "trailingComma": "all", + "tabWidth": 2, + "semi": true, + "singleQuote": false, + "bracketSpacing": true, + "arrowParens": "always" +} diff --git a/components/Header/Header.js b/components/Header/Header.js deleted file mode 100644 index 952fcba5a4..0000000000 --- a/components/Header/Header.js +++ /dev/null @@ -1,93 +0,0 @@ -import React, { Component } from "react"; -import PropTypes from "prop-types"; -import inject from "hocs/inject"; -import AppBar from "@material-ui/core/AppBar"; -import Hidden from "@material-ui/core/Hidden"; -import Toolbar from "@material-ui/core/Toolbar"; -import Typography from "@material-ui/core/Typography"; -import { withStyles } from "@material-ui/core/styles"; -import { NavigationDesktop } from "components/NavigationDesktop"; -import { NavigationMobile, NavigationToggleMobile } from "components/NavigationMobile"; -import LocaleDropdown from "components/LocaleDropdown"; -import AccountDropdown from "components/AccountDropdown"; -import ShopLogo from "@reactioncommerce/components/ShopLogo/v1"; -import Link from "components/Link"; -import MiniCart from "components/MiniCart"; - -const styles = (theme) => ({ - appBar: { - backgroundColor: theme.palette.reaction.white, - borderBottom: `solid 1px ${theme.palette.reaction.black05}`, - color: theme.palette.reaction.coolGrey500 - }, - controls: { - alignItems: "inherit", - display: "inherit", - flex: 1 - }, - title: { - color: theme.palette.reaction.reactionBlue, - marginRight: theme.spacing(), - borderBottom: `solid 5px ${theme.palette.reaction.reactionBlue200}` - }, - toolbar: { - alignItems: "center", - display: "flex", - justifyContent: "space-between" - } -}); - -class Header extends Component { - static propTypes = { - classes: PropTypes.object, - shop: PropTypes.shape({ - name: PropTypes.string.isRequired - }), - uiStore: PropTypes.shape({ - toggleMenuDrawerOpen: PropTypes.func.isRequired - }).isRequired, - viewer: PropTypes.object - }; - - static defaultProps = { - classes: {} - }; - - handleNavigationToggleClick = () => { - this.props.uiStore.toggleMenuDrawerOpen(); - }; - - render() { - const { classes: { appBar, controls, toolbar, title }, shop } = this.props; - - return ( - - - - - - -
- - - {shop ? : "Example Storefront"} - - - - - - -
- - - - - -
- -
- ); - } -} - -export default withStyles(styles)(inject("uiStore")(Header)); diff --git a/components/Header/Header.tsx b/components/Header/Header.tsx new file mode 100644 index 0000000000..27d31937b7 --- /dev/null +++ b/components/Header/Header.tsx @@ -0,0 +1,90 @@ +import React from "react"; +import inject from "hocs/inject"; +import AppBar from "@material-ui/core/AppBar"; +import Hidden from "@material-ui/core/Hidden"; +import Toolbar from "@material-ui/core/Toolbar"; +import Typography from "@material-ui/core/Typography"; +import { createStyles, withStyles } from "@material-ui/core/styles"; +import { NavigationDesktop } from "components/NavigationDesktop"; +import { + NavigationMobile, + NavigationToggleMobile, +} from "components/NavigationMobile"; +import LocaleDropdown from "components/LocaleDropdown"; +import AccountDropdown from "components/AccountDropdown"; +import ShopLogo from "@reactioncommerce/components/ShopLogo/v1"; +import Link from "components/Link"; +import MiniCart from "components/MiniCart"; + +import type { FC } from "react"; +import type { WithStyles, Theme } from "@material-ui/core"; + +const styles = (theme: Theme) => + createStyles({ + appBar: { + backgroundColor: theme.palette.reaction.white, + borderBottom: `solid 1px ${theme.palette.reaction.black05}`, + color: theme.palette.reaction.coolGrey500, + }, + controls: { + alignItems: "inherit", + display: "inherit", + flex: 1, + }, + title: { + color: theme.palette.reaction.reactionBlue, + marginRight: theme.spacing(), + borderBottom: `solid 5px ${theme.palette.reaction.reactionBlue200}`, + }, + toolbar: { + alignItems: "center", + display: "flex", + justifyContent: "space-between", + }, + }); + +interface HeaderProps extends WithStyles { + shop: { + name: string; + }; + uiStore: { + toggleMenuDrawerOpen: Function; + }; + viewer: any; +} + +const Header: FC = ({ classes, shop, uiStore }) => { + const handleNavigationToggleClick = () => { + uiStore.toggleMenuDrawerOpen(); + }; + return ( + + + + + + +
+ + {/* @ts-ignore TODO: Refactor link to address type error */} + + {shop ? : "Example Storefront"} + + + + + + +
+ + + + + +
+ +
+ ); +}; + +export default withStyles(styles)(inject("uiStore")(Header)); diff --git a/components/Header/index.js b/components/Header/index.ts similarity index 100% rename from components/Header/index.js rename to components/Header/index.ts diff --git a/package.json b/package.json index ce3f73c52e..4188524deb 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "test:unit:watch": "NODE_ENV=jesttest jest --watchAll", "test:link": "blc http://web.reaction.localhost:4000 -ro -filter=3 -e", "test:file": "NODE_ENV=jesttest jest --watch --no-coverage", + "type-check": "tsc", "create-hydra-client": "node createHydraClientIfNecessary.js", "postinstall": "is-ci || is-docker || husky install", "prepublishOnly": "pinst --disable", @@ -34,7 +35,22 @@ "react": { "version": "detect" } - } + }, + "overrides": [ + { + "files": [ + "*.ts", + "*.tsx" + ], + "rules": { + "comma-dangle": "off", + "max-len": "off", + "quote-props": "off", + "react/prop-types": "off", + "react/jsx-max-props-per-line": "off" + } + } + ] }, "dependencies": { "@apollo/client": "^3.0.0-beta.41", @@ -85,6 +101,7 @@ "@reactioncommerce/eslint-config": "~1.9.0", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^10.2.1", + "@types/react": "^16.13.0", "babel-eslint": "^10.1.0", "babel-jest": "^26.0.1", "babel-preset-jest": "^26.0.0", @@ -103,7 +120,8 @@ "jest-transform-graphql": "~2.1.0", "pinst": "^2.1.4", "rimraf": "~2.6.3", - "snyk": "~1.126.0" + "snyk": "~1.126.0", + "typescript": "^4.2.3" }, "jest": { "collectCoverage": true, @@ -149,12 +167,9 @@ "output": "reports/junit/junit.xml", "suiteName": "jest-tests" }, - "prettier": { - "arrowParens": "always" - }, "commitlint": { "extends": [ "@commitlint/config-conventional" ] } -} \ No newline at end of file +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000000..a04c7b86ba --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "target": "esnext", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "importsNotUsedAsValues": "error", + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "baseUrl": "." + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "./types/**/*"], + "exclude": ["node_modules"] +} diff --git a/types/material.d.ts b/types/material.d.ts new file mode 100644 index 0000000000..2804b70492 --- /dev/null +++ b/types/material.d.ts @@ -0,0 +1,10 @@ +import "@material-ui/core/styles/createPalette"; + +declare module "@material-ui/core/styles/createPalette" { + interface Palette { + reaction: any; + } + interface PaletteOptions { + reaction?: any; + } +} diff --git a/types/reaction.d.ts b/types/reaction.d.ts new file mode 100644 index 0000000000..3b15d1be42 --- /dev/null +++ b/types/reaction.d.ts @@ -0,0 +1 @@ +declare module "@reactioncommerce/components/ShopLogo/v1"; diff --git a/yarn.lock b/yarn.lock index 931fdaa163..fc6442f6bd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1944,6 +1944,20 @@ "@types/prop-types" "*" csstype "^2.2.0" +"@types/react@^16.13.0": + version "16.14.5" + resolved "https://registry.yarnpkg.com/@types/react/-/react-16.14.5.tgz#2c39b5cadefaf4829818f9219e5e093325979f4d" + integrity sha512-YRRv9DNZhaVTVRh9Wmmit7Y0UFhEVqXqCSw3uazRWMxa2x85hWQZ5BN24i7GXZbaclaLXEcodEeIHsjBA8eAMw== + dependencies: + "@types/prop-types" "*" + "@types/scheduler" "*" + csstype "^3.0.2" + +"@types/scheduler@*": + version "0.16.1" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.1.tgz#18845205e86ff0038517aab7a18a62a6b9f71275" + integrity sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA== + "@types/stack-utils@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" @@ -4200,6 +4214,11 @@ csstype@^2.0.0, csstype@^2.2.0, csstype@^2.5.2, csstype@^2.6.5, csstype@^2.6.7: resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.10.tgz#e63af50e66d7c266edb6b32909cfd0aabe03928b" integrity sha512-D34BqZU4cIlMCY93rZHbrq9pjTAQJ3U8S8rfBqjwHxkGPThWFjzZDQpgMJY0QViLxth6ZKYiwFBo14RdN44U/w== +csstype@^3.0.2: + version "3.0.7" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.7.tgz#2a5fb75e1015e84dd15692f71e89a1450290950b" + integrity sha512-KxnUB0ZMlnUWCsx2Z8MUsr6qV6ja1w9ArPErJaJaF8a5SOWoHLIszeCTKGRGRgtLgYrs1E8CHkNSP1VZTTPc9g== + cyclist@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" @@ -11670,6 +11689,11 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= +typescript@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.3.tgz#39062d8019912d43726298f09493d598048c1ce3" + integrity sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw== + ua-parser-js@^0.7.18: version "0.7.21" resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.21.tgz#853cf9ce93f642f67174273cc34565ae6f308777" From 38e5ee76dfc9cbe1428d1b44a0c4bbdf9345b776 Mon Sep 17 00:00:00 2001 From: Josh Habdas Date: Fri, 9 Apr 2021 14:42:38 +0800 Subject: [PATCH 2/2] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20prevent=20jest?= =?UTF-8?q?=20warn=20due=20to=20typescript=20target?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Josh Habdas --- tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tsconfig.json b/tsconfig.json index a04c7b86ba..0c21ac6b91 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "esnext", + "target": "es2019", "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "skipLibCheck": true,