Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle cleared and invalid date values #296

Merged
merged 3 commits into from
Aug 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to circumvent the behaviour where dayjs("") results in invalid day instead of returning the current day like dayjs(undefined)

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 => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this helps to convert invalid date strings like "2023-x-x" to an empty string (i.e. those values get ignored)

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