Skip to content

Commit 2de5540

Browse files
committed
refactor: add util function to compare date range and use it where applicable
1 parent 3f2a5b5 commit 2de5540

File tree

4 files changed

+82
-14
lines changed

4 files changed

+82
-14
lines changed

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

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,15 @@ describe('Date range picker', () => {
6161
await expect(picker).lightDom.to.be.accessible();
6262
});
6363

64-
xit('is accessible (open state) - default dropdown mode', async () => {
64+
it('is accessible (open state) - default dropdown mode', async () => {
6565
picker.open = true;
6666
await elementUpdated(picker);
6767

6868
await expect(picker).shadowDom.to.be.accessible();
6969
await expect(picker).lightDom.to.be.accessible();
7070
});
7171

72-
xit('is accessible (open state) - dialog mode', async () => {
72+
it('is accessible (open state) - dialog mode', async () => {
7373
picker.open = true;
7474
picker.mode = 'dialog';
7575
await elementUpdated(picker);
@@ -753,6 +753,27 @@ describe('Date range picker', () => {
753753
});
754754
});
755755

756+
it('should not emit igcChange when value is unchanged and done is clicked (dialog)', async () => {
757+
const eventSpy = spy(picker, 'emitEvent');
758+
picker.value = { start: today.native, end: tomorrow.native };
759+
picker.mode = 'dialog';
760+
await elementUpdated(picker);
761+
762+
picker.open = true;
763+
await elementUpdated(picker);
764+
765+
expect(eventSpy).not.to.be.calledWith('igcChange');
766+
const dialog = picker.renderRoot.querySelector('igc-dialog');
767+
expect(dialog?.hasAttribute('open')).to.equal(true);
768+
769+
const doneBtn = picker.shadowRoot!.querySelector(
770+
'igc-button[slot="footer"]:last-of-type'
771+
) as HTMLButtonElement;
772+
doneBtn?.click();
773+
await elementUpdated(picker);
774+
expect(eventSpy).not.calledWith('igcChange');
775+
});
776+
756777
it('should select a range of dates in dialog mode and emit igcChange when done is clicked', async () => {
757778
const eventSpy = spy(picker, 'emitEvent');
758779

@@ -2033,12 +2054,8 @@ const checkSelectedRange = (
20332054
IgcCalendarComponent.tagName
20342055
)!;
20352056

2036-
if (expectedValue?.start) {
2037-
checkDatesEqual(picker.value?.start!, expectedValue.start);
2038-
}
2039-
if (expectedValue?.end) {
2040-
checkDatesEqual(picker.value?.end!, expectedValue.end);
2041-
}
2057+
DateTimeUtil.areDateRangesEqual(picker.value, expectedValue);
2058+
20422059
if (!useTwoInputs) {
20432060
const input = picker.renderRoot.querySelector(IgcInputComponent.tagName)!;
20442061
const start = expectedValue?.start

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

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -652,7 +652,9 @@ export default class IgcDateRangePickerComponent extends FormAssociatedRequiredM
652652
}
653653

654654
protected dialogDone() {
655-
this.emitEvent('igcChange', { detail: this.value });
655+
if (!DateTimeUtil.areDateRangesEqual(this.value, this._oldValue)) {
656+
this.emitEvent('igcChange', { detail: this.value });
657+
}
656658
this._hide(true);
657659
}
658660

@@ -723,11 +725,12 @@ export default class IgcDateRangePickerComponent extends FormAssociatedRequiredM
723725
protected handleFocusOut({ relatedTarget }: FocusEvent) {
724726
if (!this.contains(relatedTarget as Node)) {
725727
this.checkValidity();
726-
if (
727-
!this.useTwoInputs &&
728-
!this.readOnly &&
729-
this._oldValue !== this.value
730-
) {
728+
729+
const isSameValue = DateTimeUtil.areDateRangesEqual(
730+
this.value,
731+
this._oldValue
732+
);
733+
if (!this.useTwoInputs && !this.readOnly && !isSameValue) {
731734
this.emitEvent('igcChange', { detail: this.value });
732735
}
733736
}

src/components/date-time-input/date-util.spec.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,4 +645,28 @@ describe('Date Util', () => {
645645
DateTimeUtil.spinAmPm(currentDate, newDate, 'AM');
646646
expect(currentDate.getHours()).to.equal(4);
647647
});
648+
649+
it('should correctly compare DateRangeValue objects', () => {
650+
const now = new Date();
651+
const later = new Date(now.getTime() + 1000 * 60 * 60); // 1 hour later
652+
653+
const range1 = { start: now, end: later };
654+
const range2 = { start: new Date(now), end: new Date(later) };
655+
const range3 = { start: new Date(now), end: new Date(now) };
656+
657+
expect(DateTimeUtil.areDateRangesEqual(range1, range2)).to.be.true;
658+
659+
expect(DateTimeUtil.areDateRangesEqual(range1, range3)).to.be.false;
660+
661+
expect(DateTimeUtil.areDateRangesEqual(range1, null)).to.be.false;
662+
expect(DateTimeUtil.areDateRangesEqual(null, range2)).to.be.false;
663+
664+
expect(DateTimeUtil.areDateRangesEqual(null, null)).to.be.true;
665+
666+
const partial1 = { start: null, end: later };
667+
const partial2 = { start: null, end: new Date(later) };
668+
const partial3 = { start: now, end: later };
669+
expect(DateTimeUtil.areDateRangesEqual(partial1, partial2)).to.be.true;
670+
expect(DateTimeUtil.areDateRangesEqual(partial1, partial3)).to.be.false;
671+
});
648672
});

src/components/date-time-input/date-util.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { parseISODate } from '../calendar/helpers.js';
2+
import type { DateRangeValue } from '../date-range-picker/date-range-picker.js';
23
import { MaskParser } from '../mask-input/mask-parser.js';
34

45
export enum FormatDesc {
@@ -553,6 +554,29 @@ export abstract class DateTimeUtil {
553554
: format;
554555
}
555556

557+
/**
558+
* Compares two date-range values.
559+
*
560+
* @param first, @param second - the values to compare
561+
*/
562+
public static areDateRangesEqual(
563+
first: DateRangeValue | null,
564+
second: DateRangeValue | null
565+
): boolean {
566+
if (!first && !second) {
567+
return true;
568+
}
569+
570+
if (!first || !second) {
571+
return false;
572+
}
573+
574+
const isStartEqual = first.start?.getTime() === second.start?.getTime();
575+
const isEndEqual = first.end?.getTime() === second.end?.getTime();
576+
577+
return isStartEqual && isEndEqual;
578+
}
579+
556580
private static setDisplayFormatOptions(
557581
value: Date,
558582
format: string,

0 commit comments

Comments
 (0)