refactor(SW-649): DateSelect component state refactoring
This commit is contained in:
@@ -28,6 +28,22 @@ export default function DateSelect({ name, registerOptions = {} }: DateProps) {
|
||||
rules: registerOptions,
|
||||
})
|
||||
|
||||
const dayLabel = intl.formatMessage({ id: "Day" })
|
||||
const monthLabel = intl.formatMessage({ id: "Month" })
|
||||
const yearLabel = intl.formatMessage({ id: "Year" })
|
||||
|
||||
const initialDate = dt(currentValue)
|
||||
|
||||
const [selectedYear, setSelectedYear] = useState<number | null>(
|
||||
initialDate.isValid() ? initialDate.year() : null
|
||||
)
|
||||
const [selectedMonth, setSelectedMonth] = useState<number | null>(
|
||||
initialDate.isValid() ? initialDate.month() : null
|
||||
)
|
||||
const [selectedDay, setSelectedDay] = useState<number | null>(
|
||||
initialDate.isValid() ? initialDate.date() : null
|
||||
)
|
||||
|
||||
const currentYear = new Date().getFullYear()
|
||||
|
||||
const months = rangeArray(1, 12).map((month) => ({
|
||||
@@ -39,32 +55,60 @@ export default function DateSelect({ name, registerOptions = {} }: DateProps) {
|
||||
.reverse()
|
||||
.map((year) => ({ value: year, label: year.toString() }))
|
||||
|
||||
// Ensure the user can't select a date that doesn't exist.
|
||||
const daysInMonth = dt(currentValue).daysInMonth()
|
||||
// Get max days based on selected month/year
|
||||
const daysInMonth =
|
||||
selectedMonth !== null && selectedYear !== null
|
||||
? dt(`${selectedYear}-${selectedMonth + 1}-01`).daysInMonth()
|
||||
: 31
|
||||
|
||||
const days = rangeArray(1, daysInMonth).map((day) => ({
|
||||
value: day,
|
||||
label: `${day}`,
|
||||
}))
|
||||
|
||||
function createOnSelect(selector: DateName) {
|
||||
/**
|
||||
* Months are 0 index based and therefore we
|
||||
* must subtract by 1 to get the selected month
|
||||
*/
|
||||
return (select: Key) => {
|
||||
if (selector === DateName.month) {
|
||||
select = Number(select) - 1
|
||||
function handleSegmentChange(selector: DateName, value: number) {
|
||||
let newYear = selectedYear
|
||||
let newMonth = selectedMonth
|
||||
let newDay = selectedDay
|
||||
|
||||
switch (selector) {
|
||||
case DateName.year:
|
||||
newYear = value
|
||||
setSelectedYear(newYear)
|
||||
break
|
||||
/**
|
||||
* Months are 0 index based and therefore we
|
||||
* must subtract by 1 to get the selected month
|
||||
*/
|
||||
case DateName.month:
|
||||
const monthZeroBased = value - 1
|
||||
newMonth = monthZeroBased
|
||||
setSelectedMonth(newMonth)
|
||||
if (selectedDay) {
|
||||
const maxDays = dt(`${newYear}-${value}-01`).daysInMonth()
|
||||
if (selectedDay > maxDays) {
|
||||
newDay = maxDays
|
||||
setSelectedDay(newDay)
|
||||
}
|
||||
}
|
||||
break
|
||||
case DateName.date:
|
||||
newDay = value
|
||||
setSelectedDay(newDay)
|
||||
break
|
||||
}
|
||||
|
||||
// Check if all segments are set and update form value.
|
||||
if (newYear && newMonth !== null && newDay) {
|
||||
const newDate = dt().year(newYear).month(newMonth).date(newDay)
|
||||
|
||||
if (newDate.isValid()) {
|
||||
setValue(name, newDate.format("YYYY-MM-DD"))
|
||||
trigger(name)
|
||||
}
|
||||
const newDate = dt(currentValue).set(selector, Number(select))
|
||||
setValue(name, newDate.format("YYYY-MM-DD"))
|
||||
trigger(name)
|
||||
}
|
||||
}
|
||||
|
||||
const dayLabel = intl.formatMessage({ id: "Day" })
|
||||
const monthLabel = intl.formatMessage({ id: "Month" })
|
||||
const yearLabel = intl.formatMessage({ id: "Year" })
|
||||
|
||||
let dateValue = null
|
||||
try {
|
||||
/**
|
||||
@@ -98,7 +142,9 @@ export default function DateSelect({ name, registerOptions = {} }: DateProps) {
|
||||
items={days}
|
||||
label={dayLabel}
|
||||
name={DateName.date}
|
||||
onSelect={createOnSelect(DateName.date)}
|
||||
onSelect={(select: Key) =>
|
||||
handleSegmentChange(DateName.date, Number(select))
|
||||
}
|
||||
placeholder="DD"
|
||||
required
|
||||
tabIndex={3}
|
||||
@@ -117,7 +163,9 @@ export default function DateSelect({ name, registerOptions = {} }: DateProps) {
|
||||
items={months}
|
||||
label={monthLabel}
|
||||
name={DateName.month}
|
||||
onSelect={createOnSelect(DateName.month)}
|
||||
onSelect={(select: Key) =>
|
||||
handleSegmentChange(DateName.month, Number(select))
|
||||
}
|
||||
placeholder="MM"
|
||||
required
|
||||
tabIndex={2}
|
||||
@@ -136,7 +184,9 @@ export default function DateSelect({ name, registerOptions = {} }: DateProps) {
|
||||
items={years}
|
||||
label={yearLabel}
|
||||
name={DateName.year}
|
||||
onSelect={createOnSelect(DateName.year)}
|
||||
onSelect={(select: Key) =>
|
||||
handleSegmentChange(DateName.year, Number(select))
|
||||
}
|
||||
placeholder="YYYY"
|
||||
required
|
||||
tabIndex={1}
|
||||
|
||||
Reference in New Issue
Block a user