fix: SW-710 Datepicker UI/UX updates

This commit is contained in:
Hrishikesh Vaipurkar
2024-10-31 09:18:33 +01:00
parent 256f4dfce3
commit 71c7f3c0a4
3 changed files with 34 additions and 33 deletions

View File

@@ -1,5 +1,6 @@
"use client" "use client"
import { useState } from "react"
import { DayPicker } from "react-day-picker" import { DayPicker } from "react-day-picker"
import { useIntl } from "react-intl" import { useIntl } from "react-intl"
@@ -26,12 +27,19 @@ export default function DatePickerDesktop({
}: DatePickerProps) { }: DatePickerProps) {
const lang = useLang() const lang = useLang()
const intl = useIntl() const intl = useIntl()
const [month, setMonth] = useState(new Date())
/** English is default language and doesn't need to be imported */ /** English is default language and doesn't need to be imported */
const locale = lang === Lang.en ? undefined : locales[lang] const locale = lang === Lang.en ? undefined : locales[lang]
const currentDate = dt().toDate() const currentDate = dt().toDate()
const startOfMonth = dt(currentDate).set("date", 1).toDate() const startOfMonth = dt(currentDate).set("date", 1).toDate()
const yesterday = dt(currentDate).subtract(1, "day").toDate() const yesterday = dt(currentDate).subtract(1, "day").toDate()
const endDate = dt().add(365, "day").toDate()
const endOfLastMonth = dt(endDate).endOf("month").toDate()
function handleMonthChange(selected: Date) {
setMonth(selected)
}
return ( return (
<DayPicker <DayPicker
classNames={{ classNames={{
@@ -49,7 +57,10 @@ export default function DatePickerDesktop({
week: styles.week, week: styles.week,
weekday: `${classNames.weekday} ${styles.weekDay}`, weekday: `${classNames.weekday} ${styles.weekDay}`,
}} }}
disabled={{ from: startOfMonth, to: yesterday }} disabled={[
{ from: startOfMonth, to: yesterday },
{ from: endDate, to: endOfLastMonth },
]}
excludeDisabled excludeDisabled
footer footer
formatters={{ formatters={{
@@ -60,12 +71,14 @@ export default function DatePickerDesktop({
lang={lang} lang={lang}
locale={locale} locale={locale}
mode="range" mode="range"
month={month}
numberOfMonths={2} numberOfMonths={2}
onDayClick={handleOnSelect} onDayClick={handleOnSelect}
pagedNavigation onMonthChange={handleMonthChange}
required={false} required={false}
selected={selectedDate} selected={selectedDate}
startMonth={currentDate} startMonth={currentDate}
endMonth={endDate}
weekStartsOn={1} weekStartsOn={1}
components={{ components={{
Chevron(props) { Chevron(props) {

View File

@@ -1,5 +1,4 @@
"use client" "use client"
import { type ChangeEvent, useState } from "react"
import { DayPicker } from "react-day-picker" import { DayPicker } from "react-day-picker"
import { useIntl } from "react-intl" import { useIntl } from "react-intl"
@@ -17,34 +16,23 @@ import classNames from "react-day-picker/style.module.css"
import type { DatePickerProps } from "@/types/components/datepicker" import type { DatePickerProps } from "@/types/components/datepicker"
function addOneYear(_: undefined, i: number) {
return new Date().getFullYear() + i
}
const fiftyYearsAhead = Array.from({ length: 50 }, addOneYear)
export default function DatePickerMobile({ export default function DatePickerMobile({
close, close,
handleOnSelect, handleOnSelect,
locales, locales,
selectedDate, selectedDate,
}: DatePickerProps) { }: DatePickerProps) {
const [selectedYear, setSelectedYear] = useState(() => dt().year())
const lang = useLang() const lang = useLang()
const intl = useIntl() const intl = useIntl()
function handleSelectYear(evt: ChangeEvent<HTMLSelectElement>) {
setSelectedYear(Number(evt.currentTarget.value))
}
/** English is default language and doesn't need to be imported */ /** English is default language and doesn't need to be imported */
const locale = lang === Lang.en ? undefined : locales[lang] const locale = lang === Lang.en ? undefined : locales[lang]
const currentDate = dt().toDate() const currentDate = dt().toDate()
const startOfCurrentMonth = dt(currentDate).set("date", 1).toDate() const startOfCurrentMonth = dt(currentDate).set("date", 1).toDate()
const yesterday = dt(currentDate).subtract(1, "day").toDate() const yesterday = dt(currentDate).subtract(1, "day").toDate()
const startMonth = dt().set("year", selectedYear).startOf("year").toDate() const endDate = dt().add(365, "day").toDate()
const decemberOfYear = dt().set("year", selectedYear).endOf("year").toDate() const endOfLastMonth = dt(endDate).endOf("month").toDate()
return ( return (
<DayPicker <DayPicker
classNames={{ classNames={{
@@ -63,8 +51,11 @@ export default function DatePickerMobile({
week: styles.week, week: styles.week,
weekday: `${classNames.weekday} ${styles.weekDay}`, weekday: `${classNames.weekday} ${styles.weekDay}`,
}} }}
disabled={{ from: startOfCurrentMonth, to: yesterday }} disabled={[
endMonth={decemberOfYear} { from: startOfCurrentMonth, to: yesterday },
{ from: endDate, to: endOfLastMonth },
]}
endMonth={endDate}
excludeDisabled excludeDisabled
footer footer
formatters={{ formatters={{
@@ -77,11 +68,11 @@ export default function DatePickerMobile({
locale={locale} locale={locale}
mode="range" mode="range"
/** Showing full year or what's left of it */ /** Showing full year or what's left of it */
numberOfMonths={12} numberOfMonths={13}
onDayClick={handleOnSelect} onDayClick={handleOnSelect}
required required
selected={selectedDate} selected={selectedDate}
startMonth={startMonth} startMonth={currentDate}
weekStartsOn={1} weekStartsOn={1}
components={{ components={{
Footer(props) { Footer(props) {
@@ -115,17 +106,6 @@ export default function DatePickerMobile({
return ( return (
<div {...props}> <div {...props}>
<header className={styles.header}> <header className={styles.header}>
<select
className={styles.select}
defaultValue={selectedYear}
onChange={handleSelectYear}
>
{fiftyYearsAhead.map((year) => (
<option key={year} value={year}>
{year}
</option>
))}
</select>
<button className={styles.close} onClick={close} type="button"> <button className={styles.close} onClick={close} type="button">
<CloseLargeIcon /> <CloseLargeIcon />
</button> </button>

View File

@@ -48,7 +48,7 @@ export default function DatePickerForm({ name = "date" }: DatePickerFormProps) {
toDate: undefined, toDate: undefined,
}) })
setIsSelectingFrom(false) setIsSelectingFrom(false)
} else { } else if (!dt(selectedDate.fromDate).isSame(dt(selected))) {
const fromDate = dt(selectedDate.fromDate) const fromDate = dt(selectedDate.fromDate)
const toDate = dt(selected) const toDate = dt(selected)
if (toDate.isAfter(fromDate)) { if (toDate.isAfter(fromDate)) {
@@ -70,6 +70,14 @@ export default function DatePickerForm({ name = "date" }: DatePickerFormProps) {
function handleClickOutside(evt: Event) { function handleClickOutside(evt: Event) {
const target = evt.target as HTMLElement const target = evt.target as HTMLElement
if (ref.current && target && !ref.current.contains(target)) { if (ref.current && target && !ref.current.contains(target)) {
if (!selectedDate.toDate) {
setValue(name, {
fromDate: selectedDate.fromDate,
toDate: dt(selectedDate.fromDate)
.add(1, "day")
.format("YYYY-MM-DD"),
})
}
setIsOpen(false) setIsOpen(false)
} }
} }
@@ -77,7 +85,7 @@ export default function DatePickerForm({ name = "date" }: DatePickerFormProps) {
return () => { return () => {
document.body.removeEventListener("click", handleClickOutside) document.body.removeEventListener("click", handleClickOutside)
} }
}, [setIsOpen]) }, [setIsOpen, setValue, selectedDate, name])
const selectedFromDate = dt(selectedDate.fromDate) const selectedFromDate = dt(selectedDate.fromDate)
.locale(lang) .locale(lang)