Skip to content
This repository has been archived by the owner on Mar 4, 2024. It is now read-only.

Commit

Permalink
Fix re-render issue
Browse files Browse the repository at this point in the history
  • Loading branch information
ilsanchez committed Oct 16, 2023
1 parent 217ff07 commit a701f7d
Show file tree
Hide file tree
Showing 3 changed files with 284 additions and 129 deletions.
6 changes: 4 additions & 2 deletions cypress/component/DateRangeWidget.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,17 @@ describe('<DateRangeWidget />', () => {
dataset: 'fake',
inputs: {
date_range_start: '2023-09-30',
date_range_end: '2025-02-10'
date_range_end: '2023-10-10'
}
})
)

const configuration = getDateRangeWidgetConfiguration()

cy.mount(
<Form handleSubmit={stubbedHandleSubmit}>
<DateRangeWidget
configuration={getDateRangeWidgetConfiguration()}
configuration={configuration}
constraints={['2023-10-05', '2023-10-11', '2023-10-30']}
error='Start date and End date are required'
/>
Expand Down
140 changes: 82 additions & 58 deletions src/common/DateField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import {
import { CalendarDate } from '@internationalized/date'

import { Error, ReservedSpace } from '../widgets/Widget'
import { SingleSelect } from './Select'

interface DateFieldProps {
name: string
Expand All @@ -39,6 +38,8 @@ interface DateFieldProps {
error?: string
disabled?: boolean
required?: boolean
years?: number[]
months?: number[]
}
const DateField = ({
name,
Expand All @@ -51,7 +52,9 @@ const DateField = ({
isDateUnavailable,
error,
disabled,
required
required,
months,
years
}: DateFieldProps) => {
return (
<DatePicker
Expand Down Expand Up @@ -82,13 +85,16 @@ const DateField = ({
<StyledDialog>
<StyledCalendar>
<StyledCalendarHeader>
<StyledBlankButton slot='previous'>
<ChevronLeftIcon width={24} height={24} />
</StyledBlankButton>
<StyledHeading />
<StyledBlankButton slot='next'>
<ChevronRightIcon width={24} height={24} />
</StyledBlankButton>
{months && months.length > 0 && years && years.length > 0 ? (
<DateSelects
value={value}
years={years}
months={months}
onDateChange={onChange}
/>
) : (
<StyledHeading />
)}
</StyledCalendarHeader>
<StyledCalendarGrid>
{date => <StyledCalendarCell date={date} />}
Expand Down Expand Up @@ -116,58 +122,76 @@ const Months = [
]

interface DateSelectsProps {
name: string
selectedYear: number
selectedMonth: number
value: CalendarDate
years: number[]
months: number[]
onYearChange(year: number): void
onMonthChange(month: number): void
}
const DateSelects = ({
name,
selectedYear,
selectedMonth,
years,
months,
onYearChange,
onMonthChange
}: DateSelectsProps) => {
const yearOptions = React.useMemo(
() => years.map(y => ({ id: y.toString(), label: y.toString() })),
[years]
)

const monthOptions = React.useMemo(
() =>
months.map(m => ({
id: m.toString(),
label: Months[m]
})),
[months]
)

return (
<Row>
<SingleSelect
defaultValue={selectedMonth.toString()}
ariaLabel='Month select'
id={`${name}-month-select`}
onChange={value => onMonthChange(parseInt(value))}
options={monthOptions}
placeholder='Select month'
/>
<SingleSelect
defaultValue={selectedYear.toString()}
ariaLabel='year select'
id={`${name}-year-select`}
onChange={value => onYearChange(parseInt(value))}
options={yearOptions}
placeholder='Select year'
/>
</Row>
)
onDateChange(date: CalendarDate): void
}
const DateSelects = React.memo(
({ value, years, months, onDateChange }: DateSelectsProps) => {
const yearOptions = React.useMemo(() => {
const baseYears = years.map(y => ({
id: y.toString(),
label: y.toString(),
disabled: false
}))
if (!baseYears.find(({ id }) => value.year.toString() === id)) {
return baseYears.concat({
id: value.year.toString(),
label: value.year.toString(),
disabled: true
})
}
return baseYears
}, [years, value])

const monthOptions = React.useMemo(
() =>
months.map((m, i) => ({
id: (m + 1).toString(),
label: Months[m]
})),
[months]
)

const handleChange =
(key: 'month' | 'year') =>
({
target: { value: selectValue }
}: React.ChangeEvent<HTMLSelectElement>) => {
const newDate = value.set({ [key]: parseInt(selectValue) })
console.log(selectValue, newDate.month)
onDateChange(newDate)
}

return (
<Row>
<select
key={value.month}
value={value.month}
onChange={handleChange('month')}
>
{monthOptions.map(({ id, label }) => (
<option key={id} value={id}>
{label}
</option>
))}
</select>
<select
key={value.year}
value={value.year}
onChange={handleChange('year')}
>
{yearOptions.map(({ id, label, disabled }) => (
<option key={id} value={id} disabled={disabled}>
{label}
</option>
))}
</select>
</Row>
)
}
)

const Row = styled.div`
width: 100%;
Expand Down
Loading

0 comments on commit a701f7d

Please sign in to comment.