Skip to content

Commit 853e3ec

Browse files
committed
feat: add TOC prototype block
1 parent 7dca815 commit 853e3ec

File tree

8 files changed

+228
-7
lines changed

8 files changed

+228
-7
lines changed

docs/src/app/app.routes.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { ApiContentBlockPage } from '../pages/examples/custom/api-content-block/
1212
import { MentionsMenuPage } from '../pages/examples/custom/mentions-menu/mentions-menu.page';
1313
import { ExamplesPage } from '../pages/examples/examples.page';
1414
import { HeadingBlockPage } from '../pages/examples/extensions/heading/heading-block.page';
15+
import { TableOfContentsBlockPage } from '../pages/examples/extensions/table-of-contents/table-of-contents-block.page';
1516
import { ConvertToHtmlPage } from '../pages/examples/interoperability/convert-to-html/convert-to-html.page';
1617
import { AddingSideMenuDragHandleItemsPage } from '../pages/examples/ui-components/adding-side-menu-drag-handle-items/adding-side-menu-drag-handle-items.page';
1718
import { FormattingSideMenuButtonsPage } from '../pages/examples/ui-components/formatting-side-menu-buttons/formatting-side-menu-buttons.page';
@@ -62,6 +63,10 @@ export const appRoutes: Route[] = [
6263
path: 'extensions/heading-block',
6364
component: HeadingBlockPage,
6465
},
66+
{
67+
path: 'extensions/table-of-contents',
68+
component: TableOfContentsBlockPage,
69+
},
6570
{
6671
path: 'interoperability/convert-to-html',
6772
component: ConvertToHtmlPage,

docs/src/pages/examples/examples.page.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,14 @@ import { HlmButtonDirective } from '@dytab/block-note-angular';
121121
routerLink="extensions/heading-block"
122122
>Heading Block</a
123123
>
124+
<a
125+
hlmBtn
126+
variant="ghost"
127+
class="justify-start"
128+
routerLinkActive="active-link"
129+
routerLink="extensions/table-of-contents"
130+
>Table Of Contents</a
131+
>
124132
Interoperability
125133
<a
126134
hlmBtn

docs/src/pages/examples/extensions/heading/heading-block.example.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ export class HeadingBlockExample {
156156
};
157157
}
158158

159-
export const alertBlockExampleCode = `import { CommonModule } from '@angular/common';
159+
export const headingBlockExampleCode = `import { CommonModule } from '@angular/common';
160160
import { Component } from '@angular/core';
161161
import {
162162
BlockNoteEditor,

docs/src/pages/examples/extensions/heading/heading-block.page.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ import { DemoBoxComponent } from '../../../../shared/layout/demo-box.component';
1111
import { TabsComponent } from '../../../../shared/layout/example-tabs.component';
1212
import { SectionIntroComponent } from '../../../../shared/layout/section-intro.component';
1313
import {
14-
alertBlockExampleCode,
1514
HeadingBlockExample,
15+
headingBlockExampleCode,
1616
} from './heading-block.example';
1717

1818
@Component({
@@ -48,5 +48,5 @@ import {
4848
</hlm-tabs>`,
4949
})
5050
export class HeadingBlockPage {
51-
exampleCode = alertBlockExampleCode;
51+
exampleCode = headingBlockExampleCode;
5252
}
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
import { CommonModule } from '@angular/common';
2+
import { Component } from '@angular/core';
3+
import {
4+
BlockNoteEditor,
5+
BlockNoteSchema,
6+
defaultBlockSpecs,
7+
defaultInlineContentSpecs,
8+
defaultStyleSpecs,
9+
insertOrUpdateBlock,
10+
PartialBlock,
11+
} from '@blocknote/core';
12+
import {
13+
BlockNoteEditorOptionsType,
14+
BnaEditorComponent,
15+
HlmButtonDirective,
16+
} from '@dytab/block-note-angular';
17+
import { Heading, TableOfContentBlock } from '@dytab/block-note-extensions';
18+
19+
const schema = BlockNoteSchema.create({
20+
blockSpecs: {
21+
...defaultBlockSpecs,
22+
tableOfContents: TableOfContentBlock,
23+
heading: Heading,
24+
},
25+
inlineContentSpecs: { ...defaultInlineContentSpecs },
26+
styleSpecs: { ...defaultStyleSpecs },
27+
});
28+
@Component({
29+
selector: 'bna-heading-block-example',
30+
standalone: true,
31+
imports: [CommonModule, BnaEditorComponent, HlmButtonDirective],
32+
template: `<bna-editor
33+
[initialContent]="initialContent"
34+
[options]="options"
35+
/>`,
36+
})
37+
export class TableOfContentsBlockExample {
38+
initialContent: PartialBlock<typeof schema.blockSchema>[] = [
39+
{ type: 'tableOfContents' },
40+
{ type: 'heading', props: { level: 1 }, content: 'Level 1' },
41+
{ type: 'heading', props: { level: 2 }, content: 'Level 2' },
42+
{ type: 'heading', props: { level: 3 }, content: 'Level 3' },
43+
{ type: 'heading', props: { level: 4 }, content: 'Level 4' },
44+
{ type: 'heading', props: { level: 5 }, content: 'Level 5' },
45+
{ type: 'heading', props: { level: 6 }, content: 'Level 6' },
46+
];
47+
options: BlockNoteEditorOptionsType<
48+
typeof schema.blockSchema,
49+
typeof schema.inlineContentSchema,
50+
typeof schema.styleSchema
51+
> = {
52+
schema,
53+
inputSlashMenuItems: [
54+
(
55+
editor: BlockNoteEditor<
56+
typeof schema.blockSchema,
57+
typeof schema.inlineContentSchema,
58+
typeof schema.styleSchema
59+
>
60+
) => ({
61+
onItemClick: () => {
62+
insertOrUpdateBlock(editor, {
63+
type: 'tableOfContents',
64+
props: { level: 1 },
65+
});
66+
},
67+
key: 'table-of-contents',
68+
group: 'Special',
69+
title: 'Table of Contents',
70+
}),
71+
],
72+
};
73+
}
74+
75+
export const tableOfContentsBlockExampleCode = `import { CommonModule } from '@angular/common';
76+
import { Component } from '@angular/core';
77+
import {
78+
BlockNoteEditor,
79+
BlockNoteSchema,
80+
defaultBlockSpecs,
81+
defaultInlineContentSpecs,
82+
defaultStyleSpecs,
83+
insertOrUpdateBlock,
84+
PartialBlock,
85+
} from '@blocknote/core';
86+
import {
87+
BlockNoteEditorOptionsType,
88+
BnaEditorComponent,
89+
} from '@dytab/block-note-angular';
90+
import { HlmButtonDirective } from '@dytab/block-note-angular';
91+
import { alertBlock } from './alert-block';
92+
93+
const schema = BlockNoteSchema.create({
94+
blockSpecs: {
95+
...defaultBlockSpecs,
96+
alert: alertBlock,
97+
},
98+
inlineContentSpecs: { ...defaultInlineContentSpecs },
99+
styleSpecs: { ...defaultStyleSpecs },
100+
});
101+
@Component({
102+
selector: 'bna-alert-block-example',
103+
standalone: true,
104+
imports: [CommonModule, BnaEditorComponent, HlmButtonDirective],
105+
template: \`<bna-editor
106+
[initialContent]="initialContent"
107+
[options]="options"
108+
/>\`,
109+
})
110+
export class AlertBlockExample {
111+
initialContent: PartialBlock<typeof schema.blockSchema>[] = [
112+
{
113+
type: 'alert',
114+
props: {
115+
type: 'warning',
116+
},
117+
},
118+
];
119+
options: BlockNoteEditorOptionsType<
120+
typeof schema.blockSchema,
121+
typeof schema.inlineContentSchema,
122+
typeof schema.styleSchema
123+
> = {
124+
schema,
125+
inputSlashMenuItems: [
126+
(
127+
editor: BlockNoteEditor<
128+
typeof schema.blockSchema,
129+
typeof schema.inlineContentSchema,
130+
typeof schema.styleSchema
131+
>
132+
) => ({
133+
title: 'Alert',
134+
onItemClick: () => {
135+
insertOrUpdateBlock(editor, {
136+
type: 'alert' as never,
137+
});
138+
},
139+
badge: 'BAFD',
140+
subtext: 'SUBTEXT',
141+
aliases: [
142+
'alert',
143+
'notification',
144+
'emphasize',
145+
'warning',
146+
'error',
147+
'info',
148+
'success',
149+
],
150+
group: 'Other',
151+
}),
152+
],
153+
};
154+
}`;
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { CommonModule } from '@angular/common';
2+
import { Component } from '@angular/core';
3+
import {
4+
BnaEditorComponent,
5+
HlmButtonDirective,
6+
hlmP,
7+
HlmTabsComponent,
8+
} from '@dytab/block-note-angular';
9+
import { CodeComponent } from '../../../../shared/code/code.component';
10+
import { DemoBoxComponent } from '../../../../shared/layout/demo-box.component';
11+
import { TabsComponent } from '../../../../shared/layout/example-tabs.component';
12+
import { SectionIntroComponent } from '../../../../shared/layout/section-intro.component';
13+
import {
14+
TableOfContentsBlockExample,
15+
tableOfContentsBlockExampleCode,
16+
} from './table-of-contents-block.example';
17+
18+
@Component({
19+
standalone: true,
20+
imports: [
21+
CommonModule,
22+
BnaEditorComponent,
23+
HlmButtonDirective,
24+
SectionIntroComponent,
25+
CodeComponent,
26+
DemoBoxComponent,
27+
HlmTabsComponent,
28+
TabsComponent,
29+
TableOfContentsBlockExample,
30+
],
31+
template: `<bna-section-intro name="Heading Block">
32+
<p class="${hlmP} mb-8">
33+
In this example, we show the custom heading which allows us to use 6
34+
level headings instead of the default 3.
35+
</p>
36+
<p>
37+
<strong>Try it out</strong>: Press the "/" key to open the Slash Menu
38+
and insert the new heading levels!
39+
</p>
40+
</bna-section-intro>
41+
<hlm-tabs tab="preview">
42+
<bna-example-tabs firstTab="Preview" secondTab="Code">
43+
<bna-demo-box firstTab>
44+
<bna-heading-block-example />
45+
</bna-demo-box>
46+
<bna-code [code]="exampleCode" secondTab />
47+
</bna-example-tabs>
48+
</hlm-tabs>`,
49+
})
50+
export class TableOfContentsBlockPage {
51+
exampleCode = tableOfContentsBlockExampleCode;
52+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export * from './lib/heading/heading.block';
2+
export * from './lib/table-of-contents/table-of-contents.block';

libs/block-note-extensions/src/lib/table-of-contents/table-of-contents.block.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
export const tableOfContentsPropSchema = {} satisfies PropSchema;
1010

1111
export const tableOfContentsBlockConfig = {
12-
type: 'table-of-contents' as const,
12+
type: 'tableOfContents' as const,
1313
propSchema: tableOfContentsPropSchema,
1414
content: 'none',
1515
} as const;
@@ -19,8 +19,9 @@ const render = (
1919
editor: BlockNoteEditor<any, any, any>
2020
) => {
2121
const div = document.createElement('div');
22-
for (const block of editor.document) {
23-
}
22+
div.innerHTML = 'TABLE Of contents';
23+
// for (const block of editor.document) {
24+
// }
2425

2526
// editor.onChange(() => {
2627
// //we need to rerender our stuff here
@@ -37,7 +38,7 @@ export const parse = (
3738
return undefined;
3839
};
3940

40-
export const tableOfContentBlock = createBlockSpec(tableOfContentsBlockConfig, {
41+
export const TableOfContentBlock = createBlockSpec(tableOfContentsBlockConfig, {
4142
render: render,
4243
parse: parse,
4344
});

0 commit comments

Comments
 (0)