Skip to content

Commit

Permalink
Merge pull request #296 from LifeSG/handle-cleared-date-input
Browse files Browse the repository at this point in the history
Handle cleared and invalid date values for date inputs
  • Loading branch information
keithtxw authored Aug 30, 2023
2 parents 55914b5 + f513fcf commit 6f89545
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 27 deletions.
15 changes: 10 additions & 5 deletions src/date-input/date-input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
StandaloneDateInputRef,
} from "../shared/standalone-date-input/standalone-date-input";
import { MediaWidths } from "../spec/media-spec";
import { DateInputHelper } from "../util/date-input-helper";
import { DateInputHelper } from "../util";
import { Container } from "./date-input.style";
import { DateInputProps } from "./types";

Expand All @@ -34,8 +34,12 @@ export const DateInput = ({
// =============================================================================
// CONST, STATE, REF
// =============================================================================
const [initialDate, setInitialDate] = useState<string>(value);
const [selectedDate, setSelectedDate] = useState<string>(value);
const [initialDate, setInitialDate] = useState<string>(
DateInputHelper.sanitizeInput(value)
);
const [selectedDate, setSelectedDate] = useState<string>(
DateInputHelper.sanitizeInput(value)
);
const [hoveredDate, setHoveredDate] = useState<string>(undefined);
const [calendarOpen, setCalendarOpen] = useState<boolean>(false);

Expand All @@ -53,8 +57,9 @@ export const DateInput = ({
// EFFECTS
// =============================================================================
useEffect(() => {
setInitialDate(value);
setSelectedDate(value);
const newValue = DateInputHelper.sanitizeInput(value);
setInitialDate(newValue);
setSelectedDate(newValue);
}, [value]);

// =============================================================================
Expand Down
9 changes: 6 additions & 3 deletions src/date-range-input/date-range-input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
StandaloneDateInput,
StandaloneDateInputRef,
} from "../shared/standalone-date-input/standalone-date-input";
import { DateInputHelper } from "../util/date-input-helper";
import { DateHelper, DateInputHelper } from "../util";
import { useStateActions } from "../util/use-state-actions";
import {
Container,
Expand Down Expand Up @@ -172,7 +172,10 @@ export const DateRangeInput = ({
// EFFECTS
// =============================================================================
useEffect(() => {
actions.resetRange({ start: value, end: valueEnd });
actions.resetRange({
start: DateInputHelper.sanitizeInput(value),
end: DateInputHelper.sanitizeInput(valueEnd),
});
}, [value, valueEnd]);

useEffect(() => {
Expand Down Expand Up @@ -349,7 +352,7 @@ export const DateRangeInput = ({

const handleWeekSelectionInputFocus = () => {
if (isWeekSelection) {
const firstDayOfWeek = dayjs(selectedStart)
const firstDayOfWeek = DateHelper.toDayjs(selectedStart)
.startOf("week")
.format("YYYY-MM-DD");

Expand Down
10 changes: 7 additions & 3 deletions src/shared/internal-calendar/calendar-day-style-helper.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import dayjs, { Dayjs } from "dayjs";
import isBetween from "dayjs/plugin/isBetween";
import { FocusType } from "./types";
import { CalendarHelper } from "../../util";
import { CalendarHelper, DateHelper } from "../../util";
import { StyleProps } from "./internal-calendar-day.style";
import { OverflowCircleProps } from "./internal-week-selection-calendar-day.style";
import { HoverDirection } from "./internal-calendar-day";
Expand Down Expand Up @@ -381,8 +381,12 @@ const isOutsideSelectedRange = (
};

const getDayOfWeek = (value: string) => {
const firstDayOfWeek = dayjs(value).startOf("week").format("YYYY-MM-DD");
const lastDayOfWeek = dayjs(value).endOf("week").format("YYYY-MM-DD");
const firstDayOfWeek = DateHelper.toDayjs(value)
.startOf("week")
.format("YYYY-MM-DD");
const lastDayOfWeek = DateHelper.toDayjs(value)
.endOf("week")
.format("YYYY-MM-DD");

return {
firstDayOfWeek,
Expand Down
20 changes: 11 additions & 9 deletions src/shared/internal-calendar/calendar-manager.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import dayjs, { Dayjs } from "dayjs";
import React, { useEffect, useImperativeHandle, useRef, useState } from "react";
import { DateHelper } from "../../util";
import { CalendarHelper } from "../../util/calendar-helper";
import {
ActionButton,
Expand Down Expand Up @@ -61,11 +62,11 @@ const Component = (
// =============================================================================
// the current visible date in month/year views and header
const [calendarDate, setCalendarDate] = useState<Dayjs>(
dayjs(initialCalendarDate)
DateHelper.toDayjs(initialCalendarDate)
);
// the selected date in month/year views and the current visible date in day view
const [viewCalendarDate, setViewCalendarDate] = useState<Dayjs>(
dayjs(initialCalendarDate)
DateHelper.toDayjs(initialCalendarDate)
);
const [currentView, setCurrentView] = useState<View>("default");

Expand All @@ -82,22 +83,22 @@ const Component = (
setCurrentView("default");
},
resetView() {
const date = dayjs(initialCalendarDate);
const date = DateHelper.toDayjs(initialCalendarDate);
setCalendarDate(date);
setViewCalendarDate(date);

setCurrentView("default");
},
setCalendarDate(value?: string) {
const date = value ? dayjs(value) : dayjs();
const date = DateHelper.toDayjs(value);
setCalendarDate(date);
setViewCalendarDate(date);
},
};
});

useEffect(() => {
const date = initialCalendarDate ? dayjs(initialCalendarDate) : dayjs();
const date = DateHelper.toDayjs(initialCalendarDate);
setCalendarDate(date);
setViewCalendarDate(date);
}, [initialCalendarDate]);
Expand Down Expand Up @@ -187,8 +188,9 @@ const Component = (
};

const handleCancelButton = () => {
setCalendarDate(dayjs(initialCalendarDate));
setViewCalendarDate(dayjs(initialCalendarDate));
const initialValue = DateHelper.toDayjs(initialCalendarDate);
setCalendarDate(initialValue);
setViewCalendarDate(initialValue);

if (currentView === "default") {
performOnDismissHandler("reset");
Expand Down Expand Up @@ -279,14 +281,14 @@ const Component = (
} else {
return getYearHeaderLabel
? getYearHeaderLabel(calendarDate)
: dayjs(calendarDate).format("YYYY");
: calendarDate.format("YYYY");
}
};

const renderDropdownButtons = () => {
const monthLabel = getMonthHeaderLabel
? getMonthHeaderLabel(calendarDate)
: dayjs(calendarDate).format("MMM");
: calendarDate.format("MMM");
return (
<>
<DropdownButton
Expand Down
11 changes: 8 additions & 3 deletions src/time-slot-week-view/time-slot-week-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useEffect, useRef, useState } from "react";
import { CalendarManagerRef } from "../shared/internal-calendar";
import { CalendarManager } from "../shared/internal-calendar/calendar-manager";
import { TimeSlot } from "../time-slot-bar";
import { DateHelper } from "../util";
import { TimeSlotWeekDays } from "./time-slot-week-days";
import { Wrapper } from "./time-slot-week-view.styles";
import { TimeSlotWeekViewProps } from "./types";
Expand Down Expand Up @@ -82,6 +83,12 @@ export const TimeSlotWeekView = ({
}
};

const getInitialCalendarDate = () => {
return DateHelper.toDayjs(selectedDate || currentCalendarDate)
.endOf("week")
.format(DATE_FORMAT);
};

// =============================================================================
// RENDER FUNCTIONS
// =============================================================================
Expand All @@ -92,9 +99,7 @@ export const TimeSlotWeekView = ({
ref={calendarManagerRef}
type="standalone"
dynamicHeight
initialCalendarDate={dayjs(selectedDate || currentCalendarDate)
.endOf("week")
.format(DATE_FORMAT)}
initialCalendarDate={getInitialCalendarDate()}
selectedStartDate={selectedDate}
getLeftArrowDate={(day) => day.subtract(1, "week")}
getRightArrowDate={(day) => day.add(1, "week")}
Expand Down
6 changes: 5 additions & 1 deletion src/util/date-helper.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import dayjs from "dayjs";
import dayjs, { Dayjs } from "dayjs";

const MONTHS_WITH_31_DAYS = [1, 3, 5, 7, 8, 10, 12];
const MONTHS_WITH_30_DAYS = [4, 6, 9, 11];
Expand Down Expand Up @@ -80,4 +80,8 @@ export namespace DateHelper {
const endTime = dayjs(end, format);
return endTime.diff(startTime, "minute");
};

export const toDayjs = (date: string): Dayjs => {
return date ? dayjs(date) : dayjs();
};
}
13 changes: 10 additions & 3 deletions src/util/date-input-helper.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import dayjs from "dayjs";
import isBetween from "dayjs/plugin/isBetween";

dayjs.extend(isBetween);

export namespace DateInputHelper {
export const isDateDisabled = (
Expand Down Expand Up @@ -31,4 +28,14 @@ export namespace DateInputHelper {

return false;
};

export const sanitizeInput = (date: string): string => {
if (date) {
const day = dayjs(date);
if (day.isValid()) {
return date;
}
}
return "";
};
}
1 change: 1 addition & 0 deletions src/util/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from "./calendar-helper";
export * from "./date-helper";
export * from "./date-input-helper";
export * from "./simple-id-generator";
export * from "./string-helper";
export * from "./use-next-input-state";
Expand Down

0 comments on commit 6f89545

Please sign in to comment.