Skip to main content
Version: v0.23.2

Alarm & reminder time

A big clock you tap to change, with repeat days chosen through a multi-select list. The clock is the renderTrigger of a TimePickerField, so the field opens the picker and formats the time. The picker follows the design: wheels on iOS, Material's clock dial on Android, and time columns in a dropdown on the web.

Loading…
import { useState } from 'react';
import { Pressable, StyleSheet, Text, View } from 'react-native';
import {
  TimePickerField,
  SelectList,
  getWeekdayNames,
  usePickerTheme,
} from '@elik56a/react-native-pickers';

const days = getWeekdayNames(undefined, 'long').map((label, value) => ({
  label,
  value,
}));

export default function Alarm() {
  const { colors } = usePickerTheme();
  const [time, setTime] = useState(() => {
    const d = new Date();
    d.setHours(7, 30, 0, 0);
    return d;
  });
  const [repeat, setRepeat] = useState<number[]>([1, 2, 3, 4, 5]);

  return (
    <View style={styles.root}>
      <TimePickerField
        title="Alarm"
        confirmLabel="Set"
        value={time}
        onConfirm={setTime}
        minuteInterval={5}
        renderTrigger={({ open, displayValue }) => (
          <Pressable
            onPress={open}
            accessibilityRole="button"
            accessibilityLabel="Change alarm time"
            accessibilityHint={displayValue}
          >
            <Text style={[styles.clock, { color: colors.text }]}>{displayValue}</Text>
          </Pressable>
        )}
      />
      <Text style={[styles.caption, { color: colors.textSecondary }]}>Repeat</Text>
      <SelectList multiple options={days} value={repeat} onChange={setRepeat} />
    </View>
  );
}

const styles = StyleSheet.create({
  root: { gap: 8 },
  clock: {
    fontSize: 64,
    fontWeight: '200',
    textAlign: 'center',
    fontVariant: ['tabular-nums'],
  },
  caption: {
    fontSize: 12,
    fontWeight: '700',
    textTransform: 'uppercase',
    marginTop: 8,
    marginStart: 16,
  },
});

Next occurrence​

To schedule a notification, compute the next matching weekday:

function nextAlarm(time: Date, repeat: number[], from = new Date()): Date {
for (let i = 0; i < 8; i++) {
const d = new Date(from.getFullYear(), from.getMonth(), from.getDate() + i, time.getHours(), time.getMinutes());
if (d > from && (repeat.length === 0 || repeat.includes(d.getDay()))) return d;
}
return from;
}