Skip to content
This repository has been archived by the owner on Aug 21, 2023. It is now read-only.

Commit

Permalink
Remove flow (#613)
Browse files Browse the repository at this point in the history
* Converts to ts

* fixes

* FormGroup

* Updates contributing docs

* fix story

* Removes the index suffix from imports

* doc

* Remove extra import

* Removes types from css.js files

* Remaining styles files

* Fix build

* Fix proptype file imports

* Removes prop-types and converts dropdown to ts

* Converting Pop from Flow to TypeScript

* Completes code coverage

* Complete conversion of Pop -> TS

Some of this involved fixing the Tests's mock implementation.
For TS files, you need to return an object with { default }, the default
value being the (mock) component.

* Fix TS for Tooltip. Convert other files to TS

Update stories import path for `index`

* Fix prop ...rest issue for Sortable components

* 2.40.0-no-flow-0

* Remove Helix dependency in HsApp.Sidenav. Fix dependency import for popper.js

* 2.40.0-no-flow-1

* Fix popper import/export

* 2.40.0-no-flow-2

* Removes flow dependencies and converts utils to TS

* quick ts fix

* TS fixes
  • Loading branch information
tinkertrain authored and Jon Quach committed May 8, 2019
1 parent 3cbe0c7 commit 4868a0a
Show file tree
Hide file tree
Showing 816 changed files with 4,113 additions and 3,883 deletions.
2 changes: 1 addition & 1 deletion .eslintrc
@@ -1,7 +1,7 @@
{
"extends": "react-app",
"parser": "babel-eslint",
"plugins": ["flowtype"],
"plugins": [],
"settings": {
"react": {
"createClass": "createReactClass",
Expand Down
2 changes: 0 additions & 2 deletions .storybook/.babelrc
Expand Up @@ -13,12 +13,10 @@
}
}
],
"@babel/preset-flow",
"@babel/react"
],
"plugins": [
"@babel/plugin-proposal-class-properties",
"@babel/plugin-transform-flow-strip-types",
"inline-svg",
"emotion"
],
Expand Down
12 changes: 12 additions & 0 deletions __mocks__/popper.js.js
@@ -0,0 +1,12 @@
import PopperJs from 'popper.js'

export default class Popper {
static placements = PopperJs.placements

constructor() {
return {
destroy: () => {},
scheduleUpdate: () => {},
}
}
}
2 changes: 0 additions & 2 deletions babel.config.js
Expand Up @@ -2,7 +2,6 @@ module.exports = api => {
const isTest = api.env('test')
const plugins = [
'@babel/plugin-proposal-class-properties',
'@babel/plugin-transform-flow-strip-types',
'inline-svg',
'emotion',
]
Expand All @@ -27,7 +26,6 @@ module.exports = api => {
loose: true,
},
],
'@babel/preset-flow',
'@babel/react',
],
plugins: plugins,
Expand Down
185 changes: 159 additions & 26 deletions docs/contributing/creating.md
Expand Up @@ -2,6 +2,9 @@

In this guide, we'll walk through creating a custom component in HSDS!

All Components in HSDS are or have been updated to TypeScript, do not fret! You can write your components in regular old JavaScript, just make sure the extensions are '.ts' or '.tsx' (if your file contains jsx, you want .tsx) things will work as normal.
We do enocurage you to have a look at other components and follow how thay are put together, you might learn a thing or two, which is always a good thing!

We'll be created a `Strong` component, an enhancement to the default HTML `strong` primitive.

## Directory
Expand All @@ -25,45 +28,43 @@ hsds-react/
└── Strong/
```

Under our newly created `Strong/` directory, we'll need to create 2 files:
Under our newly created `Strong/` directory, we'll need to create a few files:

* `index.ts`
* `Strong.tsx`
* `Strong.utils.ts`

* `index.js`
* `Strong.js`
If your component will be styled (not all are!) add a `styles` folder and put a `Strong.css.js` file in it

```
hsds-react/
└── src/
└── components/
└── Strong/
├── index.js
└── Strong.js
└── styles/
└── Strong.css.js
├── index.ts
├── Strong.tsx
└── Strong.utils.ts
```

The **`index.js`** file is the main file allow the consuming App/component to use `Strong`. It also "connects" our component to `PropProvider`, allowing the user to more easily customize `Strong` ([more on that later](#propConnect)!).
The **`index.ts`** file is the main file allow the consuming App/component to use `Strong`. It also "connects" our component to `PropProvider`, allowing the user to more easily customize `Strong` ([more on that later](#propConnect)!).

The **`String.js`** file our actual React component.
The **`String.tsx`** file our actual React component.

## Base component code

Add the starting React component boilerplate for `Strong.js`:
Add the starting React component boilerplate for `Strong.tsx`:

```jsx
// @flow
import React, { PureComponent as Component } from 'react'
import * as React from 'react'
import getValidProps from '@helpscout/react-utils/dist/getValidProps'
import { classNames } from '../../utilities/classNames'
import { namespaceComponent } from '../../utilities/component'
import { COMPONENT_KEY } from './Strong.utils.ts'
import { StrongUI } from './styles/Strong.css.js'

export const COMPONENT_KEY = 'Strong'

type Props = {
children?: any,
className?: string,
isSuperBold: boolean,
}

class Strong extends Component<Props> {
class Strong extends React.PureComponent {
static defaultProps = {
isSuperBold: false,
}
Expand Down Expand Up @@ -92,9 +93,20 @@ export default Strong

Whoa 😳! Lots of stuff going on already!

#### `Flow`
#### TypeScript

HSDS uses [Flow](https://flow.org/en/) for typing. To enable Flow type on our component, we have to start off the file with `// @flow`.
HSDS uses [TypeScript](https://www.typescriptlang.org/) for typing. You can write your component in JS, and add the TypeScript layer little by little.
Here are a couple of relevant links to get you started:

* [JSX in TypeScript](https://www.typescriptlang.org/docs/handbook/jsx.html)
* [Understanding TypeScript’s type notation](http://2ality.com/2018/04/type-notation-typescript.html)
* [Typescript, React, JSX](https://basarat.gitbooks.io/typescript/docs/jsx/react.html)

Notice how our example at the moment does not include anything TypeScript wise yet.

**Important**

I just told you a lie, TypeScript requires that specific way to import React: `import * as React from 'react'` so no `import React, { PureComponent as Component } from 'react'`

#### `Strong.css.js`

Expand Down Expand Up @@ -159,18 +171,28 @@ Wonderful 🙏! You've created the base for `Strong`, that's performant, easy to

This is a Higher-Order component that sets up the internal namespacing within HSDS. It allows for HSDS components to reliably type-check each other.

`COMPONENT_KEY` is the namespace for the component, in our case, `Strong`. Exporting it allows for other components to use the key for type-checking.
`COMPONENT_KEY` is the namespace for the component, in our case, `Strong`. This key normally resides in the "utils" file.

## Utils

Your component might need different functions, constants or other stuff that don't need to live inside of it, the place to put those is inside your utils file: `Strong.utils.ts`, at the minimum, this file is where the `COMPONENT_KEY` lives:

**Strong.utils.ts**

```ts
export const COMPONENT_KEY = 'Strong'
```

## Exporting

We'll need to export `Strong` to make it simpler to import and use. This is all done in our `index.js` file:

```jsx
// @flow
import Strong from './Strong'
import { propConnect } from '../PropProvider'
import { COMPONENT_KEY } from './Strong.utils.ts'

export default propConnect('Strong')(Strong)
export default propConnect(COMPONENT_KEY)(Strong)
```

Whoa 😳! More stuff!
Expand All @@ -179,7 +201,7 @@ Whoa 😳! More stuff!

`propConnect` is a special Higher-Order Component that works very similar to [Redux's](https://redux.js.org/) `connect`. It hooks up our `Strong` component to HSDS's `PropProvider`, which allows the user to more [easily override props](https://github.com/helpscout/hsds-react/blob/master/src/components/PropProvider/docs/Provider.md).

We provide it with the (`string`) namespace (`'Strong'`), as well as the actual Component.
We provide it with the (`string`) namespace (`COMPONENT_KEY`), as well as the actual Component.

## More Exporting

Expand All @@ -200,13 +222,124 @@ export { default as Strong } from './Strong'
...
```

## Adding TypeScript types

When working with TypeScript on A react component, one of the things it brings to the table is a different way to generate a component's "prop types", you no longer need the separate package 'prop-types' as you will be using TS's type system. Let's add this to our example, first, create a new file: `Strong.types.ts`

```
hsds-react/
└── src/
└── components/
└── Strong/
└── styles/
└── Strong.css.js
├── index.ts
├── Strong.tsx
└── Strong.types.ts
```

**Strong.types.ts**

Notice the convention to define the component prop types: `ComponentNameProps`, for state types use: `ComponentNameState`

```ts
export type StrongProps = {
children?: any
className?: string
isSuperBold: boolean
}
```
**Strong.tsx**
```jsx
import * as React from 'react'
import getValidProps from '@helpscout/react-utils/dist/getValidProps'
import { classNames } from '../../utilities/classNames'
import { namespaceComponent } from '../../utilities/component'
import { StrongUI } from './styles/Strong.css.js'
import { StrongProps } from './Strong.types.ts'

export const COMPONENT_KEY = 'Strong'

class Strong extends React.PureComponent<StrongProps> {
static defaultProps = {
isSuperBold: false,
}

render() {
const { children, className, ...rest } = this.props

const componentClassName = classNames(
'c-Strong',
isSuperBold && 'is-superBold',
className
)

return (
<StrongUI {...getValidProps(rest)} className={componentClassName}>
{children}
</StrongUI>
)
}
}

namespaceComponent(COMPONENT_KEY, Strong)

export default Strong
```

And that's it 🙏! You've successfully created, hooked up, and exported our new `Strong` component 💪.

## About naming conventions

You'll quickly notice a pattern to everything we add inside a component. The reason for this is that HSDS has many components! And when you are working inside your code editor, it's easier to find what you need if everything is named following a convention.

Below is a summary of things to pay attention to with examples of a slightly more complex component:

#### Folder Structure

```
hsds-react/
└── src/
└── components/
└── Table/
└── __tests__/
├── Table.Cell.test.js
└── Table.test.js
└── styles/
├── Table.Cell.css.js
└── Table.css.js
├── index.ts
├── Table.tsx
├── Table.Cell.tsx
├── Table.utils.ts
└── Table.types.ts
```

#### Types

```ts
export type TableProps = {
/* ... */
}
export type TableState = {
/* ... */
}
export type TableCellProps = {
/* ... */
}
export type TableCellState = {
/* ... */
}
```
In general, the pattern looks like `Component.SubComponent`...
## Next
Let's add some [styles](stying.md)!
## See also
* [Flow](https://flow.org/en/)
* [react-utils](https://helpscout.gitbook.io/react-utils)
4 changes: 1 addition & 3 deletions docs/contributing/setup.md
Expand Up @@ -46,9 +46,7 @@ Fantastic ✌️! You've got HSDS up and running on your computer.

## Code editor

You can use **whatever code editor you like**! HSDS is typed using [Flow](https://flow.org/). Because of this, we recommend using [Visual Studio Code](https://code.visualstudio.com/) as it has pretty great [Flow support](https://github.com/flowtype/flow-for-vscode).

Note: You may need to [install Flow globally](https://preview.npmjs.com/package/flow-bin) on your computer.
You can use **whatever code editor you like**! HSDS is typed using [TypeScript](https://www.typescriptlang.org/). Because of this, we recommend using [Visual Studio Code](https://code.visualstudio.com/).

## Git branch

Expand Down
2 changes: 1 addition & 1 deletion docs/contributing/storybook.md
Expand Up @@ -47,7 +47,7 @@ In our `Strong/index.js` file, we'll need to add:
```jsx
import React from 'react'
import { storiesOf } from '@storybook/react'
import { Strong } from '../../src/index.js'
import { Strong } from '../../src/index'

const stories = storiesOf('Strong', module)

Expand Down
1 change: 0 additions & 1 deletion docs/contributing/styling.md
Expand Up @@ -36,7 +36,6 @@ The `.css.js` file extension is a convention HSDS uses to distinguish dedicated
Add the starting styled component boilerplate for `Strong.css.js`:

```jsx
// @flow
import baseStyles from '../../../styles/resets/baseStyles.css.js'
import styled from '../../styled'

Expand Down

0 comments on commit 4868a0a

Please sign in to comment.