diff --git a/docs/Modifiers.md b/docs/Modifiers.md index 5191a3e606..2474fa2171 100644 --- a/docs/Modifiers.md +++ b/docs/Modifiers.md @@ -17,15 +17,13 @@ The value of a modifier can be either: ``` will match the days between the 12th and the 16th of January. -- **an object with a `before` key**, to match the days before the given date: +- **an object with a `before` and/or `after` key**, to match the days before and/or after the given date: ```js const range = { - before: new Date(), + before: new Date(), } ``` - will match all the past the days (i.e. the days before today). - -- **an object with a `after` key**, to match the days after the given date: + The code above will match all the past the days (i.e. the days before today). ```js const range = { @@ -33,7 +31,16 @@ The value of a modifier can be either: } ``` - will match all the days after the January, 1st 2018. + The code above will match all the days after the January, 1st 2018. + + ```js + const range = { + after: new Date(2020, 5, 20), + before: new Date(2020, 5, 30), + } + ``` + + The code above will match all the days between the 30th and the 20th of April 2018. - **an object with a `daysOfWeek` array**, to match specific days of week: diff --git a/src/ModifiersUtils.js b/src/ModifiersUtils.js index 5ff49a2eea..c627a35c50 100644 --- a/src/ModifiersUtils.js +++ b/src/ModifiersUtils.js @@ -24,6 +24,9 @@ export function dayMatchesModifier(day, modifier) { if (isRangeOfDates(mod)) { return isDayInRange(day, mod); } + if (mod.after && mod.before) { + return isDayAfter(day, mod.after) && isDayBefore(day, mod.before); + } if (mod.after) { return isDayAfter(day, mod.after); } diff --git a/test/ModifierUtils.js b/test/ModifierUtils.js index 02f0b11ef7..4f16d81255 100644 --- a/test/ModifierUtils.js +++ b/test/ModifierUtils.js @@ -98,6 +98,23 @@ describe('ModifiersUtils', () => { ); expect(match2).to.be.true; }); + it('matches "after" and "before" modifiers', () => { + const afterModifier = { + after: new Date(2015, 8, 10), + before: new Date(2015, 8, 18), + }; + const match = ModifiersUtils.dayMatchesModifier( + new Date(2015, 8, 15), + afterModifier + ); + expect(match).to.be.true; + + const fail = ModifiersUtils.dayMatchesModifier( + new Date(2014, 8, 9), + afterModifier + ); + expect(fail).to.be.false; + }); it('matches "after" modifiers', () => { const afterModifier = { after: new Date(2015, 8, 18), @@ -212,15 +229,9 @@ describe('ModifiersUtils', () => { describe('getModifiersForDay', () => { it('returns an array of modifiers', () => { const modifierFunctions = { - yes() { - return true; - }, - no() { - return false; - }, - maybe(d) { - return d.getMonth() === 8; - }, + yes: () => true, + no: () => false, + maybe: d => d.getMonth() === 8, }; let modifiers = ModifiersUtils.getModifiersForDay( new Date(2015, 8, 19), @@ -348,6 +359,20 @@ describe('ModifiersUtils', () => { ); expect(modifiers2.indexOf('foo')).to.equal(0); }); + it('returns an "after/before" modifier', () => { + const afterModifier = { + foo: { + after: new Date(2015, 8, 10), + before: new Date(2015, 8, 18), + }, + }; + const modifiers = ModifiersUtils.getModifiersForDay( + new Date(2015, 8, 15), + afterModifier + ); + expect(modifiers).to.have.length(1); + expect(modifiers.indexOf('foo')).to.equal(0); + }); it('returns an "after" modifier', () => { const afterModifier = { foo: { diff --git a/types/index.d.ts b/types/index.d.ts index d2aa683506..43410f0211 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -2,180 +2,253 @@ import * as React from 'react'; declare namespace DayPicker { - interface LocaleUtils { - formatDay(day: Date, locale: string): string; - formatMonthTitle(month: Date, locale: string): string; - formatWeekdayLong(weekday: number, locale: string): string; - formatWeekdayShort(weekday: number, locale: string): string; - getFirstDayOfWeek(locale: string): number; - getMonths(locale: string): [string, string, string, string, string, string, string, string, string, string, string, string]; - } - - interface DateUtils { - addDayToRange(day: Date, range: RangeModifier): RangeModifier; - addMonths(d: Date, n: number): Date; - clone(d: Date): Date; - isDayAfter(day1: Date, day2: Date): boolean; - isDayBefore(day1: Date, day2: Date): boolean; - isDayBetween(day: Date, begin: Date, end: Date): boolean; - isDayInRange(day: Date, range: RangeModifier): boolean; - isFutureDay(day: Date): boolean; - isPastDay(day: Date): boolean; - isSameDay(day1: Date, day2: Date): boolean; - } - - interface ModifiersUtils { - dayMatchesModifier(day: Date, modifier?: Modifier | Modifier[]): boolean; - getModifiersForDay(day: Date, modifiers: Record): string[]; - } - - interface CaptionElementProps { - date: Date; - classNames: ClassNames; - localeUtils: LocaleUtils; - locale: string; - months: undefined; - onClick?: React.MouseEventHandler; - } - - interface NavbarElementProps { - className: string; - classNames: ClassNames; - previousMonth: Date; - nextMonth: Date; - showPreviousButton: boolean; - showNextButton: boolean; - onPreviousClick(callback?: () => void): void; - onNextClick(callback?: () => void): void; - dir?: string; - labels: { previousMonth: string; nextMonth: string; }; - localeUtils: LocaleUtils; - locale: string; - } - - interface WeekdayElementProps { - weekday: number; - className: string; - localeUtils: LocaleUtils; - locale: string; - } - - interface ClassNames { - container: string; - interactionDisabled: string; - navBar: string; - navButtonPrev: string; - navButtonNext: string; - - month: string; - caption: string; - weekdays: string; - weekdaysRow: string; - weekday: string; - body: string; - week: string; - day: string; - - today: string; - selected: string; - disabled: string; - outside: string; - } - - interface RangeModifier { - from: Date; - to: Date; - } - interface BeforeModifier { - before: Date; - } - interface AfterModifier { - after: Date; - } - interface DaysOfWeekModifier { - daysOfWeek: number[]; - } - type FunctionModifier = (date: Date) => boolean; - type Modifier = Date | RangeModifier | BeforeModifier | AfterModifier | DaysOfWeekModifier | FunctionModifier; - - interface Modifiers { - today: Modifier | Modifier[]; - outside: Modifier | Modifier[]; - [other: string]: Modifier | Modifier[] | undefined; - } - - interface DayModifiers { - today: boolean | undefined; - outside: boolean | undefined; - [other: string]: boolean | undefined; - } - - interface Props { - canChangeMonth?: boolean; - captionElement?: React.ReactElement> | - React.ComponentClass | - React.SFC; - className?: string; - classNames?: ClassNames; - containerProps?: React.HTMLAttributes; - disabledDays?: Modifier | Modifier[]; - enableOutsideDays?: boolean; - firstDayOfWeek?: number; - fixedWeeks?: boolean; - fromMonth?: Date; - initialMonth?: Date; - labels?: { previousMonth: string; nextMonth: string; }; - locale?: string; - localeUtils?: LocaleUtils; - modifiers?: Partial; - modifiersStyles?: object; - month?: Date; - months?: [string, string, string, string, string, string, string, string, string, string, string, string]; - navbarElement?: React.ReactElement> | - React.ComponentClass | - React.SFC; - numberOfMonths?: number; - onBlur?(e: React.FocusEvent): void; - onCaptionClick?(month: Date, e: React.MouseEvent): void; - onDayClick?(day: Date, modifiers: DayModifiers, e: React.MouseEvent): void; - onDayKeyDown?(day: Date, modifiers: DayModifiers, e: React.KeyboardEvent): void; - onDayMouseEnter?(day: Date, modifiers: DayModifiers, e: React.MouseEvent): void; - onDayMouseLeave?(day: Date, modifiers: DayModifiers, e: React.MouseEvent): void; - onDayTouchEnd?(day: Date, modifiers: DayModifiers, e: React.TouchEvent): void; - onDayTouchStart?(day: Date, modifiers: DayModifiers, e: React.TouchEvent): void; - onFocus?(e: React.FocusEvent): void; - onKeyDown?(e: React.KeyboardEvent): void; - onMonthChange?(month: Date): void; - onWeekClick?(weekNumber: number, days: Date[], e: React.MouseEvent): void; - pagedNavigation?: boolean; - renderDay?(date: Date, modifiers: Modifiers): React.ReactNode; - reverseMonths?: boolean; - selectedDays?: Modifier | Modifier[]; - showWeekNumbers?: boolean; - todayButton?: string; - toMonth?: Date; - weekdayElement?: React.ReactElement> | - React.ComponentClass | - React.SFC; - weekdaysLong?: [string, string, string, string, string, string, string]; - weekdaysShort?: [string, string, string, string, string, string, string]; - } - const VERSION: string; - const LocaleUtils: DayPicker.LocaleUtils; - const DateUtils: DayPicker.DateUtils; - const ModifiersUtils: DayPicker.ModifiersUtils; + interface LocaleUtils { + formatDay(day: Date, locale: string): string; + formatMonthTitle(month: Date, locale: string): string; + formatWeekdayLong(weekday: number, locale: string): string; + formatWeekdayShort(weekday: number, locale: string): string; + getFirstDayOfWeek(locale: string): number; + getMonths( + locale: string + ): [ + string, + string, + string, + string, + string, + string, + string, + string, + string, + string, + string, + string + ]; + } + + interface DateUtils { + addDayToRange(day: Date, range: RangeModifier): RangeModifier; + addMonths(d: Date, n: number): Date; + clone(d: Date): Date; + isDayAfter(day1: Date, day2: Date): boolean; + isDayBefore(day1: Date, day2: Date): boolean; + isDayBetween(day: Date, begin: Date, end: Date): boolean; + isDayInRange(day: Date, range: RangeModifier): boolean; + isFutureDay(day: Date): boolean; + isPastDay(day: Date): boolean; + isSameDay(day1: Date, day2: Date): boolean; + } + + interface ModifiersUtils { + dayMatchesModifier(day: Date, modifier?: Modifier | Modifier[]): boolean; + getModifiersForDay( + day: Date, + modifiers: Record + ): string[]; + } + + interface CaptionElementProps { + date: Date; + classNames: ClassNames; + localeUtils: LocaleUtils; + locale: string; + months: undefined; + onClick?: React.MouseEventHandler; + } + + interface NavbarElementProps { + className: string; + classNames: ClassNames; + previousMonth: Date; + nextMonth: Date; + showPreviousButton: boolean; + showNextButton: boolean; + onPreviousClick(callback?: () => void): void; + onNextClick(callback?: () => void): void; + dir?: string; + labels: { previousMonth: string; nextMonth: string }; + localeUtils: LocaleUtils; + locale: string; + } + + interface WeekdayElementProps { + weekday: number; + className: string; + localeUtils: LocaleUtils; + locale: string; + } + + interface ClassNames { + container: string; + interactionDisabled: string; + navBar: string; + navButtonPrev: string; + navButtonNext: string; + + month: string; + caption: string; + weekdays: string; + weekdaysRow: string; + weekday: string; + body: string; + week: string; + day: string; + + today: string; + selected: string; + disabled: string; + outside: string; + } + + interface RangeModifier { + from: Date; + to: Date; + } + interface BeforeModifier { + before: Date; + } + interface AfterModifier { + after: Date; + } + interface BeforeAfterModifier { + after: Date; + before: Date; + } + interface DaysOfWeekModifier { + daysOfWeek: number[]; + } + type FunctionModifier = (date: Date) => boolean; + type Modifier = + | Date + | RangeModifier + | BeforeModifier + | AfterModifier + | BeforeAfterModifier + | DaysOfWeekModifier + | FunctionModifier; + + interface Modifiers { + today: Modifier | Modifier[]; + outside: Modifier | Modifier[]; + [other: string]: Modifier | Modifier[] | undefined; + } + + interface DayModifiers { + today: boolean | undefined; + outside: boolean | undefined; + [other: string]: boolean | undefined; + } + + interface Props { + canChangeMonth?: boolean; + captionElement?: + | React.ReactElement> + | React.ComponentClass + | React.SFC; + className?: string; + classNames?: ClassNames; + containerProps?: React.HTMLAttributes; + disabledDays?: Modifier | Modifier[]; + enableOutsideDays?: boolean; + firstDayOfWeek?: number; + fixedWeeks?: boolean; + fromMonth?: Date; + initialMonth?: Date; + labels?: { previousMonth: string; nextMonth: string }; + locale?: string; + localeUtils?: LocaleUtils; + modifiers?: Partial; + modifiersStyles?: object; + month?: Date; + months?: [ + string, + string, + string, + string, + string, + string, + string, + string, + string, + string, + string, + string + ]; + navbarElement?: + | React.ReactElement> + | React.ComponentClass + | React.SFC; + numberOfMonths?: number; + onBlur?(e: React.FocusEvent): void; + onCaptionClick?(month: Date, e: React.MouseEvent): void; + onDayClick?( + day: Date, + modifiers: DayModifiers, + e: React.MouseEvent + ): void; + onDayKeyDown?( + day: Date, + modifiers: DayModifiers, + e: React.KeyboardEvent + ): void; + onDayMouseEnter?( + day: Date, + modifiers: DayModifiers, + e: React.MouseEvent + ): void; + onDayMouseLeave?( + day: Date, + modifiers: DayModifiers, + e: React.MouseEvent + ): void; + onDayTouchEnd?( + day: Date, + modifiers: DayModifiers, + e: React.TouchEvent + ): void; + onDayTouchStart?( + day: Date, + modifiers: DayModifiers, + e: React.TouchEvent + ): void; + onFocus?(e: React.FocusEvent): void; + onKeyDown?(e: React.KeyboardEvent): void; + onMonthChange?(month: Date): void; + onWeekClick?( + weekNumber: number, + days: Date[], + e: React.MouseEvent + ): void; + pagedNavigation?: boolean; + renderDay?(date: Date, modifiers: Modifiers): React.ReactNode; + reverseMonths?: boolean; + selectedDays?: Modifier | Modifier[]; + showWeekNumbers?: boolean; + todayButton?: string; + toMonth?: Date; + weekdayElement?: + | React.ReactElement> + | React.ComponentClass + | React.SFC; + weekdaysLong?: [string, string, string, string, string, string, string]; + weekdaysShort?: [string, string, string, string, string, string, string]; + } + const VERSION: string; + const LocaleUtils: DayPicker.LocaleUtils; + const DateUtils: DayPicker.DateUtils; + const ModifiersUtils: DayPicker.ModifiersUtils; } declare class DayPicker extends React.Component { - showMonth(month: Date): void; + showMonth(month: Date): void; - showPreviousMonth(): void; + showPreviousMonth(): void; - showNextMonth(): void; + showNextMonth(): void; - showPreviousYear(): void; + showPreviousYear(): void; - showNextYear(): void; + showNextYear(): void; } export = DayPicker;