@yuntijs/ui
Version:
☁️ Yunti UI - an open-source UI component library for building Cloud Native web apps
133 lines (131 loc) • 5.74 kB
JavaScript
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
/* eslint-disable unicorn/no-useless-undefined */
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
import { useLexicalNodeSelection } from '@lexical/react/useLexicalNodeSelection';
import { mergeRegister } from '@lexical/utils';
import { $getNodeByKey, $getSelection, $isDecoratorNode, $isNodeSelection, COMMAND_PRIORITY_LOW, KEY_BACKSPACE_COMMAND, KEY_DELETE_COMMAND } from 'lexical';
import { useCallback, useEffect, useRef, useState } from 'react';
import { LENGTH_LIMIT, TRIGGERS, VALID_CHARS, VALID_JOINS } from "./constants";
export var useSelectOrDelete = function useSelectOrDelete(nodeKey, command) {
var ref = useRef(null);
var _useLexicalComposerCo = useLexicalComposerContext(),
_useLexicalComposerCo2 = _slicedToArray(_useLexicalComposerCo, 1),
editor = _useLexicalComposerCo2[0];
var _useLexicalNodeSelect = useLexicalNodeSelection(nodeKey),
_useLexicalNodeSelect2 = _slicedToArray(_useLexicalNodeSelect, 3),
isSelected = _useLexicalNodeSelect2[0],
setSelected = _useLexicalNodeSelect2[1],
clearSelection = _useLexicalNodeSelect2[2];
var handleDelete = useCallback(function (event) {
var selection = $getSelection();
var nodes = selection === null || selection === void 0 ? void 0 : selection.getNodes();
if (!isSelected && (nodes === null || nodes === void 0 ? void 0 : nodes.length) === 1) {
editor.dispatchCommand(command, undefined);
}
if (isSelected && $isNodeSelection(selection)) {
event.preventDefault();
var node = $getNodeByKey(nodeKey);
if ($isDecoratorNode(node)) {
if (command) {
editor.dispatchCommand(command, undefined);
}
node.remove();
return true;
}
}
return false;
}, [isSelected, nodeKey, command, editor]);
var handleSelect = useCallback(function (e) {
e.stopPropagation();
clearSelection();
setSelected(true);
}, [setSelected, clearSelection]);
useEffect(function () {
var ele = ref.current;
if (ele) ele.addEventListener('click', handleSelect);
return function () {
if (ele) ele.removeEventListener('click', handleSelect);
};
}, [handleSelect]);
useEffect(function () {
return mergeRegister(editor.registerCommand(KEY_DELETE_COMMAND, handleDelete, COMMAND_PRIORITY_LOW), editor.registerCommand(KEY_BACKSPACE_COMMAND, handleDelete, COMMAND_PRIORITY_LOW));
}, [editor, clearSelection, handleDelete]);
return [ref, isSelected];
};
export var useTrigger = function useTrigger() {
var triggerRef = useRef(null);
var _useState = useState(false),
_useState2 = _slicedToArray(_useState, 2),
open = _useState2[0],
setOpen = _useState2[1];
var handleOpen = useCallback(function (e) {
e.stopPropagation();
setOpen(function (v) {
return !v;
});
}, []);
useEffect(function () {
var trigger = triggerRef.current;
if (trigger) trigger.addEventListener('click', handleOpen);
return function () {
if (trigger) trigger.removeEventListener('click', handleOpen);
};
}, [handleOpen]);
return [triggerRef, open, setOpen];
};
// Regex used to trigger the mention menu.
function createMentionsRegex(triggers, preTriggerChars, punctuation, allowSpaces) {
return new RegExp((preTriggerChars ? "(^|\\s|".concat(preTriggerChars, ")(") : '(^|\\s)(') + TRIGGERS(triggers) + '((?:' + VALID_CHARS(triggers, punctuation) + (allowSpaces ? VALID_JOINS(punctuation) : '') + '){0,' + LENGTH_LIMIT + '})' + ')$');
}
export function checkForMentions(text, triggers, preTriggerChars, punctuation, allowSpaces) {
var match = createMentionsRegex(triggers, preTriggerChars, punctuation, allowSpaces).exec(text);
if (match !== null) {
// The strategy ignores leading whitespace, but we need to know its
// length to add it to the leadOffset
var maybeLeadingWhitespace = match[1];
var matchingStringWithTrigger = match[2];
var matchingString = match[3];
if (matchingStringWithTrigger.length > 0) {
return {
leadOffset: match.index + maybeLeadingWhitespace.length,
matchingString: matchingString,
replaceableString: matchingStringWithTrigger
};
}
}
return null;
}
export var useCheckForMentionMatch = function useCheckForMentionMatch(triggers, _ref) {
var punctuation = _ref.punctuation,
preTriggerChars = _ref.preTriggerChars,
allowSpaces = _ref.allowSpaces;
var _useState3 = useState(null),
_useState4 = _slicedToArray(_useState3, 2),
trigger = _useState4[0],
setTrigger = _useState4[1];
var checkForMentionMatch = useCallback(function (text) {
// Don't show the menu if the next character is a word character
// const selectionInfo = $getSelectionInfo(triggers, punctuation);
// if (selectionInfo?.isTextNode && selectionInfo.wordCharAfterCursor) {
// return null;
// }
var queryMatch = checkForMentions(text, triggers, preTriggerChars, punctuation, allowSpaces);
if (queryMatch) {
var replaceableString = queryMatch.replaceableString,
matchingString = queryMatch.matchingString;
var index = replaceableString.lastIndexOf(matchingString);
var _trigger = index === -1 ? replaceableString : replaceableString.slice(0, Math.max(0, index)) + replaceableString.slice(Math.max(0, index + matchingString.length));
setTrigger(_trigger || null);
if (queryMatch.replaceableString) {
return queryMatch;
}
} else {
setTrigger(null);
}
return null;
}, [preTriggerChars, allowSpaces, punctuation, triggers]);
return {
trigger: trigger,
checkForMentionMatch: checkForMentionMatch
};
};