diff --git a/README.md b/README.md index 33570f6e..d0ae535d 100644 --- a/README.md +++ b/README.md @@ -122,6 +122,7 @@ Displays a complete, interactive calendar. |onClickYear|Function called when the user clicks a year.|n/a|`(value, event) => alert('Clicked year: ', value)`| |onDrillDown|Function called when the user drills down by clicking a tile.|n/a|`({ activeStartDate, view }) => alert('Drilled down to: ', activeStartDate, view)`| |onDrillUp|Function called when the user drills up by clicking drill up button.|n/a|`({ activeStartDate, view }) => alert('Drilled up to: ', activeStartDate, view)`| +|overrideDrillUp|Determines whether the calendar cycles between the minimum detail view and maximum view when clicking the drill up button|`false`|`true` |prevAriaLabel|`aria-label` attribute of the "previous" button on the navigation pane.|n/a|`"Previous"`| |prevLabel|Content of the "previous" button on the navigation pane. Setting the value explicitly to null will hide the icon.|`"‹"`|| |prev2AriaLabel|`aria-label` attribute of the "previous on higher level" button on the navigation pane.|n/a|`"Jump backwards"`| diff --git a/src/Calendar.jsx b/src/Calendar.jsx index 76098958..fdbe4f94 100644 --- a/src/Calendar.jsx +++ b/src/Calendar.jsx @@ -354,18 +354,25 @@ export default class Calendar extends Component { } drillUp = () => { - if (!this.drillUpAvailable) { + const { activeStartDate, view, views } = this; + const { + onDrillUp, + maxDetail, + overrideDrillUp, + minDate, + } = this.props; + if (!this.drillUpAvailable && !overrideDrillUp) { return; } - - const { activeStartDate, view, views } = this; - const { onDrillUp } = this.props; - - const nextView = views[views.indexOf(view) - 1]; + let nextView = -1; + if (!this.drillUpAvailable && overrideDrillUp) { + nextView = views[views.indexOf(maxDetail)]; + } else { + nextView = views[views.indexOf(view) - 1]; + } const nextActiveStartDate = getBegin(nextView, activeStartDate); - this.setStateAndCallCallbacks({ - activeStartDate: nextActiveStartDate, + activeStartDate: nextActiveStartDate < minDate ? minDate : nextActiveStartDate, view: nextView, }, undefined, onDrillUp); } @@ -572,6 +579,7 @@ export default class Calendar extends Component { next2Label, nextAriaLabel, nextLabel, + overrideDrillUp, prev2AriaLabel, prev2Label, prevAriaLabel, @@ -594,6 +602,7 @@ export default class Calendar extends Component { next2Label={next2Label} nextAriaLabel={nextAriaLabel} nextLabel={nextLabel} + overrideDrillUp={overrideDrillUp} prev2AriaLabel={prev2AriaLabel} prev2Label={prev2Label} prevAriaLabel={prevAriaLabel} @@ -645,6 +654,7 @@ Calendar.defaultProps = { maxDetail: 'month', minDate: defaultMinDate, minDetail: 'century', + overrideDrillUp: false, returnValue: 'start', showNavigation: true, showNeighboringMonth: true, @@ -691,6 +701,7 @@ Calendar.propTypes = { onDrillDown: PropTypes.func, onDrillUp: PropTypes.func, onViewChange: PropTypes.func, + overrideDrillUp: PropTypes.bool, prev2AriaLabel: PropTypes.string, prev2Label: PropTypes.node, prevAriaLabel: PropTypes.string, diff --git a/src/Calendar.spec.jsx b/src/Calendar.spec.jsx index d55d294d..8344dc58 100644 --- a/src/Calendar.spec.jsx +++ b/src/Calendar.spec.jsx @@ -459,6 +459,17 @@ describe('Calendar', () => { expect(onDrillUp).not.toHaveBeenCalled(); }); + it('drill up cycles correctly to maximum detail view when already at minimum detail view', () => { + const component = shallow( + , + ); + component.setState({ view: 'century' }); + component.instance().drillUp(); + + expect(component.instance().view).toBe('month'); + }); }); describe('handles drill down properly', () => { diff --git a/src/Calendar/Navigation.jsx b/src/Calendar/Navigation.jsx index 26369f07..070db08b 100644 --- a/src/Calendar/Navigation.jsx +++ b/src/Calendar/Navigation.jsx @@ -42,8 +42,9 @@ export default function Navigation({ showDoubleView, view, views, + overrideDrillUp, }) { - const drillUpAvailable = views.indexOf(view) > 0; + const drillUpAvailable = views.indexOf(view) > 0 || overrideDrillUp; const shouldShowPrevNext2Buttons = view !== 'century'; const previousActiveStartDate = getBeginPrevious(view, activeStartDate); @@ -71,7 +72,6 @@ export default function Navigation({ })(); const nextButtonDisabled = maxDate && maxDate <= nextActiveStartDate; - const next2ButtonDisabled = ( shouldShowPrevNext2Buttons && maxDate @@ -220,6 +220,7 @@ Navigation.propTypes = { next2Label: PropTypes.node, nextAriaLabel: PropTypes.string, nextLabel: PropTypes.node, + overrideDrillUp: PropTypes.bool, prev2AriaLabel: PropTypes.string, prev2Label: PropTypes.node, prevAriaLabel: PropTypes.string, diff --git a/src/Calendar/Navigation.spec.jsx b/src/Calendar/Navigation.spec.jsx index d570f38a..217d2579 100644 --- a/src/Calendar/Navigation.spec.jsx +++ b/src/Calendar/Navigation.spec.jsx @@ -360,7 +360,6 @@ describe('Navigation', () => { expect(centurySetActiveStartDateFn).toHaveBeenCalledWith(new Date(2101, 0, 1)); }); - it('correctly marks drillUp button as disabled when already on top allowed view', () => { const component = shallow( { expect(button.prop('disabled')).toBeTruthy(); }); - it('disallows navigating before minDate', () => { const component = shallow(