UNPKG

@yuntijs/ui

Version:

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

180 lines 7.72 kB
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray"; import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'; import { LexicalTypeaheadMenuPlugin } from '@lexical/react/LexicalTypeaheadMenuPlugin'; import { ConfigProvider, Tree } from 'antd'; import { COMMAND_PRIORITY_NORMAL } from 'lexical'; import { flatMap } from 'lodash-es'; import React, { memo, useCallback, useMemo, useRef, useState } from 'react'; import ReactDOM from 'react-dom'; import { DEFAULT_PUNCTUATION, PRE_TRIGGER_CHARS } from "../../constants"; import { useCheckForMentionMatch } from "../../hooks"; import { CLEAR_HIDE_MENU_TIMEOUT } from "../mention-node"; import { useOptions } from "./hooks"; import { MentionMenu } from "./menu"; import { MentionMenuItem } from "./menu-item"; import { useStyles } from "./style"; import { jsx as _jsx } from "react/jsx-runtime"; export var MentionPickerPlugin = /*#__PURE__*/memo(function (_ref) { var overlayClassName = _ref.overlayClassName, triggers = _ref.triggers, _ref$options = _ref.options, allOptions = _ref$options === void 0 ? [] : _ref$options, _ref$allowSpaces = _ref.allowSpaces, allowSpaces = _ref$allowSpaces === void 0 ? true : _ref$allowSpaces, _ref$punctuation = _ref.punctuation, punctuation = _ref$punctuation === void 0 ? DEFAULT_PUNCTUATION : _ref$punctuation, _ref$preTriggerChars = _ref.preTriggerChars, preTriggerChars = _ref$preTriggerChars === void 0 ? PRE_TRIGGER_CHARS : _ref$preTriggerChars, onSelect = _ref.onSelect, onOpen = _ref.onOpen, parent = _ref.parent; var _useStyles = useStyles({}), cx = _useStyles.cx, styles = _useStyles.styles; var _useLexicalComposerCo = useLexicalComposerContext(), _useLexicalComposerCo2 = _slicedToArray(_useLexicalComposerCo, 1), editor = _useLexicalComposerCo2[0]; var _useCheckForMentionMa = useCheckForMentionMatch(triggers, { punctuation: punctuation, preTriggerChars: preTriggerChars, allowSpaces: allowSpaces }), trigger = _useCheckForMentionMa.trigger, checkForMentionMatch = _useCheckForMentionMa.checkForMentionMatch; var _useState = useState(null), _useState2 = _slicedToArray(_useState, 2), queryString = _useState2[0], setQueryString = _useState2[1]; var _useOptions = useOptions(allOptions, queryString, trigger), options = _useOptions.options; var flatOptions = useMemo(function () { var _flattenTree = function _flattenTree(nodes) { return flatMap(nodes, function (node) { return [node].concat(_toConsumableArray(node.children ? _flattenTree(node.children) : [])); }); }; return _flattenTree(options); }, [options]); var onSelectOption = useCallback(function (selectedOption, nodeToRemove, closeMenu, matchingString) { onSelect === null || onSelect === void 0 || onSelect(selectedOption, trigger, queryString); editor.update(function () { if (nodeToRemove && selectedOption !== null && selectedOption !== void 0 && selectedOption.key) { nodeToRemove.remove(); } if (selectedOption !== null && selectedOption !== void 0 && selectedOption.onSelect) { selectedOption.onSelect(matchingString); } closeMenu(); }); }, [editor, onSelect, queryString, trigger]); var preSelectedIndex = useRef(0); var handleDisabledItem = useCallback(function (itemProps) { var selectedIndex = itemProps.selectedIndex, setHighlightedIndex = itemProps.setHighlightedIndex; if (selectedIndex !== null) { var _flatOptions$selected; if ((_flatOptions$selected = flatOptions[selectedIndex]) !== null && _flatOptions$selected !== void 0 && _flatOptions$selected.disabled) { var newIndex = selectedIndex; // 如果是最后一项,则回到第一项 if (selectedIndex === flatOptions.length - 1) { newIndex = flatOptions.length === 1 ? null : 0; // @ts-ignore setHighlightedIndex(newIndex); } else if (selectedIndex !== preSelectedIndex.current) { var _preSelectedIndex$cur; if (selectedIndex > ((_preSelectedIndex$cur = preSelectedIndex.current) !== null && _preSelectedIndex$cur !== void 0 ? _preSelectedIndex$cur : 0)) { newIndex++; } else { newIndex--; } setHighlightedIndex(newIndex); } } preSelectedIndex.current = selectedIndex; } }, [flatOptions]); var renderMenuTree = useCallback(function (itemProps) { var selectedIndex = itemProps.selectedIndex, selectOptionAndCleanUp = itemProps.selectOptionAndCleanUp; handleDisabledItem(itemProps); return /*#__PURE__*/_jsx(ConfigProvider, { theme: { components: { Tree: { indentSize: 16, lineHeight: 32, titleHeight: 32, paddingXS: 0, nodeHoverBg: 'transparent' } } }, children: /*#__PURE__*/_jsx(Tree, { blockNode: true, defaultExpandAll: true, onExpand: function onExpand(_keys, _ref2) { var nativeEvent = _ref2.nativeEvent; nativeEvent.stopPropagation(); // 阻止 menu-picker 隐藏 editor.dispatchCommand(CLEAR_HIDE_MENU_TIMEOUT, {}); }, onSelect: function onSelect(_keys, info) { selectOptionAndCleanUp(info.node); }, titleRender: function titleRender(option) { var _flatOptions; return /*#__PURE__*/_jsx(MentionMenuItem, { isSelected: ((_flatOptions = flatOptions[selectedIndex]) === null || _flatOptions === void 0 ? void 0 : _flatOptions.value) === option.value, option: option, queryString: queryString, showIcon: !option.isChild }); }, treeData: options }) }); }, [handleDisabledItem, options, editor, flatOptions, queryString]); var renderMenu = useCallback(function (anchorElementRef, itemProps, _matchingString) { var selectedIndex = itemProps.selectedIndex, selectOptionAndCleanUp = itemProps.selectOptionAndCleanUp, setHighlightedIndex = itemProps.setHighlightedIndex; handleDisabledItem(itemProps); if (anchorElementRef.current) { return /*#__PURE__*/ReactDOM.createPortal( /*#__PURE__*/_jsx("div", { className: cx(styles.menuOverlay, overlayClassName), role: "menu", children: options.some(function (o) { return (o.children || []).length > 0; }) ? renderMenuTree(itemProps) : /*#__PURE__*/_jsx(MentionMenu, { onClick: function onClick(index, option) { if (option.disabled) return; setHighlightedIndex(index); selectOptionAndCleanUp(option); }, onMouseEnter: function onMouseEnter(index, option) { if (option.disabled) return; setHighlightedIndex(index); }, options: options, queryString: queryString, selectedIndex: selectedIndex }) }), anchorElementRef.current); } return null; }, [cx, handleDisabledItem, options, overlayClassName, queryString, renderMenuTree, styles.menuOverlay]); return /*#__PURE__*/_jsx(LexicalTypeaheadMenuPlugin, { anchorClassName: styles.anchor // 优先级要高于 ShiftEnterKeyPlugin , commandPriority: COMMAND_PRIORITY_NORMAL, menuRenderFn: renderMenu, onOpen: onOpen, onQueryChange: setQueryString, onSelectOption: onSelectOption, options: flatOptions, parent: parent, triggerFn: checkForMentionMatch }); });