@jannie-shao/components-antd4
Version:
143 lines • 5.54 kB
JavaScript
import "antd/es/space/style";
import _Space from "antd/es/space";
import React, { useRef, useEffect } from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { throttle } from 'lodash';
import DropdownMenu from "../dropdown-menu";
import { rootPrefix } from "../style/config";
import { getValue, formatPlaceholder, formatVal, getNextLength, insertRange, pasteRange } from "./util";
var prefix = rootPrefix + "-layedit";
var Layedit = function Layedit(_ref) {
var _classnames;
var _ref$className = _ref.className,
className = _ref$className === void 0 ? '' : _ref$className,
value = _ref.value,
onChange = _ref.onChange,
disabled = _ref.disabled,
placeholder = _ref.placeholder,
rows = _ref.rows,
barList = _ref.barList,
showCount = _ref.showCount,
maxLength = _ref.maxLength;
var compIframe = useRef();
// 解决回调函数里无法监听 value 变化
var valRef = useRef(value);
var handleChange = throttle(function () {
if (!compIframe.current) return;
var iframeWin = compIframe.current.contentWindow;
var valNew = getValue(iframeWin.document.body);
if (valNew !== valRef.current) {
onChange(valNew);
}
}, 200);
var handleInsertEle = function handleInsertEle(key) {
if (disabled || !compIframe.current) return;
var iframeWin = compIframe.current.contentWindow;
iframeWin.document.body.focus();
var val = "${" + key + "}";
// 剩余长度不足
var len = getNextLength(valRef.current, maxLength);
if (len !== -1 && len < val.length) return;
insertRange(formatPlaceholder(val), iframeWin);
handleChange();
};
useEffect(function () {
valRef.current = value;
if (!compIframe.current) return;
var iframeWin = compIframe.current.contentWindow;
if (value === '') {
iframeWin.document.body.innerHTML = '';
return;
}
var text = getValue(iframeWin.document.body);
if (text !== value) {
iframeWin.document.body.innerHTML = formatVal(value);
}
}, [value]);
useEffect(function () {
if (!compIframe.current) return;
var iframeWin = compIframe.current.contentWindow;
iframeWin.document.body.contentEditable = Boolean(!disabled);
}, [disabled]);
useEffect(function () {
if (!compIframe.current) return;
var iframeWin = compIframe.current.contentWindow;
// 写入样式
var style = iframeWin.document.createElement('style');
style.innerHTML = "\n html, body { margin: 0; padding: 0; }\n body { padding: 6px 11px; font-size: 12px; color: rgba(0, 0, 0, 0.25); }\n body[contenteditable=true] { color: rgba(0, 0, 0, 0.85); -webkit-user-modify: read-write-plaintext-only; }\n body:empty::before { content:'" + placeholder + "'; color: #ccc; font-size:12px; }\n body label { color: #3543ff; }";
iframeWin.document.head.append(style);
iframeWin.document.body.addEventListener('keydown', function (e) {
// 忽略组合键
if (e.ctrlKey || e.metaKey) return;
var valueNow = getValue(iframeWin.document.body);
// 长度限制
if (maxLength && e.keyCode !== 8 && e.key.length === 1 && valueNow.length >= Number(maxLength)) {
e.preventDefault();
}
});
// 粘贴纯文本
iframeWin.document.body.addEventListener('paste', function (e) {
e.preventDefault();
var valueNow = getValue(iframeWin.document.body);
var len = getNextLength(valueNow, maxLength);
if (len === 0) return;
pasteRange(e, len, iframeWin);
handleChange();
});
// 监听输入内容
iframeWin.document.body.addEventListener('input', function () {
return handleChange();
});
}, []);
return /*#__PURE__*/React.createElement("div", {
className: classnames(prefix, className, (_classnames = {}, _classnames[prefix + "-disabled"] = disabled, _classnames))
}, /*#__PURE__*/React.createElement("div", {
className: prefix + "-bar"
}, /*#__PURE__*/React.createElement(_Space, null, barList.map(function (b) {
return /*#__PURE__*/React.createElement("div", {
key: b.name,
className: prefix + "-bar-item"
}, b.type === 'placeholder' && /*#__PURE__*/React.createElement(DropdownMenu, {
getPopupContainer: function getPopupContainer(n) {
return n.parentNode;
},
trigger: "click",
menuItems: b.options,
onClick: handleInsertEle
}, /*#__PURE__*/React.createElement("span", null, b.name)));
}))), /*#__PURE__*/React.createElement("div", {
className: prefix + "-value"
}, /*#__PURE__*/React.createElement("iframe", {
ref: compIframe,
title: "layedit",
style: {
height: rows * 32
}
})), showCount && /*#__PURE__*/React.createElement("div", {
className: prefix + "-show-count"
}, value.length > maxLength && /*#__PURE__*/React.createElement("span", {
className: prefix + "-show-count-warning"
}, value.length), value.length <= maxLength && value.length, "/", maxLength));
};
Layedit.propTypes = {
value: PropTypes.string,
onChange: PropTypes.func,
disabled: PropTypes.bool,
placeholder: PropTypes.string,
rows: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
barList: PropTypes.array,
showCount: PropTypes.bool,
maxLength: PropTypes.oneOfType([PropTypes.number, PropTypes.string])
};
Layedit.defaultProps = {
value: '',
onChange: function onChange() {},
disabled: false,
placeholder: '',
rows: 1,
barList: [],
showCount: false,
maxLength: 0
};
export default Layedit;