🚚(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,
|
||||
TextAlignButton,
|
||||
UnnestBlockButton,
|
||||
useBlockNoteEditor,
|
||||
useComponentsContext,
|
||||
useSelectedBlocks,
|
||||
} from '@blocknote/react';
|
||||
import { forEach, isArray } from 'lodash';
|
||||
import React, { useMemo } from 'react';
|
||||
import React from 'react';
|
||||
|
||||
import { MarkdownButton } from './MarkdownButton';
|
||||
|
||||
export const BlockNoteToolbar = () => {
|
||||
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