@progress/kendo-angular-sortable 11.2.0-develop.9 → 11.2.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.
@@ -161,9 +161,9 @@ export class SortableBindingDirective {
161
161
  }
162
162
  }
163
163
  }
164
- SortableBindingDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: SortableBindingDirective, deps: [{ token: i1.SortableComponent }, { token: i2.SortableService }], target: i0.ɵɵFactoryTarget.Directive });
165
- SortableBindingDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.11", type: SortableBindingDirective, selector: "[kendoSortableBinding]", inputs: { data: ["kendoSortableBinding", "data"] }, ngImport: i0 });
166
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: SortableBindingDirective, decorators: [{
164
+ SortableBindingDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: SortableBindingDirective, deps: [{ token: i1.SortableComponent }, { token: i2.SortableService }], target: i0.ɵɵFactoryTarget.Directive });
165
+ SortableBindingDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: SortableBindingDirective, selector: "[kendoSortableBinding]", inputs: { data: ["kendoSortableBinding", "data"] }, ngImport: i0 });
166
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: SortableBindingDirective, decorators: [{
167
167
  type: Directive,
168
168
  args: [{
169
169
  selector: '[kendoSortableBinding]'
@@ -50,9 +50,9 @@ export class DraggableDirective {
50
50
  this.renderer.setStyle(this.el.nativeElement, 'display', this.display);
51
51
  }
52
52
  }
53
- DraggableDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: DraggableDirective, deps: [{ token: i1.SortableContainer }, { token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive });
54
- DraggableDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.11", type: DraggableDirective, selector: "[kendoDraggable]", inputs: { index: "index", disabled: "disabled", hidden: "hidden" }, host: { properties: { "class.k-focus": "this._focused", "attr.aria-disabled": "this._disabled" } }, ngImport: i0 });
55
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: DraggableDirective, decorators: [{
53
+ DraggableDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: DraggableDirective, deps: [{ token: i1.SortableContainer }, { token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive });
54
+ DraggableDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: DraggableDirective, selector: "[kendoDraggable]", inputs: { index: "index", disabled: "disabled", hidden: "hidden" }, host: { properties: { "class.k-focus": "this._focused", "attr.aria-disabled": "this._disabled" } }, ngImport: i0 });
55
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: DraggableDirective, decorators: [{
56
56
  type: Directive,
57
57
  args: [{
58
58
  selector: '[kendoDraggable]'
@@ -13,9 +13,9 @@ export class ItemTemplateDirective {
13
13
  this.templateRef = templateRef;
14
14
  }
15
15
  }
16
- ItemTemplateDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: ItemTemplateDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
17
- ItemTemplateDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.11", type: ItemTemplateDirective, selector: "[kendoSortableItemTemplate]", ngImport: i0 });
18
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: ItemTemplateDirective, decorators: [{
16
+ ItemTemplateDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ItemTemplateDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
17
+ ItemTemplateDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: ItemTemplateDirective, selector: "[kendoSortableItemTemplate]", ngImport: i0 });
18
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: ItemTemplateDirective, decorators: [{
19
19
  type: Directive,
20
20
  args: [{
21
21
  selector: '[kendoSortableItemTemplate]'
@@ -29,9 +29,9 @@ export class PlaceholderTemplateDirective {
29
29
  this.templateRef = templateRef;
30
30
  }
31
31
  }
32
- PlaceholderTemplateDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: PlaceholderTemplateDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
33
- PlaceholderTemplateDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.11", type: PlaceholderTemplateDirective, selector: "[kendoSortablePlaceholderTemplate]", ngImport: i0 });
34
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: PlaceholderTemplateDirective, decorators: [{
32
+ PlaceholderTemplateDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: PlaceholderTemplateDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
33
+ PlaceholderTemplateDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: PlaceholderTemplateDirective, selector: "[kendoSortablePlaceholderTemplate]", ngImport: i0 });
34
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: PlaceholderTemplateDirective, decorators: [{
35
35
  type: Directive,
36
36
  args: [{
37
37
  selector: '[kendoSortablePlaceholderTemplate]'
@@ -9,7 +9,7 @@ export const packageMetadata = {
9
9
  name: '@progress/kendo-angular-sortable',
10
10
  productName: 'Kendo UI for Angular',
11
11
  productCodes: ['KENDOUIANGULAR', 'KENDOUICOMPLETE'],
12
- publishDate: 1675778125,
13
- version: '11.2.0-develop.9',
12
+ publishDate: 1676453551,
13
+ version: '11.2.0',
14
14
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/'
15
15
  };
@@ -9,8 +9,8 @@ import * as i0 from "@angular/core";
9
9
  */
10
10
  export class SortableContainer {
11
11
  }
12
- SortableContainer.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: SortableContainer, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
13
- SortableContainer.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: SortableContainer });
14
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: SortableContainer, decorators: [{
12
+ SortableContainer.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: SortableContainer, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
13
+ SortableContainer.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: SortableContainer });
14
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: SortableContainer, decorators: [{
15
15
  type: Injectable
16
16
  }] });
@@ -2,10 +2,11 @@
2
2
  * Copyright © 2023 Progress Software Corporation. All rights reserved.
3
3
  * Licensed under commercial license. See LICENSE.md in the project root for more information
4
4
  *-------------------------------------------------------------------------------------------*/
5
- import { Component, Input, Output, QueryList, ContentChildren, ViewChild, ViewChildren, TemplateRef, ElementRef, EventEmitter, HostBinding, NgZone, ChangeDetectorRef, forwardRef } from '@angular/core';
5
+ /* eslint-disable @typescript-eslint/no-explicit-any */
6
+ import { Component, Input, Output, QueryList, ContentChildren, ViewChild, ViewChildren, TemplateRef, ElementRef, EventEmitter, HostBinding, NgZone, ChangeDetectorRef, forwardRef, Renderer2 } from '@angular/core';
6
7
  import { Subject, merge } from 'rxjs';
7
- import { isDocumentAvailable, isChanged } from '@progress/kendo-angular-common';
8
- import { relativeContextElement } from './util';
8
+ import { isDocumentAvailable, isChanged, Keys } from '@progress/kendo-angular-common';
9
+ import { getAllFocusableChildren, keepFocusWithinComponent, relativeContextElement } from './util';
9
10
  import { filter, take } from 'rxjs/operators';
10
11
  import { LocalizationService, L10N_PREFIX } from '@progress/kendo-angular-l10n';
11
12
  import { validatePackage } from '@progress/kendo-licensing';
@@ -23,6 +24,7 @@ import * as i1 from "@progress/kendo-angular-l10n";
23
24
  import * as i2 from "./sortable.service";
24
25
  import * as i3 from "@angular/common";
25
26
  import * as i4 from "./draggable.directive";
27
+ const KEY_SHORTCUTS = 'Control+ArrowLeft Control+ArrowRight Meta+ArrowLeft Meta+ArrowRight';
26
28
  /**
27
29
  * Represents the [Kendo UI Sortable component for Angular]({% slug overview_sortable %}).
28
30
  *
@@ -36,10 +38,11 @@ import * as i4 from "./draggable.directive";
36
38
  * Represents the Kendo UI Sortable component for Angular.
37
39
  */
38
40
  export class SortableComponent {
39
- constructor(ngZone, localization, changeDetector, wrapper, sortableService) {
41
+ constructor(ngZone, renderer, changeDetector, localization, wrapper, sortableService) {
40
42
  this.ngZone = ngZone;
41
- this.localization = localization;
43
+ this.renderer = renderer;
42
44
  this.changeDetector = changeDetector;
45
+ this.localization = localization;
43
46
  /**
44
47
  * Specifies the tab index of the Sortable component.
45
48
  */
@@ -165,7 +168,7 @@ export class SortableComponent {
165
168
  * @hidden
166
169
  */
167
170
  this.placeholderTemplateDirectiveRef = null;
168
- this.itemWrappers = null;
171
+ this.itemWrappers = new QueryList();
169
172
  /**
170
173
  * Fires when the dragging of an item is started.
171
174
  */
@@ -203,6 +206,7 @@ export class SortableComponent {
203
206
  * If no item is focused, set to `-1`.
204
207
  */
205
208
  this.activeIndex = -1;
209
+ this.hostRole = 'list';
206
210
  /**
207
211
  * Flag indicating if the component is currently playing animations.
208
212
  * @hidden
@@ -225,10 +229,16 @@ export class SortableComponent {
225
229
  */
226
230
  this.hintLocation = null;
227
231
  this._localData = [];
232
+ /**
233
+ * @hidden
234
+ */
235
+ this.ariaKeyShortcuts = KEY_SHORTCUTS;
236
+ this.focusableItems = [];
228
237
  this.animationDuration = 300;
229
238
  this.afterKeyPress = false;
230
239
  this.sortableService = null;
231
240
  this._hideActiveItem = false;
241
+ this.prevActiveIndex = 0;
232
242
  validatePackage(packageMetadata);
233
243
  this.wrapper = wrapper.nativeElement;
234
244
  this.direction = localization.rtl ? 'rtl' : 'ltr';
@@ -309,6 +319,18 @@ export class SortableComponent {
309
319
  });
310
320
  }
311
321
  }
322
+ ngAfterViewInit() {
323
+ if (this.navigable) {
324
+ this.setInitialItemTabindex();
325
+ this.setFocusableChildren();
326
+ }
327
+ this.childrenTabindexSubscription = this.itemWrappers.changes.subscribe(() => {
328
+ if (this.navigable) {
329
+ this.setInitialItemTabindex();
330
+ this.setFocusableChildren();
331
+ }
332
+ });
333
+ }
312
334
  ngOnChanges(changes) {
313
335
  if (this.data && isChanged('disabledIndexes', changes, false)) {
314
336
  this.cacheData();
@@ -326,16 +348,35 @@ export class SortableComponent {
326
348
  this.placeholderTemplateRef = this.placeholderTemplateDirectiveRef.first || this.defaultTemplateRef.first;
327
349
  }
328
350
  ngAfterViewChecked() {
329
- if (this.afterKeyPress) {
330
- if (this.itemWrappers) {
351
+ if (this.navigable) {
352
+ if (this.afterKeyPress) {
331
353
  const elems = this.itemWrappers.toArray();
332
354
  if (elems && elems.length > 0 && this.activeIndex > -1) {
333
- elems[this.activeIndex].nativeElement.focus();
355
+ const currentItem = elems[this.activeIndex].nativeElement;
356
+ const prevItem = elems[this.prevActiveIndex].nativeElement;
357
+ this.renderer.setAttribute(prevItem, 'tabindex', '-1');
358
+ this.renderer.setAttribute(currentItem, 'tabindex', '0');
359
+ currentItem.focus();
334
360
  }
335
361
  }
336
362
  this.afterKeyPress = false;
337
363
  }
338
364
  }
365
+ /**
366
+ * @hidden
367
+ */
368
+ setFocusableChildren() {
369
+ this.itemWrappers.toArray().forEach((item) => {
370
+ const itemEl = item.nativeElement;
371
+ const focusableChildren = getAllFocusableChildren(itemEl);
372
+ if (focusableChildren.length > 0) {
373
+ this.focusableItems.push(focusableChildren);
374
+ focusableChildren.forEach(focusableChild => {
375
+ this.renderer.setAttribute(focusableChild, 'tabindex', '-1');
376
+ });
377
+ }
378
+ });
379
+ }
339
380
  /**
340
381
  * @hidden
341
382
  */
@@ -365,6 +406,21 @@ export class SortableComponent {
365
406
  }
366
407
  return prevented;
367
408
  }
409
+ /**
410
+ * @hidden
411
+ */
412
+ setInitialItemTabindex() {
413
+ this.itemWrappers.toArray().forEach((item, index) => {
414
+ if (this.itemEnabled(index)) {
415
+ const isFirstItem = index === 0 ? 0 : -1;
416
+ const tabIndexValue = `${this.navigable ? this.tabIndex || isFirstItem : this.tabIndex}`;
417
+ const hasItemTabindex = item.nativeElement.getAttribute('tabindex');
418
+ if (!hasItemTabindex) {
419
+ this.renderer.setAttribute(item.nativeElement, 'tabindex', tabIndexValue);
420
+ }
421
+ }
422
+ });
423
+ }
368
424
  /**
369
425
  * @hidden
370
426
  */
@@ -480,44 +536,85 @@ export class SortableComponent {
480
536
  */
481
537
  blurHandler() {
482
538
  if (this.navigable && !this.afterKeyPress) {
539
+ this.prevActiveIndex = this.activeIndex;
483
540
  this.activeIndex = -1;
484
541
  }
485
542
  }
486
543
  /**
487
544
  * @hidden
488
545
  */
489
- keydownHandler(event) {
490
- const code = event.keyCode;
491
- const navigate = this.navigable && code >= 37 && code <= 40;
492
- const hasFocus = this.activeIndex !== -1;
493
- if (!navigate || !hasFocus) {
494
- return;
495
- }
496
- const leftKey = this.direction === 'rtl' ? 39 : 37;
497
- const dir = code === 38 || code === leftKey ? -1 : 1;
546
+ onArrowHandler(event, keyCode) {
547
+ const leftKey = this.direction === 'rtl' ? Keys.ArrowRight : Keys.ArrowLeft;
548
+ const dir = keyCode === Keys.ArrowUp || keyCode === leftKey ? -1 : 1;
498
549
  const limit = this.data.length - 1;
499
550
  let targetIndex = this.activeIndex + dir;
500
551
  while (!this.itemEnabled(targetIndex) && targetIndex <= limit) {
501
552
  targetIndex += dir;
502
553
  }
503
554
  targetIndex = Math.min(Math.max(targetIndex, 0), limit);
555
+ this.prevActiveIndex = this.activeIndex;
504
556
  if (!this.itemEnabled(targetIndex)) {
505
557
  return;
506
558
  }
507
- if (navigate) {
508
- const ctrl = event.ctrlKey || event.metaKey;
509
- const navigateEvent = new NavigateEvent({ index: targetIndex, oldIndex: this.activeIndex, ctrlKey: ctrl });
510
- this.navigate.emit(navigateEvent);
511
- if (!navigateEvent.isDefaultPrevented()) {
512
- this.activeIndex = targetIndex;
513
- }
514
- this.dragIndex = -1;
515
- this.dragOverIndex = -1;
559
+ const ctrl = event.ctrlKey || event.metaKey;
560
+ const navigateEvent = new NavigateEvent({ index: targetIndex, oldIndex: this.activeIndex, ctrlKey: ctrl });
561
+ this.navigate.emit(navigateEvent);
562
+ if (!navigateEvent.isDefaultPrevented()) {
563
+ this.activeIndex = targetIndex;
516
564
  }
565
+ this.dragIndex = -1;
566
+ this.dragOverIndex = -1;
517
567
  event.stopPropagation();
518
568
  event.preventDefault();
519
569
  this.afterKeyPress = true;
520
570
  }
571
+ /**
572
+ * @hidden
573
+ */
574
+ onEnterHandler(item) {
575
+ const focusableItems = this.focusableItems[this.activeIndex];
576
+ focusableItems.forEach(focusableItem => {
577
+ this.renderer.setAttribute(focusableItem, 'tabindex', '0');
578
+ });
579
+ this.renderer.setAttribute(item, 'tabindex', '-1');
580
+ focusableItems[0].focus();
581
+ }
582
+ /**
583
+ * @hidden
584
+ */
585
+ onEscapeHandler() {
586
+ const focusableItems = this.focusableItems[this.prevActiveIndex];
587
+ const item = this.itemWrappers.toArray()[this.prevActiveIndex].nativeElement;
588
+ focusableItems.forEach(focusableItem => {
589
+ this.renderer.setAttribute(focusableItem, 'tabindex', '-1');
590
+ });
591
+ this.renderer.setAttribute(item, 'tabindex', '0');
592
+ item.focus();
593
+ }
594
+ /**
595
+ * @hidden
596
+ */
597
+ keydownHandler(event) {
598
+ const index = this.activeIndex === -1 ? this.prevActiveIndex : this.activeIndex;
599
+ const item = this.itemWrappers.toArray()[index].nativeElement;
600
+ const isItemFocused = document.activeElement === item;
601
+ const hasFocus = this.activeIndex !== -1;
602
+ const keyCode = event.keyCode;
603
+ if (this.navigable && hasFocus) {
604
+ if (keyCode >= Keys.ArrowLeft && keyCode <= Keys.ArrowDown) {
605
+ this.onArrowHandler(event, keyCode);
606
+ }
607
+ if (keyCode === Keys.Enter && isItemFocused && this.focusableItems.length > 0) {
608
+ this.onEnterHandler(item);
609
+ }
610
+ }
611
+ if (keyCode === Keys.Tab && !isItemFocused) {
612
+ keepFocusWithinComponent(event, item);
613
+ }
614
+ if (keyCode === Keys.Escape && this.focusableItems.length > 0 && this.activeIndex === -1) {
615
+ this.onEscapeHandler();
616
+ }
617
+ }
521
618
  /**
522
619
  * Removes the currently active item from the Data collection that the Sortable uses.
523
620
  */
@@ -635,6 +732,9 @@ export class SortableComponent {
635
732
  this.dragIndex = dragIndex;
636
733
  this.dragOverIndex = dragIndex;
637
734
  this.activeIndex = dragIndex;
735
+ if (this.focusableItems.length > 0) {
736
+ this.swapFocusableChildren(fromIndex, toIndex);
737
+ }
638
738
  if (this.animation) {
639
739
  setTimeout(() => {
640
740
  toAnimate.push({ next: originalIndexAnimate, prev: dragIndex });
@@ -719,6 +819,12 @@ export class SortableComponent {
719
819
  reflow(element) {
720
820
  return element.offsetWidth;
721
821
  }
822
+ /**
823
+ * @hidden
824
+ */
825
+ swapFocusableChildren(firstItemIndex, secondItemIndex) {
826
+ [this.focusableItems[firstItemIndex], this.focusableItems[secondItemIndex]] = [this.focusableItems[secondItemIndex], this.focusableItems[firstItemIndex]];
827
+ }
722
828
  /**
723
829
  * @hidden
724
830
  */
@@ -833,6 +939,9 @@ export class SortableComponent {
833
939
  if (this.localizationChangeSubscription) {
834
940
  this.localizationChangeSubscription.unsubscribe();
835
941
  }
942
+ if (this.childrenTabindexSubscription) {
943
+ this.childrenTabindexSubscription.unsubscribe();
944
+ }
836
945
  this.dragStartSubscription.unsubscribe();
837
946
  this.dragOverSubscription.unsubscribe();
838
947
  this.dragEndSubscription.unsubscribe();
@@ -872,8 +981,8 @@ export class SortableComponent {
872
981
  }
873
982
  }
874
983
  }
875
- SortableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: SortableComponent, deps: [{ token: i0.NgZone }, { token: i1.LocalizationService }, { token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: i2.SortableService }], target: i0.ɵɵFactoryTarget.Component });
876
- SortableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: SortableComponent, selector: "kendo-sortable", inputs: { tabIndex: "tabIndex", data: "data", navigable: "navigable", navigatable: "navigatable", animation: "animation", disabledIndexes: "disabledIndexes", zone: "zone", acceptZones: "acceptZones", itemStyle: "itemStyle", emptyItemStyle: "emptyItemStyle", activeItemStyle: "activeItemStyle", disabledItemStyle: "disabledItemStyle", itemClass: "itemClass", activeItemClass: "activeItemClass", emptyItemClass: "emptyItemClass", disabledItemClass: "disabledItemClass", emptyText: "emptyText", activeIndex: "activeIndex" }, outputs: { dragStart: "dragStart", dragEnd: "dragEnd", dragOver: "dragOver", dragLeave: "dragLeave", dataMove: "dataMove", dataAdd: "dataAdd", dataRemove: "dataRemove", navigate: "navigate" }, host: { properties: { "style.touch-action": "this.touchAction", "attr.dir": "this.dir" } }, providers: [
984
+ SortableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: SortableComponent, deps: [{ token: i0.NgZone }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }, { token: i1.LocalizationService }, { token: i0.ElementRef }, { token: i2.SortableService }], target: i0.ɵɵFactoryTarget.Component });
985
+ SortableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.12", type: SortableComponent, selector: "kendo-sortable", inputs: { tabIndex: "tabIndex", data: "data", navigable: "navigable", navigatable: "navigatable", animation: "animation", disabledIndexes: "disabledIndexes", zone: "zone", acceptZones: "acceptZones", itemStyle: "itemStyle", emptyItemStyle: "emptyItemStyle", activeItemStyle: "activeItemStyle", disabledItemStyle: "disabledItemStyle", itemClass: "itemClass", activeItemClass: "activeItemClass", emptyItemClass: "emptyItemClass", disabledItemClass: "disabledItemClass", emptyText: "emptyText", activeIndex: "activeIndex" }, outputs: { dragStart: "dragStart", dragEnd: "dragEnd", dragOver: "dragOver", dragLeave: "dragLeave", dataMove: "dataMove", dataAdd: "dataAdd", dataRemove: "dataRemove", navigate: "navigate" }, host: { properties: { "style.touch-action": "this.touchAction", "attr.dir": "this.dir", "attr.role": "this.hostRole" } }, providers: [
877
986
  LocalizationService,
878
987
  {
879
988
  provide: L10N_PREFIX,
@@ -886,8 +995,10 @@ SortableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", vers
886
995
  ], queries: [{ propertyName: "defaultTemplateRef", predicate: TemplateRef }, { propertyName: "itemTemplateDirectiveRef", predicate: ItemTemplateDirective, read: TemplateRef }, { propertyName: "placeholderTemplateDirectiveRef", predicate: PlaceholderTemplateDirective, read: TemplateRef }], viewQueries: [{ propertyName: "noDataContainer", first: true, predicate: ["noDataRef"], descendants: true }, { propertyName: "hint", first: true, predicate: ["hint"], descendants: true }, { propertyName: "itemWrappers", predicate: ["itemWrapper"], descendants: true }, { propertyName: "draggables", predicate: DraggableDirective, descendants: true }], exportAs: ["kendoSortable"], usesOnChanges: true, ngImport: i0, template: `
887
996
  <div #itemWrapper *ngFor="let item of _localData;let i=index"
888
997
  kendoDraggable
889
- [attr.tabIndex]="itemEnabled(i)?(navigable?tabIndex||0:tabIndex):null"
998
+ role="listitem"
890
999
  [attr.aria-grabbed]="i===dragIndex"
1000
+ [attr.aria-disabled]="!itemEnabled(i)"
1001
+ [attr.aria-keyshortcuts]="navigable ? ariaKeyShortcuts : ''"
891
1002
  [attr.aria-dropeffect]="ariaDropEffect(i)"
892
1003
  [attr.data-sortable-item] = "true"
893
1004
  [attr.data-sortable-index]="i"
@@ -902,11 +1013,11 @@ SortableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", vers
902
1013
  (blur)="blurHandler()"
903
1014
  (keydown)="keydownHandler($event)"
904
1015
  >
905
- <ng-container *ngIf="itemTemplateRef"
1016
+ <ng-container *ngIf="itemTemplateRef"
906
1017
  [ngTemplateOutlet]="itemTemplate(i)"
907
1018
  [ngTemplateOutletContext]="item">
908
- </ng-container>
909
- <ng-container *ngIf="!itemTemplateRef">{{item.item}}</ng-container>
1019
+ </ng-container>
1020
+ <ng-container *ngIf="!itemTemplateRef">{{item.item}}</ng-container>
910
1021
  </div>
911
1022
 
912
1023
  <ng-container #noDataRef *ngIf="!_data.length || _localData.length === 1 && _localData[0].hidden">
@@ -920,15 +1031,15 @@ SortableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", vers
920
1031
  [ngClass]="currentItemClass(-1)"
921
1032
  >{{emptyText}}</div>
922
1033
  </ng-container>
923
- <div *ngIf="hintVisible()" [ngStyle]="hintStyle()" [ngClass]="currentItemClass(dragIndex)">
924
- <ng-container *ngIf="itemTemplateRef"
925
- [ngTemplateOutlet]="itemTemplateRef"
926
- [ngTemplateOutletContext]="{item: _localData[dragIndex].item}">
927
- </ng-container>
928
- <ng-container *ngIf="!itemTemplateRef">{{_localData[dragIndex].item}}</ng-container>
929
- </div>
1034
+ <div *ngIf="hintVisible()" [ngStyle]="hintStyle()" [ngClass]="currentItemClass(dragIndex)">
1035
+ <ng-container *ngIf="itemTemplateRef"
1036
+ [ngTemplateOutlet]="itemTemplateRef"
1037
+ [ngTemplateOutletContext]="{item: _localData[dragIndex].item}">
1038
+ </ng-container>
1039
+ <ng-container *ngIf="!itemTemplateRef">{{_localData[dragIndex].item}}</ng-container>
1040
+ </div>
930
1041
  `, isInline: true, directives: [{ type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i4.DraggableDirective, selector: "[kendoDraggable]", inputs: ["index", "disabled", "hidden"] }, { type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }] });
931
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: SortableComponent, decorators: [{
1042
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: SortableComponent, decorators: [{
932
1043
  type: Component,
933
1044
  args: [{
934
1045
  exportAs: 'kendoSortable',
@@ -947,8 +1058,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImpo
947
1058
  template: `
948
1059
  <div #itemWrapper *ngFor="let item of _localData;let i=index"
949
1060
  kendoDraggable
950
- [attr.tabIndex]="itemEnabled(i)?(navigable?tabIndex||0:tabIndex):null"
1061
+ role="listitem"
951
1062
  [attr.aria-grabbed]="i===dragIndex"
1063
+ [attr.aria-disabled]="!itemEnabled(i)"
1064
+ [attr.aria-keyshortcuts]="navigable ? ariaKeyShortcuts : ''"
952
1065
  [attr.aria-dropeffect]="ariaDropEffect(i)"
953
1066
  [attr.data-sortable-item] = "true"
954
1067
  [attr.data-sortable-index]="i"
@@ -963,11 +1076,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImpo
963
1076
  (blur)="blurHandler()"
964
1077
  (keydown)="keydownHandler($event)"
965
1078
  >
966
- <ng-container *ngIf="itemTemplateRef"
1079
+ <ng-container *ngIf="itemTemplateRef"
967
1080
  [ngTemplateOutlet]="itemTemplate(i)"
968
1081
  [ngTemplateOutletContext]="item">
969
- </ng-container>
970
- <ng-container *ngIf="!itemTemplateRef">{{item.item}}</ng-container>
1082
+ </ng-container>
1083
+ <ng-container *ngIf="!itemTemplateRef">{{item.item}}</ng-container>
971
1084
  </div>
972
1085
 
973
1086
  <ng-container #noDataRef *ngIf="!_data.length || _localData.length === 1 && _localData[0].hidden">
@@ -981,16 +1094,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImpo
981
1094
  [ngClass]="currentItemClass(-1)"
982
1095
  >{{emptyText}}</div>
983
1096
  </ng-container>
984
- <div *ngIf="hintVisible()" [ngStyle]="hintStyle()" [ngClass]="currentItemClass(dragIndex)">
985
- <ng-container *ngIf="itemTemplateRef"
986
- [ngTemplateOutlet]="itemTemplateRef"
987
- [ngTemplateOutletContext]="{item: _localData[dragIndex].item}">
988
- </ng-container>
989
- <ng-container *ngIf="!itemTemplateRef">{{_localData[dragIndex].item}}</ng-container>
990
- </div>
1097
+ <div *ngIf="hintVisible()" [ngStyle]="hintStyle()" [ngClass]="currentItemClass(dragIndex)">
1098
+ <ng-container *ngIf="itemTemplateRef"
1099
+ [ngTemplateOutlet]="itemTemplateRef"
1100
+ [ngTemplateOutletContext]="{item: _localData[dragIndex].item}">
1101
+ </ng-container>
1102
+ <ng-container *ngIf="!itemTemplateRef">{{_localData[dragIndex].item}}</ng-container>
1103
+ </div>
991
1104
  `
992
1105
  }]
993
- }], ctorParameters: function () { return [{ type: i0.NgZone }, { type: i1.LocalizationService }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: i2.SortableService }]; }, propDecorators: { tabIndex: [{
1106
+ }], ctorParameters: function () { return [{ type: i0.NgZone }, { type: i0.Renderer2 }, { type: i0.ChangeDetectorRef }, { type: i1.LocalizationService }, { type: i0.ElementRef }, { type: i2.SortableService }]; }, propDecorators: { tabIndex: [{
994
1107
  type: Input
995
1108
  }], data: [{
996
1109
  type: Input
@@ -1041,10 +1154,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImpo
1041
1154
  args: [DraggableDirective]
1042
1155
  }], noDataContainer: [{
1043
1156
  type: ViewChild,
1044
- args: ['noDataRef', { static: false }]
1157
+ args: ['noDataRef']
1045
1158
  }], hint: [{
1046
1159
  type: ViewChild,
1047
- args: ['hint', { static: false }]
1160
+ args: ['hint']
1048
1161
  }], dragStart: [{
1049
1162
  type: Output
1050
1163
  }], dragEnd: [{
@@ -1069,4 +1182,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImpo
1069
1182
  }], dir: [{
1070
1183
  type: HostBinding,
1071
1184
  args: ['attr.dir']
1185
+ }], hostRole: [{
1186
+ type: HostBinding,
1187
+ args: ['attr.role']
1072
1188
  }] } });
@@ -50,8 +50,8 @@ const COMPONENT_DIRECTIVES = [
50
50
  */
51
51
  export class SortableModule {
52
52
  }
53
- SortableModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: SortableModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
54
- SortableModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: SortableModule, declarations: [SortableComponent,
53
+ SortableModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: SortableModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
54
+ SortableModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: SortableModule, declarations: [SortableComponent,
55
55
  DraggableDirective,
56
56
  PlaceholderTemplateDirective,
57
57
  ItemTemplateDirective,
@@ -60,8 +60,8 @@ SortableModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version:
60
60
  PlaceholderTemplateDirective,
61
61
  ItemTemplateDirective,
62
62
  SortableBindingDirective] });
63
- SortableModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: SortableModule, providers: [SortableService], imports: [[CommonModule]] });
64
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: SortableModule, decorators: [{
63
+ SortableModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: SortableModule, providers: [SortableService], imports: [[CommonModule]] });
64
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: SortableModule, decorators: [{
65
65
  type: NgModule,
66
66
  args: [{
67
67
  declarations: [COMPONENT_DIRECTIVES],
@@ -217,8 +217,8 @@ export class SortableService {
217
217
  });
218
218
  }
219
219
  }
220
- SortableService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: SortableService, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
221
- SortableService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: SortableService });
222
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: SortableService, decorators: [{
220
+ SortableService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: SortableService, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
221
+ SortableService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: SortableService });
222
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: SortableService, decorators: [{
223
223
  type: Injectable
224
224
  }], ctorParameters: function () { return [{ type: i0.NgZone }]; } });
package/esm2020/util.mjs CHANGED
@@ -2,7 +2,7 @@
2
2
  * Copyright © 2023 Progress Software Corporation. All rights reserved.
3
3
  * Licensed under commercial license. See LICENSE.md in the project root for more information
4
4
  *-------------------------------------------------------------------------------------------*/
5
- import { isDocumentAvailable } from '@progress/kendo-angular-common';
5
+ import { focusableSelector, isDocumentAvailable } from '@progress/kendo-angular-common';
6
6
  const NODE_NAME_PREDICATES = {};
7
7
  const NODE_ATTR_PREDICATES = {};
8
8
  const focusableRegex = /^(?:a|input|select|option|textarea|button|object)$/i;
@@ -74,6 +74,38 @@ export const draggableFromEvent = (event, sortable) => {
74
74
  // TODO: refactor sortable. Add draggable getter
75
75
  return sortable.draggables.toArray()[target ? target.index : -1];
76
76
  };
77
+ /**
78
+ * @hidden
79
+ */
80
+ export const getAllFocusableChildren = (parent) => {
81
+ return Array.from(parent.querySelectorAll(focusableSelector)).filter((element) => element.offsetParent !== null);
82
+ };
83
+ /**
84
+ * @hidden
85
+ */
86
+ export const getFirstAndLastFocusable = (parent) => {
87
+ const all = getAllFocusableChildren(parent);
88
+ const firstFocusable = all.length > 0 ? all[0] : parent;
89
+ const lastFocusable = all.length > 0 ? all[all.length - 1] : parent;
90
+ return [firstFocusable, lastFocusable];
91
+ };
92
+ /**
93
+ * @hidden
94
+ */
95
+ export const keepFocusWithinComponent = (event, wrapper) => {
96
+ const [firstFocusable, lastFocusable] = getFirstAndLastFocusable(wrapper);
97
+ const tabAfterLastFocusable = !event.shiftKey && event.target === lastFocusable;
98
+ const shiftTabAfterFirstFocusable = event.shiftKey && event.target === firstFocusable;
99
+ if (tabAfterLastFocusable) {
100
+ event.preventDefault();
101
+ firstFocusable.focus();
102
+ wrapper.blur();
103
+ }
104
+ if (shiftTabAfterFirstFocusable) {
105
+ event.preventDefault();
106
+ lastFocusable.focus();
107
+ }
108
+ };
77
109
  /**
78
110
  * @hidden
79
111
  */