🔥(frontend) remove custom DividerBlock
Blocknote now has a built-in divider block, so we can remove our custom implementation.
This commit is contained in:
@@ -88,6 +88,10 @@ and this project adheres to
|
|||||||
- ✨(frontend) load docs logo from public folder via url #1462
|
- ✨(frontend) load docs logo from public folder via url #1462
|
||||||
- 🔧(keycloak) Fix https required issue in dev mode #1286
|
- 🔧(keycloak) Fix https required issue in dev mode #1286
|
||||||
|
|
||||||
|
## Removed
|
||||||
|
|
||||||
|
- 🔥(frontend) remove custom DividerBlock ##1375
|
||||||
|
|
||||||
## [3.7.0] - 2025-09-12
|
## [3.7.0] - 2025-09-12
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
@@ -274,49 +274,6 @@ test.describe('Doc Export', () => {
|
|||||||
expect(pdfData.text).toContain('Hello World'); // This is the pdf text
|
expect(pdfData.text).toContain('Hello World'); // This is the pdf text
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
|
||||||
* We cannot assert the line break is visible in the pdf, but we can assert the
|
|
||||||
* line break is visible in the editor and that the pdf is generated.
|
|
||||||
*/
|
|
||||||
test('it exports the doc with divider', async ({ page, browserName }) => {
|
|
||||||
const [randomDoc] = await createDoc(page, 'export-divider', browserName, 1);
|
|
||||||
|
|
||||||
const editor = page.locator('.ProseMirror');
|
|
||||||
await editor.click();
|
|
||||||
await editor.fill('Hello World');
|
|
||||||
|
|
||||||
// Trigger slash menu to show menu
|
|
||||||
await editor.locator('.bn-block-outer').last().fill('/');
|
|
||||||
await page.getByText('Add a horizontal line').click();
|
|
||||||
|
|
||||||
await expect(
|
|
||||||
editor.locator('.bn-block-content[data-content-type="divider"]'),
|
|
||||||
).toBeVisible();
|
|
||||||
|
|
||||||
await page
|
|
||||||
.getByRole('button', {
|
|
||||||
name: 'Export the document',
|
|
||||||
})
|
|
||||||
.click();
|
|
||||||
|
|
||||||
await expect(
|
|
||||||
page.getByTestId('doc-open-modal-download-button'),
|
|
||||||
).toBeVisible();
|
|
||||||
|
|
||||||
const downloadPromise = page.waitForEvent('download', (download) => {
|
|
||||||
return download.suggestedFilename().includes(`${randomDoc}.pdf`);
|
|
||||||
});
|
|
||||||
|
|
||||||
void page.getByTestId('doc-export-download-button').click();
|
|
||||||
|
|
||||||
const download = await downloadPromise;
|
|
||||||
expect(download.suggestedFilename()).toBe(`${randomDoc}.pdf`);
|
|
||||||
|
|
||||||
const pdfBuffer = await cs.toBuffer(await download.createReadStream());
|
|
||||||
const pdfData = await pdf(pdfBuffer);
|
|
||||||
expect(pdfData.text).toContain('Hello World');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('it exports the doc with multi columns', async ({
|
test('it exports the doc with multi columns', async ({
|
||||||
page,
|
page,
|
||||||
browserName,
|
browserName,
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ import { BlockNoteToolbar } from './BlockNoteToolBar/BlockNoteToolbar';
|
|||||||
import {
|
import {
|
||||||
AccessibleImageBlock,
|
AccessibleImageBlock,
|
||||||
CalloutBlock,
|
CalloutBlock,
|
||||||
DividerBlock,
|
|
||||||
PdfBlock,
|
PdfBlock,
|
||||||
UploadLoaderBlock,
|
UploadLoaderBlock,
|
||||||
} from './custom-blocks';
|
} from './custom-blocks';
|
||||||
@@ -54,7 +53,6 @@ const baseBlockNoteSchema = withPageBreak(
|
|||||||
blockSpecs: {
|
blockSpecs: {
|
||||||
...defaultBlockSpecs,
|
...defaultBlockSpecs,
|
||||||
callout: CalloutBlock,
|
callout: CalloutBlock,
|
||||||
divider: DividerBlock,
|
|
||||||
image: AccessibleImageBlock,
|
image: AccessibleImageBlock,
|
||||||
pdf: PdfBlock,
|
pdf: PdfBlock,
|
||||||
uploadLoader: UploadLoaderBlock,
|
uploadLoader: UploadLoaderBlock,
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import {
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
getCalloutReactSlashMenuItems,
|
getCalloutReactSlashMenuItems,
|
||||||
getDividerReactSlashMenuItems,
|
|
||||||
getPdfReactSlashMenuItems,
|
getPdfReactSlashMenuItems,
|
||||||
} from './custom-blocks';
|
} from './custom-blocks';
|
||||||
import { useGetInterlinkingMenuItems } from './custom-inline-content';
|
import { useGetInterlinkingMenuItems } from './custom-inline-content';
|
||||||
@@ -59,7 +58,6 @@ export const BlockNoteSuggestionMenu = () => {
|
|||||||
getCalloutReactSlashMenuItems(editor, t, basicBlocksName),
|
getCalloutReactSlashMenuItems(editor, t, basicBlocksName),
|
||||||
getMultiColumnSlashMenuItems?.(editor) || [],
|
getMultiColumnSlashMenuItems?.(editor) || [],
|
||||||
getPageBreakReactSlashMenuItems(editor),
|
getPageBreakReactSlashMenuItems(editor),
|
||||||
getDividerReactSlashMenuItems(editor, t, basicBlocksName),
|
|
||||||
getPdfReactSlashMenuItems(editor, t, fileBlocksName),
|
getPdfReactSlashMenuItems(editor, t, fileBlocksName),
|
||||||
),
|
),
|
||||||
query,
|
query,
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
import { insertOrUpdateBlock } from '@blocknote/core';
|
|
||||||
import { createReactBlockSpec } from '@blocknote/react';
|
|
||||||
import { TFunction } from 'i18next';
|
|
||||||
|
|
||||||
import { Box, Icon } from '@/components';
|
|
||||||
import { useCunninghamTheme } from '@/cunningham';
|
|
||||||
|
|
||||||
import { DocsBlockNoteEditor } from '../../types';
|
|
||||||
|
|
||||||
export const DividerBlock = createReactBlockSpec(
|
|
||||||
{
|
|
||||||
type: 'divider',
|
|
||||||
propSchema: {},
|
|
||||||
content: 'none',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
render: () => {
|
|
||||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
||||||
const { colorsTokens } = useCunninghamTheme();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Box
|
|
||||||
as="hr"
|
|
||||||
$width="100%"
|
|
||||||
$background={colorsTokens['greyscale-300']}
|
|
||||||
$margin="1rem 0"
|
|
||||||
$css={`border: 1px solid ${colorsTokens['greyscale-300']};`}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
export const getDividerReactSlashMenuItems = (
|
|
||||||
editor: DocsBlockNoteEditor,
|
|
||||||
t: TFunction<'translation', undefined>,
|
|
||||||
group: string,
|
|
||||||
) => [
|
|
||||||
{
|
|
||||||
title: t('Divider'),
|
|
||||||
onItemClick: () => {
|
|
||||||
insertOrUpdateBlock(editor, {
|
|
||||||
type: 'divider',
|
|
||||||
});
|
|
||||||
},
|
|
||||||
aliases: ['divider', 'hr', 'horizontal rule', 'line', 'separator'],
|
|
||||||
group,
|
|
||||||
icon: <Icon iconName="remove" $size="18px" />,
|
|
||||||
subtext: t('Add a horizontal line'),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
export * from './AccessibleImageBlock';
|
export * from './AccessibleImageBlock';
|
||||||
export * from './CalloutBlock';
|
export * from './CalloutBlock';
|
||||||
export * from './DividerBlock';
|
|
||||||
export * from './PdfBlock';
|
export * from './PdfBlock';
|
||||||
export * from './UploadLoaderBlock';
|
export * from './UploadLoaderBlock';
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
import { Paragraph } from 'docx';
|
|
||||||
|
|
||||||
import { useCunninghamTheme } from '@/cunningham';
|
|
||||||
|
|
||||||
import { DocsExporterDocx } from '../types';
|
|
||||||
|
|
||||||
export const blockMappingDividerDocx: DocsExporterDocx['mappings']['blockMapping']['divider'] =
|
|
||||||
() => {
|
|
||||||
const { colorsTokens } = useCunninghamTheme.getState();
|
|
||||||
|
|
||||||
return new Paragraph({
|
|
||||||
spacing: {
|
|
||||||
before: 200,
|
|
||||||
},
|
|
||||||
border: {
|
|
||||||
top: {
|
|
||||||
color: colorsTokens['greyscale-300'],
|
|
||||||
size: 1,
|
|
||||||
style: 'single',
|
|
||||||
space: 1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
import { Text } from '@react-pdf/renderer';
|
|
||||||
|
|
||||||
import { useCunninghamTheme } from '@/cunningham';
|
|
||||||
|
|
||||||
import { DocsExporterPDF } from '../types';
|
|
||||||
|
|
||||||
export const blockMappingDividerPDF: DocsExporterPDF['mappings']['blockMapping']['divider'] =
|
|
||||||
() => {
|
|
||||||
const { colorsTokens } = useCunninghamTheme.getState();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Text
|
|
||||||
style={{
|
|
||||||
marginVertical: 10,
|
|
||||||
backgroundColor: colorsTokens['greyscale-300'],
|
|
||||||
height: '2px',
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
export * from './calloutDocx';
|
export * from './calloutDocx';
|
||||||
export * from './calloutPDF';
|
export * from './calloutPDF';
|
||||||
export * from './dividerDocx';
|
|
||||||
export * from './dividerPDF';
|
|
||||||
export * from './headingPDF';
|
export * from './headingPDF';
|
||||||
export * from './imageDocx';
|
export * from './imageDocx';
|
||||||
export * from './imagePDF';
|
export * from './imagePDF';
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
import { docxDefaultSchemaMappings } from '@blocknote/xl-docx-exporter';
|
import { docxDefaultSchemaMappings } from '@blocknote/xl-docx-exporter';
|
||||||
import { Paragraph } from 'docx';
|
import { TextRun } from 'docx';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
blockMappingCalloutDocx,
|
blockMappingCalloutDocx,
|
||||||
blockMappingDividerDocx,
|
|
||||||
blockMappingImageDocx,
|
blockMappingImageDocx,
|
||||||
blockMappingQuoteDocx,
|
blockMappingQuoteDocx,
|
||||||
blockMappingUploadLoaderDocx,
|
blockMappingUploadLoaderDocx,
|
||||||
@@ -16,9 +15,8 @@ export const docxDocsSchemaMappings: DocsExporterDocx['mappings'] = {
|
|||||||
blockMapping: {
|
blockMapping: {
|
||||||
...docxDefaultSchemaMappings.blockMapping,
|
...docxDefaultSchemaMappings.blockMapping,
|
||||||
callout: blockMappingCalloutDocx,
|
callout: blockMappingCalloutDocx,
|
||||||
divider: blockMappingDividerDocx,
|
// We're reusing the file block mapping for PDF blocks; both share the same
|
||||||
// We're using the file block mapping for PDF blocks
|
// implementation signature, so we can reuse the handler directly.
|
||||||
// The types don't match exactly but the implementation is compatible
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
pdf: docxDefaultSchemaMappings.blockMapping.file as any,
|
pdf: docxDefaultSchemaMappings.blockMapping.file as any,
|
||||||
quote: blockMappingQuoteDocx,
|
quote: blockMappingQuoteDocx,
|
||||||
@@ -27,7 +25,7 @@ export const docxDocsSchemaMappings: DocsExporterDocx['mappings'] = {
|
|||||||
},
|
},
|
||||||
inlineContentMapping: {
|
inlineContentMapping: {
|
||||||
...docxDefaultSchemaMappings.inlineContentMapping,
|
...docxDefaultSchemaMappings.inlineContentMapping,
|
||||||
interlinkingSearchInline: () => new Paragraph(''),
|
interlinkingSearchInline: () => new TextRun(''),
|
||||||
interlinkingLinkInline: inlineContentMappingInterlinkingLinkDocx,
|
interlinkingLinkInline: inlineContentMappingInterlinkingLinkDocx,
|
||||||
},
|
},
|
||||||
styleMapping: {
|
styleMapping: {
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import { pdfDefaultSchemaMappings } from '@blocknote/xl-pdf-exporter';
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
blockMappingCalloutPDF,
|
blockMappingCalloutPDF,
|
||||||
blockMappingDividerPDF,
|
|
||||||
blockMappingHeadingPDF,
|
blockMappingHeadingPDF,
|
||||||
blockMappingImagePDF,
|
blockMappingImagePDF,
|
||||||
blockMappingParagraphPDF,
|
blockMappingParagraphPDF,
|
||||||
@@ -21,7 +20,6 @@ export const pdfDocsSchemaMappings: DocsExporterPDF['mappings'] = {
|
|||||||
heading: blockMappingHeadingPDF,
|
heading: blockMappingHeadingPDF,
|
||||||
image: blockMappingImagePDF,
|
image: blockMappingImagePDF,
|
||||||
paragraph: blockMappingParagraphPDF,
|
paragraph: blockMappingParagraphPDF,
|
||||||
divider: blockMappingDividerPDF,
|
|
||||||
quote: blockMappingQuotePDF,
|
quote: blockMappingQuotePDF,
|
||||||
table: blockMappingTablePDF,
|
table: blockMappingTablePDF,
|
||||||
// We're using the file block mapping for PDF blocks
|
// We're using the file block mapping for PDF blocks
|
||||||
|
|||||||
Reference in New Issue
Block a user