- Overview
- Technical Architecture
- Getting Started
- Install
- Usage
- API Reference
- Customization
- Contributing
- License
React Prize Wheel is a customizable and interactive spinning wheel component built with React and TypeScript. Create a prize wheel with various options and spin it to select a random prize. Easily integrate into any React project and style to match your brand.
- Framework: React (TypeScript)
- Rendering: Uses HTML5 Canvas for smooth, animated wheel rendering
- Customization: Props for segments, animation, pointer, theme, and callbacks
- Integration: Works with any React app, supports custom event handlers
- Testing: Includes unit tests for core logic and rendering
Clone the repository and run locally:
pnpm install
pnpm devOpen http://localhost:3000 in your browser.
pnpm add react-prize-wheel
# or
npm install react-prize-wheel
# or
yarn add react-prize-wheelimport { SpinWheel, type WheelSegment } from "react-prize-wheel";
const segments: WheelSegment[] = [
{ id: "1", text: "Prize 1", color: "#ff6b6b" },
{ id: "2", text: "Prize 2", color: "#4ecdc4" },
{ id: "3", text: "Prize 3", color: "#45b7d1" },
];
function App() {
const handleSpinComplete = (result) => {
alert(`Spin completed! You won: ${result.segment.text}`);
};
return (
<SpinWheel
segments={segments}
size={400}
animation={{ duration: 4000, easing: "ease-out", spins: 8 }}
pointer={{ style: "arrow", color: "#e74c3c", position: "top" }}
theme={{ background: "#fff", border: "#ccc", text: "#222" }}
onSpinComplete={handleSpinComplete}
showSpinButton={true}
spinButtonText="SPIN NOW"
/>
);
}- Use
segmentsfor wheel options (each must haveid,text,color) - Control animation with the
animationprop (duration, easing, spins) - Customize pointer style and position
- Use
predefinedResultfor testing (by segment id or index) - Use
onSpinCompleteto handle the result
| Prop | Type | Default | Description |
|---|---|---|---|
segments |
WheelSegment[] |
- | Array of segments to display |
size |
number |
400 |
Size of the wheel in pixels |
onSpinComplete |
(result: SpinResult) => void |
- | Callback when spin completes |
onSpinStart |
() => void |
- | Callback when spin starts |
animation |
Partial<AnimationConfig> |
- | Animation configuration |
pointer |
Partial<PointerConfig> |
- | Pointer configuration |
theme |
Partial<WheelTheme> |
- | Theme configuration |
disabled |
boolean |
false |
Whether the wheel is disabled |
showSpinButton |
boolean |
true |
Whether to show the spin button |
spinButtonText |
string |
'SPIN' |
Custom spin button text |
predefinedResult |
number | string |
- | Predefined result for testing |
interface WheelSegment {
id: string;
text: string;
color: string;
textColor?: string;
weight?: number;
borderColor?: string;
borderWidth?: number;
disabled?: boolean;
}interface SpinResult {
segment: WheelSegment;
index: number;
angle: number;
duration: number;
timestamp: number;
}interface AnimationConfig {
duration: number;
easing: 'linear' | 'ease-in' | 'ease-out' | 'ease-in-out';
spins: number;
}interface PointerConfig {
style: 'arrow' | 'triangle' | 'circle';
color: string;
size: number;
position: 'top' | 'right' | 'bottom' | 'left';
}interface WheelTheme {
background: string;
border: string;
text: string;
}const weightedSegments = [
{ id: '1', text: 'Common Prize', color: '#e74c3c', weight: 3 },
{ id: '2', text: 'Rare Prize', color: '#f39c12', weight: 1 },
{ id: '3', text: 'Epic Prize', color: '#9b59b6', weight: 0.5 },
];<SpinWheel
segments={segments}
animation={{
duration: 4000, // 4 seconds
easing: 'ease-out', // CSS easing function
spins: 8, // Number of rotations
}}
/><SpinWheel
segments={segments}
pointer={{
style: 'arrow', // 'arrow', 'triangle', 'circle'
color: '#e74c3c', // Pointer color
size: 25, // Size in pixels
position: 'top', // 'top', 'right', 'bottom', 'left'
}}
/><SpinWheel
segments={segments}
theme={{
background: '#ffffff', // Wheel background
border: '#dee2e6', // Border color
text: '#212529', // Text color
}}
/>Contributions, issues and feature requests are welcome! Please:
- Fork the repo and submit a PR
- Open issues for bugs or feature requests
- See issues page
This project is MIT Licensed.
See the official npm documentation or open an issue on GitHub.
