npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@h-k-dev/angular-email-editor

v0.3.1

Published

An email editor for Angular on ProseMirror — a visual composer and an HTML source editor over one schema that is the vocabulary of email HTML.

Readme

Angular Email Editor

npm version license

An email editor for Angular, built on ProseMirror: a visual composer and an HTML source editor over one schema that is the vocabulary of email HTML — what Gmail, Outlook and Apple Mail apply survives, nothing else is emitted. Headless where it can be: you own the markup and the pixels; the library brings the engine, the behaviour and accessible building blocks.

Try the live demo →

Pre-1.0. The API still moves between 0.x versions; releases are deliberate, not per commit. Pin a version and read the release notes before upgrading.

What you get

  • Email-safe by construction — markup is parsed into the email vocabulary and re-emitted deterministically: inline styles, <div> lines, tables that render in Outlook. Builder exports (MJML) keep their structure; pasted Word/Docs markup is cleaned.
  • Corrects what other editors stored — opening HTML saved by WYSIWYG editors such as Summernote repairs mailto:// links, http://{{placeholder}} links, Word's <o:p>, Bootstrap-only table borders and formatting wrapped around block lines, without losing the author's intent.
  • Two editors, one document — the visual composer and an HTML source pane (highlighting, lint, formatter) run the same commands over the same schema.
  • Placeholders — {{ expression }} tokens as merge-tag pills, an optional AngularJS expression dialect with live syntax diagnostics, and placeholder filling (createMergeTagResolution, Ctrl/⌘+Shift+Enter): your evaluator gets each expression raw, the values go back in as text, in one undo step.
  • Compose workflow — reply/forward seeds with localized labels, quoted history kept beside the body, inline images (cid:), a send intent with text/plain alternative.
  • Address fields that implement the RFCs — RFC 5322/5321/6531 parsing and formatting behind a pluggable rule, chips, signal-forms validation, placeholders as pending (not invalid) addresses, and an Angular Material form-field adapter.
  • Attachment chips with upload stages (Uppy/tus vocabulary) and progress.

Installation

npm install @h-k-dev/angular-email-editor prosemirror-commands prosemirror-gapcursor prosemirror-history prosemirror-inputrules prosemirror-keymap prosemirror-model prosemirror-schema-list prosemirror-state prosemirror-tables prosemirror-transform prosemirror-view

Requires Angular 22. The ProseMirror packages are peers so your app holds exactly one copy of each.

| Optional peer | Needed for | | --- | --- | | @angular/forms | /address-input, /attachment-chips, /toggle-button-group (signal-forms controls) | | @angular/material, rxjs | /material (the mat-form-field adapter) | | @chenglou/pretext ^1.0.0 | /metrics (word, line and height metrics) |

Quick start

import { Component, DestroyRef, ElementRef, afterNextRender, inject, signal, viewChild } from '@angular/core';
import { Editor, createEditor, emailExtensions } from '@h-k-dev/angular-email-editor';

@Component({
  selector: 'app-mail-body',
  template: `<div #host></div>`,
})
export class MailBody {
  readonly html = signal('<div>Hello</div>');
  private readonly host = viewChild.required<ElementRef<HTMLElement>>('host');
  #editor?: Editor;

  constructor() {
    afterNextRender(() => {
      this.#editor = createEditor({
        parent: this.host().nativeElement,
        extensions: emailExtensions,
        content: this.html(),
        onUpdate: (editor) => this.html.set(editor.getHTML()),
      });
    });
    inject(DestroyRef).onDestroy(() => this.#editor?.destroy());
  }
}

emailExtensions is the full email kit; add extensions next to it (createSendIntent, createMergeTagResolution, createSuggestionMenu, …) or build a kit of your own.

Entry points

Every UI piece is its own secondary entry point, so you only bundle what you import.

| Import | What it is | | --- | --- | | @h-k-dev/angular-email-editor | The engine: createEditor, kits, schema, HTML parse/serialize, extensions | | …/actions | Editor actions as signals — injectActions, [emailAction] for your own buttons; editorModel and the typed sectionPaddingModel · columnSpacingModel · pageLayoutModel · sectionBackgroundModel — what the document says as a writable signal, a model for signal forms; atRest — a value as typing settles | | …/address | The address rule (RFC 5322/5321/6531): parse, format, split, join, ADDRESS_RULES | | …/address-input | The address field: chips, FormValueControl<string[]>, addressList validator | | …/address-chip | One address chip | | …/attachment-chips | The attachment strip, a FormValueControl over the list | | …/attachment-chip | One attachment chip with upload stages and progress | | …/toggle-button-group | <hk-tgb> with hkTgbIcon (round) and hkTgbText (pill) items on any element, a sliding thumb, a FormValueControl | | …/split-button | <hk-split-button> with hkSplitButtonLeading / hkSplitButtonTrailing on the host's own buttons: an icon button that grows into a Material 3 split button (split) | | …/suggestion-menu | The / and {{ menus' floating box, with roles and ids | | …/palette | The colour palette (readable on light and dark) | | …/proposal | A streamed proposal's state for your panel (accept / discard) | | …/chat-input | A chat-style prompt input on the same engine | | …/image | [emailImageAlt] — your text field as the selected image's alt text | | …/anchor | [emailAnchor] — position an overlay at a rect | | …/editor | [emailEditor] — mounts the engine on your element and binds its value: a FormValueControl, outside writes held while typed in, canonical out, baseline(), undoable replace(), EMAIL_EDITOR / injectEditor() | | …/focus | [emailKeepFocus] — controls that keep the caret in the editor | | …/keyboard | [emailFieldKeys] — a field inside a menu: keys stay in it, Enter commits, Escape reverts; shows what its model took | | …/material | [emailMatFormField] — an address input inside mat-form-field | | …/metrics | Live text metrics (createTextMetrics), measured without DOM reads |

Styling

The components theme through a token cascade: their own --email-* tokens first, then Material's --mat-sys-* system tokens, then a built-in light/dark fallback — a Material 3 app is themed out of the box.

The editable surface is yours to style; it carries the aee-editor class. Include ProseMirror's required CSS (prosemirror-view/style/prosemirror.css, and prosemirror-tables/style/tables.css for tables). The shared scrollbar look is a Sass mixin:

@use '@h-k-dev/angular-email-editor/styles/scroll';

The demo app is the reference composer — toolbar, menus, compose windows — built only on this public API.

License

MIT