uikit 3.11.2-dev.4c11be04b → 3.11.2-dev.54d67da03

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 (60) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/css/uikit-core-rtl.css +1 -1
  3. package/dist/css/uikit-core-rtl.min.css +1 -1
  4. package/dist/css/uikit-core.css +1 -1
  5. package/dist/css/uikit-core.min.css +1 -1
  6. package/dist/css/uikit-rtl.css +1 -1
  7. package/dist/css/uikit-rtl.min.css +1 -1
  8. package/dist/css/uikit.css +1 -1
  9. package/dist/css/uikit.min.css +1 -1
  10. package/dist/js/components/countdown.js +1 -1
  11. package/dist/js/components/countdown.min.js +1 -1
  12. package/dist/js/components/filter.js +1 -1
  13. package/dist/js/components/filter.min.js +1 -1
  14. package/dist/js/components/lightbox-panel.js +1 -1
  15. package/dist/js/components/lightbox-panel.min.js +1 -1
  16. package/dist/js/components/lightbox.js +1 -1
  17. package/dist/js/components/lightbox.min.js +1 -1
  18. package/dist/js/components/notification.js +1 -1
  19. package/dist/js/components/notification.min.js +1 -1
  20. package/dist/js/components/parallax.js +6 -17
  21. package/dist/js/components/parallax.min.js +1 -1
  22. package/dist/js/components/slider-parallax.js +1 -1
  23. package/dist/js/components/slider-parallax.min.js +1 -1
  24. package/dist/js/components/slider.js +1 -1
  25. package/dist/js/components/slider.min.js +1 -1
  26. package/dist/js/components/slideshow-parallax.js +1 -1
  27. package/dist/js/components/slideshow-parallax.min.js +1 -1
  28. package/dist/js/components/slideshow.js +1 -1
  29. package/dist/js/components/slideshow.min.js +1 -1
  30. package/dist/js/components/sortable.js +2 -3
  31. package/dist/js/components/sortable.min.js +1 -1
  32. package/dist/js/components/tooltip.js +1 -1
  33. package/dist/js/components/tooltip.min.js +1 -1
  34. package/dist/js/components/upload.js +1 -1
  35. package/dist/js/components/upload.min.js +1 -1
  36. package/dist/js/uikit-core.js +255 -202
  37. package/dist/js/uikit-core.min.js +1 -1
  38. package/dist/js/uikit-icons.js +1 -1
  39. package/dist/js/uikit-icons.min.js +1 -1
  40. package/dist/js/uikit.js +261 -220
  41. package/dist/js/uikit.min.js +1 -1
  42. package/package.json +1 -1
  43. package/src/js/api/state.js +4 -4
  44. package/src/js/components/parallax.js +5 -16
  45. package/src/js/components/sortable.js +1 -2
  46. package/src/js/core/core.js +2 -2
  47. package/src/js/core/drop.js +1 -1
  48. package/src/js/core/height-viewport.js +2 -2
  49. package/src/js/core/img.js +101 -97
  50. package/src/js/core/navbar.js +6 -2
  51. package/src/js/core/sticky.js +82 -50
  52. package/src/js/util/dimensions.js +28 -12
  53. package/src/js/util/fastdom.js +2 -2
  54. package/src/js/util/options.js +4 -4
  55. package/src/js/util/viewport.js +7 -3
  56. package/tests/image.html +28 -38
  57. package/tests/images/test.avif +0 -0
  58. package/tests/images/test.webp +0 -0
  59. package/tests/sticky-parallax.html +44 -41
  60. package/tests/sticky.html +56 -24
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.11.2-dev.4c11be04b",
5
+ "version": "3.11.2-dev.54d67da03",
6
6
  "main": "dist/js/uikit.js",
7
7
  "style": "dist/css/uikit.css",
8
8
  "sideEffects": [
@@ -211,11 +211,11 @@ export default function (UIkit) {
211
211
  on(
212
212
  el,
213
213
  name,
214
- !delegate
215
- ? null
216
- : isString(delegate)
214
+ delegate
215
+ ? isString(delegate)
217
216
  ? delegate
218
- : delegate.call(component),
217
+ : delegate.call(component)
218
+ : null,
219
219
  isString(handler) ? component[handler] : handler.bind(component),
220
220
  {passive, capture, self}
221
221
  )
@@ -28,13 +28,15 @@ export default {
28
28
  },
29
29
 
30
30
  start({start}) {
31
- return parseCalc(start, this.target);
31
+ return toPx(start, 'height', this.target, true);
32
32
  },
33
33
 
34
34
  end({end, viewport}) {
35
- return parseCalc(
35
+ return toPx(
36
36
  end || (viewport = (1 - viewport) * 100) && `${viewport}vh+${viewport}%`,
37
- this.target
37
+ 'height',
38
+ this.target,
39
+ true
38
40
  );
39
41
  }
40
42
 
@@ -77,19 +79,6 @@ export default {
77
79
 
78
80
  };
79
81
 
80
- const calcRe = /-?\d+(?:\.\d+)?(?:v[wh]|%|px)?/g;
81
- function parseCalc(calc, el) {
82
- let match;
83
- let result = 0;
84
- calc = calc.toString().replace(/\s/g, '');
85
- calcRe.lastIndex = 0;
86
- while ((match = calcRe.exec(calc)) !== null) {
87
- result += toPx(match[0], 'height', el, true);
88
- }
89
-
90
- return result;
91
- }
92
-
93
82
  function ease(percent, easing) {
94
83
  return easing >= 0
95
84
  ? Math.pow(percent, easing + 1)
@@ -218,7 +218,6 @@ export default {
218
218
 
219
219
  off(document, pointerMove, this.move);
220
220
  off(document, pointerUp, this.end);
221
- off(window, 'scroll', this.scroll);
222
221
 
223
222
  if (!this.drag) {
224
223
  return;
@@ -295,7 +294,7 @@ function trackScroll(pos) {
295
294
  trackTimer = setInterval(() => {
296
295
 
297
296
  let {x, y} = pos;
298
- y += window.pageYOffset;
297
+ y += scrollTop(window);
299
298
 
300
299
  const dist = (Date.now() - last) * .3;
301
300
  last = Date.now();
@@ -13,7 +13,7 @@ export default function (UIkit) {
13
13
  return;
14
14
  }
15
15
  pendingResize = true;
16
- fastdom.write(() => pendingResize = false);
16
+ fastdom.read(() => pendingResize = false);
17
17
  UIkit.update(null, 'resize');
18
18
  };
19
19
 
@@ -32,7 +32,7 @@ export default function (UIkit) {
32
32
  return;
33
33
  }
34
34
  pending = true;
35
- fastdom.write(() => pending = false);
35
+ fastdom.read(() => pending = false);
36
36
 
37
37
  UIkit.update(null, e.type);
38
38
 
@@ -308,7 +308,7 @@ export default {
308
308
  if (active) {
309
309
 
310
310
  if (delay && active.isDelaying) {
311
- this.showTimer = setTimeout(this.show, 10);
311
+ this.showTimer = setTimeout(() => matches(target, ':hover') && this.show(), 10);
312
312
  return;
313
313
  }
314
314
 
@@ -1,5 +1,5 @@
1
1
  import FlexBug from '../mixin/flex-bug';
2
- import {boxModelAdjust, css, dimensions, endsWith, height, isNumeric, isString, isVisible, offset, query, toFloat} from 'uikit-util';
2
+ import {boxModelAdjust, css, dimensions, endsWith, height, isNumeric, isString, isVisible, offset, query, toFloat, trigger} from 'uikit-util';
3
3
 
4
4
  export default {
5
5
 
@@ -76,7 +76,7 @@ export default {
76
76
  css(this.$el, {minHeight});
77
77
 
78
78
  if (minHeight !== prev) {
79
- this.$update(this.$el, 'resize');
79
+ trigger(this.$el, 'resize');
80
80
  }
81
81
 
82
82
  if (this.minHeight && toFloat(css(this.$el, 'minHeight')) < this.minHeight) {
@@ -1,4 +1,4 @@
1
- import {createEvent, css, Dimensions, escape, getImage, includes, isUndefined, queryAll, startsWith, toFloat, toPx, trigger} from 'uikit-util';
1
+ import {append, attr, children, createEvent, css, data, escape, fragment, hasAttr, includes, isArray, isEmpty, isUndefined, parent, parseOptions, queryAll, startsWith, toFloat, toPx, trigger} from 'uikit-util';
2
2
 
3
3
  export default {
4
4
 
@@ -6,10 +6,7 @@ export default {
6
6
 
7
7
  props: {
8
8
  dataSrc: String,
9
- dataSrcset: Boolean,
10
- sizes: String,
11
- width: Number,
12
- height: Number,
9
+ dataSources: String,
13
10
  offsetTop: String,
14
11
  offsetLeft: String,
15
12
  target: String
@@ -17,10 +14,7 @@ export default {
17
14
 
18
15
  data: {
19
16
  dataSrc: '',
20
- dataSrcset: false,
21
- sizes: false,
22
- width: false,
23
- height: false,
17
+ dataSources: [],
24
18
  offsetTop: '50vh',
25
19
  offsetLeft: '50vw',
26
20
  target: false
@@ -28,26 +22,6 @@ export default {
28
22
 
29
23
  computed: {
30
24
 
31
- cacheKey({dataSrc}) {
32
- return `${this.$name}.${dataSrc}`;
33
- },
34
-
35
- width({width, dataWidth}) {
36
- return width || dataWidth;
37
- },
38
-
39
- height({height, dataHeight}) {
40
- return height || dataHeight;
41
- },
42
-
43
- sizes({sizes, dataSizes}) {
44
- return sizes || dataSizes;
45
- },
46
-
47
- isImg(_, $el) {
48
- return isImg($el);
49
- },
50
-
51
25
  target: {
52
26
 
53
27
  get({target}) {
@@ -58,14 +32,6 @@ export default {
58
32
  this.observe();
59
33
  }
60
34
 
61
- },
62
-
63
- offsetTop({offsetTop}) {
64
- return toPx(offsetTop, 'height');
65
- },
66
-
67
- offsetLeft({offsetLeft}) {
68
- return toPx(offsetLeft, 'width');
69
35
  }
70
36
 
71
37
  },
@@ -73,21 +39,15 @@ export default {
73
39
  connected() {
74
40
 
75
41
  if (!window.IntersectionObserver) {
76
- setSrcAttrs(this.$el, this.dataSrc, this.dataSrcset, this.sizes);
42
+ setSrcAttrs(this.$el, this.dataSrc);
77
43
  return;
78
44
  }
79
45
 
80
- if (storage[this.cacheKey]) {
81
- setSrcAttrs(this.$el, storage[this.cacheKey], this.dataSrcset, this.sizes);
82
- } else if (this.isImg && this.width && this.height) {
83
- setSrcAttrs(this.$el, getPlaceholderImage(this.width, this.height, this.sizes));
84
- }
85
-
86
- this.observer = new IntersectionObserver(this.load, {
87
- rootMargin: `${this.offsetTop}px ${this.offsetLeft}px`
88
- });
46
+ ensurePlaceholderImage(this.$el);
89
47
 
90
- requestAnimationFrame(this.observe);
48
+ const rootMargin = `${toPx(this.offsetTop, 'height')}px ${toPx(this.offsetLeft, 'width')}px`;
49
+ this.observer = new IntersectionObserver(this.load, {rootMargin});
50
+ this.observe();
91
51
 
92
52
  },
93
53
 
@@ -97,32 +57,17 @@ export default {
97
57
 
98
58
  update: {
99
59
 
100
- read({image}) {
101
-
102
- if (!this.observer) {
60
+ write(store) {
61
+ if (!this.observer || isImg(this.$el)) {
103
62
  return false;
104
63
  }
105
-
106
- if (!image && document.readyState === 'complete') {
107
- this.load(this.observer.takeRecords());
108
- }
109
-
110
- if (this.isImg) {
111
- return false;
112
- }
113
-
114
- image && image.then(img => img && img.currentSrc !== '' && setSrcAttrs(this.$el, currentSrc(img)));
115
-
116
- },
117
-
118
- write(data) {
119
-
120
- if (this.dataSrcset && window.devicePixelRatio !== 1) {
64
+ const srcset = data(this.$el, 'data-srcset');
65
+ if (srcset && window.devicePixelRatio !== 1) {
121
66
 
122
67
  const bgSize = css(this.$el, 'backgroundSize');
123
- if (bgSize.match(/^(auto\s?)+$/) || toFloat(bgSize) === data.bgSize) {
124
- data.bgSize = getSourceSize(this.dataSrcset, this.sizes);
125
- css(this.$el, 'backgroundSize', `${data.bgSize}px`);
68
+ if (bgSize.match(/^(auto\s?)+$/) || toFloat(bgSize) === store.bgSize) {
69
+ store.bgSize = getSourceSize(srcset, data(this.$el, 'sizes'));
70
+ css(this.$el, 'backgroundSize', `${store.bgSize}px`);
126
71
  }
127
72
 
128
73
  }
@@ -142,13 +87,20 @@ export default {
142
87
  return;
143
88
  }
144
89
 
145
- this._data.image = getImage(this.dataSrc, this.dataSrcset, this.sizes).then(img => {
90
+ if (this._data.image) {
91
+ return this._data.image;
92
+ }
146
93
 
147
- setSrcAttrs(this.$el, currentSrc(img), img.srcset, img.sizes);
148
- storage[this.cacheKey] = currentSrc(img);
149
- return img;
94
+ const image = isImg(this.$el)
95
+ ? this.$el
96
+ : getImageFromElement(
97
+ this.$el,
98
+ this.dataSrc,
99
+ this.dataSources
100
+ );
150
101
 
151
- }, e => trigger(this.$el, new e.constructor(e.type, e)));
102
+ this._data.image = image;
103
+ setSrcAttrs(this.$el, image.currentSrc);
152
104
 
153
105
  this.observer.disconnect();
154
106
  },
@@ -163,13 +115,14 @@ export default {
163
115
 
164
116
  };
165
117
 
166
- function setSrcAttrs(el, src, srcset, sizes) {
118
+ function setSrcAttrs(el, src) {
167
119
 
168
120
  if (isImg(el)) {
169
- const set = (prop, val) => val && val !== el[prop] && (el[prop] = val);
170
- set('sizes', sizes);
171
- set('srcset', srcset);
172
- set('src', src);
121
+
122
+ const parentNode = parent(el);
123
+ const elements = isPicture(parentNode) ? children(parentNode) : [el];
124
+ elements.forEach(el => setSourceProps(el, el));
125
+
173
126
  } else if (src) {
174
127
 
175
128
  const change = !includes(el.style.backgroundImage, src);
@@ -182,13 +135,66 @@ function setSrcAttrs(el, src, srcset, sizes) {
182
135
 
183
136
  }
184
137
 
185
- function getPlaceholderImage(width, height, sizes) {
138
+ const srcProps = ['data-src', 'data-srcset', 'sizes'];
139
+ function setSourceProps(sourceEl, targetEl) {
140
+ srcProps.forEach(prop => {
141
+ const value = data(sourceEl, prop);
142
+ if (value) {
143
+ attr(targetEl, prop.replace(/^(data-)+/, ''), value);
144
+ }
145
+ });
146
+ }
147
+
148
+ function getImageFromElement(el, src, sources) {
186
149
 
187
- if (sizes) {
188
- ({width, height} = Dimensions.ratio({width, height}, 'width', toPx(sizesToPixel(sizes))));
150
+ if (!src) {
151
+ return false;
189
152
  }
190
153
 
191
- return `data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}"></svg>`;
154
+ const img = new Image();
155
+
156
+ wrapInPicture(img, sources);
157
+ setSourceProps(el, img);
158
+ img.onload = () => setSrcAttrs(el, img.currentSrc);
159
+ attr(img, 'src', src);
160
+ return img;
161
+ }
162
+
163
+ function wrapInPicture(img, sources) {
164
+
165
+ sources = parseSources(sources);
166
+
167
+ if (sources.length) {
168
+ const picture = fragment('<picture>');
169
+ sources.forEach(attrs => {
170
+ const source = fragment('<source>');
171
+ attr(source, attrs);
172
+ append(picture, source);
173
+ });
174
+ append(picture, img);
175
+ }
176
+ }
177
+
178
+ function parseSources(sources) {
179
+ if (!sources) {
180
+ return [];
181
+ }
182
+
183
+ if (startsWith(sources, '[')) {
184
+ try {
185
+ sources = JSON.parse(sources);
186
+ } catch (e) {
187
+ sources = [];
188
+ }
189
+ } else {
190
+ sources = parseOptions(sources);
191
+ }
192
+
193
+ if (!isArray(sources)) {
194
+ sources = [sources];
195
+ }
196
+
197
+ return sources.filter(source => !isEmpty(source));
192
198
  }
193
199
 
194
200
  const sizesRe = /\s*(.*?)\s*(\w+|calc\(.*?\))\s*(?:,|$)/g;
@@ -228,22 +234,20 @@ function getSourceSize(srcset, sizes) {
228
234
  return descriptors.filter(size => size >= srcSize)[0] || descriptors.pop() || '';
229
235
  }
230
236
 
231
- function isImg(el) {
232
- return el.tagName === 'IMG';
237
+ function ensurePlaceholderImage(el) {
238
+ if (isImg(el) && !hasAttr(el, 'src')) {
239
+ attr(el, 'src', 'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg"></svg>');
240
+ }
233
241
  }
234
242
 
235
- function currentSrc(el) {
236
- return el.currentSrc || el.src;
243
+ function isPicture(el) {
244
+ return isA(el, 'PICTURE');
237
245
  }
238
246
 
239
- const key = '__test__';
240
- let storage;
247
+ function isImg(el) {
248
+ return isA(el, 'IMG');
249
+ }
241
250
 
242
- // workaround for Safari's private browsing mode and accessing sessionStorage in Blink
243
- try {
244
- storage = window.sessionStorage || {};
245
- storage[key] = 1;
246
- delete storage[key];
247
- } catch (e) {
248
- storage = {};
251
+ function isA(el, tagName) {
252
+ return el && el.tagName === tagName;
249
253
  }
@@ -137,7 +137,7 @@ export default {
137
137
 
138
138
  handler({current}) {
139
139
  const active = this.getActive();
140
- if (active && includes(active.mode, 'hover') && active.target && !within(active.target, current) && !active.tracker.movesTo(active.$el)) {
140
+ if (active && includes(active.mode, 'hover') && active.target && !within(active.target, current) && !active.isDelaying) {
141
141
  active.hide(false);
142
142
  }
143
143
  }
@@ -301,7 +301,11 @@ export default {
301
301
 
302
302
  const active = this.getActive();
303
303
 
304
- if (matches(this.dropbar, ':hover') && active && active.$el === $el) {
304
+ if (matches(this.dropbar, ':hover')
305
+ && active
306
+ && active.$el === $el
307
+ && !this.toggles.some(el => active.target !== el && matches(el, ':focus'))
308
+ ) {
305
309
  e.preventDefault();
306
310
  }
307
311
  }