Created
April 18, 2018 10:27
-
-
Save michieldewilde/d7c5399e445bf8d1965aafe4f3162adb to your computer and use it in GitHub Desktop.
Dialogs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react' | |
import PropTypes from 'prop-types' | |
import { Formik } from 'formik' | |
import Dialog, { | |
DialogActions, | |
DialogContent, | |
DialogContentText, | |
DialogTitle | |
} from 'material-ui/Dialog' | |
import Button from 'material-ui/Button' | |
class FormDialog extends React.Component { | |
static propTypes = { | |
opener: PropTypes.func.isRequired | |
} | |
state = { | |
open: false | |
} | |
/** | |
* The dialog can serve many purposes by opening with a completely new state | |
* this should be validated eventually, but for now newState should have: | |
* | |
* title: string | |
* contentText: string | |
* validationSchema: yup schema object | |
* initialValues: formik initialValues | |
* render: formik render prop | |
* onSubmit: formik/dialog submit handler | |
*/ | |
handleOpen = newState => { | |
this.setState(() => ({ | |
...newState, | |
open: true | |
})) | |
} | |
handleClose = () => { | |
this.setState({ | |
open: false | |
}) | |
} | |
/** | |
* Calls the onSubmit passed via handleOpen with the | |
* formik submit args and the dialog close function | |
* (values, options: { setSubmitting, setErrors }, handleClose) | |
*/ | |
handleSubmit = (...formikSubmitArgs) => { | |
this.state.onSubmit(...formikSubmitArgs, this.handleClose) | |
} | |
render () { | |
const { | |
open, | |
title, | |
contentText, | |
validationSchema, | |
initialValues, | |
render | |
} = this.state | |
return ( | |
<div> | |
{this.props.opener(this.handleOpen)} | |
<Dialog open={open} onBackdropClick={this.handleClose}> | |
<DialogTitle>{title}</DialogTitle> | |
<Formik | |
validationSchema={validationSchema} | |
initialValues={initialValues} | |
onSubmit={this.handleSubmit} | |
render={formikProps => { | |
const { handleSubmit, isSubmitting } = formikProps | |
return ( | |
<form onSubmit={handleSubmit}> | |
<DialogContent> | |
<DialogContentText>{contentText}</DialogContentText> | |
{render(formikProps)} | |
</DialogContent> | |
<DialogActions> | |
<Button onClick={this.handleClose}>Cancel</Button> | |
<Button | |
type='submit' | |
color='secondary' | |
disabled={isSubmitting} | |
> | |
Submit | |
</Button> | |
</DialogActions> | |
</form> | |
) | |
}} | |
/> | |
</Dialog> | |
</div> | |
) | |
} | |
} | |
export default FormDialog |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
So the opener is a button that opens the dialog to create a screenshot. | |
I want to reuse that modal for editing a screenshot as well. | |
That will be done in a parent view by clicking on a item in a list. | |
How do I open the modal from outside of the FormDialog without using something like a global state manager? |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component } from 'react' | |
import PropTypes from 'prop-types' | |
import yup from 'yup' | |
import { | |
FormDialog, | |
FormikTextInput as TextInput, | |
FormikFileUploadInput as FileUploadInput | |
} from 'components' | |
import Button from 'material-ui/Button' | |
import { card } from '../../../styles' | |
const schema = yup.object().shape({ | |
caption: yup.string().required('This is a required field'), | |
image: yup.mixed().required() | |
}) | |
class ScreenshotDialog extends Component { | |
static propTypes = { | |
handleSubmit: PropTypes.func.isRequired | |
} | |
static defaultProps = { | |
screenshot: null | |
} | |
handleOpen = openWithState => () => { | |
const { screenshot } = this.props | |
const title = screenshot ? 'Edit Screenshot' : 'New Screenshot' | |
openWithState({ | |
title, | |
contentText: 'Add a screenshot with a descriptive caption', | |
initialValues: { | |
caption: screenshot ? screenshot.caption : '', | |
image: screenshot ? [screenshot.image] : [] | |
}, | |
validationSchema: schema, | |
render: this.renderFields, | |
onSubmit: this.props.handleSubmit | |
}) | |
} | |
renderFields = formikProps => ( | |
<fieldset style={{ ...card }}> | |
<TextInput | |
formikProps={formikProps} | |
label='Caption' | |
field='caption' | |
autoFocus | |
/> | |
<FileUploadInput | |
formikProps={formikProps} | |
label='Image' | |
field='image' | |
multiple={false} | |
/> | |
</fieldset> | |
) | |
opener = openWithState => ( | |
<Button | |
raised | |
className='fr' | |
color='primary' | |
onClick={this.handleOpen(openWithState)} | |
> | |
+ Add | |
</Button> | |
) | |
render () { | |
return ( | |
<FormDialog | |
opener={this.opener} | |
/> | |
) | |
} | |
} | |
export default ScreenshotDialog |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment