Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | 5x 5x 5x 5x 5x 5x 5x 5x 298x 298x 28x 5x 592x 592x 66x 29x 29x 29x 588x | import { TimePicker } from "@mui/x-date-pickers";
import { useTranslation } from "i18n";
import { GLOBAL } from "i18n/namespaces";
import React, { useMemo } from "react";
import { Control, Controller, UseControllerProps } from "react-hook-form";
import { Temporal } from "temporal-polyfill";
import { getMuiTimeFormat } from "utils/date";
import dayjs, { Dayjs } from "utils/dayjs";
interface TimepickerProps {
className?: string;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
control: Control<any>;
defaultValue?: Temporal.PlainTime;
error: boolean;
helperText: React.ReactNode;
id: string;
rules?: UseControllerProps["rules"];
label?: string;
name: string;
onPostChange?(value: Temporal.PlainTime | null): void;
testId?: string;
}
// Convert between our API's Temporal.PlainTime and MUI's expected Dayjs values.
// Use the browser timezone in case we compare to now, aka dayjs().
function temporalToDayjs(value: Temporal.PlainTime): Dayjs {
const timeString = value.toString({ smallestUnit: "minute" });
return dayjs(`1970-01-01T${timeString}`); // We don't care about the date, but dayjs needs one.
}
function dayjsToTemporal(value: Dayjs): Temporal.PlainTime {
return Temporal.PlainTime.from(value.format("HH:mm"));
}
const Timepicker = ({
className,
control,
defaultValue,
error,
helperText,
id,
rules,
label,
name,
onPostChange,
testId,
}: TimepickerProps) => {
const { t, i18n } = useTranslation([GLOBAL]);
const format = useMemo(
() => getMuiTimeFormat(i18n.language),
[i18n.language],
);
return (
<Controller
control={control}
defaultValue={defaultValue ?? null}
name={name}
rules={rules}
render={({ field }) => (
<TimePicker
data-testid={testId}
{...field}
label={label}
value={field.value ? temporalToDayjs(field.value) : null}
onChange={(valueDayjs: Dayjs | null) => {
const valueTemporal =
valueDayjs && valueDayjs.isValid()
? dayjsToTemporal(valueDayjs)
: null;
field.onChange(valueTemporal);
onPostChange?.(valueTemporal);
}}
format={format}
ampm={format.includes("a")} // Clock picker uses am/pm iff format also uses it
slotProps={{
textField: {
fullWidth: true,
id,
error,
helperText: (
<span data-testid={`${name}-helper-text`}>{helperText}</span>
),
variant: "standard",
InputProps: {
className,
"aria-label": t("global:change_time"),
},
slotProps: { inputLabel: { shrink: true } },
sx: {
"& .MuiOutlinedInput-root": {
backgroundColor: "var(--mui-palette-primary-main)",
color: "var(--mui-palette-text-primary)",
},
"& .MuiPaper-root": {
backgroundColor: "var(--mui-palette-primary-main)",
color: "var(--mui-palette-text-primary)",
},
},
},
}}
/>
)}
/>
);
};
export default Timepicker;
|