DocsWheel Carousel

Wheel Carousel

A cinematic, rotating-wheel picker with inertial drag and scroll controls, curved fading labels, and a crossfading image for the active item.

Installation

pnpm dlx shadcn@latest add @componentry/wheel-carousel

Usage

API Reference

PropertyTypeDefault
items

Your own option names and photos. Each entry takes a label and an image URL, plus an optional imageAlt.

WheelCarouselItem[]Built-in demo set
mode

Use automatic, fixed, or custom color behavior.

"system" | "light" | "dark" | "custom""system"
photoSide

Side of the wheel used for the active image.

"left" | "right""left"
photoWidth

Image column width as a percentage.

number24
photoAspect

Aspect ratio of the active image.

"3/4" | "1/1" | "4/3" | "3/2""3/4"
photoRadius

Corner radius of the active image in pixels.

number14
contentWidth

Maximum inner content width in pixels.

number900
gap

Space between the image column and the wheel in pixels.

number0
radius

Radius of the label wheel in pixels.

number320
spacing

Angular spacing between labels in degrees.

number14
visibleItems

Number of labels visible on either side of the selection.

number7
apexInset

Horizontal position of the wheel's selection point.

number34
snap

Settles the wheel on the nearest whole item.

booleantrue
momentum

Preserves drag and wheel velocity after input ends.

booleantrue
appear

Plays an entrance animation on mount.

booleantrue
crossfadeDuration

Duration in seconds of the active image crossfade.

number0.5
scrollSpeed

Rotation per wheel delta pixel.

number0.008
dragSpeed

Rotation per pointer pixel dragged.

number0.02
background

Canvas color in "custom" mode.

string"rgb(255, 246, 236)"
panelColor

Image placeholder color in "custom" mode. Defaults to background.

string—
textColor

Inactive label color in "custom" mode.

string"rgba(180, 90, 20, 0.45)"
selectedColor

Active label color in "custom" mode.

string"rgb(180, 84, 30)"
showMarker

Shows the dot marking the selection point.

booleantrue
markerColor

Selection dot color in "custom" mode.

string"rgb(232, 121, 46)"
markerSize

Selection dot diameter in pixels.

number16
markerGap

Distance between the selection dot and the labels.

number20
edgeFade

Fades labels at the top and bottom edges.

booleantrue
edgeFadeSize

Size of the edge fade as a percentage.

number30
activeIndex

Controlled active item index.

number—
initialIndex

Initially selected item in uncontrolled usage.

number0
onActiveChange

Runs whenever the active item changes.

(item: WheelCarouselItem, index: number) => void—
className

Additional classes for the outer carousel.

string—
photoClassName

Additional classes for the active image frame.

string—
itemClassName

Additional classes for each wheel label.

string—

View source

Click the icon in the preview panel to browse source for each variant.

Keep in mind

This component is inspired by various open-source projects and patterns. Please verify licenses and implementation details before using in production.

Need a custom component?

I build bespoke UI components & websites tailored to your brand.

DM me on X
Halcyon Fields
Halcyon Fields
Meridian House
Norlight Pavilion
Aperture Studio
Solene Tower
Verdant Mile
Cobalt Works
Lumen Atrium
Palladium Hall
Cirrus Offices
Bramble Cottage
Vellum Library
Halden Bridge
Ember & Ash
Slate Meridian
Halcyon Fields, item 1 of 24
import {
  WheelCarousel,
  type WheelCarouselItem,
} from "@/components/ui/wheel-carousel"
const projects: WheelCarouselItem[] = [
  {
    label: "Canyon House",
    image: "/images/projects/canyon-house.jpg",
    imageAlt: "Modern concrete home built into a desert canyon",
  },
  {
    label: "Harbor Loft",
    image: "/images/projects/harbor-loft.jpg",
    imageAlt: "Bright coastal loft with large windows",
  },
  {
    label: "Glass Pavilion",
    image: "/images/projects/glass-pavilion.jpg",
    imageAlt: "Minimal glass pavilion surrounded by trees",
  },
]

<div className="h-[680px] w-full">
  <WheelCarousel items={projects} />
</div>