103 lines
3.1 KiB
JavaScript
103 lines
3.1 KiB
JavaScript
/**
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var LexicalComposerContext = require('@lexical/react/LexicalComposerContext');
|
|
var lexical = require('lexical');
|
|
var react = require('react');
|
|
|
|
/**
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
*/
|
|
|
|
|
|
/**
|
|
* A helper function to determine if a specific node is selected in a Lexical editor.
|
|
*
|
|
* @param {LexicalEditor} editor - The LexicalEditor instance.
|
|
* @param {NodeKey} key - The key of the node to check.
|
|
* @returns {boolean} Whether the node is selected.
|
|
*/
|
|
|
|
function isNodeSelected(editor, key) {
|
|
return editor.getEditorState().read(() => {
|
|
const node = lexical.$getNodeByKey(key);
|
|
if (node === null) {
|
|
return false; // Node doesn't exist, so it's not selected.
|
|
}
|
|
return node.isSelected(); // Check if the node is selected.
|
|
});
|
|
}
|
|
|
|
/**
|
|
* A custom hook to manage the selection state of a specific node in a Lexical editor.
|
|
*
|
|
* This hook provides utilities to:
|
|
* - Check if a node is selected.
|
|
* - Update its selection state.
|
|
* - Clear the selection.
|
|
*
|
|
* @param {NodeKey} key - The key of the node to track selection for.
|
|
* @returns {[boolean, (selected: boolean) => void, () => void]} A tuple containing:
|
|
* - `isSelected` (boolean): Whether the node is currently selected.
|
|
* - `setSelected` (function): A function to set the selection state of the node.
|
|
* - `clearSelected` (function): A function to clear the selection of the node.
|
|
*
|
|
*/
|
|
|
|
function useLexicalNodeSelection(key) {
|
|
const [editor] = LexicalComposerContext.useLexicalComposerContext();
|
|
|
|
// State to track whether the node is currently selected.
|
|
const [isSelected, setIsSelected] = react.useState(() => isNodeSelected(editor, key));
|
|
react.useEffect(() => {
|
|
let isMounted = true;
|
|
const unregister = editor.registerUpdateListener(() => {
|
|
if (isMounted) {
|
|
setIsSelected(isNodeSelected(editor, key));
|
|
}
|
|
});
|
|
return () => {
|
|
isMounted = false; // Prevent updates after component unmount.
|
|
unregister();
|
|
};
|
|
}, [editor, key]);
|
|
const setSelected = react.useCallback(selected => {
|
|
editor.update(() => {
|
|
let selection = lexical.$getSelection();
|
|
if (!lexical.$isNodeSelection(selection)) {
|
|
selection = lexical.$createNodeSelection();
|
|
lexical.$setSelection(selection);
|
|
}
|
|
if (lexical.$isNodeSelection(selection)) {
|
|
if (selected) {
|
|
selection.add(key);
|
|
} else {
|
|
selection.delete(key);
|
|
}
|
|
}
|
|
});
|
|
}, [editor, key]);
|
|
const clearSelected = react.useCallback(() => {
|
|
editor.update(() => {
|
|
const selection = lexical.$getSelection();
|
|
if (lexical.$isNodeSelection(selection)) {
|
|
selection.clear();
|
|
}
|
|
});
|
|
}, [editor]);
|
|
return [isSelected, setSelected, clearSelected];
|
|
}
|
|
|
|
exports.useLexicalNodeSelection = useLexicalNodeSelection;
|