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

@octane-xplat/richtext

v0.18.0

Published

Native rich-text editing leaf for Octane xplat — Android Aztec and AppKit WKWebView StarterKit

Readme

@octane-xplat/richtext

Native rich-text editing for Octane Xplat apps: WordPress Aztec's AztecText on Android — a Spannable-backed EditText, not a WebView — and AztecEditor-iOS (Aztec.TextView) on iOS through the XplatAztecEditorView Swift facade in platforms/ios. Web and Windows return supported: false; the @octane-xplat/tiptap facade covers web.

import { useState } from 'octane'
import { RichTextEditor, supported } from '@octane-xplat/richtext'
import { Text } from '@octane-xplat/ui'

export function Notes() {
	const [html, setHtml] = useState('<p>Trip notes</p>')
	return supported ? (
		<RichTextEditor value={html} onChange={setHtml} />
	) : (
		<Text>Editing is unavailable on this target</Text>
	)
}

Content in/out is document HTML via Aztec fromHtml/toPlainHtml. The ref callback returns an imperative handle (getHTML/setHTML, apply(format), linkTo/removeLink, isActive, undo/redo, focus/blur, native) once the editor exists, and onSelectionChange reports the active RichTextFormat set at the caret.

Structural commands exist on the Aztec surface: split() breaks the block at the caret, join() merges a block into the previous one from a collapsed caret at its start, and indent()/outdent() demote or promote the selected blocks — a real nested-list restructure on <ul>/<ol>, a \t indent on plain blocks. canIndent()/canOutdent() report whether the current selection can take the command. All six return false when the command cannot apply; markup Aztec does not understand (for example <div data-*> wrappers) is opaque to them. On AppKit the commands return false — the engine transport cannot report a synchronous result.

import { useRef } from 'octane'
import { RichTextEditor, type RichTextEditorHandle } from '@octane-xplat/richtext'
import { Button } from '@octane-xplat/ui'

export function Formatting() {
	const editor = useRef<RichTextEditorHandle | null>(null)
	return (
		<>
			<RichTextEditor
				ref={(handle) => {
					editor.current = handle
				}}
				onSelectionChange={({ active }) => console.log(active)}
			/>
			<Button clickAction={() => editor.current?.apply('bold')}>Bold</Button>
			<Button
				clickAction={() => {
					const handle = editor.current
					if (!handle) return
					handle.setHTML('<p>New note</p>')
					console.log(handle.getHTML(), handle.isActive('bold'))
					handle.linkTo('https://example.com')
					handle.removeLink()
					handle.undo()
					handle.redo()
					handle.focus()
					handle.blur()
				}}
			>
				Try editor commands
			</Button>
		</>
	)
}

Native dependencies

The Android Aztec dependency (org.wordpress:aztec:v2.1.7) arrives through the leaf's platforms/android/include.gradle — no app-level gradle work. On iOS the leaf declares AztecEditor-iOS as a pinned-revision Swift Package in its plugin-level nativescript.config.ts and compiles platforms/ios/src/XplatAztecEditor.swift into the app — NativeScript plugin discovery applies both when the app depends on @octane-xplat/richtext. iOS has no task-list or text-alignment surface: apply('taskList') and the align* formats report a warning and leave the document unchanged, and isActive returns false for them. See the framework guide for the full contract and the demo: docs/app/rich-text.md and packages/demos/src/RichTextEditorDemo.tsrx.

macOS AppKit

The macOS export mounts a bundled local editor document in WKWebView. RichText uses StarterKit; Tiptap and Lexical use their existing web facades. Wait for onReady; synchronous getters return the latest received snapshot and commands cross WebKit asynchronously. The native handle is the Swift host transport. See AppKit setup and engine limits.