From fc9506058d2aa658e82db88f4313ae262ce035bb Mon Sep 17 00:00:00 2001 From: Artur Quirino Date: Sat, 11 Apr 2026 09:01:39 -0300 Subject: [PATCH 1/3] docs: uptade Angular example to use modern angular features, like input and viewChild signals --- .../getting-started/frameworks/angular.mdx | 62 ++++++++++--------- 1 file changed, 33 insertions(+), 29 deletions(-) diff --git a/apps/docs/getting-started/frameworks/angular.mdx b/apps/docs/getting-started/frameworks/angular.mdx index 9facafb7ee..f0e9655909 100644 --- a/apps/docs/getting-started/frameworks/angular.mdx +++ b/apps/docs/getting-started/frameworks/angular.mdx @@ -15,7 +15,7 @@ npm install superdoc ## Basic setup ```typescript -import { Component, ElementRef, ViewChild, OnInit, OnDestroy } from '@angular/core'; +import { Component, ElementRef, viewChild, AfterViewInit, inject, DestroyRef } from '@angular/core'; import { SuperDoc } from 'superdoc'; import 'superdoc/style.css'; @@ -23,21 +23,21 @@ import 'superdoc/style.css'; selector: 'app-editor', template: `
`, }) -export class EditorComponent implements OnInit, OnDestroy { - @ViewChild('editor', { static: true }) editorRef!: ElementRef; +export class EditorComponent implements AfterViewInit { + private readonly editorRef = viewChild.required('editor'); private superdoc: SuperDoc | null = null; - ngOnInit() { + constructor() { + inject(DestroyRef).onDestroy(() => this.superdoc?.destroy()); + } + + ngAfterViewInit() { this.superdoc = new SuperDoc({ - selector: this.editorRef.nativeElement, + selector: this.editorRef().nativeElement, document: 'contract.docx', documentMode: 'editing', }); } - - ngOnDestroy() { - this.superdoc?.destroy(); - } } ``` @@ -46,7 +46,7 @@ export class EditorComponent implements OnInit, OnDestroy { A reusable editor component with mode switching and export: ```typescript -import { Component, ElementRef, ViewChild, Input, OnInit, OnDestroy } from '@angular/core'; +import { Component, ElementRef, viewChild, input, AfterViewInit, inject, DestroyRef } from '@angular/core'; import { SuperDoc } from 'superdoc'; import 'superdoc/style.css'; @@ -62,27 +62,27 @@ import 'superdoc/style.css';
`, }) -export class DocEditorComponent implements OnInit, OnDestroy { - @ViewChild('editor', { static: true }) editorRef!: ElementRef; - @Input() document!: File | string; - @Input() user?: { name: string; email: string }; +export class DocEditorComponent implements AfterViewInit { + private readonly editorRef = viewChild.required('editor'); + readonly document = input.required(); + readonly user = input<{ name: string; email: string }>(); private superdoc: SuperDoc | null = null; - ngOnInit() { + constructor() { + inject(DestroyRef).onDestroy(() => this.superdoc?.destroy()); + } + + ngAfterViewInit() { this.superdoc = new SuperDoc({ - selector: this.editorRef.nativeElement, - document: this.document, + selector: this.editorRef().nativeElement, + document: this.document(), documentMode: 'editing', - user: this.user, + user: this.user(), onReady: () => console.log('Editor ready'), }); } - ngOnDestroy() { - this.superdoc?.destroy(); - } - setMode(mode: 'editing' | 'viewing' | 'suggesting') { this.superdoc?.setDocumentMode(mode); } @@ -96,6 +96,10 @@ export class DocEditorComponent implements OnInit, OnDestroy { ## Handle file uploads ```typescript +import { Component, ElementRef, viewChild, inject, DestroyRef } from '@angular/core'; +import { SuperDoc } from 'superdoc'; +import 'superdoc/style.css'; + @Component({ selector: 'app-upload-editor', template: ` @@ -103,25 +107,25 @@ export class DocEditorComponent implements OnInit, OnDestroy {
`, }) -export class UploadEditorComponent implements OnDestroy { - @ViewChild('editor', { static: true }) editorRef!: ElementRef; +export class UploadEditorComponent { + private readonly editorRef = viewChild.required('editor'); private superdoc: SuperDoc | null = null; + constructor() { + inject(DestroyRef).onDestroy(() => this.superdoc?.destroy()); + } + onFileChange(event: Event) { const file = (event.target as HTMLInputElement).files?.[0]; if (!file) return; this.superdoc?.destroy(); this.superdoc = new SuperDoc({ - selector: this.editorRef.nativeElement, + selector: this.editorRef().nativeElement, document: file, documentMode: 'editing', }); } - - ngOnDestroy() { - this.superdoc?.destroy(); - } } ``` From 753f2a7e004be6cd4c5b4f43c45a1e74f4d407c9 Mon Sep 17 00:00:00 2001 From: Artur Quirino Date: Tue, 14 Apr 2026 08:22:40 -0300 Subject: [PATCH 2/3] docs: update Angular documentation to instruct how to use in version prior to 17.1 --- apps/docs/getting-started/frameworks/angular.mdx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/docs/getting-started/frameworks/angular.mdx b/apps/docs/getting-started/frameworks/angular.mdx index f0e9655909..cc3103a0d6 100644 --- a/apps/docs/getting-started/frameworks/angular.mdx +++ b/apps/docs/getting-started/frameworks/angular.mdx @@ -6,6 +6,8 @@ keywords: "angular docx editor, angular word component, superdoc angular, angula SuperDoc works with Angular through direct DOM manipulation. No wrapper needed. +Examples use signal-based APIs (`viewChild()`, `input()`) introduced in Angular 17.1. For older Angular versions, swap to the decorator-based equivalents (`@ViewChild`, `@Input`). + ## Install ```bash @@ -24,7 +26,7 @@ import 'superdoc/style.css'; template: `
`, }) export class EditorComponent implements AfterViewInit { - private readonly editorRef = viewChild.required('editor'); + private readonly editorRef = viewChild.required>('editor'); private superdoc: SuperDoc | null = null; constructor() { @@ -63,7 +65,7 @@ import 'superdoc/style.css'; `, }) export class DocEditorComponent implements AfterViewInit { - private readonly editorRef = viewChild.required('editor'); + private readonly editorRef = viewChild.required>('editor'); readonly document = input.required(); readonly user = input<{ name: string; email: string }>(); @@ -108,7 +110,7 @@ import 'superdoc/style.css'; `, }) export class UploadEditorComponent { - private readonly editorRef = viewChild.required('editor'); + private readonly editorRef = viewChild.required>('editor'); private superdoc: SuperDoc | null = null; constructor() { From a5f54a7527155d07ecc3dafae21628a870f1ac89 Mon Sep 17 00:00:00 2001 From: Caio Pizzol Date: Mon, 20 Apr 2026 13:45:03 -0300 Subject: [PATCH 3/3] docs(angular): correct signal-API version requirements viewChild() landed in 17.2 (not 17.1) and is stable only from Angular 19; input() is 17.1+ and stable from 19. Verified via tsc against @angular/core@17.1.0: 'has no exported member named viewChild'. Also aligns onReady log string with React/Vue docs. --- apps/docs/getting-started/frameworks/angular.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/docs/getting-started/frameworks/angular.mdx b/apps/docs/getting-started/frameworks/angular.mdx index cc3103a0d6..3395a0e6e7 100644 --- a/apps/docs/getting-started/frameworks/angular.mdx +++ b/apps/docs/getting-started/frameworks/angular.mdx @@ -6,7 +6,7 @@ keywords: "angular docx editor, angular word component, superdoc angular, angula SuperDoc works with Angular through direct DOM manipulation. No wrapper needed. -Examples use signal-based APIs (`viewChild()`, `input()`) introduced in Angular 17.1. For older Angular versions, swap to the decorator-based equivalents (`@ViewChild`, `@Input`). +Requires Angular 17.2+. `viewChild()` and `input()` are stable from Angular 19; developer preview before that. On older versions, use `@ViewChild`, `@Input`, and `ngOnDestroy` in place of `inject(DestroyRef)`. ## Install @@ -81,7 +81,7 @@ export class DocEditorComponent implements AfterViewInit { document: this.document(), documentMode: 'editing', user: this.user(), - onReady: () => console.log('Editor ready'), + onReady: () => console.log('Editor ready!'), }); }