Use native OS time picker on mobile for event times.
EventTimeInput24h switches to input type=time on touch devices while keeping dual selects on desktop for reliable 24h entry. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+7
-1
@@ -148,7 +148,8 @@ select.input-text {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.time-input-24h__select {
|
.time-input-24h__select,
|
||||||
|
.time-input-24h__native {
|
||||||
flex: 1 1 0;
|
flex: 1 1 0;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
padding-left: 12px;
|
padding-left: 12px;
|
||||||
@@ -157,6 +158,11 @@ select.input-text {
|
|||||||
font-variant-numeric: tabular-nums;
|
font-variant-numeric: tabular-nums;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input[type='time'].time-input-24h__native {
|
||||||
|
color-scheme: inherit;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
.time-input-24h__sep {
|
.time-input-24h__sep {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { useId, useMemo } from 'react'
|
import { useId, useMemo } from 'react'
|
||||||
import { joinTimeHHMM, splitTimeHHMM } from '../utils/logEntryPayload.js'
|
import { joinTimeHHMM, splitTimeHHMM } from '../utils/logEntryPayload.js'
|
||||||
|
import { preferNativeCameraPicker } from '../utils/captureVideoFrame.js'
|
||||||
|
|
||||||
const HOURS = Array.from({ length: 24 }, (_, i) => String(i).padStart(2, '0'))
|
const HOURS = Array.from({ length: 24 }, (_, i) => String(i).padStart(2, '0'))
|
||||||
const MINUTES = Array.from({ length: 60 }, (_, i) => String(i).padStart(2, '0'))
|
const MINUTES = Array.from({ length: 60 }, (_, i) => String(i).padStart(2, '0'))
|
||||||
@@ -18,7 +19,29 @@ export default function EventTimeInput24h({
|
|||||||
'aria-label': ariaLabel
|
'aria-label': ariaLabel
|
||||||
}: EventTimeInput24hProps) {
|
}: EventTimeInput24hProps) {
|
||||||
const baseId = useId()
|
const baseId = useId()
|
||||||
|
const useNativePicker = preferNativeCameraPicker()
|
||||||
const { hours, minutes } = useMemo(() => splitTimeHHMM(value), [value])
|
const { hours, minutes } = useMemo(() => splitTimeHHMM(value), [value])
|
||||||
|
const timeValue = useMemo(() => joinTimeHHMM(hours, minutes), [hours, minutes])
|
||||||
|
|
||||||
|
if (useNativePicker) {
|
||||||
|
return (
|
||||||
|
<div className="time-input-24h">
|
||||||
|
<input
|
||||||
|
id={baseId}
|
||||||
|
type="time"
|
||||||
|
step={60}
|
||||||
|
className="input-text time-input-24h__native"
|
||||||
|
value={timeValue}
|
||||||
|
onChange={(e) => {
|
||||||
|
const next = e.target.value
|
||||||
|
if (next) onChange(next.slice(0, 5))
|
||||||
|
}}
|
||||||
|
disabled={disabled}
|
||||||
|
aria-label={ariaLabel}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="time-input-24h">
|
<div className="time-input-24h">
|
||||||
|
|||||||
Reference in New Issue
Block a user