-
-
Save lfalke/1c5e7168424c8b2a65dcfba425fcc310 to your computer and use it in GitHub Desktop.
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', | |
}, | |
}} | |
/> | |
) | |
} | |
} |
@tobytraylor I just used FormHelperText
like the material-ui TextField
on which this input wrapper is based does:
{error &&
<FormHelperText error>
{error.message}
</FormHelperText>}
You could possibly embellish this or pass other props specific to the error message, but this displays error messages underneath the input like TextField
.
You can find a dedicated thread to this problem in mui/material-ui#16037.
Am afraid this is not working for me. I am getting this error: Warning: Failed context type: The context `addElementsLoadListener` is marked as required in `CardNum berElement`, but its value is `undefined`.
Am afraid this is not working for me. I am getting this error:
Warning: Failed context type: The context `addElementsLoadListener` is marked as required in `CardNum berElement`, but its value is `undefined`.
@jermsam those undefined values are usually provided by a React Stripe Elements implementation. The failed context issue is likely caused by missing required parents described in the setup procedure for [email protected]
that would embed the content of this gist as a child:
<StripeProvider>
<Elements>
<InjectedForm>
{contentOfThisGist}
</InjectedForm>
</Elements>
</StripeProvider>
It is showing an error that 'c' is undefined in StripeInput.js
Please refer to mui/material-ui#16037 for a working solution.
when pressing submit, the 'required' attribute is not triggered when the field is empty. The Component in stripeinput is disabling this option, any suggestions?
Am afraid this is not working for me. I am getting this error:
Warning: Failed context type: The context `addElementsLoadListener` is marked as required in `CardNum berElement`, but its value is `undefined`.
@jermsam those undefined values are usually provided by a React Stripe Elements implementation. The failed context issue is likely caused by missing required parents described in the setup procedure for
[email protected]
that would embed the content of this gist as a child:<StripeProvider> <Elements> <InjectedForm> {contentOfThisGist} </InjectedForm> </Elements> </StripeProvider>
Where is InjectedForm Component?
Hey. I just stumbled across this. I don't suppose you could post your Errors.js file?