Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
build/*
node_modules/*
reports/*
/**/*.d.ts
8 changes: 8 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"trailingComma": "all",
"tabWidth": 2,
"semi": true,
"singleQuote": false,
"bracketSpacing": true,
"arrowParens": "always"
}
93 changes: 0 additions & 93 deletions components/Header/Header.js

This file was deleted.

90 changes: 90 additions & 0 deletions components/Header/Header.tsx
Original file line number Diff line number Diff line change
@@ -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<typeof styles> {
shop: {
name: string;
};
uiStore: {
toggleMenuDrawerOpen: Function;
};
viewer: any;
}

const Header: FC<HeaderProps> = ({ classes, shop, uiStore }) => {
Copy link
Collaborator

@janus-reith janus-reith Mar 23, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to discuss the general style we adopt here:
Typescript could infer these, should we utilize that and reduce boilerplate, or do we want to be explicit all the time?
Also, FC seems to add no value so we could use const Header = ({ classes, shop, uiStore }: HeaderProps) which I would prefer personally.
I don't want to pick on this specific one as it's just an implementation example, but it's style will potentially be adopted in other places aswell.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My thinking behind use of Type Parameters is to identify type immediately when looking at a function without having parse my eye parse over an argument and possible default params before getting to it, e.g.

const Header = ({
  classes: { toolbar, title, controls, appBar },
  shop: { name = "cmVhY3Rpb24vc2hvcDo5TVNZOEZ4ZFI2dTJaOHVNdg==" },
  uiStore,
}: HeaderProps) => {

Add an explicit return type, assign default args or define the types inline and it personally starts to give me the bug eyes even after Prettier has gone to work on it, and still suffers from the eye scanning problem I mentioned:

const Header = ({
  classes: { toolbar, title, controls, appBar },
  shop: { name = "cmVhY3Rpb24vc2hvcDo5TVNZOEZ4ZFI2dTJaOHVNdg==" },
  uiStore,
}: {
  shop: {
    name: string;
  };
  uiStore: {
    toggleMenuDrawerOpen: Function;
  };
  viewer: any;
}) => {

Then there's the moment where you want to return null inside an element—likely with a ternary expression—and are required to add children to the type definition and you'll still get an error until you choose the correct return type (which FC already does for us).

Type 'Element | null' is not assignable to type 'HeaderProps'.
  Type 'null' is not assignable to type 'HeaderProps'.ts(2322)

The biggest disadvantage I see of using FC has to do with potentially adding children where we're not dealing with a react component, in which case I prefer the grammar you supplied.

That said it seems as though others prefer omitting FC to save a little boilerplate and I'm cool with that so long as we can agree on a way forward to get the migration started and let the style grow out of the refactored code before adding any opinion.

Thoughts?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the record, here's the number of times we're returning null in component definitions which can be used as a rough proxy for how often the above error will occur as people are coding: https://github.com/reactioncommerce/example-storefront/search?q=%22return+null%22&type=code

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for taking the time to explain your thoughts on this!
I'm happy to keep it this way.

Longer-term if we deal with passing more data types from the api (which hopefully we won't all type by hand within components anyway and just use codegen) we can still the what patterns fits best, so I'm negating my original statement, not a blocker and nothing that needs to be set in stone right now.

const handleNavigationToggleClick = () => {
uiStore.toggleMenuDrawerOpen();
};
return (
<AppBar position="static" elevation={0} className={classes.appBar}>
<Toolbar className={classes.toolbar}>
<Hidden mdUp>
<NavigationToggleMobile onClick={handleNavigationToggleClick} />
</Hidden>

<div className={classes.controls}>
<Typography className={classes.title} color="inherit" variant="h6">
{/* @ts-ignore TODO: Refactor link to address type error */}
<Link route="/">
{shop ? <ShopLogo shopName={shop.name} /> : "Example Storefront"}
</Link>
</Typography>

<Hidden smDown initialWidth={"md"}>
<NavigationDesktop />
</Hidden>
</div>

<LocaleDropdown />

<AccountDropdown />
<MiniCart />
</Toolbar>
<NavigationMobile shop={shop} />
</AppBar>
);
};

export default withStyles(styles)(inject("uiStore")(Header));
File renamed without changes.
27 changes: 21 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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",
Expand Down Expand Up @@ -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",
Expand All @@ -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,
Expand Down Expand Up @@ -149,12 +167,9 @@
"output": "reports/junit/junit.xml",
"suiteName": "jest-tests"
},
"prettier": {
"arrowParens": "always"
},
"commitlint": {
"extends": [
"@commitlint/config-conventional"
]
}
}
}
21 changes: 21 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"compilerOptions": {
"target": "es2019",
"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"]
}
10 changes: 10 additions & 0 deletions types/material.d.ts
Original file line number Diff line number Diff line change
@@ -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;
}
}
1 change: 1 addition & 0 deletions types/reaction.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
declare module "@reactioncommerce/components/ShopLogo/v1";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This prevents a type error using modules from the component library. This will eventually become a list of items as they are used from the lib, each added when it becomes used. Not the most straight-forward thing but to me sane until there's a better approach (I haven't found one yet).

Screen Shot 2021-04-01 at 6 46 02 PM

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok yes I was also expecting this to become a larger list at some point and therefore wondered if we couldn't avoid that somehow. But IMHO not a blocker, something that could easily be refactored later on.

24 changes: 24 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand Down