All files / app/components Datepicker.tsx

88.23% Statements 15/17
62.5% Branches 5/8
75% Functions 3/4
87.5% Lines 14/16

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 111 112 113 114 115 116 117 118 119 120  9x 9x 9x 9x 9x 9x   9x   9x 1422x                                                 9x                                   1069x                               381x 381x                                                                                             911x  
import { InputProps } from "@mui/material";
import TextField from "@mui/material/TextField";
import { DatePicker, PickersDay } from "@mui/x-date-pickers";
import { useTranslation } from "i18n";
import { Control, Controller, UseControllerProps } from "react-hook-form";
import { theme } from "theme";
import dayjs, { Dayjs } from "utils/dayjs";
 
import { dateFormats } from "./constants";
 
const getLocaleFormat = () => {
  return navigator.language in dateFormats
    ? dateFormats[navigator.language as keyof typeof dateFormats]
    : "DD/MM/YYYY";
};
 
interface DatepickerProps {
  className?: string;
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  control: Control<any>;
  defaultValue?: Dayjs | null;
  error: boolean;
  helperText: React.ReactNode;
  id: string;
  rules?: UseControllerProps["rules"];
  label?: string;
  name: string;
  minDate?: Dayjs;
  maxDate?: Dayjs;
  openTo?: "year" | "month" | "day";
  onPostChange?(date: Dayjs | null): void;
  testId?: string;
  variant?: "standard" | "outlined" | "filled";
  inputProps?: InputProps;
}
 
const Datepicker = ({
  className,
  control,
  defaultValue,
  error,
  helperText,
  id,
  rules,
  label,
  minDate = dayjs(),
  maxDate,
  name,
  openTo = "day",
  onPostChange,
  testId,
  variant = "standard",
  inputProps = {},
}: DatepickerProps) => {
  const { t } = useTranslation();
  return (
    <Controller
      control={control}
      defaultValue={defaultValue}
      name={name}
      rules={rules}
      render={({ field }) => (
        <DatePicker
          data-testid={testId}
          {...field}
          label={label}
          value={field.value}
          minDate={minDate}
          maxDate={maxDate}
          onChange={(date) => {
            field.onChange(date);
            onPostChange?.(date);
          }}
          openTo={openTo}
          views={["year", "month", "day"]}
          inputFormat={getLocaleFormat()}
          renderDay={(day, selectedDates, pickersDayProps) => {
            const { key, ...otherProps } = pickersDayProps;
            return (
              <PickersDay
                key={key} // Pass key explicitly to make React happy
                {...otherProps}
                style={{
                  ...(pickersDayProps.selected && {
                    backgroundColor: theme.palette.primary.main, // make selected day our primary color
                  }),
                }}
              />
            );
          }}
          renderInput={(props) => (
            <TextField
              {...props}
              fullWidth
              id={id}
              error={error}
              helperText={
                <span data-testid={`${name}-helper-text`}>{helperText}</span>
              }
              data-testid={testId}
              InputLabelProps={{
                shrink: true,
              }}
              InputProps={{
                ...props.InputProps,
                ...inputProps,
                className,
                "aria-label": t("components.datepicker.change_date"),
              }}
              variant={variant}
            />
          )}
        />
      )}
    />
  );
};
 
export default Datepicker;