Skip to content

Instantly share code, notes, and snippets.

@rosskevin
Forked from lfalke/StripeCardsSection.js
Created March 29, 2018 21:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rosskevin/bfe601a6696fdf7244161bf1ccce5d89 to your computer and use it in GitHub Desktop.
Save rosskevin/bfe601a6696fdf7244161bf1ccce5d89 to your computer and use it in GitHub Desktop.
Usage of react-stripe-elements with Material UI (v1.0) styling
import React, { PureComponent } from 'react'
import Grid from 'material-ui/Grid'
import { CardNumberElement, CardExpiryElement, CardCVCElement } from 'react-stripe-elements'
import StripeElementWrapper from './StripeElementWrapper'
export default class extends PureComponent {
static displayName = 'StripeCardsSection'
render() {
return (
<Grid container>
<Grid item xs={12}>
<StripeElementWrapper label="Card Number" component={CardNumberElement} />
</Grid>
<Grid item xs={7}>
<StripeElementWrapper label="Expiry (MM / YY)" component={CardExpiryElement} />
</Grid>
<Grid item xs={5}>
<StripeElementWrapper label="CVC" component={CardCVCElement} />
</Grid>
</Grid>
)
}
}
// A Wrapper for the <FormControl>, <InputLabel>, <Error> and the Stripe <*Element>.
// Similar to Material UI's <TextField>. Handles focused, empty and error state
// to correctly show the floating label and error messages etc.
import React, { PureComponent } from 'react'
import PropTypes from 'prop-types'
import { FormControl } from 'material-ui/Form'
import Input, { InputLabel } from 'material-ui/Input'
import StripeInput from './StripeInput'
import Errors from './Errors'
export default class extends PureComponent {
static displayName = 'StripeElementWrapper'
static propTypes = {
component: PropTypes.func.isRequired,
label: PropTypes.string.isRequired,
}
state = {
focused: false,
empty: true,
error: false,
}
handleBlur = () => {
this.setState({ focused: false })
}
handleFocus = () => {
this.setState({ focused: true })
}
handleChange = changeObj => {
this.setState({
error: changeObj.error,
empty: changeObj.empty,
})
}
render() {
const { component, label } = this.props
const { focused, empty, error } = this.state
return (
<div>
<FormControl fullWidth margin="normal">
<InputLabel
focused={focused}
shrink={focused || !empty}
error={!!error}>
{label}
</InputLabel>
<Input
fullWidth
inputComponent={StripeInput}
onFocus={this.handleFocus}
onBlur={this.handleBlur}
onChange={this.handleChange}
inputProps={{ component }}
/>
</FormControl>
{error && <Errors>{error.message}</Errors>}
</div>
)
}
}
// Wrapper around the actual Stripe <*Element>, so that it can be used as `inputComponent`
// for Material UI's <Input>. Also adds some styling.
import React, { PureComponent } from 'react'
import PropTypes from 'prop-types'
import { withStyles } from 'material-ui/styles'
const styles = () => ({
root: {
width: '100%',
padding: '6px 0 7px',
cursor: 'text',
},
})
@withStyles(styles, { withTheme: true })
export default class extends PureComponent {
static displayName = 'StripeInput'
static propTypes = {
classes: PropTypes.object.isRequired,
theme: PropTypes.object.isRequired,
component: PropTypes.func.isRequired,
onBlur: PropTypes.func,
onFocus: PropTypes.func,
onChange: PropTypes.func,
}
static defaultProps = {
onFocus: () => {},
onBlur: () => {},
onChange: () => {},
}
render() {
const {
classes: c,
theme,
component: Component,
onFocus,
onBlur,
onChange,
} = this.props
return (
<Component
className={c.root}
onFocus={onFocus}
onBlur={onBlur}
onChange={onChange}
placeholder=""
style={{
base: {
fontSize: `${theme.typography.fontSize}px`,
fontFamily: theme.typography.fontFamily,
color: '#000000de',
},
}}
/>
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment