Skip to content

Commit 7d3f0a6

Browse files
committed
fix: dateInput onClose not called with last picked date
DateInput onClose callback is not called with last picked date when value property is present
1 parent 04f07ba commit 7d3f0a6

File tree

2 files changed

+115
-12
lines changed

2 files changed

+115
-12
lines changed

src/components/Input/DateInput.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ export default class DateInput extends React.Component {
274274
componentDidUpdate(prevProps, prevState) {
275275
this.setInputValue();
276276
if (this.props.onClose && this.state.open !== prevState.open && !this.state.open) {
277-
const value = this.props.value !== undefined ? this.props.value : this.state.value;
277+
const value = this.state.value;
278278
const date = this.props.parse(value, this.props.dateFormat);
279279

280280
if (date) {

src/components/Input/DateInput.spec.js

Lines changed: 114 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import isToday from 'date-fns/is_today';
88
import frLocale from 'date-fns/locale/fr';
99
import startOfToday from 'date-fns/start_of_today';
1010
import { mount } from 'enzyme';
11-
import React from 'react';
11+
import React, { useState } from 'react';
1212
import sinon from 'sinon';
1313
import Button from '../Button/Button';
1414
import Icon from '../Icon/Icon';
@@ -159,11 +159,17 @@ describe('<DateInput />', () => {
159159
});
160160

161161
describe('date picker', () => {
162-
const callback = sinon.spy();
163-
const component = mount(<DateInput onChange={callback} showOnFocus />);
162+
let callback;
163+
let onCloseCallback;
164+
let component;
165+
166+
beforeEach(() => {
167+
callback = sinon.spy();
168+
onCloseCallback = sinon.spy();
169+
component = mount(<DateInput onChange={callback} onClose={onCloseCallback} showOnFocus />);
170+
});
164171

165172
it('should set date after clicking a date', () => {
166-
callback.resetHistory();
167173
const firstDate = component.find('Day').first();
168174
const expectedDate = firstDate.props().day.date;
169175
firstDate.simulate('click');
@@ -172,15 +178,13 @@ describe('<DateInput />', () => {
172178
});
173179

174180
it('should call onChange after clicking a date', () => {
175-
callback.resetHistory();
176181
const lastDate = component.find('Day').first();
177182
const expectedDate = lastDate.props().day.date;
178183
lastDate.simulate('click');
179184
assert(callback.calledWith(expectedDate, true));
180185
});
181186

182187
it('should set date after clicking prev year', () => {
183-
callback.resetHistory();
184188
const expectedDate = addYears(component.instance().getCurrentDate(), -1);
185189
const prevYear = component.find('Button.js-prev-year');
186190

@@ -191,7 +195,6 @@ describe('<DateInput />', () => {
191195
});
192196

193197
it('should set date after clicking next year', () => {
194-
callback.resetHistory();
195198
const expectedDate = addYears(component.instance().getCurrentDate(), 1);
196199
const nextYear = component.find('Button.js-next-year');
197200

@@ -202,7 +205,6 @@ describe('<DateInput />', () => {
202205
});
203206

204207
it('should set date after clicking prev month', () => {
205-
callback.resetHistory();
206208
const expectedDate = addMonths(component.instance().getCurrentDate(), -1);
207209
const prevMonth = component.find('Button.js-prev-month');
208210

@@ -213,7 +215,6 @@ describe('<DateInput />', () => {
213215
});
214216

215217
it('should set date after clicking next month', () => {
216-
callback.resetHistory();
217218
const expectedDate = addMonths(component.instance().getCurrentDate(), 1);
218219
const nextMonth = component.find('Button.js-next-month');
219220

@@ -230,7 +231,6 @@ describe('<DateInput />', () => {
230231
});
231232

232233
it('should call onChange after clicking today', () => {
233-
callback.resetHistory();
234234
const today = component.find('footer Button').at(0);
235235
today.simulate('click');
236236
assert(callback.called);
@@ -246,7 +246,6 @@ describe('<DateInput />', () => {
246246
});
247247

248248
it('should call onChange after clicking clear', () => {
249-
callback.resetHistory();
250249
const clear = component.find('footer Button').at(1);
251250
clear.simulate('click');
252251
assert(callback.calledWith('', false));
@@ -272,6 +271,110 @@ describe('<DateInput />', () => {
272271
input.simulate('keydown', { key: 'ArrowRight', keyCode: 39, which: 39 });
273272
assert(isSameDay(component.instance().getCurrentDate(), expectedDate));
274273
});
274+
275+
it('should call onClose when closing the date picker with the latest selected date in the current month', () => {
276+
const toggle = component.find('InputGroup').find('Button');
277+
toggle.simulate('click');
278+
279+
const initialDate = component.instance().getCurrentDate();
280+
const isFirstOfMonth = initialDate.getDate() === 1;
281+
const dayToPick = isFirstOfMonth ? component.find('Day').at(1) : component.find('Day').at(0);
282+
283+
const expectedDate = dayToPick.props().day.date;
284+
285+
dayToPick.simulate('click');
286+
assert(onCloseCallback.calledOnce);
287+
assert(onCloseCallback.calledWith(expectedDate, true));
288+
});
289+
290+
it('should call onClose with the last selected date when we change the month', () => {
291+
const toggle = component.find('InputGroup').find('Button');
292+
toggle.simulate('click');
293+
294+
const nextMonth = component.find('Button.js-next-month');
295+
nextMonth.simulate('click');
296+
297+
const tentativeIndexDayToPick = 15;
298+
const tentativeDayToPick = component.find('Day').at(tentativeIndexDayToPick);
299+
const dayToPick =
300+
tentativeDayToPick.props().day.date.getDate() === component.instance().getCurrentDate().getDate()
301+
? component.find('Day').at(tentativeIndexDayToPick + 1)
302+
: tentativeDayToPick;
303+
304+
const expectedDate = dayToPick.props().day.date;
305+
306+
dayToPick.simulate('click');
307+
assert(onCloseCallback.calledOnce);
308+
assert(onCloseCallback.calledWith(expectedDate, true));
309+
});
310+
});
311+
312+
describe('date picker with value property', () => {
313+
let onChangeCallback;
314+
let onCloseCallback;
315+
let wrapper;
316+
317+
beforeEach(() => {
318+
onChangeCallback = sinon.spy();
319+
onCloseCallback = sinon.spy();
320+
321+
const WrappingComponent = () => {
322+
const [ dateValue, setDateValue ] = useState(new Date());
323+
324+
const onChange = (date, valid) => {
325+
onChangeCallback(date, valid);
326+
setDateValue(date);
327+
};
328+
329+
return (
330+
<DateInput onChange={onChange} onClose={onCloseCallback} value={dateValue} />
331+
);
332+
};
333+
334+
wrapper = mount(<WrappingComponent />);
335+
});
336+
337+
it('should call onClose when closing the date picker with the latest selected date in the current month', () => {
338+
const toggle = wrapper.find('DateInput').find('InputGroup').find('Button');
339+
toggle.simulate('click');
340+
341+
const initialDate = wrapper.find('DateInput').instance().getCurrentDate();
342+
const isFirstOfMonth = initialDate.getDate() === 1;
343+
const dayToPick = isFirstOfMonth
344+
? wrapper.find('DateInput').find('Day').at(1)
345+
: wrapper.find('DateInput').find('Day').at(0);
346+
347+
const expectedDate = dayToPick.props().day.date;
348+
349+
dayToPick.simulate('click');
350+
assert(onCloseCallback.calledOnce);
351+
assert(onCloseCallback.calledWith(expectedDate, true));
352+
});
353+
354+
it('should call onClose with the last selected date when we change the month', () => {
355+
const toggle = wrapper.find('DateInput').find('InputGroup').find('Button');
356+
toggle.simulate('click');
357+
358+
const nextMonth = wrapper.find('DateInput').find('Button.js-next-month');
359+
nextMonth.simulate('click');
360+
361+
const tentativeIndexDayToPick = 15;
362+
const tentativeDayToPick = wrapper.find('DateInput').find('Day').at(tentativeIndexDayToPick);
363+
const dayToPick =
364+
tentativeDayToPick.props().day.date.getDate() ===
365+
wrapper.find('DateInput').instance().getCurrentDate().getDate()
366+
? wrapper
367+
.find('DateInput')
368+
.find('Day')
369+
.at(tentativeIndexDayToPick + 1)
370+
: tentativeDayToPick;
371+
372+
const expectedDate = dayToPick.props().day.date;
373+
374+
dayToPick.simulate('click');
375+
assert(onCloseCallback.calledOnce);
376+
assert(onCloseCallback.calledWith(expectedDate, true));
377+
});
275378
});
276379

277380
describe('date picker with controlled visible dates', () => {

0 commit comments

Comments
 (0)