diff --git a/packages/bento-design-system/src/DateField/Calendar.tsx b/packages/bento-design-system/src/DateField/Calendar.tsx index 55413cf03..df9f740d7 100644 --- a/packages/bento-design-system/src/DateField/Calendar.tsx +++ b/packages/bento-design-system/src/DateField/Calendar.tsx @@ -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") { diff --git a/packages/bento-design-system/src/DateField/CalendarHeader.tsx b/packages/bento-design-system/src/DateField/CalendarHeader.tsx index 8781ae216..e5f6fcb37 100644 --- a/packages/bento-design-system/src/DateField/CalendarHeader.tsx +++ b/packages/bento-design-system/src/DateField/CalendarHeader.tsx @@ -9,6 +9,8 @@ type Props = { goToPreviousMonth: () => void; goToNextMonth: () => void; selectActiveDate: (date: Date) => void; + minDate?: Date; + maxDate?: Date; }; export function CalendarHeader({ @@ -16,6 +18,8 @@ export function CalendarHeader({ goToNextMonth, selectActiveDate, activeDate, + minDate, + maxDate, }: Props) { const { defaultMessages } = useDefaultMessages(); return ( @@ -32,7 +36,13 @@ export function CalendarHeader({ /> - + )} diff --git a/packages/bento-design-system/src/DateField/Selector.tsx b/packages/bento-design-system/src/DateField/Selector.tsx index 6a56a9651..b5d08d6e7 100644 --- a/packages/bento-design-system/src/DateField/Selector.tsx +++ b/packages/bento-design-system/src/DateField/Selector.tsx @@ -7,7 +7,7 @@ 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) @@ -15,7 +15,12 @@ function getYears(activeDate: Date): Date[] { 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[] { @@ -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 ( @@ -63,7 +80,7 @@ export function Selector(props: {