@lyra/form-builder
Version:
Lyra form builder
136 lines (113 loc) • 3.83 kB
JavaScript
'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 _schema = require('@lyra/schema');
var _schema2 = _interopRequireDefault(_schema);
var _nanoPubsub = require('nano-pubsub');
var _nanoPubsub2 = _interopRequireDefault(_nanoPubsub);
var _fallbackInputs = require('./fallbackInputs');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const NOOP = () => {};
function resolve(type, providedResolve = NOOP) {
let itType = type;
while (itType) {
const resolved = providedResolve(itType);
if (resolved) {
return resolved;
}
itType = itType.type;
}
return undefined;
}
// Memoize return values from a method that takes a single arg
// memoized as a map of argument => return value
function memoizeMap(method) {
const map = new WeakMap();
return function memoizedMap(arg) {
if (map.has(arg)) {
return map.get(arg);
}
const val = method.call(this, arg);
if (arg) {
map.set(arg, val);
}
return val;
};
}
// Memoize return value from method that takes no args
function memoize(method) {
let called = false;
let val;
return function memoized() {
if (called) {
return val;
}
val = method.call(this);
called = true;
return val;
};
}
class FormBuilderContext extends _react2.default.Component {
constructor(...args) {
var _temp;
return _temp = super(...args), this.getDocument = () => {
return this.props.value;
}, this.resolveInputComponent = memoizeMap(type => {
const resolveInputComponent = this.props.resolveInputComponent;
return resolve(type, resolveInputComponent) || _fallbackInputs.fallbackInputs[type.jsonType];
}), this.resolvePreviewComponent = memoizeMap(type => {
const resolvePreviewComponent = this.props.resolvePreviewComponent;
return resolve(type, resolvePreviewComponent);
}), this.getChildContext = memoize(() => {
var _props = this.props;
const schema = _props.schema,
patchChannel = _props.patchChannel;
return {
getValuePath: () => [],
formBuilder: {
onPatch: patchChannel ? patchChannel.onPatch : () => {
// eslint-disable-next-line no-console
console.warn('No patch channel provided to form-builder. If you need input based patch updates, please provide one');
return NOOP;
},
schema,
resolveInputComponent: this.resolveInputComponent,
resolvePreviewComponent: this.resolvePreviewComponent,
getDocument: this.getDocument
}
};
}), _temp;
}
render() {
return this.props.children;
}
}
exports.default = FormBuilderContext;
FormBuilderContext.createPatchChannel = () => {
const channel = (0, _nanoPubsub2.default)();
return { onPatch: channel.subscribe, receivePatches: channel.publish };
};
FormBuilderContext.propTypes = {
schema: _propTypes2.default.instanceOf(_schema2.default).isRequired,
value: _propTypes2.default.any,
children: _propTypes2.default.any.isRequired,
patchChannel: _propTypes2.default.shape({
onPatch: _propTypes2.default.func
}),
resolveInputComponent: _propTypes2.default.func.isRequired,
resolvePreviewComponent: _propTypes2.default.func.isRequired
};
FormBuilderContext.childContextTypes = {
getValuePath: _propTypes2.default.func,
onPatch: _propTypes2.default.func,
formBuilder: _propTypes2.default.shape({
schema: _propTypes2.default.instanceOf(_schema2.default),
resolveInputComponent: _propTypes2.default.func,
document: _propTypes2.default.any
})
};