Wheel Picker
A high-performance, iOS-style 3D physics-based wheel picker. Perfect for touch-friendly date, time, and custom value selections.
Installation
npx raya-ui@latest add wheel-pickerFile Structure
your-project
components
ui
wheel-picker
WheelPicker.vue
WheelPickerWrapper.vue
API Reference
WheelPicker Props
modelValuestring | numberThe selected value of the wheel. Bind using v-model.
optionsArray<{ value: any, label: string }>Array of objects detailing the available options in the picker.
infinitebooleanfalseIf true, the wheel loops seamlessly back to the beginning when scrolling past the end.
itemHeightnumber36The exact height of each row in pixels. Required for calculating the physics translation.
classNamesObjectProvides keys to inject custom Tailwind classes into container, highlightWrapper, and highlightItem.
Active State
09:41 AMSettings
Wheel wraps around limits seamlessly.
source-code.vue
<script setup lang="ts">
import { ref } from 'vue'
import { WheelPicker, WheelPickerWrapper } from '@/components/ui/wheel-picker'
const timeState = ref({ hour: 9, minute: 41, ampm: 'AM' })
const hours = Array.from({ length: 12 }, (_, i) => ({ value: i + 1, label: String(i + 1).padStart(2, '0') }))
const minutes = Array.from({ length: 60 }, (_, i) => ({ value: i, label: String(i).padStart(2, '0') }))
const meridiem = [{ value: 'AM', label: 'AM' }, { value: 'PM', label: 'PM' }]
</script>
<template>
<div class="relative flex h-56 w-64 flex-col items-center justify-center overflow-hidden rounded-3xl border border-border bg-background shadow-2xl">
<!-- Faux Device Notch -->
<div class="absolute top-0 left-1/2 z-20 h-6 w-24 -translate-x-1/2 rounded-b-xl bg-muted"></div>
<WheelPickerWrapper class="w-full px-6">
<WheelPicker v-model="timeState.hour" :options="hours" infinite />
<WheelPicker v-model="timeState.minute" :options="minutes" infinite />
<!-- AMPM generally shouldn't loop -->
<WheelPicker v-model="timeState.ampm" :options="meridiem" />
</WheelPickerWrapper>
</div>
</template>