Repository URL to install this package:
|
Version:
3.5.5 ▾
|
import * as React from 'react'
import { observer } from 'xmobx/mobx-react'
import { FormEvent } from 'react'
import { isFunction } from 'exotic'
import { ValidationStrategyContext, ValidationStrategy } from '../strategies'
import { defaultRenderForm, defaultRenderButtonGroup } from './renderProps'
import { FormProps, FormRenderProps } from './typings'
import { Provider } from './FormContext'
@observer
export class ObserverForm extends React.Component<FormProps> {
static defaultProps = {
renderForm: defaultRenderForm,
renderButtonGroup: defaultRenderButtonGroup,
}
static contextType = ValidationStrategyContext
context: ValidationStrategy
handleSubmit = (event: FormEvent<any>) => {
event.preventDefault()
/**
* this is also where we can focus
* all the errored inputs
*
* we can also update the state here that is used by the button
* for example, adding a property such as
* "isSubmitting"
* "didSubmitSuccessfully"
* "didSubmitError"
*/
const { state } = this.props
const onSubmit = this.props.onSubmit || this.context.onSubmit
if (isFunction(onSubmit)) {
onSubmit({ state, event })
} else {
// @todo if not production @@production
const serialized = state.toJSON()
console.warn('[1forms] no onSubmit prop used')
console.log(serialized)
}
}
render() {
const {
renderForm,
renderButtonGroup,
renderInput,
...remainingProps
} = this.props
// @note - not destructuring above so it stays in `remainingProps`
const inputListView = this.props.state.inputsList.map(renderInput)
const baseAttributes = {
...remainingProps,
onSubmit: this.handleSubmit,
} as FormRenderProps
// @todo - get name from schema.org?
const submitView = renderButtonGroup(baseAttributes)
// @invariant - submit button always comes after form
// anyone asking you to change this is bad ux
const children = (
<React.Fragment>
{inputListView}
{submitView}
</React.Fragment>
)
const attributes = {
...baseAttributes,
id: this.props.state.identifier,
children,
}
const formView = renderForm(attributes)
return <Provider value={this.props.state}>{formView}</Provider>
}
}