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

@amusendame/beakblock-react

v0.1.2

Published

React bindings for BeakBlock editor

Readme

@amusendame/beakblock-react

React bindings for the BeakBlock rich text editor.

Installation

npm install @amusendame/beakblock-react @amusendame/beakblock-core
# or
pnpm add @amusendame/beakblock-react @amusendame/beakblock-core

Quick Start

import { useBeakBlock, BeakBlockView, SlashMenu, BubbleMenu } from '@amusendame/beakblock-react';
import '@amusendame/beakblock-core/styles/editor.css';

function MyEditor() {
  const editor = useBeakBlock({
    initialContent: [
      {
        type: 'heading',
        props: { level: 1 },
        content: [{ type: 'text', text: 'Hello World', styles: {} }],
      },
      {
        type: 'paragraph',
        content: [{ type: 'text', text: 'Start editing...', styles: {} }],
      },
    ],
  });

  if (!editor) return <div>Loading...</div>;

  return (
    <div className="editor-container">
      <BeakBlockView editor={editor} />
      <SlashMenu editor={editor} />
      <BubbleMenu editor={editor} />
    </div>
  );
}

Hooks

useBeakBlock

Creates and manages an BeakBlockEditor instance.

const editor = useBeakBlock({
  initialContent: [...],
  editable: true,
  autoFocus: 'end',
  onUpdate: (blocks) => console.log(blocks),
  deps: [someValue], // Recreate editor when deps change
});

useEditorContent

Subscribe to document changes.

const blocks = useEditorContent(editor);
// blocks updates whenever the document changes

useEditorSelection

Subscribe to selection changes.

const selectedBlocks = useEditorSelection(editor);
// selectedBlocks updates when selection changes

useEditorFocus

Track editor focus state.

const isFocused = useEditorFocus(editor);

Comments

Use CommentStore and createCommentPlugin from @amusendame/beakblock-core, and CommentModal from this package. There is no React CommentRail yet; use the modal and bubble menu.

Wire BubbleMenu with onComment to open the modal. On every editor transaction with a document change, call store.mapAnchors(transaction.mapping) so thread anchors match the document.

Full API and patterns: Comments guide.

Components

BeakBlockView

Renders the editor view.

<BeakBlockView
  editor={editor}
  className="my-editor"
/>

With ref for imperative access:

const viewRef = useRef<BeakBlockViewRef>(null);

<BeakBlockView
  ref={viewRef}
  editor={editor}
/>

// Later: viewRef.current?.focus()

SlashMenu

Command palette triggered by typing /.

<SlashMenu editor={editor} />

See SlashMenu Customization for advanced usage.

BubbleMenu

Floating toolbar for text formatting.

<BubbleMenu editor={editor} />

See BubbleMenu Customization for advanced usage.

ColorPicker

Color picker for text and background colors.

import { ColorPicker } from '@amusendame/beakblock-react';

<ColorPicker
  editor={editor}
  currentTextColor={textColor}
  currentBackgroundColor={bgColor}
/>

See ColorPicker Customization for advanced usage.

TableHandles

Row/column manipulation handles for tables.

<TableHandles editor={editor} />

MediaMenu

Menu for media blocks (images, videos, files).

<MediaMenu editor={editor} />

Customization API

BubbleMenu Customization

The BubbleMenu supports extensive customization through props.

Props

interface BubbleMenuProps {
  editor: BeakBlockEditor | null;
  customItems?: BubbleMenuItem[];  // Add custom buttons
  itemOrder?: string[];            // Control order (use '---' for dividers)
  hideItems?: string[];            // Hide default items
  className?: string;
  children?: React.ReactNode;
}

Default Item IDs

  • Block type: blockType
  • Alignment: alignLeft, alignCenter, alignRight
  • Formatting: bold, italic, underline, strikethrough
  • Style: code, link, color

Example: Add a Custom Button

import { BubbleMenu, BubbleMenuItem } from '@amusendame/beakblock-react';

const translateButton: BubbleMenuItem = {
  id: 'translate',
  label: 'Translate',
  icon: (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor">
      <path d="M3 5h12M9 3v2m1.048 9.5A18.022 18.022 0 016.412 9m6.088 9h7M11 21l5-10 5 10" />
    </svg>
  ),
  action: async (editor, state) => {
    const text = editor.pm.state.doc.textBetween(state.from, state.to);
    const translated = await translateAPI(text);
    // Replace selection...
  },
};

<BubbleMenu
  editor={editor}
  customItems={[translateButton]}
/>

Example: Reorder Items

<BubbleMenu
  editor={editor}
  itemOrder={[
    'bold', 'italic', 'underline',
    '---',  // Divider
    'link', 'color',
    '---',
    'translate',  // Custom item
  ]}
/>

Example: Minimal Toolbar

<BubbleMenu
  editor={editor}
  itemOrder={['bold', 'italic', '---', 'link']}
/>

Example: Hide Items

<BubbleMenu
  editor={editor}
  hideItems={['strikethrough', 'code', 'alignLeft', 'alignCenter', 'alignRight']}
/>

SlashMenu Customization

The SlashMenu supports customization similar to BubbleMenu.

Props

interface SlashMenuProps {
  editor: BeakBlockEditor | null;
  items?: SlashMenuItem[];         // Replace all defaults
  customItems?: SlashMenuItem[];   // Add to defaults
  itemOrder?: string[];            // Control order (only listed items shown)
  hideItems?: string[];            // Hide specific items
  renderItem?: (item: SlashMenuItem, isSelected: boolean) => React.ReactNode;
  className?: string;
}

Default Item IDs

  • Text: paragraph, heading
  • Lists: bulletList, numberedList, checkList
  • Blocks: blockquote, codeBlock, callout, divider
  • Tables: table
  • Media: image, video, audio, file

Example: Add Custom Items

import { SlashMenu, SlashMenuItem } from '@amusendame/beakblock-react';

const customItems: SlashMenuItem[] = [
  {
    id: 'emoji',
    title: 'Emoji',
    description: 'Insert an emoji picker',
    icon: '😀',
    action: (editor) => {
      // Show emoji picker...
    },
  },
  {
    id: 'template',
    title: 'Template',
    description: 'Insert a predefined template',
    icon: '📄',
    action: (editor) => {
      // Insert template...
    },
  },
];

<SlashMenu
  editor={editor}
  customItems={customItems}
/>

Example: Custom Order

<SlashMenu
  editor={editor}
  itemOrder={['paragraph', 'heading', 'bulletList', 'emoji', 'template']}
/>

Example: Hide Items

<SlashMenu
  editor={editor}
  hideItems={['table', 'video', 'audio', 'file']}
/>

ColorPicker Customization

The ColorPicker component allows custom color palettes.

Props

interface ColorPickerProps {
  editor: BeakBlockEditor;
  currentTextColor: string | null;
  currentBackgroundColor: string | null;
  textColors?: ColorOption[];       // Custom text color palette
  backgroundColors?: ColorOption[]; // Custom background color palette
  textColorLabel?: string;          // Label for text color section
  backgroundColorLabel?: string;    // Label for background section
  onClose?: () => void;
}

interface ColorOption {
  value: string;  // CSS color value ('' for default/remove)
  label: string;  // Display label
}

Default Palettes

import { DEFAULT_TEXT_COLORS, DEFAULT_BACKGROUND_COLORS } from '@amusendame/beakblock-react';

// DEFAULT_TEXT_COLORS includes:
// Default, Gray, Red, Orange, Yellow, Green, Blue, Purple, Pink

// DEFAULT_BACKGROUND_COLORS includes:
// Default, Gray, Red, Orange, Yellow, Green, Blue, Purple, Pink (lighter versions)

Example: Brand Color Palette

import { ColorPicker, ColorOption } from '@amusendame/beakblock-react';

const brandTextColors: ColorOption[] = [
  { value: '', label: 'Default' },
  { value: '#1a1a1a', label: 'Black' },
  { value: '#0066cc', label: 'Primary' },
  { value: '#00994d', label: 'Success' },
  { value: '#cc3300', label: 'Error' },
];

const brandBackgroundColors: ColorOption[] = [
  { value: '', label: 'None' },
  { value: '#e6f2ff', label: 'Blue' },
  { value: '#e6ffe6', label: 'Green' },
  { value: '#ffe6e6', label: 'Red' },
];

<ColorPicker
  editor={editor}
  currentTextColor={textColor}
  currentBackgroundColor={bgColor}
  textColors={brandTextColors}
  backgroundColors={brandBackgroundColors}
  textColorLabel="Text Color"
  backgroundColorLabel="Highlight"
/>

Accessing ProseMirror

The editor instance provides full ProseMirror access:

function MyEditor() {
  const editor = useBeakBlock({...});

  const handleBold = () => {
    editor.toggleBold();
  };

  const handleCustomAction = () => {
    // Direct ProseMirror access
    const tr = editor.pm.createTransaction();
    tr.insertText('Custom text');
    editor.pm.dispatch(tr);
  };

  return (
    <>
      <button onClick={handleBold}>Bold</button>
      <button onClick={handleCustomAction}>Insert</button>
      <BeakBlockView editor={editor} />
    </>
  );
}

Exports

Components

  • BeakBlockView - Main editor view
  • SlashMenu - Command palette
  • BubbleMenu - Floating toolbar
  • ColorPicker - Color selection
  • TableMenu - Table manipulation menu
  • TableHandles - Table row/column handles
  • MediaMenu - Media block menu
  • LinkPopover - Link editing popover

Hooks

  • useBeakBlock - Create editor instance
  • useEditorContent - Subscribe to content
  • useEditorSelection - Subscribe to selection
  • useEditorFocus - Track focus state

Constants

  • BUBBLE_MENU_ITEMS - Default bubble menu items map
  • DEFAULT_BUBBLE_MENU_ORDER - Default bubble menu item order
  • DEFAULT_TEXT_COLORS - Default text color palette
  • DEFAULT_BACKGROUND_COLORS - Default background color palette

Types

  • BeakBlockViewProps, BeakBlockViewRef
  • SlashMenuProps, SlashMenuItem
  • BubbleMenuProps, BubbleMenuItem
  • ColorPickerProps, ColorOption
  • TableMenuProps, TableHandlesProps
  • MediaMenuProps, LinkPopoverProps

Documentation

For complete documentation, see:

License

Apache-2.0