Skip to content

Commit

Permalink
Merge pull request #531 from buildo/522-datefield_limit_year_options
Browse files Browse the repository at this point in the history
#522: DateField - Limit year options
  • Loading branch information
federico-ercoles authored Feb 27, 2023
2 parents 6af1c86 + 126bd2b commit 1242071
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 14 deletions.
2 changes: 2 additions & 0 deletions packages/bento-design-system/src/DateField/Calendar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ type Props = CommonCalendarProps & {
selectActiveDate: (date: Date) => void;
onClose: () => void;
shortcuts?: Children;
minDate?: Date;
maxDate?: Date;
};

function boxShadowFromElevation(config: "none" | "small" | "medium" | "large") {
Expand Down
12 changes: 11 additions & 1 deletion packages/bento-design-system/src/DateField/CalendarHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,17 @@ type Props = {
goToPreviousMonth: () => void;
goToNextMonth: () => void;
selectActiveDate: (date: Date) => void;
minDate?: Date;
maxDate?: Date;
};

export function CalendarHeader({
goToPreviousMonth,
goToNextMonth,
selectActiveDate,
activeDate,
minDate,
maxDate,
}: Props) {
const { defaultMessages } = useDefaultMessages();
return (
Expand All @@ -32,7 +36,13 @@ export function CalendarHeader({
/>
</Column>
<Selector datePart="month" activeMonth={activeDate} onSelect={selectActiveDate} />
<Selector datePart="year" activeMonth={activeDate} onSelect={selectActiveDate} />
<Selector
datePart="year"
activeMonth={activeDate}
onSelect={selectActiveDate}
minDate={minDate}
maxDate={maxDate}
/>
<Column width="content">
<IconButton
label={defaultMessages.DateField.nextMonthLabel}
Expand Down
2 changes: 2 additions & 0 deletions packages/bento-design-system/src/DateField/DateField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,8 @@ export function DateField(props: Props) {
onDateFocus((props.type === "range" ? props.value[0] : props.value) || new Date());
}}
shortcuts={shortcuts}
maxDate={props.maxDate}
minDate={props.minDate}
/>
)}
</Field>
Expand Down
43 changes: 30 additions & 13 deletions packages/bento-design-system/src/DateField/Selector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,20 @@ import { ListProps } from "../List/List";
import { Label } from "../Typography/Label/Label";
import { selector } from "./DateField.css";

function getYears(activeDate: Date): Date[] {
function getYears(activeDate: Date, minDate?: Date, maxDate?: Date): Date[] {
const firstYear = new Date().getFullYear() - 100;
return Array(200)
.fill(0)
.map((_, diff) => {
const yearDate = new Date(activeDate);
yearDate.setFullYear(firstYear + diff);
return yearDate;
});
})
.filter(
(year) =>
(minDate === undefined || year.getFullYear() >= minDate.getFullYear()) &&
(maxDate === undefined || year.getFullYear() <= maxDate.getFullYear())
);
}

function getMonths(activeDate: Date): Date[] {
Expand All @@ -28,31 +33,43 @@ function getMonths(activeDate: Date): Date[] {
});
}

export function Selector(props: {
datePart: "month" | "year";
type Props = {
activeMonth: MonthType;
onSelect: (date: Date) => void;
}) {
} & (
| {
datePart: "year";
maxDate?: Date;
minDate?: Date;
}
| {
datePart: "month";
maxDate?: never;
minDate?: never;
}
);

export function Selector({ datePart, activeMonth, maxDate, minDate, onSelect }: Props) {
const config = useBentoConfig().dateField;
const formatter = useDateFormatter(
props.datePart === "month" ? { month: "long" } : { year: "numeric" }
datePart === "month" ? { month: "long" } : { year: "numeric" }
);

const values =
props.datePart === "month"
? getMonths(props.activeMonth.date)
: getYears(props.activeMonth.date);
datePart === "month"
? getMonths(activeMonth.date)
: getYears(activeMonth.date, minDate, maxDate);

const options: ListProps["items"] = useMemo(
() =>
values.map((value) => {
return {
label: formatter.format(value),
onPress: () => props.onSelect(value),
isSelected: value.getTime() === props.activeMonth.date.getTime(),
onPress: () => onSelect(value),
isSelected: value.getTime() === activeMonth.date.getTime(),
};
}),
[values, props.activeMonth]
[values, activeMonth, onSelect, formatter]
);

return (
Expand All @@ -63,7 +80,7 @@ export function Selector(props: {
<Columns space={8} align="center" alignY="center">
<Column width="content">
<Label size={config.monthYearLabelSize} color="secondary" uppercase>
{formatter.format(props.activeMonth.date)}
{formatter.format(activeMonth.date)}
</Label>
</Column>
<Column width="content">
Expand Down

2 comments on commit 1242071

@vercel
Copy link

@vercel vercel bot commented on 1242071 Feb 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on 1242071 Feb 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.