Repository URL to install this package:
|
Version:
3.0.0-beta.1 ▾
|
import * as React from 'react'
import { FocusEvent, ChangeEvent } from 'react'
import { observer } from 'xmobx/mobx-react'
import { defaultRender, defaultRenderWrap } from './renderProps'
import { InputProps, ObserverInputProps, InputRenderProps } from './typings'
import { Provider } from './InputContext'
function fromPropsToInputState(props: ObserverInputProps) {
if (process.env.NODE_ENV === 'production') {
return props.state
} else {
if (!props.state) {
throw new Error('must pass `state` to <ObserverInput>')
} else {
return props.state
}
}
}
/**
* @thought
* observable stuff here should be probably in the render of plugin
* @thought
* we *may* want to support `onChange` here
* but probably best to allow *only 1 way* (using state)
*/
@observer
export class ObserverInput<
Props extends ObserverInputProps = ObserverInputProps
> extends React.Component<Props> {
static defaultProps = {
renderInput: defaultRender,
renderWrap: defaultRenderWrap,
}
observableState = fromPropsToInputState(this.props)
handleChange = (event: ChangeEvent<any>) => {
console.debug('[1input] change')
this.observableState.setValue(event.target.value)
}
handleOnFocus = (event: FocusEvent<any>) => {
console.debug('[1input] focus')
this.observableState.setIsActive(true)
}
handleOnBlur = (event: FocusEvent<any>) => {
console.debug('[1input] blur')
this.observableState.setIsActive(false)
}
render() {
const props = this.props as InputProps
const { renderWrap, renderInput, state, ...remainingProps } = props
const {
type,
value,
label,
// identifier,
// isActive,
// isValid,
onChange,
onFocus,
onBlur,
...strippedRemainingProps
} = remainingProps
/**
* @todo we could probably get rid of most of this if we use context
* ^ ONLY THING TO NOTE IS PROPS VS STATE
*/
const renderPropProps = {
// @note !!! unsure whether props should override, or state !!!
// ^ for 1 story when debugging at least making props override...
// ...remainingProps,
// @note - changed this to explicitly spread, but allow `attributes` spreading
// ...this.observableState,
// @note - not needed
// validator: this.observableState.validator,
// formState: this.observableState.formState,
// propertyName: this.observableState.propertyName,
...this.observableState.attributes,
identifier: this.observableState.identifier,
type: type || this.observableState.type,
value: this.observableState.value as string | number,
label: this.observableState.label || label,
state: this.observableState,
isActive: this.observableState.isActive,
isValid: this.observableState.isValid,
onChange: this.handleChange,
onFocus: this.handleOnFocus,
onBlur: this.handleOnBlur,
// @note changed this to avoid any confusion
...strippedRemainingProps,
}
// @todo why is it not done this way...
// const inputView = (
// <>
// {renderLabelText(props)}
// {renderInput(renderPropProps as InputRenderProps)}
// {defaultRenderAfterInput(props)}
// {renderError(props)}
// </>
// )
const children = renderInput(renderPropProps as InputRenderProps)
const view = renderWrap({ ...renderPropProps, children })
return <Provider value={this.observableState}>{view}</Provider>
}
}