Skip to content

Commit 896157d

Browse files
committed
feat: add uploadFiles functionality and example
1 parent 4ee3bf7 commit 896157d

24 files changed

+676
-29
lines changed

docs/src/app/app.routes.ts

Lines changed: 40 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,36 @@
11
import { Route } from '@angular/router';
2-
import { SavingAndLoadingPage } from '../pages/examples/backend/saving-and-loading/saving-and-loading.page';
3-
import { AllBlocksPage } from '../pages/examples/basic/all-blocks/all-blocks.page';
4-
import { BasicSetupPage } from '../pages/examples/basic/basic-setup/basic-setup.page';
5-
import { BlocksJsonPage } from '../pages/examples/basic/blocks-json/blocks-json.page';
6-
import { ManipulatingBlocksPage } from '../pages/examples/basic/manipulating-blocks/manipulating-blocks.page';
7-
import { RemovingDefaultBlocksPage } from '../pages/examples/basic/removing-default-blocks/removing-default-blocks.page';
8-
import { SelectionBlocksPage } from '../pages/examples/basic/selection-blocks/selection-blocks.page';
9-
import { AlertBlockPage } from '../pages/examples/custom/alert-block/alert-block.page';
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';
1017
import { ExamplesPage } from '../pages/examples/examples.page';
11-
import { ConvertToHtmlPage } from '../pages/examples/interoperability/convert-to-html/convert-to-html.page';
18+
import {
19+
ConvertToHtmlPage
20+
} from '../pages/examples/interoperability/convert-to-html/convert-to-html.page';
1221
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';
1334

1435
export const appRoutes: Route[] = [
1536
{ path: '', redirectTo: 'overview', pathMatch: 'full' },
@@ -23,30 +44,31 @@ export const appRoutes: Route[] = [
2344
{ path: 'basic/blocks-json', component: BlocksJsonPage },
2445
{
2546
path: 'basic/all-blocks',
26-
component: AllBlocksPage,
47+
component: AllBlocksPage
2748
},
2849
{
2950
path: 'basic/manipulating-blocks',
30-
component: ManipulatingBlocksPage,
51+
component: ManipulatingBlocksPage
3152
},
3253
{
3354
path: 'basic/removing-default-blocks',
34-
component: RemovingDefaultBlocksPage,
55+
component: RemovingDefaultBlocksPage
3556
},
3657
{ path: 'backend/saving-and-loading', component: SavingAndLoadingPage },
58+
{ path: 'backend/upload-files', component: UploadFilePage },
3759
{
3860
path: 'basic/selection-blocks',
39-
component: SelectionBlocksPage,
61+
component: SelectionBlocksPage
4062
},
4163
{
4264
path: 'custom/alert-block',
43-
component: AlertBlockPage,
65+
component: AlertBlockPage
4466
},
4567
{
4668
path: 'interoperability/convert-to-html',
47-
component: ConvertToHtmlPage,
69+
component: ConvertToHtmlPage
4870
},
49-
{ path: '**', redirectTo: 'overview' },
50-
],
51-
},
71+
{ path: '**', redirectTo: 'overview' }
72+
]
73+
}
5274
];
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
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 { PartialBlock } from '@blocknote/core';
6+
7+
@Component({
8+
selector: 'bna-upload-file-example',
9+
standalone: true,
10+
imports: [CommonModule, BnaEditorComponent, HlmButtonDirective],
11+
template: `
12+
<bna-editor [initialContent]="initialContent" [options]="{uploadFile}" />
13+
`
14+
})
15+
export class UploadFileExample{
16+
initialContent: PartialBlock[] = [
17+
{
18+
type: "paragraph",
19+
content: "Welcome to this demo!",
20+
},
21+
{
22+
type: "paragraph",
23+
content: "Upload an image using the button below",
24+
},
25+
{
26+
type: "image",
27+
},
28+
{
29+
type: "paragraph",
30+
},
31+
];
32+
33+
// Uploads a file to tmpfiles.org and returns the URL to the uploaded file.
34+
async uploadFile(file: File) {
35+
const body = new FormData();
36+
body.append("file", file);
37+
38+
const ret = await fetch("https://tmpfiles.org/api/v1/upload", {
39+
method: "POST",
40+
body: body,
41+
});
42+
return (await ret.json()).data.url.replace(
43+
"tmpfiles.org/",
44+
"tmpfiles.org/dl/"
45+
);
46+
}
47+
}
48+
49+
export const uploadFileExampleCode = `import { CommonModule } from '@angular/common';
50+
import { Component } from '@angular/core';
51+
import { BnaEditorComponent } from '@dytab/block-note-angular';
52+
import { HlmButtonDirective } from '@spartan-ng/ui-button-helm';
53+
import { PartialBlock } from '@blocknote/core';
54+
55+
@Component({
56+
selector: 'bna-upload-file-example',
57+
standalone: true,
58+
imports: [CommonModule, BnaEditorComponent, HlmButtonDirective],
59+
template: \`
60+
<bna-editor [initialContent]="initialContent" [options]="{uploadFile}" />
61+
\`
62+
})
63+
export class UploadFileExample{
64+
initialContent: PartialBlock[] = [
65+
{
66+
type: "paragraph",
67+
content: "Welcome to this demo!",
68+
},
69+
{
70+
type: "paragraph",
71+
content: "Upload an image using the button below",
72+
},
73+
{
74+
type: "image",
75+
},
76+
{
77+
type: "paragraph",
78+
},
79+
];
80+
81+
// Uploads a file to tmpfiles.org and returns the URL to the uploaded file.
82+
async uploadFile(file: File) {
83+
const body = new FormData();
84+
body.append("file", file);
85+
86+
const ret = await fetch("https://tmpfiles.org/api/v1/upload", {
87+
method: "POST",
88+
body: body,
89+
});
90+
return (await ret.json()).data.url.replace(
91+
"tmpfiles.org/",
92+
"tmpfiles.org/dl/"
93+
);
94+
}
95+
}`;
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { CommonModule } from '@angular/common';
2+
import { Component } from '@angular/core';
3+
import {
4+
HlmTabsComponent,
5+
HlmTabsContentDirective,
6+
HlmTabsListComponent,
7+
HlmTabsTriggerDirective,
8+
} from '@spartan-ng/ui-tabs-helm';
9+
import { hlmP } from '@spartan-ng/ui-typography-helm';
10+
import { Highlight } from 'ngx-highlightjs';
11+
import { CodeComponent } from '../../../../shared/code/code.component';
12+
import { DemoBoxComponent } from '../../../../shared/layout/demo-box.component';
13+
import { TabsComponent } from '../../../../shared/layout/example-tabs.component';
14+
import { SectionIntroComponent } from '../../../../shared/layout/section-intro.component';
15+
import {
16+
UploadFileExample,
17+
uploadFileExampleCode,
18+
} from './upload-file.example';
19+
20+
@Component({
21+
standalone: true,
22+
imports: [
23+
CommonModule,
24+
SectionIntroComponent,
25+
DemoBoxComponent,
26+
HlmTabsComponent,
27+
HlmTabsListComponent,
28+
HlmTabsContentDirective,
29+
HlmTabsTriggerDirective,
30+
TabsComponent,
31+
CodeComponent,
32+
UploadFileExample,
33+
Highlight,
34+
],
35+
template: `
36+
<bna-section-intro name="Upload Files">
37+
<p class="${hlmP} mb-8">
38+
This example allows users to upload files and use them in the editor. The files are uploaded to /TMP/Files, and can be used for File, Image, Video, and Audio blocks.
39+
<br><br>
40+
<b>Try it out:</b> Click the "Add Image" button and see there's now an "Upload" tab in the toolbar!
41+
</p>
42+
</bna-section-intro>
43+
<hlm-tabs tab="preview">
44+
<bna-example-tabs firstTab="Preview" secondTab="Code">
45+
<bna-demo-box firstTab>
46+
<bna-upload-file-example />
47+
</bna-demo-box>
48+
<bna-code [code]="exampleCode" secondTab />
49+
</bna-example-tabs>
50+
</hlm-tabs>
51+
`,
52+
})
53+
export class UploadFilePage{
54+
exampleCode = uploadFileExampleCode;
55+
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ 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
72+
>
7073
7174
Custom
7275
<a

libs/block-note-angular/src/lib/block-note-editor/bna-editor.component.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
</bna-side-menu>
2626

2727
<bna-view [editor]="editor" class="block ProseMirror bn-editor relative bn-default-styles" />
28+
<bna-file-panel [editor]="editor" class="z-index-3">
29+
</bna-file-panel>
2830
<bna-suggestions-menu [editor]="editor" class="z-index-3">
2931
<hlm-menu class="shadow-3xl">
3032
<hlm-menu-label>Basic blocks</hlm-menu-label>

libs/block-note-angular/src/lib/block-note-editor/bna-editor.component.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,17 @@ import { BnaAddBlockButtonComponent } from '../components/bna-side-menu/default-
4040
import { BnaDragHandleMenuComponent } from '../components/bna-side-menu/default-buttons/drag-handle-menu/bna-drag-handle-menu.component';
4141
import { BnaSuggestionsMenuDirective } from '../components/bna-suggestions-menu/bna-suggestions-menu.directive';
4242
import { BnaViewDirective } from '../components/bna-view/bna-view.directive';
43-
import { BasicTextStyleButtonComponent } from '../components/buttons/basic-text-style-button/basic-text-style-button.component';
44-
import { TextAlignButtonComponent } from '../components/buttons/text-align-button/text-align-button.component';
43+
import {
44+
BasicTextStyleButtonComponent
45+
} from '../components/buttons/basic-text-style-button/basic-text-style-button.component';
46+
import {
47+
TextAlignButtonComponent
48+
} from '../components/buttons/text-align-button/text-align-button.component';
4549
import { BlockNoteEditorOptionsType } from '../interfaces/block-note-editor-options.type';
50+
import {
51+
BnaFilePanelComponent
52+
} from '../components/bna-file-panel/bna-file-panel.component';
53+
import { HlmInputDirective } from '@spartan-ng/ui-input-helm';
4654

4755
@Component({
4856
imports: [
@@ -64,6 +72,8 @@ import { BlockNoteEditorOptionsType } from '../interfaces/block-note-editor-opti
6472
HlmMenuShortcutComponent,
6573
HlmMenuItemSubIndicatorComponent,
6674
TextAlignButtonComponent,
75+
BnaFilePanelComponent,
76+
HlmInputDirective
6777
],
6878
selector: 'bna-editor',
6979
standalone: true,
@@ -117,6 +127,7 @@ export class BnaEditorComponent<
117127
//TODO: remove casting
118128
}) as unknown as BlockNoteSchema<BSchema, ISchema, SSchema>),
119129
initialContent: initialContent,
130+
uploadFile: this.options?.uploadFile
120131
});
121132
this.onEditorReady.emit(this.editor);
122133
this.slashMenuItems = this.getSlashMenuItems(this.editor);
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<div class="bg-white">
2+
<input class="w-80" hlmInput type="file" (input)="onFileInput($event)" />
3+
<!-- <input class="w-80" hlmInput [(ngModel)]="embedInputText" type="text" />-->
4+
<!-- <button hlmBtn (click)="insertEmbed()" >Embed Image</button>-->
5+
</div>

0 commit comments

Comments
 (0)