Skip to content

Commit 0bfc951

Browse files
committed
finish active date on typing scenario; ensure event args contain only date portion
1 parent 34e0bcd commit 0bfc951

File tree

3 files changed

+111
-21
lines changed

3 files changed

+111
-21
lines changed

src/components/calendar/helpers.ts

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -93,16 +93,14 @@ export function convertToDateRange(
9393

9494
if (isString(value)) {
9595
const obj = JSON.parse(value);
96-
if (obj.start && obj.end) {
97-
return {
98-
start: isValidDate(new Date(obj.start)),
99-
end: isValidDate(new Date(obj.end)),
100-
};
101-
}
102-
} else {
103-
return value;
96+
const start = isValidDate(new Date(obj.start));
97+
const end = isValidDate(new Date(obj.end));
98+
return {
99+
start: start ? CalendarDay.from(start).native : null,
100+
end: end ? CalendarDay.from(end).native : null,
101+
};
104102
}
105-
return null;
103+
return value;
106104
}
107105

108106
/**

src/components/date-range-picker/date-range-picker.spec.ts

Lines changed: 88 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,7 @@ describe('Date range picker', () => {
713713

714714
dateTimeInputs[1].focus();
715715
// first arrow sets today, second sets aMonthAgo
716+
dateTimeInputs[1].setSelectionRange(0, 1); // make sure caret is on the month part (MM/dd/yyyy)
716717
simulateKeyboard(dateTimeInputs[1], arrowDown);
717718
simulateKeyboard(dateTimeInputs[1], arrowDown);
718719
await elementUpdated(picker);
@@ -1223,14 +1224,99 @@ describe('Date range picker', () => {
12231224
simulateKeyboard(dateTimeInputs[0], arrowUp);
12241225
await elementUpdated(picker);
12251226

1226-
expect(eventSpy).calledWith('igcInput');
1227+
expect(eventSpy).calledWith('igcInput', {
1228+
detail: { start: today.native, end: null },
1229+
});
12271230
eventSpy.resetHistory();
12281231

1232+
dateTimeInputs[0].setSelectionRange(0, 1); // make sure caret is on the month part (MM/dd/yyyy)
12291233
simulateKeyboard(dateTimeInputs[0], arrowDown);
12301234
await elementUpdated(picker);
1235+
1236+
expect(eventSpy).calledWith('igcInput', {
1237+
detail: { start: today.add('month', -1).native, end: null },
1238+
});
1239+
eventSpy.resetHistory();
1240+
1241+
dateTimeInputs[0].blur();
1242+
expect(eventSpy).calledWith('igcChange', {
1243+
detail: { start: today.add('month', -1).native, end: null },
1244+
});
12311245
});
12321246

1233-
it('should set the calendar active date to the start of the range while typing', async () => {});
1247+
it('should set the calendar active date to the altered date of the range while typing', async () => {
1248+
const eventSpy = spy(picker, 'emitEvent');
1249+
const aMonthAgo = today.add('month', -1);
1250+
const twoMonthsAgo = today.add('month', -2);
1251+
picker.value = null;
1252+
picker.open = true;
1253+
await elementUpdated(picker);
1254+
1255+
dateTimeInputs[0].focus();
1256+
expect(isFocused(dateTimeInputs[0])).to.be.true;
1257+
1258+
dateTimeInputs[0].setSelectionRange(0, 1); // make sure caret is on the month part (MM/dd/yyyy)
1259+
simulateKeyboard(dateTimeInputs[0], arrowDown);
1260+
await elementUpdated(picker);
1261+
1262+
expect(eventSpy).calledWith('igcInput');
1263+
eventSpy.resetHistory();
1264+
checkDatesEqual(dateTimeInputs[0].value!, today.native);
1265+
// typing a single date does not select a range in the calendar
1266+
checkSelectedRange(picker, { start: null, end: null });
1267+
checkDatesEqual(calendar.activeDate, today.native);
1268+
1269+
dateTimeInputs[1].focus();
1270+
expect(isFocused(dateTimeInputs[1])).to.be.true;
1271+
1272+
dateTimeInputs[1].setSelectionRange(0, 1);
1273+
simulateKeyboard(dateTimeInputs[1], arrowDown);
1274+
await elementUpdated(picker);
1275+
1276+
expect(eventSpy).calledWith('igcInput');
1277+
eventSpy.resetHistory();
1278+
checkDatesEqual(dateTimeInputs[1].value!, today.native);
1279+
// typing the end date as well results in a selected range of a single date
1280+
checkSelectedRange(picker, { start: today.native, end: today.native });
1281+
checkDatesEqual(calendar.activeDate, today.native);
1282+
1283+
simulateKeyboard(dateTimeInputs[1], arrowDown);
1284+
await elementUpdated(picker);
1285+
1286+
expect(eventSpy).calledWith('igcInput');
1287+
eventSpy.resetHistory();
1288+
checkDatesEqual(dateTimeInputs[1].value!, aMonthAgo.native);
1289+
// changing the end date while typing alters the selected range
1290+
// the active date is set to the typed date, in this case the end one
1291+
checkSelectedRange(picker, {
1292+
start: today.native,
1293+
end: aMonthAgo.native,
1294+
});
1295+
checkDatesEqual(calendar.activeDate, aMonthAgo.native);
1296+
1297+
// on losing focus of the end input, the dates are swapped since end is earlier than start
1298+
dateTimeInputs[0].focus();
1299+
expect(isFocused(dateTimeInputs[0])).to.be.true;
1300+
await elementUpdated(picker);
1301+
1302+
checkSelectedRange(picker, {
1303+
start: aMonthAgo.native,
1304+
end: today.native,
1305+
});
1306+
checkDatesEqual(calendar.activeDate, aMonthAgo.native);
1307+
1308+
dateTimeInputs[0].setSelectionRange(0, 1);
1309+
simulateKeyboard(dateTimeInputs[0], arrowDown);
1310+
await elementUpdated(picker);
1311+
1312+
expect(eventSpy).calledWith('igcInput');
1313+
checkDatesEqual(dateTimeInputs[0].value!, twoMonthsAgo.native);
1314+
checkSelectedRange(picker, {
1315+
start: twoMonthsAgo.native,
1316+
end: today.native,
1317+
});
1318+
checkDatesEqual(calendar.activeDate, twoMonthsAgo.native);
1319+
});
12341320
});
12351321
});
12361322
describe('Slots', () => {

src/components/date-range-picker/date-range-picker.ts

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -317,11 +317,11 @@ export default class IgcDateRangePickerComponent extends FormAssociatedRequiredM
317317
}
318318

319319
public get value(): DateRangeValue | null {
320-
if (!this._formValue.value) {
321-
return { start: null, end: null }; // TODO what should the default value be? null?
322-
}
323-
324-
return this._formValue.value;
320+
// TODO what should the default value be? null?
321+
return {
322+
start: this._formValue?.value?.start ?? null,
323+
end: this._formValue?.value?.end ?? null,
324+
};
325325
}
326326
/**
327327
* Renders chips with custom ranges based on the elements of the array.
@@ -674,7 +674,8 @@ export default class IgcDateRangePickerComponent extends FormAssociatedRequiredM
674674
event.preventDefault();
675675
return;
676676
}
677-
const newValue = (event.target as IgcDateTimeInputComponent).value;
677+
const input = event.target as IgcDateTimeInputComponent;
678+
const newValue = input.value ? CalendarDay.from(input.value).native : null;
678679

679680
if (event.target === this._inputs[0]) {
680681
this._startDate = newValue;
@@ -690,7 +691,10 @@ export default class IgcDateRangePickerComponent extends FormAssociatedRequiredM
690691
protected handleInputChangeEvent(event: CustomEvent<Date | null>) {
691692
event.stopPropagation();
692693
this._swapDatesFlag = false;
693-
const newValue = (event.target as IgcDateTimeInputComponent).value;
694+
695+
const input = event.target as IgcDateTimeInputComponent;
696+
const newValue = input.value ? CalendarDay.from(input.value).native : null;
697+
694698
if (event.target === this._inputs[0]) {
695699
this._startDate = newValue;
696700
} else {
@@ -879,21 +883,22 @@ export default class IgcDateRangePickerComponent extends FormAssociatedRequiredM
879883

880884
const calendarDayStart = toCalendarDay(this._startDate);
881885
const calendarDayEnd = toCalendarDay(this._endDate);
886+
const isStartEarlierThanEnd = calendarDayStart.lessThan(calendarDayEnd);
882887

883888
// dates should not be swapped while typing
884-
if (!this._swapDatesFlag && calendarDayStart.greaterThan(calendarDayEnd)) {
889+
if (!this._swapDatesFlag && !isStartEarlierThanEnd) {
885890
this.swapDates();
886891
}
887892
if (!calendarDayStart.equalTo(calendarDayEnd)) {
888893
const range = Array.from(
889894
calendarRange({ start: this._startDate, end: this._endDate })
890895
);
891-
range.push(last(range).add('day', 1));
896+
// calendarRange is non-inclusive
897+
range.push(last(range).add('day', isStartEarlierThanEnd ? 1 : -1));
892898
this._calendar.values = range.map((d) => d.native);
893899
} else {
894900
this._calendar.values = [this._startDate];
895901
}
896-
this._calendar.activeDate = this._startDate ?? this._calendar.activeDate;
897902
}
898903

899904
private swapDates() {
@@ -919,6 +924,7 @@ export default class IgcDateRangePickerComponent extends FormAssociatedRequiredM
919924

920925
private _select(value: DateRangeValue | null, emitEvent = false) {
921926
this.value = value;
927+
this._calendar.activeDate = this._startDate ?? this._calendar.activeDate;
922928
if (emitEvent) {
923929
this.emitEvent('igcChange', { detail: this.value });
924930
}

0 commit comments

Comments
 (0)