Skip to content

Commit 89b8307

Browse files
committed
feat: add api content configuration dialog
1 parent d797f97 commit 89b8307

21 files changed

+1247
-971
lines changed

docs/src/pages/examples/custom/alert-block/alert-block.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@ const alertRender = (
7979
div.style.display = 'flex';
8080
div.style.alignItems = 'center';
8181
const alertType = alertTypes.find((type) => type.value === block.props.type);
82-
console.log(block, alertType);
8382
if (!alertType) {
8483
return {
8584
dom: div,
Lines changed: 147 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -1,131 +1,183 @@
11
import { CommonModule } from '@angular/common';
2-
import { Component } from '@angular/core';
2+
import { Component, inject, Input } from '@angular/core';
33
import {
4+
Block,
45
BlockNoteEditor,
5-
BlockNoteSchema,
6+
BlockNoteSchema, BlockSchemaFromSpecs,
7+
DefaultBlockSchema,
68
defaultBlockSpecs,
9+
DefaultInlineContentSchema,
710
defaultInlineContentSpecs,
8-
defaultStyleSpecs,
9-
insertOrUpdateBlock,
10-
PartialBlock,
11+
DefaultStyleSchema,
12+
defaultStyleSpecs, InlineContentSchema,
13+
PartialBlock, StyleSchema, TiptapBlockImplementation
1114
} from '@blocknote/core';
1215
import {
16+
BlockNoteAngularService,
1317
BlockNoteEditorOptionsType,
18+
BnaAddBlockButtonComponent,
19+
BnaDeleteBlockItemComponent,
20+
BnaDragHandleMenuComponent,
1421
BnaEditorComponent,
22+
BnaSideMenuComponent,
23+
BnaSideMenuControllerDirective,
1524
HlmButtonDirective,
25+
HlmCheckboxComponent,
26+
HlmDialogComponent,
27+
HlmDialogContentComponent,
28+
HlmDialogFooterComponent,
29+
HlmDialogHeaderComponent, HlmInputDirective
1630
} from '@dytab/block-note-angular';
1731
import { apiContentBlock } from './api-content-block';
32+
import {
33+
ResetBlockButtonComponent
34+
} from '../../ui-components/adding-side-menu-drag-handle-items/reset-block-button.component';
35+
import {
36+
BrnDialogContentDirective,
37+
BrnDialogDescriptionDirective,
38+
BrnDialogRef,
39+
BrnDialogTitleDirective,
40+
BrnDialogTriggerDirective
41+
} from '@spartan-ng/ui-dialog-brain';
42+
import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
1843

1944
const schema = BlockNoteSchema.create({
2045
blockSpecs: {
2146
...defaultBlockSpecs,
22-
apiContent: apiContentBlock,
47+
apiContent: apiContentBlock
2348
},
2449
inlineContentSpecs: { ...defaultInlineContentSpecs },
25-
styleSpecs: { ...defaultStyleSpecs },
50+
styleSpecs: { ...defaultStyleSpecs }
2651
});
52+
2753
@Component({
2854
selector: 'bna-api-content-block-example',
2955
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-
}
56+
imports: [
57+
CommonModule,
58+
BnaEditorComponent,
59+
HlmButtonDirective,
60+
BnaAddBlockButtonComponent,
61+
BnaDeleteBlockItemComponent,
62+
BnaDragHandleMenuComponent,
63+
BnaSideMenuComponent,
64+
BnaSideMenuControllerDirective,
65+
ResetBlockButtonComponent,
66+
HlmDialogComponent,
67+
HlmDialogContentComponent,
68+
BrnDialogContentDirective,
69+
HlmDialogHeaderComponent,
70+
BrnDialogTitleDirective,
71+
BrnDialogDescriptionDirective,
72+
BrnDialogTriggerDirective,
73+
HlmDialogFooterComponent,
74+
HlmCheckboxComponent,
75+
ReactiveFormsModule,
76+
HlmInputDirective
77+
],
78+
providers: [BlockNoteAngularService],
79+
template: `
80+
<bna-editor
81+
[initialContent]="initialContent"
82+
[options]="options"
83+
(onEditorReady)="onEditorReady($event)"
84+
>
85+
<bna-side-menu-controller>
86+
<bna-side-menu>
87+
<bna-add-block-btn />
88+
<bna-drag-handle-menu-btn>
89+
<hlm-dialog>
90+
<button
91+
hlmBtn
92+
brnDialogTrigger
93+
variant="ghost"
94+
size="sm"
95+
class="justify-start w-full"
96+
>
97+
Configure Block
98+
</button>
99+
<hlm-dialog-content *brnDialogContent="let ctx">
100+
<form [formGroup]="formGroup" (ngSubmit)="updateBlockConfiguration(); ctx.close()">
51101
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 '@dytab/block-note-angular';
68-
import { apiContentBlock } from './api-content-block';
102+
<hlm-dialog-header>
103+
<h3 brnDialogTitle hlm>Configure Block</h3>
104+
<p brnDialogDescription hlm>Toggle which content which should
105+
be rendered</p>
69106
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-
/>\`,
107+
<label class="flex items-center" hlmLabel>
108+
Name:
109+
<input hlmInput [size]="'sm'" formControlName="name" class="mr-2" />
110+
</label>
111+
<label class="flex items-center" hlmLabel>
112+
<hlm-checkbox formControlName="age" class="mr-2" />
113+
Age
114+
</label>
115+
<label class="flex items-center" hlmLabel>
116+
<hlm-checkbox formControlName="address" class="mr-2" />
117+
Address
118+
</label>
119+
</hlm-dialog-header>
120+
<hlm-dialog-footer>
121+
<button hlmBtn type="submit" >Save changes
122+
</button>
123+
</hlm-dialog-footer>
124+
</form>
125+
</hlm-dialog-content>
126+
</hlm-dialog>
127+
</bna-drag-handle-menu-btn>
128+
</bna-side-menu
129+
>
130+
</bna-side-menu-controller>
131+
</bna-editor>
132+
`
86133
})
87-
export class AlertBlockExample {
134+
135+
export class ApiContentBlockExample{
136+
@Input() block?: Block<any, any, any>;
137+
@Input() editor?: BlockNoteEditor<typeof schema.blockSchema>;
138+
139+
formGroup = new FormGroup({
140+
name: new FormControl(this.block?.props.name),
141+
age: new FormControl(this.block?.props.age),
142+
address: new FormControl(this.block?.props.address)
143+
});
144+
88145
initialContent: PartialBlock<typeof schema.blockSchema>[] = [
89146
{
90-
type: 'alert',
147+
type: 'apiContent',
91148
props: {
92-
type: 'warning',
93-
},
149+
name: 'Max Mustermann',
150+
age: true
151+
}
94152
},
153+
{
154+
type: 'apiContent',
155+
}
95156
];
96157
options: BlockNoteEditorOptionsType<
97158
typeof schema.blockSchema,
98159
typeof schema.inlineContentSchema,
99160
typeof schema.styleSchema
100161
> = {
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-
],
162+
schema
130163
};
131-
}`;
164+
165+
updateBlockConfiguration(){
166+
if(!this.block || !this.editor) return
167+
168+
const formValues = this.formGroup.value;
169+
this.editor.updateBlock(this.block, {
170+
props: { ...formValues }
171+
})
172+
}
173+
174+
onEditorReady(editor: BlockNoteEditor<typeof schema.blockSchema>){
175+
this.editor = editor;
176+
this.editor.sideMenu.onUpdate((state) => {
177+
this.block = state.block;
178+
this.formGroup.patchValue(this.block?.props);
179+
});
180+
}
181+
}
182+
183+
export const apiContentBlockExampleCode = ``;

docs/src/pages/examples/custom/api-content-block/api-content-block.page.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {
44
BnaEditorComponent,
55
HlmButtonDirective,
66
hlmP,
7-
HlmTabsComponent,
7+
HlmTabsComponent
88
} from '@dytab/block-note-angular';
99
import { CodeComponent } from '../../../../shared/code/code.component';
1010
import { DemoBoxComponent } from '../../../../shared/layout/demo-box.component';

docs/src/pages/examples/custom/api-content-block/api-content-block.ts

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,19 @@ import {
33
BlockNoteEditor,
44
createBlockSpec,
55
Props,
6-
PropSchema,
76
} from '@blocknote/core';
87

98
export const apiContentPropSchema = {
10-
type: {
11-
default: 'abc',
9+
name: {
10+
default: '',
1211
},
13-
} satisfies PropSchema;
12+
age: {
13+
default: false,
14+
},
15+
address: {
16+
default: false,
17+
}
18+
};
1419

1520
export const apiContentBlockConfig = {
1621
type: 'apiContent' as const,
@@ -28,7 +33,29 @@ const apiContentRender = (
2833
div.style.width = '100%';
2934
div.style.padding = '4px 8px';
3035
div.style.borderRadius = '4px';
31-
div.innerHTML = 'Add rendered content';
36+
div.innerHTML = 'Content not configured';
37+
38+
const data = {
39+
name : 'Max Musetrmann',
40+
age : 25,
41+
address : '123 Main St'
42+
}
43+
44+
let dataString = ''
45+
for (const [key,value] of Object.entries(block.props)){
46+
if (value) {
47+
if(key === 'name'){
48+
dataString += `<p>${value}</p>`;
49+
continue;
50+
}
51+
// @ts-ignore
52+
const asdf = data[key] as number | string
53+
dataString += `<p>${asdf}</p>`;
54+
}
55+
}
56+
if(dataString.length > 0)
57+
div.innerHTML = dataString;
58+
3259
return {
3360
dom: div,
3461
};

libs/block-note-angular/src/lib/components/bna-side-menu/default-buttons/drag-handle-menu/bna-drag-handle-menu.component.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,6 @@ export class BnaDragHandleMenuComponent {
9191
selectedBlocks = [this.dragBlock];
9292
}
9393
this.selectedBlocks = selectedBlocks;
94-
console.log('Open drag menu', this.selectedBlocks);
9594
this.dragMenuShown = !this.dragMenuShown;
9695
if (this.dragMenuShown) {
9796
editor.sideMenu.freezeMenu();

libs/block-note-angular/src/lib/ui/index.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,14 @@ export * from './ui-typography-helm/hlm-muted.directive';
4343
export * from './ui-typography-helm/hlm-p.directive';
4444
export * from './ui-typography-helm/hlm-small.directive';
4545
export * from './ui-typography-helm/hlm-ul.directive';
46+
export * from './ui-dialog-helm/hlm-dialog-close.directive';
47+
export * from './ui-dialog-helm/hlm-dialog-content.component';
48+
export * from './ui-dialog-helm/hlm-dialog-description.directive';
49+
export * from './ui-dialog-helm/hlm-dialog-footer.component';
50+
export * from './ui-dialog-helm/hlm-dialog-header.component';
51+
export * from './ui-dialog-helm/hlm-dialog-overlay.directive';
52+
export * from './ui-dialog-helm/hlm-dialog-title.directive';
53+
export * from './ui-dialog-helm/hlm-dialog.component';
54+
export * from './ui-dialog-helm/hlm-dialog.service';
55+
export * from './ui-checkbox-helm/hlm-checkbox-checkicon.component';
56+
export * from './ui-checkbox-helm/hlm-checkbox.component';

0 commit comments

Comments
 (0)