@cocreate/position 1.0.11 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,18 @@
1
+ ## [1.1.1](https://github.com/CoCreate-app/CoCreate-position/compare/v1.1.0...v1.1.1) (2022-11-21)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * bump d@cocreate ependencies ([f711142](https://github.com/CoCreate-app/CoCreate-position/commit/f711142bea5e104c96d04fb06a2dc4db94b41a7b))
7
+
8
+ # [1.1.0](https://github.com/CoCreate-app/CoCreate-position/compare/v1.0.11...v1.1.0) (2022-11-21)
9
+
10
+
11
+ ### Features
12
+
13
+ * incrementally increase z-index of movable elements ([ef33909](https://github.com/CoCreate-app/CoCreate-position/commit/ef339096868507078b0db780bdf593a06a9ff68c))
14
+ * observe attributes moveable and positionable ([2ffcb30](https://github.com/CoCreate-app/CoCreate-position/commit/2ffcb3022eaff83101e656749f6c4719380dbb90))
15
+
1
16
  ## [1.0.11](https://github.com/CoCreate-app/CoCreate-position/compare/v1.0.10...v1.0.11) (2022-10-02)
2
17
 
3
18
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cocreate/position",
3
- "version": "1.0.11",
3
+ "version": "1.1.1",
4
4
  "description": "Make any element draggable and movable. Customizable via attributes, great for popups, alerts, multitasking and displaying multiple views.",
5
5
  "keywords": [
6
6
  "position",
@@ -61,7 +61,7 @@
61
61
  "webpack-log": "^3.0.1"
62
62
  },
63
63
  "dependencies": {
64
- "@cocreate/docs": "^1.3.17",
65
- "@cocreate/observer": "^1.5.16"
64
+ "@cocreate/docs": "^1.3.20",
65
+ "@cocreate/observer": "^1.5.18"
66
66
  }
67
67
  }
package/src/index.js CHANGED
@@ -25,6 +25,15 @@ observer.init({
25
25
  }
26
26
  });
27
27
 
28
+ observer.init({
29
+ name: "positionAttributes",
30
+ observe: ['attributes'],
31
+ attributeName: ['moveable', 'positionable'],
32
+ callback: mutation => {
33
+ initElement(mutation.target);
34
+ }
35
+ });
36
+
28
37
  init()
29
38
 
30
39
  export default position;
package/src/position.js CHANGED
@@ -1,37 +1,38 @@
1
- function position(el, container) {
1
+ function position(el, container, options) {
2
2
  if (!(el && el.nodeType && el.nodeType === 1)) {
3
- return;
4
- }
5
-
6
- /** define constant **/
3
+ return;
4
+ }
5
+
6
+ /** define constant **/
7
7
  this.dragAreaHeight = 50;
8
- this.MARGIN = 5;
9
- this.FULLSCREEN_MARGIN = -60;
10
- this.NO_SNAP = -100;
11
- this.SNAP_MARGIN = -10;
12
- this.SELECT_ZINDEX = 10;
13
- this.UNSELECT_ZINDEX = 2;
14
-
15
- this.RIGHT_SCROL = 5;
16
-
17
- this.container = container;
18
- this.el = el;
19
- this.boundStatus = {};
20
-
8
+ this.MARGIN = 5;
9
+ this.FULLSCREEN_MARGIN = -60;
10
+ this.NO_SNAP = -100;
11
+ this.SNAP_MARGIN = -10;
12
+ this.RIGHT_SCROL = 5;
13
+
14
+ this.container = container;
15
+ if (!this.container.positionIndex)
16
+ this.container.positionIndex = 10
17
+
18
+ this.el = el;
19
+ this.boundStatus = {};
20
+
21
21
  this.selectedElement;
22
- /**
23
- * x: mouse x in element
24
- * y: mouse y in element
25
- * cx: x in document
26
- * cy: y in document
27
- * */
28
- this.point = {};
29
- this.rect = {};
30
- this.clickedInfo = null;
31
- this.preSnapped = null;
32
- this.isSnap = false;
33
- this.isHeader = true;
34
-
22
+ // this.selectedClass = "selectedPosition";
23
+ /**
24
+ * x: mouse x in element
25
+ * y: mouse y in element
26
+ * cx: x in document
27
+ * cy: y in document
28
+ * */
29
+ this.point = {};
30
+ this.rect = {};
31
+ this.clickedInfo = null;
32
+ this.preSnapped = null;
33
+ this.isSnap = false;
34
+ this.isHeader = true;
35
+
35
36
  this._createGhost(this.container.getAttribute("data-ghost-class"));
36
37
  this._initEvent();
37
38
  this._selectElement()
@@ -39,66 +40,57 @@ function position(el, container) {
39
40
 
40
41
  position.prototype = {
41
42
  constructor: position,
42
-
43
- _initEvent : function() {
43
+
44
+ _initEvent: function () {
44
45
  let self = this;
45
46
  this.iframe = this.el.querySelector('iframe')
46
47
  if (this.iframe) {
47
- this.iframe.addEventListener('load', function() {
48
- const iframeContent = self.iframe.contentDocument;
49
- iframeContent.addEventListener('click', function() {
50
- self.createEvent('elementSelected');
48
+ this.iframe.addEventListener('load', function () {
49
+ const iframeContent = self.iframe.contentDocument;
50
+ iframeContent.addEventListener('mousedown', function (e) {
51
+ self._selectElement(e.detail.element)
51
52
  })
52
53
  });
53
54
  }
54
55
 
55
- this.el.addEventListener("click", function(e) {
56
- self.createEvent('elementSelected');
57
- }, true)
58
-
59
- this.el.addEventListener('touchstart', function(e) {
60
- self.createEvent('elementSelected');
56
+ this.el.addEventListener('touchstart', function (e) {
57
+ self._selectElement(e.detail.element)
61
58
  self._onDown(e.touches[0]);
62
59
  })
63
-
64
- this.el.addEventListener('mousedown', function(e) {
65
- self.createEvent('elementSelected');
60
+
61
+ this.el.addEventListener('mousedown', function (e) {
62
+ self._selectElement(e.detail.element)
66
63
  self._onDown(e);
67
64
  })
68
65
 
69
- // events from container
70
- this.el.addEventListener('mousemove', function(e) {
66
+ this.el.addEventListener('mousemove', function (e) {
71
67
  e.preventDefault();
72
- self._onMove(e);
68
+ self._onMove(e);
73
69
  });
74
-
75
- this.el.addEventListener('mouseup', function(e) {
70
+
71
+ this.el.addEventListener('mouseup', function (e) {
76
72
  self._onUp(e);
77
73
  e.preventDefault();
78
74
  }, true);
79
75
 
80
- this.el.addEventListener('touchmove', function(e) {
76
+ this.el.addEventListener('touchmove', function (e) {
81
77
  self._onMove(e.touches[0]);
82
78
  }, { passive: false });
83
-
84
- this.el.addEventListener('touchend', function(e) {
79
+
80
+ this.el.addEventListener('touchend', function (e) {
85
81
  self._onUp(e.touches[0]);
86
82
  }, { passive: false });
87
83
 
88
- this.el.addEventListener('elementSelected', function(e) {
89
- self._selectElement(e.detail.element);
90
- })
91
-
92
84
  },
93
-
94
- _onMove : function(e) {
85
+
86
+ _onMove: function (e) {
95
87
  this.__getBoundStatus(e)
96
88
  this.__animate();
97
89
  },
98
-
99
- _onDown : function(e) {
90
+
91
+ _onDown: function (e) {
100
92
  this.__getBoundStatus(e);
101
-
93
+
102
94
  this.clickedInfo = {
103
95
  x: this.point.x,
104
96
  y: this.point.y,
@@ -107,12 +99,12 @@ position.prototype = {
107
99
  w: this.rect.width,
108
100
  h: this.rect.height,
109
101
  isMoving: this._isMovable(),
110
- boundStatus : this.boundStatus,
102
+ boundStatus: this.boundStatus,
111
103
  isChangeStart: true
112
104
  }
113
105
  },
114
-
115
- _onUp: function(e) {
106
+
107
+ _onUp: function (e) {
116
108
  if (e) {
117
109
  this.__getBoundStatus(e);
118
110
  }
@@ -122,54 +114,54 @@ position.prototype = {
122
114
  if (this.clickedInfo.isMoving && !this.isParked) {
123
115
  let p_w = this.el.parentNode.offsetWidth, p_h = this.el.parentNode.offsetHeight;
124
116
  let snap_info = null;
125
-
117
+
126
118
  if (this.__between(this.rect.top, this.NO_SNAP, this.FULLSCREEN_MARGIN) ||
127
- this.__between(this.rect.left, this.NO_SNAP, this.FULLSCREEN_MARGIN) ||
128
- this.__between(p_w - this.rect.right, this.NO_SNAP, this.FULLSCREEN_MARGIN) ||
129
- this.__between(p_h - this.rect.bottom, this.NO_SNAP, this.FULLSCREEN_MARGIN)) {
130
- snap_info = {x: 0, y: 0, w:'100%', h:'100%'}
119
+ this.__between(this.rect.left, this.NO_SNAP, this.FULLSCREEN_MARGIN) ||
120
+ this.__between(p_w - this.rect.right, this.NO_SNAP, this.FULLSCREEN_MARGIN) ||
121
+ this.__between(p_h - this.rect.bottom, this.NO_SNAP, this.FULLSCREEN_MARGIN)) {
122
+ snap_info = { x: 0, y: 0, w: '100%', h: '100%' }
131
123
  } else if (this.__between(this.rect.top, this.NO_SNAP, this.SNAP_MARGIN)) {
132
- snap_info = {x: 0, y: 0, w:'100%', h:'50%'}
124
+ snap_info = { x: 0, y: 0, w: '100%', h: '50%' }
133
125
  } else if (this.__between(this.rect.left, this.NO_SNAP, this.SNAP_MARGIN)) {
134
- snap_info = {x: 0, y: 0, w:'50%', h:'100%'}
126
+ snap_info = { x: 0, y: 0, w: '50%', h: '100%' }
135
127
  } else if (this.__between(p_w - this.rect.right, this.NO_SNAP, this.SNAP_MARGIN)) {
136
- snap_info = {x: '50%', y: 0, w: '50%', h:'100%'}
128
+ snap_info = { x: '50%', y: 0, w: '50%', h: '100%' }
137
129
  } else if (this.__between(p_h - this.rect.bottom, this.NO_SNAP, this.SNAP_MARGIN)) {
138
- snap_info = {x: 0, y: '50%', w: '100%', h: '50%'}
130
+ snap_info = { x: 0, y: '50%', w: '100%', h: '50%' }
139
131
  }
140
132
 
141
133
  if (snap_info && !this.isSnap) {
142
134
  this.__setBound(this.el, snap_info.x, snap_info.y, snap_info.w, snap_info.h);
143
- this.preSnapped = {x: this.rect.x, y: this.rect.y, width: this.rect.width, height: this.rect.height};
135
+ this.preSnapped = { x: this.rect.x, y: this.rect.y, width: this.rect.width, height: this.rect.height };
144
136
  this.isSnap = true;
145
- }
146
-
137
+ }
138
+
147
139
  var ghost_info = {
148
140
  x: this.rect.x,
149
141
  y: this.rect.y,
150
142
  w: this.rect.width,
151
143
  h: this.rect.height
152
144
  }
153
- // this.el.parentNode.dispatchEvent(new CustomEvent("cocreate-modalghost", {detail: ghost_info}));
145
+
154
146
  this._ghostProcess(ghost_info)
155
147
  }
156
148
 
157
149
  if (this.clickedInfo.isMoving) {
158
150
  this.createEvent('element-moveend');
159
151
  }
160
-
161
-
152
+
153
+
162
154
  this.clickedInfo = null;
163
155
  },
164
-
165
- __setBound : function(el, x, y, w, h) {
156
+
157
+ __setBound: function (el, x, y, w, h) {
166
158
  el.style.left = x;
167
159
  el.style.top = y;
168
160
  el.style.width = w;
169
161
  el.style.height = h;
170
162
  },
171
-
172
- __setRectInfo: function() {
163
+
164
+ __setRectInfo: function () {
173
165
  let bound = this.el.getBoundingClientRect();
174
166
  let parentRect = this.el.parentNode.getBoundingClientRect();
175
167
  this.rect = {};
@@ -182,8 +174,8 @@ position.prototype = {
182
174
  this.rect.left = bound.left - parentRect.left;
183
175
  this.rect.right = bound.right - parentRect.left;
184
176
  },
185
-
186
- __getBoundStatus : function(e) {
177
+
178
+ __getBoundStatus: function (e) {
187
179
  let bound = this.el.getBoundingClientRect();
188
180
  let parentRect = this.el.parentNode.getBoundingClientRect();
189
181
  let x = e.clientX - bound.left;// - parentRect.left;
@@ -197,51 +189,50 @@ position.prototype = {
197
189
  this.point.cy = e.clientY - parentRect.top;
198
190
 
199
191
  this.boundStatus = {
200
- isTop : y < this.MARGIN && y > -this.MARGIN,
201
- isLeft : x < this.MARGIN && x > -this.MARGIN,
202
- isRight : x >= bound.width - this.RIGHT_SCROL && x <= bound.width + this.MARGIN + (this.MARGIN - this.RIGHT_SCROL),
192
+ isTop: y < this.MARGIN && y > -this.MARGIN,
193
+ isLeft: x < this.MARGIN && x > -this.MARGIN,
194
+ isRight: x >= bound.width - this.RIGHT_SCROL && x <= bound.width + this.MARGIN + (this.MARGIN - this.RIGHT_SCROL),
203
195
  isBottom: y >= bound.height - this.MARGIN && y <= bound.height + this.MARGIN
204
196
  }
205
-
197
+
206
198
  return this.boundStatus;
207
199
  },
208
-
209
- __between: function(x, min, max) {
200
+
201
+ __between: function (x, min, max) {
210
202
  return x >= min && x <= max;
211
203
  },
212
-
213
- __animate : function() {
204
+
205
+ __animate: function () {
214
206
  let c_info = this.clickedInfo;
215
-
207
+
216
208
  var eventName = null;
217
-
209
+
218
210
  if (c_info && c_info.isMoving) {
219
211
  /**
220
212
  * Ghost Process
221
213
  **/
222
-
214
+
223
215
  let p_w = this.el.parentNode.offsetWidth, p_h = this.el.parentNode.offsetHeight;
224
216
  let ghost_info = null;
225
217
 
226
218
  if (this.__between(this.rect.top, this.NO_SNAP, this.FULLSCREEN_MARGIN) ||
227
- this.__between(this.rect.left, this.NO_SNAP, this.FULLSCREEN_MARGIN) ||
228
- this.__between(p_w - this.rect.right, this.NO_SNAP, this.FULLSCREEN_MARGIN) ||
229
- this.__between(p_h - this.rect.bottom, this.NO_SNAP, this.FULLSCREEN_MARGIN)) {
230
- ghost_info = {x: 0, y: 0, w:p_w, h:p_h, type: "show"}
219
+ this.__between(this.rect.left, this.NO_SNAP, this.FULLSCREEN_MARGIN) ||
220
+ this.__between(p_w - this.rect.right, this.NO_SNAP, this.FULLSCREEN_MARGIN) ||
221
+ this.__between(p_h - this.rect.bottom, this.NO_SNAP, this.FULLSCREEN_MARGIN)) {
222
+ ghost_info = { x: 0, y: 0, w: p_w, h: p_h, type: "show" }
231
223
  } else if (this.__between(this.rect.top, this.NO_SNAP, this.SNAP_MARGIN)) {
232
- ghost_info = {x: 0, y: 0, w:p_w, h:p_h / 2, type: "show"}
224
+ ghost_info = { x: 0, y: 0, w: p_w, h: p_h / 2, type: "show" }
233
225
  } else if (this.__between(this.rect.left, this.NO_SNAP, this.SNAP_MARGIN)) {
234
- ghost_info = {x: 0, y: 0, w:p_w / 2, h: p_h, type: "show"}
226
+ ghost_info = { x: 0, y: 0, w: p_w / 2, h: p_h, type: "show" }
235
227
  } else if (this.__between(p_w - this.rect.right, this.NO_SNAP, this.SNAP_MARGIN)) {
236
- ghost_info = {x: p_w / 2, y: 0, w: p_w / 2, h: p_h, type: "show"}
228
+ ghost_info = { x: p_w / 2, y: 0, w: p_w / 2, h: p_h, type: "show" }
237
229
  } else if (this.__between(p_h - this.rect.bottom, this.NO_SNAP, this.SNAP_MARGIN)) {
238
- ghost_info = {x: 0, y: p_h / 2, w:p_w, h:p_h / 2, type: "show"}
230
+ ghost_info = { x: 0, y: p_h / 2, w: p_w, h: p_h / 2, type: "show" }
239
231
  } else {
240
- ghost_info = {x: this.rect.left, y: this.rect.top, w: this.rect.width, h: this.rect.height, type: "hide"}
232
+ ghost_info = { x: this.rect.left, y: this.rect.top, w: this.rect.width, h: this.rect.height, type: "hide" }
241
233
  }
242
234
 
243
235
  if (ghost_info && !this.isParked && !this.isSnap) {
244
- // this.container.dispatchEvent(new CustomEvent("cocreate-modalghost", {detail: ghost_info}));
245
236
  this._ghostProcess(ghost_info)
246
237
  }
247
238
 
@@ -249,38 +240,38 @@ position.prototype = {
249
240
  this.el.style.left = this.point.cx + 'px';
250
241
  this.el.style.top = this.point.cy + 'px';
251
242
  this.el.style.width = this.preSnapped.width + 'px';
252
- this.el.style.height = this.preSnapped.height + 'px';
243
+ this.el.style.height = this.preSnapped.height + 'px';
253
244
  this.isSnap = false;
254
245
  } else {
255
246
  this.el.style.top = (this.point.cy - c_info.y) + 'px';
256
247
  this.el.style.left = (this.point.cx - c_info.x) + 'px';
257
248
  }
258
-
249
+
259
250
  eventName = "element-moving";
260
251
  if (c_info.isChangeStart) {
261
252
  this.clickedInfo.isChangeStart = false;
262
253
  eventName = "element-movestart";
263
254
  }
264
-
255
+
265
256
  this.createEvent(eventName)
266
257
  return;
267
258
  }
268
259
  },
269
-
260
+
270
261
  minMax() {
271
262
  if (!this.isSnap) {
272
263
  this.isSnap = true;
273
- this.preSnapped = {x: this.rect.x, y: this.rect.y, width: this.rect.width, height: this.rect.height};
264
+ this.preSnapped = { x: this.rect.x, y: this.rect.y, width: this.rect.width, height: this.rect.height };
274
265
  this.__setBound(this.el, 0, 0, "100%", "100%");
275
266
  } else {
276
267
  this.isSnap = false;
277
268
  this.el.style.left = this.preSnapped.x + 'px';
278
269
  this.el.style.top = this.preSnapped.y + 'px';
279
270
  this.el.style.width = this.preSnapped.width + 'px';
280
- this.el.style.height = this.preSnapped.height + 'px';
271
+ this.el.style.height = this.preSnapped.height + 'px';
281
272
  }
282
273
  },
283
-
274
+
284
275
  _isMovable() {
285
276
  var width = this.rect.width;
286
277
  // if (this.isHeader) {
@@ -288,44 +279,38 @@ position.prototype = {
288
279
  // }
289
280
  return this.point.x > 0 && this.point.x < width && this.point.y > 0 && this.point.y < this.dragAreaHeight;
290
281
  },
291
-
282
+
292
283
  /**
293
284
  * Position Events
294
285
  * move: element-moving, element-moveend, element-movestart
295
286
  **/
296
287
  createEvent(eventName) {
297
- var event = new CustomEvent(eventName, {detail: {element: this.el, instance: this}});
288
+ var event = new CustomEvent(eventName, { detail: { element: this.el, instance: this } });
298
289
  this.el.dispatchEvent(event);
299
290
  },
300
291
 
301
- _createGhost: function(ghostClass) {
292
+ _createGhost: function (ghostClass) {
302
293
  var node = document.createElement("div");
303
294
  if (!ghostClass) {
304
295
  ghostClass = "snap-ghost";
305
296
  }
306
-
297
+
307
298
  node.classList.add(ghostClass);
308
299
  this.container.appendChild(node);
309
300
  this.ghostEl = node;
310
301
  },
311
302
 
312
- // this.el.addEventListener('cocreate-modalghost', function(e) {
313
- // if (_this.selectedModal) {
314
- // _this._ghostProcess(e.detail)
315
- // }
316
- // })
317
-
318
- _ghostProcess: function(info) {
303
+ _ghostProcess: function (info) {
319
304
  this.ghostEl.style.left = info.x + 'px';
320
305
  this.ghostEl.style.top = info.y + 'px';
321
306
  this.ghostEl.style.width = info.w + 'px';
322
307
  this.ghostEl.style.height = info.h + 'px';
323
-
308
+
324
309
  if (info.type === "show") {
325
310
  if (this.ghostEl.style.display === 'none') {
326
311
  this.ghostEl.style.display = 'block'
327
312
  }
328
- this.ghostEl.style.opacity = 0.2;
313
+ this.ghostEl.style.opacity = 0.2;
329
314
  } else {
330
315
  this.ghostEl.style.opacity = 0;
331
316
  if (this.ghostEl.style.display !== 'none') {
@@ -335,24 +320,20 @@ position.prototype = {
335
320
  return;
336
321
  },
337
322
 
338
- _selectElement: function(el) {
323
+ _selectElement: function (el) {
339
324
  this._releaseSelect();
340
325
  this.container['selectedPositionElement'] = this.el
341
326
  if (this.el) {
342
- this.el.style.zIndex = this.SELECT_ZINDEX;
343
- this.el.classList.add('modal_selected');
344
- // this.ghostEl.style.width = 0;
345
- // this.ghostEl.style.height = 0;
327
+ this.createEvent('elementSelected');
328
+ this.el.style.zIndex = this.container.positionIndex += 1;
329
+ this.el.classList.add('selectedPosition');
346
330
  }
347
331
  },
348
332
 
349
- _releaseSelect: function() {
333
+ _releaseSelect: function () {
350
334
  let el = this.container['selectedPositionElement']
351
- if (!el) {
352
- return;
353
- }
354
- el.style.zIndex = this.UNSELECT_ZINDEX;
355
- el.classList.remove("modal_selected");
335
+ if (el)
336
+ el.classList.remove("selectedPosition");
356
337
  },
357
338
  }
358
339