Skip to content

Commit 1242071

Browse files
Merge pull request #531 from buildo/522-datefield_limit_year_options
#522: DateField - Limit year options
2 parents 6af1c86 + 126bd2b commit 1242071

File tree

4 files changed

+45
-14
lines changed

4 files changed

+45
-14
lines changed

packages/bento-design-system/src/DateField/Calendar.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ type Props = CommonCalendarProps & {
3535
selectActiveDate: (date: Date) => void;
3636
onClose: () => void;
3737
shortcuts?: Children;
38+
minDate?: Date;
39+
maxDate?: Date;
3840
};
3941

4042
function boxShadowFromElevation(config: "none" | "small" | "medium" | "large") {

packages/bento-design-system/src/DateField/CalendarHeader.tsx

+11-1
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,17 @@ type Props = {
99
goToPreviousMonth: () => void;
1010
goToNextMonth: () => void;
1111
selectActiveDate: (date: Date) => void;
12+
minDate?: Date;
13+
maxDate?: Date;
1214
};
1315

1416
export function CalendarHeader({
1517
goToPreviousMonth,
1618
goToNextMonth,
1719
selectActiveDate,
1820
activeDate,
21+
minDate,
22+
maxDate,
1923
}: Props) {
2024
const { defaultMessages } = useDefaultMessages();
2125
return (
@@ -32,7 +36,13 @@ export function CalendarHeader({
3236
/>
3337
</Column>
3438
<Selector datePart="month" activeMonth={activeDate} onSelect={selectActiveDate} />
35-
<Selector datePart="year" activeMonth={activeDate} onSelect={selectActiveDate} />
39+
<Selector
40+
datePart="year"
41+
activeMonth={activeDate}
42+
onSelect={selectActiveDate}
43+
minDate={minDate}
44+
maxDate={maxDate}
45+
/>
3646
<Column width="content">
3747
<IconButton
3848
label={defaultMessages.DateField.nextMonthLabel}

packages/bento-design-system/src/DateField/DateField.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,8 @@ export function DateField(props: Props) {
238238
onDateFocus((props.type === "range" ? props.value[0] : props.value) || new Date());
239239
}}
240240
shortcuts={shortcuts}
241+
maxDate={props.maxDate}
242+
minDate={props.minDate}
241243
/>
242244
)}
243245
</Field>

packages/bento-design-system/src/DateField/Selector.tsx

+30-13
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,20 @@ import { ListProps } from "../List/List";
77
import { Label } from "../Typography/Label/Label";
88
import { selector } from "./DateField.css";
99

10-
function getYears(activeDate: Date): Date[] {
10+
function getYears(activeDate: Date, minDate?: Date, maxDate?: Date): Date[] {
1111
const firstYear = new Date().getFullYear() - 100;
1212
return Array(200)
1313
.fill(0)
1414
.map((_, diff) => {
1515
const yearDate = new Date(activeDate);
1616
yearDate.setFullYear(firstYear + diff);
1717
return yearDate;
18-
});
18+
})
19+
.filter(
20+
(year) =>
21+
(minDate === undefined || year.getFullYear() >= minDate.getFullYear()) &&
22+
(maxDate === undefined || year.getFullYear() <= maxDate.getFullYear())
23+
);
1924
}
2025

2126
function getMonths(activeDate: Date): Date[] {
@@ -28,31 +33,43 @@ function getMonths(activeDate: Date): Date[] {
2833
});
2934
}
3035

31-
export function Selector(props: {
32-
datePart: "month" | "year";
36+
type Props = {
3337
activeMonth: MonthType;
3438
onSelect: (date: Date) => void;
35-
}) {
39+
} & (
40+
| {
41+
datePart: "year";
42+
maxDate?: Date;
43+
minDate?: Date;
44+
}
45+
| {
46+
datePart: "month";
47+
maxDate?: never;
48+
minDate?: never;
49+
}
50+
);
51+
52+
export function Selector({ datePart, activeMonth, maxDate, minDate, onSelect }: Props) {
3653
const config = useBentoConfig().dateField;
3754
const formatter = useDateFormatter(
38-
props.datePart === "month" ? { month: "long" } : { year: "numeric" }
55+
datePart === "month" ? { month: "long" } : { year: "numeric" }
3956
);
4057

4158
const values =
42-
props.datePart === "month"
43-
? getMonths(props.activeMonth.date)
44-
: getYears(props.activeMonth.date);
59+
datePart === "month"
60+
? getMonths(activeMonth.date)
61+
: getYears(activeMonth.date, minDate, maxDate);
4562

4663
const options: ListProps["items"] = useMemo(
4764
() =>
4865
values.map((value) => {
4966
return {
5067
label: formatter.format(value),
51-
onPress: () => props.onSelect(value),
52-
isSelected: value.getTime() === props.activeMonth.date.getTime(),
68+
onPress: () => onSelect(value),
69+
isSelected: value.getTime() === activeMonth.date.getTime(),
5370
};
5471
}),
55-
[values, props.activeMonth]
72+
[values, activeMonth, onSelect, formatter]
5673
);
5774

5875
return (
@@ -63,7 +80,7 @@ export function Selector(props: {
6380
<Columns space={8} align="center" alignY="center">
6481
<Column width="content">
6582
<Label size={config.monthYearLabelSize} color="secondary" uppercase>
66-
{formatter.format(props.activeMonth.date)}
83+
{formatter.format(activeMonth.date)}
6784
</Label>
6885
</Column>
6986
<Column width="content">

0 commit comments

Comments
 (0)