Skip to Content

reaction-picker

ui

Emoji reaction selector popover with counts.

Source Code

View the full component source code below.

"use client"

import * as React from "react"
import { Plus } from "lucide-react"

import { cn } from "@/lib/utils"
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover"

interface Reaction {
  emoji: string
  count: number
  active?: boolean
}

const DEFAULT_EMOJIS = ["๐Ÿ‘", "โค๏ธ", "๐Ÿ˜‚", "๐Ÿ˜ฎ", "๐Ÿ˜ข", "๐ŸŽ‰", "๐Ÿ”ฅ", "๐Ÿ‘"]

function ReactionPicker({
  className,
  reactions,
  onReact,
  emojis = DEFAULT_EMOJIS,
  ...props
}: React.ComponentProps<"div"> & {
  reactions: Reaction[]
  onReact?: (emoji: string) => void
  emojis?: string[]
}) {
  return (
    <div
      data-slot="reaction-picker"
      className={cn("flex flex-wrap items-center gap-1.5", className)}
      {...props}
    >
      {reactions.map((reaction) => (
        <button
          key={reaction.emoji}
          onClick={() => onReact?.(reaction.emoji)}
          className={cn(
            "inline-flex items-center gap-1 rounded-full border px-2 py-0.5 text-xs font-medium transition-colors",
            reaction.active
              ? "border-primary/30 bg-primary/10 text-foreground"
              : "border-border bg-input/30 text-muted-foreground hover:bg-input/50"
          )}
        >
          <span>{reaction.emoji}</span>
          <span>{reaction.count}</span>
        </button>
      ))}
      <Popover>
        <PopoverTrigger asChild>
          <button className="inline-flex size-7 items-center justify-center rounded-full border border-border bg-input/30 text-muted-foreground transition-colors hover:bg-input/50 hover:text-foreground">
            <Plus className="size-3.5" />
          </button>
        </PopoverTrigger>
        <PopoverContent className="w-auto p-2">
          <div className="flex gap-1">
            {emojis.map((emoji) => (
              <button
                key={emoji}
                onClick={() => onReact?.(emoji)}
                className="flex size-8 items-center justify-center rounded-lg text-base transition-colors hover:bg-muted"
              >
                {emoji}
              </button>
            ))}
          </div>
        </PopoverContent>
      </Popover>
    </div>
  )
}

export { ReactionPicker, type Reaction }

Installation

npx shadcn@latest add https://registry.mukoko.com/api/v1/ui/reaction-picker

API

Fetch this component's metadata and source code from the registry API.

GET/api/v1/ui/reaction-picker

Source

components/ui/reaction-picker.tsx