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

@trevixal/angular

v1.0.5

Published

Angular bindings for the Trevixal editor: a signal-backed snapshot and view lifecycle, with no Angular compiler required.

Downloads

495

Readme

@trevixal/angular

CI npm types license

Documentation · Live editor · Changelog · Issues

The Trevixal editor

Features

  • A signal-backed snapshot and a view lifecycle tied to the component
  • No Angular compiler required: it is a plain library, not a schematic
  • 0.3 kB minified and gzipped, with TypeScript types in the package

Angular bindings for the Trevixal editor: a signal-backed snapshot and the view lifecycle, with no Angular compiler required.

npm install @trevixal/core @trevixal/angular

Usage

import { Component, DestroyRef, ElementRef, afterNextRender, computed, inject, viewChild } from '@angular/core'
import { Schema, defaultMarks, defaultNodes } from '@trevixal/core'
import { createAngularEditor } from '@trevixal/angular'

const schema = new Schema({ nodes: defaultNodes(), marks: defaultMarks() })

@Component({
  selector: 'app-editor',
  standalone: true,
  template: `
    <button
      [attr.aria-pressed]="isBold()"
      (mousedown)="$event.preventDefault()"
      (click)="editor.commands.toggleMark('bold')"
    >Bold</button>

    <div class="trevixal" #host></div>
  `,
})
export class EditorComponent {
  private readonly host = viewChild.required<ElementRef<HTMLElement>>('host')
  private readonly binding = createAngularEditor({ schema })

  readonly editor = this.binding.editor
  readonly isBold = computed(() => this.binding.snapshot()?.activeMarks.includes('bold') ?? false)

  constructor() {
    afterNextRender(() => this.binding.attach(this.host().nativeElement))
    inject(DestroyRef).onDestroy(() => this.binding.destroy())
  }
}

mousedown is cancelled rather than handled on click: the toolbar must not take the selection the command is about to act on.

No compiler, and why that matters

There is no @Component, @Directive or @Injectable in this package. A package that ships those has to be built by Angular's own compiler into partial-Ivy output, a second toolchain for a few dozen lines of glue, and a hand-rolled imitation of that output would be worse than shipping nothing. That is why this adapter was deferred for a long time (ADR-0007).

What the glue actually needs from Angular is signal, which is an ordinary function. So this ships ordinary functions. Your component owns the decorators; nothing here needs compiling beyond TypeScript, and the package builds with the same tsup pipeline as every other one in the repository.

Zoneless by construction

The snapshot is a signal, so a change notifies exactly the templates that read it. No NgZone, no markForCheck, and nothing else re-renders while somebody types.

It goes further than that: the snapshot keeps its identity while nothing a toolbar would draw differently has changed, so ten keystrokes produce one signal change, the first, which flips canUndo, rather than ten.

Server rendering

createAngularEditor touches no DOM. The view is built only by attach, so a component can construct the binding in a field initialiser, before its template exists and on a server that has no document at all.

Exports

| Export | What it does | | --- | --- | | createAngularEditor(options) | The editor, its snapshot signal, attach(host) and destroy() | | editorSnapshotSignal(editor) | Just the signal, for an editor you already have | | AngularEditor, AngularEditorOptions | The types |

attach returns a disposer, and calling it again replaces the view rather than stacking a second one, so a host that re-renders its container does not end up with two editors on one document.

License

Apache-2.0