uikit 3.13.6-dev.d986a0728 → 3.13.7-dev.04818b8b8

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 (48) hide show
  1. package/CHANGELOG.md +11 -4
  2. package/build/util.js +1 -1
  3. package/dist/css/uikit-core-rtl.css +1 -1
  4. package/dist/css/uikit-core-rtl.min.css +1 -1
  5. package/dist/css/uikit-core.css +1 -1
  6. package/dist/css/uikit-core.min.css +1 -1
  7. package/dist/css/uikit-rtl.css +1 -1
  8. package/dist/css/uikit-rtl.min.css +1 -1
  9. package/dist/css/uikit.css +1 -1
  10. package/dist/css/uikit.min.css +1 -1
  11. package/dist/js/components/countdown.js +1 -1
  12. package/dist/js/components/countdown.min.js +1 -1
  13. package/dist/js/components/filter.js +1 -1
  14. package/dist/js/components/filter.min.js +1 -1
  15. package/dist/js/components/lightbox-panel.js +1 -1
  16. package/dist/js/components/lightbox-panel.min.js +1 -1
  17. package/dist/js/components/lightbox.js +1 -1
  18. package/dist/js/components/lightbox.min.js +1 -1
  19. package/dist/js/components/notification.js +1 -1
  20. package/dist/js/components/notification.min.js +1 -1
  21. package/dist/js/components/parallax.js +1 -1
  22. package/dist/js/components/parallax.min.js +1 -1
  23. package/dist/js/components/slider-parallax.js +1 -1
  24. package/dist/js/components/slider-parallax.min.js +1 -1
  25. package/dist/js/components/slider.js +1 -1
  26. package/dist/js/components/slider.min.js +1 -1
  27. package/dist/js/components/slideshow-parallax.js +1 -1
  28. package/dist/js/components/slideshow-parallax.min.js +1 -1
  29. package/dist/js/components/slideshow.js +1 -1
  30. package/dist/js/components/slideshow.min.js +1 -1
  31. package/dist/js/components/sortable.js +1 -1
  32. package/dist/js/components/sortable.min.js +1 -1
  33. package/dist/js/components/tooltip.js +17 -51
  34. package/dist/js/components/tooltip.min.js +1 -1
  35. package/dist/js/components/upload.js +1 -1
  36. package/dist/js/components/upload.min.js +1 -1
  37. package/dist/js/uikit-core.js +139 -225
  38. package/dist/js/uikit-core.min.js +1 -1
  39. package/dist/js/uikit-icons.js +1 -1
  40. package/dist/js/uikit-icons.min.js +1 -1
  41. package/dist/js/uikit.js +138 -224
  42. package/dist/js/uikit.min.js +1 -1
  43. package/package.json +1 -1
  44. package/src/js/core/drop.js +1 -1
  45. package/src/js/core/img.js +0 -57
  46. package/src/js/mixin/position.js +15 -48
  47. package/src/js/util/position.js +129 -125
  48. package/tests/position.html +39 -38
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "uikit",
3
3
  "title": "UIkit",
4
4
  "description": "UIkit is a lightweight and modular front-end framework for developing fast and powerful web interfaces.",
5
- "version": "3.13.6-dev.d986a0728",
5
+ "version": "3.13.7-dev.04818b8b8",
6
6
  "main": "dist/js/uikit.js",
7
7
  "style": "dist/css/uikit.css",
8
8
  "sideEffects": [
@@ -360,7 +360,7 @@ export default {
360
360
  const targetOffset = offset(this.target);
361
361
  const alignTo = this.boundaryAlign ? boundaryOffset : targetOffset;
362
362
 
363
- if (this.align === 'justify') {
363
+ if (this.pos[1] === 'justify') {
364
364
  const prop = this.getAxis() === 'y' ? 'width' : 'height';
365
365
  css(this.$el, prop, alignTo[prop]);
366
366
  } else if (
@@ -19,7 +19,6 @@ import {
19
19
  queryAll,
20
20
  removeAttr,
21
21
  startsWith,
22
- toFloat,
23
22
  toPx,
24
23
  trigger,
25
24
  } from 'uikit-util';
@@ -89,25 +88,6 @@ export default {
89
88
  }
90
89
  },
91
90
 
92
- update: {
93
- write(store) {
94
- if (!this.observer || isImg(this.$el)) {
95
- return false;
96
- }
97
-
98
- const srcset = data(this.$el, 'data-srcset');
99
- if (srcset && window.devicePixelRatio !== 1) {
100
- const bgSize = css(this.$el, 'backgroundSize');
101
- if (bgSize.match(/^(auto\s?)+$/) || toFloat(bgSize) === store.bgSize) {
102
- store.bgSize = getSourceSize(srcset, data(this.$el, 'sizes'));
103
- css(this.$el, 'backgroundSize', `${store.bgSize}px`);
104
- }
105
- }
106
- },
107
-
108
- events: ['resize'],
109
- },
110
-
111
91
  methods: {
112
92
  load() {
113
93
  if (this._data.image) {
@@ -197,43 +177,6 @@ function parseSources(sources) {
197
177
  return sources.filter((source) => !isEmpty(source));
198
178
  }
199
179
 
200
- const sizesRe = /\s*(.*?)\s*(\w+|calc\(.*?\))\s*(?:,|$)/g;
201
- function sizesToPixel(sizes) {
202
- let matches;
203
-
204
- sizesRe.lastIndex = 0;
205
-
206
- while ((matches = sizesRe.exec(sizes))) {
207
- if (!matches[1] || window.matchMedia(matches[1]).matches) {
208
- matches = evaluateSize(matches[2]);
209
- break;
210
- }
211
- }
212
-
213
- return matches || '100vw';
214
- }
215
-
216
- const sizeRe = /\d+(?:\w+|%)/g;
217
- const additionRe = /[+-]?(\d+)/g;
218
- function evaluateSize(size) {
219
- return startsWith(size, 'calc')
220
- ? size
221
- .slice(5, -1)
222
- .replace(sizeRe, (size) => toPx(size))
223
- .replace(/ /g, '')
224
- .match(additionRe)
225
- .reduce((a, b) => a + +b, 0)
226
- : size;
227
- }
228
-
229
- const srcSetRe = /\s+\d+w\s*(?:,|$)/g;
230
- function getSourceSize(srcset, sizes) {
231
- const srcSize = toPx(sizesToPixel(sizes));
232
- const descriptors = (srcset.match(srcSetRe) || []).map(toFloat).sort((a, b) => a - b);
233
-
234
- return descriptors.filter((size) => size >= srcSize)[0] || descriptors.pop() || '';
235
- }
236
-
237
180
  function ensureSrcAttribute(el) {
238
181
  if (isImg(el) && !hasAttr(el, 'src')) {
239
182
  attr(el, 'src', 'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg"></svg>');
@@ -3,7 +3,6 @@ import {
3
3
  flipPosition,
4
4
  getCssVar,
5
5
  offset as getOffset,
6
- includes,
7
6
  isNumeric,
8
7
  isRtl,
9
8
  positionAt,
@@ -45,57 +44,25 @@ export default {
45
44
  }
46
45
  offset = toPx(offset) + toPx(getCssVar('position-offset', element));
47
46
 
48
- positionAt(element, target, {
49
- boundary,
50
- flip: this.flip,
51
- attach: {
52
- element: axis === 'x' ? [flipPosition(dir), align] : [align, flipPosition(dir)],
53
- target: axis === 'x' ? [dir, align] : [align, dir],
54
- },
55
- offset:
56
- axis === 'x'
57
- ? [dir === 'left' ? -offset : +offset, 0]
58
- : [0, dir === 'top' ? -offset : +offset],
59
- });
47
+ const { x, y } = positionAt(
48
+ element,
49
+ target,
50
+ axis === 'x' ? `${flipPosition(dir)} ${align}` : `${align} ${flipPosition(dir)}`,
51
+ axis === 'x' ? `${dir} ${align}` : `${align} ${dir}`,
52
+ axis === 'x'
53
+ ? `${dir === 'left' ? -offset : offset}`
54
+ : ` ${dir === 'top' ? -offset : offset}`,
55
+ null,
56
+ this.flip,
57
+ boundary
58
+ ).target;
60
59
 
61
- [this.dir, this.align] = getAlignment(element, target);
60
+ this.dir = axis === 'x' ? x : y;
61
+ this.align = axis === 'x' ? y : x;
62
62
  },
63
63
 
64
64
  getAxis() {
65
- return includes(['top', 'bottom'], this.dir) ? 'y' : 'x';
65
+ return this.dir === 'top' || this.dir === 'bottom' ? 'y' : 'x';
66
66
  },
67
67
  },
68
68
  };
69
-
70
- function getAlignment(el, target) {
71
- const elOffset = getOffset(el);
72
- const targetOffset = getOffset(target);
73
- const properties = [
74
- ['left', 'right'],
75
- ['top', 'bottom'],
76
- ];
77
-
78
- let dir;
79
- for (const props of properties) {
80
- if (elOffset[props[0]] >= targetOffset[props[1]]) {
81
- dir = props[1];
82
- break;
83
- }
84
- if (elOffset[props[1]] <= targetOffset[props[0]]) {
85
- dir = props[0];
86
- break;
87
- }
88
- }
89
-
90
- let align;
91
- const props = includes(properties[0], dir) ? properties[1] : properties[0];
92
- if (elOffset[props[0]] === targetOffset[props[0]]) {
93
- align = props[0];
94
- } else if (elOffset[props[1]] === targetOffset[props[1]]) {
95
- align = props[1];
96
- } else {
97
- align = 'center';
98
- }
99
-
100
- return [dir, align];
101
- }
@@ -1,152 +1,156 @@
1
1
  import { offset } from './dimensions';
2
- import { clamp, includes } from './lang';
2
+ import { each, endsWith, includes, toFloat } from './lang';
3
3
  import { getViewport, scrollParents } from './viewport';
4
4
 
5
- const dirs = [
6
- ['width', 'x', 'left', 'right'],
7
- ['height', 'y', 'top', 'bottom'],
8
- ];
9
-
10
- export function positionAt(element, target, options) {
11
- options = {
12
- attach: {
13
- element: ['left', 'top'],
14
- target: ['left', 'top'],
15
- ...options.attach,
16
- },
17
- offset: [0, 0],
18
- ...options,
19
- };
20
-
21
- const dim = options.flip
22
- ? attachToWithFlip(element, target, options)
23
- : attachTo(element, target, options);
24
-
25
- offset(element, dim);
26
- }
27
-
28
- function attachTo(element, target, options) {
29
- let { attach, offset: offsetBy } = {
30
- attach: {
31
- element: ['left', 'top'],
32
- target: ['left', 'top'],
33
- ...options.attach,
34
- },
35
- offset: [0, 0],
36
- ...options,
37
- };
38
-
39
- const position = offset(element);
40
- const targetOffset = offset(target);
41
- for (const i in dirs) {
42
- const [prop, dir, start, end] = dirs[i];
43
- position[start] = position[dir] =
44
- targetOffset[start] +
45
- moveBy(attach.target[i], end, targetOffset[prop]) -
46
- moveBy(attach.element[i], end, position[prop]) +
47
- +offsetBy[i];
48
- position[end] = position[start] + position[prop];
5
+ const dirs = {
6
+ width: ['x', 'left', 'right'],
7
+ height: ['y', 'top', 'bottom'],
8
+ };
9
+
10
+ export function positionAt(
11
+ element,
12
+ target,
13
+ elAttach,
14
+ targetAttach,
15
+ elOffset,
16
+ targetOffset,
17
+ flip,
18
+ boundary
19
+ ) {
20
+ elAttach = getPos(elAttach);
21
+ targetAttach = getPos(targetAttach);
22
+
23
+ const flipped = { element: elAttach, target: targetAttach };
24
+
25
+ if (!element || !target) {
26
+ return flipped;
49
27
  }
50
- return position;
51
- }
52
28
 
53
- function attachToWithFlip(element, target, options) {
54
- const position = attachTo(element, target, options);
29
+ const dim = offset(element);
55
30
  const targetDim = offset(target);
56
- const viewports = scrollParents(element).map(getViewport);
57
-
58
- let {
59
- flip,
60
- attach: { element: elAttach, target: targetAttach },
61
- offset: elOffset,
62
- boundary,
63
- viewport,
64
- } = options;
31
+ const position = targetDim;
65
32
 
66
- viewports.push(viewport);
33
+ moveTo(position, elAttach, dim, -1);
34
+ moveTo(position, targetAttach, targetDim, 1);
67
35
 
68
- for (const i in dirs) {
69
- const [prop, dir, start, end] = dirs[i];
36
+ elOffset = getOffsets(elOffset, dim.width, dim.height);
37
+ targetOffset = getOffsets(targetOffset, targetDim.width, targetDim.height);
70
38
 
71
- if (flip !== true && !includes(flip, dir)) {
72
- continue;
73
- }
39
+ elOffset['x'] += targetOffset['x'];
40
+ elOffset['y'] += targetOffset['y'];
74
41
 
75
- const willFlip =
76
- !intersectLine(position, targetDim, i) && intersectLine(position, targetDim, 1 - i);
42
+ position.left += elOffset['x'];
43
+ position.top += elOffset['y'];
77
44
 
78
- viewport = getIntersectionArea(...viewports, willFlip ? null : boundary);
79
- const isInStartBoundary = position[start] >= viewport[start];
80
- const isInEndBoundary = position[end] <= viewport[end];
45
+ if (flip) {
46
+ let boundaries = scrollParents(element).map(getViewport);
81
47
 
82
- if (isInStartBoundary && isInEndBoundary) {
83
- continue;
48
+ if (boundary && !includes(boundaries, boundary)) {
49
+ boundaries.unshift(boundary);
84
50
  }
85
51
 
86
- let offsetBy;
52
+ boundaries = boundaries.map((el) => offset(el));
87
53
 
88
- // Flip
89
- if (willFlip) {
90
- if (
91
- (elAttach[i] === end && isInStartBoundary) ||
92
- (elAttach[i] === start && isInEndBoundary)
93
- ) {
94
- continue;
54
+ each(dirs, ([dir, align, alignFlip], prop) => {
55
+ if (!(flip === true || includes(flip, dir))) {
56
+ return;
95
57
  }
96
58
 
97
- offsetBy =
98
- (elAttach[i] === start
99
- ? -position[prop]
100
- : elAttach[i] === end
101
- ? position[prop]
102
- : 0) +
103
- (targetAttach[i] === start
104
- ? targetDim[prop]
105
- : targetAttach[i] === end
106
- ? -targetDim[prop]
107
- : 0) -
108
- elOffset[i] * 2;
109
-
110
- // Move
111
- } else {
112
- offsetBy =
113
- clamp(
114
- clamp(position[start], viewport[start], viewport[end] - position[prop]),
115
- targetDim[start] - position[prop] + elOffset[i],
116
- targetDim[end] - elOffset[i]
117
- ) - position[start];
118
- }
119
-
120
- position[start] = position[dir] = position[start] + offsetBy;
121
- position[end] += offsetBy;
59
+ boundaries.some((boundary) => {
60
+ const elemOffset =
61
+ elAttach[dir] === align
62
+ ? -dim[prop]
63
+ : elAttach[dir] === alignFlip
64
+ ? dim[prop]
65
+ : 0;
66
+
67
+ const targetOffset =
68
+ targetAttach[dir] === align
69
+ ? targetDim[prop]
70
+ : targetAttach[dir] === alignFlip
71
+ ? -targetDim[prop]
72
+ : 0;
73
+
74
+ if (
75
+ position[align] < boundary[align] ||
76
+ position[align] + dim[prop] > boundary[alignFlip]
77
+ ) {
78
+ const centerOffset = dim[prop] / 2;
79
+ const centerTargetOffset =
80
+ targetAttach[dir] === 'center' ? -targetDim[prop] / 2 : 0;
81
+
82
+ return (
83
+ (elAttach[dir] === 'center' &&
84
+ (apply(centerOffset, centerTargetOffset) ||
85
+ apply(-centerOffset, -centerTargetOffset))) ||
86
+ apply(elemOffset, targetOffset)
87
+ );
88
+ }
89
+
90
+ function apply(elemOffset, targetOffset) {
91
+ const newVal = toFloat(
92
+ (position[align] + elemOffset + targetOffset - elOffset[dir] * 2).toFixed(4)
93
+ );
94
+
95
+ if (newVal >= boundary[align] && newVal + dim[prop] <= boundary[alignFlip]) {
96
+ position[align] = newVal;
97
+
98
+ for (const el of ['element', 'target']) {
99
+ if (elemOffset) {
100
+ flipped[el][dir] =
101
+ flipped[el][dir] === dirs[prop][1]
102
+ ? dirs[prop][2]
103
+ : dirs[prop][1];
104
+ }
105
+ }
106
+
107
+ return true;
108
+ }
109
+ }
110
+ });
111
+ });
122
112
  }
123
113
 
124
- return position;
125
- }
114
+ offset(element, position);
126
115
 
127
- function moveBy(start, end, dim) {
128
- return start === 'center' ? dim / 2 : start === end ? dim : 0;
116
+ return flipped;
129
117
  }
130
118
 
131
- function getIntersectionArea(...elements) {
132
- let intersection;
133
- for (const el of elements.filter(Boolean)) {
134
- const rect = offset(el);
135
- if (!intersection) {
136
- intersection = rect;
137
- continue;
138
- }
139
- for (const prop of ['left', 'top']) {
140
- intersection[prop] = Math.max(rect[prop], intersection[prop]);
141
- }
142
- for (const prop of ['right', 'bottom']) {
143
- intersection[prop] = Math.min(rect[prop], intersection[prop]);
119
+ function moveTo(position, attach, dim, factor) {
120
+ each(dirs, ([dir, align, alignFlip], prop) => {
121
+ if (attach[dir] === alignFlip) {
122
+ position[align] += dim[prop] * factor;
123
+ } else if (attach[dir] === 'center') {
124
+ position[align] += (dim[prop] * factor) / 2;
144
125
  }
126
+ });
127
+ }
128
+
129
+ function getPos(pos) {
130
+ const x = /left|center|right/;
131
+ const y = /top|center|bottom/;
132
+
133
+ pos = (pos || '').split(' ');
134
+
135
+ if (pos.length === 1) {
136
+ pos = x.test(pos[0])
137
+ ? pos.concat('center')
138
+ : y.test(pos[0])
139
+ ? ['center'].concat(pos)
140
+ : ['center', 'center'];
145
141
  }
146
- return intersection;
142
+
143
+ return {
144
+ x: x.test(pos[0]) ? pos[0] : 'center',
145
+ y: y.test(pos[1]) ? pos[1] : 'center',
146
+ };
147
147
  }
148
148
 
149
- function intersectLine(dimA, dimB, dir) {
150
- const [, , start, end] = dirs[dir];
151
- return dimA[end] > dimB[start] && dimB[end] > dimA[start];
149
+ function getOffsets(offsets, width, height) {
150
+ const [x, y] = (offsets || '').split(' ');
151
+
152
+ return {
153
+ x: x ? toFloat(x) * (endsWith(x, '%') ? width / 100 : 1) : 0,
154
+ y: y ? toFloat(y) * (endsWith(y, '%') ? height / 100 : 1) : 0,
155
+ };
152
156
  }
@@ -9,7 +9,7 @@
9
9
  <style>
10
10
 
11
11
  /* JavaScript */
12
- #js-viewport {
12
+ #js-boundary {
13
13
  height: 300px;
14
14
  outline: 1px solid rgba(0,0,0,0.1);
15
15
  position: relative;
@@ -26,6 +26,7 @@
26
26
 
27
27
  #js-element {
28
28
  position: absolute;
29
+ display: none;
29
30
  width: 75px;
30
31
  height: 75px;
31
32
  background: rgba(0,0,0,0.1);
@@ -237,13 +238,13 @@
237
238
 
238
239
  <h2>JavaScript</h2>
239
240
 
240
- <div id="js-viewport" class="uk-margin">
241
+ <div id="js-boundary" class="uk-margin">
241
242
  <div id="js-target" class="uk-flex uk-flex-center uk-flex-middle" draggable="true">Drag me!</div>
242
243
  </div>
243
244
 
244
245
  <div id="js-element"></div>
245
246
 
246
- <div class="uk-grid uk-child-width-auto uk-form-stacked" style="margin-bottom: 100vh">
247
+ <div class="uk-grid uk-child-width-auto uk-form-stacked">
247
248
  <div>
248
249
 
249
250
  <div class="uk-margin">
@@ -326,26 +327,27 @@
326
327
 
327
328
  <script>
328
329
 
329
- const {$, $$, css, getEventPos, on, offset, positionAt} = UIkit.util;
330
- let viewport = $('#js-viewport');
331
- let element = $('#js-element');
332
- let target = $('#js-target');
333
- let offsetX;
334
- let offsetY;
330
+ var util = UIkit.util,
331
+ $ = util.$,
332
+ on = util.on,
333
+ offset = util.offset,
334
+ ticking,
335
+ element = $('#js-element'),
336
+ boundary = $('#js-boundary'),
337
+ target = $('#js-target'),
338
+ offsetX,
339
+ offsetY;
335
340
 
336
341
  function position() {
337
- positionAt(
342
+ util.positionAt(
338
343
  element,
339
344
  target,
340
- {
341
- viewport,
342
- attach:{
343
- element: [$('#js-element_x').value, $('#js-element_y').value],
344
- target: [$('#js-target_x').value, $('#js-target_y').value]
345
- },
346
- offset: [$('#js-offset_x').value, $('#js-offset_y').value],
347
- flip: [$('#js-flip_x').value, $('#js-flip_y').value]
348
- }
345
+ $('#js-element_x').value + ' ' + $('#js-element_y').value,
346
+ $('#js-target_x').value + ' ' + $('#js-target_y').value,
347
+ $('#js-offset_x').value + ' ' + $('#js-offset_y').value,
348
+ null,
349
+ $('#js-flip_x').value + $('#js-flip_y').value,
350
+ boundary
349
351
  );
350
352
  }
351
353
 
@@ -357,34 +359,33 @@
357
359
 
358
360
  });
359
361
 
360
- let lastPos;
361
362
  on(window, 'dragover', function (e) {
362
363
 
363
- const pos = getEventPos(e);
364
+ e.preventDefault();
364
365
 
365
- if (lastPos?.x === pos.x && lastPos?.y === pos.y) {
366
- return;
367
- }
368
- lastPos = pos;
366
+ if (!ticking) {
367
+ requestAnimationFrame(function () {
369
368
 
370
- e.preventDefault();
369
+ util.positionAt(
370
+ target,
371
+ boundary,
372
+ 'left top',
373
+ 'left top',
374
+ (e.pageX - offset(boundary).left - offsetX) + ' ' + (e.pageY - offset(boundary).top - offsetY)
375
+ );
371
376
 
372
- // positions target at mouse cursor
373
- positionAt(
374
- target,
375
- viewport,
376
- {
377
- offset: [e.pageX - offset(viewport).left - offsetX, e.pageY - offset(viewport).top - offsetY]
378
- }
379
- );
377
+ position();
378
+
379
+ ticking = false;
380
+ });
381
+ ticking = true;
382
+ }
380
383
 
381
- // positions element at target
382
- position();
383
384
  });
384
385
 
385
- on($$('select,input'), 'change', position);
386
- on(window, 'scroll', position);
386
+ util.$$('select,input').forEach(el => on(el, 'change', position));
387
387
 
388
+ util.css(element, 'display', 'block');
388
389
  position();
389
390
 
390
391
  </script>