Skip to content

Commit 4e17a9b

Browse files
committed
feat(drp): add default clear icon in single input
1 parent e841401 commit 4e17a9b

File tree

3 files changed

+100
-5
lines changed

3 files changed

+100
-5
lines changed

projects/igniteui-angular/src/lib/date-range-picker/date-range-picker.component.html

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,24 @@
2222
<ng-template #defDateSeparatorTemplate>{{ dateSeparator }}</ng-template>
2323

2424
<ng-template #defTemplate>
25-
<igx-input-group [type]="type" (click)="open()">
25+
<igx-input-group [type]="type">
2626
<!-- only set mask placeholder when empty, otherwise input group might use it as label if none is set -->
2727
<input #singleInput igxInput type="text" readonly [disabled]="disabled" [placeholder]="value ? '' : singleInputFormat"
2828
role="combobox" aria-haspopup="grid" [attr.aria-expanded]="!collapsed" [attr.aria-labelledby]="label?.id"
2929
[value]="value | dateRange: appliedFormat : locale : formatter" />
3030

3131
@if (!toggleComponents.length) {
32-
<igx-prefix>
32+
<igx-prefix (click)="toggle()">
3333
<ng-container *ngTemplateOutlet="defIcon"></ng-container>
3434
</igx-prefix>
3535
}
3636

37+
@if (!clearComponents.length && value) {
38+
<igx-suffix (click)="clear()">
39+
<igx-icon family="default" name="input_clear"></igx-icon>
40+
</igx-suffix>
41+
}
42+
3743
<ng-container ngProjectAs="[igxLabel]">
3844
<ng-content select="[igxLabel]"></ng-content>
3945
</ng-container>

projects/igniteui-angular/src/lib/date-range-picker/date-range-picker.component.spec.ts

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { ComponentFixture, TestBed, fakeAsync, tick, waitForAsync, flush } from '@angular/core/testing';
22
import { Component, OnInit, ViewChild, DebugElement, ChangeDetectionStrategy } from '@angular/core';
3-
import { IgxInputDirective, IgxInputState, IgxLabelDirective, IgxPrefixDirective, IgxSuffixDirective } from '../input-group/public_api';
3+
import { IgxInputDirective, IgxInputGroupComponent, IgxInputState, IgxLabelDirective, IgxPrefixDirective, IgxSuffixDirective } from '../input-group/public_api';
44
import { PickerInteractionMode } from '../date-common/types';
55
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
66
import { FormsModule, ReactiveFormsModule, UntypedFormBuilder, UntypedFormControl, Validators } from '@angular/forms';
@@ -29,6 +29,7 @@ import localeBg from "@angular/common/locales/bg";
2929
// The number of milliseconds in one day
3030
const DEBOUNCE_TIME = 16;
3131
const DEFAULT_ICON_TEXT = 'date_range';
32+
const CLEAR_ICON_TEXT = 'clear';
3233
const DEFAULT_FORMAT_OPTIONS = { day: '2-digit', month: '2-digit', year: 'numeric' };
3334
const CSS_CLASS_INPUT_BUNDLE = '.igx-input-group__bundle';
3435
const CSS_CLASS_INPUT_START = '.igx-input-group__bundle-start'
@@ -399,6 +400,72 @@ describe('IgxDateRangePicker', () => {
399400
});
400401
});
401402

403+
describe('Clear tests', () => {
404+
describe('Default clear icon', () => {
405+
it('should display default clear icon when value is set', () => {
406+
const inputGroup = fixture.debugElement.query(By.directive(IgxInputGroupComponent));
407+
let suffix = inputGroup.query(By.directive(IgxSuffixDirective));
408+
expect(suffix).toBeNull();
409+
410+
dateRange.value = { start: new Date(2025, 1, 1), end: new Date(2025, 1, 2) };
411+
fixture.detectChanges();
412+
413+
suffix = inputGroup.query(By.directive(IgxSuffixDirective));
414+
const icon = suffix.query(By.css(CSS_CLASS_ICON));
415+
expect(icon).not.toBeNull();
416+
expect(icon.nativeElement.textContent.trim()).toEqual(CLEAR_ICON_TEXT);
417+
});
418+
419+
it('should clear the value when clicking the default clear icon (suffix)', fakeAsync(() => {
420+
dateRange.value = { start: new Date(2025, 1, 1), end: new Date(2025, 1, 2) };
421+
fixture.detectChanges();
422+
423+
const inputGroup = fixture.debugElement.query(By.directive(IgxInputGroupComponent));
424+
let suffix = inputGroup.query(By.directive(IgxSuffixDirective));
425+
spyOn(dateRange.valueChange, 'emit');
426+
427+
UIInteractions.simulateClickAndSelectEvent(suffix.nativeElement);
428+
tick();
429+
fixture.detectChanges();
430+
431+
expect(dateRange.value).toBeNull();
432+
suffix = inputGroup.query(By.directive(IgxSuffixDirective));
433+
expect(suffix).toBeNull();
434+
expect(dateRange.valueChange.emit).toHaveBeenCalledOnceWith(null);
435+
}));
436+
437+
it('should not clear the value when clicking element in the suffix that is not the clear icon', fakeAsync(() => {
438+
fixture = TestBed.createComponent(DateRangeTemplatesComponent);
439+
fixture.detectChanges();
440+
441+
dateRange = fixture.debugElement.queryAll(By.directive(IgxDateRangePickerComponent))[0].componentInstance;
442+
const range = { start: new Date(2025, 1, 1), end: new Date(2025, 1, 2) };
443+
dateRange.value = range;
444+
fixture.detectChanges();
445+
446+
const suffixIconText = 'flight_land';
447+
const inputGroupsEnd = fixture.debugElement.queryAll(By.css(CSS_CLASS_INPUT_END));
448+
449+
const customSuffix = inputGroupsEnd[1];
450+
expect(customSuffix.children[0].nativeElement.innerText).toBe(suffixIconText);
451+
expect(customSuffix.children[0].children[0].classes[CSS_CLASS_ICON]).toBeTruthy();
452+
453+
const suffix = inputGroupsEnd[0];
454+
const icon = suffix.query(By.css(CSS_CLASS_ICON));
455+
expect(icon).not.toBeNull();
456+
expect(icon.nativeElement.textContent.trim()).toEqual(CLEAR_ICON_TEXT);
457+
458+
UIInteractions.simulateClickAndSelectEvent(customSuffix.nativeElement);
459+
tick();
460+
fixture.detectChanges();
461+
462+
expect(dateRange.value).toEqual(range);
463+
}));
464+
});
465+
466+
//xdescribe('Projected clear icon', () => {});
467+
});
468+
402469
describe('Properties & events tests', () => {
403470
it('should display placeholder', () => {
404471
fixture.detectChanges();

projects/igniteui-angular/src/lib/date-range-picker/date-range-picker.component.ts

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ import { DateRangePickerResourceStringsEN, IDateRangePickerResourceStrings } fro
1919
import { IBaseCancelableBrowserEventArgs, isDate, parseDate, PlatformUtil } from '../core/utils';
2020
import { IgxCalendarContainerComponent } from '../date-common/calendar-container/calendar-container.component';
2121
import { PickerBaseDirective } from '../date-common/picker-base.directive';
22-
import { IgxPickerActionsDirective } from '../date-common/picker-icons.common';
22+
import { IgxPickerActionsDirective, IgxPickerClearComponent } from '../date-common/picker-icons.common';
2323
import { DateTimeUtil } from '../date-common/util/date-time.util';
2424
import { IgxOverlayOutletDirective } from '../directives/toggle/toggle.directive';
2525
import {
2626
IgxInputDirective, IgxInputGroupComponent, IgxInputGroupType, IgxInputState,
27-
IgxLabelDirective, IGX_INPUT_GROUP_TYPE
27+
IgxLabelDirective, IGX_INPUT_GROUP_TYPE, IgxSuffixDirective
2828
} from '../input-group/public_api';
2929
import {
3030
AutoPositionStrategy, IgxOverlayService, OverlayCancelableEventArgs, OverlayEventArgs,
@@ -73,6 +73,7 @@ const SingleInputDatesConcatenationString = ' - ';
7373
IgxInputGroupComponent,
7474
IgxInputDirective,
7575
IgxPrefixDirective,
76+
IgxSuffixDirective,
7677
DateRangePickerFormatPipe
7778
]
7879
})
@@ -301,6 +302,10 @@ export class IgxDateRangePickerComponent extends PickerBaseDirective
301302
@ContentChildren(IgxDateRangeInputsBaseComponent)
302303
public projectedInputs: QueryList<IgxDateRangeInputsBaseComponent>;
303304

305+
/** @hidden @internal */
306+
@ContentChildren(IgxPickerClearComponent)
307+
public clearComponents: QueryList<IgxPickerClearComponent>;
308+
304309
@ContentChild(IgxLabelDirective)
305310
public label: IgxLabelDirective;
306311

@@ -574,6 +579,23 @@ export class IgxDateRangePickerComponent extends PickerBaseDirective
574579
this.handleSelection(dateRange);
575580
}
576581

582+
/**
583+
* Clears the input field(s) and the picker's value.
584+
*
585+
* @example
586+
* ```typescript
587+
* this.dateRangePicker.clear();
588+
* ```
589+
*/
590+
public clear(): void {
591+
// TODO clear the projected inputs
592+
if (!this.disabled) {
593+
this.value = null;
594+
this._calendar?.deselectDate();
595+
this.inputDirective.clear();
596+
}
597+
}
598+
577599
/** @hidden @internal */
578600
public writeValue(value: DateRange): void {
579601
this.updateValue(value);

0 commit comments

Comments
 (0)