import React , { PureComponent } from 'react' ; import PropTypes from 'prop-types' ; import { Base16Theme } from 'base16' ; import createStyledComponent from '../utils/createStyledComponent' ; import * as styles from './styles' ; import Button from '../Button' ; import Form from '../Form' ; import { Props as FormProps } from '../Form/Form' ; const DialogWrapper = createStyledComponent ( styles ) ; export interface DialogProps { open ? : boolean ; title ? : string ; children ? : React . ReactNode ; actions ? : React . ReactNode [ ] ; submitText ? : string ; fullWidth ? : boolean ; noHeader ? : boolean ; noFooter ? : boolean ; modal ? : boolean ; onDismiss : ( e : React . MouseEvent < HTMLButtonElement | HTMLDivElement > | false ) => void ; onSubmit : ( ) => void ; theme ? : Base16Theme ; } type Rest < P > = Omit < DialogProps & FormProps < P > , 'modal' | 'open' | 'fullWidth' | 'title' | 'children' | 'actions' | 'noHeader' | 'noFooter' | 'submitText' | 'onDismiss' > ; function isForm < P > ( rest ? ) { return ( rest as FormProps < P > ) . schema !== undefined ; } export default class Dialog < P > extends PureComponent < DialogProps | ( Omit < DialogProps , 'onSubmit' > & FormProps < P > ) > { submitButton ? : HTMLInputElement | null ; onSubmit = ( ) => { if ( this . submitButton ) this . submitButton . click ( ) ; else ( this . props . onSubmit as ( ) => void ) ( ) ; } ; getFormButtonRef : React . RefCallback < HTMLInputElement > = ( node ) => { this . submitButton = node ; } ; onKeyDown : React . KeyboardEventHandler < HTMLDivElement > = ( e ) => { if ( e . keyCode === 27 ) { e . preventDefault ( ) ; this . props . onDismiss ( false ) ; } } ; render ( ) { const { modal , open , fullWidth , title , children , actions , noHeader , noFooter , submitText , onDismiss , ... rest } = this . props ; const schema = ( rest as Rest < P > ) . schema ; return ( < DialogWrapper open = { open } fullWidth = { fullWidth } onKeyDown = { this . onKeyDown } theme = { rest . theme } > < div onClick = { ! modal ? onDismiss : undefined } /> < div > { ! noHeader && ( < div className = "mc-dialog--header" > < div > { schema ? schema . title || title : title } < /div> { ! modal && < button onClick = { onDismiss } > × < /button>} < /div>)} < div className = "mc-dialog--body" > { children } { isForm ( rest as FormProps < P > ) && ( < Form { ... ( rest as FormProps < P > ) } > { ! noFooter && ( < input type = "submit" ref = { this . getFormButtonRef } className = "mc-dialog--hidden" / > ) } < /Form>)} < /div> { ! noFooter && ( actions ? ( < div className = "mc-dialog--footer" > { submitText ? [ ... actions , < Button key = "default-submit" primary onClick = { this . onSubmit } > { submitText } < /Button>, ] : actions } < /div>) : (<div className="mc-dialog--footer"> < Button onClick = { onDismiss } > Cancel < /Button> < Button primary onClick = { this . onSubmit } > { submitText || 'Submit' } < /Button> < /div>))} < /div> < /DialogWrapper>); } static propTypes = { open : PropTypes . bool , title : PropTypes . string , children : PropTypes . any , actions : PropTypes . node , submitText : PropTypes . string , fullWidth : PropTypes . bool , noHeader : PropTypes . bool , noFooter : PropTypes . bool , modal : PropTypes . bool , onDismiss : PropTypes . func , onSubmit : PropTypes . func , theme : PropTypes . object , } ; }