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,
|
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 currentYear = new Date().getFullYear()
|
||||||
|
|
||||||
const months = rangeArray(1, 12).map((month) => ({
|
const months = rangeArray(1, 12).map((month) => ({
|
||||||
@@ -39,32 +55,60 @@ export default function DateSelect({ name, registerOptions = {} }: DateProps) {
|
|||||||
.reverse()
|
.reverse()
|
||||||
.map((year) => ({ value: year, label: year.toString() }))
|
.map((year) => ({ value: year, label: year.toString() }))
|
||||||
|
|
||||||
// Ensure the user can't select a date that doesn't exist.
|
// Get max days based on selected month/year
|
||||||
const daysInMonth = dt(currentValue).daysInMonth()
|
const daysInMonth =
|
||||||
|
selectedMonth !== null && selectedYear !== null
|
||||||
|
? dt(`${selectedYear}-${selectedMonth + 1}-01`).daysInMonth()
|
||||||
|
: 31
|
||||||
|
|
||||||
const days = rangeArray(1, daysInMonth).map((day) => ({
|
const days = rangeArray(1, daysInMonth).map((day) => ({
|
||||||
value: day,
|
value: day,
|
||||||
label: `${day}`,
|
label: `${day}`,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
function createOnSelect(selector: DateName) {
|
function handleSegmentChange(selector: DateName, value: number) {
|
||||||
/**
|
let newYear = selectedYear
|
||||||
* Months are 0 index based and therefore we
|
let newMonth = selectedMonth
|
||||||
* must subtract by 1 to get the selected month
|
let newDay = selectedDay
|
||||||
*/
|
|
||||||
return (select: Key) => {
|
switch (selector) {
|
||||||
if (selector === DateName.month) {
|
case DateName.year:
|
||||||
select = Number(select) - 1
|
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
|
let dateValue = null
|
||||||
try {
|
try {
|
||||||
/**
|
/**
|
||||||
@@ -98,7 +142,9 @@ export default function DateSelect({ name, registerOptions = {} }: DateProps) {
|
|||||||
items={days}
|
items={days}
|
||||||
label={dayLabel}
|
label={dayLabel}
|
||||||
name={DateName.date}
|
name={DateName.date}
|
||||||
onSelect={createOnSelect(DateName.date)}
|
onSelect={(select: Key) =>
|
||||||
|
handleSegmentChange(DateName.date, Number(select))
|
||||||
|
}
|
||||||
placeholder="DD"
|
placeholder="DD"
|
||||||
required
|
required
|
||||||
tabIndex={3}
|
tabIndex={3}
|
||||||
@@ -117,7 +163,9 @@ export default function DateSelect({ name, registerOptions = {} }: DateProps) {
|
|||||||
items={months}
|
items={months}
|
||||||
label={monthLabel}
|
label={monthLabel}
|
||||||
name={DateName.month}
|
name={DateName.month}
|
||||||
onSelect={createOnSelect(DateName.month)}
|
onSelect={(select: Key) =>
|
||||||
|
handleSegmentChange(DateName.month, Number(select))
|
||||||
|
}
|
||||||
placeholder="MM"
|
placeholder="MM"
|
||||||
required
|
required
|
||||||
tabIndex={2}
|
tabIndex={2}
|
||||||
@@ -136,7 +184,9 @@ export default function DateSelect({ name, registerOptions = {} }: DateProps) {
|
|||||||
items={years}
|
items={years}
|
||||||
label={yearLabel}
|
label={yearLabel}
|
||||||
name={DateName.year}
|
name={DateName.year}
|
||||||
onSelect={createOnSelect(DateName.year)}
|
onSelect={(select: Key) =>
|
||||||
|
handleSegmentChange(DateName.year, Number(select))
|
||||||
|
}
|
||||||
placeholder="YYYY"
|
placeholder="YYYY"
|
||||||
required
|
required
|
||||||
tabIndex={1}
|
tabIndex={1}
|
||||||
|
|||||||
Reference in New Issue
Block a user