From 48b472163f9f496e33c96518216585d243dff86a Mon Sep 17 00:00:00 2001 From: Daniel Lautzenheiser Date: Thu, 14 Sep 2023 10:14:42 -0400 Subject: [PATCH] fix: delete code block on backspace when code block is empty (#877) --- .../nodes/code-block/CodeBlockElement.tsx | 13 +++++++++++-- .../components/nodes/code-block/CodeBlockFrame.tsx | 13 ++++++++++++- .../plugins/code-block/createCodeBlockPlugin.ts | 4 ++-- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/packages/core/src/widgets/markdown/plate/components/nodes/code-block/CodeBlockElement.tsx b/packages/core/src/widgets/markdown/plate/components/nodes/code-block/CodeBlockElement.tsx index 71740240..8f1d6a9b 100644 --- a/packages/core/src/widgets/markdown/plate/components/nodes/code-block/CodeBlockElement.tsx +++ b/packages/core/src/widgets/markdown/plate/components/nodes/code-block/CodeBlockElement.tsx @@ -1,4 +1,4 @@ -import { findNodePath, setNodes } from '@udecode/plate'; +import { findNodePath, focusEditor, removeNodes, setNodes } from '@udecode/plate'; import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import Frame from 'react-frame-component'; @@ -32,15 +32,24 @@ const CodeBlockElement: FC> [editor, element], ); + const handleDelete = useCallback(() => { + const path = findNodePath(editor, element); + path && removeNodes(editor, { at: path }); + focusEditor(editor); + }, [editor, element]); + const receiveMessage = useCallback( (event: MessageEvent) => { switch (event.data.message) { case `code_block_${id}_onChange`: handleChange(event.data.value); break; + case `code_block_${id}_delete`: + handleDelete(); + break; } }, - [handleChange, id], + [handleChange, handleDelete, id], ); useWindowEvent('message', receiveMessage); diff --git a/packages/core/src/widgets/markdown/plate/components/nodes/code-block/CodeBlockFrame.tsx b/packages/core/src/widgets/markdown/plate/components/nodes/code-block/CodeBlockFrame.tsx index 47c828ac..7ab4d21f 100644 --- a/packages/core/src/widgets/markdown/plate/components/nodes/code-block/CodeBlockFrame.tsx +++ b/packages/core/src/widgets/markdown/plate/components/nodes/code-block/CodeBlockFrame.tsx @@ -7,8 +7,9 @@ import React, { useCallback, useMemo } from 'react'; import { useFrame } from 'react-frame-component'; import languages from '@staticcms/code/data/languages'; +import { isEmpty } from '@staticcms/core/lib/util/string.util'; -import type { FC } from 'react'; +import type { FC, KeyboardEvent } from 'react'; export interface CodeBlockFrameProps { id: string; @@ -61,6 +62,15 @@ const CodeBlockFrame: FC = ({ id, lang, code, theme }) => { window?.parent.postMessage({ message: `code_block_${id}_onBlur` }); }, [id, window?.parent]); + const handleKeyDown = useCallback( + (event: KeyboardEvent) => { + if (event.key === 'Backspace' && isEmpty(code)) { + window?.parent.postMessage({ message: `code_block_${id}_delete` }); + } + }, + [code, id, window?.parent], + ); + return ( = ({ id, lang, code, theme }) => { onFocus={handleFocus} onBlur={handleBlur} onChange={handleChange} + onKeyDown={handleKeyDown} extensions={extensions} theme={theme} /> diff --git a/packages/core/src/widgets/markdown/plate/plugins/code-block/createCodeBlockPlugin.ts b/packages/core/src/widgets/markdown/plate/plugins/code-block/createCodeBlockPlugin.ts index b7a41aaf..fcb3a55f 100644 --- a/packages/core/src/widgets/markdown/plate/plugins/code-block/createCodeBlockPlugin.ts +++ b/packages/core/src/widgets/markdown/plate/plugins/code-block/createCodeBlockPlugin.ts @@ -3,12 +3,12 @@ import { ELEMENT_CODE_BLOCK, createPluginFactory } from '@udecode/plate'; import deserializeHtmlCodeBlock from './deserializeHtmlCodeBlock'; import type { MdValue } from '@staticcms/markdown'; -import type { HotkeyPlugin, PlateEditor } from '@udecode/plate'; +import type { CodeBlockPlugin, PlateEditor } from '@udecode/plate'; /** * Enables support for pre-formatted code blocks. */ -const createCodeBlockPlugin = createPluginFactory>({ +const createCodeBlockPlugin = createPluginFactory>({ key: ELEMENT_CODE_BLOCK, isElement: true, deserializeHtml: deserializeHtmlCodeBlock,