(frontend) add divider blocks to the editor

Add a custom block to add a divider in the editor.
This commit is contained in:
Anthony LC
2025-03-10 16:55:07 +01:00
committed by Anthony LC
parent da02d3d756
commit 534085439f
6 changed files with 73 additions and 7 deletions

View File

@@ -27,12 +27,13 @@ import { randomColor } from '../utils';
import { BlockNoteSuggestionMenu } from './BlockNoteSuggestionMenu';
import { BlockNoteToolbar } from './BlockNoteToolBar/BlockNoteToolbar';
import { QuoteBlock } from './custom-blocks';
import { DividerBlock, QuoteBlock } from './custom-blocks';
export const blockNoteSchema = withPageBreak(
BlockNoteSchema.create({
blockSpecs: {
...defaultBlockSpecs,
divider: DividerBlock,
quote: QuoteBlock,
},
}),

View File

@@ -11,7 +11,10 @@ import { useTranslation } from 'react-i18next';
import { DocsBlockSchema } from '../types';
import { getQuoteReactSlashMenuItems } from './custom-blocks';
import {
getDividerReactSlashMenuItems,
getQuoteReactSlashMenuItems,
} from './custom-blocks';
export const BlockNoteSuggestionMenu = () => {
const editor = useBlockNoteEditor<DocsBlockSchema>();
@@ -26,6 +29,7 @@ export const BlockNoteSuggestionMenu = () => {
getDefaultReactSlashMenuItems(editor),
getPageBreakReactSlashMenuItems(editor),
getQuoteReactSlashMenuItems(editor, t, basicBlocksName),
getDividerReactSlashMenuItems(editor, t, basicBlocksName),
),
query,
),

View File

@@ -0,0 +1,55 @@
import { insertOrUpdateBlock } from '@blocknote/core';
import { createReactBlockSpec } from '@blocknote/react';
import { TFunction } from 'i18next';
import { Box, Text } 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: (
<Text $isMaterialIcon $size="18px">
remove
</Text>
),
subtext: t('Add a horizontal line'),
},
];

View File

@@ -13,7 +13,6 @@ export const QuoteBlock = createReactBlockSpec(
type: 'quote',
propSchema: {
textAlignment: defaultProps.textAlignment,
textColor: defaultProps.textColor,
},
content: 'inline',
},

View File

@@ -1 +1,2 @@
export * from './DividerBlock';
export * from './QuoteBlock';

View File

@@ -10,10 +10,6 @@ export const cssEditor = (readonly: boolean) => css`
pointer-events: none;
}
.bn-side-menu[data-block-type='quote'] {
height: 46px;
}
.collaboration-cursor-custom__base {
position: relative;
}
@@ -49,6 +45,9 @@ export const cssEditor = (readonly: boolean) => css`
clip-path: polygon(0 0, 100% 0%, 100% 100%, 0% 100%);
}
/**
* Side menu
*/
.bn-side-menu[data-block-type='heading'][data-level='1'] {
height: 50px;
}
@@ -58,6 +57,13 @@ export const cssEditor = (readonly: boolean) => css`
.bn-side-menu[data-block-type='heading'][data-level='3'] {
height: 35px;
}
.bn-side-menu[data-block-type='quote'] {
height: 46px;
}
.bn-side-menu[data-block-type='divider'] {
height: 38px;
}
h1 {
font-size: 1.875rem;
}