Documentation Index
Fetch the complete documentation index at: https://docs.fanfare.io/llms.txt
Use this file to discover all available pages before exploring further.
Auction Widget
The Auction Widget provides a complete real-time bidding experience with current bid display, bid form, bid history, and countdown timer.
Web Component
<fanfare-auction-widget
auction-id="auction_123"
show-header="true"
show-bid-history="true"
show-countdown="true"
currency-code="USD"
/>
Attributes
| Attribute | Type | Default | Description |
|---|
auction-id | string | Required | The auction identifier |
show-header | string | "true" | Show title and description |
show-bid-history | string | "true" | Show recent bid history |
show-countdown | string | "true" | Show countdown timer |
currency-code | string | "USD" | Currency for bid display |
container-class | string | - | Custom CSS class for container |
Events
| Event | Detail | Description |
|---|
fanfare-auction-bid | { auctionId, amount: number } | Bid placed |
fanfare-auction-outbid | { auctionId, newBid: number } | User was outbid |
fanfare-auction-win | { auctionId, amount: number } | User won auction |
fanfare-auction-proceed | { auctionId, token: string } | User proceeding to pay |
Event Handling Example
import { useEffect, useRef, useState } from "react";
function AuctionPage() {
const widgetRef = useRef<HTMLElement>(null);
const [outbidAlert, setOutbidAlert] = useState(false);
useEffect(() => {
const widget = widgetRef.current;
if (!widget) return;
const handleBid = (e: CustomEvent<{ amount: number }>) => {
console.log("Bid placed:", e.detail.amount);
analytics.track("auction_bid", { amount: e.detail.amount });
};
const handleOutbid = (e: CustomEvent<{ newBid: number }>) => {
setOutbidAlert(true);
// Play notification sound
new Audio("/sounds/outbid.mp3").play();
setTimeout(() => setOutbidAlert(false), 5000);
};
const handleWin = (e: CustomEvent) => {
console.log("Auction won!");
showConfetti();
};
const handleProceed = (e: CustomEvent<{ token: string }>) => {
window.location.href = `/checkout?token=${e.detail.token}`;
};
widget.addEventListener("fanfare-auction-bid", handleBid);
widget.addEventListener("fanfare-auction-outbid", handleOutbid);
widget.addEventListener("fanfare-auction-win", handleWin);
widget.addEventListener("fanfare-auction-proceed", handleProceed);
return () => {
widget.removeEventListener("fanfare-auction-bid", handleBid);
widget.removeEventListener("fanfare-auction-outbid", handleOutbid);
widget.removeEventListener("fanfare-auction-win", handleWin);
widget.removeEventListener("fanfare-auction-proceed", handleProceed);
};
}, []);
return (
<div className="auction-container">
{outbidAlert && <div className="outbid-alert">You have been outbid! Place a higher bid to stay in the lead.</div>}
<h1>Exclusive Item Auction</h1>
<fanfare-auction-widget ref={widgetRef} auction-id="auction_123" />
</div>
);
}
Auction Status States
The widget handles these auction states automatically:
| Status | Description | UI Display |
|---|
open | Auction is active | Bid form + Current bid |
winning | User has highest bid | Winning status + Timer |
outbid | User was outbid | Outbid alert + Quick rebid |
won | User won the auction | Winner message + Proceed CTA |
lost | Auction ended, user lost | Auction ended message |
ended | Auction has ended | Final results |
Styling
CSS Variables
fanfare-auction-widget {
--fanfare-primary: #ef4444;
--fanfare-primary-hover: #dc2626;
--fanfare-success: #22c55e;
--fanfare-warning: #f59e0b;
--fanfare-background: #ffffff;
--fanfare-foreground: #1f2937;
--fanfare-radius: 0.5rem;
}
Outbid Notifications
function AuctionWithPushNotifications() {
const widgetRef = useRef<HTMLElement>(null);
useEffect(() => {
const widget = widgetRef.current;
if (!widget) return;
const handleOutbid = async (e: CustomEvent<{ newBid: number }>) => {
// Browser notification (if permission granted)
if (Notification.permission === "granted") {
new Notification("You've been outbid!", {
body: `New high bid: $${e.detail.newBid}`,
icon: "/icons/auction.png",
});
}
};
widget.addEventListener("fanfare-auction-outbid", handleOutbid);
return () => widget.removeEventListener("fanfare-auction-outbid", handleOutbid);
}, []);
return <fanfare-auction-widget ref={widgetRef} auction-id="auction_123" />;
}
Using with React Hook (Alternative)
For more control, use the useAuction hook instead:
import { useAuction } from "@waitify-io/fanfare-sdk-react";
import { useState } from "react";
function CustomAuctionUI() {
const { auction, status, currentBid, myBid, minNextBid, bidHistory, timeRemaining, isWinning, placeBid, isLoading } =
useAuction("auction_123");
const [bidAmount, setBidAmount] = useState(minNextBid);
const handleSubmitBid = async () => {
await placeBid(bidAmount);
setBidAmount(minNextBid);
};
if (status === "won") {
return (
<div className="winner">
<h2>Congratulations! You Won!</h2>
<p>Winning bid: ${myBid}</p>
<a href="/checkout">Complete Purchase</a>
</div>
);
}
return (
<div className="auction-ui">
<div className="current-bid">
<span>Current Bid:</span>
<span className="amount">${currentBid}</span>
</div>
{isWinning && <div className="winning-badge">You are winning!</div>}
{timeRemaining && <div className="countdown">Time left: {formatTime(timeRemaining)}</div>}
<div className="bid-form">
<input
type="number"
value={bidAmount}
onChange={(e) => setBidAmount(Number(e.target.value))}
min={minNextBid}
step={10}
/>
<button onClick={handleSubmitBid} disabled={isLoading}>
{isLoading ? "Placing Bid..." : `Bid $${bidAmount}`}
</button>
</div>
<div className="bid-history">
<h4>Recent Bids</h4>
{bidHistory.slice(0, 5).map((bid) => (
<div key={bid.id} className="bid-entry">
<span>${bid.amount}</span>
<span>{bid.userLabel}</span>
</div>
))}
</div>
</div>
);
}
TypeScript Declaration
declare namespace JSX {
interface IntrinsicElements {
"fanfare-auction-widget": React.DetailedHTMLProps<
React.HTMLAttributes<HTMLElement> & {
"auction-id": string;
"show-header"?: string;
"show-bid-history"?: string;
"show-countdown"?: string;
"currency-code"?: string;
"container-class"?: string;
},
HTMLElement
>;
}
}