import { useCallback, useEffect, useState } from "react"; import { Button } from "@/components/ui/button"; import { useTranslation } from "@/lib/i18n/client"; import { $convertFromMarkdownString, $convertToMarkdownString, TRANSFORMERS, } from "@lexical/markdown"; import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext"; import { mergeRegister } from "@lexical/utils"; import { $createParagraphNode, $createTextNode, $getRoot, $getSelection, $isRangeSelection, FORMAT_TEXT_COMMAND, LexicalCommand, SELECTION_CHANGE_COMMAND, TextFormatType, } from "lexical"; import { Bold, Code, Highlighter, Italic, LucideIcon, Save, Strikethrough, } from "lucide-react"; import { ActionButton } from "../../action-button"; import InfoTooltip from "../../info-tooltip"; import { Label } from "../../label"; import { Switch } from "../../switch"; const LowPriority = 1; function MarkdownToolTip() { const { t } = useTranslation(); return (
{t("editor.text_toolbar.markdown_shortcuts.label")}
{t("editor.text_toolbar.markdown_shortcuts.heading.label")} {t("editor.text_toolbar.markdown_shortcuts.heading.example")}
{t("editor.text_toolbar.markdown_shortcuts.bold.label")} {t("editor.text_toolbar.markdown_shortcuts.bold.example")}
{t("editor.text_toolbar.markdown_shortcuts.italic.label")} {t("editor.text_toolbar.markdown_shortcuts.italic.example")}
{t("editor.text_toolbar.markdown_shortcuts.blockquote.label")} {t("editor.text_toolbar.markdown_shortcuts.blockquote.example")}
{t("editor.text_toolbar.markdown_shortcuts.ordered_list.label")} {t("editor.text_toolbar.markdown_shortcuts.ordered_list.example")}
{t("editor.text_toolbar.markdown_shortcuts.unordered_list.label")} {t( "editor.text_toolbar.markdown_shortcuts.unordered_list.example", )}
{t("editor.text_toolbar.markdown_shortcuts.inline_code.label")} {t("editor.text_toolbar.markdown_shortcuts.inline_code.example")}
{t("editor.text_toolbar.markdown_shortcuts.block_code.label")} {t("editor.text_toolbar.markdown_shortcuts.block_code.example")}
); } export default function ToolbarPlugin({ isRawMarkdownMode = false, setIsRawMarkdownMode, onSave, isSaving, }: { isRawMarkdownMode: boolean; setIsRawMarkdownMode: (value: boolean) => void; onSave?: () => void; isSaving: boolean; }) { const { t } = useTranslation(); const [editor] = useLexicalComposerContext(); const [editorToolbarState, setEditorToolbarState] = useState<{ isBold: boolean; isItalic: boolean; isStrikethrough: boolean; isHighlight: boolean; isCode: boolean; }>({ isBold: false, isItalic: false, isStrikethrough: false, isHighlight: false, isCode: false, }); const $updateToolbar = useCallback(() => { const selection = $getSelection(); if ($isRangeSelection(selection)) { setEditorToolbarState({ isBold: selection.hasFormat("bold"), isItalic: selection.hasFormat("italic"), isStrikethrough: selection.hasFormat("strikethrough"), isHighlight: selection.hasFormat("highlight"), isCode: selection.hasFormat("code"), }); } }, []); useEffect(() => { return mergeRegister( editor.registerUpdateListener(({ editorState }) => { editorState.read(() => { $updateToolbar(); }); }), editor.registerCommand( SELECTION_CHANGE_COMMAND, (_payload, _newEditor) => { $updateToolbar(); return false; }, LowPriority, ), ); }, [editor, $updateToolbar]); const formatButtons: { command: LexicalCommand; format: TextFormatType; isActive?: boolean; icon: LucideIcon; label: string; }[] = [ { command: FORMAT_TEXT_COMMAND, format: "bold", icon: Bold, isActive: editorToolbarState.isBold, label: t("editor.text_toolbar.bold"), }, { command: FORMAT_TEXT_COMMAND, format: "italic", icon: Italic, isActive: editorToolbarState.isItalic, label: t("editor.text_toolbar.italic"), }, { command: FORMAT_TEXT_COMMAND, format: "strikethrough", icon: Strikethrough, isActive: editorToolbarState.isStrikethrough, label: t("editor.text_toolbar.strikethrough"), }, { command: FORMAT_TEXT_COMMAND, format: "code", icon: Code, isActive: editorToolbarState.isCode, label: t("editor.text_toolbar.code"), }, { command: FORMAT_TEXT_COMMAND, format: "highlight", icon: Highlighter, isActive: editorToolbarState.isHighlight, label: t("editor.text_toolbar.highlight"), }, ]; const handleRawMarkdownToggle = useCallback(() => { editor.update(() => { console.log(isRawMarkdownMode); const root = $getRoot(); const firstChild = root.getFirstChild(); if (isRawMarkdownMode) { if (firstChild) { $convertFromMarkdownString(firstChild.getTextContent(), TRANSFORMERS); } setIsRawMarkdownMode(false); } else { const markdown = $convertToMarkdownString(TRANSFORMERS); const pNode = $createParagraphNode(); pNode.append($createTextNode(markdown)); root.clear().append(pNode); setIsRawMarkdownMode(true); } }); }, [editor, isRawMarkdownMode]); return (
{formatButtons.map( ({ command, format, icon: Icon, isActive, label }) => ( ), )}
{onSave && ( { onSave?.(); }} > Save )}
); }