@lyra/form-builder
Version:
Lyra form builder
291 lines (239 loc) • 8.9 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _get2 = require('lodash/get');
var _get3 = _interopRequireDefault(_get2);
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _default = require('part:@lyra/components/lists/default');
var _sortable = require('part:@lyra/components/lists/sortable');
var _functions = require('part:@lyra/form-builder/input/array/functions');
var _functions2 = _interopRequireDefault(_functions);
var _default2 = require('part:@lyra/components/fieldsets/default');
var _default3 = _interopRequireDefault(_default2);
var _PatchEvent = require('../../PatchEvent');
var _pathUtils = require('../../utils/pathUtils');
var _resolveTypeName = require('../../utils/resolveTypeName');
var _InvalidValueInput = require('../InvalidValueInput');
var _InvalidValueInput2 = _interopRequireDefault(_InvalidValueInput);
var _ArrayOfPrimitivesInput = require('./styles/ArrayOfPrimitivesInput.css');
var _ArrayOfPrimitivesInput2 = _interopRequireDefault(_ArrayOfPrimitivesInput);
var _getEmptyValue = require('./getEmptyValue');
var _getEmptyValue2 = _interopRequireDefault(_getEmptyValue);
var _Item = require('./Item');
var _Item2 = _interopRequireDefault(_Item);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/*:: import type {Path} from '../../typedefs/path'*/
/*:: import type {Type, Marker} from '../../typedefs'*/
/*:: import type {ItemValue} from '../ArrayInput/typedefs'*/
function move(arr, from, to) {
const copy = arr.slice();
const val = copy[from];
copy.splice(from, 1);
copy.splice(to, 0, val);
return copy;
}
function insertAt(arr, index, item) {
const copy = arr.slice();
copy.splice(index + 1, 0, item);
return copy;
}
/*:: type Props = {
type: Type,
value: Array<ItemValue>,
level: number,
onChange: (event: PatchEvent) => void,
onFocus: Path => void,
onBlur: () => void,
focusPath: Path,
readOnly: ?boolean,
markers: Array<Marker>
}*/
class ArrayOfPrimitivesInput extends _react2.default.PureComponent /*:: <Props>*/ {
constructor(...args) {
var _temp;
return _temp = super(...args), this._lastAddedIndex = -1, this.handleAppend = itemValue => {
var _props = this.props,
_props$value = _props.value;
const value = _props$value === undefined ? [] : _props$value,
onFocus = _props.onFocus;
this.set(value.concat(itemValue));
onFocus([value.length]);
}, this.handlePrepend = itemValue => {
var _props2 = this.props,
_props2$value = _props2.value;
const value = _props2$value === undefined ? [] : _props2$value,
onFocus = _props2.onFocus;
this.set([itemValue].concat(value));
onFocus([value.length]);
}, this.handleRemoveItem = (index /*: number*/) => {
this.removeAt(index);
}, this.handleItemChange = event => {
this._lastAddedIndex = -1;
this.props.onChange(event);
}, this.handleItemEnterKey = index => {
this.insertAt(index, this.props.type.of[0]);
this._lastAddedIndex = index + 1;
}, this.handleItemEscapeKey = index => {
const value = this.props.value;
if (index === this._lastAddedIndex && value[index] === '') {
this.removeAt(index);
}
}, this.handleSortEnd = event => {
const value = this.props.value;
const oldIndex = event.oldIndex,
newIndex = event.newIndex;
this.set(move(value, oldIndex, newIndex));
}, this.renderItem = (item, index) => {
var _props3 = this.props;
const type = _props3.type,
level = _props3.level,
markers = _props3.markers,
value = _props3.value,
focusPath = _props3.focusPath,
onChange = _props3.onChange,
onFocus = _props3.onFocus,
readOnly = _props3.readOnly,
onBlur = _props3.onBlur;
const typeName = (0, _resolveTypeName.resolveTypeName)(item);
const itemMemberType = this.getMemberType(typeName);
if (!itemMemberType) {
return _react2.default.createElement(_InvalidValueInput2.default, {
key: index,
actualType: typeName,
validTypes: type.of.map(memberType => memberType.name),
onChange: function (_onChange) {
function onChange(_x) {
return _onChange.apply(this, arguments);
}
onChange.toString = function () {
return _onChange.toString();
};
return onChange;
}(ev => onChange(ev.prefixAll(index))),
value: value
});
}
const isSortable = (0, _get3.default)(type, 'options.sortable') !== false;
const ListItem = isSortable ? _sortable.Item : _default.Item;
const filteredMarkers = markers.filter(marker => (0, _pathUtils.startsWith)([index], marker.path));
return _react2.default.createElement(
ListItem,
{ key: index, index: index, className: _ArrayOfPrimitivesInput2.default.item },
_react2.default.createElement(_Item2.default, {
level: level + 1,
index: index,
value: item,
readOnly: readOnly,
markers: filteredMarkers,
isSortable: isSortable,
type: itemMemberType,
focusPath: focusPath,
onFocus: onFocus,
onBlur: onBlur,
onEnterKey: this.handleItemEnterKey,
onEscapeKey: this.handleItemEscapeKey,
onChange: this.handleItemChange,
onRemove: this.handleRemoveItem
})
);
}, this.setElement = (el /*: ?Fieldset*/) => {
this._element = el;
}, this.handleFocusItem = index => {
this.props.onFocus([index]);
}, _temp;
}
set(nextValue /*: any[]*/) {
this._lastAddedIndex = -1;
const patch = nextValue.length === 0 ? (0, _PatchEvent.unset)() : (0, _PatchEvent.set)(nextValue);
this.props.onChange(_PatchEvent.PatchEvent.from(patch));
}
removeAt(index /*: number*/) {
var _props$value2 = this.props.value;
const value = _props$value2 === undefined ? [] : _props$value2;
this.set(value.filter((_, i) => i !== index));
this.props.onFocus([Math.max(0, index - 1)]);
}
insertAt(index, type) {
var _props4 = this.props,
_props4$value = _props4.value;
const value = _props4$value === undefined ? [] : _props4$value,
onFocus = _props4.onFocus;
this.set(insertAt(value, index, (0, _getEmptyValue2.default)(type)));
onFocus([index + 1]);
}
getMemberType(typeName) {
const type = this.props.type;
return type.of.find(memberType => memberType.name === typeName || memberType.jsonType === typeName);
}
renderList(value) {
const type = this.props.type;
const isSortable = (0, _get3.default)(type, 'options.sortable') !== false;
return isSortable ? _react2.default.createElement(
_sortable.List,
{
className: _ArrayOfPrimitivesInput2.default.list,
onSortEnd: this.handleSortEnd,
movingItemClass: _ArrayOfPrimitivesInput2.default.movingItem,
useDragHandle: true
},
value.map(this.renderItem)
) : _react2.default.createElement(
_default.List,
{ decoration: 'divider' },
value.map(this.renderItem)
);
}
focus() {
if (this._element) {
this._element.focus();
}
}
render() {
var _props5 = this.props;
const type = _props5.type,
value = _props5.value,
level = _props5.level,
markers = _props5.markers,
readOnly = _props5.readOnly,
onChange = _props5.onChange,
onFocus = _props5.onFocus;
return _react2.default.createElement(
_default3.default,
{
legend: type.title,
description: type.description,
level: level,
tabIndex: 0,
onFocus: onFocus,
ref: this.setElement,
markers: markers
},
_react2.default.createElement(
'div',
{ className: _ArrayOfPrimitivesInput2.default.root },
_react2.default.createElement(
'div',
{ className: _ArrayOfPrimitivesInput2.default.list },
value && value.length > 0 && this.renderList(value)
),
_react2.default.createElement(
'div',
{ className: _ArrayOfPrimitivesInput2.default.functions },
_react2.default.createElement(_functions2.default, {
type: type,
value: value,
readOnly: readOnly,
onAppendItem: this.handleAppend,
onPrependItem: this.handlePrepend,
onFocusItem: this.handleFocusItem,
onCreateValue: _getEmptyValue2.default,
onChange: onChange
})
)
)
);
}
}
exports.default = ArrayOfPrimitivesInput;