add support for 24hr time to TimePicker

This commit is contained in:
Gimle Larpes 2025-07-25 01:05:53 +02:00
parent 78ac14eb6b
commit 77b551d004
3 changed files with 76 additions and 50 deletions

View file

@ -4,6 +4,8 @@ import dayjs from 'dayjs';
import * as css from './styles.css'; import * as css from './styles.css';
import { PickerColumn } from './PickerColumn'; import { PickerColumn } from './PickerColumn';
import { hour12to24, hour24to12, hoursToMs, inSameDay, minutesToMs } from '../../utils/time'; import { hour12to24, hour24to12, hoursToMs, inSameDay, minutesToMs } from '../../utils/time';
import { useSetting } from '../../state/hooks/settings';
import { settingsAtom } from '../../state/settings';
type TimePickerProps = { type TimePickerProps = {
min: number; min: number;
@ -13,9 +15,11 @@ type TimePickerProps = {
}; };
export const TimePicker = forwardRef<HTMLDivElement, TimePickerProps>( export const TimePicker = forwardRef<HTMLDivElement, TimePickerProps>(
({ min, max, value, onChange }, ref) => { ({ min, max, value, onChange }, ref) => {
const [hour24Clock] = useSetting(settingsAtom, 'hour24Clock');
const hour24 = dayjs(value).hour(); const hour24 = dayjs(value).hour();
const selectedHour = hour24to12(hour24); const selectedHour = hour24Clock ? hour24 : hour24to12(hour24);
const selectedMinute = dayjs(value).minute(); const selectedMinute = dayjs(value).minute();
const selectedPM = hour24 >= 12; const selectedPM = hour24 >= 12;
@ -24,7 +28,7 @@ export const TimePicker = forwardRef<HTMLDivElement, TimePickerProps>(
}; };
const handleHour = (hour: number) => { const handleHour = (hour: number) => {
const seconds = hoursToMs(hour12to24(hour, selectedPM)); const seconds = hoursToMs(hour24Clock ? hour : hour12to24(hour, selectedPM));
const lastSeconds = hoursToMs(hour24); const lastSeconds = hoursToMs(hour24);
const newValue = value + (seconds - lastSeconds); const newValue = value + (seconds - lastSeconds);
handleSubmit(newValue); handleSubmit(newValue);
@ -59,7 +63,22 @@ export const TimePicker = forwardRef<HTMLDivElement, TimePickerProps>(
<Menu className={css.PickerMenu} ref={ref}> <Menu className={css.PickerMenu} ref={ref}>
<Box direction="Row" gap="200" className={css.PickerContainer}> <Box direction="Row" gap="200" className={css.PickerContainer}>
<PickerColumn title="Hour"> <PickerColumn title="Hour">
{Array.from(Array(12).keys()) {hour24Clock
? Array.from(Array(24).keys()).map((hour) => (
<Chip
key={hour}
size="500"
variant={hour === selectedHour ? 'Primary' : 'Background'}
fill="None"
radii="300"
aria-selected={hour === selectedHour}
onClick={() => handleHour(hour)}
disabled={(minDay && hour < minHour24) || (maxDay && hour > maxHour24)}
>
<Text size="T300">{hour < 10 ? `0${hour}` : hour}</Text>
</Chip>
))
: Array.from(Array(12).keys())
.map((i) => { .map((i) => {
if (i === 0) return 12; if (i === 0) return 12;
return i; return i;
@ -101,6 +120,7 @@ export const TimePicker = forwardRef<HTMLDivElement, TimePickerProps>(
</Chip> </Chip>
))} ))}
</PickerColumn> </PickerColumn>
{!hour24Clock && (
<PickerColumn title="Period"> <PickerColumn title="Period">
<Chip <Chip
size="500" size="500"
@ -125,6 +145,7 @@ export const TimePicker = forwardRef<HTMLDivElement, TimePickerProps>(
<Text size="T300">PM</Text> <Text size="T300">PM</Text>
</Chip> </Chip>
</PickerColumn> </PickerColumn>
)}
</Box> </Box>
</Menu> </Menu>
); );

View file

@ -29,6 +29,8 @@ import { useRoom } from '../../../hooks/useRoom';
import { StateEvent } from '../../../../types/matrix/room'; import { StateEvent } from '../../../../types/matrix/room';
import { getToday, getYesterday, timeDayMonthYear, timeHourMinute } from '../../../utils/time'; import { getToday, getYesterday, timeDayMonthYear, timeHourMinute } from '../../../utils/time';
import { DatePicker, TimePicker } from '../../../components/time-date'; import { DatePicker, TimePicker } from '../../../components/time-date';
import { useSetting } from '../../../state/hooks/settings';
import { settingsAtom } from '../../../state/settings';
type JumpToTimeProps = { type JumpToTimeProps = {
onCancel: () => void; onCancel: () => void;
@ -45,6 +47,8 @@ export function JumpToTime({ onCancel, onSubmit }: JumpToTimeProps) {
const createTs = useMemo(() => createStateEvent?.getTs() ?? 0, [createStateEvent]); const createTs = useMemo(() => createStateEvent?.getTs() ?? 0, [createStateEvent]);
const [ts, setTs] = useState(() => Date.now()); const [ts, setTs] = useState(() => Date.now());
const [hour24Clock] = useSetting(settingsAtom, 'hour24Clock');
const [timePickerCords, setTimePickerCords] = useState<RectCords>(); const [timePickerCords, setTimePickerCords] = useState<RectCords>();
const [datePickerCords, setDatePickerCords] = useState<RectCords>(); const [datePickerCords, setDatePickerCords] = useState<RectCords>();
@ -125,7 +129,7 @@ export function JumpToTime({ onCancel, onSubmit }: JumpToTimeProps) {
after={<Icon size="50" src={Icons.ChevronBottom} />} after={<Icon size="50" src={Icons.ChevronBottom} />}
onClick={handleTimePicker} onClick={handleTimePicker}
> >
<Text size="B300">{timeHourMinute(ts)}</Text> <Text size="B300">{timeHourMinute(ts, hour24Clock)}</Text>
</Chip> </Chip>
<PopOut <PopOut
anchor={timePickerCords} anchor={timePickerCords}

View file

@ -9,7 +9,8 @@ export const today = (ts: number): boolean => dayjs(ts).isToday();
export const yesterday = (ts: number): boolean => dayjs(ts).isYesterday(); export const yesterday = (ts: number): boolean => dayjs(ts).isYesterday();
export const timeHour = (ts: number): string => dayjs(ts).format('hh'); export const timeHour = (ts: number, hour24Clock: boolean): string =>
dayjs(ts).format(hour24Clock ? 'HH' : 'hh');
export const timeMinute = (ts: number): string => dayjs(ts).format('mm'); export const timeMinute = (ts: number): string => dayjs(ts).format('mm');
export const timeAmPm = (ts: number): string => dayjs(ts).format('A'); export const timeAmPm = (ts: number): string => dayjs(ts).format('A');
export const timeDay = (ts: number): string => dayjs(ts).format('D'); export const timeDay = (ts: number): string => dayjs(ts).format('D');