Skip to content
Native Animation
Time Slot Picker animation preview

This preview uses fictional demo content. See the props below for the customization options available in this component.

npx nativeanimation add time-slot-picker
Picker

Time Slot Picker

An appointment picker that folds selected times into confirmation tickets, with configurable slots, dates, accent color, and fonts.

$9 for this animation

Add to your project

Copy the component and its assets into your app with the Native Animation CLI, or paste the agent prompt into Claude Code, Codex or Cursor once the MCP server is connected.

About this animation

An appointment picker that folds selected times into confirmation tickets, with configurable slots, dates, accent color, and fonts.

Why this one

The selected pill becomes the details card in its own row, keeping the user's place. Neighboring pills move aside, unavailable times draw their strike, and a time-zone change rolls the displayed times together with a column stagger. Booking takes two taps without navigating to another screen.

How it works

  1. onLayout measures the available container. Seven 44-point day targets scroll horizontally on narrow screens.
  2. A shared day position drives the sliding indicator; swipes and taps select the same state. A short outgoing transition precedes incoming columns.
  3. One shared booking phase drives the selected pill's width, position, row height, details opacity, folding, and ticket transfer: 0 is browsing, 1 is expanded, and 2 is confirmed.
  4. Time-zone labels use fixed minute offsets supplied by the host. Each time has a clipped, correctly measured rolling window that settles on one label.
  5. Confirmation calls onConfirm and announces the result. The host owns persistence, booking availability, and calendar integration.
  6. The demo controls the public ref, shows the expansion at 1.05 seconds, and stops autoplay on direct interaction.

Install

npx expo install expo-image react-native-gesture-handler react-native-reanimated react-native-worklets

Wrap your app in GestureHandlerRootView and configure Reanimated/worklets as required by your Expo project. No Skia setup or remote image assets are needed. Icons: Lucide (ISC), copied from the project kit and rendered as SVG sources by expo-image.

Usage

import TimeSlotPicker from './time-slot-picker';

export default function BookingScreen() {
  return <TimeSlotPicker />;
}
import { useRef } from 'react';
import { TimeSlotPicker, type TimeSlotPickerRef } from './time-slot-picker';

export default function CustomBookingScreen() {
  const picker = useRef<TimeSlotPickerRef>(null);
  return (
    <TimeSlotPicker
      ref={picker}
      accentColor="#7C4DDF"
      colorScheme="light"
      duration={45}
      springDamping={30}
      guide={{ name: 'Jamie Ellis', initials: 'JE', description: 'Mindfulness guide' }}
      timeZones={[
        { label: 'PT', offsetMinutes: 0 },
        { label: 'ET', offsetMinutes: 180 },
      ]}
    />
  );
}

Props

PropTypeDefaultDescription
slotsreadonly TimeSlot[]DEFAULT_SLOTSStable IDs, minutes after midnight, period, unavailable, fewLeft. Replace from your availability service.
datesreadonly string[]04/13–04/19Seven MM/DD labels beginning Monday.
timeZonesreadonly { label, offsetMinutes }[]PT, MT, CT, ETFixed display offsets relative to the first zone; supply date-aware offsets for production.
durationnumber45Session length in minutes.
guide{ name, initials, description }Generic guideDetails and initials avatar.
accentColorstring#8B5CF6Active surfaces and controls.
colorSchemelight / dark / autoautoDevice theme or explicit appearance.
fontFamilystringSystemInterface typeface.
monoFontFamilystringSystemTime typeface.
springDampingnumber28Clamped to at least 26.
confirmLabelstringConfirmConfirmation button label.
successLabelstringAdded to your calendarReceipt and announcement; connect calendar behavior in onConfirm.
onDayChange(day: number) => void—Zero-based day selection.
onSlotChange(booking: Booking) => void—Selected slot, day index, and time-zone label.
onConfirm(booking: Booking) => void—Confirmation integration point.
onInteraction() => void—Direct interaction; stops demo autoplay.
styleStyleProp<ViewStyle>—Root styles; use a bounded container.
testIDstring—Root test ID.

TimeSlotPickerRef: selectDay(index), selectSlot(id), confirm(), reset(), setTimeZone(index). Imperative actions do not call onInteraction. Slot minutes always remain in the first zone; offsets affect presentation only. This component does not reserve a booking or write a calendar event itself.

Compatibility

Expo SDK 58, React Native 0.88.0, Reanimated 4.7.1, Worklets 0.13.0, Gesture Handler 3.3.0, and expo-image 58.0.17. Uses modules bundled with this project's Expo Go environment. iOS, Android, and web are intended targets. No dependency or app configuration changes are included.

Accessibility

Buttons and day gestures expose roles, selection/disabled states, labels, and activation actions. Swiping days has an equivalent tap action. All interactive targets are at least 44 points. Day changes, slot selection, time-zone changes, and confirmation announce their result; the receipt also uses a polite live region. Reduced motion uses 200 ms fades, immediate layout changes, static numbers, and no flights or press scaling. In compact containers the slots scroll, keeping the footer and time-zone control available.

Demo timeline

0 ms reset; 450 ms Wednesday; 1,050 ms expand 9:30 AM; 2,450 ms confirm; 3,350 ms roll to ET; 5,200 ms repeat. A finger touch or explicit control activation cancels the loop. The demo's Aurora tile uses the kit's pink-to-violet gradient and sparkles glyph. Common typography is supplied only by the demo; the distributable component has no repository imports.