Nexus UI

Hold to Record, animated React component

A press-and-hold voice button that grows into a live waveform with a timer, cancels when you slide away, and settles into a playable voice note.

  • Free
  • Inputs & Controls
  • Spring

Play with it

Move the controls and watch it change. Copy code gives you a snippet with only the props you changed.

Props

PropTypeDefaultWhat it does
onRecorded—Called when a recording is kept. levels holds loudness samples from 0 to 1.
onCancel—Called when a recording is cancelled by sliding left or pressing Escape.
onDelete—Called when the kept voice note is deleted.
maxDuration60000Recording stops by itself after this many milliseconds.
minDuration400Holds shorter than this are ignored.
useMicrophonefalseDrive the waveform from the real microphone (asks for permission). Simulated otherwise.
cancelDistance90How far to slide left, in pixels, before releasing cancels.
label"Hold to record"Button label.
accent"#ef4444"Colour of the recording dot and the live waveform.
className—Extra classes on the wrapper.

Add it to your project

  1. 1

    Prepare your project

    You need Tailwind CSS and the @/import alias. If shadcn isn't set up yet, initialise it once:

    npx shadcn@latest init

    Then add the Nexus registry to your components.json (the registries key is the part that matters):

    {
      "$schema": "https://ui.shadcn.com/schema.json",
      "style": "default",
      "rsc": true,
      "tsx": true,
      "tailwind": {
        "css": "src/app/globals.css",
        "baseColor": "neutral",
        "cssVariables": true,
        "prefix": ""
      },
      "aliases": {
        "components": "@/components",
        "utils": "@/lib/utils",
        "ui": "@/components/ui",
        "lib": "@/lib",
        "hooks": "@/hooks"
      },
      "registries": {
        "@nexus-labs": "https://www.nexus-ui.com/api/registry/{name}"
      }
    }
  2. 2

    Add the component

    Run this from your project root. It adds the component, the utilities it uses and its packages.

    npx shadcn@latest add @nexus-labs/hold-to-record
  3. 3

    Check what was added

    With the standard aliases, these files land in your project:

    components/
    hold-to-record/
    hold-to-record.tsx
    index.ts
  4. 4

    Copying by hand? Install the packages

    Skip this if you used the command above.

    npm install framer-motion lucide-react
  5. 5

    Use it in a page

    Import it and render it. The Code tab above has the full example.

    // app/page.tsx
    import { HoldToRecord } from "@/components/hold-to-record";
    
    export default function Page() {
      return (
        <main>
          <HoldToRecord />
        </main>
      );
    }