Component

Action Hint

See on GitHub

A particle emitter for showing ephemeral action feedback hints that fade out.

'use client'

import {
  ActionHintEmitter,
  useActionHint,
} from '@/components/action-hint'
import { Button } from '@/components/ui/button'
import { Copy, Check, Download, Share2, Bookmark } from 'lucide-react'

function CopyButton() {
  const { emit } = useActionHint()
  return (
    <Button
      variant="secondary"
      size="sm"
      onClick={() =>
        emit(
          <span className="flex items-center gap-1.5">
            <Check className="size-3" />
            Copied!
          </span>
        )
      }
    >
      <Copy className="size-4" />
      Copy
    </Button>
  )
}

function DownloadButton() {
  const { emit } = useActionHint()
  return (
    <Button
      variant="secondary"
      size="sm"
      onClick={() =>
        emit(
          <span className="flex items-center gap-1.5">
            <Download className="size-3" />
            Downloading...
          </span>
        )
      }
    >
      <Download className="size-4" />
      Download
    </Button>
  )
}

function ShareButton() {
  const { emit } = useActionHint()
  return (
    <Button
      variant="secondary"
      size="sm"
      onClick={() =>
        emit(
          <span className="flex items-center gap-1.5">
            <Share2 className="size-3" />
            Link shared!
          </span>
        )
      }
    >
      <Share2 className="size-4" />
      Share
    </Button>
  )
}

function SaveButton() {
  const { emit } = useActionHint()
  return (
    <Button
      variant="secondary"
      size="sm"
      onClick={() =>
        emit(
          <span className="flex items-center gap-1.5">
            <Bookmark className="size-3" />
            Saved!
          </span>
        )
      }
    >
      <Bookmark className="size-4" />
      Save
    </Button>
  )
}

function ActionHintDemo() {
  return (
    <div className="flex min-h-40 w-full items-center justify-center p-8">
      <div className="flex flex-wrap items-center gap-2">
        <ActionHintEmitter>
          <CopyButton />
        </ActionHintEmitter>

        <ActionHintEmitter>
          <DownloadButton />
        </ActionHintEmitter>

        <ActionHintEmitter>
          <ShareButton />
        </ActionHintEmitter>

        <ActionHintEmitter>
          <SaveButton />
        </ActionHintEmitter>
      </div>
    </div>
  )
}

export default ActionHintDemo

Installation

pnpm dlx shadcn@latest add @joyco/action-hint

Usage

import { ActionHintEmitter, useActionHint } from '@/components/action-hint'
 
function MyComponent() {
  return (
    <ActionHintEmitter>
      <ActionButton />
    </ActionHintEmitter>
  )
}
 
function ActionButton() {
  const { emit } = useActionHint()
 
  return (
    <button onClick={() => emit(<span>Action completed!</span>)}>
      Click me
    </button>
  )
}

Props

ActionHintEmitter

PropTypeDefaultDescription
align'start' | 'center' | 'end''center'Horizontal alignment of the hint relative to the emitter
marginnumber4Vertical gap between the hint and the emitter in pixels
durationnumber1500Duration of the fade animation in milliseconds

API

useActionHint

Returns an object with:

  • emit(content: ReactNode) - Emits a hint particle with the given content. Calling emit again will abort any existing hints and show only the new one.

Related Components

Maintainers
Downloads
29Total
0 downloads today