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

@dictate-button/react

v0.2.1

Published

React text fields with Dictate Button integrated

Downloads

562

Readme

@dictate-button/react

Tests

React text field components with speech-to-text dictation powered by Dictate Button.

Provides a thin integration layer that avoids DOM scanning and mutation, making it fully compatible with React and any CSS framework.

Features

  • No DOM Scanning: Declarative React components instead of inject scripts
  • No DOM Mutation: Integrates naturally with React's virtual DOM
  • Framework Agnostic: Works with any CSS framework (Tailwind, Bootstrap, etc.)
  • TypeScript First: Full type safety and IntelliSense support
  • React 19 Ready: Built for modern React
  • Controlled & Uncontrolled: Supports both patterns
  • Customizable: Full control over styling and behavior

Installation

pnpm add @dictate-button/react

Registration Required

You need to register your app on dictate-button.io to use the @dictate-button/react components in your app.

To do that, visit dash.dictate-button.io, create a free account and register your site. No API key configuration needed - the service works automatically once your site is registered and verified.

Quick Start

import { DictateInput, DictateTextarea, DictateButton } from '@dictate-button/react';

function MyForm() {
  return (
    <div>
      <DictateInput
        type="text"
        placeholder="Start typing or click the mic..."
        className="your-input-class"
      />

      <DictateTextarea
        rows={5}
        placeholder="Or speak here..."
        className="your-textarea-class"
      />

      <DictateButton
        onDictateEnd={(text) => console.log('Transcribed:', text)}
      />
    </div>
  );
}

Why This Integration Layer?

The dictate-button package includes inject scripts that scan the DOM using querySelectorAll and mutate it by wrapping elements.

This integration layer provides:

  • ✅ Declarative React components
  • ✅ No DOM scanning or mutation
  • ✅ Works with any CSS framework or styling approach
  • ✅ Full TypeScript support
  • ✅ React refs, controlled components, and hooks

Components

<DictateInput />

A text input with integrated speech-to-text button.

<DictateInput
  type="text"
  placeholder="Type or speak..."
  buttonSize={30}
  onDictateEnd={(text) => console.log(text)}
/>

<DictateTextarea />

A textarea with integrated speech-to-text button.

<DictateTextarea
  rows={5}
  placeholder="Type or speak..."
  buttonSize={30}
  onDictateEnd={(text) => console.log(text)}
/>

<DictateButton />

A standalone dictate button for custom event-based implementations.

<DictateButton
  size={30}
  onDictateStart={() => console.log('Started')}
  onDictateText={(text) => console.log('Interim:', text)}
  onDictateEnd={(text) => console.log('Final:', text)}
  onDictateError={(error) => console.error(error)}
/>

Use this when you want to handle dictation events yourself without automatic text field integration.

useDictateButtonEventHandlers Hook

For building custom text field integrations, use the hook to get text insertion event handlers:

import { useRef } from 'react';
import { DictateButton, useDictateButtonEventHandlers } from '@dictate-button/react';

function CustomInput() {
  const inputRef = useRef<HTMLInputElement>(null);
  const handlers = useDictateButtonEventHandlers(inputRef);

  return (
    <div style={{ position: 'relative' }}>
      <input ref={inputRef} style={{ paddingRight: '40px' }} />
      <DictateButton
        {...handlers}
        style={{ position: 'absolute', right: '4px', top: '50%', transform: 'translateY(-50%)' }}
      />
    </div>
  );
}

Props

DictateInput & DictateTextarea Props

All standard HTML input/textarea props are supported, plus:

| Prop | Type | Default | Description | |------|------|---------|-------------| | buttonSize | number | 30 | Size of the dictate button in pixels | | buttonClassName | string | - | CSS class for the button | | apiEndpoint | string | - | Custom API endpoint for transcription | | language | string | 'en' | Language code (e.g., 'en', 'es', 'fr') | | theme | 'light' \| 'dark' | - | Button theme | | onDictateStart | () => void | - | Called when dictation starts (overrides text insertion if provided) | | onDictateText | (text: string) => void | - | Called with interim results (overrides text insertion if provided) | | onDictateEnd | (text: string) => void | - | Called with final transcription (overrides text insertion if provided) | | onDictateError | (error: Error \| string) => void | - | Called on errors (overrides text insertion if provided) |

DictateButton Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | size | number | 30 | Size of the button in pixels | | className | string | - | CSS class for the button | | style | React.CSSProperties | - | Inline styles for the button | | apiEndpoint | string | - | Custom API endpoint for transcription | | language | string | 'en' | Language code (e.g., 'en', 'es', 'fr') | | theme | 'light' \| 'dark' | - | Button theme | | onDictateStart | () => void | - | Called when dictation starts | | onDictateText | (text: string) => void | - | Called with interim results | | onDictateEnd | (text: string) => void | - | Called with final transcription | | onDictateError | (error: Error \| string) => void | - | Called on errors |

Styling with Tailwind CSS

These components accept standard className props and work with any CSS framework. Here's an example using Tailwind CSS with the popular cn() utility for conditional classes:

import { DictateInput } from '@dictate-button/react';
import { cn } from '@/lib/utils'; // clsx + tailwind-merge utility

<DictateInput
  className={cn(
    "flex h-10 w-full rounded-md border border-input bg-background px-3 py-2",
    "text-sm ring-offset-background",
    "placeholder:text-muted-foreground",
    "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
    "disabled:cursor-not-allowed disabled:opacity-50"
  )}
/>

The cn() utility is commonly used in Tailwind projects to merge class names. It's not specific to any component library.

Examples

See EXAMPLES.md for comprehensive usage examples including:

  • Basic usage
  • Tailwind CSS styling
  • Controlled components
  • Custom event handlers
  • React Hook Form integration
  • Advanced hook usage

TypeScript

All components and hooks are fully typed. Import types as needed:

import type {
  DictateButtonComponentProps,
  DictateInputProps,
  DictateTextareaProps,
  UseDictateButtonEventHandlersReturn,
} from '@dictate-button/react';

Development

# Build the library
pnpm build

# Run tests
pnpm test

# Type checking
pnpm typecheck

# Watch mode for development
pnpm dev

License

Apache-2.0

Credits

Built on top of dictate-button by the Dictate Button team.