🚚(frontend) move Markdown button to is own file
To keep the codebase clean and organized, we moved the Markdown button to its own file.
This commit is contained in:
@@ -9,12 +9,10 @@ import {
|
|||||||
NestBlockButton,
|
NestBlockButton,
|
||||||
TextAlignButton,
|
TextAlignButton,
|
||||||
UnnestBlockButton,
|
UnnestBlockButton,
|
||||||
useBlockNoteEditor,
|
|
||||||
useComponentsContext,
|
|
||||||
useSelectedBlocks,
|
|
||||||
} from '@blocknote/react';
|
} from '@blocknote/react';
|
||||||
import { forEach, isArray } from 'lodash';
|
import React from 'react';
|
||||||
import React, { useMemo } from 'react';
|
|
||||||
|
import { MarkdownButton } from './MarkdownButton';
|
||||||
|
|
||||||
export const BlockNoteToolbar = () => {
|
export const BlockNoteToolbar = () => {
|
||||||
return (
|
return (
|
||||||
@@ -57,79 +55,3 @@ export const BlockNoteToolbar = () => {
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
type Block = {
|
|
||||||
type: string;
|
|
||||||
text: string;
|
|
||||||
content: Block[];
|
|
||||||
};
|
|
||||||
|
|
||||||
function isBlock(block: Block): block is Block {
|
|
||||||
return (
|
|
||||||
block.content &&
|
|
||||||
isArray(block.content) &&
|
|
||||||
block.content.length > 0 &&
|
|
||||||
typeof block.type !== 'undefined'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const recursiveContent = (content: Block[], base: string = '') => {
|
|
||||||
let fullContent = base;
|
|
||||||
for (const innerContent of content) {
|
|
||||||
if (innerContent.type === 'text') {
|
|
||||||
fullContent += innerContent.text;
|
|
||||||
} else if (isBlock(innerContent)) {
|
|
||||||
fullContent = recursiveContent(innerContent.content, fullContent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return fullContent;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Custom Formatting Toolbar Button to convert markdown to json.
|
|
||||||
*/
|
|
||||||
export function MarkdownButton() {
|
|
||||||
const editor = useBlockNoteEditor();
|
|
||||||
const Components = useComponentsContext();
|
|
||||||
const selectedBlocks = useSelectedBlocks(editor);
|
|
||||||
|
|
||||||
const handleConvertMarkdown = () => {
|
|
||||||
const blocks = editor.getSelection()?.blocks;
|
|
||||||
|
|
||||||
forEach(blocks, async (block) => {
|
|
||||||
if (!isBlock(block as unknown as Block)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const fullContent = recursiveContent(
|
|
||||||
block.content as unknown as Block[],
|
|
||||||
);
|
|
||||||
|
|
||||||
const blockMarkdown =
|
|
||||||
await editor.tryParseMarkdownToBlocks(fullContent);
|
|
||||||
editor.replaceBlocks([block.id], blockMarkdown);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error parsing Markdown:', error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const show = useMemo(() => {
|
|
||||||
return !!selectedBlocks.find((block) => block.content !== undefined);
|
|
||||||
}, [selectedBlocks]);
|
|
||||||
|
|
||||||
if (!show || !editor.isEditable || !Components) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Components.FormattingToolbar.Button
|
|
||||||
mainTooltip="Convert Markdown"
|
|
||||||
onClick={handleConvertMarkdown}
|
|
||||||
>
|
|
||||||
M
|
|
||||||
</Components.FormattingToolbar.Button>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -0,0 +1,84 @@
|
|||||||
|
import '@blocknote/mantine/style.css';
|
||||||
|
import {
|
||||||
|
useBlockNoteEditor,
|
||||||
|
useComponentsContext,
|
||||||
|
useSelectedBlocks,
|
||||||
|
} from '@blocknote/react';
|
||||||
|
import { forEach, isArray } from 'lodash';
|
||||||
|
import React, { useMemo } from 'react';
|
||||||
|
|
||||||
|
type Block = {
|
||||||
|
type: string;
|
||||||
|
text: string;
|
||||||
|
content: Block[];
|
||||||
|
};
|
||||||
|
|
||||||
|
function isBlock(block: Block): block is Block {
|
||||||
|
return (
|
||||||
|
block.content &&
|
||||||
|
isArray(block.content) &&
|
||||||
|
block.content.length > 0 &&
|
||||||
|
typeof block.type !== 'undefined'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const recursiveContent = (content: Block[], base: string = '') => {
|
||||||
|
let fullContent = base;
|
||||||
|
for (const innerContent of content) {
|
||||||
|
if (innerContent.type === 'text') {
|
||||||
|
fullContent += innerContent.text;
|
||||||
|
} else if (isBlock(innerContent)) {
|
||||||
|
fullContent = recursiveContent(innerContent.content, fullContent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fullContent;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom Formatting Toolbar Button to convert markdown to json.
|
||||||
|
*/
|
||||||
|
export function MarkdownButton() {
|
||||||
|
const editor = useBlockNoteEditor();
|
||||||
|
const Components = useComponentsContext();
|
||||||
|
const selectedBlocks = useSelectedBlocks(editor);
|
||||||
|
|
||||||
|
const handleConvertMarkdown = () => {
|
||||||
|
const blocks = editor.getSelection()?.blocks;
|
||||||
|
|
||||||
|
forEach(blocks, async (block) => {
|
||||||
|
if (!isBlock(block as unknown as Block)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const fullContent = recursiveContent(
|
||||||
|
block.content as unknown as Block[],
|
||||||
|
);
|
||||||
|
|
||||||
|
const blockMarkdown =
|
||||||
|
await editor.tryParseMarkdownToBlocks(fullContent);
|
||||||
|
editor.replaceBlocks([block.id], blockMarkdown);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error parsing Markdown:', error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const show = useMemo(() => {
|
||||||
|
return !!selectedBlocks.find((block) => block.content !== undefined);
|
||||||
|
}, [selectedBlocks]);
|
||||||
|
|
||||||
|
if (!show || !editor.isEditable || !Components) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Components.FormattingToolbar.Button
|
||||||
|
mainTooltip="Convert Markdown"
|
||||||
|
onClick={handleConvertMarkdown}
|
||||||
|
>
|
||||||
|
M
|
||||||
|
</Components.FormattingToolbar.Button>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user