From cb9c28be2ba1e00d62c0d810fd83f9cc58f8a12f Mon Sep 17 00:00:00 2001 From: Wojciech Maj Date: Fri, 16 Oct 2020 11:19:24 +0200 Subject: [PATCH] Add support for inputRef prop Closes #384 --- README.md | 1 + src/Calendar.jsx | 11 +++++++++-- src/Calendar.spec.jsx | 11 +++++++++++ src/shared/propTypes.js | 7 +++++++ 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a16eb820..d950fca2 100644 --- a/README.md +++ b/README.md @@ -102,6 +102,7 @@ Displays a complete, interactive calendar. |formatMonthYear|Function called to override default formatting of months and years. Can be used to use your own formatting function.|(default formatter)|`(locale, date) => formatDate(date, 'MMMM YYYY')`| |formatShortWeekday|Function called to override default formatting of weekday names. Can be used to use your own formatting function.|(default formatter)|`(locale, date) => formatDate(date, 'dd')`| |formatYear|Function called to override default formatting of year in the top navigation section. Can be used to use your own formatting function.|(default formatter)|`(locale, date) => formatDate(date, 'YYYY')`| +|inputRef|A prop that behaves like [ref](https://reactjs.org/docs/refs-and-the-dom.html), but it's passed to main `
` rendered by `` component.|n/a|
  • Function:
    `(ref) => { this.myCalendar = ref; }`
  • Ref created using `React.createRef`:
    `this.ref = React.createRef();`

    `inputRef={this.ref}`
  • Ref created using `React.useRef`:
    `const ref = React.useRef();`

    `inputRef={ref}`
| |locale|Locale that should be used by the calendar. Can be any [IETF language tag](https://en.wikipedia.org/wiki/IETF_language_tag).|User's browser settings|`"hu-HU"`| |maxDate|Maximum date that the user can select. Periods partially overlapped by maxDate will also be selectable, although React-Calendar will ensure that no later date is selected.|n/a|Date: `new Date()`| |maxDetail|The most detailed view that the user shall see. View defined here also becomes the one on which clicking an item will select a date and pass it to onChange. Can be `"month"`, `"year"`, `"decade"` or `"century"`.|`"month"`|`"year"`| diff --git a/src/Calendar.jsx b/src/Calendar.jsx index 14cfd827..2bc4ac3c 100644 --- a/src/Calendar.jsx +++ b/src/Calendar.jsx @@ -12,7 +12,7 @@ import { getBegin, getBeginNext, getEnd, getValueRange, } from './shared/dates'; import { - isCalendarType, isClassName, isMaxDate, isMinDate, isValue, isView, + isCalendarType, isClassName, isMaxDate, isMinDate, isRef, isValue, isView, } from './shared/propTypes'; import { between } from './shared/utils'; @@ -594,7 +594,12 @@ export default class Calendar extends Component { } render() { - const { className, selectRange, showDoubleView } = this.props; + const { + className, + inputRef, + selectRange, + showDoubleView, + } = this.props; const { onMouseLeave, value } = this; const valueArray = [].concat(value); @@ -606,6 +611,7 @@ export default class Calendar extends Component { showDoubleView && `${baseClassName}--doubleView`, className, )} + ref={inputRef} > {this.renderNavigation()}
{ expect(wrapperClassName.includes(className)).toBe(true); }); + it('passes container element to inputRef properly', () => { + const inputRef = jest.fn(); + + mount( + , + ); + + expect(inputRef).toHaveBeenCalled(); + expect(inputRef.mock.calls[0][0]).toBeInstanceOf(HTMLElement); + }); + it('renders Navigation by default', () => { const component = shallow( , diff --git a/src/shared/propTypes.js b/src/shared/propTypes.js index 72e121cf..4e50c28b 100644 --- a/src/shared/propTypes.js +++ b/src/shared/propTypes.js @@ -52,6 +52,13 @@ export const isMaxDate = (props, propName, componentName) => { return null; }; +export const isRef = PropTypes.oneOfType([ + PropTypes.func, + PropTypes.shape({ + current: PropTypes.any, + }), +]); + export const isValue = PropTypes.oneOfType([ PropTypes.instanceOf(Date), PropTypes.arrayOf(PropTypes.instanceOf(Date)),