/** * 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. * */ import type {DOMConversionMap, DOMConversionOutput, NodeKey} from 'lexical'; import type {JSX} from 'react'; import { $isHorizontalRuleNode, HorizontalRuleNode as BaseHorizontalRuleNode, INSERT_HORIZONTAL_RULE_COMMAND, type SerializedHorizontalRuleNode, } from '@lexical/extension'; import {useLexicalComposerContext} from '@lexical/react/LexicalComposerContext'; import {useLexicalNodeSelection} from '@lexical/react/useLexicalNodeSelection'; import { addClassNamesToElement, mergeRegister, removeClassNamesFromElement, } from '@lexical/utils'; import { $applyNodeReplacement, CLICK_COMMAND, COMMAND_PRIORITY_LOW, } from 'lexical'; import * as React from 'react'; import {useEffect} from 'react'; export { $isHorizontalRuleNode, INSERT_HORIZONTAL_RULE_COMMAND, type SerializedHorizontalRuleNode, }; function HorizontalRuleComponent({nodeKey}: {nodeKey: NodeKey}) { const [editor] = useLexicalComposerContext(); const [isSelected, setSelected, clearSelection] = useLexicalNodeSelection(nodeKey); useEffect(() => { return mergeRegister( editor.registerCommand( CLICK_COMMAND, (event: MouseEvent) => { const hrElem = editor.getElementByKey(nodeKey); if (event.target === hrElem) { if (!event.shiftKey) { clearSelection(); } setSelected(!isSelected); return true; } return false; }, COMMAND_PRIORITY_LOW, ), ); }, [clearSelection, editor, isSelected, nodeKey, setSelected]); useEffect(() => { const hrElem = editor.getElementByKey(nodeKey); const isSelectedClassName = editor._config.theme.hrSelected ?? 'selected'; if (hrElem !== null) { if (isSelected) { addClassNamesToElement(hrElem, isSelectedClassName); } else { removeClassNamesFromElement(hrElem, isSelectedClassName); } } }, [editor, isSelected, nodeKey]); return null; } /** * @deprecated A pure Lexical implementation is available in `@lexical/extension` as HorizontalRuleExtension */ export class HorizontalRuleNode extends BaseHorizontalRuleNode { static getType(): string { return 'horizontalrule'; } static clone(node: HorizontalRuleNode): HorizontalRuleNode { return new HorizontalRuleNode(node.__key); } static importJSON( serializedNode: SerializedHorizontalRuleNode, ): HorizontalRuleNode { return $createHorizontalRuleNode().updateFromJSON(serializedNode); } static importDOM(): DOMConversionMap | null { return { hr: () => ({ conversion: $convertHorizontalRuleElement, priority: 0, }), }; } decorate(): JSX.Element { return ; } } function $convertHorizontalRuleElement(): DOMConversionOutput { return {node: $createHorizontalRuleNode()}; } /** * @deprecated A pure Lexical implementation is available in `@lexical/extension` as HorizontalRuleExtension */ export function $createHorizontalRuleNode(): HorizontalRuleNode { return $applyNodeReplacement(new HorizontalRuleNode()); }