UNPKG

@lyra/form-builder

Version:
243 lines (195 loc) 7.83 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.FormBuilderInput = undefined; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _class, _temp2; /* eslint-disable complexity */ var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _PatchEvent = require('./PatchEvent'); var _PatchEvent2 = _interopRequireDefault(_PatchEvent); var _generateHelpUrl = require('@lyra/generate-help-url'); var _generateHelpUrl2 = _interopRequireDefault(_generateHelpUrl); var _pathUtils = require('./utils/pathUtils'); var PathUtils = _interopRequireWildcard(_pathUtils); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } /*:: import type {Path} from './typedefs/path'*/ /*:: import type {Type} from './typedefs'*/ /*:: type Props = { value: any, type: Type, onChange: PatchEvent => void, onFocus: Path => void, onBlur: () => void, readOnly: boolean, focusPath: Path, markers: Array<*>, level: number, isRoot: boolean, path: Array<PathSegment> }*/ const ENABLE_CONTEXT = () => {}; function getDisplayName(component) { return component.displayName || component.name || 'Unknown'; } function trimChildPath(path, childPath) { return PathUtils.startsWith(path, childPath) ? PathUtils.trimLeft(path, childPath) : []; } const FormBuilderInput = (_temp2 = _class = class FormBuilderInput extends _react2.default.PureComponent /*:: < Props >*/ { constructor(...args) { var _temp; return _temp = super(...args), this.getValuePath = () => { return this.context.getValuePath().concat(this.props.path); }, this.setInput = (component /*: ?FormBuilderInput*/) => { this._input = component; }, this.handleChange = patchEvent => { var _props = this.props; const type = _props.type, onChange = _props.onChange; if (type.readOnly) { return; } onChange(patchEvent); }, this.handleFocus = nextPath => { var _props2 = this.props; const path = _props2.path, onFocus = _props2.onFocus, focusPath = _props2.focusPath; if (!onFocus) { console.warn( // eslint-disable-line no-console 'FormBuilderInput was used without passing a required onFocus prop. Read more at %s.', (0, _generateHelpUrl2.default)('form-builder-input-missing-required-prop')); return; } const nextFocusPath = Array.isArray(nextPath) ? [...path, ...nextPath] : path; if (PathUtils.isEqual(focusPath, nextFocusPath)) { // no change return; } onFocus(nextFocusPath); }, this.handleBlur = () => { const onBlur = this.props.onBlur; if (!onBlur) { console.warn( // eslint-disable-line no-console 'FormBuilderInput was used without passing a required onBlur prop. Read more at %s.', (0, _generateHelpUrl2.default)('form-builder-input-missing-required-prop')); return; } onBlur(); }, this.setElement = (el /*: ?HTMLDivElement*/) => { this._element = el; }, _temp; } getChildContext() { return { getValuePath: this.getValuePath }; } componentDidMount() { var _props3 = this.props; const focusPath = _props3.focusPath, path = _props3.path; if (PathUtils.hasFocus(focusPath, path)) { this.focus(); } } componentWillReceiveProps(nextProps /*: Props*/) { const willHaveFocus = PathUtils.hasFocus(nextProps.focusPath, nextProps.path); const hasFocus = PathUtils.hasFocus(this.props.focusPath, this.props.path); if (willHaveFocus && !hasFocus) { this.focus(); } } componentWillUnmount() { if (this.scrollTimeout) { clearTimeout(this.scrollTimeout); } } resolveInputComponent(type /*: Type*/) { return this.context.formBuilder.resolveInputComponent(type); } _withInputDisplayName(cb /*: (str: string) => void*/) { cb(getDisplayName(this.resolveInputComponent(this.props.type))); } focus() { if (!this._input) { // should never happen throw new Error('Attempted to set focus on a missing input component'); } if (typeof this._input.focus !== 'function') { this._withInputDisplayName(displayName => console.warn('Missing a required ".focus()" method on input component. Please check the implementation of %s. Read more at %s', displayName, (0, _generateHelpUrl2.default)('input-component-missing-required-method'))); return; } this._input.focus(); } getChildFocusPath() { var _props4 = this.props; const path = _props4.path, focusPath = _props4.focusPath; return trimChildPath(path, focusPath); } render() { var _props5 = this.props; const onChange = _props5.onChange, onFocus = _props5.onFocus, onBlur = _props5.onBlur, path = _props5.path, readOnly = _props5.readOnly, value = _props5.value, markers = _props5.markers, type = _props5.type, level = _props5.level, focusPath = _props5.focusPath, isRoot = _props5.isRoot, rest = _objectWithoutProperties(_props5, ['onChange', 'onFocus', 'onBlur', 'path', 'readOnly', 'value', 'markers', 'type', 'level', 'focusPath', 'isRoot']); const InputComponent = this.resolveInputComponent(type); if (!InputComponent) { return _react2.default.createElement( 'div', null, 'No input resolved for type ', JSON.stringify(type.name) ); } const rootProps = isRoot ? { isRoot } : {}; let childMarkers = markers; if (!isRoot) { childMarkers = markers.filter(marker => PathUtils.startsWith(path, marker.path)).map(marker => _extends({}, marker, { path: trimChildPath(path, marker.path) })); } const childFocusPath = this.getChildFocusPath(); const isLeaf = childFocusPath.length === 0 || childFocusPath[0] === PathUtils.FOCUS_TERMINATOR; const leafProps = isLeaf ? {} : { focusPath: childFocusPath }; return _react2.default.createElement( 'div', { ref: this.setElement, 'data-focus-path': PathUtils.toString(path) }, _react2.default.createElement(InputComponent, _extends({}, rest, rootProps, leafProps, { value: value, readOnly: readOnly || type.readOnly, markers: childMarkers, type: type, onChange: this.handleChange, onFocus: this.handleFocus, onBlur: this.handleBlur, level: level, ref: this.setInput })) ); } }, _class.contextTypes = { formBuilder: ENABLE_CONTEXT, getValuePath: ENABLE_CONTEXT }, _class.childContextTypes = { getValuePath: ENABLE_CONTEXT }, _class.defaultProps = { focusPath: [], path: [], markers: [] }, _temp2); exports.FormBuilderInput = FormBuilderInput;