@firstform/spinnerwheel
v1.1.0
Published
React spinner wheel component for random selection with animations
Downloads
40
Maintainers
Readme
@firstform/spinnerwheel
A customizable React spinner wheel component for random selection with smooth animations, sound effects, and confetti celebrations.
Installation
npm install @firstform/spinnerwheelQuick Start
import { SpinnerWheel, useSpinnerWheelState } from '@firstform/spinnerwheel';
import '@firstform/spinnerwheel/styles';
function App() {
const wheel = useSpinnerWheelState({
initialEntries: [
{ id: '1', name: 'Pizza' },
{ id: '2', name: 'Burger' },
{ id: '3', name: 'Sushi' },
],
});
return (
<SpinnerWheel
entries={wheel.entries}
isSpinning={wheel.isSpinning}
winner={wheel.winner}
currentSegment={wheel.currentSegment}
showWinnerPopup={wheel.showWinnerPopup}
onEntriesChange={wheel.setEntries}
onSpin={wheel.spin}
onSpinComplete={wheel.handleSpinComplete}
onSegmentChange={wheel.handleSegmentChange}
onWinnerPopupClose={wheel.closeWinnerPopup}
/>
);
}Features
- Smooth spinning animations powered by GSAP
- Confetti celebration on winner selection
- Audio feedback (tick sounds and celebration)
- URL sync for shareable wheels
- Multiple color themes
- Dark and light theme variants
- Table and default layout options
- Fully typed with TypeScript
Components
SpinnerWheel
The main component that includes the wheel, entry management, and winner popup.
<SpinnerWheel
// Required props
entries={entries}
isSpinning={isSpinning}
winner={winner}
currentSegment={currentSegment}
showWinnerPopup={showWinnerPopup}
onEntriesChange={setEntries}
onSpin={spin}
onSpinComplete={handleSpinComplete}
onWinnerPopupClose={closeWinnerPopup}
// Optional props
canvasSize={465}
variant="white" // 'white' | 'dark'
layout="default" // 'default' | 'table'
showEntryInput={true}
audioEnabled={true}
confettiEnabled={true}
colorTheme="default" // 'rainbow' | 'sunset' | 'ocean' | 'forest' | etc.
spinDuration={10}
spinRevolutions={7}
/>SpinnerWheelCanvas
Just the wheel canvas without entry management UI.
import { SpinnerWheelCanvas } from '@firstform/spinnerwheel';
<SpinnerWheelCanvas
entries={entries}
isSpinning={isSpinning}
onSpinComplete={handleComplete}
onSegmentChange={handleSegmentChange}
onSpin={handleSpin}
/>Hooks
useSpinnerWheelState
Manages all wheel state with optional URL synchronization.
const wheel = useSpinnerWheelState({
initialEntries: [],
syncToUrl: true, // Sync entries to URL for sharing
onWinnerSelected: (winner) => console.log('Winner:', winner),
});
// Returns:
// - entries, isSpinning, winner, currentSegment, showWinnerPopup
// - setEntries, addEntries, removeEntry, clearEntries
// - spin, handleSpinComplete, handleSegmentChange, closeWinnerPopup, resetuseAudio
Control audio playback.
const audio = useAudio({ enabled: true });
audio.playTick();
audio.playCelebration();useConfetti
Trigger confetti effects.
const confetti = useConfetti({ enabled: true });
confetti.fire();Types
interface WheelEntry {
id: string;
name: string;
}
type ThemeVariant = 'white' | 'dark';
type LayoutVariant = 'default' | 'table';
type ColorTheme =
| 'default' | 'rainbow' | 'sunset' | 'ocean'
| 'forest' | 'candy' | 'neon' | 'pastel'
| 'blues' | 'reds' | 'greens' | 'earth' | 'retro';Color Themes
Choose from 13 built-in color themes:
default- Balanced mix of colorsrainbow- Full spectrumsunset- Warm oranges and redsocean- Blues and tealsforest- Greens and earth tonescandy- Bright pinks and purplesneon- Vibrant glowing colorspastel- Soft muted tonesblues/reds/greens- Monochromaticearth- Natural brown tonesretro- Vintage color palette
URL Sharing
Enable syncToUrl to automatically encode entries in the URL:
const wheel = useSpinnerWheelState({
syncToUrl: true,
});
// Get shareable URL
import { getShareableUrl } from '@firstform/spinnerwheel';
const url = getShareableUrl(entries);License
MIT
