diff --git a/.changeset/code-block-node-selection.md b/.changeset/code-block-node-selection.md new file mode 100644 index 00000000..a9c100cf --- /dev/null +++ b/.changeset/code-block-node-selection.md @@ -0,0 +1,5 @@ +--- +'@meowdown/react': patch +--- + +Show the node selection outline on code blocks, including math and Mermaid previews, when they are selected with the block handle. diff --git a/packages/react/src/components/code-block-view.module.css b/packages/react/src/components/code-block-view.module.css index b32c14f4..c7d944d0 100644 --- a/packages/react/src/components/code-block-view.module.css +++ b/packages/react/src/components/code-block-view.module.css @@ -2,6 +2,18 @@ position: relative; } +/* The node view replaces prosemirror-view's `selectNode`, so the root never + * gets `ProseMirror-selectednode`. Mirror the core node selection style. */ +.Root[data-selected] { + border-radius: 0.6rem; + outline: 1px solid var(--meowdown-node-outline); + background: var(--meowdown-node-selection); +} + +:global(.prosekit-dragging) .Root[data-selected] { + background: transparent; +} + /* Preview-only state: the caret is outside a rendered block, so the source and * its toolbar give way to the rendered formula. The caret can never sit in * the hidden source (entering it flips the state back), so the missing box diff --git a/packages/react/src/components/code-block-view.module.d.css.ts b/packages/react/src/components/code-block-view.module.d.css.ts index 0a101365..f84e5ba1 100644 --- a/packages/react/src/components/code-block-view.module.d.css.ts +++ b/packages/react/src/components/code-block-view.module.d.css.ts @@ -1,5 +1,7 @@ // @ts-nocheck declare const styles = { + 'Root': '' as string, + 'Root': '' as string, 'Root': '' as string, 'Root': '' as string, 'Root': '' as string, diff --git a/packages/react/src/components/code-block-view.test.tsx b/packages/react/src/components/code-block-view.test.tsx index bffbaec1..7f2bc7b0 100644 --- a/packages/react/src/components/code-block-view.test.tsx +++ b/packages/react/src/components/code-block-view.test.tsx @@ -8,7 +8,7 @@ import { describe, expect, it, vi } from 'vitest' import { render } from 'vitest-browser-react' import { page, userEvent } from 'vitest/browser' -import { hover } from '../testing/mouse.ts' +import { hover, unhover } from '../testing/mouse.ts' import { ProseKitEditor } from './prosekit-editor.tsx' import type { EditorHandle } from './types.ts' @@ -264,6 +264,33 @@ describe('code block Mermaid preview', () => { }) }) +describe('code block node selection', () => { + const codeBlock = page.getByTestId('code-block') + const dragHandle = page.getByTestId('block-handle-drag') + + it('outlines a math block selected with the block handle', async () => { + await unhover() + await render() + await expect.element(mathPreview.locate('.katex')).toBeInTheDocument() + + await hover(mathPreview) + await dragHandle.click() + + await expect.element(codeBlock).toHaveStyle({ outlineStyle: 'solid' }) + }) + + it('outlines a Mermaid block selected with the block handle', async () => { + await unhover() + await render() + await expect.element(mermaidPreview.locate('svg'), { timeout: 15000 }).toBeInTheDocument() + + await hover(mermaidPreview) + await dragHandle.click() + + await expect.element(codeBlock).toHaveStyle({ outlineStyle: 'solid' }) + }) +}) + describe('typing over code block selections', () => { async function setupHighlightedCodeBlock(onDocChange?: VoidFunction) { const ref = createRef() diff --git a/packages/react/src/components/code-block-view.tsx b/packages/react/src/components/code-block-view.tsx index cd787737..881f03c1 100644 --- a/packages/react/src/components/code-block-view.tsx +++ b/packages/react/src/components/code-block-view.tsx @@ -70,7 +70,12 @@ export function CodeBlockView(props: ReactNodeViewProps): ReactElement { ) return ( - + { /* Skip rendering the toolbar during dragging to improve the performance of rendering the drag preview image in Safari */