@dile/ui 2.21.3 → 2.21.4

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.
@@ -46,6 +46,14 @@ export const DileOverlay = function(superClass) {
46
46
  this.horizontalAlign = 'under_left';
47
47
  this.verticalAlign = 'bottom';
48
48
  this.delayId = null;
49
+ this._rafId = null;
50
+ this._onScrollResize = () => {
51
+ if (this._rafId) return;
52
+ this._rafId = requestAnimationFrame(() => {
53
+ this._rafId = null;
54
+ if (this._overlayClass === 'opened') this.updatePosition();
55
+ });
56
+ };
49
57
  }
50
58
 
51
59
  firstUpdated() {
@@ -80,6 +88,7 @@ export const DileOverlay = function(superClass) {
80
88
  }));
81
89
  if(!this._opening && this._overlayClass=='opened') {
82
90
  this._overlayClass = '';
91
+ this._removePositionListeners();
83
92
  this.cancelDelay();
84
93
  this.delayId = setTimeout(() => {
85
94
  this.overlay.style.display = 'none'
@@ -106,64 +115,96 @@ export const DileOverlay = function(superClass) {
106
115
  this._overlayClass = 'opened'
107
116
  this._opening = false;
108
117
  this.overlay.style.display = 'block';
118
+ this._addPositionListeners();
109
119
  }, 50);
110
120
  }
111
121
  }
112
122
 
123
+ _addPositionListeners() {
124
+ window.addEventListener('scroll', this._onScrollResize, { passive: true, capture: true });
125
+ window.addEventListener('resize', this._onScrollResize, { passive: true });
126
+ }
127
+
128
+ _removePositionListeners() {
129
+ window.removeEventListener('scroll', this._onScrollResize, { capture: true });
130
+ window.removeEventListener('resize', this._onScrollResize);
131
+ if (this._rafId) {
132
+ cancelAnimationFrame(this._rafId);
133
+ this._rafId = null;
134
+ }
135
+ }
136
+
113
137
  updatePosition() {
114
- let triggerWidth = parseInt(this.trigger.offsetWidth);
115
- let triggerHeight = parseInt(this.trigger.offsetHeight);
116
138
  let moveTop = parseInt(this.moveTop);
117
139
  let moveLeft = parseInt(this.moveLeft);
118
-
140
+
141
+ let triggerRect = this.trigger.getBoundingClientRect();
142
+
143
+ // Switch to fixed positioning so overflow:hidden ancestors don't clip the overlay
144
+ this.overlay.style.position = 'fixed';
119
145
  let lastDisplay = this.overlay.style.display;
120
- this.overlay.style.top = "-1000px";
146
+ this.overlay.style.top = '-10000px';
147
+ this.overlay.style.left = '-10000px';
121
148
  this.overlay.style.display = 'block';
122
-
149
+
123
150
  let overlayWidth = parseInt(this.overlay.offsetWidth);
124
151
  let overlayHeight = parseInt(this.overlay.offsetHeight);
125
-
152
+
126
153
  switch(this.verticalAlign) {
127
154
  case 'top':
128
- this.overlay.style.top = (0 - overlayHeight + moveTop) + 'px';
155
+ this.setOverlayStyleTop(triggerRect.top - overlayHeight + moveTop, triggerRect, overlayHeight, 'top');
129
156
  break;
130
157
  case 'center':
131
- this.overlay.style.top = '-' + (((overlayHeight - (triggerHeight / 2)) / 2) + moveTop) + 'px';
158
+ this.setOverlayStyleTop(triggerRect.top - ((overlayHeight - (triggerRect.height / 2)) / 2) - moveTop, triggerRect, overlayHeight, 'center');
132
159
  break;
133
160
  default:
134
- this.overlay.style.top = (triggerHeight + 10 + moveTop) + 'px';
161
+ this.setOverlayStyleTop(triggerRect.bottom + 10 + moveTop, triggerRect, overlayHeight, 'bottom');
135
162
  }
163
+
136
164
  switch(this.horizontalAlign) {
137
165
  case 'under_left':
138
- this.setOverlayStyleLeft('0px');
166
+ this.setOverlayStyleLeft(triggerRect.left);
167
+ break;
168
+ case 'under_right':
169
+ this.setOverlayStyleLeft(triggerRect.right - overlayWidth);
139
170
  break;
140
- case 'under_right':
141
- this.setOverlayStyleLeft(`-${overlayWidth - triggerWidth}px`);
142
- break;
143
171
  case 'left':
144
- this.setOverlayStyleLeft('-' + (overlayWidth + moveLeft) + 'px');
172
+ this.setOverlayStyleLeft(triggerRect.left - overlayWidth - moveLeft);
145
173
  break;
146
174
  case 'right':
147
- this.setOverlayStyleLeft((triggerWidth + moveLeft) + 'px');
175
+ this.setOverlayStyleLeft(triggerRect.right + moveLeft);
148
176
  break;
149
177
  default:
150
- this.setOverlayStyleLeft('-' + (((overlayWidth - triggerWidth) / 2) + moveLeft) + 'px');
178
+ this.setOverlayStyleLeft(triggerRect.left - ((overlayWidth - triggerRect.width) / 2) - moveLeft);
151
179
  }
180
+
152
181
  this.overlay.style.display = lastDisplay;
153
182
  }
154
-
155
- setOverlayStyleLeft(pos) {
156
- this.overlay.style.left = pos;
157
- var rect = this.overlay.getBoundingClientRect();
158
- let posLeft = parseInt(this.overlay.style.left);
159
- if (rect.left < 0) {
160
- this.overlay.style.left = (posLeft - rect.left + 10) + 'px';
183
+
184
+ setOverlayStyleTop(topValue, triggerRect, overlayHeight, direction) {
185
+ const viewportHeight = document.documentElement.clientHeight;
186
+ const margin = 10;
187
+ if (direction === 'bottom' && topValue + overlayHeight > viewportHeight - margin) {
188
+ const flipped = triggerRect.top - overlayHeight - margin;
189
+ topValue = flipped >= margin ? flipped : viewportHeight - overlayHeight - margin;
190
+ } else if (direction === 'top' && topValue < margin) {
191
+ const flipped = triggerRect.bottom + margin;
192
+ topValue = flipped + overlayHeight <= viewportHeight - margin ? flipped : margin;
161
193
  }
162
- let pageWidth = document.querySelector('html').clientWidth;
163
- if (rect.left + rect.width > pageWidth) {
164
- let displacement = posLeft - (rect.right - pageWidth) - 15;
165
- this.overlay.style.left = (displacement ) + 'px';
194
+ if (topValue < margin) topValue = margin;
195
+ if (topValue + overlayHeight > viewportHeight - margin) topValue = viewportHeight - overlayHeight - margin;
196
+ this.overlay.style.top = topValue + 'px';
197
+ }
198
+
199
+ setOverlayStyleLeft(posLeft) {
200
+ const pageWidth = document.querySelector('html').clientWidth;
201
+ const overlayWidth = this.overlay.offsetWidth;
202
+ if (posLeft < 10) {
203
+ posLeft = 10;
204
+ } else if (posLeft + overlayWidth > pageWidth - 15) {
205
+ posLeft = pageWidth - overlayWidth - 15;
166
206
  }
207
+ this.overlay.style.left = posLeft + 'px';
167
208
  }
168
209
  }
169
210
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dile/ui",
3
- "version": "2.21.3",
3
+ "version": "2.21.4",
4
4
  "description": "UI Core components from dile-components.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -26,5 +26,5 @@
26
26
  "publishConfig": {
27
27
  "access": "public"
28
28
  },
29
- "gitHead": "67e2e845295d11fcdbf3dedcc989d26b821005d4"
29
+ "gitHead": "f3d7061476125162d6d9822928d40dc15e110c6c"
30
30
  }