@progress/kendo-angular-sortable 21.4.1 → 22.0.0-develop.1
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.
- package/fesm2022/progress-kendo-angular-sortable.mjs +28 -28
- package/package.json +9 -17
- package/esm2022/binding.directive.mjs +0 -189
- package/esm2022/data-event-args.interface.mjs +0 -5
- package/esm2022/data-events.mjs +0 -69
- package/esm2022/directives.mjs +0 -38
- package/esm2022/draggable-event.mjs +0 -26
- package/esm2022/draggable.directive.mjs +0 -79
- package/esm2022/index.mjs +0 -18
- package/esm2022/item-template.directive.mjs +0 -43
- package/esm2022/navigate-event.mjs +0 -29
- package/esm2022/package-metadata.mjs +0 -16
- package/esm2022/preventable-event.mjs +0 -30
- package/esm2022/progress-kendo-angular-sortable.mjs +0 -8
- package/esm2022/sortable-container.mjs +0 -16
- package/esm2022/sortable-event-args.interface.mjs +0 -5
- package/esm2022/sortable-events.mjs +0 -37
- package/esm2022/sortable.component.mjs +0 -1204
- package/esm2022/sortable.module.mjs +0 -44
- package/esm2022/sortable.service.mjs +0 -238
- package/esm2022/util.mjs +0 -176
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
/**-----------------------------------------------------------------------------------------
|
|
2
|
-
* Copyright © 2026 Progress Software Corporation. All rights reserved.
|
|
3
|
-
* Licensed under commercial license. See LICENSE.md in the project root for more information
|
|
4
|
-
*-------------------------------------------------------------------------------------------*/
|
|
5
|
-
import { NgModule } from '@angular/core';
|
|
6
|
-
import { SortableService } from "./sortable.service";
|
|
7
|
-
import { KENDO_SORTABLE } from './directives';
|
|
8
|
-
import * as i0 from "@angular/core";
|
|
9
|
-
import * as i1 from "./sortable.component";
|
|
10
|
-
import * as i2 from "./draggable.directive";
|
|
11
|
-
import * as i3 from "./item-template.directive";
|
|
12
|
-
import * as i4 from "./binding.directive";
|
|
13
|
-
//IMPORTANT: NgModule export kept for backwards compatibility
|
|
14
|
-
/**
|
|
15
|
-
* Represents the [`NgModule`](link:site.data.urls.angular['ngmoduleapi']) definition for the Sortable component.
|
|
16
|
-
*
|
|
17
|
-
* @example
|
|
18
|
-
* ```typescript
|
|
19
|
-
* import { NgModule } from '@angular/core';
|
|
20
|
-
* import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
|
21
|
-
* import { SortableModule } from '@progress/kendo-angular-sortable';
|
|
22
|
-
* import { AppComponent } from './app.component';
|
|
23
|
-
*
|
|
24
|
-
* @NgModule({
|
|
25
|
-
* declarations: [AppComponent],
|
|
26
|
-
* imports: [BrowserModule, SortableModule],
|
|
27
|
-
* bootstrap: [AppComponent]
|
|
28
|
-
* })
|
|
29
|
-
* export class AppModule {}
|
|
30
|
-
* ```
|
|
31
|
-
*/
|
|
32
|
-
export class SortableModule {
|
|
33
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SortableModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
34
|
-
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.14", ngImport: i0, type: SortableModule, imports: [i1.SortableComponent, i2.DraggableDirective, i3.PlaceholderTemplateDirective, i3.ItemTemplateDirective, i4.SortableBindingDirective], exports: [i1.SortableComponent, i2.DraggableDirective, i3.PlaceholderTemplateDirective, i3.ItemTemplateDirective, i4.SortableBindingDirective] });
|
|
35
|
-
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SortableModule, providers: [SortableService] });
|
|
36
|
-
}
|
|
37
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SortableModule, decorators: [{
|
|
38
|
-
type: NgModule,
|
|
39
|
-
args: [{
|
|
40
|
-
imports: [...KENDO_SORTABLE],
|
|
41
|
-
exports: [...KENDO_SORTABLE],
|
|
42
|
-
providers: [SortableService]
|
|
43
|
-
}]
|
|
44
|
-
}] });
|
|
@@ -1,238 +0,0 @@
|
|
|
1
|
-
/**-----------------------------------------------------------------------------------------
|
|
2
|
-
* Copyright © 2026 Progress Software Corporation. All rights reserved.
|
|
3
|
-
* Licensed under commercial license. See LICENSE.md in the project root for more information
|
|
4
|
-
*-------------------------------------------------------------------------------------------*/
|
|
5
|
-
import { Injectable, NgZone } from '@angular/core';
|
|
6
|
-
import { isDocumentAvailable } from '@progress/kendo-angular-common';
|
|
7
|
-
import { draggableFromEvent, isFocusable, MINIMAL_DRAG_DISTANCE, widgetTarget } from './util';
|
|
8
|
-
import { Subject } from 'rxjs';
|
|
9
|
-
import { switchMap, filter, take, tap } from 'rxjs/operators';
|
|
10
|
-
import * as i0 from "@angular/core";
|
|
11
|
-
const allowDrag = (e) => {
|
|
12
|
-
const target = e.originalEvent.target;
|
|
13
|
-
return target.hasAttribute('data-sortable-item') || !(isFocusable(target) || widgetTarget(target));
|
|
14
|
-
};
|
|
15
|
-
/**
|
|
16
|
-
* The `SortableService` is a service that manages the drag-and-drop functionality
|
|
17
|
-
* for transferring items between Sortable components.
|
|
18
|
-
*/
|
|
19
|
-
export class SortableService {
|
|
20
|
-
ngZone;
|
|
21
|
-
/**
|
|
22
|
-
* Specifies the Draggable item that is currently being moved.
|
|
23
|
-
*/
|
|
24
|
-
activeDraggable = null;
|
|
25
|
-
/**
|
|
26
|
-
* Specifies the Draggable item from which the dragging started.
|
|
27
|
-
*/
|
|
28
|
-
originDraggable = null;
|
|
29
|
-
/**
|
|
30
|
-
* @hidden
|
|
31
|
-
*/
|
|
32
|
-
originIndex;
|
|
33
|
-
/**
|
|
34
|
-
* @hidden
|
|
35
|
-
*/
|
|
36
|
-
targetSortable = null;
|
|
37
|
-
/**
|
|
38
|
-
* Specifies the Draggable item that last emitted an event.
|
|
39
|
-
*/
|
|
40
|
-
lastDraggable = null;
|
|
41
|
-
/**
|
|
42
|
-
* @hidden
|
|
43
|
-
*/
|
|
44
|
-
onPressSubject = new Subject();
|
|
45
|
-
/**
|
|
46
|
-
* @hidden
|
|
47
|
-
*/
|
|
48
|
-
onDragSubject = new Subject();
|
|
49
|
-
/**
|
|
50
|
-
* @hidden
|
|
51
|
-
*/
|
|
52
|
-
onReleaseSubject = new Subject();
|
|
53
|
-
subscriptions;
|
|
54
|
-
source = null;
|
|
55
|
-
_target = null;
|
|
56
|
-
sortableCounter = 0;
|
|
57
|
-
sortableRegister = {};
|
|
58
|
-
pressArgs;
|
|
59
|
-
/**
|
|
60
|
-
* Specifies the `SortableComponent` instance under the currently dragged item.
|
|
61
|
-
*/
|
|
62
|
-
set target(target) {
|
|
63
|
-
this._target = target;
|
|
64
|
-
}
|
|
65
|
-
get target() {
|
|
66
|
-
return this._target;
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* @hidden
|
|
70
|
-
*/
|
|
71
|
-
constructor(ngZone) {
|
|
72
|
-
this.ngZone = ngZone;
|
|
73
|
-
if (!isDocumentAvailable()) {
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
this.subscriptions = this.onPressSubject.pipe(filter(allowDrag), tap(press => {
|
|
77
|
-
this.targetSortable = this.getSortableComponentFromTouch(press);
|
|
78
|
-
}), filter(_ => Boolean(this.targetSortable)), tap(press => {
|
|
79
|
-
this.onReleaseSubject.pipe(take(1)).subscribe(event => this.release(event));
|
|
80
|
-
this.pressArgs = press;
|
|
81
|
-
if (press.isTouch) {
|
|
82
|
-
press.originalEvent.preventDefault();
|
|
83
|
-
}
|
|
84
|
-
}), switchMap(_drag => this.onDragSubject.pipe(filter(_ => Boolean(this.targetSortable)), //stop further events if dragStart is prevented
|
|
85
|
-
tap((e) => this.drag(e))))).subscribe();
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* @hidden
|
|
89
|
-
*/
|
|
90
|
-
onPress(e) {
|
|
91
|
-
this.onPressSubject.next(e);
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* @hidden
|
|
95
|
-
*/
|
|
96
|
-
onDrag(e) {
|
|
97
|
-
this.onDragSubject.next(e);
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* @hidden
|
|
101
|
-
*/
|
|
102
|
-
onRelease(e) {
|
|
103
|
-
this.onReleaseSubject.next(e);
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* @hidden
|
|
107
|
-
*/
|
|
108
|
-
ngOnDestroy() {
|
|
109
|
-
if (this.subscriptions) {
|
|
110
|
-
this.subscriptions.unsubscribe();
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* Registers a `SortableComponent` with the `SortableService` so that it can be managed by the service.
|
|
115
|
-
*
|
|
116
|
-
* @param sortableComponent - The `SortableComponent`.
|
|
117
|
-
* @return - The unique key that the current `SortableComponent` gets when registered.
|
|
118
|
-
*/
|
|
119
|
-
registerComponent(sortableComponent) {
|
|
120
|
-
const id = this.sortableCounter.toString();
|
|
121
|
-
this.sortableRegister[id] = sortableComponent;
|
|
122
|
-
this.sortableCounter++;
|
|
123
|
-
return id;
|
|
124
|
-
}
|
|
125
|
-
/**
|
|
126
|
-
* Removes a `SortableComponent` from the registered `SortableComponents` with which the service operates.
|
|
127
|
-
*
|
|
128
|
-
* @param key - The key of the `SortableComponent` which will be removed from the register.
|
|
129
|
-
* Obtained when `registerComponent` is called.
|
|
130
|
-
*/
|
|
131
|
-
unregisterComponent(key) {
|
|
132
|
-
this.sortableRegister[key] = null;
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
* Sets the `SortableComponent` as a source component. When dragging an item from one Sortable to another,
|
|
136
|
-
* the source component is the one from which the item originates.
|
|
137
|
-
*
|
|
138
|
-
* @param sortable - The `SortableComponent`.
|
|
139
|
-
*/
|
|
140
|
-
setSource(sortable) {
|
|
141
|
-
this.source = sortable;
|
|
142
|
-
}
|
|
143
|
-
/**
|
|
144
|
-
* Returns the source `SortableComponent` from which
|
|
145
|
-
* an item is dragged to other Sortable components.
|
|
146
|
-
*
|
|
147
|
-
* @return - The `SourceComponent`.
|
|
148
|
-
*/
|
|
149
|
-
getSource() {
|
|
150
|
-
return this.source;
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* The method that finds the `SortableComponent` which is registered to
|
|
154
|
-
* the `SortableService` by using the arguments of the `touch` event.
|
|
155
|
-
*
|
|
156
|
-
* @param touch - A Touch-Object of the `Touch` type interface.
|
|
157
|
-
* Represents a single contact point (finger or stylus)
|
|
158
|
-
* on a touch-sensitive device (touchscreen or trackpad).
|
|
159
|
-
*
|
|
160
|
-
* @return { component: SortableComponent, index: number } - An object where the component is the `SortableComponent` that owns the item and the index is the index of the touched item.
|
|
161
|
-
*/
|
|
162
|
-
getSortableComponentFromTouch(touch) {
|
|
163
|
-
if (!isDocumentAvailable()) {
|
|
164
|
-
return { component: undefined, index: undefined };
|
|
165
|
-
}
|
|
166
|
-
let realTarget = document.elementFromPoint(touch.clientX, touch.clientY);
|
|
167
|
-
while (realTarget) {
|
|
168
|
-
const id = realTarget.getAttribute('data-sortable-id');
|
|
169
|
-
const index = realTarget.getAttribute('data-sortable-index');
|
|
170
|
-
if (id) {
|
|
171
|
-
const targetSortable = this.sortableRegister[id];
|
|
172
|
-
if (targetSortable) {
|
|
173
|
-
return { component: targetSortable, index: parseInt(index, 10) };
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
realTarget = realTarget.parentElement;
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
start() {
|
|
180
|
-
const pressArgs = this.pressArgs;
|
|
181
|
-
if (pressArgs) {
|
|
182
|
-
this.pressArgs = null;
|
|
183
|
-
const startTarget = draggableFromEvent(pressArgs, this.targetSortable.component);
|
|
184
|
-
if (this.targetSortable.component.startDrag({ target: startTarget, originalEvent: pressArgs })) {
|
|
185
|
-
this.targetSortable = null;
|
|
186
|
-
return true;
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
release(event) {
|
|
191
|
-
if (this.source) {
|
|
192
|
-
this.ngZone.run(() => {
|
|
193
|
-
if (this.targetSortable) {
|
|
194
|
-
const dropTarget = draggableFromEvent(event, this.targetSortable.component);
|
|
195
|
-
this.source.endDrag({ target: dropTarget, originalEvent: event });
|
|
196
|
-
}
|
|
197
|
-
this.source.positionHintFromEvent(null);
|
|
198
|
-
this.source.markForCheck();
|
|
199
|
-
});
|
|
200
|
-
}
|
|
201
|
-
this.targetSortable = null;
|
|
202
|
-
this.pressArgs = null;
|
|
203
|
-
}
|
|
204
|
-
drag(event) {
|
|
205
|
-
const distance = this.pressArgs && Math.sqrt((event.pageX - this.pressArgs.pageX) ** 2 + (event.pageY - this.pressArgs.pageY) ** 2);
|
|
206
|
-
if (distance && distance < MINIMAL_DRAG_DISTANCE) {
|
|
207
|
-
return;
|
|
208
|
-
}
|
|
209
|
-
this.ngZone.run(() => {
|
|
210
|
-
if (this.start()) {
|
|
211
|
-
return;
|
|
212
|
-
}
|
|
213
|
-
this.source.positionHintFromEvent(event);
|
|
214
|
-
const sortable = this.getSortableComponentFromTouch(event);
|
|
215
|
-
if (!sortable || sortable && sortable.component !== this.target) {
|
|
216
|
-
if (this.target) {
|
|
217
|
-
this.target.leave({ target: undefined, originalEvent: event });
|
|
218
|
-
}
|
|
219
|
-
else if (this.source !== this.target) {
|
|
220
|
-
this.source.leave({ target: undefined, originalEvent: event });
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
if (sortable && sortable.component) {
|
|
224
|
-
const draggable = draggableFromEvent(event, sortable.component);
|
|
225
|
-
sortable.component.drag({ target: draggable, originalEvent: event });
|
|
226
|
-
}
|
|
227
|
-
this.source.markForCheck();
|
|
228
|
-
});
|
|
229
|
-
}
|
|
230
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SortableService, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
231
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SortableService, providedIn: 'root' });
|
|
232
|
-
}
|
|
233
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SortableService, decorators: [{
|
|
234
|
-
type: Injectable,
|
|
235
|
-
args: [{
|
|
236
|
-
providedIn: 'root'
|
|
237
|
-
}]
|
|
238
|
-
}], ctorParameters: () => [{ type: i0.NgZone }] });
|
package/esm2022/util.mjs
DELETED
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
/**-----------------------------------------------------------------------------------------
|
|
2
|
-
* Copyright © 2026 Progress Software Corporation. All rights reserved.
|
|
3
|
-
* Licensed under commercial license. See LICENSE.md in the project root for more information
|
|
4
|
-
*-------------------------------------------------------------------------------------------*/
|
|
5
|
-
import { focusableSelector, isDocumentAvailable } from '@progress/kendo-angular-common';
|
|
6
|
-
const NODE_NAME_PREDICATES = {};
|
|
7
|
-
const NODE_ATTR_PREDICATES = {};
|
|
8
|
-
const focusableRegex = /^(?:a|input|select|option|textarea|button|object)$/i;
|
|
9
|
-
/**
|
|
10
|
-
* @hidden
|
|
11
|
-
*/
|
|
12
|
-
export const MINIMAL_DRAG_DISTANCE = 5;
|
|
13
|
-
/**
|
|
14
|
-
* @hidden
|
|
15
|
-
*/
|
|
16
|
-
export const matchesNodeName = (nodeName) => {
|
|
17
|
-
if (!NODE_NAME_PREDICATES[nodeName]) {
|
|
18
|
-
NODE_NAME_PREDICATES[nodeName] = (element) => String(element.nodeName).toLowerCase() === nodeName.toLowerCase();
|
|
19
|
-
}
|
|
20
|
-
return NODE_NAME_PREDICATES[nodeName];
|
|
21
|
-
};
|
|
22
|
-
/**
|
|
23
|
-
* @hidden
|
|
24
|
-
*/
|
|
25
|
-
export const matchesNodeAttr = (nodeAttr) => {
|
|
26
|
-
if (!NODE_ATTR_PREDICATES[nodeAttr]) {
|
|
27
|
-
NODE_ATTR_PREDICATES[nodeAttr] = (element) => element.hasAttribute ? element.hasAttribute(nodeAttr) : false;
|
|
28
|
-
}
|
|
29
|
-
return NODE_ATTR_PREDICATES[nodeAttr];
|
|
30
|
-
};
|
|
31
|
-
/**
|
|
32
|
-
* @hidden
|
|
33
|
-
*/
|
|
34
|
-
export const closest = (node, predicate) => {
|
|
35
|
-
while (node && !predicate(node)) {
|
|
36
|
-
node = node.parentNode;
|
|
37
|
-
}
|
|
38
|
-
return node;
|
|
39
|
-
};
|
|
40
|
-
/**
|
|
41
|
-
* Returns an object specifying whether there is a `DraggableDirective` under the cursor.
|
|
42
|
-
* @hidden
|
|
43
|
-
*/
|
|
44
|
-
export const draggableFromPoint = (x, y) => {
|
|
45
|
-
if (!isDocumentAvailable()) {
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
const el = document.elementFromPoint(x, y);
|
|
49
|
-
if (!el) {
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
const isDraggable = el.hasAttribute("kendoDraggable");
|
|
53
|
-
const isChild = closest(el, matchesNodeAttr("kendoDraggable")) !== null;
|
|
54
|
-
const parentDraggable = closest(el, matchesNodeAttr("data-sortable-index"));
|
|
55
|
-
const index = parentDraggable ? parseInt(parentDraggable.getAttribute("data-sortable-index"), 10) : -1;
|
|
56
|
-
return {
|
|
57
|
-
element: el,
|
|
58
|
-
index: index,
|
|
59
|
-
isDraggable: isDraggable,
|
|
60
|
-
isDraggableChild: isChild,
|
|
61
|
-
parentDraggable: parentDraggable,
|
|
62
|
-
rect: el.getBoundingClientRect()
|
|
63
|
-
};
|
|
64
|
-
};
|
|
65
|
-
/**
|
|
66
|
-
* Returns the DraggableDirective under the cursor.
|
|
67
|
-
* @hidden
|
|
68
|
-
*/
|
|
69
|
-
export const draggableFromEvent = (event, sortable) => {
|
|
70
|
-
let target;
|
|
71
|
-
if (event.changedTouches) {
|
|
72
|
-
const touch = event.changedTouches[0];
|
|
73
|
-
target = draggableFromPoint(touch.clientX, touch.clientY);
|
|
74
|
-
}
|
|
75
|
-
else {
|
|
76
|
-
target = draggableFromPoint(event.clientX, event.clientY);
|
|
77
|
-
}
|
|
78
|
-
// TODO: refactor sortable. Add draggable getter
|
|
79
|
-
return sortable.draggables.toArray()[target ? target.index : -1];
|
|
80
|
-
};
|
|
81
|
-
/**
|
|
82
|
-
* @hidden
|
|
83
|
-
*/
|
|
84
|
-
export const getAllFocusableChildren = (parent) => {
|
|
85
|
-
return Array.from(parent.querySelectorAll(focusableSelector)).filter((element) => element.offsetParent !== null);
|
|
86
|
-
};
|
|
87
|
-
/**
|
|
88
|
-
* @hidden
|
|
89
|
-
*/
|
|
90
|
-
export const getFirstAndLastFocusable = (parent) => {
|
|
91
|
-
const all = getAllFocusableChildren(parent);
|
|
92
|
-
const firstFocusable = all.length > 0 ? all[0] : parent;
|
|
93
|
-
const lastFocusable = all.length > 0 ? all[all.length - 1] : parent;
|
|
94
|
-
return [firstFocusable, lastFocusable];
|
|
95
|
-
};
|
|
96
|
-
/**
|
|
97
|
-
* @hidden
|
|
98
|
-
*/
|
|
99
|
-
export const keepFocusWithinComponent = (event, wrapper) => {
|
|
100
|
-
const [firstFocusable, lastFocusable] = getFirstAndLastFocusable(wrapper);
|
|
101
|
-
const tabAfterLastFocusable = !event.shiftKey && event.target === lastFocusable;
|
|
102
|
-
const shiftTabAfterFirstFocusable = event.shiftKey && event.target === firstFocusable;
|
|
103
|
-
if (tabAfterLastFocusable) {
|
|
104
|
-
event.preventDefault();
|
|
105
|
-
firstFocusable.focus();
|
|
106
|
-
wrapper.blur();
|
|
107
|
-
}
|
|
108
|
-
if (shiftTabAfterFirstFocusable) {
|
|
109
|
-
event.preventDefault();
|
|
110
|
-
lastFocusable.focus();
|
|
111
|
-
}
|
|
112
|
-
};
|
|
113
|
-
/**
|
|
114
|
-
* @hidden
|
|
115
|
-
*/
|
|
116
|
-
export const isFocusable = (element) => {
|
|
117
|
-
if (element.tagName) {
|
|
118
|
-
const tagName = element.tagName.toLowerCase();
|
|
119
|
-
const tabIndex = element.getAttribute('tabIndex');
|
|
120
|
-
const skipTab = tabIndex === '-1';
|
|
121
|
-
let focusable = tabIndex !== null && !skipTab;
|
|
122
|
-
if (focusableRegex.test(tagName)) {
|
|
123
|
-
focusable = !element.disabled && !skipTab;
|
|
124
|
-
}
|
|
125
|
-
return focusable;
|
|
126
|
-
}
|
|
127
|
-
return false;
|
|
128
|
-
};
|
|
129
|
-
const toClassList = (classNames) => String(classNames).trim().split(' ');
|
|
130
|
-
/**
|
|
131
|
-
* @hidden
|
|
132
|
-
*/
|
|
133
|
-
export const hasClasses = (element, classNames) => {
|
|
134
|
-
const namesList = toClassList(classNames);
|
|
135
|
-
return Boolean(toClassList(element.className).find((className) => namesList.indexOf(className) >= 0));
|
|
136
|
-
};
|
|
137
|
-
const isSortable = matchesNodeName('kendo-sortable');
|
|
138
|
-
/**
|
|
139
|
-
* @hidden
|
|
140
|
-
*/
|
|
141
|
-
export const widgetTarget = (target) => {
|
|
142
|
-
const element = closest(target, node => hasClasses(node, 'k-widget') || isSortable(node));
|
|
143
|
-
return element && !isSortable(element);
|
|
144
|
-
};
|
|
145
|
-
const hasRelativeStackingContext = () => {
|
|
146
|
-
if (!isDocumentAvailable()) {
|
|
147
|
-
return false;
|
|
148
|
-
}
|
|
149
|
-
const top = 10;
|
|
150
|
-
const parent = document.createElement("div");
|
|
151
|
-
parent.style.transform = "matrix(10, 0, 0, 10, 0, 0)";
|
|
152
|
-
const innerDiv = document.createElement('div');
|
|
153
|
-
innerDiv.style.position = 'fixed';
|
|
154
|
-
innerDiv.style.top = `${top}px;`;
|
|
155
|
-
parent.appendChild(innerDiv);
|
|
156
|
-
document.body.appendChild(parent);
|
|
157
|
-
const isDifferent = parent.children[0].getBoundingClientRect().top !== top;
|
|
158
|
-
document.body.removeChild(parent);
|
|
159
|
-
return isDifferent;
|
|
160
|
-
};
|
|
161
|
-
const HAS_RELATIVE_STACKING_CONTEXT = hasRelativeStackingContext();
|
|
162
|
-
/**
|
|
163
|
-
* @hidden
|
|
164
|
-
*/
|
|
165
|
-
export const relativeContextElement = (element) => {
|
|
166
|
-
if (!element || !HAS_RELATIVE_STACKING_CONTEXT || !isDocumentAvailable()) {
|
|
167
|
-
return null;
|
|
168
|
-
}
|
|
169
|
-
let node = element.parentElement;
|
|
170
|
-
while (node) {
|
|
171
|
-
if (window.getComputedStyle(node).transform !== 'none') {
|
|
172
|
-
return node;
|
|
173
|
-
}
|
|
174
|
-
node = node.parentElement;
|
|
175
|
-
}
|
|
176
|
-
};
|