Skip to content

Instantly share code, notes, and snippets.

@peterblazejewicz
Created September 22, 2019 10:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save peterblazejewicz/2fc4a682e4ed1a56093ac04f7a67b480 to your computer and use it in GitHub Desktop.
Save peterblazejewicz/2fc4a682e4ed1a56093ac04f7a67b480 to your computer and use it in GitHub Desktop.
commit 38488c5e1e297f362c2ff50b9e1b0decb6c8aa6a
Author: Peter Blazejewicz <peterblazejewicz@users.noreply.github.com>
Date: Sun Sep 22 12:39:29 2019 +0200
chore(commit): fix
diff --git a/src/datepicker/datepicker-input.ts b/src/datepicker/datepicker-input.ts
index 08026a6..7ecc1d8 100644
--- a/src/datepicker/datepicker-input.ts
+++ b/src/datepicker/datepicker-input.ts
@@ -441,6 +441,11 @@ export class NgbInputDatepicker implements OnChanges,
this.close();
}
});
+ datepickerInstance.close.subscribe((event: KeyboardEvent) => {
+ if (this.autoClose && this.isOpen()) {
+ this.close();
+ }
+ });
}
private _writeModelValue(model: NgbDate) {
diff --git a/src/datepicker/datepicker-keymap-service.spec.ts b/src/datepicker/datepicker-keymap-service.spec.ts
index a3269ae..777c8d2 100644
--- a/src/datepicker/datepicker-keymap-service.spec.ts
+++ b/src/datepicker/datepicker-keymap-service.spec.ts
@@ -14,14 +14,14 @@ describe('ngb-datepicker-keymap-service', () => {
let service: NgbDatepickerKeyMapService;
let calendar: NgbCalendar;
- let mock: {focus, focusMove, focusSelect, model$};
+ let mock: {focus, focusMove, focusSelect, close, model$};
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
NgbDatepickerKeyMapService, {provide: NgbCalendar, useClass: NgbCalendarGregorian}, {
provide: NgbDatepickerService,
- useValue: {focus: () => {}, focusMove: () => {}, focusSelect: () => {}, model$: new Subject()}
+ useValue: {focus: () => {}, focusMove: () => {}, focusSelect: () => {}, close: () => {}, model$: new Subject()}
}
]
});
@@ -33,6 +33,7 @@ describe('ngb-datepicker-keymap-service', () => {
spyOn(mock, 'focus');
spyOn(mock, 'focusMove');
spyOn(mock, 'focusSelect');
+ spyOn(mock, 'close');
});
it('should be instantiated', () => { expect(service).toBeTruthy(); });
@@ -120,6 +121,15 @@ describe('ngb-datepicker-keymap-service', () => {
expect(e.preventDefault).toHaveBeenCalled();
expect(e.stopPropagation).toHaveBeenCalled();
+ // ESC
+ e = event(Key.Escape);
+ spyOn(e, 'preventDefault');
+ spyOn(e, 'stopPropagation');
+
+ service.processKey(e);
+ expect(e.preventDefault).toHaveBeenCalled();
+ expect(e.stopPropagation).toHaveBeenCalled();
+
// unknown key
e = event(23);
spyOn(e, 'preventDefault');
diff --git a/src/datepicker/datepicker-keymap-service.ts b/src/datepicker/datepicker-keymap-service.ts
index 0bf6769..4333ccf 100644
--- a/src/datepicker/datepicker-keymap-service.ts
+++ b/src/datepicker/datepicker-keymap-service.ts
@@ -51,6 +51,9 @@ export class NgbDatepickerKeyMapService {
case Key.Space:
this._service.focusSelect();
break;
+ case Key.Escape:
+ this._service.close(event);
+ break;
default:
return;
}
diff --git a/src/datepicker/datepicker-service.spec.ts b/src/datepicker/datepicker-service.spec.ts
index 0538876..cc1854d 100644
--- a/src/datepicker/datepicker-service.spec.ts
+++ b/src/datepicker/datepicker-service.spec.ts
@@ -6,6 +6,7 @@ import {Subscription} from 'rxjs';
import {DatepickerViewModel} from './datepicker-view-model';
import {NgbDatepickerI18n, NgbDatepickerI18nDefault} from './datepicker-i18n';
import {Type} from '@angular/core';
+import {Key} from '../util/key';
describe('ngb-datepicker-service', () => {
@@ -15,6 +16,8 @@ describe('ngb-datepicker-service', () => {
let mock: {onNext};
let selectDate: NgbDate;
let mockSelect: {onNext};
+ let mockClose: {onNext};
+ let closeEvent: KeyboardEvent;
let subscriptions: Subscription[];
@@ -35,6 +38,7 @@ describe('ngb-datepicker-service', () => {
subscriptions = [];
model = undefined;
selectDate = null;
+ closeEvent = undefined;
mock = {onNext: () => {}};
spyOn(mock, 'onNext');
@@ -42,10 +46,14 @@ describe('ngb-datepicker-service', () => {
mockSelect = {onNext: () => {}};
spyOn(mockSelect, 'onNext');
+ mockClose = {onNext: () => {}};
+ spyOn(mockClose, 'onNext');
+
// subscribing
subscriptions.push(
service.model$.subscribe(mock.onNext), service.model$.subscribe(m => model = m),
- service.select$.subscribe(mockSelect.onNext), service.select$.subscribe(d => selectDate = d));
+ service.select$.subscribe(mockSelect.onNext), service.select$.subscribe(d => selectDate = d),
+ service.close$.subscribe(mockClose.onNext), service.close$.subscribe(e => closeEvent = e));
});
afterEach(() => { subscriptions.forEach(s => s.unsubscribe()); });
@@ -953,6 +961,25 @@ describe('ngb-datepicker-service', () => {
});
});
+ describe('close handling', () => {
+
+ const event = (type: string, keyCode: number, shift = false) =>
+ <any>({type, which: keyCode, shiftKey: shift, preventDefault: () => {}, stopPropagation: () => {}});
+
+ it(`should emit keyboard event on Escape key down`, () => {
+ const mockEvent = event('keydown', Key.Escape);
+ service.close(mockEvent);
+ expect(mockClose.onNext).toHaveBeenCalledTimes(1);
+ expect(mockEvent).toBe(closeEvent);
+ });
+
+ it(`should not emit keyboard event when not Escape or key down`, () => {
+ service.close(event('keyup', Key.ArrowLeft));
+ expect(mockClose.onNext).toHaveBeenCalledTimes(0);
+ });
+
+ });
+
describe(`focus handling`, () => {
it(`should generate 1 month on 'focus()' by default`, () => {
diff --git a/src/datepicker/datepicker-service.ts b/src/datepicker/datepicker-service.ts
index 88b0665..720714d 100644
--- a/src/datepicker/datepicker-service.ts
+++ b/src/datepicker/datepicker-service.ts
@@ -20,6 +20,7 @@ import {
import {filter} from 'rxjs/operators';
import {NgbDatepickerI18n} from './datepicker-i18n';
+import { Key } from '../util/key';
@Injectable()
export class NgbDatepickerService {
@@ -27,6 +28,8 @@ export class NgbDatepickerService {
private _select$ = new Subject<NgbDate>();
+ private _close$ = new Subject<KeyboardEvent>();
+
private _state: DatepickerViewModel = {
disabled: false,
displayMonths: 1,
@@ -45,6 +48,8 @@ export class NgbDatepickerService {
get select$(): Observable<NgbDate> { return this._select$.pipe(filter(date => date !== null)); }
+ get close$(): Observable<KeyboardEvent> { return this._close$.pipe(filter(event => event.which === Key.Escape)); }
+
set dayTemplateData(dayTemplateData: NgbDayTemplateData) {
if (this._state.dayTemplateData !== dayTemplateData) {
this._nextState({dayTemplateData});
@@ -127,6 +132,12 @@ export class NgbDatepickerService {
}
}
+ close(event: KeyboardEvent) {
+ if(event.type === 'keydown' && event.which === Key.Escape) {
+ this._close$.next(event);
+ }
+ }
+
open(date: NgbDate) {
const firstDate = this.toValidDate(date, this._calendar.getToday());
if (!this._state.disabled && (!this._state.firstDate || isChangedMonth(this._state.firstDate, date))) {
diff --git a/src/datepicker/datepicker.ts b/src/datepicker/datepicker.ts
index a17e658..fc04226 100644
--- a/src/datepicker/datepicker.ts
+++ b/src/datepicker/datepicker.ts
@@ -242,6 +242,11 @@ export class NgbDatepicker implements OnDestroy,
*/
@Output() select = new EventEmitter<NgbDate>();
+ /**
+ * An event emitted when user press down ESC key
+ */
+ @Output() close = new EventEmitter<KeyboardEvent>();
+
onChange = (_: any) => {};
onTouched = () => {};
@@ -296,6 +301,11 @@ export class NgbDatepicker implements OnDestroy,
_cd.markForCheck();
});
+
+ _service.close$.pipe(takeUntil(this._destroyed$)).subscribe(event => {
+ this.close.emit(event);
+ });
+
}
focus() {
diff --git a/src/modal/modal-window.spec.ts b/src/modal/modal-window.spec.ts
index 2f55d07..c91a2ec 100644
--- a/src/modal/modal-window.spec.ts
+++ b/src/modal/modal-window.spec.ts
@@ -105,7 +105,7 @@ describe('ngb-modal-dialog', () => {
done();
});
- fixture.debugElement.triggerEventHandler('keyup.esc', {});
+ fixture.debugElement.triggerEventHandler('keydown.esc', {});
});
});
diff --git a/src/modal/modal-window.ts b/src/modal/modal-window.ts
index 9ea8a5f..be7c253 100644
--- a/src/modal/modal-window.ts
+++ b/src/modal/modal-window.ts
@@ -21,7 +21,7 @@ import {ModalDismissReasons} from './modal-dismiss-reasons';
'[class]': '"modal fade show d-block" + (windowClass ? " " + windowClass : "")',
'role': 'dialog',
'tabindex': '-1',
- '(keyup.esc)': 'escKey($event)',
+ '(keydown.esc)': 'escKey($event)',
'(click)': 'backdropClick($event)',
'[attr.aria-modal]': 'true',
'[attr.aria-labelledby]': 'ariaLabelledBy',
diff --git a/src/modal/modal.spec.ts b/src/modal/modal.spec.ts
index 80af80c..865d843 100644
--- a/src/modal/modal.spec.ts
+++ b/src/modal/modal.spec.ts
@@ -350,12 +350,12 @@ describe('ngb-modal', () => {
expect(fixture.nativeElement).toHaveModal(['foo', 'bar']);
expect(document.activeElement).toBe(ngbModalWindow2);
- (<DebugElement>getDebugNode(document.activeElement)).triggerEventHandler('keyup.esc', {});
+ (<DebugElement>getDebugNode(document.activeElement)).triggerEventHandler('keydown.esc', {});
fixture.detectChanges();
expect(fixture.nativeElement).toHaveModal(['foo']);
expect(document.activeElement).toBe(ngbModalWindow1);
- (<DebugElement>getDebugNode(document.activeElement)).triggerEventHandler('keyup.esc', {});
+ (<DebugElement>getDebugNode(document.activeElement)).triggerEventHandler('keydown.esc', {});
fixture.detectChanges();
expect(fixture.nativeElement).not.toHaveModal();
expect(document.activeElement).toBe(document.body);
@@ -575,7 +575,7 @@ describe('ngb-modal', () => {
fixture.detectChanges();
expect(fixture.nativeElement).toHaveModal('foo');
- (<DebugElement>getDebugNode(document.querySelector('ngb-modal-window'))).triggerEventHandler('keyup.esc', {});
+ (<DebugElement>getDebugNode(document.querySelector('ngb-modal-window'))).triggerEventHandler('keydown.esc', {});
fixture.detectChanges();
expect(fixture.nativeElement).not.toHaveModal();
});
@@ -585,7 +585,7 @@ describe('ngb-modal', () => {
fixture.detectChanges();
expect(fixture.nativeElement).toHaveModal('foo');
- (<DebugElement>getDebugNode(document.querySelector('ngb-modal-window'))).triggerEventHandler('keyup.esc', {});
+ (<DebugElement>getDebugNode(document.querySelector('ngb-modal-window'))).triggerEventHandler('keydown.esc', {});
fixture.detectChanges();
expect(fixture.nativeElement).toHaveModal();
@@ -599,7 +599,7 @@ describe('ngb-modal', () => {
fixture.detectChanges();
expect(fixture.nativeElement).toHaveModal('foo');
- (<DebugElement>getDebugNode(document.querySelector('ngb-modal-window'))).triggerEventHandler('keyup.esc', {
+ (<DebugElement>getDebugNode(document.querySelector('ngb-modal-window'))).triggerEventHandler('keydown.esc', {
defaultPrevented: true
});
fixture.detectChanges();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment