Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Reset visibleDays/currentMonth state when enableOutsideDays or numberOfMonths has changed #702

Merged
merged 2 commits into from
Sep 6, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/components/DayPicker.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -283,8 +283,13 @@ export default class DayPicker extends React.Component {
}

componentDidUpdate(prevProps, prevState) {
const { numberOfMonths } = this.props;
const { monthTransition, currentMonth, focusedDate } = this.state;
if (monthTransition || !currentMonth.isSame(prevState.currentMonth)) {
if (
monthTransition ||
!currentMonth.isSame(prevState.currentMonth) ||
numberOfMonths !== prevProps.numberOfMonths
) {
if (this.isHorizontal()) {
this.adjustDayPickerHeight();
}
Expand Down
7 changes: 3 additions & 4 deletions src/components/DayPickerRangeController.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -215,11 +215,10 @@ export default class DayPickerRangeController extends React.Component {
const didFocusChange = focusedInput !== this.props.focusedInput;

if (
numberOfMonths !== this.props.numberOfMonths ||
enableOutsideDays !== this.props.enableOutsideDays ||
(
initialVisibleMonth !== this.props.initialVisibleMonth ||
numberOfMonths !== this.props.numberOfMonths ||
enableOutsideDays !== this.props.enableOutsideDays
) && (
initialVisibleMonth !== this.props.initialVisibleMonth &&
!this.props.focusedInput &&
didFocusChange
)
Expand Down
8 changes: 6 additions & 2 deletions src/components/DayPickerSingleDateController.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -197,9 +197,13 @@ export default class DayPickerSingleDateController extends React.Component {
recomputeOutsideRange || recomputeDayBlocked || recomputeDayHighlighted;

if (
initialVisibleMonth !== this.props.initialVisibleMonth ||
numberOfMonths !== this.props.numberOfMonths ||
enableOutsideDays !== this.props.enableOutsideDays
enableOutsideDays !== this.props.enableOutsideDays ||
(
initialVisibleMonth !== this.props.initialVisibleMonth &&
!this.props.focused &&
focused
)
) {
const newMonthState = this.getStateForNewMonth(nextProps);
const currentMonth = newMonthState.currentMonth;
Expand Down
234 changes: 62 additions & 172 deletions test/components/DayPickerRangeController_spec.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -143,198 +143,88 @@ describe('DayPickerRangeController', () => {
});

describe('numberOfMonths changed', () => {
describe('focusedInput has changed and is truthy', () => {
it('calls getStateForNewMonth with nextProps', () => {
const getStateForNewMonthSpy =
sinon.spy(DayPickerRangeController.prototype, 'getStateForNewMonth');
const wrapper = shallow(<DayPickerRangeController {...props} focusedInput={null} />);
getStateForNewMonthSpy.reset();
wrapper.instance().componentWillReceiveProps({
...props,
focusedInput: START_DATE,
numberOfMonths: 5,
});
expect(getStateForNewMonthSpy.callCount).to.equal(1);
});

it('sets state.currentMonth to getStateForNewMonth.currentMonth', () => {
const currentMonth = moment().add(10, 'months');
const getStateForNewMonthStub =
sinon.stub(DayPickerRangeController.prototype, 'getStateForNewMonth');
getStateForNewMonthStub.returns({ currentMonth, visibleDays: {} });

const wrapper = shallow(<DayPickerRangeController {...props} focusedInput={null} />);
wrapper.instance().componentWillReceiveProps({
...props,
focusedInput: START_DATE,
numberOfMonths: 5,
});
expect(wrapper.instance().state.currentMonth).to.equal(currentMonth);
});

it('sets state.visibleDays to getStateForNewMonth.visibleDays', () => {
const currentMonth = moment().add(10, 'months');
const visibleDays = getVisibleDays(currentMonth, 1);
const getStateForNewMonthStub =
sinon.stub(DayPickerRangeController.prototype, 'getStateForNewMonth');
getStateForNewMonthStub.returns({ currentMonth, visibleDays });

const wrapper = shallow(<DayPickerRangeController {...props} focusedInput={null} />);
wrapper.instance().componentWillReceiveProps({
...props,
focusedInput: START_DATE,
numberOfMonths: 5,
});
expect(wrapper.instance().state.visibleDays).to.equal(visibleDays);
it('calls getStateForNewMonth with nextProps', () => {
const getStateForNewMonthSpy =
sinon.spy(DayPickerRangeController.prototype, 'getStateForNewMonth');
const wrapper = shallow(<DayPickerRangeController {...props} />);
getStateForNewMonthSpy.reset();
wrapper.instance().componentWillReceiveProps({
...props,
numberOfMonths: 5,
});
expect(getStateForNewMonthSpy.callCount).to.equal(1);
});

describe('focusedInput has not changed', () => {
it('does not call getStateForNewMonth', () => {
const getStateForNewMonthSpy =
sinon.spy(DayPickerRangeController.prototype, 'getStateForNewMonth');
const wrapper = shallow(<DayPickerRangeController {...props} focusedInput={null} />);
getStateForNewMonthSpy.reset();
wrapper.instance().componentWillReceiveProps({
...props,
focusedInput: null,
numberOfMonths: 5,
});
expect(getStateForNewMonthSpy.callCount).to.equal(0);
});

it('does not change state.currentMonth', () => {
const currentMonth = moment().add(10, 'months');
const getStateForNewMonthStub =
sinon.stub(DayPickerRangeController.prototype, 'getStateForNewMonth');
getStateForNewMonthStub.returns({ currentMonth: moment(), visibleDays: {} });
it('sets state.currentMonth to getStateForNewMonth.currentMonth', () => {
const currentMonth = moment().add(10, 'months');
const getStateForNewMonthStub =
sinon.stub(DayPickerRangeController.prototype, 'getStateForNewMonth');
getStateForNewMonthStub.returns({ currentMonth, visibleDays: {} });

const wrapper = shallow(<DayPickerRangeController {...props} focusedInput={null} />);
wrapper.setState({ currentMonth });
wrapper.instance().componentWillReceiveProps({
...props,
focusedInput: null,
numberOfMonths: 5,
});
expect(wrapper.instance().state.currentMonth).to.equal(currentMonth);
const wrapper = shallow(<DayPickerRangeController {...props} />);
wrapper.instance().componentWillReceiveProps({
...props,
numberOfMonths: 5,
});
expect(wrapper.instance().state.currentMonth).to.equal(currentMonth);
});

it('does not change state.visibleDays', () => {
const visibleDays = {};
const getStateForNewMonthStub =
sinon.stub(DayPickerRangeController.prototype, 'getStateForNewMonth');
getStateForNewMonthStub.returns({
currentMonth: moment(),
visibleDays: getVisibleDays(moment(), 1),
});
it('sets state.visibleDays to getStateForNewMonth.visibleDays', () => {
const currentMonth = moment().add(10, 'months');
const visibleDays = getVisibleDays(currentMonth, 1);
const getStateForNewMonthStub =
sinon.stub(DayPickerRangeController.prototype, 'getStateForNewMonth');
getStateForNewMonthStub.returns({ currentMonth, visibleDays });

const wrapper = shallow(<DayPickerRangeController {...props} focusedInput={null} />);
wrapper.setState({ visibleDays });
wrapper.instance().componentWillReceiveProps({
...props,
focusedInput: null,
numberOfMonths: 5,
});
expect(wrapper.instance().state.visibleDays).to.equal(visibleDays);
const wrapper = shallow(<DayPickerRangeController {...props} />);
wrapper.instance().componentWillReceiveProps({
...props,
numberOfMonths: 5,
});
expect(wrapper.instance().state.visibleDays).to.equal(visibleDays);
});
});

describe('enableOutsideDays changed', () => {
describe('focusedInput has changed and is truthy', () => {
it('calls getStateForNewMonth with nextProps', () => {
const getStateForNewMonthSpy =
sinon.spy(DayPickerRangeController.prototype, 'getStateForNewMonth');
const wrapper = shallow(<DayPickerRangeController {...props} focusedInput={null} />);
getStateForNewMonthSpy.reset();
wrapper.instance().componentWillReceiveProps({
...props,
focusedInput: START_DATE,
enableOutsideDays: true,
});
expect(getStateForNewMonthSpy.callCount).to.equal(1);
});

it('sets state.currentMonth to getStateForNewMonth.currentMonth', () => {
const currentMonth = moment().add(10, 'months');
const getStateForNewMonthStub =
sinon.stub(DayPickerRangeController.prototype, 'getStateForNewMonth');
getStateForNewMonthStub.returns({ currentMonth, visibleDays: {} });

const wrapper = shallow(<DayPickerRangeController {...props} focusedInput={null} />);
wrapper.instance().componentWillReceiveProps({
...props,
focusedInput: START_DATE,
enableOutsideDays: true,
});
expect(wrapper.instance().state.currentMonth).to.equal(currentMonth);
});

it('sets state.visibleDays to getStateForNewMonth.visibleDays', () => {
const currentMonth = moment().add(10, 'months');
const visibleDays = getVisibleDays(currentMonth, 1);
const getStateForNewMonthStub =
sinon.stub(DayPickerRangeController.prototype, 'getStateForNewMonth');
getStateForNewMonthStub.returns({ currentMonth, visibleDays });

const wrapper = shallow(<DayPickerRangeController {...props} focusedInput={null} />);
wrapper.instance().componentWillReceiveProps({
...props,
focusedInput: START_DATE,
enableOutsideDays: true,
});
expect(wrapper.instance().state.visibleDays).to.equal(visibleDays);
it('calls getStateForNewMonth with nextProps', () => {
const getStateForNewMonthSpy =
sinon.spy(DayPickerRangeController.prototype, 'getStateForNewMonth');
const wrapper = shallow(<DayPickerRangeController {...props} />);
getStateForNewMonthSpy.reset();
wrapper.instance().componentWillReceiveProps({
...props,
enableOutsideDays: true,
});
expect(getStateForNewMonthSpy.callCount).to.equal(1);
});

describe('focusedInput has not changed', () => {
it('does not call getStateForNewMonth', () => {
const getStateForNewMonthSpy =
sinon.spy(DayPickerRangeController.prototype, 'getStateForNewMonth');
const wrapper = shallow(<DayPickerRangeController {...props} focusedInput={null} />);
getStateForNewMonthSpy.reset();
wrapper.instance().componentWillReceiveProps({
...props,
focusedInput: null,
enableOutsideDays: true,
});
expect(getStateForNewMonthSpy.callCount).to.equal(0);
});

it('does not change state.currentMonth', () => {
const currentMonth = moment().add(10, 'months');
const getStateForNewMonthStub =
sinon.stub(DayPickerRangeController.prototype, 'getStateForNewMonth');
getStateForNewMonthStub.returns({ currentMonth: moment(), visibleDays: {} });
it('sets state.currentMonth to getStateForNewMonth.currentMonth', () => {
const currentMonth = moment().add(10, 'months');
const getStateForNewMonthStub =
sinon.stub(DayPickerRangeController.prototype, 'getStateForNewMonth');
getStateForNewMonthStub.returns({ currentMonth, visibleDays: {} });

const wrapper = shallow(<DayPickerRangeController {...props} focusedInput={null} />);
wrapper.setState({ currentMonth });
wrapper.instance().componentWillReceiveProps({
...props,
focusedInput: null,
enableOutsideDays: true,
});
expect(wrapper.instance().state.currentMonth).to.equal(currentMonth);
const wrapper = shallow(<DayPickerRangeController {...props} />);
wrapper.instance().componentWillReceiveProps({
...props,
enableOutsideDays: true,
});
expect(wrapper.instance().state.currentMonth).to.equal(currentMonth);
});

it('does not change state.visibleDays', () => {
const visibleDays = {};
const getStateForNewMonthStub =
sinon.stub(DayPickerRangeController.prototype, 'getStateForNewMonth');
getStateForNewMonthStub.returns({
currentMonth: moment(),
visibleDays: getVisibleDays(moment(), 1),
});
it('sets state.visibleDays to getStateForNewMonth.visibleDays', () => {
const currentMonth = moment().add(10, 'months');
const visibleDays = getVisibleDays(currentMonth, 1);
const getStateForNewMonthStub =
sinon.stub(DayPickerRangeController.prototype, 'getStateForNewMonth');
getStateForNewMonthStub.returns({ currentMonth, visibleDays });

const wrapper = shallow(<DayPickerRangeController {...props} focusedInput={null} />);
wrapper.setState({ visibleDays });
wrapper.instance().componentWillReceiveProps({
...props,
focusedInput: null,
enableOutsideDays: true,
});
expect(wrapper.instance().state.visibleDays).to.equal(visibleDays);
const wrapper = shallow(<DayPickerRangeController {...props} />);
wrapper.instance().componentWillReceiveProps({
...props,
enableOutsideDays: true,
});
expect(wrapper.instance().state.visibleDays).to.equal(visibleDays);
});
});
});
Expand Down