@itfin/components 1.3.95 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/package.json +1 -1
  2. package/src/assets/scss/_css_variables.scss +2 -2
  3. package/src/assets/scss/_variables.scss +18 -7
  4. package/src/assets/scss/components/_button.scss +10 -0
  5. package/src/assets/scss/components/_pagination.scss +4 -1
  6. package/src/assets/scss/components/_select.scss +1 -3
  7. package/src/assets/scss/components/_text-field.scss +17 -7
  8. package/src/assets/scss/main.scss +36 -2
  9. package/src/components/app/message.js +1 -1
  10. package/src/components/button/Button.vue +4 -2
  11. package/src/components/filter/FilterAmountRange.vue +50 -42
  12. package/src/components/filter/FilterBadge.vue +25 -22
  13. package/src/components/filter/FilterFacetsList.vue +1 -1
  14. package/src/components/filter/FilterPanel.vue +82 -27
  15. package/src/components/filter/index.stories.js +0 -2
  16. package/src/components/icon/Icon.vue +3 -1
  17. package/src/components/icon/components/fi_fingerprint.vue +4 -0
  18. package/src/components/icon/components/nomi-arrow-down.vue +4 -0
  19. package/src/components/icon/components/nomi-arrow-right-top.vue +4 -0
  20. package/src/components/icon/components/nomi-arrow-up.vue +4 -0
  21. package/src/components/icon/components/nomi-arrows.vue +7 -0
  22. package/src/components/icon/components/nomi-calendar-alt.vue +4 -0
  23. package/src/components/icon/components/nomi-calendar.vue +11 -0
  24. package/src/components/icon/components/nomi-card.vue +4 -0
  25. package/src/components/icon/components/nomi-close.vue +5 -0
  26. package/src/components/icon/components/nomi-eye-close.vue +4 -0
  27. package/src/components/icon/components/nomi-eye-open.vue +4 -0
  28. package/src/components/icon/components/nomi-filter.vue +4 -0
  29. package/src/components/icon/components/nomi-hide.vue +4 -0
  30. package/src/components/icon/components/nomi-money.vue +4 -0
  31. package/src/components/icon/components/nomi-move-left.vue +4 -0
  32. package/src/components/icon/components/nomi-move-right.vue +4 -0
  33. package/src/components/icon/components/nomi-person.vue +5 -0
  34. package/src/components/icon/components/nomi-pin.vue +7 -0
  35. package/src/components/icon/components/nomi-sort-asc.vue +7 -0
  36. package/src/components/icon/components/nomi-sort-desc.vue +7 -0
  37. package/src/components/icon/components/nomi-table-view.vue +4 -0
  38. package/src/components/icon/components/nomi-tag.vue +4 -0
  39. package/src/components/icon/components/nomi-target.vue +4 -0
  40. package/src/components/icon/components/nomi-text.vue +6 -0
  41. package/src/components/icon/components/nomi-unpin.vue +7 -0
  42. package/src/components/icon/convert-icons.js +11 -0
  43. package/src/components/icon/icons.js +302 -277
  44. package/src/components/icon/new-icons/arrow-down.svg +3 -0
  45. package/src/components/icon/new-icons/arrow-right-top.svg +3 -0
  46. package/src/components/icon/new-icons/arrow-up.svg +3 -0
  47. package/src/components/icon/new-icons/arrows.svg +6 -0
  48. package/src/components/icon/new-icons/calendar-alt.svg +3 -0
  49. package/src/components/icon/new-icons/calendar.svg +10 -0
  50. package/src/components/icon/new-icons/card.svg +3 -0
  51. package/src/components/icon/new-icons/clear.svg +3 -0
  52. package/src/components/icon/new-icons/close.svg +4 -0
  53. package/src/components/icon/new-icons/eye-close.svg +3 -0
  54. package/src/components/icon/new-icons/eye-open.svg +3 -0
  55. package/src/components/icon/new-icons/filter.svg +3 -0
  56. package/src/components/icon/new-icons/hide.svg +3 -0
  57. package/src/components/icon/new-icons/money.svg +3 -0
  58. package/src/components/icon/new-icons/move-left.svg +3 -0
  59. package/src/components/icon/new-icons/move-right.svg +3 -0
  60. package/src/components/icon/new-icons/person.svg +4 -0
  61. package/src/components/icon/new-icons/pin.svg +6 -0
  62. package/src/components/icon/new-icons/sort-asc.svg +6 -0
  63. package/src/components/icon/new-icons/sort-desc.svg +6 -0
  64. package/src/components/icon/new-icons/table-view.svg +3 -0
  65. package/src/components/icon/new-icons/tag.svg +3 -0
  66. package/src/components/icon/new-icons/target.svg +3 -0
  67. package/src/components/icon/new-icons/text.svg +5 -0
  68. package/src/components/icon/new-icons/unpin.svg +6 -0
  69. package/src/components/pagination/Pagination.vue +3 -2
  70. package/src/components/pagination/Pagination2.vue +176 -0
  71. package/src/components/panels/Panel.vue +5 -1
  72. package/src/components/panels/PanelItemEdit.vue +61 -0
  73. package/src/components/panels/PanelList.vue +2 -0
  74. package/src/components/select/Select.vue +1 -1
  75. package/src/components/sortable/draggable.js +2 -1
  76. package/src/components/table/Table2.vue +24 -1
  77. package/src/components/table/TableBody.vue +7 -2
  78. package/src/components/table/TableGroup.vue +8 -4
  79. package/src/components/table/TableHeader.vue +101 -24
  80. package/src/components/table/TableRows.vue +5 -3
  81. package/src/components/table/index.stories.js +22 -200
  82. package/src/components/table/table2.scss +179 -52
  83. package/src/components/text-field/MoneyField.vue +2 -2
  84. package/src/components/text-field/TextField.vue +12 -8
  85. package/src/components/tree/TreeEditor.vue +602 -0
  86. package/src/components/view/View.vue +119 -0
  87. package/src/components/view/index.stories.js +588 -0
  88. package/src/helpers/formatters.js +14 -1
  89. package/src/helpers/tree/cdbl.js +32 -0
  90. package/src/helpers/tree/cint.js +43 -0
  91. package/src/helpers/tree/domDrag.js +911 -0
  92. package/src/helpers/tree/domFinds.js +20 -0
  93. package/src/helpers/tree/domGetPointFromEvent.js +53 -0
  94. package/src/helpers/tree/domIsClientXYIn.js +65 -0
  95. package/src/helpers/tree/domRemove.js +50 -0
  96. package/src/helpers/tree/evem.js +27 -0
  97. package/src/helpers/tree/genID.js +56 -0
  98. package/src/helpers/tree/isEle.js +28 -0
  99. package/src/helpers/tree/isestr.js +35 -0
  100. package/src/helpers/tree/isint.js +40 -0
  101. package/src/helpers/tree/isnbr.js +24 -0
  102. package/src/helpers/tree/isnum.js +38 -0
  103. package/src/helpers/tree/ispint.js +41 -0
  104. package/src/helpers/tree/isstr.js +27 -0
  105. package/src/helpers/tree.js +30 -0
  106. package/src/helpers/vuetifyColor.js +136 -0
  107. package/src/locales/en.js +13 -0
  108. package/src/locales/uk.js +11 -0
  109. package/src/components/table/TableRow.vue +0 -221
@@ -0,0 +1,911 @@
1
+ import each from 'lodash/each'
2
+ import get from 'lodash/get'
3
+ import isNumber from 'lodash/isNumber'
4
+ import isBoolean from 'lodash/isBoolean'
5
+ import genID from './genID.js'
6
+ import isestr from './isestr.js'
7
+ import cint from './cint.js'
8
+ import evem from './evem.js'
9
+ import domIsClientXYIn from './domIsClientXYIn.js'
10
+ import domRemove from './domRemove.js'
11
+ import domGetPointFromEvent from './domGetPointFromEvent.js'
12
+ import isElement from "lodash/isElement";
13
+
14
+
15
+ function getEles(ele, selectors) {
16
+ let eles = null
17
+ try {
18
+ eles = ele.querySelectorAll(selectors)
19
+ }
20
+ catch (err) { }
21
+ return eles
22
+ }
23
+
24
+
25
+ function getAttr(ele, attr) {
26
+ let r = null
27
+ try {
28
+ r = ele.getAttribute(attr)
29
+ }
30
+ catch (err) {}
31
+ return r
32
+ }
33
+
34
+
35
+ // function domFindParent(ele, f) {
36
+ // let r = null
37
+
38
+ // //check
39
+ // if (!isEle(ele)) {
40
+ // console.log('ele is not HTMLElement')
41
+ // return r
42
+ // }
43
+ // if (!isfun(f)) {
44
+ // console.log('invalid f')
45
+ // return r
46
+ // }
47
+
48
+ // //while
49
+ // let parent = ele
50
+ // try {
51
+ // while (parent) {
52
+
53
+ // //check
54
+ // if (f(parent)) {
55
+ // r = parent
56
+ // break
57
+ // }
58
+
59
+ // //parentNode
60
+ // parent = parent.parentNode
61
+
62
+ // }
63
+ // }
64
+ // catch (err) {
65
+ // console.log('can not find parent in while', err)
66
+ // }
67
+ // return r
68
+ // }
69
+
70
+
71
+ function getBoudRect(ele) {
72
+ try {
73
+ return ele.getBoundingClientRect()
74
+ }
75
+ catch (err) {}
76
+ return null
77
+ }
78
+
79
+
80
+ function getPointRefLoc(p, ele) {
81
+ let rt = getBoudRect(ele)
82
+ if (!rt) {
83
+ return null
84
+ }
85
+ let x = p.clientX - rt.left //事件的clientX,Y是基於瀏覽器可視區域左上角的座標
86
+ let y = p.clientY - rt.top
87
+ let w = ele.offsetWidth
88
+ let h = ele.offsetHeight
89
+ return {
90
+ x, y, w, h
91
+ }
92
+ }
93
+
94
+
95
+ // function isInner(p, ele) {
96
+ // let rl = getPointRefLoc(p, ele)
97
+ // if (!rl) {
98
+ // return false
99
+ // }
100
+ // return rl.x >= 0 && rl.x <= rl.w && rl.y >= 0 && rl.y <= rl.h
101
+ // }
102
+
103
+
104
+ function getIndex(ele, attIndex) {
105
+ let kitem = getAttr(ele, attIndex)
106
+ kitem = cint(kitem)
107
+ return kitem
108
+ }
109
+
110
+
111
+ function dragPreview(opt = {}) {
112
+ let _prevName = '_prevName'
113
+ let _ele = null
114
+ let _node = null
115
+ let _cover = null
116
+ let _shell = null
117
+ let _container = null
118
+
119
+ //attIdentify, 產生preview會於preview內刪除, 並偵測該欄位與值是否有存在
120
+ let attIdentify = get(opt, 'attIdentify', null)
121
+ if (!isestr(attIdentify)) {
122
+ attIdentify = 'dragid'
123
+ }
124
+
125
+ //containerOpacity
126
+ let containerOpacity = get(opt, 'containerOpacity', null)
127
+ if (!isNumber(containerOpacity)) {
128
+ containerOpacity = 0.4
129
+ }
130
+
131
+ //containerBackground
132
+ let containerBackground = get(opt, 'containerBackground', null)
133
+ if (!isestr(containerBackground)) {
134
+ containerBackground = 'white'
135
+ }
136
+
137
+ //containerBorderWidth
138
+ let containerBorderWidth = get(opt, 'containerBorderWidth', null)
139
+ if (!isNumber(containerBorderWidth)) {
140
+ containerBorderWidth = 1
141
+ }
142
+
143
+ //containerBorderColor
144
+ let containerBorderColor = get(opt, 'containerBorderColor', null)
145
+ if (!isestr(containerBorderColor)) {
146
+ containerBorderColor = '#f26'
147
+ }
148
+
149
+ function cloneNode(ele, x, y) {
150
+ //console.log('cloneNode')
151
+
152
+ //getBoudRect
153
+ let rt = getBoudRect(ele)
154
+ if (!rt) {
155
+ return
156
+ }
157
+
158
+ //備份ele
159
+ _ele = ele
160
+
161
+ //深複製
162
+ let nd = ele.cloneNode(true)
163
+
164
+ //儲存資訊
165
+ nd.tShiftX = x - rt.left
166
+ nd.tShiftY = y - rt.top
167
+ nd.tWidth = ele.offsetWidth
168
+ nd.tHeight = ele.offsetHeight
169
+ nd.tParent = ele.parentNode
170
+ nd.setAttribute(attIdentify, '') //清除attIdentify欄位, 使全域存在唯一識別元素
171
+
172
+ return nd
173
+ }
174
+
175
+ function createPreview(ele, x, y) {
176
+ //console.log('createPreview')
177
+
178
+ function core() {
179
+
180
+ //複製ele
181
+ let node = cloneNode(ele, x, y)
182
+
183
+ //創建container
184
+ let container = document.createElement('div')
185
+ container.setAttribute('dragpreview', _prevName)
186
+
187
+ //創建殼層shell
188
+ let shell = document.createElement('div')
189
+ shell.style.position = 'relative'
190
+
191
+ //將複製的ele(node)塞入shell
192
+ shell.appendChild(node)
193
+
194
+ //創建遮罩cover
195
+ let cover = document.createElement('div')
196
+ cover.style.position = 'absolute'
197
+ cover.style.zIndex = 1
198
+ cover.style.top = 0
199
+ cover.style.left = 0
200
+ cover.style.width = '100%'
201
+ cover.style.height = '100%'
202
+
203
+ //將cover塞入shell
204
+ shell.appendChild(cover)
205
+
206
+ //將shell塞入container
207
+ container.appendChild(shell)
208
+ container.style.position = 'fixed'
209
+ container.style.zIndex = 100000
210
+ //container.style.pointerEvents = 'none' //會導致游標樣式失效
211
+ container.style.width = `${node.tWidth + 2 * containerBorderWidth}px`
212
+ container.style.height = `${node.tHeight + 2 * containerBorderWidth}px`
213
+ container.style.opacity = containerOpacity
214
+ container.style.background = containerBackground
215
+ container.style.border = `${containerBorderWidth}px solid ${containerBorderColor}`
216
+
217
+ //將container塞入原本ele的父層內
218
+ node.tParent.appendChild(container)
219
+
220
+ //儲存至全域
221
+ _node = node
222
+ _cover = cover
223
+ _shell = shell
224
+ _container = container
225
+
226
+ //updateDragPreview
227
+ updateDragPreview(x, y, 'createPreview')
228
+
229
+ }
230
+
231
+ //core, 暴力try catch攔錯, 因可能原dom例如是按鈕要自我刪除故會導致出錯
232
+ try {
233
+ core()
234
+ }
235
+ catch (err) {}
236
+
237
+ //檢查原始元素是否存在, 若例如拖曳項目是可自我刪除的按鈕, 就有可能產生preview後原始元素被刪除, 故需跟著清除preview
238
+ let t = setInterval(() => {
239
+ let dragid = getAttr(_ele, 'dragid')
240
+ let draggroup = getAttr(_ele, 'draggroup')
241
+ let ele = document.querySelector(`[dragid='${dragid}'][draggroup='${draggroup}']`)
242
+ if (!ele) {
243
+ clearInterval(t)
244
+ removeDragPreview()
245
+ }
246
+ }, 500)
247
+
248
+ }
249
+
250
+ function updateDragPreview(x, y, from) {
251
+ //console.log('updateDragPreview', x, y, from)
252
+
253
+ //check
254
+ if (!_node || !_cover || !_shell || !_container) {
255
+ return
256
+ }
257
+
258
+ //update
259
+ _container.style.top = `${y - _node.tShiftY}px`
260
+ _container.style.left = `${x - _node.tShiftX}px`
261
+
262
+ }
263
+
264
+ function removeDragPreview() {
265
+ //console.log('removeDragPreview')
266
+
267
+ //domRemove
268
+ domRemove(`[dragpreview=${_prevName}]`)
269
+
270
+ //clear
271
+ _node = null
272
+ _cover = null
273
+ _shell = null
274
+ _container = null
275
+
276
+ }
277
+
278
+ let evMM = function(e) {
279
+ //console.log('window mousemove', e)
280
+ updateDragPreview(e.clientX, e.clientY, 'window mousemove')
281
+ }
282
+ window.addEventListener('mousemove', evMM)
283
+
284
+ let evTM = function(e) {
285
+ //console.log('window touchmove', e)
286
+ let p = domGetPointFromEvent(e)
287
+ if (p) {
288
+ updateDragPreview(p.clientX, p.clientY, 'window touchmove')
289
+ }
290
+ }
291
+ window.addEventListener('touchmove', evTM)
292
+
293
+ function setNodeStyle(st) {
294
+ try {
295
+ each(st, (v, k) => {
296
+ _node.style[k] = v
297
+ })
298
+ }
299
+ catch (err) {}
300
+ }
301
+
302
+ function setCoverStyle(st) {
303
+ try {
304
+ each(st, (v, k) => {
305
+ _cover.style[k] = v
306
+ })
307
+ }
308
+ catch (err) {}
309
+ }
310
+
311
+ function setSellStyle(st) {
312
+ try {
313
+ each(st, (v, k) => {
314
+ _shell.style[k] = v
315
+ })
316
+ }
317
+ catch (err) {}
318
+ }
319
+
320
+ function setContainerStyle(st) {
321
+ try {
322
+ each(st, (v, k) => {
323
+ _container.style[k] = v
324
+ })
325
+ }
326
+ catch (err) {}
327
+ }
328
+
329
+ function clear() {
330
+ window.removeEventListener('mousemove', evMM)
331
+ window.removeEventListener('touchmove', evTM)
332
+ }
333
+
334
+ return {
335
+ createPreview,
336
+ updateDragPreview,
337
+ removeDragPreview,
338
+ setNodeStyle,
339
+ setCoverStyle,
340
+ setSellStyle,
341
+ setContainerStyle,
342
+ clear,
343
+ }
344
+ }
345
+
346
+
347
+ /**
348
+ * 前端監聽DOM元素陣列拖曳事件
349
+ *
350
+ * Unit Test: {@link https://github.com/yuda-lyu/wsemi/blob/master/test/domDrag.test.js Github}
351
+ * @memberOf wsemi
352
+ * @param {HTMLElement} ele 輸入元素
353
+ * @param {Object} [opt={}] 輸入設定物件,預設{}
354
+ * @param {String} [opt.active=true] 輸入是否啟用拖曳功能布林值,預設true
355
+ * @param {String} [opt.attIdentify='dragid'] 輸入標記元素唯一識別用字串,預設'dragid'
356
+ * @param {String} [opt.attIndex='dragindex'] 輸入標記元素順序指標字串,預設'dragindex'
357
+ * @param {String} [opt.attGroup='draggroup'] 輸入標記元素群組字串,預設'draggroup'
358
+ * @param {String} [opt.selectors='[dragtag]'] 輸入查詢元素用字串,主要是給draggable.js用來標記哪些元素可被拖曳之用,預設'[dragtag]'
359
+ * @param {Number} [opt.timeDragStartDelay=120] 輸入標記元素由點擊後延遲出現的時間數字,單位ms,預設120。使用pointerEvents會導致游標樣式失效,故延遲顯示可用來讓點擊事件穿透
360
+ * @param {Number} [opt.previewOpacity=0.4] 輸入標記元素透明度數字,預設0.4
361
+ * @param {String} [opt.previewBackground='white'] 輸入標記元素背景顏色字串,預設'white'
362
+ * @param {Number} [opt.previewBorderWidth=1] 輸入標記元素邊框寬度數字,預設1
363
+ * @param {String} [opt.previewBorderColor='#f26'] 輸入標記元素邊框顏色字串,預設'#f26'
364
+ * @returns {Object} 回傳物件,可使用on與clear函數,on可監聽change、start、move、enter、leave、drop事件,clear為釋放監聽
365
+ * @example
366
+ * need test in browser
367
+ *
368
+ * //監聽dom
369
+ * let dd = domDrag(document.querySelector('#id'), { attIndex: 'dragindex', selectors: '[dragtag]' })
370
+ *
371
+ * //change
372
+ * dd.on('change', (msg) => {
373
+ * console.log('change', msg)
374
+ * })
375
+ * dd.on('start', (msg) => {
376
+ * console.log('start', msg)
377
+ * })
378
+ * dd.on('move', (msg) => {
379
+ * console.log('move', msg)
380
+ * })
381
+ * dd.on('enter', (msg) => {
382
+ * console.log('enter', msg)
383
+ * })
384
+ * dd.on('leave', (msg) => {
385
+ * console.log('leave', msg)
386
+ * })
387
+ * dd.on('drop', (msg) => {
388
+ * console.log('drop', msg)
389
+ * })
390
+ *
391
+ * //釋放監聽
392
+ * dd.clear()
393
+ *
394
+ */
395
+ function domDrag(ele, opt = {}) {
396
+ let _startInd = null
397
+ let _startEle = null
398
+ let _endInd = null
399
+ let _endEle = null
400
+ let _events = []
401
+ let _dragStartPoint = null
402
+ let _createdPreview = false
403
+
404
+ //check
405
+ if (!isElement(ele)) {
406
+ console.log('ele is not HTMLElement', ele)
407
+ return
408
+ }
409
+
410
+ //attIdentify
411
+ let attIdentify = get(opt, 'attIdentify', null)
412
+ if (!isestr(attIdentify)) {
413
+ attIdentify = 'dragid'
414
+ }
415
+
416
+ //attIndex
417
+ let attIndex = get(opt, 'attIndex', null)
418
+ if (!isestr(attIndex)) {
419
+ attIndex = 'dragindex'
420
+ }
421
+
422
+ //attGroup
423
+ let attGroup = get(opt, 'attGroup', null)
424
+ if (!isestr(attGroup)) {
425
+ attGroup = 'draggroup'
426
+ }
427
+
428
+ //selectors
429
+ let selectors = get(opt, 'selectors', null)
430
+ if (!isestr(selectors)) {
431
+ selectors = '[dragtag]'
432
+ }
433
+
434
+ //active
435
+ let active = get(opt, 'active', null)
436
+ if (!isBoolean(active)) {
437
+ active = true
438
+ }
439
+
440
+ //timeDragStartDelay
441
+ let timeDragStartDelay = get(opt, 'timeDragStartDelay', null)
442
+ if (!isNumber(timeDragStartDelay)) {
443
+ timeDragStartDelay = 120
444
+ }
445
+
446
+ //previewOpacity
447
+ let previewOpacity = get(opt, 'previewOpacity', null)
448
+
449
+ //previewBackground
450
+ let previewBackground = get(opt, 'previewBackground', null)
451
+
452
+ //previewBorderWidth
453
+ let previewBorderWidth = get(opt, 'previewBorderWidth', null)
454
+
455
+ //previewBorderColor
456
+ let previewBorderColor = get(opt, 'previewBorderColor', null)
457
+
458
+ //dragPreview
459
+ let pv = dragPreview({
460
+ attIdentify,
461
+ containerOpacity: previewOpacity,
462
+ containerBackground: previewBackground,
463
+ containerBorderWidth: previewBorderWidth,
464
+ containerBorderColor: previewBorderColor,
465
+ })
466
+
467
+ //eles
468
+ let eles = getEles(ele, selectors)
469
+ if (!eles) {
470
+ console.log('初始化時無法取得拖曳元素')
471
+ return
472
+ }
473
+
474
+ //gid
475
+ let gid = 'dg' + genID(8)
476
+
477
+ //setAttrs
478
+ function setAttrs() {
479
+ each(eles, (ele, k) => {
480
+ ele.setAttribute(attGroup, gid)
481
+ ele.setAttribute(attIdentify, `dg-${genID(8)}`)
482
+ })
483
+ }
484
+
485
+ //bindEvents
486
+ function bindEvents() {
487
+ let f
488
+ let name
489
+
490
+ name = 'mousemove'
491
+ f = function(e) {
492
+ dragMove(e, 'mousemove')
493
+ }
494
+ window.addEventListener(name, f)
495
+ _events.push({ ele: window, name, f })
496
+
497
+ name = 'mouseup'
498
+ f = function(e) {
499
+ dragDrop(e, 'mouseup')
500
+ }
501
+ window.addEventListener(name, f)
502
+ _events.push({ ele: window, name, f })
503
+
504
+ name = 'touchmove'
505
+ f = function(e) {
506
+ dragMove(e, 'touchmove')
507
+ }
508
+ window.addEventListener(name, f)
509
+ _events.push({ ele: window, name, f })
510
+
511
+ name = 'touchend'
512
+ f = function(e) {
513
+ dragDrop(e, 'touchend')
514
+ }
515
+ window.addEventListener(name, f)
516
+ _events.push({ ele: window, name, f })
517
+
518
+ each(eles, (ele, k) => { //k不可信, 而eles綁定成為元素需自動更新, 因例如用vue由數據順序產生元素, 當拖曳完的eles將不會是原始元素順序, 但eles仍為原始數據順序
519
+ let dragEl = ele;
520
+ if (opt.handle) {
521
+ dragEl = ele.querySelector(opt.handle);
522
+ }
523
+ name = 'mousedown'
524
+ f = function(e) {
525
+ dragStart(e, ele, 'mousedown')
526
+ }
527
+ dragEl.addEventListener(name, f, false)
528
+ _events.push({ ele, name, f })
529
+
530
+ name = 'touchstart'
531
+ f = function(e) {
532
+ dragStart(e, ele, 'touchstart')
533
+ }
534
+ dragEl.addEventListener(name, f, false)
535
+ _events.push({ ele, name, f })
536
+
537
+ name = 'touchmove'
538
+ f = function(e) {
539
+ //domCancelEvent(e) //不能使用domCancelEvent, 因其內使用stopPropagation會連window的touchmove無法收到訊息
540
+ if (e.cancelable) { //window捲動中時事件為禁止取消(cancelable=false)狀態
541
+ e.preventDefault() //必要, 需由元素touchmove事件阻止預設拖曳行為, 否則會變成捲動螢幕, 此外由window的touchmove事件來阻止會失效
542
+ }
543
+ }
544
+ dragEl.addEventListener(name, f, false)
545
+ _events.push({ ele, name, f })
546
+
547
+ })
548
+ }
549
+
550
+ //unbindEvents
551
+ function unbindEvents() {
552
+ each(_events, ({ ele, name, f }) => {
553
+ ele.removeEventListener(name, f)
554
+ })
555
+ }
556
+
557
+ function safeCreatePreview() {
558
+ if (_startEle === null) {
559
+ return
560
+ }
561
+ if (!_createdPreview) {
562
+ let p = _dragStartPoint
563
+ pv.createPreview(_startEle, p.clientX, p.clientY)
564
+ _createdPreview = true
565
+ }
566
+ }
567
+
568
+
569
+ function findEleFromEvent(e) {
570
+ let eleIn = null
571
+
572
+ //p
573
+ let p = domGetPointFromEvent(e)
574
+ if (!p) {
575
+ return eleIn
576
+ }
577
+
578
+ //each
579
+ for (let i = 0; i < eles.length; i++) {
580
+ let ele = eles[i]
581
+ let b = domIsClientXYIn(p.clientX, p.clientY, ele)
582
+ if (b) {
583
+ eleIn = ele
584
+ break
585
+ }
586
+ }
587
+
588
+ return eleIn
589
+ }
590
+
591
+ function setActive(bol) {
592
+ active = bol
593
+ }
594
+
595
+ function dragStart(e, ele, from) {
596
+ //console.log('dragStart', e, ele, from)
597
+
598
+ //check
599
+ if (!active) {
600
+ return
601
+ }
602
+
603
+ //getIndex
604
+ let kitem = getIndex(ele, attIndex)
605
+
606
+ //check
607
+ if (kitem === null) { //不能用!kitem判斷, 因kitem可能為0
608
+ //console.log('dragStart: 無法取得kitem')
609
+ return
610
+ }
611
+
612
+ _startInd = kitem
613
+ _startEle = ele
614
+
615
+ //emit
616
+ let msg = {
617
+ event: e,
618
+ startInd: _startInd,
619
+ startEle: _startEle,
620
+ }
621
+ ev.emit('change', { mode: 'start', ...msg })
622
+ ev.emit('start', msg)
623
+
624
+ //p
625
+ let p = domGetPointFromEvent(e)
626
+ if (!p) {
627
+ return
628
+ }
629
+
630
+ //save _dragStartPoint
631
+ _dragStartPoint = p
632
+
633
+ //setTimeout, preview不能太快出現導致原本元素例如click事件失效
634
+ setTimeout(() => {
635
+
636
+ //check, 若觸發例如dragDrop事件因已清除故會無_startInd
637
+ if (_startInd === null) {
638
+ return
639
+ }
640
+
641
+ //safeCreatePreview
642
+ safeCreatePreview()
643
+
644
+ //setCoverStyle, 必要, 快速拖曳但只在原拖曳項目時就需要能更改滑鼠游標
645
+ pv.setCoverStyle({ cursor: 'no-drop' })
646
+
647
+ }, timeDragStartDelay)
648
+
649
+ }
650
+
651
+ function dragMove(e, from) {
652
+ //console.log('dragMove', e, from)
653
+
654
+ //check
655
+ if (!active) {
656
+ return
657
+ }
658
+
659
+ //check
660
+ if (_startInd === null) {
661
+ return
662
+ }
663
+
664
+ //p
665
+ let p = domGetPointFromEvent(e)
666
+ if (!p) {
667
+ return
668
+ }
669
+
670
+ function emitEnter(endInd, endEle) {
671
+ _endInd = endInd
672
+ _endEle = endEle
673
+
674
+ //emit
675
+ let msg = {
676
+ event: e,
677
+ startInd: _startInd,
678
+ startEle: _startEle,
679
+ endInd: _endInd,
680
+ endEle: _endEle,
681
+ }
682
+ ev.emit('change', { mode: 'enter', ...msg })
683
+ ev.emit('enter', msg)
684
+
685
+ //safeCreatePreview
686
+ safeCreatePreview()
687
+
688
+ //setCoverStyle
689
+ pv.setCoverStyle({ cursor: 'pointer' })
690
+
691
+ }
692
+
693
+ function emitLeave() {
694
+
695
+ //emit
696
+ let msg = {
697
+ event: e,
698
+ startInd: _startInd,
699
+ startEle: _startEle,
700
+ endInd: _endInd,
701
+ endEle: _endEle,
702
+ }
703
+ ev.emit('change', { mode: 'leave', ...msg })
704
+ ev.emit('leave', msg)
705
+
706
+ //clear, 要放在emit之後才能清除
707
+ _endInd = null
708
+ _endEle = null
709
+
710
+ //setCoverStyle
711
+ pv.setCoverStyle({ cursor: 'no-drop' })
712
+
713
+ }
714
+
715
+ function emitMove(rl, rx, ry) {
716
+
717
+ //emit
718
+ let msg = {
719
+ event: e,
720
+ startInd: _startInd,
721
+ startEle: _startEle,
722
+ endInd: _endInd,
723
+ endEle: _endEle,
724
+ ...rl,
725
+ rx,
726
+ ry,
727
+ }
728
+ ev.emit('change', { mode: 'move', ...msg })
729
+ ev.emit('move', msg)
730
+
731
+ //safeCreatePreview
732
+ safeCreatePreview()
733
+
734
+ //setCoverStyle, 必要, 因現在dragStart為延遲觸發會setCoverStyle為no-drop, 當使用者拖曳過快, 就會先觸發完enter內的setCoverStyle, 才換dragStart內延遲觸發setCoverStyle導致游標有誤
735
+ pv.setCoverStyle({ cursor: 'pointer' })
736
+
737
+ //updateDragPreview
738
+ pv.updateDragPreview(p.clientX, p.clientY, 'emitMove')
739
+
740
+ }
741
+
742
+ //eleIn
743
+ let eleIn = findEleFromEvent(e)
744
+
745
+ //check, 滑鼠所在處的可被拖曳元素
746
+ if (!eleIn) {
747
+
748
+ //check
749
+ if (_endInd !== null) {
750
+
751
+ //emitLeave
752
+ emitLeave()
753
+
754
+ }
755
+
756
+ return
757
+ }
758
+
759
+ //getIndex
760
+ let kitem = getIndex(eleIn, attIndex)
761
+
762
+ //check
763
+ if (kitem === null) { //不能用!kitem判斷, 因kitem可能為0
764
+ //console.log('dragMove: 無法取得kitem')
765
+ return
766
+ }
767
+
768
+ //check
769
+ if (kitem === _startInd) { //拖曳至原拖曳項目
770
+
771
+ //由其他拖曳項目拖曳至原拖曳項目內, 需要觸發leave事件
772
+ if (_endInd !== null) {
773
+
774
+ //emitLeave
775
+ emitLeave()
776
+
777
+ }
778
+
779
+ return
780
+ }
781
+
782
+ //check
783
+ if (kitem !== _endInd) { //拖曳至不同於上一個拖曳項目
784
+ //enter
785
+
786
+ //於其他拖曳項目之間拖曳, 且非拖曳至原拖曳項目, 故也需要觸發leave事件
787
+ if (_endInd !== null) {
788
+
789
+ //emitLeave
790
+ emitLeave()
791
+
792
+ }
793
+
794
+ //emitEnter
795
+ emitEnter(kitem, eleIn)
796
+
797
+ }
798
+ else { //move, 於上一個拖曳項目內拖曳
799
+
800
+ //rl
801
+ let rl = getPointRefLoc(p, eleIn)
802
+
803
+ //rx, ry
804
+ let rx = 0
805
+ if (rl.w > 0) {
806
+ rx = rl.x / rl.w
807
+ }
808
+ let ry = 0
809
+ if (rl.h > 0) {
810
+ ry = rl.y / rl.h
811
+ }
812
+
813
+ if (rx >= 0 && rx <= 1 && ry >= 0 && ry <= 1) {
814
+
815
+ //emitMove
816
+ emitMove(rl, rx, ry)
817
+
818
+ }
819
+
820
+ }
821
+
822
+ }
823
+
824
+ function dragDrop(e, from) {
825
+ //console.log('dragDrop', e, from)
826
+
827
+ //check
828
+ if (!active) {
829
+ return
830
+ }
831
+
832
+ //removeDragPreview
833
+ pv.removeDragPreview()
834
+ _createdPreview = false
835
+
836
+ //check
837
+ if (_startInd === null) {
838
+ //console.log('dragDrop: 無_startInd')
839
+ return
840
+ }
841
+
842
+ function emitDrop(endInd, endEle) {
843
+ _endInd = endInd
844
+ _endEle = endEle
845
+
846
+ //emit
847
+ let msg = {
848
+ event: e,
849
+ startInd: _startInd,
850
+ startEle: _startEle,
851
+ endInd: _endInd,
852
+ endEle: _endEle,
853
+ }
854
+ ev.emit('change', { mode: 'drop', ...msg })
855
+ ev.emit('drop', msg)
856
+
857
+ }
858
+
859
+ //eleIn
860
+ let eleIn = findEleFromEvent(e)
861
+
862
+ //check, 釋放時不在拖曳元素內故跳出
863
+ if (!eleIn) {
864
+ //console.log('dragDrop: 釋放時不在拖曳元素內')
865
+ _startInd = null
866
+ _startEle = null
867
+ _endInd = null
868
+ _endEle = null
869
+ return
870
+ }
871
+
872
+ //getIndex
873
+ let kitem = getIndex(eleIn, attIndex)
874
+
875
+ //check
876
+ if (kitem === null) { //不能用!kitem判斷, 因kitem可能為0
877
+ //console.log('dragDrop: 無法取得kitem')
878
+ return
879
+ }
880
+
881
+ //emitDrop, 若拖曳至原拖曳項目上也要能觸發, 否則外部收不到滑鼠放掉訊息, 僅收得到拖曳至非拖曳項目的leave事件
882
+ emitDrop(kitem, eleIn)
883
+
884
+ //clear, 要放在emit之後才能清除
885
+ _startInd = null
886
+ _startEle = null
887
+ _endInd = null
888
+ _endEle = null
889
+
890
+ }
891
+
892
+ //ev
893
+ let ev = evem()
894
+
895
+ //bindEvents, setAttrs
896
+ bindEvents()
897
+ setAttrs()
898
+
899
+ //save
900
+ ev.gid = gid
901
+ ev.setActive = setActive
902
+ ev.clear = function() {
903
+ unbindEvents()
904
+ pv.clear()
905
+ }
906
+
907
+ return ev
908
+ }
909
+
910
+
911
+ export default domDrag