Skip to content

Commit 40d47eb

Browse files
committed
feat: add prototype of api-content block example
1 parent d23b590 commit 40d47eb

File tree

6 files changed

+272
-42
lines changed

6 files changed

+272
-42
lines changed

docs/src/app/app.routes.ts

Lines changed: 24 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,17 @@
11
import { Route } from '@angular/router';
2-
import {
3-
AllBlocksPage
4-
} from '../pages/examples/basic/all-blocks/all-blocks.page';
5-
import {
6-
BasicSetupPage
7-
} from '../pages/examples/basic/basic-setup/basic-setup.page';
8-
import {
9-
BlocksJsonPage
10-
} from '../pages/examples/basic/blocks-json/blocks-json.page';
11-
import {
12-
SelectionBlocksPage
13-
} from '../pages/examples/basic/selection-blocks/selection-blocks.page';
14-
import {
15-
AlertBlockPage
16-
} from '../pages/examples/custom/alert-block/alert-block.page';
2+
import { SavingAndLoadingPage } from '../pages/examples/backend/saving-and-loading/saving-and-loading.page';
3+
import { UploadFilePage } from '../pages/examples/backend/upload-file/upload-file.page';
4+
import { AllBlocksPage } from '../pages/examples/basic/all-blocks/all-blocks.page';
5+
import { BasicSetupPage } from '../pages/examples/basic/basic-setup/basic-setup.page';
6+
import { BlocksJsonPage } from '../pages/examples/basic/blocks-json/blocks-json.page';
7+
import { ManipulatingBlocksPage } from '../pages/examples/basic/manipulating-blocks/manipulating-blocks.page';
8+
import { RemovingDefaultBlocksPage } from '../pages/examples/basic/removing-default-blocks/removing-default-blocks.page';
9+
import { SelectionBlocksPage } from '../pages/examples/basic/selection-blocks/selection-blocks.page';
10+
import { AlertBlockPage } from '../pages/examples/custom/alert-block/alert-block.page';
11+
import { ApiContentBlockPage } from '../pages/examples/custom/api-content-block/api-content-block.page';
1712
import { ExamplesPage } from '../pages/examples/examples.page';
18-
import {
19-
ConvertToHtmlPage
20-
} from '../pages/examples/interoperability/convert-to-html/convert-to-html.page';
13+
import { ConvertToHtmlPage } from '../pages/examples/interoperability/convert-to-html/convert-to-html.page';
2114
import { OverviewPage } from '../pages/overview.page';
22-
import {
23-
ManipulatingBlocksPage
24-
} from '../pages/examples/basic/manipulating-blocks/manipulating-blocks.page';
25-
import {
26-
RemovingDefaultBlocksPage
27-
} from '../pages/examples/basic/removing-default-blocks/removing-default-blocks.page';
28-
import {
29-
SavingAndLoadingPage
30-
} from '../pages/examples/backend/saving-and-loading/saving-and-loading.page';
31-
import {
32-
UploadFilePage
33-
} from '../pages/examples/backend/upload-file/upload-file.page';
3415

3516
export const appRoutes: Route[] = [
3617
{ path: '', redirectTo: 'overview', pathMatch: 'full' },
@@ -44,31 +25,35 @@ export const appRoutes: Route[] = [
4425
{ path: 'basic/blocks-json', component: BlocksJsonPage },
4526
{
4627
path: 'basic/all-blocks',
47-
component: AllBlocksPage
28+
component: AllBlocksPage,
4829
},
4930
{
5031
path: 'basic/manipulating-blocks',
51-
component: ManipulatingBlocksPage
32+
component: ManipulatingBlocksPage,
5233
},
5334
{
5435
path: 'basic/removing-default-blocks',
55-
component: RemovingDefaultBlocksPage
36+
component: RemovingDefaultBlocksPage,
5637
},
5738
{ path: 'backend/saving-and-loading', component: SavingAndLoadingPage },
5839
{ path: 'backend/upload-files', component: UploadFilePage },
5940
{
6041
path: 'basic/selection-blocks',
61-
component: SelectionBlocksPage
42+
component: SelectionBlocksPage,
6243
},
6344
{
6445
path: 'custom/alert-block',
65-
component: AlertBlockPage
46+
component: AlertBlockPage,
47+
},
48+
{
49+
path: 'custom/api-content-block',
50+
component: ApiContentBlockPage,
6651
},
6752
{
6853
path: 'interoperability/convert-to-html',
69-
component: ConvertToHtmlPage
54+
component: ConvertToHtmlPage,
7055
},
71-
{ path: '**', redirectTo: 'overview' }
72-
]
73-
}
56+
{ path: '**', redirectTo: 'overview' },
57+
],
58+
},
7459
];
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
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+
} from '@dytab/block-note-angular';
16+
import { HlmButtonDirective } from '@spartan-ng/ui-button-helm';
17+
import { apiContentBlock } from './api-content-block';
18+
19+
const schema = BlockNoteSchema.create({
20+
blockSpecs: {
21+
...defaultBlockSpecs,
22+
apiContent: apiContentBlock,
23+
},
24+
inlineContentSpecs: { ...defaultInlineContentSpecs },
25+
styleSpecs: { ...defaultStyleSpecs },
26+
});
27+
@Component({
28+
selector: 'bna-api-content-block-example',
29+
standalone: true,
30+
imports: [CommonModule, BnaEditorComponent, HlmButtonDirective],
31+
template: `<bna-editor
32+
[initialContent]="initialContent"
33+
[options]="options"
34+
/>`,
35+
})
36+
export class ApiContentBlockExample {
37+
initialContent: PartialBlock<typeof schema.blockSchema>[] = [
38+
{
39+
type: 'apiContent',
40+
props: {},
41+
},
42+
];
43+
options: BlockNoteEditorOptionsType<
44+
typeof schema.blockSchema,
45+
typeof schema.inlineContentSchema,
46+
typeof schema.styleSchema
47+
> = {
48+
schema,
49+
};
50+
}
51+
52+
export const apiContentBlockExampleCode = `import { CommonModule } from '@angular/common';
53+
import { Component } from '@angular/core';
54+
import {
55+
BlockNoteEditor,
56+
BlockNoteSchema,
57+
defaultBlockSpecs,
58+
defaultInlineContentSpecs,
59+
defaultStyleSpecs,
60+
insertOrUpdateBlock,
61+
PartialBlock,
62+
} from '@blocknote/core';
63+
import {
64+
BlockNoteEditorOptionsType,
65+
BnaEditorComponent,
66+
} from '@dytab/block-note-angular';
67+
import { HlmButtonDirective } from '@spartan-ng/ui-button-helm';
68+
import { apiContentBlock } from './api-content-block';
69+
70+
const schema = BlockNoteSchema.create({
71+
blockSpecs: {
72+
...defaultBlockSpecs,
73+
alert: apiContentBlock,
74+
},
75+
inlineContentSpecs: { ...defaultInlineContentSpecs },
76+
styleSpecs: { ...defaultStyleSpecs },
77+
});
78+
@Component({
79+
selector: 'bna-alert-block-example',
80+
standalone: true,
81+
imports: [CommonModule, BnaEditorComponent, HlmButtonDirective],
82+
template: \`<bna-editor
83+
[initialContent]="initialContent"
84+
[options]="options"
85+
/>\`,
86+
})
87+
export class AlertBlockExample {
88+
initialContent: PartialBlock<typeof schema.blockSchema>[] = [
89+
{
90+
type: 'alert',
91+
props: {
92+
type: 'warning',
93+
},
94+
},
95+
];
96+
options: BlockNoteEditorOptionsType<
97+
typeof schema.blockSchema,
98+
typeof schema.inlineContentSchema,
99+
typeof schema.styleSchema
100+
> = {
101+
schema,
102+
inputSlashMenuItems: [
103+
(
104+
editor: BlockNoteEditor<
105+
typeof schema.blockSchema,
106+
typeof schema.inlineContentSchema,
107+
typeof schema.styleSchema
108+
>
109+
) => ({
110+
title: 'Alert',
111+
onItemClick: () => {
112+
insertOrUpdateBlock(editor, {
113+
type: 'alert' as never,
114+
});
115+
},
116+
badge: 'BAFD',
117+
subtext: 'SUBTEXT',
118+
aliases: [
119+
'alert',
120+
'notification',
121+
'emphasize',
122+
'warning',
123+
'error',
124+
'info',
125+
'success',
126+
],
127+
group: 'Other',
128+
}),
129+
],
130+
};
131+
}`;
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { CommonModule } from '@angular/common';
2+
import { Component } from '@angular/core';
3+
import { BnaEditorComponent } from '@dytab/block-note-angular';
4+
import { HlmButtonDirective } from '@spartan-ng/ui-button-helm';
5+
import { HlmTabsComponent } from '@spartan-ng/ui-tabs-helm';
6+
import { hlmP } from '@spartan-ng/ui-typography-helm';
7+
import { CodeComponent } from '../../../../shared/code/code.component';
8+
import { DemoBoxComponent } from '../../../../shared/layout/demo-box.component';
9+
import { TabsComponent } from '../../../../shared/layout/example-tabs.component';
10+
import { SectionIntroComponent } from '../../../../shared/layout/section-intro.component';
11+
import {
12+
ApiContentBlockExample,
13+
apiContentBlockExampleCode,
14+
} from './api-content-block.example';
15+
16+
@Component({
17+
standalone: true,
18+
imports: [
19+
CommonModule,
20+
BnaEditorComponent,
21+
HlmButtonDirective,
22+
SectionIntroComponent,
23+
CodeComponent,
24+
DemoBoxComponent,
25+
HlmTabsComponent,
26+
TabsComponent,
27+
ApiContentBlockExample,
28+
],
29+
template: `<bna-section-intro name="Api Content Block">
30+
<p class="${hlmP} mb-8">
31+
In this example, we create a custom block which is used to render
32+
content fetched by an api.
33+
</p>
34+
<ul class="list-disc">
35+
<li>Block can be configured</li>
36+
<li>Block content is fetched from api with configuration data</li>
37+
<li>Fetched Content is rendered</li>
38+
</ul>
39+
</bna-section-intro>
40+
<hlm-tabs tab="preview">
41+
<bna-example-tabs firstTab="Preview" secondTab="Code">
42+
<bna-demo-box firstTab>
43+
<bna-api-content-block-example />
44+
</bna-demo-box>
45+
<bna-code [code]="exampleCode" secondTab />
46+
</bna-example-tabs>
47+
</hlm-tabs>`,
48+
})
49+
export class ApiContentBlockPage {
50+
exampleCode = apiContentBlockExampleCode;
51+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import {
2+
BlockFromConfig,
3+
BlockNoteEditor,
4+
createBlockSpec,
5+
Props,
6+
PropSchema,
7+
} from '@blocknote/core';
8+
9+
export const apiContentPropSchema = {
10+
type: {
11+
default: 'abc',
12+
},
13+
} satisfies PropSchema;
14+
15+
export const apiContentBlockConfig = {
16+
type: 'apiContent' as const,
17+
propSchema: apiContentPropSchema,
18+
content: 'inline',
19+
} as const;
20+
21+
const apiContentRender = (
22+
block: BlockFromConfig<typeof apiContentBlockConfig, any, any>,
23+
editor: BlockNoteEditor<any, any, any>
24+
) => {
25+
const div = document.createElement('div');
26+
// Render content in div
27+
div.style.backgroundColor = '#BBB';
28+
div.style.width = '100%';
29+
div.style.padding = '4px 8px';
30+
div.style.borderRadius = '4px';
31+
div.innerHTML = 'Add rendered content';
32+
return {
33+
dom: div,
34+
};
35+
};
36+
37+
export const apiContentParse = (
38+
element: HTMLElement
39+
): Partial<Props<typeof apiContentBlockConfig.propSchema>> | undefined => {
40+
return undefined;
41+
};
42+
43+
export const apiContentBlock = createBlockSpec(apiContentBlockConfig, {
44+
render: apiContentRender,
45+
parse: apiContentParse,
46+
});

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

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,12 @@ import { HlmButtonDirective } from '@spartan-ng/ui-button-helm';
6767
class="justify-start"
6868
>Saving & Loading</a
6969
>
70-
<a hlmBtn variant="ghost" routerLink="backend/upload-files" class="justify-start"
71-
>Upload Files</a
70+
<a
71+
hlmBtn
72+
variant="ghost"
73+
routerLink="backend/upload-files"
74+
class="justify-start"
75+
>Upload Files</a
7276
>
7377
7478
Custom
@@ -79,7 +83,13 @@ import { HlmButtonDirective } from '@spartan-ng/ui-button-helm';
7983
routerLink="custom/alert-block"
8084
>Alert Block</a
8185
>
82-
86+
<a
87+
hlmBtn
88+
variant="ghost"
89+
class="justify-start"
90+
routerLink="custom/api-content-block"
91+
>Api Content Block</a
92+
>
8393
Interoperability
8494
<a
8595
hlmBtn

libs/ui/ui-tabs-helm/tsconfig.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,10 @@
2121
"strictTemplates": true
2222
}
2323
}
24+
25+
26+
/**
27+
* block sachen configuriert werden können
28+
* block eine "api" abruft und seinen block nachfragt und diesen dann renderts
29+
30+
**/

0 commit comments

Comments
 (0)