@progress/kendo-angular-dateinputs 12.1.0-develop.1 → 12.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -432,6 +432,9 @@ export declare class DateTimePickerComponent implements OnInit, OnChanges, After
432
432
  private popupTemplate;
433
433
  actionSheet: ActionSheetComponent;
434
434
  private get popupUID();
435
+ private get acceptButton();
436
+ private get cancelButtonElement();
437
+ private get dateTabButton();
435
438
  private popupRef;
436
439
  private _popupSettings;
437
440
  private _value;
@@ -528,6 +531,10 @@ export declare class DateTimePickerComponent implements OnInit, OnChanges, After
528
531
  * @hidden
529
532
  */
530
533
  handleTabChangeTransitionEnd(dateTimeSelector: HTMLElement, event: TransitionEvent): void;
534
+ /**
535
+ * @hidden
536
+ */
537
+ onTabOutLastPart(): void;
531
538
  /**
532
539
  * @hidden
533
540
  */
@@ -555,11 +562,7 @@ export declare class DateTimePickerComponent implements OnInit, OnChanges, After
555
562
  /**
556
563
  * @hidden
557
564
  */
558
- handleTabOut(event: KeyboardEvent): void;
559
- /**
560
- * @hidden
561
- */
562
- handleBackTabOut(event: KeyboardEvent): void;
565
+ handleTab(event: KeyboardEvent): void;
563
566
  /**
564
567
  * @hidden
565
568
  */
@@ -58,6 +58,9 @@ const DEFAULT_ACTIVE_TAB = 'date';
58
58
  const DEFAULT_DATEINPUT_FORMAT = 'g';
59
59
  const DEFAULT_TIMESELECTOR_FORMAT = 't';
60
60
  const TWO_DIGIT_YEAR_MAX = 68;
61
+ const ACCEPT_BUTTON_SELECTOR = '.k-button.k-time-accept';
62
+ const CANCEL_BUTTON_SELECOTR = '.k-button.k-time-cancel';
63
+ const DATE_TAB_BUTTON_SELECTOR = '.k-button.k-date-tab';
61
64
  /**
62
65
  * Represents the [Kendo UI DateTimePicker component for Angular]({% slug overview_datetimepicker %}).
63
66
  */
@@ -579,6 +582,18 @@ export class DateTimePickerComponent {
579
582
  return this.calendar?.popupId;
580
583
  }
581
584
  ;
585
+ get acceptButton() {
586
+ return this.popupRef?.popup.instance.container.nativeElement.querySelector(ACCEPT_BUTTON_SELECTOR);
587
+ }
588
+ ;
589
+ get cancelButtonElement() {
590
+ return this.popupRef?.popup.instance.container.nativeElement.querySelector(CANCEL_BUTTON_SELECOTR);
591
+ }
592
+ ;
593
+ get dateTabButton() {
594
+ return this.popupRef?.popup.instance.container.nativeElement.querySelector(DATE_TAB_BUTTON_SELECTOR);
595
+ }
596
+ ;
582
597
  ngOnInit() {
583
598
  this.subscriptions.add(this.pickerService.onFocus
584
599
  // detect popup changes to disable the inactive view mark-up when the popup is open
@@ -784,6 +799,20 @@ export class DateTimePickerComponent {
784
799
  }
785
800
  this.activeTabComponent.focus();
786
801
  }
802
+ /**
803
+ * @hidden
804
+ */
805
+ onTabOutLastPart() {
806
+ if (!this.cancelButton && !this.calendarValue) {
807
+ this.dateTabButton.focus();
808
+ }
809
+ else if (!this.cancelButton && this.calendarValue) {
810
+ this.acceptButton.focus();
811
+ }
812
+ else if (this.cancelButton) {
813
+ this.cancelButtonElement.focus();
814
+ }
815
+ }
787
816
  /**
788
817
  * @hidden
789
818
  */
@@ -866,22 +895,41 @@ export class DateTimePickerComponent {
866
895
  /**
867
896
  * @hidden
868
897
  */
869
- handleTabOut(event) {
870
- const { keyCode, shiftKey, target } = event;
871
- // if no focusable next sibling elements exist in the controls sections, the user is tabbing out of the popup
872
- const focusableSiblingAvailable = isPresent(target.nextElementSibling) && !target.nextElementSibling.disabled;
873
- if (keyCode === Keys.Tab && !shiftKey && !focusableSiblingAvailable) {
874
- this.input.focus();
875
- this.handleCancel();
876
- }
877
- }
878
- /**
879
- * @hidden
880
- */
881
- handleBackTabOut(event) {
882
- const { keyCode, shiftKey } = event;
883
- if (keyCode === Keys.Tab && shiftKey) {
884
- this.input.focus();
898
+ handleTab(event) {
899
+ event.preventDefault();
900
+ const { shiftKey } = event;
901
+ switch (event.target) {
902
+ case this.acceptButton:
903
+ if (!shiftKey && this.calendarValue) {
904
+ this.dateTabButton.focus();
905
+ }
906
+ break;
907
+ case this.cancelButtonElement:
908
+ if (!shiftKey && !this.calendarValue) {
909
+ this.dateTabButton.focus();
910
+ }
911
+ else if (!shiftKey && this.calendarValue) {
912
+ this.acceptButton.focus();
913
+ }
914
+ break;
915
+ case this.dateTabButton:
916
+ if (this.calendarValue) {
917
+ this.acceptButton.focus();
918
+ }
919
+ else if (!this.calendarValue && this.cancelButton) {
920
+ this.cancelButtonElement.focus();
921
+ }
922
+ else if (!this.calendarValue && !this.cancelButton) {
923
+ if (this.activeTab === 'date') {
924
+ this.calendar.monthView.list.nativeElement.focus();
925
+ }
926
+ else {
927
+ this.timeSelector.focus();
928
+ }
929
+ }
930
+ break;
931
+ default:
932
+ break;
885
933
  }
886
934
  }
887
935
  /**
@@ -1066,6 +1114,15 @@ export class DateTimePickerComponent {
1066
1114
  this.renderer.setAttribute(this.inputElement, attributeNames.ariaControls, this.popupUID);
1067
1115
  this.setAriaActiveDescendant();
1068
1116
  this.popupRef.popupAnchorViewportLeave.subscribe(() => this.handleCancel());
1117
+ if (this.calendar.type === 'infinite') {
1118
+ this.subscriptions.add(fromEvent(this.calendar.monthView.list.nativeElement, 'keydown').subscribe((event) => {
1119
+ const { keyCode, shiftKey } = event;
1120
+ if (keyCode === Keys.Tab && !shiftKey && !this.cancelButton && !this.calendarValue) {
1121
+ event.preventDefault();
1122
+ this.dateTabButton.focus();
1123
+ }
1124
+ }));
1125
+ }
1069
1126
  }
1070
1127
  setAriaActiveDescendant() {
1071
1128
  const focusedCellChangeEvent = this.calendar.type === 'infinite' ?
@@ -1374,7 +1431,7 @@ DateTimePickerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0"
1374
1431
  [attr.aria-label]="localization.get('dateTabLabel')"
1375
1432
  [kendoEventsOutsideAngular]="{
1376
1433
  click: changeActiveTab.bind(this, 'date'),
1377
- keydown: handleBackTabOut
1434
+ 'keydown.shift.tab': handleTab
1378
1435
  }"
1379
1436
  [scope]="this"
1380
1437
  >
@@ -1447,6 +1504,7 @@ DateTimePickerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0"
1447
1504
  [disabled]="disableTimeSelector"
1448
1505
  [isAdaptiveEnabled]="isAdaptiveModeEnabled"
1449
1506
  [isDateTimePicker]="true"
1507
+ (tabOutLastPart)="onTabOutLastPart()"
1450
1508
  >
1451
1509
  <kendo-timeselector-messages
1452
1510
  [acceptLabel]="localization.get('acceptLabel')"
@@ -1469,7 +1527,6 @@ DateTimePickerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0"
1469
1527
  *ngIf="!isAdaptive"
1470
1528
  class="k-datetime-footer k-action-buttons k-actions k-hstack k-justify-content-stretch"
1471
1529
  [kendoEventsOutsideAngular]="{
1472
- keydown: handleTabOut,
1473
1530
  focusin: handleFocus,
1474
1531
  focusout: handleBlur
1475
1532
  }"
@@ -1483,7 +1540,8 @@ DateTimePickerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0"
1483
1540
  [attr.title]="localization.get('cancelLabel')"
1484
1541
  [attr.aria-label]="localization.get('cancelLabel')"
1485
1542
  [kendoEventsOutsideAngular]="{
1486
- click: handleCancel
1543
+ click: handleCancel,
1544
+ 'keydown.tab': handleTab
1487
1545
  }"
1488
1546
  [scope]="this"
1489
1547
  >
@@ -1497,7 +1555,8 @@ DateTimePickerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0"
1497
1555
  [attr.aria-label]="localization.get('acceptLabel')"
1498
1556
  [disabled]="!calendarValue"
1499
1557
  [kendoEventsOutsideAngular]="{
1500
- click: handleAccept
1558
+ click: handleAccept,
1559
+ 'keydown.tab': handleTab
1501
1560
  }"
1502
1561
  [scope]="this"
1503
1562
  >
@@ -1506,7 +1565,7 @@ DateTimePickerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0"
1506
1565
  </div>
1507
1566
  </div>
1508
1567
  </ng-template>
1509
- `, isInline: true, components: [{ type: i6.DateInputComponent, selector: "kendo-dateinput", inputs: ["focusableId", "pickerType", "disabled", "readonly", "title", "tabindex", "role", "ariaReadOnly", "tabIndex", "format", "formatPlaceholder", "placeholder", "steps", "max", "min", "rangeValidation", "autoCorrect", "incompleteDateValidation", "twoDigitYearMax", "value", "spinners", "isPopupOpen", "hasPopup", "size", "rounded", "fillMode"], outputs: ["valueChange", "valueUpdate", "focus", "blur"], exportAs: ["kendo-dateinput"] }, { type: i7.IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass"], exportAs: ["kendoIconWrapper"] }, { type: i8.ResizeSensorComponent, selector: "kendo-resize-sensor", inputs: ["rateLimit"], outputs: ["resize"] }, { type: i9.ActionSheetComponent, selector: "kendo-actionsheet", inputs: ["title", "subtitle", "items", "cssClass", "animation", "expanded"], outputs: ["expandedChange", "expand", "collapse", "itemClick", "overlayClick"], exportAs: ["kendoActionSheet"] }, { type: i10.Button, selector: "button[kendoButton], span[kendoButton], kendo-button", inputs: ["toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "role", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { type: i11.CalendarComponent, selector: "kendo-calendar", inputs: ["id", "focusedDate", "min", "max", "rangeValidation", "selection", "value", "disabled", "tabindex", "tabIndex", "disabledDates", "navigation", "activeView", "bottomView", "topView", "type", "animateNavigation", "weekNumber", "cellTemplate", "monthCellTemplate", "yearCellTemplate", "decadeCellTemplate", "centuryCellTemplate", "weekNumberTemplate", "headerTitleTemplate", "navigationItemTemplate", "size"], outputs: ["activeViewChange", "navigate", "activeViewDateChange", "blur", "focus", "valueChange"], exportAs: ["kendo-calendar"] }, { type: i12.CalendarCustomMessagesComponent, selector: "kendo-calendar-messages" }, { type: i13.TimeSelectorComponent, selector: "kendo-timeselector", inputs: ["format", "min", "max", "cancelButton", "setButton", "nowButton", "disabled", "isAdaptiveEnabled", "isDateTimePicker", "steps", "value"], outputs: ["valueChange", "valueReject"], exportAs: ["kendo-timeselector"] }, { type: i14.TimeSelectorCustomMessagesComponent, selector: "kendo-timeselector-messages" }], directives: [{ type: i15.LocalizedMessagesDirective, selector: "[kendoDateTimePickerLocalizedMessages]" }, { type: i8.EventsOutsideAngularDirective, selector: "[kendoEventsOutsideAngular]", inputs: ["kendoEventsOutsideAngular", "scope"] }, { type: i16.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i16.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i9.ActionSheetTemplateDirective, selector: "[kendoActionSheetTemplate]" }, { type: i16.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1568
+ `, isInline: true, components: [{ type: i6.DateInputComponent, selector: "kendo-dateinput", inputs: ["focusableId", "pickerType", "disabled", "readonly", "title", "tabindex", "role", "ariaReadOnly", "tabIndex", "format", "formatPlaceholder", "placeholder", "steps", "max", "min", "rangeValidation", "autoCorrect", "incompleteDateValidation", "twoDigitYearMax", "value", "spinners", "isPopupOpen", "hasPopup", "size", "rounded", "fillMode"], outputs: ["valueChange", "valueUpdate", "focus", "blur"], exportAs: ["kendo-dateinput"] }, { type: i7.IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass"], exportAs: ["kendoIconWrapper"] }, { type: i8.ResizeSensorComponent, selector: "kendo-resize-sensor", inputs: ["rateLimit"], outputs: ["resize"] }, { type: i9.ActionSheetComponent, selector: "kendo-actionsheet", inputs: ["title", "subtitle", "items", "cssClass", "animation", "expanded"], outputs: ["expandedChange", "expand", "collapse", "itemClick", "overlayClick"], exportAs: ["kendoActionSheet"] }, { type: i10.Button, selector: "button[kendoButton], span[kendoButton], kendo-button", inputs: ["toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "role", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { type: i11.CalendarComponent, selector: "kendo-calendar", inputs: ["id", "focusedDate", "min", "max", "rangeValidation", "selection", "value", "disabled", "tabindex", "tabIndex", "disabledDates", "navigation", "activeView", "bottomView", "topView", "type", "animateNavigation", "weekNumber", "cellTemplate", "monthCellTemplate", "yearCellTemplate", "decadeCellTemplate", "centuryCellTemplate", "weekNumberTemplate", "headerTitleTemplate", "navigationItemTemplate", "size"], outputs: ["activeViewChange", "navigate", "activeViewDateChange", "blur", "focus", "valueChange"], exportAs: ["kendo-calendar"] }, { type: i12.CalendarCustomMessagesComponent, selector: "kendo-calendar-messages" }, { type: i13.TimeSelectorComponent, selector: "kendo-timeselector", inputs: ["format", "min", "max", "cancelButton", "setButton", "nowButton", "disabled", "isAdaptiveEnabled", "isDateTimePicker", "steps", "value"], outputs: ["valueChange", "valueReject", "tabOutLastPart"], exportAs: ["kendo-timeselector"] }, { type: i14.TimeSelectorCustomMessagesComponent, selector: "kendo-timeselector-messages" }], directives: [{ type: i15.LocalizedMessagesDirective, selector: "[kendoDateTimePickerLocalizedMessages]" }, { type: i8.EventsOutsideAngularDirective, selector: "[kendoEventsOutsideAngular]", inputs: ["kendoEventsOutsideAngular", "scope"] }, { type: i16.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i16.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i9.ActionSheetTemplateDirective, selector: "[kendoActionSheetTemplate]" }, { type: i16.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1510
1569
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: DateTimePickerComponent, decorators: [{
1511
1570
  type: Component,
1512
1571
  args: [{
@@ -1732,7 +1791,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImpo
1732
1791
  [attr.aria-label]="localization.get('dateTabLabel')"
1733
1792
  [kendoEventsOutsideAngular]="{
1734
1793
  click: changeActiveTab.bind(this, 'date'),
1735
- keydown: handleBackTabOut
1794
+ 'keydown.shift.tab': handleTab
1736
1795
  }"
1737
1796
  [scope]="this"
1738
1797
  >
@@ -1805,6 +1864,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImpo
1805
1864
  [disabled]="disableTimeSelector"
1806
1865
  [isAdaptiveEnabled]="isAdaptiveModeEnabled"
1807
1866
  [isDateTimePicker]="true"
1867
+ (tabOutLastPart)="onTabOutLastPart()"
1808
1868
  >
1809
1869
  <kendo-timeselector-messages
1810
1870
  [acceptLabel]="localization.get('acceptLabel')"
@@ -1827,7 +1887,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImpo
1827
1887
  *ngIf="!isAdaptive"
1828
1888
  class="k-datetime-footer k-action-buttons k-actions k-hstack k-justify-content-stretch"
1829
1889
  [kendoEventsOutsideAngular]="{
1830
- keydown: handleTabOut,
1831
1890
  focusin: handleFocus,
1832
1891
  focusout: handleBlur
1833
1892
  }"
@@ -1841,7 +1900,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImpo
1841
1900
  [attr.title]="localization.get('cancelLabel')"
1842
1901
  [attr.aria-label]="localization.get('cancelLabel')"
1843
1902
  [kendoEventsOutsideAngular]="{
1844
- click: handleCancel
1903
+ click: handleCancel,
1904
+ 'keydown.tab': handleTab
1845
1905
  }"
1846
1906
  [scope]="this"
1847
1907
  >
@@ -1855,7 +1915,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImpo
1855
1915
  [attr.aria-label]="localization.get('acceptLabel')"
1856
1916
  [disabled]="!calendarValue"
1857
1917
  [kendoEventsOutsideAngular]="{
1858
- click: handleAccept
1918
+ click: handleAccept,
1919
+ 'keydown.tab': handleTab
1859
1920
  }"
1860
1921
  [scope]="this"
1861
1922
  >
@@ -9,7 +9,7 @@ export const packageMetadata = {
9
9
  name: '@progress/kendo-angular-dateinputs',
10
10
  productName: 'Kendo UI for Angular',
11
11
  productCodes: ['KENDOUIANGULAR', 'KENDOUICOMPLETE'],
12
- publishDate: 1684148954,
13
- version: '12.1.0-develop.1',
12
+ publishDate: 1684310705,
13
+ version: '12.1.0',
14
14
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/'
15
15
  };
@@ -17,6 +17,7 @@ import { MillisecondsService } from './services/milliseconds.service';
17
17
  import { DayPeriodService } from './services/dayperiod.service';
18
18
  import { closestInScope } from '../common/dom-queries';
19
19
  import { LocalizationService } from '@progress/kendo-angular-l10n';
20
+ import { Keys } from '@progress/kendo-angular-common';
20
21
  import * as i0 from "@angular/core";
21
22
  import * as i1 from "./services/dom.service";
22
23
  import * as i2 from "@progress/kendo-angular-l10n";
@@ -54,7 +55,9 @@ export class TimeListComponent {
54
55
  this.max = cloneDate(MAX_TIME);
55
56
  this.step = 1;
56
57
  this.disabled = false;
58
+ this.isLast = false;
57
59
  this.valueChange = new EventEmitter();
60
+ this.tabOutLastPart = new EventEmitter();
58
61
  this.componentClass = true;
59
62
  this.animateToIndex = true;
60
63
  this.isActive = false;
@@ -231,6 +234,10 @@ export class TimeListComponent {
231
234
  return oldData && newData && oldData.text !== newData.text;
232
235
  }
233
236
  handleKeyDown(e) {
237
+ if (e.keyCode === Keys.Tab && !e.shiftKey && this.isLast) {
238
+ e.preventDefault();
239
+ this.tabOutLastPart.emit();
240
+ }
234
241
  const getter = getters[e.keyCode] || nil;
235
242
  const dataItem = getter(this.data, this.service.selectedIndex(this.value));
236
243
  if (dataItem) {
@@ -251,7 +258,7 @@ export class TimeListComponent {
251
258
  }
252
259
  }
253
260
  TimeListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: TimeListComponent, deps: [{ token: i0.ElementRef }, { token: i0.Injector }, { token: i1.TimePickerDOMService }, { token: i0.Renderer2 }, { token: i0.NgZone }, { token: i2.LocalizationService }], target: i0.ɵɵFactoryTarget.Component });
254
- TimeListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.12", type: TimeListComponent, selector: "kendo-timelist", inputs: { min: "min", max: "max", part: "part", step: "step", disabled: "disabled", value: "value" }, outputs: { valueChange: "valueChange" }, host: { properties: { "attr.role": "this.roleAttribute", "attr.aria-label": "this.ariaLabel", "attr.tabindex": "this.tabIndex", "class.k-time-list": "this.componentClass" } }, viewQueries: [{ propertyName: "virtualization", first: true, predicate: VirtualizationComponent, descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: `
261
+ TimeListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.12", type: TimeListComponent, selector: "kendo-timelist", inputs: { min: "min", max: "max", part: "part", step: "step", disabled: "disabled", value: "value", isLast: "isLast" }, outputs: { valueChange: "valueChange", tabOutLastPart: "tabOutLastPart" }, host: { properties: { "attr.role": "this.roleAttribute", "attr.aria-label": "this.ariaLabel", "attr.tabindex": "this.tabIndex", "class.k-time-list": "this.componentClass" } }, viewQueries: [{ propertyName: "virtualization", first: true, predicate: VirtualizationComponent, descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: `
255
262
  <kendo-virtualization
256
263
  [skip]="skip"
257
264
  [take]="total"
@@ -326,8 +333,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImpo
326
333
  type: Input
327
334
  }], value: [{
328
335
  type: Input
336
+ }], isLast: [{
337
+ type: Input
329
338
  }], valueChange: [{
330
339
  type: Output
340
+ }], tabOutLastPart: [{
341
+ type: Output
331
342
  }], virtualization: [{
332
343
  type: ViewChild,
333
344
  args: [VirtualizationComponent, { static: true }]
@@ -747,6 +747,17 @@ export class TimePickerComponent {
747
747
  }
748
748
  this.windowSize = windowSize();
749
749
  }
750
+ /**
751
+ * @hidden
752
+ */
753
+ onTabOutLastPart() {
754
+ if (this.cancelButton) {
755
+ this.timeSelector.cancel.nativeElement.focus();
756
+ }
757
+ else {
758
+ this.timeSelector.accept.nativeElement.focus();
759
+ }
760
+ }
750
761
  toggleTimeSelector(show) {
751
762
  this.windowSize = windowSize();
752
763
  if (this.isAdaptive) {
@@ -1105,6 +1116,7 @@ TimePickerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", ve
1105
1116
  [scope]="this"
1106
1117
  (valueChange)="handleChange($event)"
1107
1118
  (valueReject)="handleReject()"
1119
+ (tabOutLastPart)="onTabOutLastPart()"
1108
1120
  >
1109
1121
  <kendo-timeselector-messages
1110
1122
  [acceptLabel]="localization.get('acceptLabel')"
@@ -1122,7 +1134,7 @@ TimePickerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", ve
1122
1134
  </kendo-timeselector-messages>
1123
1135
  </kendo-timeselector>
1124
1136
  </ng-template>
1125
- `, isInline: true, components: [{ type: i6.DateInputComponent, selector: "kendo-dateinput", inputs: ["focusableId", "pickerType", "disabled", "readonly", "title", "tabindex", "role", "ariaReadOnly", "tabIndex", "format", "formatPlaceholder", "placeholder", "steps", "max", "min", "rangeValidation", "autoCorrect", "incompleteDateValidation", "twoDigitYearMax", "value", "spinners", "isPopupOpen", "hasPopup", "size", "rounded", "fillMode"], outputs: ["valueChange", "valueUpdate", "focus", "blur"], exportAs: ["kendo-dateinput"] }, { type: i7.IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass"], exportAs: ["kendoIconWrapper"] }, { type: i8.ResizeSensorComponent, selector: "kendo-resize-sensor", inputs: ["rateLimit"], outputs: ["resize"] }, { type: i9.ActionSheetComponent, selector: "kendo-actionsheet", inputs: ["title", "subtitle", "items", "cssClass", "animation", "expanded"], outputs: ["expandedChange", "expand", "collapse", "itemClick", "overlayClick"], exportAs: ["kendoActionSheet"] }, { type: i10.Button, selector: "button[kendoButton], span[kendoButton], kendo-button", inputs: ["toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "role", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { type: i11.TimeSelectorComponent, selector: "kendo-timeselector", inputs: ["format", "min", "max", "cancelButton", "setButton", "nowButton", "disabled", "isAdaptiveEnabled", "isDateTimePicker", "steps", "value"], outputs: ["valueChange", "valueReject"], exportAs: ["kendo-timeselector"] }, { type: i12.TimeSelectorCustomMessagesComponent, selector: "kendo-timeselector-messages" }], directives: [{ type: i13.TimePickerLocalizedMessagesDirective, selector: "[kendoTimePickerLocalizedMessages]" }, { type: i8.EventsOutsideAngularDirective, selector: "[kendoEventsOutsideAngular]", inputs: ["kendoEventsOutsideAngular", "scope"] }, { type: i14.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i14.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i9.ActionSheetTemplateDirective, selector: "[kendoActionSheetTemplate]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1137
+ `, isInline: true, components: [{ type: i6.DateInputComponent, selector: "kendo-dateinput", inputs: ["focusableId", "pickerType", "disabled", "readonly", "title", "tabindex", "role", "ariaReadOnly", "tabIndex", "format", "formatPlaceholder", "placeholder", "steps", "max", "min", "rangeValidation", "autoCorrect", "incompleteDateValidation", "twoDigitYearMax", "value", "spinners", "isPopupOpen", "hasPopup", "size", "rounded", "fillMode"], outputs: ["valueChange", "valueUpdate", "focus", "blur"], exportAs: ["kendo-dateinput"] }, { type: i7.IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass"], exportAs: ["kendoIconWrapper"] }, { type: i8.ResizeSensorComponent, selector: "kendo-resize-sensor", inputs: ["rateLimit"], outputs: ["resize"] }, { type: i9.ActionSheetComponent, selector: "kendo-actionsheet", inputs: ["title", "subtitle", "items", "cssClass", "animation", "expanded"], outputs: ["expandedChange", "expand", "collapse", "itemClick", "overlayClick"], exportAs: ["kendoActionSheet"] }, { type: i10.Button, selector: "button[kendoButton], span[kendoButton], kendo-button", inputs: ["toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "role", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { type: i11.TimeSelectorComponent, selector: "kendo-timeselector", inputs: ["format", "min", "max", "cancelButton", "setButton", "nowButton", "disabled", "isAdaptiveEnabled", "isDateTimePicker", "steps", "value"], outputs: ["valueChange", "valueReject", "tabOutLastPart"], exportAs: ["kendo-timeselector"] }, { type: i12.TimeSelectorCustomMessagesComponent, selector: "kendo-timeselector-messages" }], directives: [{ type: i13.TimePickerLocalizedMessagesDirective, selector: "[kendoTimePickerLocalizedMessages]" }, { type: i8.EventsOutsideAngularDirective, selector: "[kendoEventsOutsideAngular]", inputs: ["kendoEventsOutsideAngular", "scope"] }, { type: i14.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i14.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i9.ActionSheetTemplateDirective, selector: "[kendoActionSheetTemplate]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1126
1138
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: TimePickerComponent, decorators: [{
1127
1139
  type: Component,
1128
1140
  args: [{
@@ -1304,6 +1316,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImpo
1304
1316
  [scope]="this"
1305
1317
  (valueChange)="handleChange($event)"
1306
1318
  (valueReject)="handleReject()"
1319
+ (tabOutLastPart)="onTabOutLastPart()"
1307
1320
  >
1308
1321
  <kendo-timeselector-messages
1309
1322
  [acceptLabel]="localization.get('acceptLabel')"
@@ -12,6 +12,7 @@ import { TimeListComponent } from './timelist.component';
12
12
  import { TimePickerDOMService } from './services/dom.service';
13
13
  import { getNow, hasChange, isInTimeRange, timeInRange } from '../util';
14
14
  import { generateGetters, generateSnappers, snapTime, valueMerger } from './util';
15
+ import { fromEvent } from 'rxjs';
15
16
  import { PickerService } from '../common/picker.service';
16
17
  import { closest } from '../common/dom-queries';
17
18
  import { currentFocusTarget, isPresent } from '../common/utils';
@@ -95,6 +96,7 @@ export class TimeSelectorComponent {
95
96
  * Fires each time the user cancels the selected value.
96
97
  */
97
98
  this.valueReject = new EventEmitter();
99
+ this.tabOutLastPart = new EventEmitter();
98
100
  this.isActive = false;
99
101
  this.showNowButton = true;
100
102
  this._activeListIndex = -1;
@@ -184,6 +186,22 @@ export class TimeSelectorComponent {
184
186
  this.init();
185
187
  this.bindEvents();
186
188
  }
189
+ ngAfterViewInit() {
190
+ this.subscriptions.add(fromEvent(this.timeListWrappers.first.nativeElement, 'keydown').subscribe((event) => {
191
+ const { keyCode, shiftKey } = event;
192
+ if (keyCode === Keys.Tab && shiftKey) {
193
+ event.preventDefault();
194
+ this.renderer.removeClass(this.timeListWrappers.first.nativeElement, 'k-focus');
195
+ this.accept.nativeElement.focus();
196
+ }
197
+ }));
198
+ this.subscriptions.add(fromEvent(this.timeListWrappers.last.nativeElement, 'keydown').subscribe((event) => {
199
+ const { keyCode, shiftKey } = event;
200
+ if (keyCode === Keys.Tab && !shiftKey) {
201
+ this.renderer.removeClass(this.timeListWrappers.last.nativeElement, 'k-focus');
202
+ }
203
+ }));
204
+ }
187
205
  /**
188
206
  * @hidden
189
207
  */
@@ -288,6 +306,16 @@ export class TimeSelectorComponent {
288
306
  containsElement(element) {
289
307
  return Boolean(closest(element, node => node === this.element.nativeElement));
290
308
  }
309
+ /**
310
+ * @hidden
311
+ */
312
+ handleTabOut(event) {
313
+ const { keyCode, shiftKey } = event;
314
+ if (keyCode === Keys.Tab && !shiftKey) {
315
+ event.preventDefault();
316
+ this.timeLists.first.focus();
317
+ }
318
+ }
291
319
  partStep(part) {
292
320
  return this.steps[part.type] || 1;
293
321
  }
@@ -375,7 +403,7 @@ export class TimeSelectorComponent {
375
403
  }
376
404
  }
377
405
  TimeSelectorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: TimeSelectorComponent, deps: [{ token: i1.LocalizationService }, { token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: i2.IntlService }, { token: i3.TimePickerDOMService }, { token: i0.NgZone }, { token: i0.Renderer2 }, { token: i4.PickerService, optional: true }], target: i0.ɵɵFactoryTarget.Component });
378
- TimeSelectorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.12", type: TimeSelectorComponent, selector: "kendo-timeselector", inputs: { format: "format", min: "min", max: "max", cancelButton: "cancelButton", setButton: "setButton", nowButton: "nowButton", disabled: "disabled", isAdaptiveEnabled: "isAdaptiveEnabled", isDateTimePicker: "isDateTimePicker", steps: "steps", value: "value" }, outputs: { valueChange: "valueChange", valueReject: "valueReject" }, host: { properties: { "class.k-disabled": "this.disabledClass" } }, providers: [
406
+ TimeSelectorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.12", type: TimeSelectorComponent, selector: "kendo-timeselector", inputs: { format: "format", min: "min", max: "max", cancelButton: "cancelButton", setButton: "setButton", nowButton: "nowButton", disabled: "disabled", isAdaptiveEnabled: "isAdaptiveEnabled", isDateTimePicker: "isDateTimePicker", steps: "steps", value: "value" }, outputs: { valueChange: "valueChange", valueReject: "valueReject", tabOutLastPart: "tabOutLastPart" }, host: { properties: { "class.k-disabled": "this.disabledClass" } }, providers: [
379
407
  LocalizationService,
380
408
  {
381
409
  provide: L10N_PREFIX,
@@ -433,12 +461,14 @@ TimeSelectorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0",
433
461
  >
434
462
  <span class="k-title k-timeselector-title">{{intl.dateFieldName(part)}}</span>
435
463
  <kendo-timelist
464
+ [isLast]="idx === dateFormatParts.length - 1"
436
465
  [min]="min"
437
466
  [max]="max"
438
467
  [part]="part"
439
468
  [step]="partStep(part)"
440
469
  [disabled]="disabled"
441
470
  [(value)]="current"
471
+ (tabOutLastPart)="tabOutLastPart.emit()"
442
472
  [kendoEventsOutsideAngular]="{
443
473
  focus: handleListFocus,
444
474
  blur: handleBlur
@@ -478,13 +508,14 @@ TimeSelectorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0",
478
508
  [kendoEventsOutsideAngular]="{
479
509
  click: handleAccept,
480
510
  focus: handleFocus,
481
- blur: handleBlur
511
+ blur: handleBlur,
512
+ keydown: handleTabOut
482
513
  }"
483
514
  [scope]="this"
484
515
  [disabled]="disabled"
485
516
  >{{localization.get('accept')}}</button>
486
517
  </div>
487
- `, isInline: true, components: [{ type: i5.TimeListComponent, selector: "kendo-timelist", inputs: ["min", "max", "part", "step", "disabled", "value"], outputs: ["valueChange"] }], directives: [{ type: i6.TimeSelectorLocalizedMessagesDirective, selector: "[kendoTimeSelectorLocalizedMessages]" }, { type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i8.EventsOutsideAngularDirective, selector: "[kendoEventsOutsideAngular]", inputs: ["kendoEventsOutsideAngular", "scope"] }, { type: i7.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
518
+ `, isInline: true, components: [{ type: i5.TimeListComponent, selector: "kendo-timelist", inputs: ["min", "max", "part", "step", "disabled", "value", "isLast"], outputs: ["valueChange", "tabOutLastPart"] }], directives: [{ type: i6.TimeSelectorLocalizedMessagesDirective, selector: "[kendoTimeSelectorLocalizedMessages]" }, { type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i8.EventsOutsideAngularDirective, selector: "[kendoEventsOutsideAngular]", inputs: ["kendoEventsOutsideAngular", "scope"] }, { type: i7.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
488
519
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: TimeSelectorComponent, decorators: [{
489
520
  type: Component,
490
521
  args: [{
@@ -550,12 +581,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImpo
550
581
  >
551
582
  <span class="k-title k-timeselector-title">{{intl.dateFieldName(part)}}</span>
552
583
  <kendo-timelist
584
+ [isLast]="idx === dateFormatParts.length - 1"
553
585
  [min]="min"
554
586
  [max]="max"
555
587
  [part]="part"
556
588
  [step]="partStep(part)"
557
589
  [disabled]="disabled"
558
590
  [(value)]="current"
591
+ (tabOutLastPart)="tabOutLastPart.emit()"
559
592
  [kendoEventsOutsideAngular]="{
560
593
  focus: handleListFocus,
561
594
  blur: handleBlur
@@ -595,7 +628,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImpo
595
628
  [kendoEventsOutsideAngular]="{
596
629
  click: handleAccept,
597
630
  focus: handleFocus,
598
- blur: handleBlur
631
+ blur: handleBlur,
632
+ keydown: handleTabOut
599
633
  }"
600
634
  [scope]="this"
601
635
  [disabled]="disabled"
@@ -649,4 +683,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImpo
649
683
  type: Output
650
684
  }], valueReject: [{
651
685
  type: Output
686
+ }], tabOutLastPart: [{
687
+ type: Output
652
688
  }] } });