react-text-holder-insertable
Version:
insert text holder block to content editable area
154 lines (121 loc) • 4.66 kB
JavaScript
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
var $ = _interopDefault(require('jquery'));
var lodash = require('lodash');
var React = require('react');
var React__default = _interopDefault(React);
var PropTypes = _interopDefault(require('prop-types'));
var ContentEditable = _interopDefault(require('react-contenteditable'));
var style = {"text-holder":"_text-holder-module__text-holder__YG9kW","text-holder-label":"_text-holder-module__text-holder-label__2FfSn","text-holder-cancel":"_text-holder-module__text-holder-cancel__3Sv40"};
var TextHolder = function TextHolder(label, options) {
var _this = this;
if (options === void 0) {
options = {};
}
this.getJq = function () {
var holderLabel = $("<span/>").addClass(style["text-holder-label"]).css(_this.options.textHolderLabelStyle || {}).html(_this.label);
var jq = $("<span/>").addClass(style["text-holder"]).css(_this.options.textHolderStyle || {}).attr("contenteditable", "false").append(holderLabel);
if (_this.options.withCancel) {
var holderCancel = $("<span/>").addClass(style["text-holder-cancel"]).css(_this.options.textHolderCancelStyle || {}).html("x");
jq.append(holderCancel);
}
return jq;
};
this.getEl = function () {
return _this.getJq()[0];
};
this.getHolderOuterHTML = function () {
return _this.getEl().outerHTML;
};
this.insert = function (anchorOffset, setHtml, boxRef) {
var inputBox = lodash.get(boxRef, "current.el.current");
if (anchorOffset >= 0 && anchorOffset !== null && inputBox) {
var __html = $(inputBox).html();
var front = __html.substring(0, anchorOffset);
var latter = __html.substring(anchorOffset);
var inserted = _this.getEl().outerHTML;
__html = "" + front + inserted + latter;
setHtml(__html);
}
};
this.label = label;
this.options = options;
};
function TextHolderInsertable(_ref) {
var html = _ref.html,
onChange = _ref.onChange,
initialAnchorOffset = _ref.initialAnchorOffset,
onAnchorOffsetChange = _ref.onAnchorOffsetChange,
onTextChange = _ref.onTextChange,
boxRef = _ref.boxRef;
var _useState = React.useState(initialAnchorOffset || 0),
__anchorOffset = _useState[0],
__setAnchorOffset = _useState[1];
var _useState2 = React.useState(html || ""),
__html = _useState2[0],
__setHtml = _useState2[1];
var handleChange = function handleChange(e) {
onChange(e);
__setHtml(e.target.value);
};
React.useEffect(function () {
onAnchorOffsetChange(__anchorOffset);
}, [__anchorOffset, onAnchorOffsetChange]);
React.useEffect(function () {
__setHtml(html);
}, [html]);
React.useEffect(function () {
onTextChange && onTextChange(getText());
}, [__html]);
function getText() {
var jq = $("<div/>").html(__html);
jq.find("." + style["text-holder-cancel"]).each(function (_, ele) {
return $(ele).remove();
});
return jq.text();
}
function getTextActualStartOffset(startContainer) {
var prevSib = startContainer.previousSibling;
if (!prevSib) return 0;
var prevSibContentLen = prevSib.nodeType === 1 ? prevSib.outerHTML.length : prevSib.textContent.length;
return prevSibContentLen + getTextActualStartOffset(prevSib);
}
var updateAnchorOffset = function updateAnchorOffset(e) {
var sel = window.getSelection();
var jq = $(e.target);
if ([style["text-holder"], style["text-holder-label"], style["text-holder-cancel"]].every(function (className) {
return !jq.hasClass(className);
})) {
__setAnchorOffset(getTextActualStartOffset(sel.getRangeAt(0).startContainer) + sel.anchorOffset);
}
};
var handleClick = function handleClick(e) {
if ($(e.target).hasClass(style["text-holder-cancel"])) {
var box = e.target.parentNode.parentNode;
$(e.target.parentNode).remove();
__setHtml($(box).html());
}
updateAnchorOffset(e);
};
var handleKeyUp = function handleKeyUp(e) {
updateAnchorOffset(e);
};
return /*#__PURE__*/React__default.createElement(ContentEditable, {
ref: boxRef,
html: __html,
disabled: false,
onChange: handleChange,
onClick: handleClick,
onKeyUp: handleKeyUp
});
}
TextHolderInsertable.propTypes = {
ref: PropTypes.object,
html: PropTypes.string,
onChange: PropTypes.func,
onTextChange: PropTypes.func,
initialAnchorOffset: PropTypes.number,
onAnchorOffsetChange: PropTypes.func
};
exports.TextHolder = TextHolder;
exports.default = TextHolderInsertable;
//# sourceMappingURL=index.js.map