@sunku/email-builder
v0.2.4
Published
Drag-and-drop email template editor for Angular, packaged as a standalone component. Builds responsive, email-client-safe HTML.
Downloads
649
Maintainers
Readme
@sunku/email-builder
Drag-and-drop email template editor for Angular, packaged as a standalone component. Builds responsive, email-client-safe HTML.
Installation
npm install @sunku/email-builder --savePeer dependencies: @angular/core, @angular/common, @angular/cdk,
@angular/forms, @angular/platform-browser, rxjs.
The editor uses HttpClient, so your app needs provideHttpClient().
Usage
Import the standalone component and drop it in. No global stylesheet to wire up, no setup call — the component registers its blocks and injects its own styles.
import { Component, ViewChild } from '@angular/core';
import { EmailBuilderComponent, Template } from '@sunku/email-builder';
@Component({
selector: 'app-root',
standalone: true,
imports: [EmailBuilderComponent],
template: `
<button (click)="exportHtml()">Export</button>
<sunku-email-builder
[design]="design"
minHeight="100vh"
(ready)="onReady()"
(designChange)="onDesignChange($event)">
</sunku-email-builder>
`,
})
export class AppComponent {
design: Template | null = null;
@ViewChild(EmailBuilderComponent)
private editor!: EmailBuilderComponent;
onReady() {
// The editor is initialised. Load a saved design at any point:
// this.editor.loadDesign(savedJsonOrTemplate);
}
onDesignChange(design: Template) {
// Fires on every edit — debounce before persisting.
}
exportHtml() {
const { html, design } = this.editor.exportHtml();
console.log(html, design);
}
}Using an NgModule instead of standalone components? Add EmailBuilderComponent
to that module's imports — standalone components are importable from modules.
Inputs
| Input | Type | Default | Description |
| --- | --- | --- | --- |
| design | Template \| string \| null | null | Design to load, as an object or JSON string. Reassigning reloads the editor. Unset starts blank. |
| minHeight | string | '600px' | Smallest height the editor may occupy. Grows if the parent is taller; pass 100vh for a full-page editor. |
Outputs
| Output | Payload | Description |
| --- | --- | --- |
| ready | — | Editor initialised and first design loaded. |
| designChange | Template | Fires on every edit. Debounce it for autosave. |
Methods
Access them through @ViewChild(EmailBuilderComponent).
| Method | Params | Description |
| --- | --- | --- |
| loadDesign | Template \| string | Replaces the current design. |
| saveDesign | callback? | Returns the design; also passes it to the callback. |
| saveDesignJson | — | Returns the design serialised to JSON. |
| exportHtml | callback? | Returns { html, design }; also passes it to the callback. |
| newDesign | name? | Starts a blank template. |
Image search (optional)
The sidebar's image search needs a free Pixabay API key. No key ships with the package — without one, that tab shows setup instructions instead of search results.
import { PIXABAY_API_KEY } from '@sunku/email-builder';
providers: [{ provide: PIXABAY_API_KEY, useValue: 'your-key' }]Going lower-level
EmailBuilderComponent is a thin facade. For full control, use
EditorShellComponent (the bare UI) and drive it through the exported services,
all providedIn: 'root':
EditorEngineService—newTemplate(),loadTemplate(),loadFromJson(), block/row operations, undo/redo, logo versions.EditorStore.template()— the current template as a signal.RenderEngineService.render(template)— the final email HTML.TemplateEngineService.serialize()/.deserialize()— JSON import/export.
Development
Build the library from this repo:
ng build email-builderOutput goes to dist/email-builder. For a local link during development, point
the consuming project at it:
"@sunku/email-builder": "file:../snap-email-builder/dist/email-builder"Re-run the build after changes for the link to pick them up.
Running unit tests
ng test email-builderLicense
MIT
