Skip to content

Commit

Permalink
Flowify
Browse files Browse the repository at this point in the history
  • Loading branch information
jxom committed Feb 4, 2018
1 parent 6ec1693 commit 8552972
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 72 deletions.
11 changes: 11 additions & 0 deletions .flowconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[ignore]

[include]

[libs]

[lints]

[options]

[strict]
14 changes: 10 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,17 @@
"prepublish": "npm run build",
"lint": "eslint src/",
"fix": "npm run lint -- --fix && npm run prettier",
"flow": "flow",
"prettier": "prettier --config .prettierrc --write 'src/**/*.js'",
"prettier:list-diff": "prettier --config .prettierrc --list-different 'src/**/*.js'",
"storybook": "start-storybook -p 9001 -c .storybook",
"storybook:build": "build-storybook -c .storybook -o docs/",
"test": "npm run lint && npm run prettier:list-diff"
"test": "npm run lint && npm run flow && npm run prettier:list-diff"
},
"dependencies": {
"babel-loader": "^7.1.2",
"credit-card-type": "^6.1.0",
"payment": "^2.3.0",
"prop-types": "^15.6.0",
"styled-components": "^2.2.3"
},
"devDependencies": {
Expand All @@ -37,13 +37,15 @@
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-plugin-transform-object-rest-spread": "6.26.0",
"babel-preset-env": "^1.6.1",
"babel-preset-flow": "^6.23.0",
"babel-preset-react": "^6.24.1",
"eslint": "^4.11.0",
"eslint-config-react-app": "^2.0.1",
"eslint-plugin-flowtype": "^2.39.1",
"eslint-plugin-jsx-a11y": "^6.0.2",
"eslint-plugin-prettier": "^2.3.1",
"eslint-plugin-react": "^7.4.0",
"flow-bin": "^0.64.0",
"prettier": "^1.8.2",
"react": "^16.1.1",
"react-dom": "^16.1.1",
Expand Down
6 changes: 2 additions & 4 deletions rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ export default {
globals: {
react: 'React',
'react-dom': 'ReactDOM',
'prop-types': 'PropTypes',
payment: 'payment',
'credit-card-type': 'creditCardType',
'styled-components': 'styled'
Expand All @@ -20,12 +19,11 @@ export default {
'react-dom',
'credit-card-type',
'payment',
'styled-components',
'prop-types'
'styled-components'
],
plugins: [
babel({
presets: [['env', { modules: false }], 'react'],
presets: [['env', { modules: false }], 'react', 'flow'],
plugins: [
'external-helpers',
'transform-class-properties',
Expand Down
133 changes: 71 additions & 62 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// @flow

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import payment from 'payment';
import creditCardType from 'credit-card-type';
import styled from 'styled-components';
Expand Down Expand Up @@ -66,29 +67,35 @@ const CARD_TYPES = {
amex: 'AMERICAN_EXPRESS'
};

class CreditCardInput extends Component {
static propTypes = {
cardExpiryInputProps: PropTypes.object,
cardNumberInputProps: PropTypes.object,
cardCVCInputProps: PropTypes.object,
cardImageClassName: PropTypes.string,
cardImageStyle: PropTypes.object,
containerClassName: PropTypes.string,
containerStyle: PropTypes.object,
dangerTextClassName: PropTypes.string,
dangerTextStyle: PropTypes.object,
fieldClassName: PropTypes.string,
fieldStyle: PropTypes.object,
inputComponent: PropTypes.oneOfType([
PropTypes.func,
PropTypes.object,
PropTypes.string
]),
inputClassName: PropTypes.string,
inputStyle: PropTypes.object,
invalidClassName: PropTypes.string,
invalidStyle: PropTypes.object
};
type Props = {
cardExpiryInputProps: Object,
cardNumberInputProps: Object,
cardCVCInputProps: Object,
cardImageClassName: string,
cardImageStyle: Object,
containerClassName: string,
containerStyle: Object,
dangerTextClassName: string,
dangerTextStyle: Object,
fieldClassName: string,
fieldStyle: Object,
inputComponent: Function | Object | string,
inputClassName: string,
inputStyle: Object,
invalidClassName: string,
invalidStyle: Object
};
type State = {
cardImage: string,
cardNumberLength: number,
cardNumber: string,
errorText: ?string
};

class CreditCardInput extends Component<Props, State> {
cardExpiryField: any;
cardNumberField: any;
cvcField: any;

static defaultProps = {
cardExpiryInputProps: {},
Expand All @@ -109,34 +116,25 @@ class CreditCardInput extends Component {
invalidStyle: {}
};

constructor(props) {
constructor(props: Props) {
super(props);
this.state = {
cardImage: images.placeholder,
cardNumberLength: 0,
cardNumber: props.cardNumberInputProps.value,
errorText: null
};
this.handleCardNumberBlur = this.handleCardNumberBlur.bind(this);
this.handleCardNumberChange = this.handleCardNumberChange.bind(this);
this.handleCardExpiryBlur = this.handleCardExpiryBlur.bind(this);
this.handleCardExpiryChange = this.handleCardExpiryChange.bind(this);
this.handleCVCBlur = this.handleCVCBlur.bind(this);
this.handleCVCChange = this.handleCVCChange.bind(this);
this.handleKeyDown = this.handleKeyDown.bind(this);
this.setFieldInvalid = this.setFieldInvalid.bind(this);
this.setFieldValid = this.setFieldValid.bind(this);
}

componentDidMount() {
componentDidMount = () => {
const { cardNumber } = this.state;
const cardType = payment.fns.cardType(cardNumber);
this.setState({
cardImage: images[cardType] || images.placeholder
});
}
};

handleCardNumberBlur(e) {
handleCardNumberBlur = (e: SyntheticInputEvent<*>) => {
if (!payment.fns.validateCardNumber(e.target.value)) {
this.setFieldInvalid('Card number is invalid');
}
Expand All @@ -145,9 +143,9 @@ class CreditCardInput extends Component {
if (cardNumberInputProps.onBlur) {
cardNumberInputProps.onBlur(e);
}
}
};

handleCardNumberChange(e) {
handleCardNumberChange = (e: SyntheticInputEvent<*>) => {
const cardNumber = e.target.value;
const cardNumberLength = cardNumber.split(' ').join('').length;
const cardType = payment.fns.cardType(cardNumber);
Expand All @@ -170,7 +168,7 @@ class CreditCardInput extends Component {
length === cardNumberLength &&
payment.fns.validateCardNumber(cardNumber)
) {
document.getElementById('card-expiry').focus();
this.cardExpiryField.focus();
break;
}
if (cardNumberLength === lastCardTypeLength) {
Expand All @@ -183,9 +181,9 @@ class CreditCardInput extends Component {
if (cardNumberInputProps.onChange) {
cardNumberInputProps.onChange(e);
}
}
};

handleCardExpiryBlur(e) {
handleCardExpiryBlur = (e: SyntheticInputEvent<*>) => {
if (!payment.fns.validateCardExpiry(e.target.value)) {
this.setFieldInvalid('Expiry date is invalid');
}
Expand All @@ -194,17 +192,17 @@ class CreditCardInput extends Component {
if (cardExpiryInputProps.onBlur) {
cardExpiryInputProps.onBlur(e);
}
}
};

handleCardExpiryChange(e) {
handleCardExpiryChange = (e: SyntheticInputEvent<*>) => {
const cardExpiry = e.target.value;
const cardExpiryLength = cardExpiry.split(' / ').join('').length;
payment.formatCardExpiry(document.getElementById('card-expiry'));

this.setFieldValid();
if (cardExpiryLength >= 4) {
if (payment.fns.validateCardExpiry(cardExpiry)) {
document.getElementById('cvc').focus();
this.cvcField.focus();
} else {
this.setFieldInvalid('Expiry date is invalid');
}
Expand All @@ -214,9 +212,9 @@ class CreditCardInput extends Component {
if (cardExpiryInputProps.onChange) {
cardExpiryInputProps.onChange(e);
}
}
};

handleCVCBlur(e) {
handleCVCBlur = (e: SyntheticInputEvent<*>) => {
if (!payment.fns.validateCardCVC(e.target.value)) {
this.setFieldInvalid('CVC is invalid');
}
Expand All @@ -225,9 +223,9 @@ class CreditCardInput extends Component {
if (cardCVCInputProps.onBlur) {
cardCVCInputProps.onBlur(e);
}
}
};

handleCVCChange(e) {
handleCVCChange = (e: SyntheticInputEvent<*>) => {
const CVC = e.target.value;
const CVCLength = CVC.length;
payment.formatCardCVC(document.getElementById('cvc'));
Expand All @@ -244,29 +242,31 @@ class CreditCardInput extends Component {
if (cardCVCInputProps.onChange) {
cardCVCInputProps.onChange(e);
}
}
};

handleKeyDown(targetFocusId) {
return e => {
handleKeyDown = (ref: any) => {
return (e: SyntheticInputEvent<*>) => {
if (e.keyCode === BACKSPACE_KEY_CODE && !e.target.value) {
document.getElementById(targetFocusId).focus();
ref.focus();
}
};
}
};

setFieldInvalid(errorText) {
setFieldInvalid = (errorText: string) => {
const { invalidClassName } = this.props;
// $FlowFixMe
document.getElementById('field-wrapper').classList.add(invalidClassName);
this.setState({ errorText });
}
};

setFieldValid(errorText) {
setFieldValid = () => {
const { invalidClassName } = this.props;
// $FlowFixMe
document.getElementById('field-wrapper').classList.remove(invalidClassName);
this.setState({ errorText: null });
}
};

render() {
render = () => {
const { cardImage, errorText } = this.state;
const {
cardExpiryInputProps,
Expand Down Expand Up @@ -304,6 +304,9 @@ class CreditCardInput extends Component {
>
<Input
id="card-number"
ref={cardNumberField => {
this.cardNumberField = cardNumberField;
}}
autoComplete="cc-number"
className={`credit-card-input ${inputClassName}`}
pattern="[0-9]*"
Expand All @@ -318,6 +321,9 @@ class CreditCardInput extends Component {
<InputWrapper inputStyled={inputStyle} data-max="MM / YY 99">
<Input
id="card-expiry"
ref={cardExpiryField => {
this.cardExpiryField = cardExpiryField;
}}
autoComplete="cc-exp"
className={`credit-card-input ${inputClassName}`}
pattern="[0-9]*"
Expand All @@ -327,12 +333,15 @@ class CreditCardInput extends Component {
{...cardExpiryInputProps}
onBlur={this.handleCardExpiryBlur}
onChange={this.handleCardExpiryChange}
onKeyDown={this.handleKeyDown('card-number')}
onKeyDown={this.handleKeyDown(this.cardNumberField)}
/>
</InputWrapper>
<InputWrapper inputStyled={inputStyle} data-max="999999">
<Input
id="cvc"
ref={cvcField => {
this.cvcField = cvcField;
}}
autoComplete="cc-csc"
className={`credit-card-input ${inputClassName}`}
pattern="[0-9]*"
Expand All @@ -342,7 +351,7 @@ class CreditCardInput extends Component {
{...cardCVCInputProps}
onBlur={this.handleCVCBlur}
onChange={this.handleCVCChange}
onKeyDown={this.handleKeyDown('card-expiry')}
onKeyDown={this.handleKeyDown(this.cardExpiryField)}
/>
</InputWrapper>
</FieldWrapper>
Expand All @@ -353,7 +362,7 @@ class CreditCardInput extends Component {
)}
</Container>
);
}
};
}

export default CreditCardInput;

0 comments on commit 8552972

Please sign in to comment.