uiik 1.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/index.esm.js ADDED
@@ -0,0 +1,1971 @@
1
+ /**
2
+ * uiik v1.0.0
3
+ * A UI interaction kit includes draggable, splittable, rotatable, selectable, etc.
4
+ * https://github.com/holyhigh2/uii
5
+ * c) 2021-2023 @holyhigh2 may be freely distributed under the MIT license
6
+ */
7
+ import { isArrayLike, isString, map, isElement, toArray, each, assign, reject, includes, isArray, isEmpty, call, isNumber, isFunction, isDefined, isUndefined, closest, some, compact, split, test, flatMap } from '@holyhigh/func.js';
8
+
9
+ /******************************************************************************
10
+ Copyright (c) Microsoft Corporation.
11
+
12
+ Permission to use, copy, modify, and/or distribute this software for any
13
+ purpose with or without fee is hereby granted.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
16
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
17
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
18
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
19
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
20
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
21
+ PERFORMANCE OF THIS SOFTWARE.
22
+ ***************************************************************************** */
23
+
24
+ function __classPrivateFieldGet(receiver, state, kind, f) {
25
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
26
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
27
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
28
+ }
29
+
30
+ function __classPrivateFieldSet(receiver, state, value, kind, f) {
31
+ if (kind === "m") throw new TypeError("Private method is not writable");
32
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
33
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
34
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
35
+ }
36
+
37
+ var _Uii_listeners;
38
+ /**
39
+ * A Base class for all Uii classes
40
+ */
41
+ class Uii {
42
+ constructor(ele, opts) {
43
+ this.enabled = true;
44
+ _Uii_listeners.set(this, []);
45
+ this.opts = opts || {};
46
+ if (isArrayLike(ele) && !isString(ele)) {
47
+ this.ele = map(ele, (el) => {
48
+ let e = isString(el) ? document.querySelector(el) : el;
49
+ if (!isElement(e)) {
50
+ console.error('Invalid element "' + el + '"');
51
+ return false;
52
+ }
53
+ return e;
54
+ });
55
+ }
56
+ else {
57
+ const el = isString(ele) ? document.querySelectorAll(ele) : ele;
58
+ if (!isElement(el) && !isArrayLike(el)) {
59
+ console.error('Invalid element "' + ele + '"');
60
+ return;
61
+ }
62
+ this.ele = isArrayLike(el) ? toArray(el) : [el];
63
+ }
64
+ }
65
+ /**
66
+ * 销毁uii对象,包括卸载事件、清空元素等
67
+ */
68
+ destroy() {
69
+ each(__classPrivateFieldGet(this, _Uii_listeners, "f"), ev => {
70
+ ev[0].removeEventListener(ev[1], ev[2], ev[3]);
71
+ });
72
+ __classPrivateFieldSet(this, _Uii_listeners, [], "f");
73
+ }
74
+ /**
75
+ * 注册事件,以便在{@link destroy}方法中卸载
76
+ * @param el dom元素
77
+ * @param event 事件名
78
+ * @param hook 回调函数
79
+ * @param useCapture 默认false
80
+ */
81
+ registerEvent(el, event, hook, useCapture = false) {
82
+ const wrapper = ((ev) => {
83
+ if (!this.enabled)
84
+ return;
85
+ hook(ev);
86
+ }).bind(this);
87
+ el.addEventListener(event, wrapper, useCapture);
88
+ __classPrivateFieldGet(this, _Uii_listeners, "f").push([el, event, wrapper, useCapture]);
89
+ }
90
+ /**
91
+ * 禁用uii实例,禁用后的dom不会响应事件
92
+ */
93
+ disable() {
94
+ this.enabled = false;
95
+ }
96
+ /**
97
+ * 启用uii实例
98
+ */
99
+ enable() {
100
+ this.enabled = true;
101
+ }
102
+ /**
103
+ * 获取指定名称的选项值
104
+ * @param name
105
+ * @returns
106
+ */
107
+ getOption(name) {
108
+ return name ? this.opts[name] : this.opts;
109
+ }
110
+ /**
111
+ * 一次设置多个选项值。触发`onOptionChanged`
112
+ * @param options
113
+ */
114
+ setOptions(options) {
115
+ assign(this.opts, options);
116
+ this.onOptionChanged(this.opts);
117
+ }
118
+ /**
119
+ * 设置指定name的选项值。触发`onOptionChanged`
120
+ * @param name
121
+ * @param value
122
+ */
123
+ setOption(name, value) {
124
+ this.opts[name] = value;
125
+ this.onOptionChanged(this.opts);
126
+ }
127
+ /**
128
+ * @internal
129
+ */
130
+ onOptionChanged(opts) {
131
+ }
132
+ }
133
+ _Uii_listeners = new WeakMap();
134
+
135
+ /* eslint-disable max-len */
136
+ /**
137
+ * 工具包
138
+ * @author holyhigh2
139
+ */
140
+ /**
141
+ * 获取child相对于parent的offset信息。含border宽度
142
+ * @returns
143
+ */
144
+ function getOffset(child, parent) {
145
+ const rs = { x: 0, y: 0 };
146
+ let op = child.offsetParent;
147
+ while (op && parent && op !== parent) {
148
+ const style = window.getComputedStyle(op);
149
+ rs.x += op.offsetLeft + parseFloat(style.borderLeftWidth);
150
+ rs.y += op.offsetTop + parseFloat(style.borderTopWidth);
151
+ op = op.offsetParent;
152
+ }
153
+ rs.x += child.offsetLeft;
154
+ rs.y += child.offsetTop;
155
+ return rs;
156
+ }
157
+ /**
158
+ * 边缘检测最小内部边距
159
+ */
160
+ const EDGE_THRESHOLD = 5;
161
+ const DRAGGING_RULE = "body * { pointer-events: none; }";
162
+ function lockPage() {
163
+ document.styleSheets[0].insertRule(DRAGGING_RULE, 0);
164
+ }
165
+ function unlockPage() {
166
+ document.styleSheets[0].deleteRule(0);
167
+ }
168
+
169
+ var _Splittable_instances, _Splittable_checkDirection, _Splittable_bindHandle;
170
+ const THRESHOLD$3 = 1;
171
+ const CLASS_SPLITTABLE = "uii-splittable";
172
+ const CLASS_SPLITTABLE_HANDLE = "uii-splittable-handle";
173
+ const CLASS_SPLITTABLE_HANDLE_GHOST = "uii-splittable-handle-ghost";
174
+ const CLASS_SPLITTABLE_HANDLE_ACTIVE = "uii-splittable-handle-active";
175
+ const CLASS_SPLITTABLE_V = "uii-splittable-v";
176
+ const CLASS_SPLITTABLE_H = "uii-splittable-h";
177
+ function getRootEl(el, root) {
178
+ let rs = el.parentNode;
179
+ while (rs && rs.parentNode !== root) {
180
+ rs = rs.parentNode;
181
+ }
182
+ return rs;
183
+ }
184
+ /**
185
+ * 用于表示一个或多个分割器的定义
186
+ * > 可用CSS接口
187
+ * - .uii-splittable
188
+ * - .uii-splittable-handle
189
+ * - .uii-splittable-handle-ghost
190
+ * - .uii-splittable-handle-active
191
+ * - .uii-splittable-v
192
+ * - .uii-splittable-h
193
+ * @public
194
+ */
195
+ class Splittable extends Uii {
196
+ constructor(container, opts) {
197
+ super(container, assign({
198
+ handleSize: 10,
199
+ minSize: 0,
200
+ sticky: false,
201
+ inside: false,
202
+ ghost: false
203
+ }, opts));
204
+ _Splittable_instances.add(this);
205
+ const con = this.ele[0];
206
+ //detect container position
207
+ const pos = window.getComputedStyle(con).position;
208
+ if (pos === "static") {
209
+ con.style.position = "relative";
210
+ }
211
+ con.classList.toggle(CLASS_SPLITTABLE, true);
212
+ const handleDoms = con.querySelectorAll(this.opts.handle);
213
+ const children = reject(con.children, c => {
214
+ if (includes(handleDoms, c))
215
+ return true;
216
+ return false;
217
+ });
218
+ const dir = __classPrivateFieldGet(this, _Splittable_instances, "m", _Splittable_checkDirection).call(this, con);
219
+ con.classList.toggle(dir === 'v' ? CLASS_SPLITTABLE_V : CLASS_SPLITTABLE_H, true);
220
+ const minSizeAry = map(children, (c, i) => {
221
+ if (isArray(this.opts.minSize)) {
222
+ return this.opts.minSize[i] || 0;
223
+ }
224
+ else {
225
+ return this.opts.minSize;
226
+ }
227
+ });
228
+ const stickyAry = map(children, (c, i) => {
229
+ if (isArray(this.opts.sticky)) {
230
+ return this.opts.sticky[i] || false;
231
+ }
232
+ else {
233
+ return this.opts.sticky;
234
+ }
235
+ });
236
+ if (isEmpty(handleDoms)) {
237
+ const len = children.length - 1;
238
+ for (let i = 0; i < len; i++) {
239
+ __classPrivateFieldGet(this, _Splittable_instances, "m", _Splittable_bindHandle).call(this, minSizeAry.slice(i, i + 2), stickyAry.slice(i, i + 2), this.opts, dir, children[i], children[i + 1]);
240
+ }
241
+ }
242
+ else {
243
+ each(handleDoms, (h, i) => {
244
+ const isRoot = h.parentNode.classList.contains(CLASS_SPLITTABLE);
245
+ let dom1, dom2;
246
+ if (isRoot) {
247
+ dom1 = h.previousElementSibling;
248
+ dom2 = h.nextElementSibling;
249
+ }
250
+ else {
251
+ dom2 = getRootEl(h, con);
252
+ dom1 = dom2.previousElementSibling;
253
+ }
254
+ __classPrivateFieldGet(this, _Splittable_instances, "m", _Splittable_bindHandle).call(this, minSizeAry.slice(i, i + 2), stickyAry.slice(i, i + 2), this.opts, dir, dom1, dom2, h);
255
+ });
256
+ }
257
+ }
258
+ }
259
+ _Splittable_instances = new WeakSet(), _Splittable_checkDirection = function _Splittable_checkDirection(container) {
260
+ let dir = 'h';
261
+ const child = container.children[0];
262
+ let lastY = child.offsetTop;
263
+ each(container.children, c => {
264
+ if (c.offsetTop != lastY) {
265
+ dir = 'v';
266
+ return false;
267
+ }
268
+ });
269
+ return dir;
270
+ }, _Splittable_bindHandle = function _Splittable_bindHandle(minSizeAry, stickyAry, opts, dir, dom1, dom2, handle) {
271
+ var _a;
272
+ const handleSize = opts.handleSize;
273
+ if (!handle) {
274
+ handle = document.createElement('div');
275
+ let initPos = 0;
276
+ if (!opts.inside) {
277
+ initPos = (dir === 'v' ? dom2.offsetTop : dom2.offsetLeft);
278
+ }
279
+ const sensorHCss = `width:${handleSize}px;height:100%;top:0;left:${initPos - handleSize / 2}px;z-index:9;`;
280
+ const sensorVCss = `height:${handleSize}px;width:100%;left:0;top:${initPos - handleSize / 2}px;z-index:9;`;
281
+ handle.style.cssText =
282
+ 'position: absolute;' + (dir === 'v' ? sensorVCss : sensorHCss);
283
+ if (opts.inside) {
284
+ dom2.appendChild(handle);
285
+ }
286
+ (_a = dom2.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(handle, dom2);
287
+ }
288
+ handle.style.cursor = dir === 'v' ? 's-resize' : 'e-resize';
289
+ handle.dataset.cursor = handle.style.cursor;
290
+ handle.classList.add(CLASS_SPLITTABLE_HANDLE);
291
+ const minSize1 = minSizeAry[0];
292
+ const minSize2 = minSizeAry[1];
293
+ let sticky1 = stickyAry[0];
294
+ let sticky2 = stickyAry[1];
295
+ const onStart = opts.onStart;
296
+ const onSplit = opts.onSplit;
297
+ const onEnd = opts.onEnd;
298
+ const onSticky = opts.onSticky;
299
+ const onClone = opts.onClone;
300
+ const oneSideMode = opts.oneSideMode;
301
+ const updateStart = !oneSideMode || oneSideMode === 'start';
302
+ const updateEnd = !oneSideMode || oneSideMode === 'end';
303
+ handle.onmousedown = function (e) {
304
+ // 1. 获取原始高度/宽度;设置宽度/高度
305
+ let originSize = 0;
306
+ let originSize1 = 0;
307
+ const originPosX = e.clientX;
308
+ const originPosY = e.clientY;
309
+ let splitterSize = 1;
310
+ let blockSize = 0; // 分割区size
311
+ switch (dir) {
312
+ case 'v':
313
+ originSize = dom1.offsetHeight;
314
+ originSize1 = dom2.offsetHeight;
315
+ splitterSize = handle.offsetHeight;
316
+ break;
317
+ case 'h':
318
+ originSize = dom1.offsetWidth;
319
+ originSize1 = dom2.offsetWidth;
320
+ splitterSize = handle.offsetWidth;
321
+ break;
322
+ }
323
+ blockSize = splitterSize + originSize + originSize1;
324
+ const dom1Style = dom1.style;
325
+ const dom2Style = dom2.style;
326
+ //ghost
327
+ const ghost = opts.ghost;
328
+ const ghostClass = opts.ghostClass;
329
+ let ghostNode = null;
330
+ // 初始化sticked位置
331
+ let sticked = 'none';
332
+ if (originSize < minSize1 / 2) {
333
+ sticked = 'start';
334
+ }
335
+ else if (blockSize - originSize - splitterSize < minSize2 / 2) {
336
+ sticked = 'end';
337
+ }
338
+ let dragging = false;
339
+ let bodyCursor = document.body.style.cursor;
340
+ let startPos = dir === 'v' ? dom1.offsetTop : dom1.offsetLeft;
341
+ let ds1, anotherSize;
342
+ const dragListener = (ev) => {
343
+ var _a;
344
+ const offsetx = ev.clientX - originPosX;
345
+ const offsety = ev.clientY - originPosY;
346
+ if (!dragging) {
347
+ if (Math.abs(offsetx) > THRESHOLD$3 || Math.abs(offsety) > THRESHOLD$3) {
348
+ dragging = true;
349
+ handle === null || handle === void 0 ? void 0 : handle.classList.add(CLASS_SPLITTABLE_HANDLE_ACTIVE);
350
+ if (ghost) {
351
+ ghostNode = handle.cloneNode(true);
352
+ ghostNode.style.opacity = '0.3';
353
+ ghostNode.style.pointerEvents = 'none';
354
+ ghostNode.classList.add(CLASS_SPLITTABLE_HANDLE_GHOST);
355
+ if (ghostNode) {
356
+ if (ghostClass) {
357
+ ghostNode.className =
358
+ ghostNode.className.replace(ghostClass, '') + ' ' + ghostClass;
359
+ }
360
+ (_a = handle === null || handle === void 0 ? void 0 : handle.parentNode) === null || _a === void 0 ? void 0 : _a.appendChild(ghostNode);
361
+ call(onClone, ghostNode, e);
362
+ }
363
+ }
364
+ lockPage();
365
+ document.body.style.cursor = (handle === null || handle === void 0 ? void 0 : handle.dataset.cursor) || '';
366
+ call(onStart, originSize, originSize1);
367
+ }
368
+ else {
369
+ ev.preventDefault();
370
+ return false;
371
+ }
372
+ }
373
+ let doSticky = false;
374
+ ds1 = dir === 'v' ? originSize + offsety : originSize + offsetx;
375
+ if (ds1 < minSize1 / 2 && sticky1 && minSize1 > 0) {
376
+ if (sticked == 'none') {
377
+ doSticky = true;
378
+ sticked = 'start';
379
+ }
380
+ ds1 = 0;
381
+ }
382
+ else if (ds1 < minSize1) {
383
+ ds1 = minSize1;
384
+ if (sticked == 'start' && sticky1) {
385
+ // 重置状态
386
+ doSticky = true;
387
+ sticked = 'none';
388
+ }
389
+ }
390
+ else if (blockSize - ds1 - splitterSize < minSize2 / 2 &&
391
+ sticky2) {
392
+ if (sticked == 'none') {
393
+ doSticky = true;
394
+ sticked = 'end';
395
+ }
396
+ ds1 = blockSize - splitterSize;
397
+ }
398
+ else if (blockSize - ds1 - splitterSize < minSize2) {
399
+ ds1 = blockSize - minSize2 - splitterSize;
400
+ if (sticked == 'end' && sticky2) {
401
+ // 重置状态
402
+ doSticky = true;
403
+ sticked = 'none';
404
+ }
405
+ }
406
+ anotherSize = blockSize - ds1 - splitterSize;
407
+ if (ghostNode) {
408
+ if (dir === 'v') {
409
+ ghostNode.style.top = startPos + ds1 - handleSize / 2 + 'px';
410
+ }
411
+ else {
412
+ ghostNode.style.left = startPos + ds1 - handleSize / 2 + 'px';
413
+ }
414
+ }
415
+ else {
416
+ const updateProp = dir === 'v' ? 'height' : 'width';
417
+ if (updateStart) {
418
+ dom1Style.setProperty(updateProp, ds1 + 'px', 'important');
419
+ }
420
+ if (updateEnd) {
421
+ dom2Style.setProperty(updateProp, anotherSize + 'px', 'important');
422
+ }
423
+ if (doSticky) {
424
+ call(onSticky, ds1, anotherSize, sticked);
425
+ }
426
+ //update handle
427
+ if (dir === 'v') {
428
+ handle.style.top = dom2.offsetTop - handleSize / 2 + 'px';
429
+ }
430
+ else {
431
+ handle.style.left = dom2.offsetLeft - handleSize / 2 + 'px';
432
+ }
433
+ }
434
+ call(onSplit, ds1, anotherSize);
435
+ ev.preventDefault();
436
+ return false;
437
+ };
438
+ const dragEndListener = (ev) => {
439
+ var _a;
440
+ document.removeEventListener('mousemove', dragListener, false);
441
+ document.removeEventListener('mouseup', dragEndListener, false);
442
+ window.removeEventListener('blur', dragEndListener, false);
443
+ if (dragging) {
444
+ switch (dir) {
445
+ case 'v':
446
+ originSize = (dom1 === null || dom1 === void 0 ? void 0 : dom1.offsetHeight) || -1;
447
+ originSize1 = (dom2 === null || dom2 === void 0 ? void 0 : dom2.offsetHeight) || -1;
448
+ break;
449
+ case 'h':
450
+ originSize = (dom1 === null || dom1 === void 0 ? void 0 : dom1.offsetWidth) || -1;
451
+ originSize1 = (dom2 === null || dom2 === void 0 ? void 0 : dom2.offsetWidth) || -1;
452
+ break;
453
+ }
454
+ handle === null || handle === void 0 ? void 0 : handle.classList.remove(CLASS_SPLITTABLE_HANDLE_ACTIVE);
455
+ if (ghostNode) {
456
+ const updateProp = dir === 'v' ? 'height' : 'width';
457
+ if (updateStart) {
458
+ dom1Style.setProperty(updateProp, ds1 + 'px', 'important');
459
+ }
460
+ if (updateEnd) {
461
+ dom2Style.setProperty(updateProp, anotherSize + 'px', 'important');
462
+ }
463
+ //update handle
464
+ if (dir === 'v') {
465
+ handle.style.top = startPos + ds1 - handleSize / 2 + 'px';
466
+ }
467
+ else {
468
+ handle.style.left = startPos + ds1 - handleSize / 2 + 'px';
469
+ }
470
+ (_a = ghostNode.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(ghostNode);
471
+ }
472
+ unlockPage();
473
+ document.body.style.cursor = bodyCursor;
474
+ call(onEnd, originSize, originSize1);
475
+ }
476
+ };
477
+ document.addEventListener('mousemove', dragListener, false);
478
+ document.addEventListener('mouseup', dragEndListener, false);
479
+ window.addEventListener('blur', dragEndListener, false);
480
+ e.preventDefault();
481
+ return false;
482
+ };
483
+ };
484
+ /**
485
+ * Add one or more splittors into the container
486
+ * @param container css selector or html element
487
+ * @param opts SplittableOptions
488
+ * @returns
489
+ */
490
+ function newSplittable(container, opts) {
491
+ return new Splittable(container, opts);
492
+ }
493
+
494
+ /* eslint-disable max-len */
495
+ const THRESHOLD$2 = 2;
496
+ const CLASS_RESIZABLE_HANDLE = "uii-resizable-handle";
497
+ const CLASS_RESIZABLE_HANDLE_DIR = "uii-resizable-handle-";
498
+ const CLASS_RESIZABLE_HANDLE_ACTIVE = "uii-resizable-handle-active";
499
+ /**
500
+ * 用于表示一个或多个可改变尺寸元素的定义
501
+ * > 可用CSS接口
502
+ * - .uii-resizable-handle
503
+ * - .uii-resizable-handle-[n/s/e/w/ne/nw/se/sw]
504
+ * - .uii-resizable-handle-active
505
+ * @public
506
+ */
507
+ class Resizable extends Uii {
508
+ constructor(els, opts) {
509
+ super(els, assign({
510
+ handleSize: 8,
511
+ minSize: 50,
512
+ dir: ['n', 's', 'e', 'w', 'ne', 'nw', 'se', 'sw'],
513
+ ghost: false,
514
+ offset: 0
515
+ }, opts));
516
+ each(this.ele, (el) => {
517
+ initHandle$1(el, this.opts);
518
+ });
519
+ }
520
+ }
521
+ function bindHandle$1(handle, dir, panel, opts) {
522
+ const onStart = opts.onStart;
523
+ const onResize = opts.onResize;
524
+ const onEnd = opts.onEnd;
525
+ const onClone = opts.onClone;
526
+ handle.onmousedown = function (e) {
527
+ // 获取panel当前信息
528
+ const originW = panel.offsetWidth;
529
+ const originH = panel.offsetHeight;
530
+ const originX = panel.offsetLeft;
531
+ const originY = panel.offsetTop;
532
+ let changeW = false;
533
+ let changeH = false;
534
+ let changeX = false;
535
+ let changeY = false;
536
+ switch (dir) {
537
+ case 's':
538
+ changeH = true;
539
+ break;
540
+ case 'e':
541
+ changeW = true;
542
+ break;
543
+ case 'n':
544
+ changeY = true;
545
+ changeH = true;
546
+ break;
547
+ case 'w':
548
+ changeX = true;
549
+ changeW = true;
550
+ break;
551
+ case 'se':
552
+ changeW = true;
553
+ changeH = true;
554
+ break;
555
+ case 'sw':
556
+ changeX = true;
557
+ changeW = true;
558
+ changeH = true;
559
+ break;
560
+ case 'ne':
561
+ changeY = true;
562
+ changeW = true;
563
+ changeH = true;
564
+ break;
565
+ case 'nw':
566
+ changeX = true;
567
+ changeY = true;
568
+ changeW = true;
569
+ changeH = true;
570
+ break;
571
+ }
572
+ const originPosX = e.clientX;
573
+ const originPosY = e.clientY;
574
+ // boundary
575
+ let minWidth;
576
+ let minHeight;
577
+ let maxWidth;
578
+ let maxHeight;
579
+ if (isArray(opts.minSize)) {
580
+ minWidth = opts.minSize[0];
581
+ minHeight = opts.minSize[1];
582
+ }
583
+ else if (isNumber(opts.minSize)) {
584
+ minWidth = opts.minSize;
585
+ minHeight = opts.minSize;
586
+ }
587
+ if (isArray(opts.maxSize)) {
588
+ maxWidth = opts.maxSize[0];
589
+ maxHeight = opts.maxSize[1];
590
+ }
591
+ else if (isNumber(opts.maxSize)) {
592
+ maxWidth = opts.maxSize;
593
+ maxHeight = opts.maxSize;
594
+ }
595
+ const minX = maxWidth ? originX - maxWidth + originW : null;
596
+ const minY = maxHeight ? originY - maxHeight + originH : null;
597
+ const maxX = minWidth ? originX + originW - minWidth : null;
598
+ const maxY = minHeight ? originY + originH - minHeight : null;
599
+ //ghost
600
+ const ghost = opts.ghost;
601
+ const ghostClass = opts.ghostClass;
602
+ let ghostNode = null;
603
+ //aspectRatio
604
+ const aspectRatio = opts.aspectRatio;
605
+ const panelStyle = panel.style;
606
+ let style = panelStyle;
607
+ let currentW = originW;
608
+ let currentH = originH;
609
+ let dragging = false;
610
+ let bodyCursor = document.body.style.cursor;
611
+ const dragListener = (ev) => {
612
+ var _a;
613
+ const offsetx = ev.clientX - originPosX;
614
+ const offsety = ev.clientY - originPosY;
615
+ if (!dragging) {
616
+ if (Math.abs(offsetx) > THRESHOLD$2 || Math.abs(offsety) > THRESHOLD$2) {
617
+ dragging = true;
618
+ handle.classList.add(CLASS_RESIZABLE_HANDLE_ACTIVE);
619
+ if (ghost) {
620
+ if (isFunction(ghost)) {
621
+ ghostNode = ghost();
622
+ }
623
+ else {
624
+ ghostNode = panel.cloneNode(true);
625
+ ghostNode.style.opacity = '0.3';
626
+ ghostNode.style.pointerEvents = 'none';
627
+ }
628
+ if (ghostNode) {
629
+ if (ghostClass) {
630
+ ghostNode.className =
631
+ ghostNode.className.replace(ghostClass, '') + ' ' + ghostClass;
632
+ }
633
+ (_a = panel.parentNode) === null || _a === void 0 ? void 0 : _a.appendChild(ghostNode);
634
+ call(onClone, ghostNode, e);
635
+ }
636
+ style = ghostNode === null || ghostNode === void 0 ? void 0 : ghostNode.style;
637
+ }
638
+ lockPage();
639
+ document.body.style.cursor = handle.dataset.cursor || '';
640
+ call(onStart, originW, originH);
641
+ }
642
+ else {
643
+ ev.preventDefault();
644
+ return false;
645
+ }
646
+ }
647
+ let w = originW;
648
+ let h = originH;
649
+ let y = originY;
650
+ let x = originX;
651
+ if (changeW) {
652
+ w = originW + offsetx * (changeX ? -1 : 1);
653
+ if (minWidth && w < minWidth)
654
+ w = minWidth;
655
+ if (maxWidth && w > maxWidth)
656
+ w = maxWidth;
657
+ }
658
+ if (changeH) {
659
+ h = originH + offsety * (changeY ? -1 : 1);
660
+ if (minHeight && h < minHeight)
661
+ h = minHeight;
662
+ if (maxHeight && h > maxHeight)
663
+ h = maxHeight;
664
+ }
665
+ if (changeY) {
666
+ y = originY + offsety;
667
+ if (minY && y < minY)
668
+ y = minY;
669
+ if (maxY && y > maxY)
670
+ y = maxY;
671
+ }
672
+ if (changeX) {
673
+ x = originX + offsetx;
674
+ if (minX && x < minX)
675
+ x = minX;
676
+ if (maxX && x > maxX)
677
+ x = maxX;
678
+ }
679
+ if (aspectRatio) {
680
+ if (changeW) {
681
+ style.width = w + 'px';
682
+ style.height = w / aspectRatio + 'px';
683
+ }
684
+ if (changeH && dir !== 'sw') {
685
+ if (dir === 'nw') {
686
+ y = originY - w / aspectRatio + originH;
687
+ }
688
+ else {
689
+ style.width = h * aspectRatio + 'px';
690
+ style.height = h + 'px';
691
+ }
692
+ }
693
+ }
694
+ else {
695
+ if (changeW) {
696
+ style.width = w + 'px';
697
+ }
698
+ if (changeH) {
699
+ style.height = h + 'px';
700
+ }
701
+ }
702
+ if (changeY) {
703
+ style.top = y + 'px';
704
+ }
705
+ if (changeX) {
706
+ style.left = x + 'px';
707
+ }
708
+ currentW = w;
709
+ currentH = h;
710
+ call(onResize, w, h);
711
+ ev.preventDefault();
712
+ return false;
713
+ };
714
+ const dragEndListener = (ev) => {
715
+ var _a;
716
+ document.removeEventListener('mousemove', dragListener, false);
717
+ document.removeEventListener('mouseup', dragEndListener, false);
718
+ window.removeEventListener('blur', dragEndListener, false);
719
+ if (ghost && ghostNode) {
720
+ (_a = panel.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(ghostNode);
721
+ panelStyle.left = ghostNode.style.left;
722
+ panelStyle.top = ghostNode.style.top;
723
+ panelStyle.width = ghostNode.style.width;
724
+ panelStyle.height = ghostNode.style.height;
725
+ }
726
+ handle.classList.remove(CLASS_RESIZABLE_HANDLE_ACTIVE);
727
+ unlockPage();
728
+ document.body.style.cursor = bodyCursor;
729
+ call(onEnd, currentW, currentH);
730
+ };
731
+ document.addEventListener('mousemove', dragListener, false);
732
+ document.addEventListener('mouseup', dragEndListener, false);
733
+ window.addEventListener('blur', dragEndListener, false);
734
+ e.preventDefault();
735
+ return false;
736
+ };
737
+ }
738
+ function initHandle$1(panel, opts) {
739
+ // create handles
740
+ const handleSize = opts.handleSize;
741
+ const offset = opts.offset || 0;
742
+ each(opts.dir || ['n', 's', 'e', 'w', 'ne', 'nw', 'se', 'sw'], (dir) => {
743
+ const handle = document.createElement('div');
744
+ handle.classList.add(CLASS_RESIZABLE_HANDLE, CLASS_RESIZABLE_HANDLE_DIR + dir);
745
+ handle.setAttribute('name', 'handle');
746
+ let css = '';
747
+ switch (dir) {
748
+ case 'n':
749
+ css = `left:0px;top:${-offset}px;width:100%;height:${handleSize}px;`;
750
+ break;
751
+ case 's':
752
+ css = `left:0px;bottom:${-offset}px;width:100%;height:${handleSize}px;`;
753
+ break;
754
+ case 'w':
755
+ css = `top:0px;left:${-offset}px;width:${handleSize}px;height:100%;`;
756
+ break;
757
+ case 'e':
758
+ css = `top:0px;right:${-offset}px;width:${handleSize}px;height:100%;`;
759
+ break;
760
+ default:
761
+ css = `width:${handleSize}px;height:${handleSize}px;z-index:9;`;
762
+ switch (dir) {
763
+ case 'ne':
764
+ css += `top:${-offset}px;right:${-offset}px;`;
765
+ break;
766
+ case 'nw':
767
+ css += `top:${-offset}px;left:${-offset}px;`;
768
+ break;
769
+ case 'se':
770
+ css += `bottom:${-offset}px;right:${-offset}px;`;
771
+ break;
772
+ case 'sw':
773
+ css += `bottom:${-offset}px;left:${-offset}px;`;
774
+ }
775
+ }
776
+ bindHandle$1(handle, dir, panel, opts);
777
+ handle.style.cssText = `position: absolute;cursor: ${dir}-resize;` + css;
778
+ handle.dataset.cursor = `${dir}-resize`;
779
+ panel.appendChild(handle);
780
+ });
781
+ }
782
+ /**
783
+ * Make els resizable
784
+ * @param els selector string / html element
785
+ * @param opts
786
+ * @returns
787
+ */
788
+ function newResizable(els, opts) {
789
+ return new Resizable(els, opts);
790
+ }
791
+
792
+ var _Draggable_handleMap;
793
+ const DRAGGER_GROUPS = {};
794
+ const CLASS_DRAGGABLE = "uii-draggable";
795
+ const CLASS_DRAGGABLE_HANDLE = "uii-draggable-handle";
796
+ const CLASS_DRAGGABLE_ACTIVE = "uii-draggable-active";
797
+ const CLASS_DRAGGABLE_GHOST = "uii-draggable-ghost";
798
+ /**
799
+ * 用于表示一个或多个可拖动元素的定义
800
+ * > 可用CSS接口
801
+ * - .uii-draggable
802
+ * - .uii-draggable-handle
803
+ * - .uii-draggable-active
804
+ * - .uii-draggable-ghost
805
+ * @public
806
+ */
807
+ class Draggable extends Uii {
808
+ constructor(els, opts) {
809
+ super(els, assign({
810
+ container: false,
811
+ threshold: 0,
812
+ ghost: false,
813
+ direction: "",
814
+ scroll: true,
815
+ snapOptions: {
816
+ tolerance: 10,
817
+ }
818
+ }, opts));
819
+ _Draggable_handleMap.set(this, new WeakMap());
820
+ if (this.opts.handle) {
821
+ each(this.ele, (el) => {
822
+ const h = el.querySelector(this.opts.handle);
823
+ if (!h) {
824
+ console.error('No handle found "' + this.opts.handle + '"');
825
+ return false;
826
+ }
827
+ __classPrivateFieldGet(this, _Draggable_handleMap, "f").set(el, h);
828
+ });
829
+ }
830
+ this.onOptionChanged(this.opts);
831
+ //put into group
832
+ if (this.opts.group) {
833
+ if (!DRAGGER_GROUPS[this.opts.group]) {
834
+ DRAGGER_GROUPS[this.opts.group] = [];
835
+ }
836
+ DRAGGER_GROUPS[this.opts.group].push(...this.ele);
837
+ }
838
+ each(this.ele, (el) => {
839
+ bindEvent(this.registerEvent.bind(this), el, this.opts, __classPrivateFieldGet(this, _Draggable_handleMap, "f"));
840
+ if (isDefined(this.opts.type))
841
+ el.dataset.dropType = this.opts.type;
842
+ el.classList.toggle(CLASS_DRAGGABLE, true);
843
+ const ee = __classPrivateFieldGet(this, _Draggable_handleMap, "f").get(el) || el;
844
+ ee.classList.toggle(CLASS_DRAGGABLE_HANDLE, true);
845
+ if (isDefined(this.opts.cursor)) {
846
+ el.style.cursor = this.opts.cursor.default || 'move';
847
+ if (isDefined(this.opts.cursor.over)) {
848
+ el.dataset.cursorOver = this.opts.cursor.over;
849
+ el.dataset.cursorActive = this.opts.cursor.active || 'move';
850
+ }
851
+ }
852
+ });
853
+ }
854
+ /**
855
+ * @internal
856
+ */
857
+ onOptionChanged(opts) {
858
+ const droppable = opts.droppable;
859
+ if (!isFunction(droppable)) {
860
+ if (isUndefined(droppable)) {
861
+ opts.droppable = () => { };
862
+ }
863
+ else if (isString(droppable)) {
864
+ opts.droppable = () => document.querySelectorAll(droppable);
865
+ }
866
+ else if (isArrayLike(droppable)) {
867
+ opts.droppable = () => droppable;
868
+ }
869
+ else if (isElement(droppable)) {
870
+ opts.droppable = () => [droppable];
871
+ }
872
+ }
873
+ if (opts.snap) {
874
+ opts.snapTargets = map(document.querySelectorAll(opts.snap), (el) => {
875
+ let offX = 0, offY = 0;
876
+ closest(el, (el) => {
877
+ offX += el.offsetLeft;
878
+ offY += el.offsetTop;
879
+ return false;
880
+ }, "offsetParent");
881
+ return {
882
+ x1: offX,
883
+ y1: offY,
884
+ x2: offX + el.offsetWidth,
885
+ y2: offY + el.offsetHeight,
886
+ el: el,
887
+ };
888
+ });
889
+ }
890
+ }
891
+ }
892
+ _Draggable_handleMap = new WeakMap();
893
+ function bindEvent(registerEvent, el, opts, handleMap) {
894
+ registerEvent(el, "mousedown", (e) => {
895
+ // get options
896
+ let dragDom = e.currentTarget;
897
+ let t = e.target;
898
+ if (!t)
899
+ return;
900
+ let handle = handleMap.get(dragDom);
901
+ if (handle && !handle.contains(t)) {
902
+ return;
903
+ }
904
+ const filter = opts.filter;
905
+ //check filter
906
+ if (filter) {
907
+ if (some(el.querySelectorAll(filter), ele => ele.contains(t)))
908
+ return;
909
+ }
910
+ const computedStyle = window.getComputedStyle(dragDom);
911
+ const container = dragDom.offsetParent || document.body;
912
+ const inContainer = opts.container;
913
+ const threshold = opts.threshold;
914
+ const ghost = opts.ghost;
915
+ const ghostClass = opts.ghostClass;
916
+ const direction = opts.direction;
917
+ const onStart = opts.onStart;
918
+ const onDrag = opts.onDrag;
919
+ const onEnd = opts.onEnd;
920
+ const onClone = opts.onClone;
921
+ const originalZIndex = computedStyle.zIndex;
922
+ let zIndex = opts.zIndex || originalZIndex;
923
+ const classes = opts.classes;
924
+ const group = opts.group;
925
+ if (group) {
926
+ let i = -1;
927
+ each(DRAGGER_GROUPS[group], el => {
928
+ const z = parseInt(window.getComputedStyle(el).zIndex);
929
+ if (z > i)
930
+ i = z;
931
+ });
932
+ zIndex = i + 1;
933
+ }
934
+ const scroll = opts.scroll;
935
+ const scrollSpeed = opts.scrollSpeed || 10;
936
+ let gridX, gridY;
937
+ const grid = opts.grid;
938
+ if (isArray(grid)) {
939
+ gridX = grid[0];
940
+ gridY = grid[1];
941
+ }
942
+ else if (isNumber(grid)) {
943
+ gridX = gridY = grid;
944
+ }
945
+ const snapOn = opts.snap;
946
+ const snappable = opts.snapTargets;
947
+ const snapTolerance = opts.snapOptions.tolerance;
948
+ const onSnap = opts.onSnap;
949
+ let lastSnapDirY = "", lastSnapDirX = "";
950
+ let lastSnapping = "";
951
+ let parentOffsetX = 0, parentOffsetY = 0;
952
+ if (snapOn) {
953
+ closest(dragDom, (el, times) => {
954
+ if (times > 0) {
955
+ parentOffsetX += el.offsetLeft;
956
+ parentOffsetY += el.offsetTop;
957
+ }
958
+ return false;
959
+ }, "offsetParent");
960
+ }
961
+ const originW = dragDom.offsetWidth + parseFloat(computedStyle.borderLeftWidth) + parseFloat(computedStyle.borderRightWidth);
962
+ const originH = dragDom.offsetHeight + parseFloat(computedStyle.borderTopWidth) + parseFloat(computedStyle.borderBottomWidth);
963
+ // boundary
964
+ let minX;
965
+ let minY;
966
+ let maxX;
967
+ let maxY;
968
+ if (inContainer) {
969
+ minX = 0;
970
+ minY = 0;
971
+ maxX = container.scrollWidth - originW;
972
+ maxY = container.scrollHeight - originH;
973
+ }
974
+ //start point
975
+ const rect = container.getBoundingClientRect();
976
+ const offset = getOffset(t, container);
977
+ const ox = e.offsetX || 0;
978
+ const oy = e.offsetY || 0;
979
+ let hitPosX = offset.x + ox + container.scrollLeft;
980
+ let hitPosY = offset.y + oy + container.scrollTop;
981
+ let cursorX = ox, cursorY = e.offsetY;
982
+ if (e.target !== dragDom) {
983
+ const offset = getOffset(t, dragDom);
984
+ const style = window.getComputedStyle(t);
985
+ cursorX = offset.x + ox + parseFloat(style.borderLeftWidth);
986
+ cursorY = offset.y + oy + parseFloat(style.borderTopWidth);
987
+ }
988
+ const cursorAt = opts.cursorAt;
989
+ if (cursorAt) {
990
+ const l = cursorAt.left;
991
+ const t = cursorAt.top;
992
+ if (isString(l)) {
993
+ cursorX = parseFloat(l) / 100 * dragDom.offsetWidth;
994
+ }
995
+ else {
996
+ cursorX = l;
997
+ }
998
+ if (isString(t)) {
999
+ cursorY = parseFloat(t) / 100 * dragDom.offsetWidth;
1000
+ }
1001
+ else {
1002
+ cursorY = t;
1003
+ }
1004
+ }
1005
+ const style = dragDom.style;
1006
+ let dragging = false;
1007
+ let copyNode;
1008
+ let timer = null;
1009
+ let toLeft = false;
1010
+ let toTop = false;
1011
+ let toRight = false;
1012
+ let toBottom = false;
1013
+ let bodyCursor = document.body.style.cursor;
1014
+ const dragListener = (ev) => {
1015
+ var _a;
1016
+ const newX = ev.clientX - rect.x + container.scrollLeft;
1017
+ const newY = ev.clientY - rect.y + container.scrollTop;
1018
+ let offsetx = newX - hitPosX;
1019
+ let offsety = newY - hitPosY;
1020
+ if (!dragging) {
1021
+ if (Math.abs(offsetx) > threshold || Math.abs(offsety) > threshold) {
1022
+ dragging = true;
1023
+ if (ghost) {
1024
+ if (isFunction(ghost)) {
1025
+ copyNode = ghost(dragDom);
1026
+ }
1027
+ else {
1028
+ copyNode = dragDom.cloneNode(true);
1029
+ copyNode.style.opacity = "0.3";
1030
+ copyNode.style.pointerEvents = "none";
1031
+ copyNode.style.position = "absolute";
1032
+ }
1033
+ copyNode.style.left = dragDom.style.left;
1034
+ copyNode.style.top = dragDom.style.top;
1035
+ copyNode.style.zIndex = zIndex;
1036
+ if (ghostClass) {
1037
+ copyNode.classList.add(...compact(split(ghostClass, ' ')));
1038
+ }
1039
+ copyNode.classList.add(...compact(split(classes, ' ')));
1040
+ copyNode.classList.toggle(CLASS_DRAGGABLE_GHOST, true);
1041
+ (_a = dragDom.parentNode) === null || _a === void 0 ? void 0 : _a.appendChild(copyNode);
1042
+ if (onClone) {
1043
+ onClone(copyNode, ev);
1044
+ }
1045
+ }
1046
+ //apply classes
1047
+ dragDom.classList.add(...compact(split(classes, ' ')));
1048
+ dragDom.style.zIndex = zIndex;
1049
+ dragDom.classList.toggle(CLASS_DRAGGABLE_ACTIVE, true);
1050
+ call(onStart, dragDom, ev);
1051
+ lockPage();
1052
+ if (isDefined(opts.cursor)) {
1053
+ document.body.style.cursor = opts.cursor.active || 'move';
1054
+ }
1055
+ //notify
1056
+ const customEv = new Event("uii-dragactive", { "bubbles": true, "cancelable": false });
1057
+ dragDom.dispatchEvent(customEv);
1058
+ }
1059
+ else {
1060
+ ev.preventDefault();
1061
+ return false;
1062
+ }
1063
+ }
1064
+ //edge detect
1065
+ if (scroll) {
1066
+ const ltX = ev.clientX - rect.x;
1067
+ const ltY = ev.clientY - rect.y;
1068
+ const rbX = rect.x + rect.width - ev.clientX;
1069
+ const rbY = rect.y + rect.height - ev.clientY;
1070
+ toLeft = ltX < EDGE_THRESHOLD;
1071
+ toTop = ltY < EDGE_THRESHOLD;
1072
+ toRight = rbX < EDGE_THRESHOLD;
1073
+ toBottom = rbY < EDGE_THRESHOLD;
1074
+ if (toLeft || toTop
1075
+ ||
1076
+ toRight || toBottom) {
1077
+ if (!timer) {
1078
+ timer = setInterval(() => {
1079
+ if (toLeft) {
1080
+ container.scrollLeft -= scrollSpeed;
1081
+ }
1082
+ else if (toRight) {
1083
+ container.scrollLeft += scrollSpeed;
1084
+ }
1085
+ if (toTop) {
1086
+ container.scrollTop -= scrollSpeed;
1087
+ }
1088
+ else if (toBottom) {
1089
+ container.scrollTop += scrollSpeed;
1090
+ }
1091
+ }, 20);
1092
+ }
1093
+ }
1094
+ else {
1095
+ if (timer) {
1096
+ clearInterval(timer);
1097
+ timer = null;
1098
+ }
1099
+ }
1100
+ }
1101
+ let x = newX - cursorX;
1102
+ let y = newY - cursorY;
1103
+ //grid
1104
+ if (isNumber(gridX) && isNumber(gridY)) {
1105
+ x = ((x / gridX) >> 0) * gridX;
1106
+ y = ((y / gridY) >> 0) * gridY;
1107
+ }
1108
+ if (inContainer) {
1109
+ if (x < minX)
1110
+ x = minX;
1111
+ if (y < minY)
1112
+ y = minY;
1113
+ if (x > maxX)
1114
+ x = maxX;
1115
+ if (y > maxY)
1116
+ y = maxY;
1117
+ }
1118
+ let canDrag = true;
1119
+ let emitSnap = false;
1120
+ if (snapOn) {
1121
+ const currPageX1 = parentOffsetX + x;
1122
+ const currPageY1 = parentOffsetY + y;
1123
+ const currPageX2 = currPageX1 + originW;
1124
+ const currPageY2 = currPageY1 + originH;
1125
+ //check snappable
1126
+ let snapX = NaN, snapY = NaN;
1127
+ let targetX, targetY;
1128
+ let snapDirX, snapDirY;
1129
+ if (!direction || direction === "v") {
1130
+ each(snappable, (data) => {
1131
+ if (Math.abs(data.y1 - currPageY1) <= snapTolerance) {
1132
+ //top parallel
1133
+ snapY = data.y1;
1134
+ snapDirY = "t2t";
1135
+ }
1136
+ else if (Math.abs(data.y2 - currPageY1) <= snapTolerance) {
1137
+ //b2t
1138
+ snapY = data.y2;
1139
+ snapDirY = "t2b";
1140
+ }
1141
+ else if (Math.abs(data.y1 - currPageY2) <= snapTolerance) {
1142
+ //t2b
1143
+ snapY = data.y1 - originH;
1144
+ snapDirY = "b2t";
1145
+ }
1146
+ else if (Math.abs(data.y2 - currPageY2) <= snapTolerance) {
1147
+ //bottom parallel
1148
+ snapY = data.y2 - originH;
1149
+ snapDirY = "b2b";
1150
+ }
1151
+ if (snapY) {
1152
+ lastSnapDirY = snapDirY;
1153
+ targetY = data.el;
1154
+ return false;
1155
+ }
1156
+ });
1157
+ }
1158
+ if (!direction || direction === "h") {
1159
+ each(snappable, (data) => {
1160
+ if (Math.abs(data.x1 - currPageX1) <= snapTolerance) {
1161
+ //left parallel
1162
+ snapX = data.x1;
1163
+ snapDirX = "l2l";
1164
+ }
1165
+ else if (Math.abs(data.x2 - currPageX1) <= snapTolerance) {
1166
+ //r2l
1167
+ snapX = data.x2;
1168
+ snapDirX = "l2r";
1169
+ }
1170
+ else if (Math.abs(data.x1 - currPageX2) <= snapTolerance) {
1171
+ //l2r
1172
+ snapX = data.x1 - originW;
1173
+ snapDirX = "r2l";
1174
+ }
1175
+ else if (Math.abs(data.x2 - currPageX2) <= snapTolerance) {
1176
+ //right parallel
1177
+ snapX = data.x2 - originW;
1178
+ snapDirX = "r2r";
1179
+ }
1180
+ if (snapX) {
1181
+ lastSnapDirX = snapDirX;
1182
+ targetX = data.el;
1183
+ return false;
1184
+ }
1185
+ });
1186
+ }
1187
+ if (snapX || snapY) {
1188
+ if (snapX) {
1189
+ x = snapX - parentOffsetX;
1190
+ }
1191
+ if (snapY) {
1192
+ y = snapY - parentOffsetY;
1193
+ }
1194
+ if (onSnap && lastSnapping !== lastSnapDirX + "" + lastSnapDirY) {
1195
+ setTimeout(() => {
1196
+ //emit after relocate
1197
+ onSnap(copyNode || dragDom, targetX, targetY, snapDirX, snapDirY);
1198
+ }, 0);
1199
+ lastSnapping = lastSnapDirX + "" + lastSnapDirY;
1200
+ }
1201
+ emitSnap = true;
1202
+ }
1203
+ else {
1204
+ lastSnapDirX = lastSnapDirY = lastSnapping = "";
1205
+ }
1206
+ }
1207
+ if (onDrag && !emitSnap) {
1208
+ if (onDrag(dragDom, ev, offsetx, offsety, x, y) === false) {
1209
+ canDrag = false;
1210
+ }
1211
+ }
1212
+ if (canDrag) {
1213
+ if (copyNode) {
1214
+ if (direction === "v") {
1215
+ copyNode.style.top = `${y}px`;
1216
+ }
1217
+ else if (direction === "v") {
1218
+ copyNode.style.left = `${x}px`;
1219
+ }
1220
+ else {
1221
+ copyNode.style.left = `${x}px`;
1222
+ copyNode.style.top = `${y}px`;
1223
+ }
1224
+ }
1225
+ else {
1226
+ if (direction === "v") {
1227
+ style.top = `${y}px`;
1228
+ }
1229
+ else if (direction === "v") {
1230
+ style.left = `${x}px`;
1231
+ }
1232
+ else {
1233
+ style.left = `${x}px`;
1234
+ style.top = `${y}px`;
1235
+ }
1236
+ }
1237
+ }
1238
+ ev.preventDefault();
1239
+ return false;
1240
+ };
1241
+ const dragEndListener = (ev) => {
1242
+ var _a;
1243
+ document.removeEventListener("mousemove", dragListener);
1244
+ document.removeEventListener("mouseup", dragEndListener);
1245
+ window.removeEventListener("blur", dragEndListener);
1246
+ if (scroll) {
1247
+ if (timer) {
1248
+ clearInterval(timer);
1249
+ timer = null;
1250
+ }
1251
+ }
1252
+ //restore classes
1253
+ dragDom.classList.remove(...compact(split(classes, ' ')));
1254
+ dragDom.style.zIndex = originalZIndex;
1255
+ dragDom.classList.remove(CLASS_DRAGGABLE_ACTIVE);
1256
+ let moveToGhost = true;
1257
+ if (dragging) {
1258
+ moveToGhost = call(onEnd, dragDom, ev);
1259
+ }
1260
+ //notify
1261
+ const customEv = new Event("uii-dragdeactive", { "bubbles": true, "cancelable": false });
1262
+ dragDom.dispatchEvent(customEv);
1263
+ if (dragging) {
1264
+ unlockPage();
1265
+ document.body.style.cursor = bodyCursor;
1266
+ if (ghost) {
1267
+ (_a = dragDom.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(copyNode);
1268
+ if (moveToGhost !== false) {
1269
+ style.left = copyNode.style.left;
1270
+ style.top = copyNode.style.top;
1271
+ }
1272
+ }
1273
+ }
1274
+ };
1275
+ document.addEventListener("mousemove", dragListener);
1276
+ document.addEventListener("mouseup", dragEndListener);
1277
+ window.addEventListener("blur", dragEndListener);
1278
+ e.preventDefault();
1279
+ return false;
1280
+ });
1281
+ }
1282
+ /**
1283
+ * create a draggable pattern for one or more elements with opts
1284
+ * @param els selector string / html element
1285
+ * @param opts
1286
+ * @returns Draggable instance
1287
+ */
1288
+ function newDraggable(els, opts) {
1289
+ return new Draggable(els, opts);
1290
+ }
1291
+
1292
+ var _Droppable_active;
1293
+ const Droppables = [];
1294
+ const CLASS_DROPPABLE = "uii-droppable";
1295
+ /**
1296
+ * 用于表示一个或多个可响应拖动元素的定义
1297
+ * > 可用CSS接口
1298
+ * - .uii-droppable
1299
+ * @public
1300
+ */
1301
+ class Droppable extends Uii {
1302
+ constructor(el, opts) {
1303
+ super(el, assign({}, opts));
1304
+ _Droppable_active.set(this, void 0);
1305
+ Droppables.push(this);
1306
+ }
1307
+ /**
1308
+ * @internal
1309
+ */
1310
+ bindEvent(el, opts) {
1311
+ //dragenter
1312
+ this.registerEvent(el, "mouseenter", (e) => {
1313
+ if (!__classPrivateFieldGet(this, _Droppable_active, "f"))
1314
+ return;
1315
+ if (opts.hoverClass) {
1316
+ each(split(opts.hoverClass, ' '), cls => {
1317
+ el.classList.toggle(cls, true);
1318
+ });
1319
+ }
1320
+ if (__classPrivateFieldGet(this, _Droppable_active, "f").dataset.cursorOver) {
1321
+ document.body.style.cursor = __classPrivateFieldGet(this, _Droppable_active, "f").dataset.cursorOver;
1322
+ }
1323
+ call(opts.onEnter, el, e);
1324
+ });
1325
+ //dragleave
1326
+ this.registerEvent(el, "mouseleave", (e) => {
1327
+ if (!__classPrivateFieldGet(this, _Droppable_active, "f"))
1328
+ return;
1329
+ if (opts.hoverClass) {
1330
+ each(split(opts.hoverClass, ' '), cls => {
1331
+ el.classList.toggle(cls, false);
1332
+ });
1333
+ }
1334
+ if (__classPrivateFieldGet(this, _Droppable_active, "f").dataset.cursorOver) {
1335
+ document.body.style.cursor = __classPrivateFieldGet(this, _Droppable_active, "f").dataset.cursorActive || '';
1336
+ }
1337
+ call(opts.onLeave, el, e);
1338
+ });
1339
+ //dragover
1340
+ this.registerEvent(el, "mousemove", (e) => {
1341
+ if (!__classPrivateFieldGet(this, _Droppable_active, "f"))
1342
+ return;
1343
+ if (opts.onDragOver) {
1344
+ opts.onDragOver(el, e);
1345
+ }
1346
+ });
1347
+ //drop
1348
+ this.registerEvent(el, "mouseup", (e) => {
1349
+ if (!__classPrivateFieldGet(this, _Droppable_active, "f"))
1350
+ return;
1351
+ if (opts.hoverClass) {
1352
+ each(split(opts.hoverClass, ' '), cls => {
1353
+ el.classList.toggle(cls, false);
1354
+ });
1355
+ }
1356
+ call(opts.onDrop, el, e);
1357
+ });
1358
+ }
1359
+ /**
1360
+ * @internal
1361
+ */
1362
+ active(target) {
1363
+ let valid = true;
1364
+ //check accepts
1365
+ if (isString(this.opts.accepts)) {
1366
+ valid = !!target.dataset.dropType && test(this.opts.accepts, target.dataset.dropType);
1367
+ }
1368
+ else if (isFunction(this.opts.accepts)) {
1369
+ valid = this.opts.accepts(this.ele, target);
1370
+ }
1371
+ if (!valid)
1372
+ return;
1373
+ __classPrivateFieldSet(this, _Droppable_active, target, "f");
1374
+ if (this.opts.activeClass) {
1375
+ each(this.ele, el => {
1376
+ each(split(this.opts.activeClass, ' '), cls => {
1377
+ el.classList.toggle(cls, true);
1378
+ });
1379
+ });
1380
+ }
1381
+ call(this.opts.onActive, target, this.ele);
1382
+ //bind events
1383
+ each(this.ele, (el) => {
1384
+ el.classList.toggle(CLASS_DROPPABLE, true);
1385
+ el.style.pointerEvents = 'initial';
1386
+ this.bindEvent(el, this.opts);
1387
+ });
1388
+ }
1389
+ /**
1390
+ * @internal
1391
+ */
1392
+ deactive(target) {
1393
+ if (!__classPrivateFieldGet(this, _Droppable_active, "f"))
1394
+ return;
1395
+ __classPrivateFieldSet(this, _Droppable_active, null, "f");
1396
+ if (this.opts.activeClass) {
1397
+ each(this.ele, el => {
1398
+ each(split(this.opts.activeClass, ' '), cls => {
1399
+ el.classList.toggle(cls, false);
1400
+ });
1401
+ });
1402
+ }
1403
+ call(this.opts.onDeactive, target, this.ele);
1404
+ //unbind events
1405
+ this.destroy();
1406
+ }
1407
+ }
1408
+ _Droppable_active = new WeakMap();
1409
+ //uii-drag active
1410
+ document.addEventListener("uii-dragactive", (e) => {
1411
+ each(Droppables, dpb => {
1412
+ dpb.active(e.target);
1413
+ });
1414
+ });
1415
+ document.addEventListener("uii-dragdeactive", (e) => {
1416
+ each(Droppables, dpb => {
1417
+ dpb.deactive(e.target);
1418
+ });
1419
+ });
1420
+ /**
1421
+ * Enable els to response to draggable objects
1422
+ * @param els selector string / html element
1423
+ * @param opts
1424
+ * @returns
1425
+ */
1426
+ function newDroppable(els, opts) {
1427
+ return new Droppable(els, opts);
1428
+ }
1429
+
1430
+ /* eslint-disable max-len */
1431
+ const ONE_DEG = 180 / Math.PI;
1432
+ const THRESHOLD$1 = 2;
1433
+ const CLASS_ROTATABLE = "uii-rotatable";
1434
+ const CLASS_ROTATABLE_HANDLE = "uii-rotatable-handle";
1435
+ const CLASS_ROTATABLE_ACTIVE = "uii-rotatable-active";
1436
+ /**
1437
+ * 用于表示一个或多个可旋转元素的定义
1438
+ * > 可用CSS接口
1439
+ * - .uii-rotatable
1440
+ * - .uii-rotatable-handle
1441
+ * - .uii-rotatable-active
1442
+ * @public
1443
+ */
1444
+ class Rotatable extends Uii {
1445
+ constructor(els, opts) {
1446
+ super(els, opts);
1447
+ each(this.ele, (el) => {
1448
+ initHandle(el, this.opts);
1449
+ });
1450
+ }
1451
+ }
1452
+ function initHandle(el, opts) {
1453
+ var _a;
1454
+ const handle = document.createElement('div');
1455
+ handle.className = CLASS_ROTATABLE_HANDLE;
1456
+ handle.style.cssText = `
1457
+ position:absolute;
1458
+ width:12px;
1459
+ height:12px;
1460
+ border-radius:50%;
1461
+ left: calc(50% - 6px);
1462
+ top: -24px;
1463
+ `;
1464
+ handle.style.cursor = ((_a = opts.cursor) === null || _a === void 0 ? void 0 : _a.default) || 'crosshair';
1465
+ bindHandle(handle, el, opts);
1466
+ el.classList.toggle(CLASS_ROTATABLE, true);
1467
+ el.appendChild(handle);
1468
+ }
1469
+ function bindHandle(handle, el, opts) {
1470
+ const onStart = opts.onStart;
1471
+ const onRotate = opts.onRotate;
1472
+ const onEnd = opts.onEnd;
1473
+ handle.onmousedown = function (e) {
1474
+ var _a, _b;
1475
+ // calc center
1476
+ const center = window.getComputedStyle(el).transformOrigin || '';
1477
+ const centerPair = center.split(' ');
1478
+ const shadowDom = el.cloneNode();
1479
+ shadowDom.style.cssText = 'transform:rotate(0);z-index:-999;position:absolute;';
1480
+ (_a = el.parentElement) === null || _a === void 0 ? void 0 : _a.appendChild(shadowDom);
1481
+ const offsetXY = shadowDom.getBoundingClientRect();
1482
+ (_b = el.parentElement) === null || _b === void 0 ? void 0 : _b.removeChild(shadowDom);
1483
+ let centerX = parseFloat(centerPair[0]) + offsetXY.x;
1484
+ let centerY = parseFloat(centerPair[1]) + offsetXY.y;
1485
+ let a = 0, b = 0;
1486
+ const matrix = window.getComputedStyle(el).transform;
1487
+ if (matrix.indexOf('matrix') > -1) {
1488
+ const abcd = matrix.replace(/^matrix\(|\)$/mg, '').split(',');
1489
+ a = parseFloat(abcd[0]);
1490
+ b = parseFloat(abcd[1]);
1491
+ }
1492
+ let deg = Math.atan2(b, a) * ONE_DEG;
1493
+ if (deg < 0)
1494
+ deg = 360 - deg;
1495
+ if (deg > 360)
1496
+ deg = 360 - deg % 360;
1497
+ const style = el.style;
1498
+ let startDeg = Math.atan2(e.clientY - centerY, e.clientX - centerX) * ONE_DEG + 90;
1499
+ if (startDeg < 0)
1500
+ startDeg = 360 + startDeg;
1501
+ const offsetDeg = startDeg - deg;
1502
+ let dragging = false;
1503
+ let bodyCursor = document.body.style.cursor;
1504
+ const dragListener = (ev) => {
1505
+ var _a;
1506
+ const offsetx = ev.clientX - centerX;
1507
+ const offsety = ev.clientY - centerY;
1508
+ if (!dragging) {
1509
+ if (Math.abs(offsetx) > THRESHOLD$1 || Math.abs(offsety) > THRESHOLD$1) {
1510
+ dragging = true;
1511
+ //apply classes
1512
+ el.classList.toggle(CLASS_ROTATABLE_ACTIVE, true);
1513
+ call(onStart, deg);
1514
+ lockPage();
1515
+ if (isDefined(opts.cursor)) {
1516
+ document.body.style.cursor = ((_a = opts.cursor) === null || _a === void 0 ? void 0 : _a.active) || 'crosshair';
1517
+ }
1518
+ }
1519
+ else {
1520
+ ev.preventDefault();
1521
+ return false;
1522
+ }
1523
+ }
1524
+ deg = Math.atan2(offsety, offsetx) * ONE_DEG + 90 - offsetDeg;
1525
+ if (deg < 0)
1526
+ deg = 360 + deg;
1527
+ call(onRotate, deg);
1528
+ style.transform = style.transform.replace(/rotateZ\(.*?\)/, '') + ' rotateZ(' + deg + 'deg)';
1529
+ ev.preventDefault();
1530
+ return false;
1531
+ };
1532
+ const dragEndListener = (ev) => {
1533
+ document.removeEventListener('mousemove', dragListener, false);
1534
+ document.removeEventListener('mouseup', dragEndListener, false);
1535
+ window.removeEventListener('blur', dragEndListener, false);
1536
+ if (dragging) {
1537
+ unlockPage();
1538
+ document.body.style.cursor = bodyCursor;
1539
+ el.classList.toggle(CLASS_ROTATABLE_ACTIVE, false);
1540
+ call(onEnd, deg);
1541
+ }
1542
+ };
1543
+ document.addEventListener('mousemove', dragListener, false);
1544
+ document.addEventListener('mouseup', dragEndListener, false);
1545
+ window.addEventListener('blur', dragEndListener, false);
1546
+ e.preventDefault();
1547
+ return false;
1548
+ };
1549
+ }
1550
+ /**
1551
+ * Make els rotatable
1552
+ * @param els selector string / html element
1553
+ * @param opts
1554
+ * @returns
1555
+ */
1556
+ function newRotatable(els, opts) {
1557
+ return new Rotatable(els, opts);
1558
+ }
1559
+
1560
+ var _CollisionDetector__targets;
1561
+ class CollisionDetector {
1562
+ constructor(el, targets, opts) {
1563
+ _CollisionDetector__targets.set(this, void 0);
1564
+ __classPrivateFieldSet(this, _CollisionDetector__targets, targets, "f");
1565
+ this.opts = {
1566
+ container: document.body
1567
+ };
1568
+ this.opts = assign(this.opts, opts);
1569
+ const domEl = isString(el) ? document.querySelector(el) : el;
1570
+ if (!domEl) {
1571
+ console.error('Invalid selector "' + el + '"');
1572
+ return;
1573
+ }
1574
+ const ele = domEl;
1575
+ this.el = domEl;
1576
+ //el data
1577
+ const offset = getOffset(ele, this.opts.container);
1578
+ const rect = { x: offset.x, y: offset.y, width: ele.offsetWidth, height: ele.offsetHeight };
1579
+ this.elData = {
1580
+ x1: rect.x,
1581
+ y1: rect.y,
1582
+ x2: rect.x + rect.width,
1583
+ y2: rect.y + rect.height,
1584
+ };
1585
+ //targets data
1586
+ this.update();
1587
+ }
1588
+ /**
1589
+ * update targets data if them changed
1590
+ */
1591
+ update() {
1592
+ let targets;
1593
+ if (isFunction(__classPrivateFieldGet(this, _CollisionDetector__targets, "f"))) {
1594
+ targets = __classPrivateFieldGet(this, _CollisionDetector__targets, "f").call(this);
1595
+ }
1596
+ else if (isString(__classPrivateFieldGet(this, _CollisionDetector__targets, "f"))) {
1597
+ targets = this.opts.container.querySelectorAll(__classPrivateFieldGet(this, _CollisionDetector__targets, "f"));
1598
+ }
1599
+ else if (isElement(__classPrivateFieldGet(this, _CollisionDetector__targets, "f"))) {
1600
+ targets = [__classPrivateFieldGet(this, _CollisionDetector__targets, "f")];
1601
+ }
1602
+ else {
1603
+ targets = __classPrivateFieldGet(this, _CollisionDetector__targets, "f");
1604
+ }
1605
+ this.targetsData = flatMap(targets, t => {
1606
+ if (!t)
1607
+ return [];
1608
+ if (!isElement(t))
1609
+ return [];
1610
+ const offset = getOffset(t, this.opts.container);
1611
+ const rect = { x: offset.x, y: offset.y, width: t.offsetWidth, height: t.offsetHeight };
1612
+ return {
1613
+ x1: rect.x,
1614
+ y1: rect.y,
1615
+ x2: rect.x + rect.width,
1616
+ y2: rect.y + rect.height,
1617
+ el: t
1618
+ };
1619
+ });
1620
+ }
1621
+ getOverlaps(x1, y1, x2, y2) {
1622
+ let elData = this.elData;
1623
+ if (x1 && x2 && y1 && y2) {
1624
+ elData = {
1625
+ x1,
1626
+ y1,
1627
+ x2,
1628
+ y2,
1629
+ };
1630
+ }
1631
+ let overlaps = flatMap(this.targetsData, (td, i) => {
1632
+ if (elData.x2 < td.x1 || elData.x1 > td.x2 || elData.y2 < td.y1 || elData.y1 > td.y2)
1633
+ return [];
1634
+ return td.el;
1635
+ });
1636
+ return overlaps;
1637
+ }
1638
+ getInclusions(x1, y1, x2, y2) {
1639
+ let elData = this.elData;
1640
+ if (x1 && x2 && y1 && y2) {
1641
+ elData = {
1642
+ x1,
1643
+ y1,
1644
+ x2,
1645
+ y2,
1646
+ };
1647
+ }
1648
+ let contains = flatMap(this.targetsData, (td, i) => {
1649
+ if (elData.x2 >= td.x2 && elData.x1 <= td.x1 && elData.y2 >= td.y2 && elData.y1 <= td.y1)
1650
+ return td.el;
1651
+ return [];
1652
+ });
1653
+ return contains;
1654
+ }
1655
+ }
1656
+ _CollisionDetector__targets = new WeakMap();
1657
+ /**
1658
+ * create a detector for the el and return
1659
+ * @param el element to be detected
1660
+ * @param targets
1661
+ * @param opts CollisionDetectorOptions
1662
+ * @param opts.container a root element of targets
1663
+ * @returns
1664
+ */
1665
+ function newCollisionDetector(el, targets, opts) {
1666
+ return new CollisionDetector(el, targets, opts);
1667
+ }
1668
+
1669
+ /* eslint-disable max-len */
1670
+ /**
1671
+ * selector
1672
+ * @author holyhigh2
1673
+ */
1674
+ var _Selectable_instances, _Selectable__detector, _Selectable__lastSelected, _Selectable_bindEvent;
1675
+ const CLASS_SELECTOR = "uii-selector";
1676
+ const CLASS_SELECTING = "uii-selecting";
1677
+ const CLASS_SELECTED = "uii-selected";
1678
+ const THRESHOLD = 2;
1679
+ /**
1680
+ * 用于表示一个元素选择器的定义
1681
+ * > 可用CSS接口
1682
+ * - .uii-selector
1683
+ * - .uii-selecting
1684
+ * - .uii-selected
1685
+ * @public
1686
+ */
1687
+ class Selectable extends Uii {
1688
+ constructor(container, opts) {
1689
+ super(container, assign({
1690
+ targets: [],
1691
+ scroll: true,
1692
+ }, opts));
1693
+ _Selectable_instances.add(this);
1694
+ _Selectable__detector.set(this, void 0);
1695
+ _Selectable__lastSelected.set(this, void 0);
1696
+ const domEl = this.ele[0];
1697
+ //create selector
1698
+ const selector = document.createElement("div");
1699
+ selector.className = CLASS_SELECTOR;
1700
+ selector.style.cssText = `
1701
+ position:absolute;
1702
+ left:-9999px;
1703
+ `;
1704
+ if (this.opts.class) {
1705
+ selector.className += " " + this.opts.class;
1706
+ }
1707
+ else {
1708
+ selector.style.cssText += "border:1px dashed #000;";
1709
+ }
1710
+ domEl.appendChild(selector);
1711
+ //create detector
1712
+ __classPrivateFieldSet(this, _Selectable__detector, newCollisionDetector(selector, this.opts.targets, {
1713
+ container: domEl,
1714
+ }), "f");
1715
+ __classPrivateFieldGet(this, _Selectable_instances, "m", _Selectable_bindEvent).call(this, selector, domEl);
1716
+ }
1717
+ /**
1718
+ * 更新targets
1719
+ */
1720
+ updateTargets() {
1721
+ __classPrivateFieldGet(this, _Selectable__detector, "f").update();
1722
+ }
1723
+ /**
1724
+ * @internal
1725
+ */
1726
+ onOptionChanged() {
1727
+ this.updateTargets();
1728
+ }
1729
+ }
1730
+ _Selectable__detector = new WeakMap(), _Selectable__lastSelected = new WeakMap(), _Selectable_instances = new WeakSet(), _Selectable_bindEvent = function _Selectable_bindEvent(selector, con) {
1731
+ const that = this;
1732
+ this.registerEvent(con, "mousedown", (e) => {
1733
+ const t = e.target;
1734
+ const onStart = that.opts.onStart;
1735
+ const onSelect = that.opts.onSelect;
1736
+ const onEnd = that.opts.onEnd;
1737
+ const mode = that.opts.mode || "overlap";
1738
+ const scroll = that.opts.scroll;
1739
+ const scrollSpeed = that.opts.scrollSpeed || 10;
1740
+ const filter = that.opts.filter;
1741
+ const selectingClassAry = compact(split(that.opts.selectingClass, " "));
1742
+ const selectedClassAry = compact(split(that.opts.selectedClass, " "));
1743
+ //check filter
1744
+ if (filter) {
1745
+ if (isFunction(filter)) {
1746
+ if (filter(t))
1747
+ return;
1748
+ }
1749
+ else if (some(con.querySelectorAll(filter), (el) => el.contains(t)))
1750
+ return;
1751
+ }
1752
+ let originPos = "";
1753
+ //offset
1754
+ const rect = con.getBoundingClientRect();
1755
+ const conStyle = window.getComputedStyle(con);
1756
+ const blw = parseFloat(conStyle.borderLeftWidth);
1757
+ const btw = parseFloat(conStyle.borderTopWidth);
1758
+ let hitPosX = e.offsetX + con.scrollLeft, hitPosY = e.offsetY + con.scrollTop;
1759
+ if (t !== con) {
1760
+ const offset = getOffset(t, con);
1761
+ const style = window.getComputedStyle(t);
1762
+ hitPosX = offset.x + e.offsetX + parseFloat(style.borderLeftWidth);
1763
+ hitPosY = offset.y + e.offsetY + parseFloat(style.borderTopWidth);
1764
+ }
1765
+ const style = selector.style;
1766
+ let selection = [];
1767
+ let lastSelection = [];
1768
+ let x1 = hitPosX, y1 = hitPosY;
1769
+ let dragging = false;
1770
+ let timer = null;
1771
+ let toLeft = false;
1772
+ let toTop = false;
1773
+ let toRight = false;
1774
+ let toBottom = false;
1775
+ const dragListener = (ev) => {
1776
+ const newX = ev.clientX - rect.x + con.scrollLeft - blw;
1777
+ const newY = ev.clientY - rect.y + con.scrollTop - btw;
1778
+ const offsetx = newX - hitPosX;
1779
+ const offsety = newY - hitPosY;
1780
+ if (!dragging) {
1781
+ if (Math.abs(offsetx) > THRESHOLD || Math.abs(offsety) > THRESHOLD) {
1782
+ dragging = true;
1783
+ //update targets count & positions
1784
+ __classPrivateFieldGet(this, _Selectable__detector, "f").update();
1785
+ //detect container position
1786
+ const pos = window.getComputedStyle(con).position;
1787
+ if (pos === "static") {
1788
+ originPos = con.style.position;
1789
+ con.style.position = "relative";
1790
+ }
1791
+ //clear _lastSelected
1792
+ each(__classPrivateFieldGet(this, _Selectable__lastSelected, "f"), t => {
1793
+ t.classList.toggle(CLASS_SELECTED, false);
1794
+ });
1795
+ call(onStart, t);
1796
+ }
1797
+ else {
1798
+ ev.preventDefault();
1799
+ return false;
1800
+ }
1801
+ }
1802
+ //edge detect
1803
+ if (scroll) {
1804
+ const ltX = ev.clientX - rect.x;
1805
+ const ltY = ev.clientY - rect.y;
1806
+ const rbX = rect.x + rect.width - ev.clientX;
1807
+ const rbY = rect.y + rect.height - ev.clientY;
1808
+ toLeft = ltX < EDGE_THRESHOLD;
1809
+ toTop = ltY < EDGE_THRESHOLD;
1810
+ toRight = rbX < EDGE_THRESHOLD;
1811
+ toBottom = rbY < EDGE_THRESHOLD;
1812
+ if (toLeft || toTop || toRight || toBottom) {
1813
+ if (!timer) {
1814
+ timer = setInterval(() => {
1815
+ if (toLeft) {
1816
+ con.scrollLeft -= scrollSpeed;
1817
+ }
1818
+ else if (toRight) {
1819
+ con.scrollLeft += scrollSpeed;
1820
+ }
1821
+ if (toTop) {
1822
+ con.scrollTop -= scrollSpeed;
1823
+ }
1824
+ else if (toBottom) {
1825
+ con.scrollTop += scrollSpeed;
1826
+ }
1827
+ }, 20);
1828
+ }
1829
+ }
1830
+ else {
1831
+ if (timer) {
1832
+ clearInterval(timer);
1833
+ timer = null;
1834
+ }
1835
+ }
1836
+ }
1837
+ let x = hitPosX, y = hitPosY, w = Math.abs(offsetx), h = Math.abs(offsety);
1838
+ if (offsetx > 0 && offsety > 0) {
1839
+ x1 = hitPosX;
1840
+ y1 = hitPosY;
1841
+ }
1842
+ else if (offsetx < 0 && offsety < 0) {
1843
+ x = x1 = newX;
1844
+ y = y1 = newY;
1845
+ }
1846
+ else if (offsetx < 0) {
1847
+ x = x1 = newX;
1848
+ }
1849
+ else if (offsety < 0) {
1850
+ y = y1 = newY;
1851
+ }
1852
+ style.left = x + "px";
1853
+ style.top = y + "px";
1854
+ style.width = w + "px";
1855
+ style.height = h + "px";
1856
+ //detect collision
1857
+ if (mode === "overlap") {
1858
+ selection = __classPrivateFieldGet(that, _Selectable__detector, "f").getOverlaps(x1, y1, x1 + w, y1 + h);
1859
+ }
1860
+ else if (mode === "inclusion") {
1861
+ selection = __classPrivateFieldGet(that, _Selectable__detector, "f").getInclusions(x1, y1, x1 + w, y1 + h);
1862
+ }
1863
+ each(lastSelection, (t) => {
1864
+ if (!includes(selection, t)) {
1865
+ t.classList.toggle(CLASS_SELECTING, false);
1866
+ each(selectingClassAry, (cls) => {
1867
+ t.classList.toggle(cls, false);
1868
+ });
1869
+ }
1870
+ });
1871
+ each(selection, (t) => {
1872
+ t.classList.toggle(CLASS_SELECTING, true);
1873
+ each(selectingClassAry, (cls) => {
1874
+ t.classList.toggle(cls, true);
1875
+ });
1876
+ });
1877
+ const changed = lastSelection.length != selection.length;
1878
+ lastSelection = selection;
1879
+ if (changed)
1880
+ call(onSelect, selection);
1881
+ ev.preventDefault();
1882
+ return false;
1883
+ };
1884
+ const dragEndListener = (ev) => {
1885
+ style.left = "-9999px";
1886
+ style.width = style.height = "0px";
1887
+ document.removeEventListener("mousemove", dragListener, false);
1888
+ document.removeEventListener("mouseup", dragEndListener, false);
1889
+ window.removeEventListener("blur", dragEndListener, false);
1890
+ if (scroll) {
1891
+ if (timer) {
1892
+ clearInterval(timer);
1893
+ timer = null;
1894
+ }
1895
+ }
1896
+ //restore container position
1897
+ if (originPos) {
1898
+ con.style.position = originPos;
1899
+ }
1900
+ each(selection, (t) => {
1901
+ each(selectingClassAry, (cls) => {
1902
+ t.classList.toggle(cls, false);
1903
+ });
1904
+ each(selectedClassAry, (cls) => {
1905
+ t.classList.toggle(cls, true);
1906
+ });
1907
+ t.classList.toggle(CLASS_SELECTING, false);
1908
+ t.classList.toggle(CLASS_SELECTED, true);
1909
+ });
1910
+ __classPrivateFieldSet(this, _Selectable__lastSelected, selection, "f");
1911
+ if (dragging)
1912
+ call(onEnd, selection);
1913
+ };
1914
+ document.addEventListener("mousemove", dragListener, false);
1915
+ document.addEventListener("mouseup", dragEndListener, false);
1916
+ window.addEventListener("blur", dragEndListener, false);
1917
+ e.preventDefault();
1918
+ return false;
1919
+ });
1920
+ };
1921
+ /**
1922
+ * Add a selector into the container
1923
+ * @param container css selector or html element
1924
+ * @param opts
1925
+ * @returns
1926
+ */
1927
+ function newSelectable(container, opts) {
1928
+ return new Selectable(container, opts);
1929
+ }
1930
+
1931
+ var version = "1.0.0";
1932
+ var repository = {
1933
+ type: "git",
1934
+ url: "https://github.com/holyhigh2/uii"
1935
+ };
1936
+
1937
+ // welcome info
1938
+ const welcome = globalThis.top
1939
+ ? globalThis.top.welcome
1940
+ : globalThis.welcome;
1941
+ if (!welcome) {
1942
+ const ssAry = [];
1943
+ ['102,227,255', '59,208,251', '67,180,255'].forEach((v, i) => {
1944
+ const cu = 'background:rgb(' + v + ');';
1945
+ if (i < 2) {
1946
+ ssAry[i] = ssAry[5 - 1 - i] = cu;
1947
+ }
1948
+ else {
1949
+ ssAry[i] = 'color:#fff;' + cu;
1950
+ }
1951
+ });
1952
+ console.info(`%c %c %c Uii - UI Interactions | v${version} %c %c `, ...ssAry, `💎 ${repository.url}`);
1953
+ if (globalThis.top) {
1954
+ globalThis.top.welcome = true;
1955
+ }
1956
+ else {
1957
+ globalThis.welcome = true;
1958
+ }
1959
+ }
1960
+ const VERSION = version;
1961
+ var index = {
1962
+ VERSION: version,
1963
+ newSplittable,
1964
+ newResizable,
1965
+ newDraggable,
1966
+ newDroppable,
1967
+ newRotatable,
1968
+ newSelectable
1969
+ };
1970
+
1971
+ export { CollisionDetector, Draggable, Droppable, Resizable, Rotatable, Selectable, Splittable, Uii, VERSION, index as default, newCollisionDetector, newDraggable, newDroppable, newResizable, newRotatable, newSelectable, newSplittable };