Skip to content

Commit 32f3174

Browse files
committed
Added reference inline content and bibliography block
1 parent d952815 commit 32f3174

File tree

7 files changed

+446
-3
lines changed

7 files changed

+446
-3
lines changed

src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteEditor.tsx

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,19 @@ import { codeBlock } from '@blocknote/code-block';
22
import {
33
BlockNoteSchema,
44
defaultBlockSpecs,
5+
defaultInlineContentSpecs,
6+
filterSuggestionItems,
57
withPageBreak,
68
} from '@blocknote/core';
79
import '@blocknote/core/fonts/inter.css';
810
import * as locales from '@blocknote/core/locales';
911
import { BlockNoteView } from '@blocknote/mantine';
1012
import '@blocknote/mantine/style.css';
11-
import { useCreateBlockNote } from '@blocknote/react';
13+
import {
14+
SuggestionMenuController,
15+
getDefaultReactSlashMenuItems,
16+
useCreateBlockNote,
17+
} from '@blocknote/react';
1218
import { HocuspocusProvider } from '@hocuspocus/provider';
1319
import { useEffect } from 'react';
1420
import { useTranslation } from 'react-i18next';
@@ -27,15 +33,22 @@ import { randomColor } from '../utils';
2733

2834
import { BlockNoteSuggestionMenu } from './BlockNoteSuggestionMenu';
2935
import { BlockNoteToolbar } from './BlockNoteToolBar/BlockNoteToolbar';
30-
import { CalloutBlock, DividerBlock } from './custom-blocks';
36+
import { BibliographyBlock, CalloutBlock, DividerBlock } from './custom-blocks';
37+
import { ReferenceInlineContent } from './custom-inline-content';
38+
import { getBibliographyReactSlashMenuItems } from './slash-menu-items/getBibliographyReactSlashMenuItems';
3139

3240
export const blockNoteSchema = withPageBreak(
3341
BlockNoteSchema.create({
3442
blockSpecs: {
3543
...defaultBlockSpecs,
44+
bibliography: BibliographyBlock,
3645
callout: CalloutBlock,
3746
divider: DividerBlock,
3847
},
48+
inlineContentSpecs: {
49+
...defaultInlineContentSpecs,
50+
reference: ReferenceInlineContent,
51+
},
3952
}),
4053
);
4154

@@ -205,7 +218,25 @@ export const BlockNoteEditorVersion = ({
205218

206219
return (
207220
<Box $css={cssEditor(readOnly)} className="--docs--editor-container">
208-
<BlockNoteView editor={editor} editable={!readOnly} theme="light" />
221+
<BlockNoteView
222+
editor={editor}
223+
editable={!readOnly}
224+
slashMenu={false}
225+
theme="light"
226+
>
227+
<SuggestionMenuController
228+
triggerCharacter="/"
229+
getItems={async (query) =>
230+
filterSuggestionItems(
231+
[
232+
...getDefaultReactSlashMenuItems(editor),
233+
...getBibliographyReactSlashMenuItems(editor),
234+
],
235+
query,
236+
)
237+
}
238+
/>
239+
</BlockNoteView>
209240
</Box>
210241
);
211242
};
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
2+
/* eslint-disable @typescript-eslint/no-floating-promises */
3+
/* eslint-disable @typescript-eslint/no-explicit-any */
4+
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
5+
import { BlockConfig } from '@blocknote/core';
6+
import {
7+
ReactCustomBlockRenderProps,
8+
createReactBlockSpec,
9+
} from '@blocknote/react';
10+
import { useEffect, useState } from 'react';
11+
12+
export const bibliographyBlockConfig = {
13+
type: 'bibliography',
14+
propSchema: {
15+
bibTexJSON: {
16+
default: '[]',
17+
},
18+
},
19+
content: 'none',
20+
isSelectable: false,
21+
} as const satisfies BlockConfig;
22+
23+
export const Bibliography = (
24+
props: ReactCustomBlockRenderProps<typeof bibliographyBlockConfig, any, any>,
25+
) => {
26+
const [sources, setSources] = useState<any[]>([]);
27+
28+
useEffect(() => {
29+
async function fetchBibliography() {
30+
const dois: string[] = JSON.parse(props.block.props.bibTexJSON);
31+
32+
const data = await Promise.all(
33+
dois
34+
.filter((source) => source)
35+
.map((doi) =>
36+
fetch(`https://api.datacite.org/dois/${doi}`).then((res) =>
37+
res.json(),
38+
),
39+
),
40+
);
41+
42+
setSources(data.filter((source) => source));
43+
}
44+
45+
fetchBibliography();
46+
}, [props.block.props.bibTexJSON]);
47+
48+
// console.log(sources);
49+
50+
return (
51+
<div>
52+
<h2>Bibliography</h2>
53+
{sources.map((source: any) => (
54+
<div key={source.data.attributes.doi}>{source.data.attributes.doi}</div>
55+
))}
56+
</div>
57+
);
58+
};
59+
60+
export const BibliographyBlock = createReactBlockSpec(bibliographyBlockConfig, {
61+
render: Bibliography,
62+
});
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import {
2+
BlockNoteEditor,
3+
BlockSchema,
4+
InlineContentSchema,
5+
StyleSchema,
6+
} from '@blocknote/core';
7+
import { useEditorChange } from '@blocknote/react';
8+
9+
export const useSingleBibliographyBlock = <
10+
B extends BlockSchema,
11+
I extends InlineContentSchema,
12+
S extends StyleSchema,
13+
>(
14+
editor?: BlockNoteEditor<B, I, S>,
15+
) => {
16+
useEditorChange((editor) => {
17+
const bibliographyBlockIds: string[] = [];
18+
19+
editor.forEachBlock((block) => {
20+
if (block.type === 'bibliography') {
21+
bibliographyBlockIds.push(block.id);
22+
}
23+
24+
return true;
25+
}, true);
26+
27+
if (bibliographyBlockIds.length > 1) {
28+
editor.removeBlocks(bibliographyBlockIds.slice(1));
29+
}
30+
}, editor);
31+
};
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
1+
export * from './BibliographyBlock/BibliographyBlock';
2+
export * from './BibliographyBlock/hooks/useSingleBibliographyBlock';
13
export * from './CalloutBlock';
24
export * from './DividerBlock';

0 commit comments

Comments
 (0)