Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add flow types generation, fix flow types #207

Merged
merged 21 commits into from
Feb 20, 2019
Merged
Show file tree
Hide file tree
Changes from 20 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
2 changes: 2 additions & 0 deletions .flowconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,7 @@
[options]
module.name_mapper.extension='css' -> '<PROJECT_ROOT>/flow/CSSModule.js.flow'
module.name_mapper.extension='scss' -> '<PROJECT_ROOT>/flow/CSSModule.js.flow'
esproposal.class_static_fields=enable
esproposal.class_instance_fields=enable

[strict]
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ Developing with Storybook
1. Run `yarn run styleguide:build`
2. Files output to /styleguide

### Building flow-typed definitions

1. Run `yarn flow:buildTypeDefs`

This will output flow-typed compatible definitions of Flow types for Plasma. For Spacestation, you likely want to `yarn flow:buildTypeDefs | pbcopy` (if on Mac) and paste the contents to the `plasma_vx.x.x.js` under flow-typed/

### Documenting components

1. Run `./docs/publish.sh` from the root dir. This will update the docs, commit to gh-pages, and push to github (updating http://plasma.guide)
Expand Down
12 changes: 7 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
"test:watch": "yarn test --watch --coverage",
"test:update": "yarn test --updateSnapshot",
"test:coverage": "yarn test --coverage --coverageReporters=text-lcov",
"flow:coverage": "flow-coverage-report --config .flow-coverage.config.json --strict-coverage"
"flow:coverage": "flow-coverage-report --config .flow-coverage.config.json --strict-coverage",
"flow:buildTypeDefs": "node ./scripts/buildFlowTypeDefs.js"
},
"lint-staged": {
"*.{js,jsx}": [
Expand All @@ -40,9 +41,7 @@
"author": "WeWork",
"license": "ISC",
"devDependencies": {
"@storybook/addon-actions": "^3.1.9",
"@storybook/addon-links": "^3.1.6",
"@storybook/react": "^3.4.8",
"anchorate": "^1.1.0",
"babel-cli": "^6.24.1",
"babel-core": "^6.10.4",
Expand All @@ -61,15 +60,15 @@
"babel-runtime": "^6.9.2",
"base64-image-loader": "^1.2.0",
"css-loader": "^0.23.1",
"eslint-config-prettier": "4.0.0",
"eslint-plugin-prettier": "3.0.1",
"enzyme": "3.7.0",
"enzyme-adapter-react-16": "1.7.0",
"eslint": "4.19.1",
"eslint-config-airbnb": "10.0.1",
"eslint-config-prettier": "4.0.0",
"eslint-plugin-flowtype": "3.2.1",
"eslint-plugin-import": "2.15.0",
"eslint-plugin-jsx-a11y": "2.2.3",
"eslint-plugin-prettier": "3.0.1",
"eslint-plugin-react": "6.10.3",
"extract-text-webpack-plugin": "^2.1.2",
"flow-bin": "^0.69.0",
Expand Down Expand Up @@ -104,8 +103,11 @@
"webpack-dev-server": "^1.14.1"
},
"dependencies": {
"@storybook/addon-actions": "^3.1.9",
"@storybook/react": "^3.4.8",
"classnames": "^2.2.5",
"jest-cli": "^22.0.6",
"jscodeshift": "^0.6.3",
"jsdom": "^11.1.0",
"lodash": "^4.14.1",
"proxy-middleware": "^0.15.0",
Expand Down
26 changes: 26 additions & 0 deletions scripts/buildFlowTypeDefs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/* eslint-disable */
const { execSync } = require('child_process');

const p = require('../package.json');

const currentVersion = p.version;
const flowVersion = String(execSync('flow version')).match(/[\d\.]+/)[0];

const declarations = execSync(
`jscodeshift -s -t scripts/extractFlowTypes.js src/components/**/*.jsx src/components/layout/**/*.jsx --parser flow`
);

console.log(`
// flow-typed version: <<STUB>>/@wework-dev/plasma_v${currentVersion}/flow_v${flowVersion}

${String(declarations).replace(/\bNode\b/g, 'React$Node')}

declare module '@wework-dev/plasma' {
declare type Data = { key: string, value: string };

declare export class CountedTextInput extends React$Component<{ ...$PropertyType<TextInput, 'props'>, counterStyle: string }> { }
declare export class CountedTextArea extends React$Component<{ ...$PropertyType<TextArea, 'props'>, counterStyle: string }> { }
Copy link
Contributor Author

Choose a reason for hiding this comment

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

ideally we would generate decorated components automatically


declare export var LocationPin: string;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

should we automatically export all files under icons as strings?

}
`);
32 changes: 32 additions & 0 deletions scripts/extractFlowTypes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
const { execSync } = require('child_process');

export default function transformer(file, api) {
const j = api.jscodeshift;
const root = j(file.source);

root.find(j.TypeAlias).forEach(p => {
const componentName = file.path.match(/(\w+)\.jsx/)[1];

const { line, column } = p.value.id.loc.start;

const typeAtPosOutput = String(
execSync(`flow type-at-pos ${file.path} ${line} ${column + 1} --quiet`)
);

const fullTypeDeclaration = typeAtPosOutput.split('\n')[0];
const typeDeclarationRHS = fullTypeDeclaration.replace(/^type\s+\w+\s+=\s+/, '');

if (p.value.id.name === 'Props') {
// declare export class ...
console.log(
`declare export class ${componentName} extends React$Component<${typeDeclarationRHS}> { }`
);
} else if (p.value.id.name !== 'State') {
// declare type ... = ...
console.log(`declare ${fullTypeDeclaration}`);
}

console.log('\n');
});
return file.source;
}
2 changes: 1 addition & 1 deletion src/components/Checkbox/Checkbox.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ type Props = {|
icon?: string,
indeterminate?: boolean,
isBold?: boolean,
name: string,
name?: string,
onBlur?: () => mixed,
onChange?: () => mixed,
text: Node,
Expand Down
2 changes: 1 addition & 1 deletion src/components/DatePicker/DatePicker.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import React from 'react';
import ExternalDatePicker from 'react-datepicker';

type Props = ExternalDatePicker.propTypes;
type Props = {};

class DatePicker extends React.Component<Props> {
static defaultProps = ExternalDatePicker.defaultProps;
Expand Down
2 changes: 1 addition & 1 deletion src/components/Header/Header.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ type Props = {|
h5?: boolean,
h6?: boolean,
invert?: boolean,
style?: boolean,
style?: { [string]: string },
noMargin?: boolean,
data?: Data,
|};
Expand Down
14 changes: 7 additions & 7 deletions src/components/Image/Image.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ import type { Data } from '../../types';
const defaultImage = 'https://cdn.spacetelescope.org/archives/images/screen/s82e5407.jpg';

type Props = {|
style: Object,
imageStyle: Object,
style?: { [string]: string },
imageStyle?: { [string]: string },
src: string,
altText: string,
data: Data,
onClick: (evt: MouseEvent) => void,
className: Object,
fallback: string,
altText?: string,
data?: Data,
onClick?: (evt: MouseEvent) => void,
className?: string,
fallback?: string,
onLoad?: (evt: MouseEvent) => void,
|};

Expand Down
2 changes: 1 addition & 1 deletion src/components/Loader/Loader.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import type { Data } from '../../types';

type Props = {|
style?: Object,
dotStyle: ?Object,
dotStyle?: ?Object,
data?: Data,
|};

Expand Down
16 changes: 8 additions & 8 deletions src/components/Modal/Modal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ import { getDataAttrs } from '../../dataUtils';
import type { Data } from '../../types';

type Props = {|
title: string,
actions: Array<Node>,
title?: string,
actions?: Array<Node>,
children: Node,
visible: boolean,
onDismiss: (evt: MouseEvent) => void,
style: Object,
minWidth: number,
maxWidth: number,
data: Data,
visible?: boolean,
onDismiss?: (evt: MouseEvent) => void,
style?: { [string]: string | number },
minWidth?: string | number,
maxWidth?: string | number,
data?: Data,
|};

class Modal extends React.Component<Props> {
Expand Down
15 changes: 8 additions & 7 deletions src/components/NumberInput/NumberInput.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ type HandleEvent = {|
},
|};
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like a mock (and roundabout) definition of SyntheticEvent<T>

type Props = {|
data: Data,
disabled: boolean,
error: boolean,
data?: Data,
disabled?: boolean,
error?: boolean,
maxValue: number,
minValue: number,
onBlur: HandleEvent => void,
onBlur?: HandleEvent => void,
onChange: HandleEvent => void,
onFocus: HandleEvent => void,
placeholder: string,
onFocus?: HandleEvent => void,
placeholder?: string,
step: number,
value: string,
|};
Expand All @@ -42,6 +42,7 @@ class NumberInput extends React.Component<Props> {
step: 1,
maxValue: Number.MAX_SAFE_INTEGER,
minValue: Number.MIN_SAFE_INTEGER,
onChange() {},
};

handleIncrement = (): void => {
Expand All @@ -59,7 +60,7 @@ class NumberInput extends React.Component<Props> {
};

handleChange = (e: HandleEvent): void => {
this.props.onChange(e.nativeEvent.target.value);
this.props.onChange && this.props.onChange(e.nativeEvent.target.value);
};

handleBlur = (e: HandleEvent): void => {
Expand Down
16 changes: 8 additions & 8 deletions src/components/OverflowMenu/OverflowMenu.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ import style from './style.scss';
const direction = { RIGHT: 'right', LEFT: 'left' };

type Props = {|
disabled: boolean,
options: Array<Data>,
onClick: (event: Event) => void,
openDirection: $Values<typeof direction>,
label: string,
data: Data,
disabled?: boolean,
options: Array<{| key: string, text: string |}>,
onClick: string => void,
openDirection?: $Values<typeof direction>,
label?: string,
data?: Data,
|};

type State = {|
Expand All @@ -42,9 +42,9 @@ class OverflowMenu extends React.Component<Props, State> {
this.setState({ revealed: false });
};

handleClick = (event: Event) => {
handleClick = (optionKey: string) => {
this.setState({ revealed: false });
this.props.onClick(event);
this.props.onClick(optionKey);
};

renderLabel = (): Node => {
Expand Down
2 changes: 1 addition & 1 deletion src/components/OverflowMenu/OverflowMenuItem.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React from 'react';
import style from './style.scss';

type Props = {
onClick: any => void,
onClick: string => void,
optionKey: string,
text: string,
};
Expand Down
16 changes: 8 additions & 8 deletions src/components/RadioButton/RadioButton.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ import style from './style.scss';

type Props = {|
data?: Data,
checked: boolean,
description: ?string,
disabled: ?boolean,
fancy: ?boolean,
fieldValue: string,
icon: ?string,
isLarge: ?boolean,
checked?: boolean,
description?: ?string,
disabled?: ?boolean,
fancy?: ?boolean,
fieldValue?: string,
icon?: ?string,
isLarge?: ?boolean,
name: string,
onChange: () => mixed,
onChange: (event: SyntheticEvent<HTMLInputElement>) => mixed,
Copy link
Contributor

Choose a reason for hiding this comment

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

I suggest evt. I think event should be considered a saved word.

text: string,
value?: string,
|};
Expand Down
6 changes: 3 additions & 3 deletions src/components/Rule/Rule.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import type { Data } from '../../types';
const type = { SOLID: 'solid', DOTTED: 'dotted', DASHED: 'dashed' };

type Props = {|
type: string,
withTopMargin: boolean,
data: Data,
type?: string,
withTopMargin?: boolean,
data?: Data,
|};

class Rule extends React.Component<Props> {
Expand Down
26 changes: 13 additions & 13 deletions src/components/Search/Search.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ import type { Data } from '../../types';
import style from './style.scss';

type Props = {|
clearable: boolean,
clearIconUrl: string,
disabled: boolean,
clearable?: boolean,
clearIconUrl?: string,
disabled?: boolean,
iconUrl: string,
instructionText: string,
onChange: ({ target: { value: string } }) => void,
onKeyDown: (event: Event) => void,
onClear: (event: Event) => void,
placeholder: string,
value: string,
data: Data,
instructionText?: string,
onChange?: (event: SyntheticEvent<HTMLInputElement>) => void,
onKeyDown?: (event: SyntheticEvent<HTMLInputElement>) => void,
onClear?: (event: SyntheticEvent<HTMLInputElement>) => void,
placeholder?: string,
value?: string,
data?: Data,
|};

type State = {|
Expand Down Expand Up @@ -43,15 +43,15 @@ class Search extends Component<Props, State> {
}
}

onChange = (event: { target: { value: string } }): void => {
onChange = (event: SyntheticEvent<HTMLInputElement>): void => {
const { onChange } = this.props;

this.setState({ text: event.target.value });
this.setState({ text: event.currentTarget.value });

onChange && onChange(event);
};

onClear = (event: Event): void => {
onClear = (event: SyntheticEvent<HTMLInputElement>): void => {
const { onClear } = this.props;

this.setState({ text: '' });
Expand Down
2 changes: 1 addition & 1 deletion src/components/SegmentedCard/SegmentedCard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ type Props = {|
children: Array<Node>,
style: Object,
vertical: Boolean,
data: Data,
data?: Data,
|};

class SegmentedCard extends React.Component<Props> {
Expand Down
2 changes: 1 addition & 1 deletion src/components/Select/Select.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import React from 'react';
import ExternalSelect from 'react-select';

type Props = ExternalSelect.propTypes;
type Props = {};

class Select extends React.Component<Props> {
render() {
Expand Down
Loading