UNPKG

@yuntijs/ui

Version:

☁️ Yunti UI - an open-source UI component library for building Cloud Native web apps

133 lines (131 loc) 5.74 kB
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 }; };