@exmg/exm-sortable 1.1.36 → 1.1.37-alpha.31
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/.rollup.cache/root/repo/packages/exm-sortable/dist/exm-sortable-base.d.ts +100 -0
- package/.rollup.cache/root/repo/packages/exm-sortable/dist/exm-sortable-base.js +357 -0
- package/.rollup.cache/root/repo/packages/exm-sortable/dist/exm-sortable.d.ts +27 -0
- package/.rollup.cache/root/repo/packages/exm-sortable/dist/exm-sortable.js +29 -0
- package/.rollup.cache/root/repo/packages/exm-sortable/dist/index.d.ts +2 -0
- package/.rollup.cache/root/repo/packages/exm-sortable/dist/index.js +3 -0
- package/dist/exm-sortable-base.js +7 -5
- package/dist/exm-sortable.js +4 -2
- package/dist/index.js +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { PropertyValues } from 'lit';
|
|
2
|
+
import { ExmgElement } from '@exmg/lit-base/index.js';
|
|
3
|
+
export declare class SortableElementBase extends ExmgElement {
|
|
4
|
+
handleSelector?: string;
|
|
5
|
+
itemSelector: string;
|
|
6
|
+
/**
|
|
7
|
+
* Optionally is possible to pass node instance which is host of sortable elements otherwise host for sortable elements
|
|
8
|
+
* is `exm-sortable` itself.
|
|
9
|
+
* Note that style `sortableHostNode.style.position` will be set to `relative`
|
|
10
|
+
*/
|
|
11
|
+
sortableHostNode?: HTMLElement;
|
|
12
|
+
animationEnabled: boolean;
|
|
13
|
+
clonedClass: string;
|
|
14
|
+
draggedClass: string;
|
|
15
|
+
animationTiming: any;
|
|
16
|
+
orientation?: 'horizontal' | 'vertical';
|
|
17
|
+
private dragRequestPending;
|
|
18
|
+
private draggedElement?;
|
|
19
|
+
private draggedElementClone?;
|
|
20
|
+
private draggedElementOrigin?;
|
|
21
|
+
private sortableNodes;
|
|
22
|
+
private animatedElements;
|
|
23
|
+
private initialScrollTop;
|
|
24
|
+
private animationPromise?;
|
|
25
|
+
constructor();
|
|
26
|
+
connectedCallback(): void;
|
|
27
|
+
disconnectedCallback(): void;
|
|
28
|
+
protected updated(changedProperties: PropertyValues): void;
|
|
29
|
+
/**
|
|
30
|
+
* Get instance of sortable host.
|
|
31
|
+
* By default it is `exm-sortable` which can be overridden by property `sortableHostNode`
|
|
32
|
+
*/
|
|
33
|
+
private getSortableHost;
|
|
34
|
+
/**
|
|
35
|
+
* Tracks a pointer from touchstart/mousedown to touchend/mouseup. Note that the start state is fired following
|
|
36
|
+
* the first actual move event following a touchstart/mousedown.
|
|
37
|
+
*/
|
|
38
|
+
private handleTrack;
|
|
39
|
+
/**
|
|
40
|
+
* Initialized a drag and drop sequence if a child node was clicked that matches the itemSelector property. If a
|
|
41
|
+
* handleSelector is defined, a node matching this selector must be clicked instead.
|
|
42
|
+
*/
|
|
43
|
+
private trackStart;
|
|
44
|
+
/**
|
|
45
|
+
* Ends the drag and drop sequence.
|
|
46
|
+
*/
|
|
47
|
+
private trackEnd;
|
|
48
|
+
/**
|
|
49
|
+
* Moves the active node's clone to follow the pointer. The node that the clone intersects with (via hitTest) is
|
|
50
|
+
* the insert point for updated sorting.
|
|
51
|
+
*/
|
|
52
|
+
private trackMove;
|
|
53
|
+
private updateUserSelectStyle;
|
|
54
|
+
/**
|
|
55
|
+
* Fast and simple hit test to check whether the center of a node intersects with the rectangle of any of the
|
|
56
|
+
* given targets. Returns an array of matches.
|
|
57
|
+
*
|
|
58
|
+
* @param {HTMLElement} node
|
|
59
|
+
* @param {Array} targets
|
|
60
|
+
* @return {Array<HTMLElement>} matches
|
|
61
|
+
*/
|
|
62
|
+
private hitTest;
|
|
63
|
+
/**
|
|
64
|
+
* Returns a boolean indicating whether the node is currently in an animation.
|
|
65
|
+
*
|
|
66
|
+
* @param {HTMLElement} node
|
|
67
|
+
* @returns {boolean} isAnimating
|
|
68
|
+
*/
|
|
69
|
+
private isAnimating;
|
|
70
|
+
private reset;
|
|
71
|
+
/**
|
|
72
|
+
* Triggers a CSS animation on a node with the given dx and dy. Used following dom updates to make it appear as
|
|
73
|
+
* if nodes animate from their old to their new position in the dom.
|
|
74
|
+
*
|
|
75
|
+
* @param {Node} node
|
|
76
|
+
* @param {number} dx
|
|
77
|
+
* @param {number} dy
|
|
78
|
+
*/
|
|
79
|
+
private animateNode;
|
|
80
|
+
/**
|
|
81
|
+
* Inserts node at target to update sibling sorting. If the node precedes the target, it is inserted after it;
|
|
82
|
+
* If it follows the target, it is inserted before it. This ensures any node can be dragged from the very
|
|
83
|
+
* beginning to the very end and vice versa. The animateNode function is called for all nodes that moved because
|
|
84
|
+
* of this dom update.
|
|
85
|
+
*
|
|
86
|
+
* @param {Node} node
|
|
87
|
+
* @param {Node} target
|
|
88
|
+
*/
|
|
89
|
+
private insertAtTarget;
|
|
90
|
+
/**
|
|
91
|
+
* Clones a given node to visually drag around. The original node is left in the same flow as its siblings. Clone
|
|
92
|
+
* styles are added onto the style object directly, since the ::slotted() selector can't universally target nodes
|
|
93
|
+
* that may be nested an unknown amount of shadow dom levels deep.
|
|
94
|
+
*
|
|
95
|
+
* @param {HTMLElement} node
|
|
96
|
+
* @return {Node} clone
|
|
97
|
+
*/
|
|
98
|
+
private createClone;
|
|
99
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
100
|
+
}
|
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
|
+
import { html } from 'lit';
|
|
3
|
+
import { ExmgElement } from '@exmg/lit-base/index.js';
|
|
4
|
+
import { property } from 'lit/decorators.js';
|
|
5
|
+
import { gestures } from '@exmg/lit-base/index.js';
|
|
6
|
+
/**
|
|
7
|
+
* Orientation map to limit dragging to horizontal or vertical.
|
|
8
|
+
*/
|
|
9
|
+
const orientationMap = {
|
|
10
|
+
horizontal: { x: 1, y: 0 },
|
|
11
|
+
vertical: { x: 0, y: 1 },
|
|
12
|
+
};
|
|
13
|
+
export class SortableElementBase extends ExmgElement {
|
|
14
|
+
constructor() {
|
|
15
|
+
super();
|
|
16
|
+
this.itemSelector = 'li';
|
|
17
|
+
this.animationEnabled = false;
|
|
18
|
+
this.clonedClass = 'cloned';
|
|
19
|
+
this.draggedClass = 'dragged';
|
|
20
|
+
this.animationTiming = { duration: 200, easing: 'ease-out' };
|
|
21
|
+
this.dragRequestPending = false;
|
|
22
|
+
this.sortableNodes = [];
|
|
23
|
+
this.animatedElements = [];
|
|
24
|
+
this.initialScrollTop = 0;
|
|
25
|
+
/* Save function references */
|
|
26
|
+
this.handleTrack = this.handleTrack.bind(this);
|
|
27
|
+
}
|
|
28
|
+
connectedCallback() {
|
|
29
|
+
super.connectedCallback();
|
|
30
|
+
gestures.addListener(this.getSortableHost(), 'track', this.handleTrack);
|
|
31
|
+
}
|
|
32
|
+
disconnectedCallback() {
|
|
33
|
+
gestures.removeListener(this.getSortableHost(), 'track', this.handleTrack);
|
|
34
|
+
super.disconnectedCallback();
|
|
35
|
+
}
|
|
36
|
+
updated(changedProperties) {
|
|
37
|
+
if (changedProperties.has('sortableHostNode')) {
|
|
38
|
+
// reset listeners when sortableHostNode changed
|
|
39
|
+
gestures.removeListener(changedProperties.get('sortableHostNode') || this, 'track', this.handleTrack);
|
|
40
|
+
gestures.addListener(this.getSortableHost(), 'track', this.handleTrack);
|
|
41
|
+
if (this.sortableHostNode) {
|
|
42
|
+
// sortable host must have position relative
|
|
43
|
+
this.sortableHostNode.style.position = 'relative';
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Get instance of sortable host.
|
|
49
|
+
* By default it is `exm-sortable` which can be overridden by property `sortableHostNode`
|
|
50
|
+
*/
|
|
51
|
+
getSortableHost() {
|
|
52
|
+
if (this.sortableHostNode) {
|
|
53
|
+
return this.sortableHostNode;
|
|
54
|
+
}
|
|
55
|
+
return this;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Tracks a pointer from touchstart/mousedown to touchend/mouseup. Note that the start state is fired following
|
|
59
|
+
* the first actual move event following a touchstart/mousedown.
|
|
60
|
+
*/
|
|
61
|
+
handleTrack(e) {
|
|
62
|
+
switch (e.detail.state) {
|
|
63
|
+
case 'start':
|
|
64
|
+
if (!this.dragRequestPending) {
|
|
65
|
+
this.trackStart(e);
|
|
66
|
+
}
|
|
67
|
+
break;
|
|
68
|
+
case 'track':
|
|
69
|
+
this.trackMove(e);
|
|
70
|
+
break;
|
|
71
|
+
case 'end':
|
|
72
|
+
if (this.animationPromise) {
|
|
73
|
+
this.animationPromise.then(() => {
|
|
74
|
+
setTimeout(() => this.trackEnd());
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
setTimeout(() => this.trackEnd());
|
|
79
|
+
}
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Initialized a drag and drop sequence if a child node was clicked that matches the itemSelector property. If a
|
|
85
|
+
* handleSelector is defined, a node matching this selector must be clicked instead.
|
|
86
|
+
*/
|
|
87
|
+
trackStart(e) {
|
|
88
|
+
const handle = this.handleSelector;
|
|
89
|
+
const eventPath = e.path ? e.path : e.composedPath();
|
|
90
|
+
const targetElement = eventPath[0];
|
|
91
|
+
/* Look for closest handle */
|
|
92
|
+
if (handle && !targetElement.closest(handle)) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
this.updateUserSelectStyle('none');
|
|
96
|
+
this.dragRequestPending = true;
|
|
97
|
+
const selector = this.itemSelector;
|
|
98
|
+
const node = targetElement.closest(selector);
|
|
99
|
+
if (node) {
|
|
100
|
+
e.preventDefault();
|
|
101
|
+
this.draggedElement = node;
|
|
102
|
+
this.sortableNodes = Array.from(this.getSortableHost().querySelectorAll(selector)) || [];
|
|
103
|
+
this.draggedElementClone = this.createClone(node);
|
|
104
|
+
this.draggedElementOrigin = node.nextSibling;
|
|
105
|
+
this.animatedElements = [];
|
|
106
|
+
this.draggedElement.classList.add(this.draggedClass);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Ends the drag and drop sequence.
|
|
111
|
+
*/
|
|
112
|
+
trackEnd() {
|
|
113
|
+
if (!this.draggedElement) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
const updated = Array.from(this.getSortableHost().querySelectorAll(this.itemSelector));
|
|
117
|
+
const sourceIndex = this.sortableNodes.indexOf(this.draggedElement);
|
|
118
|
+
const targetIndex = updated.indexOf(this.draggedElement);
|
|
119
|
+
if (sourceIndex !== targetIndex) {
|
|
120
|
+
this.dispatchEvent(new CustomEvent('dom-order-change', {
|
|
121
|
+
bubbles: true,
|
|
122
|
+
composed: true,
|
|
123
|
+
detail: {
|
|
124
|
+
sourceIndex,
|
|
125
|
+
targetIndex,
|
|
126
|
+
},
|
|
127
|
+
}));
|
|
128
|
+
}
|
|
129
|
+
this.reset();
|
|
130
|
+
this.dragRequestPending = false;
|
|
131
|
+
this.updateUserSelectStyle('text');
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Moves the active node's clone to follow the pointer. The node that the clone intersects with (via hitTest) is
|
|
135
|
+
* the insert point for updated sorting.
|
|
136
|
+
*/
|
|
137
|
+
trackMove(e) {
|
|
138
|
+
e.preventDefault();
|
|
139
|
+
if (!this.draggedElementClone) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
let { dx, dy } = e.detail;
|
|
143
|
+
const scrollTop = Math.max(window.pageYOffset, document.documentElement.scrollTop, document.body.scrollTop);
|
|
144
|
+
if (this.orientation) {
|
|
145
|
+
dx = dx * orientationMap[this.orientation].x;
|
|
146
|
+
dy = dy * orientationMap[this.orientation].y;
|
|
147
|
+
}
|
|
148
|
+
/* Work around for issue with first element being party offscreen when drag start */
|
|
149
|
+
dy = dy - (this.initialScrollTop - scrollTop);
|
|
150
|
+
Object.assign(this.draggedElementClone.style, {
|
|
151
|
+
transform: `translate3d(${dx}px, ${dy}px, 0)`,
|
|
152
|
+
});
|
|
153
|
+
const target = this.hitTest(this.draggedElementClone, this.sortableNodes)[0];
|
|
154
|
+
if (
|
|
155
|
+
// if clone intersects with a valid target,
|
|
156
|
+
target &&
|
|
157
|
+
// other than its own origin,
|
|
158
|
+
target !== this.draggedElement &&
|
|
159
|
+
// and the target isn't currently animating, which causes false hit tests,
|
|
160
|
+
!this.isAnimating(target)) {
|
|
161
|
+
this.insertAtTarget(this.draggedElement, target);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
updateUserSelectStyle(userSelect) {
|
|
165
|
+
/**
|
|
166
|
+
* Firefox bug fix: when dragging elements in firefox, closest text also getting selected
|
|
167
|
+
*/
|
|
168
|
+
this.style.userSelect = userSelect;
|
|
169
|
+
this.style.MozUserSelect = userSelect;
|
|
170
|
+
// @ts-ignore
|
|
171
|
+
this.style.msUserSelect = userSelect;
|
|
172
|
+
this.style.webkitUserSelect = userSelect;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Fast and simple hit test to check whether the center of a node intersects with the rectangle of any of the
|
|
176
|
+
* given targets. Returns an array of matches.
|
|
177
|
+
*
|
|
178
|
+
* @param {HTMLElement} node
|
|
179
|
+
* @param {Array} targets
|
|
180
|
+
* @return {Array<HTMLElement>} matches
|
|
181
|
+
*/
|
|
182
|
+
hitTest(node, targets) {
|
|
183
|
+
const { left: l, top: t, width: w, height: h } = node.getBoundingClientRect();
|
|
184
|
+
const x = l + w / 2;
|
|
185
|
+
const y = t + h / 2;
|
|
186
|
+
return targets.filter((item) => {
|
|
187
|
+
const { left, right, top, bottom } = item.getBoundingClientRect();
|
|
188
|
+
return !(x < left || x > right || y < top || y > bottom);
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Returns a boolean indicating whether the node is currently in an animation.
|
|
193
|
+
*
|
|
194
|
+
* @param {HTMLElement} node
|
|
195
|
+
* @returns {boolean} isAnimating
|
|
196
|
+
*/
|
|
197
|
+
isAnimating(node) {
|
|
198
|
+
return this.animatedElements.indexOf(node) !== -1;
|
|
199
|
+
}
|
|
200
|
+
reset() {
|
|
201
|
+
if (this.draggedElementClone !== undefined && this.draggedElementClone.parentNode !== null) {
|
|
202
|
+
this.draggedElementClone.parentNode.removeChild(this.draggedElementClone);
|
|
203
|
+
}
|
|
204
|
+
if (this.draggedElement && this.draggedElement.parentNode && this.draggedElementOrigin) {
|
|
205
|
+
this.draggedElement.classList.remove(this.draggedClass);
|
|
206
|
+
this.draggedElement.parentNode.insertBefore(this.draggedElement, this.draggedElementOrigin);
|
|
207
|
+
}
|
|
208
|
+
delete this.draggedElementClone;
|
|
209
|
+
delete this.draggedElement;
|
|
210
|
+
this.sortableNodes = [];
|
|
211
|
+
this.animatedElements = [];
|
|
212
|
+
this.dragRequestPending = false;
|
|
213
|
+
this.updateUserSelectStyle('text');
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Triggers a CSS animation on a node with the given dx and dy. Used following dom updates to make it appear as
|
|
217
|
+
* if nodes animate from their old to their new position in the dom.
|
|
218
|
+
*
|
|
219
|
+
* @param {Node} node
|
|
220
|
+
* @param {number} dx
|
|
221
|
+
* @param {number} dy
|
|
222
|
+
*/
|
|
223
|
+
animateNode(node, dx = 0, dy = 0) {
|
|
224
|
+
if (!node.animate) {
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
// keep a stack of currently animating nodes to exclude as drag & drop targets.
|
|
228
|
+
this.animatedElements.push(node);
|
|
229
|
+
Object.assign(node.style, {
|
|
230
|
+
willChange: 'transform',
|
|
231
|
+
});
|
|
232
|
+
// animate from dx/dy (old node position) to none (new node position)
|
|
233
|
+
this.animationPromise = new Promise((resolve) => {
|
|
234
|
+
node
|
|
235
|
+
.animate([{ transform: `translate3d(${dx}px, ${dy}px, 0)` }, { transform: 'none' }], this.animationTiming)
|
|
236
|
+
.addEventListener('finish', () => {
|
|
237
|
+
const index = this.animatedElements.indexOf(node);
|
|
238
|
+
Object.assign(node.style, {
|
|
239
|
+
willChange: 'initial',
|
|
240
|
+
});
|
|
241
|
+
if (index !== -1) {
|
|
242
|
+
// splice out when done to unlock as a valid target
|
|
243
|
+
this.animatedElements.splice(index, 1);
|
|
244
|
+
}
|
|
245
|
+
resolve();
|
|
246
|
+
delete this.animationPromise;
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Inserts node at target to update sibling sorting. If the node precedes the target, it is inserted after it;
|
|
252
|
+
* If it follows the target, it is inserted before it. This ensures any node can be dragged from the very
|
|
253
|
+
* beginning to the very end and vice versa. The animateNode function is called for all nodes that moved because
|
|
254
|
+
* of this dom update.
|
|
255
|
+
*
|
|
256
|
+
* @param {Node} node
|
|
257
|
+
* @param {Node} target
|
|
258
|
+
*/
|
|
259
|
+
insertAtTarget(node, target) {
|
|
260
|
+
let offsets = [];
|
|
261
|
+
if (this.animationEnabled) {
|
|
262
|
+
offsets = this.sortableNodes.map((item) => ({
|
|
263
|
+
x: item.offsetLeft,
|
|
264
|
+
y: item.offsetTop,
|
|
265
|
+
}));
|
|
266
|
+
}
|
|
267
|
+
if (node && node.parentNode) {
|
|
268
|
+
const insert = node.compareDocumentPosition(target) & this.DOCUMENT_POSITION_FOLLOWING ? target.nextSibling : target;
|
|
269
|
+
node.parentNode.insertBefore(node, insert);
|
|
270
|
+
}
|
|
271
|
+
if (this.animationEnabled) {
|
|
272
|
+
this.sortableNodes.forEach((sortableNode, i) => {
|
|
273
|
+
const { x, y } = offsets[i];
|
|
274
|
+
const dx = x - sortableNode.offsetLeft;
|
|
275
|
+
const dy = y - sortableNode.offsetTop;
|
|
276
|
+
if (dx !== 0 || dy !== 0) {
|
|
277
|
+
this.animateNode(sortableNode, dx, dy);
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Clones a given node to visually drag around. The original node is left in the same flow as its siblings. Clone
|
|
284
|
+
* styles are added onto the style object directly, since the ::slotted() selector can't universally target nodes
|
|
285
|
+
* that may be nested an unknown amount of shadow dom levels deep.
|
|
286
|
+
*
|
|
287
|
+
* @param {HTMLElement} node
|
|
288
|
+
* @return {Node} clone
|
|
289
|
+
*/
|
|
290
|
+
createClone(node) {
|
|
291
|
+
const clone = node.cloneNode(true);
|
|
292
|
+
/**
|
|
293
|
+
* Bugfix for table row sorting.
|
|
294
|
+
* During dragging table rows shrink, so we manually set them width of original node.
|
|
295
|
+
*/
|
|
296
|
+
Array.from(clone.children).forEach((nodeChild, index) => {
|
|
297
|
+
const clonedNodeChild = nodeChild;
|
|
298
|
+
const originalNodeChild = node.children.item(index);
|
|
299
|
+
if (originalNodeChild) {
|
|
300
|
+
clonedNodeChild.style.width = `${originalNodeChild.offsetWidth}px`;
|
|
301
|
+
}
|
|
302
|
+
});
|
|
303
|
+
/**
|
|
304
|
+
* We have to copy all user defined properties manually.
|
|
305
|
+
* Lit element prefixes custom properties with '__' so that's why we check for it.
|
|
306
|
+
*/
|
|
307
|
+
Object.keys(node)
|
|
308
|
+
.filter((prop) => prop.startsWith('__'))
|
|
309
|
+
.forEach((prop) => (clone[prop] = node[prop]));
|
|
310
|
+
const { offsetLeft: x, offsetTop: y } = node;
|
|
311
|
+
this.initialScrollTop = Math.max(window.pageYOffset, document.documentElement.scrollTop, document.body.scrollTop);
|
|
312
|
+
Object.assign(clone.style, {
|
|
313
|
+
position: 'absolute',
|
|
314
|
+
left: `${x}px`,
|
|
315
|
+
top: `${y}px`,
|
|
316
|
+
willChange: 'transform,opacity',
|
|
317
|
+
});
|
|
318
|
+
clone.classList.add(this.clonedClass);
|
|
319
|
+
return node.parentNode.appendChild(clone);
|
|
320
|
+
}
|
|
321
|
+
render() {
|
|
322
|
+
return html `
|
|
323
|
+
<style>
|
|
324
|
+
:host {
|
|
325
|
+
position: relative;
|
|
326
|
+
display: block;
|
|
327
|
+
}
|
|
328
|
+
</style>
|
|
329
|
+
<slot></slot>
|
|
330
|
+
`;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
__decorate([
|
|
334
|
+
property({ type: String, attribute: 'handle-selector' })
|
|
335
|
+
], SortableElementBase.prototype, "handleSelector", void 0);
|
|
336
|
+
__decorate([
|
|
337
|
+
property({ type: String, attribute: 'item-selector' })
|
|
338
|
+
], SortableElementBase.prototype, "itemSelector", void 0);
|
|
339
|
+
__decorate([
|
|
340
|
+
property({ type: Object })
|
|
341
|
+
], SortableElementBase.prototype, "sortableHostNode", void 0);
|
|
342
|
+
__decorate([
|
|
343
|
+
property({ type: Boolean, attribute: 'animation-enabled' })
|
|
344
|
+
], SortableElementBase.prototype, "animationEnabled", void 0);
|
|
345
|
+
__decorate([
|
|
346
|
+
property({ type: String, attribute: 'cloned-class' })
|
|
347
|
+
], SortableElementBase.prototype, "clonedClass", void 0);
|
|
348
|
+
__decorate([
|
|
349
|
+
property({ type: String, attribute: 'dragged-class' })
|
|
350
|
+
], SortableElementBase.prototype, "draggedClass", void 0);
|
|
351
|
+
__decorate([
|
|
352
|
+
property({ type: Object, attribute: 'animation-timing' })
|
|
353
|
+
], SortableElementBase.prototype, "animationTiming", void 0);
|
|
354
|
+
__decorate([
|
|
355
|
+
property({ type: String })
|
|
356
|
+
], SortableElementBase.prototype, "orientation", void 0);
|
|
357
|
+
//# sourceMappingURL=exm-sortable-base.js.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { SortableElementBase } from './exm-sortable-base.js';
|
|
2
|
+
/**
|
|
3
|
+
* The `<exm-sortable>` element Enables drag and drop sorting of nodes in a list, table or any other set of
|
|
4
|
+
* elements.
|
|
5
|
+
*
|
|
6
|
+
* !!! You should always handle @dom-order-change to update your local .items property to update sorted list properly
|
|
7
|
+
*
|
|
8
|
+
* ```html
|
|
9
|
+
* <exm-sortable item-selector="li" @dom-order-change="${this.myChangeHandler}">
|
|
10
|
+
* <ul>
|
|
11
|
+
* ${this.items.map((item) => {
|
|
12
|
+
* return html`
|
|
13
|
+
* <li>${item}</li>
|
|
14
|
+
* `;
|
|
15
|
+
* })}
|
|
16
|
+
* </ul>
|
|
17
|
+
* </exm-sortable>
|
|
18
|
+
* ```
|
|
19
|
+
* @extends {SortableElementBase}
|
|
20
|
+
*/
|
|
21
|
+
export declare class SortableElement extends SortableElementBase {
|
|
22
|
+
}
|
|
23
|
+
declare global {
|
|
24
|
+
interface HTMLElementTagNameMap {
|
|
25
|
+
'exm-sortable': SortableElement;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
|
+
import { customElement } from 'lit/decorators.js';
|
|
3
|
+
import { SortableElementBase } from './exm-sortable-base.js';
|
|
4
|
+
/**
|
|
5
|
+
* The `<exm-sortable>` element Enables drag and drop sorting of nodes in a list, table or any other set of
|
|
6
|
+
* elements.
|
|
7
|
+
*
|
|
8
|
+
* !!! You should always handle @dom-order-change to update your local .items property to update sorted list properly
|
|
9
|
+
*
|
|
10
|
+
* ```html
|
|
11
|
+
* <exm-sortable item-selector="li" @dom-order-change="${this.myChangeHandler}">
|
|
12
|
+
* <ul>
|
|
13
|
+
* ${this.items.map((item) => {
|
|
14
|
+
* return html`
|
|
15
|
+
* <li>${item}</li>
|
|
16
|
+
* `;
|
|
17
|
+
* })}
|
|
18
|
+
* </ul>
|
|
19
|
+
* </exm-sortable>
|
|
20
|
+
* ```
|
|
21
|
+
* @extends {SortableElementBase}
|
|
22
|
+
*/
|
|
23
|
+
let SortableElement = class SortableElement extends SortableElementBase {
|
|
24
|
+
};
|
|
25
|
+
SortableElement = __decorate([
|
|
26
|
+
customElement('exm-sortable')
|
|
27
|
+
], SortableElement);
|
|
28
|
+
export { SortableElement };
|
|
29
|
+
//# sourceMappingURL=exm-sortable.js.map
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { __decorate } from
|
|
1
|
+
import { __decorate } from 'tslib';
|
|
2
2
|
import { html } from 'lit';
|
|
3
|
-
import { ExmgElement } from '@exmg/lit-base/index.js';
|
|
3
|
+
import { ExmgElement, gestures } from '@exmg/lit-base/index.js';
|
|
4
4
|
import { property } from 'lit/decorators.js';
|
|
5
|
-
|
|
5
|
+
|
|
6
6
|
/**
|
|
7
7
|
* Orientation map to limit dragging to horizontal or vertical.
|
|
8
8
|
*/
|
|
@@ -10,7 +10,7 @@ const orientationMap = {
|
|
|
10
10
|
horizontal: { x: 1, y: 0 },
|
|
11
11
|
vertical: { x: 0, y: 1 },
|
|
12
12
|
};
|
|
13
|
-
|
|
13
|
+
class SortableElementBase extends ExmgElement {
|
|
14
14
|
constructor() {
|
|
15
15
|
super();
|
|
16
16
|
this.itemSelector = 'li';
|
|
@@ -354,4 +354,6 @@ __decorate([
|
|
|
354
354
|
__decorate([
|
|
355
355
|
property({ type: String })
|
|
356
356
|
], SortableElementBase.prototype, "orientation", void 0);
|
|
357
|
-
|
|
357
|
+
|
|
358
|
+
export { SortableElementBase };
|
|
359
|
+
//# sourceMappingURL=exm-sortable-base.js.map
|
package/dist/exm-sortable.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { __decorate } from
|
|
1
|
+
import { __decorate } from 'tslib';
|
|
2
2
|
import { customElement } from 'lit/decorators.js';
|
|
3
3
|
import { SortableElementBase } from './exm-sortable-base.js';
|
|
4
|
+
|
|
4
5
|
/**
|
|
5
6
|
* The `<exm-sortable>` element Enables drag and drop sorting of nodes in a list, table or any other set of
|
|
6
7
|
* elements.
|
|
@@ -25,5 +26,6 @@ let SortableElement = class SortableElement extends SortableElementBase {
|
|
|
25
26
|
SortableElement = __decorate([
|
|
26
27
|
customElement('exm-sortable')
|
|
27
28
|
], SortableElement);
|
|
29
|
+
|
|
28
30
|
export { SortableElement };
|
|
29
|
-
//# sourceMappingURL=exm-sortable.js.map
|
|
31
|
+
//# sourceMappingURL=exm-sortable.js.map
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exmg/exm-sortable",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.37-alpha.31+513140a",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -39,5 +39,5 @@
|
|
|
39
39
|
"publishConfig": {
|
|
40
40
|
"access": "public"
|
|
41
41
|
},
|
|
42
|
-
"gitHead": "
|
|
42
|
+
"gitHead": "513140a59e3a5a9a0fa572147ba6c0cf9801816e"
|
|
43
43
|
}
|