feat(web): editor variable support key command
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import { useEffect, useState, type FC } from 'react';
|
import { useEffect, useState, type FC } from 'react';
|
||||||
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
||||||
import { $getSelection, $isRangeSelection, $isTextNode } from 'lexical';
|
import { $getSelection, $isRangeSelection, $isTextNode, COMMAND_PRIORITY_HIGH, KEY_ENTER_COMMAND, KEY_ARROW_DOWN_COMMAND, KEY_ARROW_UP_COMMAND, KEY_ESCAPE_COMMAND } from 'lexical';
|
||||||
|
|
||||||
import { INSERT_VARIABLE_COMMAND } from '../commands';
|
import { INSERT_VARIABLE_COMMAND } from '../commands';
|
||||||
import type { NodeProperties } from '../../../types'
|
import type { NodeProperties } from '../../../types'
|
||||||
@@ -45,6 +45,9 @@ const AutocompletePlugin: FC<{ options: Suggestion[], enableJinja2?: boolean }>
|
|||||||
(textBeforeCursor === '/' && anchorOffset === 1);
|
(textBeforeCursor === '/' && anchorOffset === 1);
|
||||||
|
|
||||||
setShowSuggestions(shouldShow);
|
setShowSuggestions(shouldShow);
|
||||||
|
if (!shouldShow) {
|
||||||
|
setSelectedIndex(0);
|
||||||
|
}
|
||||||
|
|
||||||
if (shouldShow) {
|
if (shouldShow) {
|
||||||
const domSelection = window.getSelection();
|
const domSelection = window.getSelection();
|
||||||
@@ -113,9 +116,6 @@ const AutocompletePlugin: FC<{ options: Suggestion[], enableJinja2?: boolean }>
|
|||||||
setShowSuggestions(false);
|
setShowSuggestions(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!showSuggestions) return null;
|
|
||||||
|
|
||||||
// Group options by node id
|
|
||||||
const groupedSuggestions = options.reduce((groups: Record<string, any[]>, suggestion) => {
|
const groupedSuggestions = options.reduce((groups: Record<string, any[]>, suggestion) => {
|
||||||
const { nodeData } = suggestion
|
const { nodeData } = suggestion
|
||||||
const nodeId = nodeData.id as string;
|
const nodeId = nodeData.id as string;
|
||||||
@@ -126,6 +126,93 @@ const AutocompletePlugin: FC<{ options: Suggestion[], enableJinja2?: boolean }>
|
|||||||
return groups;
|
return groups;
|
||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!showSuggestions) return;
|
||||||
|
|
||||||
|
const allOptions = Object.values(groupedSuggestions).flat();
|
||||||
|
|
||||||
|
return editor.registerCommand(
|
||||||
|
KEY_ENTER_COMMAND,
|
||||||
|
(event) => {
|
||||||
|
if (showSuggestions && allOptions.length > 0) {
|
||||||
|
const selectedOption = allOptions[selectedIndex];
|
||||||
|
if (selectedOption && !selectedOption.disabled) {
|
||||||
|
event?.preventDefault();
|
||||||
|
insertMention(selectedOption);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
COMMAND_PRIORITY_HIGH
|
||||||
|
);
|
||||||
|
}, [showSuggestions, selectedIndex, groupedSuggestions, insertMention, editor]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!showSuggestions) return;
|
||||||
|
|
||||||
|
const allOptions = Object.values(groupedSuggestions).flat();
|
||||||
|
|
||||||
|
const unregisterArrowDown = editor.registerCommand(
|
||||||
|
KEY_ARROW_DOWN_COMMAND,
|
||||||
|
(event) => {
|
||||||
|
if (showSuggestions && allOptions.length > 0) {
|
||||||
|
event?.preventDefault();
|
||||||
|
setSelectedIndex(prev => {
|
||||||
|
let nextIndex = prev + 1;
|
||||||
|
while (nextIndex < allOptions.length && allOptions[nextIndex].disabled) {
|
||||||
|
nextIndex++;
|
||||||
|
}
|
||||||
|
return nextIndex >= allOptions.length ? prev : nextIndex;
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
COMMAND_PRIORITY_HIGH
|
||||||
|
);
|
||||||
|
|
||||||
|
const unregisterArrowUp = editor.registerCommand(
|
||||||
|
KEY_ARROW_UP_COMMAND,
|
||||||
|
(event) => {
|
||||||
|
if (showSuggestions && allOptions.length > 0) {
|
||||||
|
event?.preventDefault();
|
||||||
|
setSelectedIndex(prev => {
|
||||||
|
let prevIndex = prev - 1;
|
||||||
|
while (prevIndex >= 0 && allOptions[prevIndex].disabled) {
|
||||||
|
prevIndex--;
|
||||||
|
}
|
||||||
|
return prevIndex < 0 ? prev : prevIndex;
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
COMMAND_PRIORITY_HIGH
|
||||||
|
);
|
||||||
|
|
||||||
|
const unregisterEscape = editor.registerCommand(
|
||||||
|
KEY_ESCAPE_COMMAND,
|
||||||
|
(event) => {
|
||||||
|
if (showSuggestions) {
|
||||||
|
event?.preventDefault();
|
||||||
|
setShowSuggestions(false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
COMMAND_PRIORITY_HIGH
|
||||||
|
);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
unregisterArrowDown();
|
||||||
|
unregisterArrowUp();
|
||||||
|
unregisterEscape();
|
||||||
|
};
|
||||||
|
}, [showSuggestions, selectedIndex, groupedSuggestions, editor]);
|
||||||
|
|
||||||
|
if (!showSuggestions) return null;
|
||||||
|
|
||||||
if (Object.entries(groupedSuggestions).length === 0) {
|
if (Object.entries(groupedSuggestions).length === 0) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user