kedao
Version:
Rich Text Editor Based On Draft.js
120 lines (119 loc) • 6.63 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import { classNameParser } from '../../utils/style';
import React, { useState, useEffect, useRef } from 'react';
import { insertText, toggleSelectionLink, getSelectionEntityData, getSelectionBlockType, getSelectionText } from '../../utils';
import Switch from '../Switch';
import Button from '../Button';
import ControlGroup from '../ControlGroup';
import styles from "./style.module.css";
import { useAtom } from 'jotai';
import { linkEditorActiveAtom } from '../../states';
import { useResetState } from '../../hooks/use-reset-state';
import loadable from '@loadable/component';
import useLanguage from '../../hooks/use-language';
import LinkIcon from 'tabler-icons-react/dist/icons/link';
import LinkOffIcon from 'tabler-icons-react/dist/icons/link-off';
import XIcon from 'tabler-icons-react/dist/icons/x';
import { tablerIconProps } from '../../constants';
const DropDown = loadable(() => __awaiter(void 0, void 0, void 0, function* () { return yield import('../DropDown'); }));
const cls = classNameParser(styles);
const LinkEditor = ({ defaultLinkTarget = '', editorState, getContainerNode, allowInsertLinkText, disabled, onChange, onRequestFocus }) => {
const [text, setText, resetText] = useResetState('');
const [href, setHref, resetHref] = useResetState('');
const [target, setTarget, resetTarget] = useResetState(defaultLinkTarget || '');
const [textSelected, setTextSelected] = useState(false);
const [isDropdownActive, setDropdownActive] = useAtom(linkEditorActiveAtom);
useEffect(() => {
const { href, target } = getSelectionEntityData(editorState, 'LINK');
const textSelected = !editorState.getSelection().isCollapsed() &&
getSelectionBlockType(editorState) !== 'atomic';
let selectedText = '';
if (textSelected) {
selectedText = getSelectionText(editorState);
}
setTextSelected(textSelected);
setText(selectedText);
setHref(href || '');
setTarget(typeof target === 'undefined' ? defaultLinkTarget || '' : target || '');
}, [editorState, defaultLinkTarget]);
const dropDownInstance = useRef(null);
const handeKeyDown = (e) => {
if (e.keyCode === 13) {
handleConfirm();
e.preventDefault();
return false;
}
return true;
};
const handleTnputText = (e) => {
setText(e.currentTarget.value);
};
const handleInputLink = (e) => {
setHref(e.currentTarget.value);
};
const toggleTarget = () => {
setTarget((target) => (target === '_blank' ? '' : '_blank'));
};
const handleCancel = () => {
setDropdownActive(false);
};
const handleUnlink = () => {
setDropdownActive(false);
onChange(toggleSelectionLink(editorState, false));
};
const handleConfirm = () => {
setDropdownActive(false);
onRequestFocus();
if (textSelected) {
if (href) {
onChange(toggleSelectionLink(editorState, href, target));
}
else {
onChange(toggleSelectionLink(editorState, false));
}
}
else {
onChange(insertText(editorState, text || href, null, {
type: 'LINK',
data: { href, target }
}));
}
return true;
};
const caption = React.createElement(LinkIcon, Object.assign({}, tablerIconProps));
const language = useLanguage();
return (React.createElement(ControlGroup, null,
React.createElement(DropDown, { key: 0, caption: caption, isActive: isDropdownActive, onActiveChage: (v) => {
setDropdownActive(v);
if (!v) {
resetHref();
resetTarget();
resetText();
}
}, title: language.controls.link, autoHide: true, getContainerNode: getContainerNode, showArrow: false, ref: dropDownInstance, className: cls('link-editor-dropdown'), disabled: disabled },
React.createElement("div", { className: cls('kedao-link-editor') },
allowInsertLinkText
? (React.createElement("div", { className: cls('input-group') },
React.createElement("input", { type: "text", value: text, spellCheck: false, disabled: textSelected, placeholder: language.linkEditor.textInputPlaceHolder, onKeyDown: handeKeyDown, onChange: handleTnputText })))
: null,
React.createElement("div", { className: cls('input-group') },
React.createElement("input", { type: "text", value: href, spellCheck: false, placeholder: language.linkEditor.linkInputPlaceHolder, onKeyDown: handeKeyDown, onChange: handleInputLink })),
React.createElement(Switch, { active: target === '_blank', onClick: toggleTarget, label: language.linkEditor.openInNewWindow }),
React.createElement("div", { className: cls('buttons') },
React.createElement("a", { onClick: handleUnlink, role: "presentation", className: cls('primary button-remove-link pull-left') },
React.createElement("span", null, language.linkEditor.removeLink),
React.createElement(XIcon, Object.assign({}, tablerIconProps))),
React.createElement("button", { type: "button", onClick: handleConfirm, className: cls('primary pull-right') }, language.base.confirm),
React.createElement("button", { type: "button", onClick: handleCancel, className: cls('default pull-right') }, language.base.cancel)))),
React.createElement(Button, { key: 1, type: "button", "data-title": language.controls.unlink, onClick: handleUnlink, disabled: disabled || !textSelected || !href },
React.createElement(LinkOffIcon, Object.assign({}, tablerIconProps)))));
};
export default LinkEditor;