BigBlocks

Like Button

An on-chain like/unlike toggle button for BSocial content with optimistic UI updates

Installation

bunx shadcn@latest add https://registry.bigblocks.dev/r/like-button.json

Usage

Pass the transaction ID of the content to like, the current like count, and whether the user has already liked it. Supply onLike (and optionally onUnlike) to broadcast the transaction.

The button applies optimistic UI updates immediately and reverts on error.

import { LikeButton } from "@/components/blocks/like-button"
 
export default function PostCard({ post }) {
  return (
    <LikeButton
      txid={post.txid}
      count={post.likes}
      liked={post.likedByMe}
      onLike={async (txid) => {
        const txid = await broadcastLike(txid)
        return { txid }
      }}
      onUnlike={async (txid) => {
        const txid = await broadcastUnlike(txid)
        return { txid }
      }}
      onToggled={(liked, result) => {
        console.log("Like toggled:", liked, result.txid)
      }}
    />
  )
}

Variants

VariantDescription
defaultBordered button with icon and count
compactSquare icon-only button (count hidden)
textPlain text style for minimal UIs

Liked State

Compact

Text

Hook: useLike

Use useLike directly when you need to embed the like state into a custom component without the default button rendering.

import { useLike } from "@/components/blocks/like-button"
 
export function CustomLikeControl({ txid, count, liked }) {
  const { isLiked, displayCount, isLoading, handleToggle } = useLike({
    txid,
    count,
    liked,
    onLike: async (id) => {
      const result = await broadcastLike(id)
      return { txid: result.txid }
    },
    onUnlike: async (id) => {
      const result = await broadcastUnlike(id)
      return { txid: result.txid }
    },
  })
 
  return (
    <button onClick={handleToggle} disabled={isLoading}>
      {isLiked ? "Unlike" : "Like"} ({displayCount})
    </button>
  )
}

API Reference

LikeButton

PropTypeDefaultDescription
txidstring—Required. Transaction ID of the content to like
onLike(txid: string) => Promise<LikeResult>—Required. Called to broadcast a like action
onUnlike(txid: string) => Promise<LikeResult>—Called to broadcast an unlike action
countnumber0Current like count to display
likedbooleanfalseWhether the current user has already liked this content
onToggled(liked: boolean, result: LikeResult) => void—Called after a successful like/unlike
onError(error: Error) => void—Called when the action fails
useThumbsUpbooleanfalseUse a thumbs-up icon instead of a heart
variant"default" | "compact" | "text""default"Visual variant
disabledbooleanfalseDisable the button
classNamestring—Additional CSS classes

LikeResult

interface LikeResult {
  /** Transaction ID of the like/unlike action */
  txid?: string
  /** Raw transaction hex */
  rawtx?: string
  /** Error message if the action failed */
  error?: string
}

useLike Options

OptionTypeDefaultDescription
txidstring—Required. Transaction ID to like
onLike(txid: string) => Promise<LikeResult>—Required. Like broadcast callback
onUnlike(txid: string) => Promise<LikeResult>—Unlike broadcast callback
countnumber0Initial like count
likedbooleanfalseInitial liked state
onToggled(liked: boolean, result: LikeResult) => void—Success callback
onError(error: Error) => void—Error callback

useLike Return

PropertyTypeDescription
isLikedbooleanWhether the content is currently liked
displayCountnumberCurrent display count (updates optimistically)
isLoadingbooleanWhether a like/unlike action is in progress
handleToggle() => Promise<void>Toggle the like state