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

@open-wysiwyg-editor/angular

v1.0.2

Published

Angular standalone component for open-wysiwyg-editor with ngModel and reactive forms support. Accessible (WCAG 2.2 AA), RTL-first, CSP-safe, SSR-safe.

Readme

@open-wysiwyg-editor/angular

npm version license

Live demo → · GitHub · npm

Angular component for open-wysiwyg-editor: an accessible (WCAG 2.2 AA), RTL-first, CSP-safe rich text editor. It is a standalone component that works with [(ngModel)], reactive forms, signals and Angular SSR.

Requires Angular 21+.

Install

npm install @open-wysiwyg-editor/angular

This also installs the core package open-wysiwyg-editor. The package re-exports the whole core API (createEditor, StarterKit, types…), so you don't need to import from the core package yourself.

Setup

Add the stylesheet to angular.json:

"styles": [
  "node_modules/@open-wysiwyg-editor/angular/style.css",
  "src/styles.css"
]

Or import it in your global styles.css:

@import "@open-wysiwyg-editor/angular/style.css";

style.css styles the toolbar and the editor. If you render saved HTML outside the editor, add content.css (the same content styles) to that page. Minified style.min.css and content.min.css are included.

Usage

Standalone component with [(ngModel)]

import { Component } from "@angular/core";
import { FormsModule } from "@angular/forms";
import { RichTextEditorComponent } from "@open-wysiwyg-editor/angular";

@Component({
  selector: "app-post",
  imports: [FormsModule, RichTextEditorComponent],
  template: `
    <owe-rich-text-editor [(ngModel)]="html" placeholder="Write something…" />
    <pre>{{ html }}</pre>
  `,
})
export class PostComponent {
  html = "<p>Hello <strong>world</strong></p>";
}

Reactive forms

import { Component, inject } from "@angular/core";
import { FormBuilder, ReactiveFormsModule, Validators } from "@angular/forms";
import { RichTextEditorComponent } from "@open-wysiwyg-editor/angular";

@Component({
  selector: "app-compose",
  imports: [ReactiveFormsModule, RichTextEditorComponent],
  template: `
    <form [formGroup]="form" (ngSubmit)="save()">
      <owe-rich-text-editor formControlName="body" />
      @if (form.controls.body.touched && form.controls.body.errors) {
        <p role="alert">Write something first.</p>
      }
      <button>Save</button>
    </form>
  `,
})
export class ComposeComponent {
  form = inject(FormBuilder).nonNullable.group({
    body: ["", [Validators.required, Validators.minLength(10)]],
  });

  save() {
    console.log(this.form.getRawValue().body);
  }
}

The control is marked touched when the editor loses focus. form.controls.body.disable() makes the editor read-only.

Without forms: [(value)]

<owe-rich-text-editor [(value)]="html" />

Signals

value is a regular input and valueChange is a regular output, so [(value)] works with a model() or signal():

import { Component, signal } from "@angular/core";
import { RichTextEditorComponent } from "@open-wysiwyg-editor/angular";

@Component({
  selector: "app-note",
  imports: [RichTextEditorComponent],
  template: `
    <owe-rich-text-editor [(value)]="html" />
    <p>{{ html().length }} characters of HTML</p>
  `,
})
export class NoteComponent {
  html = signal("<p>Start here</p>");
}

Options

[options] takes anything createEditor() accepts, except element. It is read once, when the editor starts. placeholder and readonly follow changes.

<owe-rich-text-editor
  [(ngModel)]="html"
  [options]="{ language: 'ar', dir: 'rtl', autofocus: true }"
  placeholder="اكتب هنا…"
/>

See the core docs for all options (extensions, labels, languages, URL policy, input rules…).

Get the editor: (ready)

import type { Editor } from "@open-wysiwyg-editor/angular";

onReady(editor: Editor) {
  editor.focus();
  console.log(editor.getJSON());
}
<owe-rich-text-editor [(ngModel)]="html" (ready)="onReady($event)" />

You can also read it with a viewChild: editor()?.editor is null until the editor has started.

Read-only and disabled

<owe-rich-text-editor [value]="html" readonly />

With forms, FormControl.disable() or [disabled] on the control does the same.

Server-side rendering

Nothing to configure. The editor starts in afterNextRender, so it never runs on the server, and it works with Angular SSR and hydration. The server renders an empty container, and the editor mounts in the browser. Its DOM listeners run outside the Angular zone, so typing doesn't trigger change detection except when the value changes.

API

Inputs

| Input | Type | Default | Notes | | --- | --- | --- | --- | | value | string | undefined | HTML content. Two-way with [(value)]. | | options | RichTextEditorOptions | {} | createEditor() options without element. Read once at start. | | placeholder | string | undefined | Overrides options.placeholder. Updates live. | | readonly | boolean | false | Disables editing. Updates live. |

Outputs

| Output | Payload | Notes | | --- | --- | --- | | valueChange | string | The HTML after every change. | | ready | Editor | Emitted once, in the browser, after the editor starts. |

Members

| Member | Notes | | --- | --- | | editor | The live Editor, or null before it starts (and on the server). |

Forms: implements ControlValueAccessor (value, disabled state, touched on blur).

Alternative: the <owe-editor> web component

The core package also ships a form-associated custom element. Use it if you prefer no Angular wrapper. Angular binds it with ngDefaultControl.

// main.ts
import "open-wysiwyg-editor/element";
import { CUSTOM_ELEMENTS_SCHEMA, Component } from "@angular/core";
import { FormsModule } from "@angular/forms";

@Component({
  selector: "app-post",
  imports: [FormsModule],
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
  template: `<owe-editor ngDefaultControl [(ngModel)]="html" language="ar"></owe-editor>`,
})
export class PostComponent {
  html = "";
}

You still need style.css from the setup above. See the core docs for the element's attributes and events.

Links

License

MIT © alhassan-ahmed