@lyra/form-builder
Version:
Lyra form builder
182 lines (155 loc) • 5.58 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
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 _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _slate = require('slate');
var _pathUtils = require('../../../utils/pathUtils');
var _Span = require('./styles/Span.css');
var _Span2 = _interopRequireDefault(_Span);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/*:: import type {
BlockContentFeatures,
SlateValue,
Type,
SlateChange,
Marker
} from '../typeDefs'*/
/*:: import type {Node} from 'react'*/
/*:: type Props = {
attributes: {},
blockContentFeatures: BlockContentFeatures,
children: Node,
editorValue: SlateValue,
node: Inline,
markers: Marker[],
onChange: (change: SlateChange) => void,
onFocus: (nextPath: []) => void,
onFormBuilderInputBlur: (nextPath: []) => void,
onFormBuilderInputFocus: (nextPath: []) => void,
readOnly?: boolean,
type: ?Type
}*/
/*:: type State = {
focusedAnnotationName: ?string,
isEditing: boolean,
rootElement: ?HTMLSpanElement
}*/
class Span extends _react2.default.Component /*:: <Props, State>*/ {
constructor(props /*: Props*/) {
super(props);
_initialiseProps.call(this);
const focusedAnnotationName = this.props.node.data.get('focusedAnnotationName');
this.state = {
focusedAnnotationName: focusedAnnotationName
};
}
getAnnotations() {
return this.props.node.data.get('annotations');
}
focusAnnotation(annotationName /*: string*/) {
var _props = this.props;
const editorValue = _props.editorValue,
node = _props.node,
onChange = _props.onChange;
this.setState({ focusedAnnotationName: annotationName });
if (node.data.get('focusedAnnotationName') === annotationName) {
return;
}
const data = _extends({}, node.data.toObject(), {
focusedAnnotationName: annotationName
});
const change = editorValue.change();
change.setNodeByKey(node.key, { data });
onChange(change);
}
// Open dialog when user clicks the node,
// but don't act on double clicks (mark text as normal)
startEditing() {
var _props2 = this.props;
const editorValue = _props2.editorValue,
node = _props2.node,
onFocus = _props2.onFocus;
const block = editorValue.document.getClosestBlock(node.key);
const focusPath = [{ _key: block.key }, 'markDefs', {
_key: node.data.get('annotations')[this.state.focusedAnnotationName]._key
}, _pathUtils.FOCUS_TERMINATOR];
onFocus(focusPath);
}
render() {
var _props3 = this.props;
const attributes = _props3.attributes,
blockContentFeatures = _props3.blockContentFeatures,
markers = _props3.markers;
let children = this.props.children;
const annotations = this.getAnnotations();
const annotationTypes = blockContentFeatures.annotations.filter(item => Object.keys(annotations).includes(item.value));
annotationTypes.forEach(annotation => {
const CustomComponent = annotation && annotation.blockEditor && annotation.blockEditor.render ? annotation.blockEditor.render : null;
if (CustomComponent) {
children = _react2.default.createElement(
CustomComponent,
annotations[annotation.value],
children
);
}
});
const validation = markers.filter(marker => marker.type === 'validation');
const errors = validation.filter(marker => marker.level === 'error');
return _react2.default.createElement(
'span',
_extends({}, attributes, {
onMouseDown: this.handleMouseDown,
onMouseUp: this.handleMouseUp,
onClick: this.handleClick,
className: errors.length ? _Span2.default.error : _Span2.default.valid,
ref: this.refSpan
}),
children
);
}
}
exports.default = Span;
var _initialiseProps = function _initialiseProps() {
this._clickCounter = 0;
this._isMarkingText = false;
this.handleMouseDown = () => {
this._isMarkingText = true;
setTimeout(() => {
if (this._clickCounter === 1 && !this._isMarkingText) {
this.startEditing();
}
this._clickCounter = 0;
}, 200);
this._clickCounter++;
};
this.handleMouseUp = () => {
this._isMarkingText = false;
};
this.handleClick = () => {
const type = this.props.type;
if (!type) {
return;
}
// Don't do anyting if this type doesn't support any annotations.
if (!type.annotations || type.annotations.length === 0) {
return;
}
const annotations = this.getAnnotations();
// Try to figure out which annotation that should be focused when user clicks the span
let focusedAnnotationName;
if (type.annotations && type.annotations.length === 1) {
// Only one annotation type, always focus this one
focusedAnnotationName = type.annotations[0].name;
} else if (annotations && Object.keys(annotations).length === 1) {
// Only one annotation value, focus it
focusedAnnotationName = annotations[Object.keys(annotations)[0]]._type;
}
if (focusedAnnotationName) {
this.focusAnnotation(focusedAnnotationName);
}
// If no focusedAnnotationName was found, buttons to edit respective annotations will be show
};
};