@ng-vui/editor
v1.0.0
Published
Angular Rich Text Editor Component for NG VUI Library
Maintainers
Readme
@ng-vui/editor
A powerful, feature-rich WYSIWYG editor component for Angular 20+ with advanced formatting tools, media support, and modern standalone architecture.
🚀 Features
- ✅ Standalone Component - Modern Angular 20+ standalone architecture
- ✅ Rich Text Editing - Bold, italic, underline, strikethrough, lists, alignment
- ✅ Advanced Formatting - Headers, text colors, highlights, font sizes
- ✅ Media Management - Image upload, resize, and storage service
- ✅ Link Management - Create, edit, and remove hyperlinks
- ✅ Table Support - Insert and format tables
- ✅ Code Blocks - Syntax highlighting for code
- ✅ Undo/Redo - Full history management
- ✅ Customizable Toolbar - Configure available tools
- ✅ HTML Output - Clean, semantic HTML output
- ✅ Reactive Forms - Full Angular Forms integration (ngModel, FormControl)
- ✅ TypeScript - Complete type safety and IntelliSense
- ✅ Responsive Design - Mobile-friendly interface
📦 Installation
npm install @ng-vui/editorPeer Dependencies:
- Angular 14+ (
@angular/core,@angular/common,@angular/forms) - TypeScript 4.7+
🏗️ Architecture
Built with modern Angular patterns:
- Standalone Component - No NgModules required
- Media Storage Service - Configurable media upload and management
- Type Safety - Full TypeScript interfaces and types
- Reactive Forms - Complete Angular Forms integration
🎯 Basic Usage
Simple Implementation
import { NgVuiEditorComponent, MediaStorageService } from '@ng-vui/editor';
@Component({
selector: 'app-example',
standalone: true,
imports: [NgVuiEditorComponent, FormsModule],
template: `
<ng-vui-editor
[(ngModel)]="content"
[placeholder]="'Start typing...'"
[readonly]="false"
(contentChange)="onContentChange($event)"
(mediaUpload)="onMediaUpload($event)">
</ng-vui-editor>
`
})
export class EditorExampleComponent {
content = '<p>Welcome to the rich text editor!</p>';
onContentChange(newContent: string) {
console.log('Content changed:', newContent);
}
onMediaUpload(event: any) {
console.log('Media uploaded:', event);
}
}With Reactive Forms
import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
@Component({
standalone: true,
imports: [NgVuiEditorComponent, ReactiveFormsModule],
template: `
<form [formGroup]="editorForm">
<ng-vui-editor formControlName="content">
</ng-vui-editor>
</form>
`
})
export class ReactiveFormExample {
editorForm = new FormGroup({
content: new FormControl('<p>Default content</p>')
});
}Media Storage Configuration
import { MediaStorageService, MediaUploadResult } from '@ng-vui/editor';
@Injectable()
export class CustomMediaStorage implements MediaStorageService {
async uploadMedia(file: File): Promise<MediaUploadResult> {
// Your custom upload logic
const formData = new FormData();
formData.append('file', file);
const response = await fetch('/api/upload', {
method: 'POST',
body: formData
});
const result = await response.json();
return {
url: result.url,
alt: file.name,
width: result.width,
height: result.height
};
}
async deleteMedia(url: string): Promise<boolean> {
// Your custom delete logic
return true;
}
}🔧 API Reference
NgVuiEditorComponent
Inputs
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| placeholder | string | 'Enter text...' | Placeholder text when editor is empty |
| readonly | boolean | false | Makes the editor read-only |
| height | string | '300px' | Fixed height for editor content area |
| maxLength | number | undefined | Maximum character limit |
Outputs
| Event | Type | Description |
|-------|------|-------------|
| contentChange | string | Emitted when content changes |
| mediaUpload | MediaUploadResult | Emitted when media is uploaded |
| focus | void | Emitted when editor gains focus |
| blur | void | Emitted when editor loses focus |
Methods
| Method | Description |
|--------|-------------|
| getContent() | Returns current HTML content |
| setContent(html: string) | Sets HTML content |
| insertHTML(html: string) | Inserts HTML at cursor position |
| focus() | Focuses the editor |
| clear() | Clears all content |
MediaStorageService Interface
interface MediaStorageService {
uploadMedia(file: File): Promise<MediaUploadResult>;
deleteMedia(url: string): Promise<boolean>;
}
interface MediaUploadResult {
url: string;
alt?: string;
width?: number;
height?: number;
}🎨 Styling & Theming
The editor uses Tailwind CSS classes by default. You can customize the appearance by overriding CSS classes:
/* Custom editor styling */
.ng-vui-editor {
--editor-border: #e5e7eb;
--editor-bg: #ffffff;
--toolbar-bg: #f9fafb;
--button-hover: #e5e7eb;
}
.ng-vui-editor .toolbar {
background: var(--toolbar-bg);
}
.ng-vui-editor .content-area {
background: var(--editor-bg);
border-color: var(--editor-border);
}🧪 Testing
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { NgVuiEditorComponent } from '@ng-vui/editor';
describe('NgVuiEditorComponent', () => {
let component: NgVuiEditorComponent;
let fixture: ComponentFixture<NgVuiEditorComponent>;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [NgVuiEditorComponent]
});
fixture = TestBed.createComponent(NgVuiEditorComponent);
component = fixture.componentInstance;
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should update content', () => {
const testContent = '<p>Test content</p>';
component.setContent(testContent);
expect(component.getContent()).toContain('Test content');
});
});🤝 Contributing
- Fork the repository
- Create a feature branch:
git checkout -b feature/my-feature - Commit changes:
git commit -am 'Add my feature' - Push to branch:
git push origin feature/my-feature - Submit a pull request
📄 License
MIT © VUI
🔗 Related Packages
@ng-vui/ng-vui-grid- Advanced data grid component@ng-vui/text-input- Text input component@ng-vui/textarea- Textarea component@ng-vui/select-input- Select dropdown component@ng-vui/multi-select- Multi-select dropdown@ng-vui/date-picker- Date picker component
