UNPKG

@lyra/form-builder

Version:
282 lines (228 loc) 8.22 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _propTypes = require('prop-types'); var _propTypes2 = _interopRequireDefault(_propTypes); var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _FormBuilderPropTypes = require('../../FormBuilderPropTypes'); var _FormBuilderPropTypes2 = _interopRequireDefault(_FormBuilderPropTypes); var _Field = require('./Field'); var _Field2 = _interopRequireDefault(_Field); var _default = require('part:@lyra/components/fieldsets/default'); var _default2 = _interopRequireDefault(_default); var _PatchEvent = require('../../PatchEvent'); var _PatchEvent2 = _interopRequireDefault(_PatchEvent); var _isEmpty = require('../../utils/isEmpty'); var _isEmpty2 = _interopRequireDefault(_isEmpty); var _UnknownFields = require('./UnknownFields'); var _UnknownFields2 = _interopRequireDefault(_UnknownFields); var _Field3 = require('./styles/Field.css'); var _Field4 = _interopRequireDefault(_Field3); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function getCollapsedWithDefaults(options = {}, level) { // todo: warn on "collapsable" and deprecate collapsible in favor of just "collapsed" // --> relevant: https://github.com/lyra-io/lyra/issues/537 if (options.collapsible === true || options.collapsable === true) { // collapsible explicit set to true return { collapsible: true, collapsed: options.collapsed !== false }; } else if (options.collapsible === false || options.collapsable === false) { // collapsible explicit set to false return { // hard limit to avoid infinite recursion collapsible: level > 9, collapsed: level > 9 }; } // default return { collapsible: level > 2, collapsed: level > 2 }; } class ObjectInput extends _react2.default.PureComponent { constructor(...args) { var _temp; return _temp = super(...args), this.handleFieldChange = (fieldEvent /*: PatchEvent*/, field) => { var _props = this.props; const onChange = _props.onChange, type = _props.type, value = _props.value, isRoot = _props.isRoot; let event = fieldEvent.prefixAll(field.name); if (!isRoot) { event = event.prepend((0, _PatchEvent.setIfMissing)(type.name === 'object' ? {} : { _type: type.name })); if (value) { const valueTypeName = value && value._type; const schemaTypeName = type.name; // eslint-disable-next-line max-depth if (valueTypeName && schemaTypeName === 'object') { // The value has a _type key, but the type name from schema is 'object', // but _type: 'object' is implicit so we should fix it by removing it event = event.prepend((0, _PatchEvent.unset)(['_type'])); } else if (schemaTypeName !== 'object' && valueTypeName !== schemaTypeName) { // There's a mismatch between schema type and the value _type // fix it by setting _type to type name defined in schema event = event.prepend((0, _PatchEvent.set)(schemaTypeName, ['_type'])); } } } onChange(event); }, this.setFirstField = el => { this._firstField = el; }, _temp; } handleBlur() { var _props2 = this.props; const onChange = _props2.onChange, value = _props2.value; if ((0, _isEmpty2.default)(value)) { onChange(_PatchEvent2.default.from((0, _PatchEvent.unset)())); } } renderField(field, level, index) { if (field.type.hidden) { return null; } var _props3 = this.props; const value = _props3.value, markers = _props3.markers, readOnly = _props3.readOnly, focusPath = _props3.focusPath, onFocus = _props3.onFocus, onBlur = _props3.onBlur; const fieldValue = value && value[field.name]; return _react2.default.createElement(_Field2.default, { key: field.name, field: field, value: fieldValue, onChange: this.handleFieldChange, onFocus: onFocus, onBlur: onBlur, markers: markers, focusPath: focusPath, level: level, readOnly: readOnly, ref: index === 0 && this.setFirstField }); } renderFieldset(fieldset, fieldsetIndex) { var _props4 = this.props; const level = _props4.level, focusPath = _props4.focusPath; const columns = fieldset.options && fieldset.options.columns; const collapsibleOpts = getCollapsedWithDefaults(fieldset.options, level); const isExpanded = focusPath.length > 0 && fieldset.fields.some(field => focusPath[0] === field.name); return _react2.default.createElement( 'div', { key: fieldset.name, className: _Field4.default.root }, _react2.default.createElement( _default2.default, { legend: fieldset.title, description: fieldset.description, level: level + 1, columns: columns, isCollapsible: collapsibleOpts.collapsible, isCollapsed: !isExpanded && collapsibleOpts.collapsed }, fieldset.fields.map((field, fieldIndex) => { return this.renderField(field, level + 2, fieldsetIndex + fieldIndex); }) ) ); } getRenderedFields() { var _props5 = this.props; const type = _props5.type, level = _props5.level; if (!type.fieldsets) { // this is a fallback for schema types that are not parsed to be objects, but still has jsonType == 'object' return (type.fields || []).map((field, i) => this.renderField(field, level + 1, i)); } return type.fieldsets.map((fieldset, i) => { return fieldset.single ? this.renderField(fieldset.field, level + 1, i) : this.renderFieldset(fieldset, i); }); } renderUnknownFields() { var _props6 = this.props; const value = _props6.value, type = _props6.type, onChange = _props6.onChange, readOnly = _props6.readOnly; if (!type.fields) { return null; } const knownFieldNames = type.fields.map(field => field.name); const unknownFields = Object.keys(value || {}).filter(key => !key.startsWith('_') && !knownFieldNames.includes(key)); if (unknownFields.length === 0) { return null; } return _react2.default.createElement(_UnknownFields2.default, { readOnly: readOnly, fieldNames: unknownFields, value: value, onChange: onChange }); } focus() { if (this._firstField) { this._firstField.focus(); } } render() { var _props7 = this.props; const type = _props7.type, level = _props7.level, focusPath = _props7.focusPath; const renderedFields = this.getRenderedFields(); const renderedUnknownFields = this.renderUnknownFields(); if (level === 0) { return _react2.default.createElement( 'div', null, renderedFields, renderedUnknownFields ); } const collapsibleOpts = getCollapsedWithDefaults(type.options, level); const isExpanded = focusPath.length > 0; const columns = type.options && type.options.columns; return _react2.default.createElement( _default2.default, { level: level, legend: type.title, description: type.description, columns: columns, isCollapsible: collapsibleOpts.collapsible, isCollapsed: !isExpanded && collapsibleOpts.collapsed }, renderedFields, renderedUnknownFields ); } } exports.default = ObjectInput; ObjectInput.propTypes = { type: _FormBuilderPropTypes2.default.type, value: _propTypes2.default.object, onChange: _propTypes2.default.func, onFocus: _propTypes2.default.func.isRequired, focusPath: _propTypes2.default.array, markers: _propTypes2.default.array, onBlur: _propTypes2.default.func.isRequired, level: _propTypes2.default.number, readOnly: _propTypes2.default.bool, isRoot: _propTypes2.default.bool }; ObjectInput.defaultProps = { onChange() {}, level: 0, focusPath: [], isRoot: false };