@nanoporetech-digital/components 4.9.4 → 5.0.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.
- package/CHANGELOG.md +51 -0
- package/dist/cjs/drag-777bd8dd.js +74 -0
- package/dist/cjs/drag-777bd8dd.js.map +1 -0
- package/dist/cjs/{form-control-2e900f54.js → form-control-443e90bf.js} +2 -3
- package/dist/cjs/form-control-443e90bf.js.map +1 -0
- package/dist/cjs/index-71f899a7.js +10 -2
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/nano-components.cjs.js +1 -1
- package/dist/cjs/nano-global-nav-user-profile_3.cjs.entry.js +6 -6
- package/dist/cjs/nano-global-nav-user-profile_3.cjs.entry.js.map +1 -1
- package/dist/cjs/nano-grid-item.cjs.entry.js +29 -0
- package/dist/cjs/nano-grid-item.cjs.entry.js.map +1 -0
- package/dist/cjs/nano-grid_2.cjs.entry.js +436 -0
- package/dist/cjs/nano-grid_2.cjs.entry.js.map +1 -0
- package/dist/cjs/nano-hero.cjs.entry.js +4 -10
- package/dist/cjs/nano-hero.cjs.entry.js.map +1 -1
- package/dist/cjs/nano-icon-button_2.cjs.entry.js +40 -3
- package/dist/cjs/nano-icon-button_2.cjs.entry.js.map +1 -1
- package/dist/cjs/nano-input.cjs.entry.js +2 -2
- package/dist/cjs/nano-input.cjs.entry.js.map +1 -1
- package/dist/cjs/nano-range.cjs.entry.js +1 -1
- package/dist/cjs/nano-range.cjs.entry.js.map +1 -1
- package/dist/cjs/nano-sortable.cjs.entry.js +654 -0
- package/dist/cjs/nano-sortable.cjs.entry.js.map +1 -0
- package/dist/cjs/nano-split-pane.cjs.entry.js +30 -45
- package/dist/cjs/nano-split-pane.cjs.entry.js.map +1 -1
- package/dist/cjs/nano-tab-group.cjs.entry.js +39 -43
- package/dist/cjs/nano-tab-group.cjs.entry.js.map +1 -1
- package/dist/cjs/nano-tab.cjs.entry.js +3 -3
- package/dist/cjs/nano-tab.cjs.entry.js.map +1 -1
- package/dist/cjs/{nano-table-54a4ba34.js → nano-table-11052a34.js} +52 -172
- package/dist/cjs/nano-table-11052a34.js.map +1 -0
- package/dist/cjs/nano-table.cjs.entry.js +1 -1
- package/dist/cjs/{table.worker-20ed37a5.js → table.worker-83433a8b.js} +3 -3
- package/dist/cjs/table.worker-83433a8b.js.map +1 -0
- package/dist/cjs/{table.worker-f820b411.js → table.worker-bd51e29f.js} +1 -1
- package/dist/collection/collection-manifest.json +1 -0
- package/dist/collection/components/form-control/form-control.js +1 -2
- package/dist/collection/components/form-control/form-control.js.map +1 -1
- package/dist/collection/components/grid/grid-item.js +11 -136
- package/dist/collection/components/grid/grid-item.js.map +1 -1
- package/dist/collection/components/grid/grid.css +9 -242
- package/dist/collection/components/grid/grid.js +248 -240
- package/dist/collection/components/grid/grid.js.map +1 -1
- package/dist/collection/components/hero/hero.css +42 -89
- package/dist/collection/components/hero/hero.js +4 -11
- package/dist/collection/components/hero/hero.js.map +1 -1
- package/dist/collection/components/icon-button/icon-button.css +18 -4
- package/dist/collection/components/icon-button/icon-button.js +83 -4
- package/dist/collection/components/icon-button/icon-button.js.map +1 -1
- package/dist/collection/components/input/input.css +8 -9
- package/dist/collection/components/nav-item/nav-item.js +4 -4
- package/dist/collection/components/nav-item/nav-item.js.map +1 -1
- package/dist/collection/components/range/range.css +0 -3
- package/dist/collection/components/select/select.css +8 -9
- package/dist/collection/components/sortable/sortable.css +28 -0
- package/dist/collection/components/sortable/sortable.js +1181 -0
- package/dist/collection/components/sortable/sortable.js.map +1 -0
- package/dist/collection/components/split-pane/split-pane.js +29 -27
- package/dist/collection/components/split-pane/split-pane.js.map +1 -1
- package/dist/collection/components/table/table-interface.js.map +1 -1
- package/dist/collection/components/table/table.css +18 -38
- package/dist/collection/components/table/table.header.js +3 -86
- package/dist/collection/components/table/table.header.js.map +1 -1
- package/dist/collection/components/table/table.js +27 -108
- package/dist/collection/components/table/table.js.map +1 -1
- package/dist/collection/components/table/table.row.js +7 -7
- package/dist/collection/components/table/table.row.js.map +1 -1
- package/dist/collection/components/table/table.store.js +1 -1
- package/dist/collection/components/table/table.store.js.map +1 -1
- package/dist/collection/components/table/table.worker.js +3 -3
- package/dist/collection/components/table/table.worker.js.map +1 -1
- package/dist/collection/components/tabs/tab-group.css +9 -13
- package/dist/collection/components/tabs/tab-group.js +39 -43
- package/dist/collection/components/tabs/tab-group.js.map +1 -1
- package/dist/collection/components/tabs/tab.css +53 -14
- package/dist/collection/components/tabs/tab.js +8 -2
- package/dist/collection/components/tabs/tab.js.map +1 -1
- package/dist/collection/utils/constructible-style.js +129 -0
- package/dist/collection/utils/constructible-style.js.map +1 -0
- package/dist/collection/utils/drag.js +52 -4
- package/dist/collection/utils/drag.js.map +1 -1
- package/dist/components/drag.js +72 -0
- package/dist/components/drag.js.map +1 -0
- package/dist/components/form-control.js +1 -2
- package/dist/components/form-control.js.map +1 -1
- package/dist/components/grid.js +268 -183
- package/dist/components/grid.js.map +1 -1
- package/dist/components/icon-button.js +45 -5
- package/dist/components/icon-button.js.map +1 -1
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.js +1 -0
- package/dist/components/index.js.map +1 -1
- package/dist/components/input.js +1 -1
- package/dist/components/input.js.map +1 -1
- package/dist/components/nano-grid-item.js +33 -1
- package/dist/components/nano-grid-item.js.map +1 -1
- package/dist/components/nano-hero.js +6 -19
- package/dist/components/nano-hero.js.map +1 -1
- package/dist/components/nano-range.js +1 -1
- package/dist/components/nano-range.js.map +1 -1
- package/dist/components/nano-sortable.d.ts +11 -0
- package/dist/components/nano-sortable.js +692 -0
- package/dist/components/nano-sortable.js.map +1 -0
- package/dist/components/nano-split-pane.js +30 -45
- package/dist/components/nano-split-pane.js.map +1 -1
- package/dist/components/nano-tab-group.js +40 -44
- package/dist/components/nano-tab-group.js.map +1 -1
- package/dist/components/nano-tab.js +3 -3
- package/dist/components/nano-tab.js.map +1 -1
- package/dist/components/nav-item.js +4 -4
- package/dist/components/nav-item.js.map +1 -1
- package/dist/components/select.js +1 -1
- package/dist/components/select.js.map +1 -1
- package/dist/components/table.js +52 -173
- package/dist/components/table.js.map +1 -1
- package/dist/components/table.worker.js +1 -1
- package/dist/esm/drag-1723a4cc.js +72 -0
- package/dist/esm/drag-1723a4cc.js.map +1 -0
- package/dist/esm/{form-control-269ba84f.js → form-control-e8739b2e.js} +2 -3
- package/dist/esm/form-control-e8739b2e.js.map +1 -0
- package/dist/esm/index-dad5627b.js +10 -2
- package/dist/esm/loader.js +1 -1
- package/dist/esm/nano-components.js +1 -1
- package/dist/esm/nano-global-nav-user-profile_3.entry.js +6 -6
- package/dist/esm/nano-global-nav-user-profile_3.entry.js.map +1 -1
- package/dist/esm/nano-grid-item.entry.js +25 -0
- package/dist/esm/nano-grid-item.entry.js.map +1 -0
- package/dist/esm/nano-grid_2.entry.js +431 -0
- package/dist/esm/nano-grid_2.entry.js.map +1 -0
- package/dist/esm/nano-hero.entry.js +4 -10
- package/dist/esm/nano-hero.entry.js.map +1 -1
- package/dist/esm/nano-icon-button_2.entry.js +41 -4
- package/dist/esm/nano-icon-button_2.entry.js.map +1 -1
- package/dist/esm/nano-input.entry.js +2 -2
- package/dist/esm/nano-input.entry.js.map +1 -1
- package/dist/esm/nano-range.entry.js +1 -1
- package/dist/esm/nano-range.entry.js.map +1 -1
- package/dist/esm/nano-sortable.entry.js +650 -0
- package/dist/esm/nano-sortable.entry.js.map +1 -0
- package/dist/esm/nano-split-pane.entry.js +30 -45
- package/dist/esm/nano-split-pane.entry.js.map +1 -1
- package/dist/esm/nano-tab-group.entry.js +39 -43
- package/dist/esm/nano-tab-group.entry.js.map +1 -1
- package/dist/esm/nano-tab.entry.js +3 -3
- package/dist/esm/nano-tab.entry.js.map +1 -1
- package/dist/esm/{nano-table-929ac4d9.js → nano-table-ba637f26.js} +53 -173
- package/dist/esm/nano-table-ba637f26.js.map +1 -0
- package/dist/esm/nano-table.entry.js +1 -1
- package/dist/esm/{table.worker-2425382a.js → table.worker-1cae39c9.js} +3 -3
- package/dist/esm/table.worker-1cae39c9.js.map +1 -0
- package/dist/{nano-components/p-f820b411.js → esm/table.worker-bd51e29f.js} +1 -1
- package/dist/nano-components/nano-components.css +1 -1
- package/dist/nano-components/nano-components.esm.js +1 -1
- package/dist/nano-components/nano-components.esm.js.map +1 -1
- package/dist/nano-components/p-00cf8021.entry.js +5 -0
- package/dist/nano-components/p-00cf8021.entry.js.map +1 -0
- package/dist/nano-components/{p-906de5a2.entry.js → p-158c73b0.entry.js} +2 -2
- package/dist/nano-components/p-365c997a.js +5 -0
- package/dist/nano-components/p-553acf24.entry.js +5 -0
- package/dist/nano-components/p-553acf24.entry.js.map +1 -0
- package/dist/nano-components/p-6975f110.entry.js +5 -0
- package/dist/nano-components/p-6975f110.entry.js.map +1 -0
- package/dist/nano-components/p-71057181.js +5 -0
- package/dist/nano-components/p-71057181.js.map +1 -0
- package/dist/nano-components/p-842cf127.js +5 -0
- package/dist/nano-components/p-842cf127.js.map +1 -0
- package/dist/nano-components/p-ad6209ec.entry.js +5 -0
- package/dist/nano-components/p-ad6209ec.entry.js.map +1 -0
- package/dist/nano-components/p-b8e76fdf.entry.js +5 -0
- package/dist/nano-components/p-b8e76fdf.entry.js.map +1 -0
- package/dist/{esm/table.worker-f820b411.js → nano-components/p-bd51e29f.js} +1 -1
- package/dist/nano-components/p-bdef618c.entry.js +5 -0
- package/dist/nano-components/p-bdef618c.entry.js.map +1 -0
- package/dist/nano-components/p-d79c6862.entry.js +5 -0
- package/dist/nano-components/p-d79c6862.entry.js.map +1 -0
- package/dist/nano-components/p-deb0799c.entry.js +5 -0
- package/dist/nano-components/{p-6a3a29c6.entry.js.map → p-deb0799c.entry.js.map} +1 -1
- package/dist/nano-components/p-ebb98a9e.entry.js +5 -0
- package/dist/nano-components/p-ebb98a9e.entry.js.map +1 -0
- package/dist/nano-components/p-f60fe933.entry.js +5 -0
- package/dist/nano-components/p-f60fe933.entry.js.map +1 -0
- package/dist/nano-components/p-f7535f45.entry.js +5 -0
- package/dist/nano-components/p-f7535f45.entry.js.map +1 -0
- package/dist/nano-components/p-fc585ea2.js +5 -0
- package/dist/nano-components/p-fc585ea2.js.map +1 -0
- package/dist/types/components/grid/grid-item.d.ts +3 -11
- package/dist/types/components/grid/grid.d.ts +44 -68
- package/dist/types/components/hero/hero.d.ts +1 -3
- package/dist/types/components/icon-button/icon-button.d.ts +14 -0
- package/dist/types/components/sortable/sortable.d.ts +204 -0
- package/dist/types/components/table/table-interface.d.ts +2 -4
- package/dist/types/components/table/table.d.ts +5 -30
- package/dist/types/components/table/table.header.d.ts +0 -3
- package/dist/types/components/tabs/tab-group.d.ts +0 -1
- package/dist/types/components/tabs/tab.d.ts +6 -0
- package/dist/types/components.d.ts +333 -89
- package/dist/types/utils/constructible-style.d.ts +31 -0
- package/dist/types/utils/drag.d.ts +21 -1
- package/docs-json.json +743 -168
- package/docs-vscode.json +102 -26
- package/hydrate/index.js +1210 -552
- package/package.json +2 -2
- package/dist/cjs/form-control-2e900f54.js.map +0 -1
- package/dist/cjs/nano-grid_3.cjs.entry.js +0 -431
- package/dist/cjs/nano-grid_3.cjs.entry.js.map +0 -1
- package/dist/cjs/nano-table-54a4ba34.js.map +0 -1
- package/dist/cjs/table.worker-20ed37a5.js.map +0 -1
- package/dist/collection/components/grid/grid-item.css +0 -15
- package/dist/components/grid-item.js +0 -107
- package/dist/components/grid-item.js.map +0 -1
- package/dist/esm/form-control-269ba84f.js.map +0 -1
- package/dist/esm/nano-grid_3.entry.js +0 -425
- package/dist/esm/nano-grid_3.entry.js.map +0 -1
- package/dist/esm/nano-table-929ac4d9.js.map +0 -1
- package/dist/esm/table.worker-2425382a.js.map +0 -1
- package/dist/nano-components/p-068bdd89.entry.js +0 -5
- package/dist/nano-components/p-068bdd89.entry.js.map +0 -1
- package/dist/nano-components/p-107d4549.entry.js +0 -5
- package/dist/nano-components/p-107d4549.entry.js.map +0 -1
- package/dist/nano-components/p-239d343a.entry.js +0 -5
- package/dist/nano-components/p-239d343a.entry.js.map +0 -1
- package/dist/nano-components/p-4f260028.js +0 -5
- package/dist/nano-components/p-4f260028.js.map +0 -1
- package/dist/nano-components/p-5381c118.js +0 -5
- package/dist/nano-components/p-58b53239.entry.js +0 -5
- package/dist/nano-components/p-58b53239.entry.js.map +0 -1
- package/dist/nano-components/p-5ac74848.js +0 -5
- package/dist/nano-components/p-5ac74848.js.map +0 -1
- package/dist/nano-components/p-64b56ee6.entry.js +0 -5
- package/dist/nano-components/p-64b56ee6.entry.js.map +0 -1
- package/dist/nano-components/p-6a3a29c6.entry.js +0 -5
- package/dist/nano-components/p-a5a560e7.entry.js +0 -5
- package/dist/nano-components/p-a5a560e7.entry.js.map +0 -1
- package/dist/nano-components/p-a761ac89.entry.js +0 -5
- package/dist/nano-components/p-a761ac89.entry.js.map +0 -1
- package/dist/nano-components/p-d792f692.entry.js +0 -5
- package/dist/nano-components/p-d792f692.entry.js.map +0 -1
- /package/dist/nano-components/{p-5381c118.js.map → p-158c73b0.entry.js.map} +0 -0
- /package/dist/nano-components/{p-906de5a2.entry.js.map → p-365c997a.js.map} +0 -0
@@ -0,0 +1,650 @@
|
|
1
|
+
/*!
|
2
|
+
* Web Components for Nanopore digital Web Apps
|
3
|
+
*/
|
4
|
+
import { w as writeTask, r as registerInstance, c as createEvent, d as readTask, h, a as Host, g as getElement } from './index-dad5627b.js';
|
5
|
+
import { d as drag } from './drag-1723a4cc.js';
|
6
|
+
import { d as debounce } from './throttle-7836544e.js';
|
7
|
+
|
8
|
+
const sortableCss = ":host{box-sizing:border-box}*,*::before,*::after{box-sizing:border-box}[hidden]{display:none !important}:host{position:relative;display:block}.sortable__live-region{clip:rect(1px, 1px, 1px, 1px);-webkit-clip-path:inset(50%);clip-path:inset(50%);block-size:1px;inline-size:1px;margin:-1px;overflow:hidden;padding:0;position:absolute}";
|
9
|
+
|
10
|
+
// Orientation map to limit dragging to horizontal or vertical.
|
11
|
+
const orientationMap = {
|
12
|
+
horizontal: { x: 1, y: 0 },
|
13
|
+
vertical: { x: 0, y: 1 },
|
14
|
+
};
|
15
|
+
let sortableIds = 0;
|
16
|
+
const Sortable = class {
|
17
|
+
handleItemSelectorChange() {
|
18
|
+
this.refreshKeyboardHandles();
|
19
|
+
}
|
20
|
+
handleHandleSelectorChange() {
|
21
|
+
this.refreshKeyboardHandles();
|
22
|
+
this.attachMutationObserver();
|
23
|
+
}
|
24
|
+
handleCreateKeyboardHandleChange() {
|
25
|
+
this.refreshKeyboardHandles();
|
26
|
+
}
|
27
|
+
handleSortableHostElement(_newVal, oldVal) {
|
28
|
+
if (oldVal)
|
29
|
+
this.removeEventHandlers(oldVal);
|
30
|
+
this.addEventHandlers();
|
31
|
+
this.refreshKeyboardHandles();
|
32
|
+
this.attachMutationObserver();
|
33
|
+
if (this.sortableHostElement) {
|
34
|
+
// sortable host must have position relative
|
35
|
+
this.sortableHostElement.style.position = 'relative';
|
36
|
+
}
|
37
|
+
}
|
38
|
+
/** If sortable elements change dynamically, use this method to add handle controls to new elements */
|
39
|
+
async refreshKeyboardHandles() {
|
40
|
+
var _a, _b, _c;
|
41
|
+
if (this.handleSelector) {
|
42
|
+
if ((_a = this.keyboardHandleMap) === null || _a === void 0 ? void 0 : _a.size) {
|
43
|
+
this.keyboardHandleMap.clear();
|
44
|
+
}
|
45
|
+
this.sortableHost
|
46
|
+
.querySelectorAll(this.handleSelector)
|
47
|
+
.forEach((handle) => {
|
48
|
+
if (!handle.getAttribute('aria-describedby'))
|
49
|
+
handle.setAttribute('aria-describedby', this.sortableId);
|
50
|
+
const sortEle = handle.closest(this.itemSelector);
|
51
|
+
if (sortEle)
|
52
|
+
this.keyboardHandleMap.set(handle, sortEle);
|
53
|
+
});
|
54
|
+
return;
|
55
|
+
}
|
56
|
+
if ((_b = this.keyboardHandleMap) === null || _b === void 0 ? void 0 : _b.size) {
|
57
|
+
(_c = this.keyboardHandleMap) === null || _c === void 0 ? void 0 : _c.forEach((_ele, handle) => handle.remove());
|
58
|
+
this.keyboardHandleMap.clear();
|
59
|
+
}
|
60
|
+
this.sortableHost
|
61
|
+
.querySelectorAll(this.itemSelector)
|
62
|
+
.forEach((ele, i) => {
|
63
|
+
const handle = this.createKeyboardHandle(i, ele);
|
64
|
+
if (!handle) {
|
65
|
+
console.error('`createKeyboardHandle` *must* return the handle element it creates');
|
66
|
+
return;
|
67
|
+
}
|
68
|
+
this.keyboardHandleMap.set(handle, ele);
|
69
|
+
handle.setAttribute('aria-describedby', this.sortableId);
|
70
|
+
});
|
71
|
+
}
|
72
|
+
/**
|
73
|
+
* Get instance of sortable host.
|
74
|
+
* By default it is `nano-sortable` which can be overridden by property `sortableHostElement`
|
75
|
+
*/
|
76
|
+
get sortableHost() {
|
77
|
+
if (this.sortableHostElement)
|
78
|
+
return this.sortableHostElement;
|
79
|
+
return this.host;
|
80
|
+
}
|
81
|
+
/**
|
82
|
+
* Queues aria messages which are then displayed in a 'live' region.
|
83
|
+
* Messages are cleared after 10s
|
84
|
+
* @param msg aria message to announce
|
85
|
+
*/
|
86
|
+
addAriaMsg(msg) {
|
87
|
+
this.ariaTextList = [...this.ariaTextList, msg];
|
88
|
+
setTimeout(() => {
|
89
|
+
const mIdx = this.ariaTextList.indexOf(msg);
|
90
|
+
this.ariaTextList.splice(mIdx, 1);
|
91
|
+
this.ariaTextList = [...this.ariaTextList];
|
92
|
+
}, 10000);
|
93
|
+
}
|
94
|
+
/**
|
95
|
+
* Try to stop text highlight whilst dragging
|
96
|
+
* @param userSelect
|
97
|
+
*/
|
98
|
+
updateUserSelectStyle(userSelect) {
|
99
|
+
this.host.style.userSelect = userSelect;
|
100
|
+
// @ts-ignore
|
101
|
+
this.host.style.MozUserSelect = userSelect;
|
102
|
+
// @ts-ignore
|
103
|
+
this.host.style.msUserSelect = userSelect;
|
104
|
+
this.host.style.webkitUserSelect = userSelect;
|
105
|
+
}
|
106
|
+
/**
|
107
|
+
* Fast and simple hit test to check whether the center of a node intersects with the rectangle of any of the
|
108
|
+
* given targets. Returns an array of matches.
|
109
|
+
* @param node
|
110
|
+
* @param targets
|
111
|
+
* @returns all the items that currently intersect with the target node
|
112
|
+
*/
|
113
|
+
hitTest(node, targets) {
|
114
|
+
const { left: l, top: t, width: w, height: h, } = node.getBoundingClientRect();
|
115
|
+
const x = l + w / 2;
|
116
|
+
const y = t + h / 2;
|
117
|
+
return targets.filter((item) => {
|
118
|
+
const { left, right, top, bottom } = item.getBoundingClientRect();
|
119
|
+
return !(x < left || x > right || y < top || y > bottom);
|
120
|
+
});
|
121
|
+
}
|
122
|
+
/**
|
123
|
+
* Returns a boolean indicating whether the node is currently in an animation.
|
124
|
+
* @param node
|
125
|
+
* @returns whether a node is currently animating or not
|
126
|
+
*/
|
127
|
+
isAnimating(node) {
|
128
|
+
return this.animatedElements.indexOf(node) !== -1;
|
129
|
+
}
|
130
|
+
/**
|
131
|
+
* Triggers a CSS animation on a node with the given dx and dy. Used following dom updates to make it appear as
|
132
|
+
* if nodes animate from their old to their new position in the dom. */
|
133
|
+
animateNode(node, dx = 0, dy = 0) {
|
134
|
+
if (!node.animate) {
|
135
|
+
return;
|
136
|
+
}
|
137
|
+
// keep a stack of currently animating nodes to exclude as drag & drop targets.
|
138
|
+
this.animatedElements.push(node);
|
139
|
+
node.style.willChange = 'transform';
|
140
|
+
// animate from dx/dy (old node position) to none (new node position)
|
141
|
+
writeTask(() => {
|
142
|
+
this.animationPromise = new Promise((resolve) => {
|
143
|
+
node
|
144
|
+
.animate([
|
145
|
+
{ transform: `translate3d(${dx}px, ${dy}px, 0)` },
|
146
|
+
{ transform: 'none' },
|
147
|
+
], this.animationTiming)
|
148
|
+
.addEventListener('finish', () => {
|
149
|
+
const index = this.animatedElements.indexOf(node);
|
150
|
+
node.style.willChange = '';
|
151
|
+
if (index !== -1) {
|
152
|
+
// splice out when done to unlock as a valid target
|
153
|
+
this.animatedElements.splice(index, 1);
|
154
|
+
}
|
155
|
+
resolve();
|
156
|
+
delete this.animationPromise;
|
157
|
+
}, { once: true });
|
158
|
+
});
|
159
|
+
});
|
160
|
+
}
|
161
|
+
/**
|
162
|
+
* Inserts node at target to update sibling sorting. If the node precedes the target, it is inserted after it;
|
163
|
+
* If it follows the target, it is inserted before it. This ensures any node can be dragged from the very
|
164
|
+
* beginning to the very end and vice versa. The animateNode function is called for all nodes that moved because
|
165
|
+
* of this dom update */
|
166
|
+
insertAtTarget(node, target) {
|
167
|
+
if (!node || !target)
|
168
|
+
return;
|
169
|
+
let offsets = [];
|
170
|
+
if (this.animationEnabled) {
|
171
|
+
offsets = this.sortableNodes.map((item) => ({
|
172
|
+
x: item.offsetLeft,
|
173
|
+
y: item.offsetTop,
|
174
|
+
}));
|
175
|
+
}
|
176
|
+
if (!node.isConnected || !target.isConnected)
|
177
|
+
return;
|
178
|
+
if (this.dropzoneNodes.indexOf(target) > -1) {
|
179
|
+
target.append(node);
|
180
|
+
}
|
181
|
+
else {
|
182
|
+
const nodeComparison = node.compareDocumentPosition(target);
|
183
|
+
let position;
|
184
|
+
if (nodeComparison & this.host.DOCUMENT_POSITION_FOLLOWING) {
|
185
|
+
position =
|
186
|
+
target.parentNode === node.parentNode ? 'afterend' : 'beforebegin';
|
187
|
+
}
|
188
|
+
if (nodeComparison & this.host.DOCUMENT_POSITION_PRECEDING) {
|
189
|
+
position =
|
190
|
+
target.parentNode === node.parentNode ? 'beforebegin' : 'afterend';
|
191
|
+
}
|
192
|
+
if (position)
|
193
|
+
target.insertAdjacentElement(position, node);
|
194
|
+
}
|
195
|
+
if (this.animationEnabled) {
|
196
|
+
this.sortableNodes.forEach((sortableNode, i) => {
|
197
|
+
const { x, y } = offsets[i];
|
198
|
+
const dx = x - sortableNode.offsetLeft;
|
199
|
+
const dy = y - sortableNode.offsetTop;
|
200
|
+
if (dx !== 0 || dy !== 0) {
|
201
|
+
this.animateNode(sortableNode, dx, dy);
|
202
|
+
}
|
203
|
+
});
|
204
|
+
}
|
205
|
+
}
|
206
|
+
reset() {
|
207
|
+
if (this.draggedElementClone !== undefined &&
|
208
|
+
this.draggedElementClone.parentNode !== null) {
|
209
|
+
this.draggedElementClone.parentNode.removeChild(this.draggedElementClone);
|
210
|
+
}
|
211
|
+
if (this.draggedElement &&
|
212
|
+
this.draggedElement.parentNode &&
|
213
|
+
this.draggedElementOrigin) {
|
214
|
+
this.draggedElement.classList.remove(this.placeholderClass);
|
215
|
+
}
|
216
|
+
if (this.dropzoneActiveClass && this.dropzoneNodes.length) {
|
217
|
+
this.dropzoneNodes.forEach((dze) => dze.classList.remove(this.dropzoneActiveClass));
|
218
|
+
}
|
219
|
+
delete this.draggedElementClone;
|
220
|
+
delete this.draggedElement;
|
221
|
+
this.dropzoneNodes = [];
|
222
|
+
this.sortableNodes = [];
|
223
|
+
this.animatedElements = [];
|
224
|
+
this.dragRequestPending = false;
|
225
|
+
this.updateUserSelectStyle('');
|
226
|
+
}
|
227
|
+
/**
|
228
|
+
* Clones a given node to visually drag around. The original node is left in the same flow as its siblings.
|
229
|
+
* Clone styles are added onto the style object directly, since the ::slotted()
|
230
|
+
* selector can't universally target nodes that may be nested an unknown amount of shadow dom levels deep
|
231
|
+
* @param node html node to clone
|
232
|
+
* @returns the cloned html node
|
233
|
+
*/
|
234
|
+
createClone(node) {
|
235
|
+
const clone = node.cloneNode(true);
|
236
|
+
if (node.id)
|
237
|
+
clone.id = 'clone__' + clone.id;
|
238
|
+
/**
|
239
|
+
* Bugfix for table row sorting.
|
240
|
+
* During dragging table rows shrink, so we manually set them width of original node.
|
241
|
+
*/
|
242
|
+
Array.from(clone.children).forEach((nodeChild, index) => {
|
243
|
+
const clonedNodeChild = nodeChild;
|
244
|
+
const originalNodeChild = node.children.item(index);
|
245
|
+
if (originalNodeChild) {
|
246
|
+
clonedNodeChild.style.width = `${originalNodeChild.offsetWidth}px`;
|
247
|
+
}
|
248
|
+
});
|
249
|
+
const { offsetLeft: x, offsetTop: y, offsetWidth: w, offsetHeight: h, } = node;
|
250
|
+
Object.assign(clone.style, {
|
251
|
+
position: 'absolute',
|
252
|
+
left: `calc(${x}px - var(--grab-offset-x, 0px))`,
|
253
|
+
top: `calc(${y}px - var(--grab-offset-y, 0px))`,
|
254
|
+
height: this.dragResize ? `${h}px` : undefined,
|
255
|
+
width: this.dragResize ? `${w}px` : undefined,
|
256
|
+
willChange: 'transform,opacity',
|
257
|
+
});
|
258
|
+
clone.classList.add(this.draggedClass);
|
259
|
+
return node.parentNode.appendChild(clone);
|
260
|
+
}
|
261
|
+
/// Event handlers ///
|
262
|
+
removeEventHandlers(ele) {
|
263
|
+
ele = ele || this.sortableHost;
|
264
|
+
ele.removeEventListener('mousedown', this.handleTrack);
|
265
|
+
ele.removeEventListener('touchstart', this.handleTrack);
|
266
|
+
ele.removeEventListener('keydown', this.handleKeydown);
|
267
|
+
}
|
268
|
+
addEventHandlers(ele) {
|
269
|
+
ele = ele || this.sortableHost;
|
270
|
+
ele.addEventListener('mousedown', this.handleTrack);
|
271
|
+
ele.addEventListener('touchstart', this.handleTrack);
|
272
|
+
ele.addEventListener('keydown', this.handleKeydown);
|
273
|
+
}
|
274
|
+
/**
|
275
|
+
* Watch for any changes in grab-able handle elements.
|
276
|
+
*/
|
277
|
+
attachMutationObserver() {
|
278
|
+
if (this.mutationObserver) {
|
279
|
+
this.mutationObserver.disconnect();
|
280
|
+
this.mutationObserver = undefined;
|
281
|
+
}
|
282
|
+
this.mutationObserver = new MutationObserver(() => {
|
283
|
+
const currHandles = Array.from(this.keyboardHandleMap.values());
|
284
|
+
const newHandles = Array.from(this.sortableHost.querySelectorAll(this.itemSelector));
|
285
|
+
// simple test for equality
|
286
|
+
if (currHandles.length !== newHandles.length ||
|
287
|
+
!!newHandles.find((h) => !currHandles.includes(h))) {
|
288
|
+
this.refreshKeyboardHandles();
|
289
|
+
}
|
290
|
+
});
|
291
|
+
this.mutationObserver.observe(this.sortableHost, {
|
292
|
+
subtree: true,
|
293
|
+
childList: true,
|
294
|
+
});
|
295
|
+
}
|
296
|
+
handleKeydown(e) {
|
297
|
+
const targetElement = e.target;
|
298
|
+
let foundHandle;
|
299
|
+
let sortEle;
|
300
|
+
if (this.handleSelector) {
|
301
|
+
foundHandle = targetElement.closest(this.handleSelector);
|
302
|
+
sortEle = targetElement.closest(this.itemSelector);
|
303
|
+
}
|
304
|
+
else {
|
305
|
+
sortEle = this.keyboardHandleMap.get(targetElement);
|
306
|
+
foundHandle = targetElement;
|
307
|
+
}
|
308
|
+
// have we found a handle and matching sort element from the keydown element
|
309
|
+
if (!foundHandle || !sortEle)
|
310
|
+
return;
|
311
|
+
const activateSort = (isActive) => {
|
312
|
+
this.keyboardSortActive = isActive;
|
313
|
+
this.draggedElement = isActive ? sortEle : undefined;
|
314
|
+
sortEle.classList.toggle(this.draggedClass, isActive);
|
315
|
+
foundHandle.classList.toggle(this.handleDraggedClass, isActive);
|
316
|
+
if (isActive) {
|
317
|
+
this.addAriaMsg(this.grabbedHelperText(sortEle));
|
318
|
+
document.addEventListener('mousedown', () => activateSort(false), {
|
319
|
+
once: true,
|
320
|
+
});
|
321
|
+
}
|
322
|
+
else {
|
323
|
+
this.addAriaMsg(this.droppedHelperText(sortEle));
|
324
|
+
}
|
325
|
+
};
|
326
|
+
// start editing this element's order?
|
327
|
+
if ([' ', 'Space', 'Enter'].includes(e.key)) {
|
328
|
+
e.preventDefault();
|
329
|
+
if (!this.keyboardSortActive) {
|
330
|
+
// grabbed the element
|
331
|
+
activateSort(true);
|
332
|
+
this.sortableNodes =
|
333
|
+
Array.from(this.sortableHost.querySelectorAll(this.itemSelector)) ||
|
334
|
+
[];
|
335
|
+
const nanoGrabbedEv = this.nanoGrabbed.emit({
|
336
|
+
element: sortEle,
|
337
|
+
index: this.sortableNodes.indexOf(sortEle),
|
338
|
+
});
|
339
|
+
if (nanoGrabbedEv.defaultPrevented) {
|
340
|
+
activateSort(false);
|
341
|
+
return;
|
342
|
+
}
|
343
|
+
}
|
344
|
+
else {
|
345
|
+
// dropped the element
|
346
|
+
activateSort(false);
|
347
|
+
this.nanoDropped.emit({ element: sortEle });
|
348
|
+
}
|
349
|
+
return;
|
350
|
+
}
|
351
|
+
if (!this.keyboardSortActive)
|
352
|
+
return;
|
353
|
+
// Tabbing away from this handle - deactivate
|
354
|
+
if (['Escape', 'Tab'].includes(e.key))
|
355
|
+
activateSort(false);
|
356
|
+
let moveKeys = ['Home', 'End'];
|
357
|
+
if (!this.orientation || this.orientation === 'horizontal')
|
358
|
+
moveKeys = [...moveKeys, 'ArrowRight', 'ArrowLeft'];
|
359
|
+
if (!this.orientation || this.orientation === 'vertical')
|
360
|
+
moveKeys = [...moveKeys, 'ArrowUp', 'ArrowDown'];
|
361
|
+
if (!moveKeys.includes(e.key))
|
362
|
+
return;
|
363
|
+
// move the element with the keyboard
|
364
|
+
e.preventDefault();
|
365
|
+
/** Collect all elements that have drag positions.
|
366
|
+
* Both sortable elements and 'dropzones' (placeholders where items can always be placed) */
|
367
|
+
this.sortableNodes =
|
368
|
+
Array.from(this.sortableHost.querySelectorAll(this.itemSelector)) || [];
|
369
|
+
this.dropzoneNodes =
|
370
|
+
Array.from(this.sortableHost.querySelectorAll(this.dropzoneSelector)) ||
|
371
|
+
[];
|
372
|
+
const currIdx = this.sortableNodes.indexOf(this.draggedElement);
|
373
|
+
let curDzIdx = -1;
|
374
|
+
if (this.dropzoneNodes.length) {
|
375
|
+
const curDropzone = this.draggedElement.closest(this.dropzoneSelector);
|
376
|
+
curDzIdx = this.dropzoneNodes.indexOf(curDropzone);
|
377
|
+
curDzIdx = curDzIdx > -1 ? curDzIdx : -1;
|
378
|
+
}
|
379
|
+
/** If we don't have a next / prev sortable element in our list, test to see if there's a dropzone instead */
|
380
|
+
const prevEle = currIdx - 1 < 0 && curDzIdx > -1
|
381
|
+
? this.dropzoneNodes[curDzIdx - 1]
|
382
|
+
: this.sortableNodes[currIdx - 1];
|
383
|
+
const nextEle = currIdx + 1 === this.sortableNodes.length && curDzIdx > -1
|
384
|
+
? this.dropzoneNodes[curDzIdx + 1]
|
385
|
+
: this.sortableNodes[currIdx + 1];
|
386
|
+
if (e.key === 'Home') {
|
387
|
+
this.insertAtTarget(this.draggedElement, this.sortableNodes[0]);
|
388
|
+
}
|
389
|
+
if (e.key === 'End') {
|
390
|
+
this.insertAtTarget(this.draggedElement, this.sortableNodes[this.sortableNodes.length - 1]);
|
391
|
+
}
|
392
|
+
if (['ArrowRight', 'ArrowDown'].includes(e.key)) {
|
393
|
+
this.insertAtTarget(this.draggedElement, nextEle);
|
394
|
+
}
|
395
|
+
if (['ArrowLeft', 'ArrowUp'].includes(e.key)) {
|
396
|
+
this.insertAtTarget(this.draggedElement, prevEle);
|
397
|
+
}
|
398
|
+
this.finishOrder();
|
399
|
+
this.draggedElement = sortEle;
|
400
|
+
const focus = () => {
|
401
|
+
requestAnimationFrame(() => {
|
402
|
+
typeof foundHandle['setFocus'] === 'function'
|
403
|
+
? foundHandle.setFocus()
|
404
|
+
: foundHandle.focus();
|
405
|
+
});
|
406
|
+
};
|
407
|
+
// replace focus to handle so we don't 'drop' the element
|
408
|
+
if (this.animationPromise)
|
409
|
+
this.animationPromise.then(() => focus());
|
410
|
+
else
|
411
|
+
focus();
|
412
|
+
}
|
413
|
+
/**
|
414
|
+
* Tracks a pointer from touchstart/mousedown to touchend/mouseup. Note that the start state is fired following
|
415
|
+
* the first actual move event following a touchstart/mousedown */
|
416
|
+
handleTrack(e) {
|
417
|
+
if (this.dragRequestPending || (e.button && e.button !== 1))
|
418
|
+
return;
|
419
|
+
clearTimeout(this.mouseDownTimer);
|
420
|
+
this.mouseDownTimer = window === null || window === void 0 ? void 0 : window.setTimeout(() => {
|
421
|
+
if (!this.trackStart(e))
|
422
|
+
return;
|
423
|
+
this.addAriaMsg(this.grabbedHelperText(this.draggedElement));
|
424
|
+
drag(this.sortableHost, {
|
425
|
+
initialEvent: e,
|
426
|
+
relative: true,
|
427
|
+
onMove: (x, y) => {
|
428
|
+
this.trackMove(x, y);
|
429
|
+
},
|
430
|
+
onStop: () => {
|
431
|
+
this.nanoDropped.emit({ element: this.draggedElement });
|
432
|
+
const didStop = () => {
|
433
|
+
this.addAriaMsg(this.droppedHelperText(this.draggedElement));
|
434
|
+
requestAnimationFrame(() => this.finishOrder());
|
435
|
+
};
|
436
|
+
if (this.animationPromise) {
|
437
|
+
this.animationPromise.then(() => didStop());
|
438
|
+
}
|
439
|
+
else
|
440
|
+
didStop();
|
441
|
+
},
|
442
|
+
});
|
443
|
+
}, 100);
|
444
|
+
document.addEventListener('mouseup', () => clearTimeout(this.mouseDownTimer), { once: true });
|
445
|
+
}
|
446
|
+
/**
|
447
|
+
* Initialized a drag and drop sequence if a child node was clicked that matches the itemSelector property.
|
448
|
+
* OR If a handleSelector is defined, a node matching this selector must be clicked instead
|
449
|
+
* @returns boolean - whether tracking for this event should continue or not
|
450
|
+
*/
|
451
|
+
trackStart(e) {
|
452
|
+
const targetElement = e.target;
|
453
|
+
let targetHandle;
|
454
|
+
// If we have a handle set, return now if not being pressed
|
455
|
+
if (this.handleSelector) {
|
456
|
+
targetHandle = targetElement.closest(this.handleSelector);
|
457
|
+
if (!targetHandle)
|
458
|
+
return;
|
459
|
+
targetHandle.classList.add(this.handleDraggedClass);
|
460
|
+
}
|
461
|
+
// Check that we've found the target element via itemSelector
|
462
|
+
const node = targetElement.closest(this.itemSelector);
|
463
|
+
if (!node)
|
464
|
+
return false;
|
465
|
+
this.sortableNodes =
|
466
|
+
Array.from(this.sortableHost.querySelectorAll(this.itemSelector)) || [];
|
467
|
+
const nanoGrabbedEv = this.nanoGrabbed.emit({
|
468
|
+
element: node,
|
469
|
+
index: this.sortableNodes.indexOf(node),
|
470
|
+
});
|
471
|
+
if (nanoGrabbedEv.defaultPrevented)
|
472
|
+
return false;
|
473
|
+
// Element found... start everything
|
474
|
+
e.preventDefault();
|
475
|
+
this.updateUserSelectStyle('none');
|
476
|
+
this.dragRequestPending = true;
|
477
|
+
this.draggedElement = node;
|
478
|
+
this.dropzoneNodes =
|
479
|
+
Array.from(this.sortableHost.querySelectorAll(this.dropzoneSelector)) ||
|
480
|
+
[];
|
481
|
+
this.draggedElementClone = this.createClone(node);
|
482
|
+
this.draggedElementOrigin = node.nextSibling;
|
483
|
+
this.animatedElements = [];
|
484
|
+
this.draggedElement.classList.add(this.placeholderClass);
|
485
|
+
return true;
|
486
|
+
}
|
487
|
+
/** Ends re-ordering */
|
488
|
+
finishOrder() {
|
489
|
+
if (!this.draggedElement)
|
490
|
+
return;
|
491
|
+
const updated = Array.from(this.sortableHost.querySelectorAll(this.itemSelector)).filter((ele) => ele !== this.draggedElementClone);
|
492
|
+
const originalIndex = this.sortableNodes.indexOf(this.draggedElement);
|
493
|
+
const targetIndex = updated.indexOf(this.draggedElement);
|
494
|
+
if (this.handleSelector) {
|
495
|
+
const targetHandle = this.draggedElement.querySelector(this.handleSelector);
|
496
|
+
targetHandle.classList.remove(this.handleDraggedClass);
|
497
|
+
}
|
498
|
+
if (originalIndex !== targetIndex) {
|
499
|
+
const orderChangeEv = this.nanoOrderChange.emit({
|
500
|
+
element: this.draggedElement,
|
501
|
+
originalIndex,
|
502
|
+
targetIndex,
|
503
|
+
});
|
504
|
+
if (orderChangeEv.defaultPrevented) {
|
505
|
+
/** Event was prevented, wait a moment to send element back to whence it came - gives a nicer visual queue */
|
506
|
+
this.animationPromise = new Promise((resolve) => {
|
507
|
+
setTimeout(() => {
|
508
|
+
this.insertAtTarget(this.draggedElement, updated[originalIndex]);
|
509
|
+
this.reset();
|
510
|
+
this.dragRequestPending = false;
|
511
|
+
resolve();
|
512
|
+
}, 200);
|
513
|
+
});
|
514
|
+
return;
|
515
|
+
}
|
516
|
+
this.addAriaMsg(this.reorderHelperText(this.draggedElement, updated, targetIndex + 1));
|
517
|
+
}
|
518
|
+
this.reset();
|
519
|
+
this.dragRequestPending = false;
|
520
|
+
}
|
521
|
+
/// Component lifecycle ///
|
522
|
+
constructor(hostRef) {
|
523
|
+
registerInstance(this, hostRef);
|
524
|
+
this.nanoOrderChange = createEvent(this, "nanoOrderChange", 7);
|
525
|
+
this.nanoGrabbed = createEvent(this, "nanoGrabbed", 7);
|
526
|
+
this.nanoDropped = createEvent(this, "nanoDropped", 7);
|
527
|
+
this.dragRequestPending = false;
|
528
|
+
this.sortableNodes = [];
|
529
|
+
this.dropzoneNodes = [];
|
530
|
+
this.animatedElements = [];
|
531
|
+
this.keyboardHandleMap = new Map();
|
532
|
+
this.sortableId = `nano-sortable-${sortableIds++}`;
|
533
|
+
/**
|
534
|
+
* Moves the active node's clone to follow the pointer. The node that the clone intersects with (via hitTest) is
|
535
|
+
* the insert point for updated sorting */
|
536
|
+
this.trackMove = (x, y) => {
|
537
|
+
if (!this.draggedElementClone) {
|
538
|
+
return;
|
539
|
+
}
|
540
|
+
if (this.orientation) {
|
541
|
+
x = x * orientationMap[this.orientation].x;
|
542
|
+
y = y * orientationMap[this.orientation].y;
|
543
|
+
}
|
544
|
+
writeTask(() => {
|
545
|
+
Object.assign(this.draggedElementClone.style, {
|
546
|
+
transform: `translate3d(${x}px, ${y}px, 0)`,
|
547
|
+
});
|
548
|
+
});
|
549
|
+
let target = this.hitTest(this.draggedElementClone, this.sortableNodes)[0];
|
550
|
+
let activeDropzone;
|
551
|
+
if (this.dropzoneSelector && this.dropzoneActiveClass) {
|
552
|
+
readTask(() => {
|
553
|
+
activeDropzone = this.draggedElement.closest(this.dropzoneSelector);
|
554
|
+
writeTask(() => {
|
555
|
+
this.dropzoneNodes
|
556
|
+
.filter((dze) => dze !== activeDropzone)
|
557
|
+
.forEach((dze) => dze.classList.remove(this.dropzoneActiveClass));
|
558
|
+
activeDropzone.classList.add(this.dropzoneActiveClass);
|
559
|
+
});
|
560
|
+
});
|
561
|
+
}
|
562
|
+
// didn't find a target - let's test to see if we can use a drop-zone instead
|
563
|
+
if (!target && this.dropzoneNodes.length) {
|
564
|
+
target = this.hitTest(this.draggedElementClone, this.dropzoneNodes)[0];
|
565
|
+
if (this.draggedElement.closest(this.dropzoneSelector) === target)
|
566
|
+
return;
|
567
|
+
}
|
568
|
+
if (
|
569
|
+
// if clone intersects with a valid target,
|
570
|
+
target &&
|
571
|
+
// other than its own origin,
|
572
|
+
target !== this.draggedElement &&
|
573
|
+
// and the target isn't currently animating, which causes false hit tests,
|
574
|
+
!this.isAnimating(target)) {
|
575
|
+
this.insertAtTarget(this.draggedElement, target);
|
576
|
+
}
|
577
|
+
};
|
578
|
+
this.itemSelector = 'li';
|
579
|
+
this.handleSelector = undefined;
|
580
|
+
this.dropzoneSelector = undefined;
|
581
|
+
this.helperText = 'Press "Space" or "Enter" to enable element reordering and use the arrow keys to reorder items.' +
|
582
|
+
'Press "Escape" to cancel reordering. Alternatively, use your mouse to drag / reorder.';
|
583
|
+
this.itemDescriptor = (el) => `"${el.textContent.trim()}"`;
|
584
|
+
this.grabbedHelperText = (el) => `${this.itemDescriptor(el)} grabbed`;
|
585
|
+
this.droppedHelperText = (el) => `${this.itemDescriptor(el)} dropped`;
|
586
|
+
this.reorderHelperText = (el, elements, position) => `The list has been reordered, ${this.itemDescriptor(el)} is now item ${position} of ${elements.length}`;
|
587
|
+
this.createKeyboardHandle = (_number, _element) => {
|
588
|
+
const handleTpl = /* html */ `
|
589
|
+
<nano-icon-button
|
590
|
+
slot="end"
|
591
|
+
icon-name="light/arrows"
|
592
|
+
class="nano-sortable__keyboard-handle visually-hidden"
|
593
|
+
label="Re-order this item"
|
594
|
+
></nano-icon-button>`;
|
595
|
+
const div = globalThis.document.createElement('div');
|
596
|
+
div.innerHTML = handleTpl;
|
597
|
+
const handle = div.children[0];
|
598
|
+
_element.append(handle);
|
599
|
+
return handle;
|
600
|
+
};
|
601
|
+
this.sortableHostElement = undefined;
|
602
|
+
this.animationEnabled = true;
|
603
|
+
this.draggedClass = 'nano-sortable__dragged';
|
604
|
+
this.handleDraggedClass = 'nano-sortable__handle-dragged';
|
605
|
+
this.placeholderClass = 'nano-sortable__placeholder';
|
606
|
+
this.dropzoneActiveClass = '';
|
607
|
+
this.animationTiming = { duration: 200, easing: 'ease-out' };
|
608
|
+
this.orientation = undefined;
|
609
|
+
this.dragResize = false;
|
610
|
+
this.keyboardSortActive = false;
|
611
|
+
this.ariaTextList = [];
|
612
|
+
this.handleTrack = this.handleTrack.bind(this);
|
613
|
+
this.handleKeydown = this.handleKeydown.bind(this);
|
614
|
+
this.refreshKeyboardHandles = this.refreshKeyboardHandles.bind(this);
|
615
|
+
this.refreshKeyboardHandles = debounce(this.refreshKeyboardHandles, 500);
|
616
|
+
}
|
617
|
+
connectedCallback() {
|
618
|
+
this.addEventHandlers();
|
619
|
+
this.refreshKeyboardHandles();
|
620
|
+
this.attachMutationObserver();
|
621
|
+
if (!this.host.querySelector(`#${this.sortableId}`)) {
|
622
|
+
// inject a light-dom / a11y description that we can connect sortable items to
|
623
|
+
this.host.insertAdjacentHTML('beforeend', `<div class="visually-hidden" id="${this.sortableId}">${this.helperText}</div>`);
|
624
|
+
}
|
625
|
+
}
|
626
|
+
disconnectedCallback() {
|
627
|
+
var _a;
|
628
|
+
this.removeEventHandlers();
|
629
|
+
(_a = this.host.querySelector(`#${this.sortableId}`)) === null || _a === void 0 ? void 0 : _a.remove();
|
630
|
+
if (this.mutationObserver) {
|
631
|
+
this.mutationObserver.disconnect();
|
632
|
+
this.mutationObserver = undefined;
|
633
|
+
}
|
634
|
+
}
|
635
|
+
render() {
|
636
|
+
return (h(Host, null, h("div", { class: "sortable__live-region", "aria-live": "polite", "aria-relevant": "additions", "aria-atomic": "true", role: "log", part: "announcements" }, this.ariaTextList.map((str) => (h("div", null, str)))), h("slot", null)));
|
637
|
+
}
|
638
|
+
get host() { return getElement(this); }
|
639
|
+
static get watchers() { return {
|
640
|
+
"itemSelector": ["handleItemSelectorChange"],
|
641
|
+
"handleSelector": ["handleHandleSelectorChange"],
|
642
|
+
"createKeyboardHandle": ["handleCreateKeyboardHandleChange"],
|
643
|
+
"sortableHostElement": ["handleSortableHostElement"]
|
644
|
+
}; }
|
645
|
+
};
|
646
|
+
Sortable.style = sortableCss;
|
647
|
+
|
648
|
+
export { Sortable as nano_sortable };
|
649
|
+
|
650
|
+
//# sourceMappingURL=nano-sortable.entry.js.map
|