This commit is contained in:
Louis Mazin 2026-09-20 04:44:16 +02:00
parent ba5fd9bf85
commit 7c0ebd6923

View File

@ -335,6 +335,7 @@ const TimePicker = ({
placeholder = 'Choisir une heure',
}) => {
const [open, setOpen] = useState(false);
const touchStartY = useRef(null);
const [hours = '', minutes = ''] = value
? value.split(':')
@ -363,12 +364,9 @@ const TimePicker = ({
const changeHour = (direction) => {
const currentHour = Number(hours || 0);
const currentMinute = Number(
minutes || 0,
);
const currentMinute = Number(minutes || 0);
let nextHour =
currentHour + direction;
let nextHour = currentHour + direction;
if (nextHour < 0) nextHour = 23;
if (nextHour > 23) nextHour = 0;
@ -381,13 +379,9 @@ const TimePicker = ({
const changeMinute = (direction) => {
const currentHour = Number(hours || 0);
const currentMinute = Number(
minutes || 0,
);
let nextMinute =
currentMinute + direction;
const currentMinute = Number(minutes || 0);
let nextMinute = currentMinute + direction;
let nextHour = currentHour;
if (nextMinute < 0) {
@ -419,7 +413,7 @@ const TimePicker = ({
event.preventDefault();
event.stopPropagation();
// Un événement de molette = une seule unité
// Une molette = une seule unité
const direction =
event.deltaY > 0 ? 1 : -1;
@ -430,6 +424,44 @@ const TimePicker = ({
}
};
const handleTouchStart = (event) => {
touchStartY.current =
event.touches[0].clientY;
};
const handleTouchEnd = (
event,
type,
) => {
if (touchStartY.current === null) {
return;
}
const touchEndY =
event.changedTouches[0].clientY;
const deltaY =
touchStartY.current - touchEndY;
touchStartY.current = null;
// Ignore les tout petits mouvements
if (Math.abs(deltaY) < 20) {
return;
}
// Swipe vers le haut = +1
// Swipe vers le bas = -1
const direction =
deltaY > 0 ? 1 : -1;
if (type === 'hours') {
changeHour(direction);
} else {
changeMinute(direction);
}
};
const clearTime = () => {
onChange('');
setOpen(false);
@ -482,20 +514,30 @@ const TimePicker = ({
{/* HEURES */}
<div
className="flex-1"
className="flex-1 touch-none"
onWheel={(event) =>
handleWheel(
event,
'hours',
)
}
onTouchStart={handleTouchStart}
onTouchEnd={(event) =>
handleTouchEnd(
event,
'hours',
)
}
>
<div className="flex h-full flex-col items-center justify-center select-none">
<span className="h-9 text-sm text-muted-foreground/40">
{hourOptions[
(Number(hours || 0) + 23) %
24
]}
{
hourOptions[
(Number(hours || 0) +
23) %
24
]
}
</span>
<span className="flex h-9 w-full items-center justify-center rounded-md font-mono text-sm font-semibold tabular-nums">
@ -503,10 +545,13 @@ const TimePicker = ({
</span>
<span className="h-9 text-sm text-muted-foreground/40">
{hourOptions[
(Number(hours || 0) + 1) %
24
]}
{
hourOptions[
(Number(hours || 0) +
1) %
24
]
}
</span>
</div>
</div>
@ -520,21 +565,30 @@ const TimePicker = ({
{/* MINUTES */}
<div
className="flex-1"
className="flex-1 touch-none"
onWheel={(event) =>
handleWheel(
event,
'minutes',
)
}
onTouchStart={handleTouchStart}
onTouchEnd={(event) =>
handleTouchEnd(
event,
'minutes',
)
}
>
<div className="flex h-full flex-col items-center justify-center select-none">
<span className="h-9 text-sm text-muted-foreground/40">
{minuteOptions[
(Number(minutes || 0) +
59) %
60
]}
{
minuteOptions[
(Number(minutes || 0) +
59) %
60
]
}
</span>
<span className="flex h-9 w-full items-center justify-center rounded-md font-mono text-sm font-semibold tabular-nums">
@ -542,17 +596,20 @@ const TimePicker = ({
</span>
<span className="h-9 text-sm text-muted-foreground/40">
{minuteOptions[
(Number(minutes || 0) + 1) %
60
]}
{
minuteOptions[
(Number(minutes || 0) +
1) %
60
]
}
</span>
</div>
</div>
</div>
<p className="mt-2 text-center text-[10px] text-muted-foreground">
Molette pour modifier
Molette ou glissement pour modifier
</p>
<div className="mt-2 border-t pt-2">
@ -572,7 +629,6 @@ const TimePicker = ({
);
};
/* =========================================================
PAGE
========================================================= */