diff --git a/docs/datepicker.md b/docs/datepicker.md index f162eacba..d31c7e40b 100644 --- a/docs/datepicker.md +++ b/docs/datepicker.md @@ -22,6 +22,7 @@ General datepicker component. | `dateFormatCalendar` | `string` | `'LLLL yyyy'` | | | `dayClassName` | `func` | | | | `weekDayClassName` | `func` | | | +| `yearClassName` | `func` | | | | `disabled` | `bool` | `false` | | | `disabledKeyboardNavigation` | `bool` | `false` | | | `dropdownMode` (required) | `enum('scroll'\|'select')` | `'scroll'` | | diff --git a/docs/index.md b/docs/index.md index 46d61e5da..c2e967c07 100644 --- a/docs/index.md +++ b/docs/index.md @@ -156,6 +156,7 @@ | `value` | `string` | | | | `weekAriaLabelPrefix` | `string` | | | | `weekDayClassName` | `func` | | | +| `yearClassName` | `func` | | | | `weekLabel` | `string` | | | | `withPortal` | `bool` | `false` | | | `wrapperClassName` | `string` | | | diff --git a/docs/year.md b/docs/year.md index 5e2dd161a..bdbf10be7 100644 --- a/docs/year.md +++ b/docs/year.md @@ -27,3 +27,4 @@ | `startDate` | `instanceOfDate` | | | | `usePointerEvent` | `bool` | | | | `yearItemNumber` | `number` | | | +| `yearClassName` | `func` | | | diff --git a/src/calendar.jsx b/src/calendar.jsx index e16639768..83ffa7985 100644 --- a/src/calendar.jsx +++ b/src/calendar.jsx @@ -87,6 +87,7 @@ export default class Calendar extends React.Component { disabledDayAriaLabelPrefix: PropTypes.string, monthClassName: PropTypes.func, timeClassName: PropTypes.func, + yearClassName: PropTypes.func, disabledKeyboardNavigation: PropTypes.bool, calendarStartDay: PropTypes.number, dropdownMode: PropTypes.oneOf(["scroll", "select"]), diff --git a/src/index.jsx b/src/index.jsx index b812c7168..03d84ba3f 100644 --- a/src/index.jsx +++ b/src/index.jsx @@ -324,6 +324,7 @@ export default class DatePicker extends React.Component { weekAriaLabelPrefix: PropTypes.string, monthAriaLabelPrefix: PropTypes.string, usePointerEvent: PropTypes.bool, + yearClassName: PropTypes.func, }; constructor(props) { @@ -1150,6 +1151,7 @@ export default class DatePicker extends React.Component { customTimeInput={this.props.customTimeInput} setPreSelection={this.setPreSelection} usePointerEvent={this.props.usePointerEvent} + yearClassName={this.props.yearClassName} > {this.props.children} diff --git a/src/year.jsx b/src/year.jsx index 13f998d22..6b2009606 100644 --- a/src/year.jsx +++ b/src/year.jsx @@ -39,6 +39,7 @@ export default class Year extends React.Component { filterDate: PropTypes.func, yearItemNumber: PropTypes.number, handleOnKeyDown: PropTypes.func, + yearClassName: PropTypes.func, }; constructor(props) { @@ -195,31 +196,39 @@ export default class Year extends React.Component { getYearClassNames = (y) => { const { + date, minDate, maxDate, selected, excludeDates, includeDates, filterDate, + yearClassName, } = this.props; - return clsx("react-datepicker__year-text", { - "react-datepicker__year-text--selected": y === getYear(selected), - "react-datepicker__year-text--disabled": - (minDate || maxDate || excludeDates || includeDates || filterDate) && - utils.isYearDisabled(y, this.props), - "react-datepicker__year-text--keyboard-selected": - this.isKeyboardSelected(y), - "react-datepicker__year-text--range-start": this.isRangeStart(y), - "react-datepicker__year-text--range-end": this.isRangeEnd(y), - "react-datepicker__year-text--in-range": this.isInRange(y), - "react-datepicker__year-text--in-selecting-range": - this.isInSelectingRange(y), - "react-datepicker__year-text--selecting-range-start": - this.isSelectingRangeStart(y), - "react-datepicker__year-text--selecting-range-end": - this.isSelectingRangeEnd(y), - "react-datepicker__year-text--today": this.isCurrentYear(y), - }); + + return clsx( + "react-datepicker__year-text", + `react-datepicker__year-${y}`, + yearClassName ? yearClassName(utils.setYear(date, y)) : undefined, + { + "react-datepicker__year-text--selected": y === getYear(selected), + "react-datepicker__year-text--disabled": + (minDate || maxDate || excludeDates || includeDates || filterDate) && + utils.isYearDisabled(y, this.props), + "react-datepicker__year-text--keyboard-selected": + this.isKeyboardSelected(y), + "react-datepicker__year-text--range-start": this.isRangeStart(y), + "react-datepicker__year-text--range-end": this.isRangeEnd(y), + "react-datepicker__year-text--in-range": this.isInRange(y), + "react-datepicker__year-text--in-selecting-range": + this.isInSelectingRange(y), + "react-datepicker__year-text--selecting-range-start": + this.isSelectingRangeStart(y), + "react-datepicker__year-text--selecting-range-end": + this.isSelectingRangeEnd(y), + "react-datepicker__year-text--today": this.isCurrentYear(y), + }, + ); }; getYearTabIndex = (y) => { diff --git a/test/year_picker_test.test.js b/test/year_picker_test.test.js index ae4778f13..0d54815bf 100644 --- a/test/year_picker_test.test.js +++ b/test/year_picker_test.test.js @@ -737,4 +737,27 @@ describe("YearPicker", () => { expect(utils.getYear(preSelected)).toBe(2021); }); }); + + it("should apply className returned from passed yearClassName prop function", () => { + const className = "customClassName"; + const yearClassNameFunc = () => className; + const date = new Date(); + const { container } = render( + {}} + onYearMouseLeave={() => {}} + yearClassName={yearClassNameFunc} + />, + ); + expect( + container + .querySelector(".react-datepicker__year-text") + .classList.contains(className), + ).toBe(true); + + expect( + container.querySelector(`.react-datepicker__year-${date.getFullYear()}`), + ).not.toBeNull(); + }); });