uikit 3.25.17-dev.80dfe87 → 3.25.17-dev.8c70e44

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 (200) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/build/prefix.js +1 -1
  3. package/build/publishDev.js +1 -1
  4. package/build/release.js +2 -2
  5. package/build/scope.js +1 -1
  6. package/build/scss.js +1 -1
  7. package/dist/css/uikit-core-rtl.css +892 -802
  8. package/dist/css/uikit-core-rtl.min.css +1 -1
  9. package/dist/css/uikit-core.css +892 -802
  10. package/dist/css/uikit-core.min.css +1 -1
  11. package/dist/css/uikit-rtl.css +893 -803
  12. package/dist/css/uikit-rtl.min.css +1 -1
  13. package/dist/css/uikit.css +893 -803
  14. package/dist/css/uikit.min.css +1 -1
  15. package/dist/js/components/countdown.js +1 -1
  16. package/dist/js/components/countdown.min.js +1 -1
  17. package/dist/js/components/filter.js +1 -1
  18. package/dist/js/components/filter.min.js +1 -1
  19. package/dist/js/components/lightbox-panel.js +133 -132
  20. package/dist/js/components/lightbox-panel.min.js +1 -1
  21. package/dist/js/components/lightbox.js +134 -133
  22. package/dist/js/components/lightbox.min.js +1 -1
  23. package/dist/js/components/marquee.js +179 -0
  24. package/dist/js/components/marquee.min.js +1 -0
  25. package/dist/js/components/notification.js +1 -1
  26. package/dist/js/components/notification.min.js +1 -1
  27. package/dist/js/components/parallax.js +8 -12
  28. package/dist/js/components/parallax.min.js +1 -1
  29. package/dist/js/components/slider-parallax.js +8 -12
  30. package/dist/js/components/slider-parallax.min.js +1 -1
  31. package/dist/js/components/slider.js +41 -25
  32. package/dist/js/components/slider.min.js +1 -1
  33. package/dist/js/components/slideshow-parallax.js +8 -12
  34. package/dist/js/components/slideshow-parallax.min.js +1 -1
  35. package/dist/js/components/slideshow.js +71 -102
  36. package/dist/js/components/slideshow.min.js +1 -1
  37. package/dist/js/components/sortable.js +1 -1
  38. package/dist/js/components/sortable.min.js +1 -1
  39. package/dist/js/components/tooltip.js +19 -19
  40. package/dist/js/components/tooltip.min.js +1 -1
  41. package/dist/js/components/upload.js +1 -1
  42. package/dist/js/components/upload.min.js +1 -1
  43. package/dist/js/uikit-core.js +754 -262
  44. package/dist/js/uikit-core.min.js +1 -1
  45. package/dist/js/uikit-icons.js +1 -1
  46. package/dist/js/uikit-icons.min.js +1 -1
  47. package/dist/js/uikit.js +629 -374
  48. package/dist/js/uikit.min.js +1 -1
  49. package/package.json +2 -2
  50. package/src/js/api/component.js +2 -3
  51. package/src/js/api/observables.js +2 -4
  52. package/src/js/api/options.js +6 -3
  53. package/src/js/api/props.js +1 -4
  54. package/src/js/api/state.js +7 -8
  55. package/src/js/components/index.js +1 -0
  56. package/src/js/components/internal/lightbox-animations.js +7 -26
  57. package/src/js/components/internal/slideshow-animations.js +15 -62
  58. package/src/js/components/lightbox-panel.js +121 -96
  59. package/src/js/components/lightbox.js +5 -8
  60. package/src/js/components/marquee.js +123 -0
  61. package/src/js/components/tooltip.js +4 -2
  62. package/src/js/core/accordion.js +78 -29
  63. package/src/js/core/drop.js +5 -4
  64. package/src/js/core/dropnav.js +3 -3
  65. package/src/js/core/grid.js +5 -19
  66. package/src/js/core/height-match.js +1 -2
  67. package/src/js/core/margin.js +3 -0
  68. package/src/js/core/overflow-fade.js +5 -5
  69. package/src/js/core/sticky.js +1 -1
  70. package/src/js/core/switcher.js +24 -44
  71. package/src/js/core/video.js +172 -15
  72. package/src/js/mixin/connect.js +57 -0
  73. package/src/js/mixin/internal/slideshow-animations.js +5 -13
  74. package/src/js/mixin/internal/slideshow-transitioner.js +2 -2
  75. package/src/js/mixin/modal.js +4 -3
  76. package/src/js/mixin/parallax.js +1 -4
  77. package/src/js/mixin/position.js +1 -1
  78. package/src/js/mixin/scroll-driven.js +57 -0
  79. package/src/js/mixin/slider-nav.js +1 -1
  80. package/src/js/mixin/slider-parallax.js +9 -38
  81. package/src/js/mixin/togglable.js +13 -14
  82. package/src/js/util/attr.js +7 -7
  83. package/src/js/util/class.js +1 -1
  84. package/src/js/util/dom.js +3 -4
  85. package/src/js/util/lang.js +1 -1
  86. package/src/js/util/player.js +4 -4
  87. package/src/js/util/style.js +10 -15
  88. package/src/js/util/viewport.js +22 -25
  89. package/src/less/components/_import.less +6 -1
  90. package/src/less/components/base.less +1 -1
  91. package/src/less/components/button.less +1 -1
  92. package/src/less/components/dropcap.less +71 -0
  93. package/src/less/components/floating-shadow.less +65 -0
  94. package/src/less/components/form.less +5 -5
  95. package/src/less/components/grid.less +57 -64
  96. package/src/less/components/logo.less +94 -0
  97. package/src/less/components/margin.less +81 -81
  98. package/src/less/components/marquee.less +133 -0
  99. package/src/less/components/nav.less +1 -1
  100. package/src/less/components/padding.less +9 -9
  101. package/src/less/components/utility.less +0 -157
  102. package/src/less/theme/_import.less +5 -1
  103. package/src/less/theme/dropcap.less +29 -0
  104. package/src/less/theme/floating-shadow.less +20 -0
  105. package/src/less/theme/logo.less +29 -0
  106. package/src/less/theme/marquee.less +14 -0
  107. package/src/less/theme/utility.less +0 -32
  108. package/src/scss/components/_import.scss +6 -1
  109. package/src/scss/components/base.scss +1 -1
  110. package/src/scss/components/button.scss +1 -1
  111. package/src/scss/components/dropcap.scss +63 -0
  112. package/src/scss/components/floating-shadow.scss +62 -0
  113. package/src/scss/components/form.scss +5 -5
  114. package/src/scss/components/grid.scss +57 -64
  115. package/src/scss/components/logo.scss +75 -0
  116. package/src/scss/components/margin.scss +81 -81
  117. package/src/scss/components/marquee.scss +136 -0
  118. package/src/scss/components/nav.scss +1 -1
  119. package/src/scss/components/padding.scss +9 -9
  120. package/src/scss/components/utility.scss +0 -128
  121. package/src/scss/mixins-theme.scss +41 -32
  122. package/src/scss/mixins.scss +38 -29
  123. package/src/scss/variables-theme.scss +14 -9
  124. package/src/scss/variables.scss +14 -9
  125. package/tests/accordion.html +77 -10
  126. package/tests/alert.html +1 -1
  127. package/tests/align.html +5 -5
  128. package/tests/animation.html +4 -4
  129. package/tests/article.html +7 -7
  130. package/tests/background.html +2 -2
  131. package/tests/badge.html +1 -1
  132. package/tests/base.html +2 -2
  133. package/tests/button.html +1 -1
  134. package/tests/card.html +15 -15
  135. package/tests/close.html +2 -2
  136. package/tests/comment.html +9 -9
  137. package/tests/container.html +2 -2
  138. package/tests/countdown.html +21 -21
  139. package/tests/cover.html +3 -3
  140. package/tests/description-list.html +1 -1
  141. package/tests/divider.html +3 -3
  142. package/tests/dotnav.html +1 -1
  143. package/tests/drop.html +7 -7
  144. package/tests/dropbar.html +5 -5
  145. package/tests/dropcap.html +26 -0
  146. package/tests/dropdown.html +1 -1
  147. package/tests/dropnav.html +18 -18
  148. package/tests/filter.html +3 -3
  149. package/tests/floating-shadow.html +44 -0
  150. package/tests/form.html +14 -14
  151. package/tests/grid.html +41 -47
  152. package/tests/heading.html +2 -2
  153. package/tests/height-viewport.html +4 -4
  154. package/tests/height.html +5 -5
  155. package/tests/icon.html +8 -8
  156. package/tests/image.html +6 -6
  157. package/tests/index.html +13 -13
  158. package/tests/js/index.js +1 -1
  159. package/tests/leader.html +5 -5
  160. package/tests/lightbox.html +6 -6
  161. package/tests/link.html +1 -1
  162. package/tests/list.html +4 -4
  163. package/tests/logo.html +84 -0
  164. package/tests/margin.html +7 -7
  165. package/tests/marker.html +3 -3
  166. package/tests/marquee.html +617 -0
  167. package/tests/modal.html +3 -3
  168. package/tests/nav.html +5 -5
  169. package/tests/navbar.html +27 -27
  170. package/tests/notification.html +2 -2
  171. package/tests/offcanvas.html +12 -12
  172. package/tests/overlay.html +3 -3
  173. package/tests/padding.html +1 -1
  174. package/tests/pagination.html +3 -3
  175. package/tests/parallax.html +1 -1
  176. package/tests/position.html +6 -6
  177. package/tests/scrollspy.html +12 -12
  178. package/tests/search.html +5 -5
  179. package/tests/section.html +17 -17
  180. package/tests/slidenav.html +3 -3
  181. package/tests/slider.html +5 -5
  182. package/tests/slideshow.html +3 -3
  183. package/tests/sortable.html +15 -15
  184. package/tests/sticky-navbar.html +4 -4
  185. package/tests/sticky-parallax.html +3 -3
  186. package/tests/sticky.html +3 -3
  187. package/tests/svg.html +3 -2
  188. package/tests/switcher.html +6 -6
  189. package/tests/tab.html +4 -4
  190. package/tests/text.html +3 -3
  191. package/tests/tile.html +4 -4
  192. package/tests/toggle.html +1 -1
  193. package/tests/tooltip.html +3 -3
  194. package/tests/totop.html +2 -2
  195. package/tests/transition.html +1 -1
  196. package/tests/upload.html +5 -5
  197. package/tests/utility.html +16 -116
  198. package/tests/video.html +224 -24
  199. package/tests/visibility.html +4 -4
  200. package/tests/width.html +12 -12
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.25.17-dev.80dfe87",
5
+ "version": "3.25.17-dev.8c70e44",
6
6
  "main": "dist/js/uikit.js",
7
7
  "style": "dist/css/uikit.css",
8
8
  "sideEffects": [
@@ -35,7 +35,7 @@
35
35
  "devDependencies": {
36
36
  "@eslint/js": "^10.0.1",
37
37
  "@rollup/plugin-alias": "^6.0.0",
38
- "archiver": "^7.0.1",
38
+ "archiver": "^8.0.0",
39
39
  "camelcase": "^9.0.0",
40
40
  "clean-css": "^5.3.3",
41
41
  "esbuild": "^0.28.0",
@@ -48,11 +48,10 @@ export function createComponent(name, element, data, ...args) {
48
48
  const instance = getComponent(element, name);
49
49
 
50
50
  if (instance) {
51
- if (data) {
52
- instance.$destroy();
53
- } else {
51
+ if (!data) {
54
52
  return instance;
55
53
  }
54
+ instance.$destroy();
56
55
  }
57
56
 
58
57
  return new Component({ el: element, data });
@@ -43,10 +43,8 @@ export function lazyload(options = {}) {
43
43
  .forEach((el) => removeAttr(el, 'loading'));
44
44
  }
45
45
 
46
- for (const el of entries
47
- .filter(({ isIntersecting }) => isIntersecting)
48
- .map(({ target }) => target)) {
49
- observer.unobserve(el);
46
+ for (const { target } of entries.filter(({ isIntersecting }) => isIntersecting)) {
47
+ observer.unobserve(target);
50
48
  }
51
49
  },
52
50
  ...options,
@@ -153,11 +153,14 @@ export function parseOptions(options, args = []) {
153
153
  export function coerce(type, value) {
154
154
  if (type === Boolean) {
155
155
  return toBoolean(value);
156
- } else if (type === Number) {
156
+ }
157
+ if (type === Number) {
157
158
  return toNumber(value);
158
- } else if (type === 'list') {
159
+ }
160
+ if (type === 'list') {
159
161
  return toList(value);
160
- } else if (type === Object && isString(value)) {
162
+ }
163
+ if (type === Object && isString(value)) {
161
164
  return parseOptions(value);
162
165
  }
163
166
 
@@ -67,10 +67,7 @@ function getProps(opts) {
67
67
 
68
68
  const getAttributes = memoize((id, props) => {
69
69
  const attributes = Object.keys(props);
70
- const filter = attributes
71
- .concat(id)
72
- .map((key) => [hyphenate(key), `data-${hyphenate(key)}`])
73
- .flat();
70
+ const filter = [...attributes, id].flatMap((key) => [hyphenate(key), `data-${hyphenate(key)}`]);
74
71
  return { attributes, filter };
75
72
  });
76
73
 
@@ -43,14 +43,13 @@ function initMethods(instance) {
43
43
 
44
44
  function normalizeData({ data = {} }, { args = [], props = {} }) {
45
45
  if (isArray(data)) {
46
- data = data.slice(0, args.length).reduce((data, value, index) => {
47
- if (isPlainObject(value)) {
48
- assign(data, value);
49
- } else {
50
- data[args[index]] = value;
51
- }
52
- return data;
53
- }, {});
46
+ data = data
47
+ .slice(0, args.length)
48
+ .reduce(
49
+ (data, value, index) =>
50
+ assign(data, isPlainObject(value) ? value : { [args[index]]: value }),
51
+ {},
52
+ );
54
53
  }
55
54
 
56
55
  for (const key in data) {
@@ -2,6 +2,7 @@ export { default as Countdown } from './countdown';
2
2
  export { default as Filter } from './filter';
3
3
  export { default as Lightbox } from './lightbox';
4
4
  export { default as LightboxPanel } from './lightbox-panel';
5
+ export { default as Marquee } from './marquee';
5
6
  export { default as Notification } from './notification';
6
7
  export { default as Parallax } from './parallax';
7
8
  export { default as Slider } from './slider';
@@ -5,36 +5,17 @@ import { scale3d } from './slideshow-animations';
5
5
  export default {
6
6
  ...Animations,
7
7
  fade: {
8
- show() {
9
- return [{ opacity: 0 }, { opacity: 1 }];
10
- },
8
+ percent: (current) => 1 - css(current, 'opacity'),
11
9
 
12
- percent(current) {
13
- return 1 - css(current, 'opacity');
14
- },
15
-
16
- translate(percent) {
17
- return [{ opacity: 1 - percent }, { opacity: percent }];
18
- },
10
+ translate: (percent) => [{ opacity: 1 - percent }, { opacity: percent }],
19
11
  },
20
12
 
21
13
  scale: {
22
- show() {
23
- return [
24
- { opacity: 0, transform: scale3d(1 - 0.2) },
25
- { opacity: 1, transform: scale3d(1) },
26
- ];
27
- },
28
-
29
- percent(current) {
30
- return 1 - css(current, 'opacity');
31
- },
14
+ percent: (current) => 1 - css(current, 'opacity'),
32
15
 
33
- translate(percent) {
34
- return [
35
- { opacity: 1 - percent, transform: scale3d(1 - 0.2 * percent) },
36
- { opacity: percent, transform: scale3d(1 - 0.2 + 0.2 * percent) },
37
- ];
38
- },
16
+ translate: (percent) => [
17
+ { opacity: 1 - percent, transform: scale3d(1 - 0.2 * percent) },
18
+ { opacity: percent, transform: scale3d(1 - 0.2 + 0.2 * percent) },
19
+ ],
39
20
  },
40
21
  };
@@ -4,55 +4,24 @@ import Animations, { translate, translated } from '../../mixin/internal/slidesho
4
4
  export default {
5
5
  ...Animations,
6
6
  fade: {
7
- show() {
8
- return [{ opacity: 0, zIndex: 0 }, { zIndex: -1 }];
9
- },
10
-
11
- percent(current) {
12
- return 1 - css(current, 'opacity');
13
- },
14
-
15
- translate(percent) {
16
- return [{ opacity: 1 - percent, zIndex: 0 }, { zIndex: -1 }];
17
- },
7
+ percent: (current) => 1 - css(current, 'opacity'),
8
+ translate: (percent) => [{ opacity: 1 - percent, zIndex: 0 }, { zIndex: -1 }],
18
9
  },
19
10
 
20
11
  scale: {
21
- show() {
22
- return [{ opacity: 0, transform: scale3d(1 + 0.5), zIndex: 0 }, { zIndex: -1 }];
23
- },
24
-
25
- percent(current) {
26
- return 1 - css(current, 'opacity');
27
- },
12
+ percent: (current) => 1 - css(current, 'opacity'),
28
13
 
29
- translate(percent) {
30
- return [
31
- { opacity: 1 - percent, transform: scale3d(1 + 0.5 * percent), zIndex: 0 },
32
- { zIndex: -1 },
33
- ];
34
- },
14
+ translate: (percent) => [
15
+ { opacity: 1 - percent, transform: scale3d(1 + 0.5 * percent), zIndex: 0 },
16
+ { zIndex: -1 },
17
+ ],
35
18
  },
36
19
 
37
20
  pull: {
38
- show(dir) {
39
- return dir < 0
40
- ? [
41
- { transform: translate(30), zIndex: -1 },
42
- { transform: translate(), zIndex: 0 },
43
- ]
44
- : [
45
- { transform: translate(-100), zIndex: 0 },
46
- { transform: translate(), zIndex: -1 },
47
- ];
48
- },
21
+ percent: (current, next, dir) => (dir < 0 ? 1 - translated(next) : translated(current)),
49
22
 
50
- percent(current, next, dir) {
51
- return dir < 0 ? 1 - translated(next) : translated(current);
52
- },
53
-
54
- translate(percent, dir) {
55
- return dir < 0
23
+ translate: (percent, dir) =>
24
+ dir < 0
56
25
  ? [
57
26
  { transform: translate(30 * percent), zIndex: -1 },
58
27
  { transform: translate(-100 * (1 - percent)), zIndex: 0 },
@@ -60,29 +29,14 @@ export default {
60
29
  : [
61
30
  { transform: translate(-percent * 100), zIndex: 0 },
62
31
  { transform: translate(30 * (1 - percent)), zIndex: -1 },
63
- ];
64
- },
32
+ ],
65
33
  },
66
34
 
67
35
  push: {
68
- show(dir) {
69
- return dir < 0
70
- ? [
71
- { transform: translate(100), zIndex: 0 },
72
- { transform: translate(), zIndex: -1 },
73
- ]
74
- : [
75
- { transform: translate(-30), zIndex: -1 },
76
- { transform: translate(), zIndex: 0 },
77
- ];
78
- },
79
-
80
- percent(current, next, dir) {
81
- return dir > 0 ? 1 - translated(next) : translated(current);
82
- },
36
+ percent: (current, next, dir) => (dir > 0 ? 1 - translated(next) : translated(current)),
83
37
 
84
- translate(percent, dir) {
85
- return dir < 0
38
+ translate: (percent, dir) =>
39
+ dir < 0
86
40
  ? [
87
41
  { transform: translate(percent * 100), zIndex: 0 },
88
42
  { transform: translate(-30 * (1 - percent)), zIndex: -1 },
@@ -90,8 +44,7 @@ export default {
90
44
  : [
91
45
  { transform: translate(-30 * percent), zIndex: -1 },
92
46
  { transform: translate(100 * (1 - percent)), zIndex: 0 },
93
- ];
94
- },
47
+ ],
95
48
  },
96
49
  };
97
50
 
@@ -280,103 +280,23 @@ export default {
280
280
  return;
281
281
  }
282
282
 
283
- let matches;
284
- const iframeAttrs = {
285
- allowfullscreen: '',
286
- style: 'max-width: 100%; box-sizing: border-box;',
287
- 'uk-responsive': '',
288
- 'uk-video': Boolean(this.videoAutoplay),
289
- };
290
-
291
- // Image
292
- if (type === 'image' || isImage(src)) {
293
- const img = createEl('img');
294
-
295
- wrapInPicture(img, item.sources);
296
- attr(img, {
297
- src,
298
- ...pick(item, ['alt', 'srcset', 'sizes']),
299
- ...attrs,
300
- });
301
-
302
- on(img, 'load', () => this.setItem(item, parent(img) || img));
303
- on(img, 'error', () => this.setError(item));
304
-
305
- // Video
306
- } else if (type === 'video' || isVideo(src)) {
307
- const inline = this.videoAutoplay === 'inline';
308
- const video = createEl('video', {
309
- src,
310
- playsinline: '',
311
- controls: inline ? null : '',
312
- loop: inline ? '' : null,
313
- muted: inline ? '' : null,
314
- poster: this.videoAutoplay ? null : item.poster,
315
- 'uk-video': Boolean(this.videoAutoplay),
316
- ...attrs,
317
- });
318
-
319
- on(video, 'loadedmetadata', () => this.setItem(item, video));
320
- on(video, 'error', () => this.setError(item));
321
-
322
- // Iframe
323
- } else if (type === 'iframe' || src.match(/\.(html|php)($|\?)/i)) {
324
- this.setItem(
325
- item,
326
- createEl('iframe', {
327
- src,
328
- allowfullscreen: '',
329
- class: 'uk-lightbox-iframe',
330
- ...attrs,
331
- }),
332
- );
333
-
334
- // YouTube
335
- } else if (
336
- (matches = src.match(
337
- /\/\/(?:.*?youtube(-nocookie)?\..*?(?:[?&]v=|\/shorts\/)|youtu\.be\/)([\w-]{11})[&?]?(.*)?/,
338
- ))
339
- ) {
340
- this.setItem(
341
- item,
342
- createEl('iframe', {
343
- src: `https://www.youtube${matches[1] || ''}.com/embed/${matches[2]}${
344
- matches[3] ? `?${matches[3]}` : ''
345
- }`,
346
- width: 1920,
347
- height: 1080,
348
- ...iframeAttrs,
349
- ...attrs,
350
- }),
351
- );
352
-
353
- // Vimeo
354
- } else if ((matches = src.match(/\/\/.*?vimeo\.[a-z]+\/(\d+)[&?]?(.*)?/))) {
355
- try {
356
- const { height, width } = await (
357
- await fetch(
358
- `https://vimeo.com/api/oembed.json?maxwidth=1920&url=${encodeURI(
359
- src,
360
- )}`,
361
- { credentials: 'omit' },
362
- )
363
- ).json();
364
-
365
- this.setItem(
366
- item,
367
- createEl('iframe', {
368
- src: `https://player.vimeo.com/video/${matches[1]}${
369
- matches[2] ? `?${matches[2]}` : ''
370
- }`,
371
- width,
372
- height,
373
- ...iframeAttrs,
374
- ...attrs,
375
- }),
376
- );
377
- } catch {
378
- this.setError(item);
283
+ try {
284
+ for (const loader of [
285
+ loadImage,
286
+ loadVideo,
287
+ loadIframe,
288
+ loadYouTube,
289
+ loadVimeo,
290
+ ]) {
291
+ const content = await loader({ src, type, attrs, item, cmp: this });
292
+
293
+ if (content) {
294
+ this.setItem(item, content);
295
+ return;
296
+ }
379
297
  }
298
+ } catch {
299
+ this.setError(item);
380
300
  }
381
301
  },
382
302
  },
@@ -452,6 +372,111 @@ function createEl(tag, attrs) {
452
372
  return el;
453
373
  }
454
374
 
375
+ async function loadImage({ src, type, attrs, item }) {
376
+ if (type !== 'image' && !isImage(src)) {
377
+ return;
378
+ }
379
+
380
+ const img = createEl('img');
381
+
382
+ wrapInPicture(img, item.sources);
383
+ attr(img, {
384
+ src,
385
+ ...pick(item, ['alt', 'srcset', 'sizes']),
386
+ ...attrs,
387
+ });
388
+
389
+ await img.decode();
390
+
391
+ return parent(img) || img;
392
+ }
393
+
394
+ function loadVideo({ src, type, attrs, item, cmp }) {
395
+ if (type !== 'video' && !isVideo(src)) {
396
+ return;
397
+ }
398
+
399
+ const inline = cmp.videoAutoplay === 'inline';
400
+ const video = createEl('video', {
401
+ src,
402
+ playsinline: '',
403
+ controls: inline ? null : '',
404
+ loop: inline ? '' : null,
405
+ muted: inline ? '' : null,
406
+ poster: cmp.videoAutoplay ? null : item.poster,
407
+ 'uk-video': Boolean(cmp.videoAutoplay),
408
+ ...attrs,
409
+ });
410
+
411
+ return new Promise((resolve, reject) => {
412
+ on(video, 'loadedmetadata', () => resolve(video));
413
+ on(video, 'error', reject);
414
+ });
415
+ }
416
+
417
+ function loadIframe({ src, type, attrs }) {
418
+ if (type !== 'iframe' && !/\.(html|php)($|\?)/i.test(src)) {
419
+ return;
420
+ }
421
+
422
+ return createEl('iframe', {
423
+ src,
424
+ allowfullscreen: '',
425
+ class: 'uk-lightbox-iframe',
426
+ ...attrs,
427
+ });
428
+ }
429
+
430
+ function loadYouTube({ src, attrs, cmp }) {
431
+ const matches = src.match(
432
+ /\/\/(?:.*?youtube(-nocookie)?\..*?(?:[?&]v=|\/shorts\/)|youtu\.be\/)([\w-]{11})[&?]?(.*)?/,
433
+ );
434
+
435
+ if (!matches) {
436
+ return;
437
+ }
438
+
439
+ return createEl('iframe', {
440
+ src: `https://www.youtube${matches[1] || ''}.com/embed/${matches[2]}${matches[3] ? `?${matches[3]}` : ''}`,
441
+ width: 1920,
442
+ height: 1080,
443
+ ...getIframeAttrs(cmp),
444
+ ...attrs,
445
+ });
446
+ }
447
+
448
+ async function loadVimeo({ src, attrs, cmp }) {
449
+ const matches = src.match(/\/\/.*?vimeo\.[a-z]+\/(\d+)[&?]?(.*)?/);
450
+
451
+ if (!matches) {
452
+ return;
453
+ }
454
+
455
+ const { height, width } = await (
456
+ await fetch(
457
+ `https://vimeo.com/api/oembed.json?maxwidth=1920&url=${encodeURIComponent(src)}`,
458
+ { credentials: 'omit' },
459
+ )
460
+ ).json();
461
+
462
+ return createEl('iframe', {
463
+ src: `https://player.vimeo.com/video/${matches[1]}${matches[2] ? `?${matches[2]}` : ''}`,
464
+ width,
465
+ height,
466
+ ...getIframeAttrs(cmp),
467
+ ...attrs,
468
+ });
469
+ }
470
+
471
+ function getIframeAttrs(cmp) {
472
+ return {
473
+ allowfullscreen: '',
474
+ style: 'max-width: 100%; box-sizing: border-box;',
475
+ 'uk-responsive': '',
476
+ 'uk-video': Boolean(cmp.videoAutoplay),
477
+ };
478
+ }
479
+
455
480
  function toThumbnavItem(item, videoAutoplay) {
456
481
  const el =
457
482
  item.poster || (item.thumb && (item.type === 'image' || isImage(item.thumb)))
@@ -98,14 +98,11 @@ function ensureThumb(toggles, items) {
98
98
  continue;
99
99
  }
100
100
 
101
- const parent = parents(toggle)
102
- .reverse()
103
- .concat(toggle)
104
- .find(
105
- (parent) =>
106
- this.$el.contains(parent) &&
107
- (parent === toggle || $$(this.toggle, parent).length === 1),
108
- );
101
+ const parent = [...parents(toggle).reverse(), toggle].find(
102
+ (parent) =>
103
+ this.$el.contains(parent) &&
104
+ (parent === toggle || $$(this.toggle, parent).length === 1),
105
+ );
109
106
 
110
107
  if (!parent) {
111
108
  continue;
@@ -0,0 +1,123 @@
1
+ import {
2
+ $,
3
+ children,
4
+ css,
5
+ dimensions,
6
+ hasClass,
7
+ inBrowser,
8
+ isRtl,
9
+ pointerEnter,
10
+ pointerLeave,
11
+ toggleClass,
12
+ toPx,
13
+ } from 'uikit-util';
14
+ import { intersection, resize } from '../api/observables';
15
+ import Class from '../mixin/class';
16
+
17
+ const hasAnimationApi = inBrowser && window.Animation;
18
+
19
+ export default {
20
+ mixins: [Class],
21
+
22
+ props: {
23
+ velocity: Number,
24
+ start: Number,
25
+ reverse: Boolean,
26
+ pause: Boolean,
27
+ pauseVelocity: Number,
28
+ fadeSize: null,
29
+ },
30
+
31
+ data: {
32
+ velocity: 25,
33
+ start: 0,
34
+ reverse: false,
35
+ pause: false,
36
+ pauseVelocity: 10,
37
+ selList: '.uk-marquee-items',
38
+ fadeSize: 0,
39
+ },
40
+
41
+ computed: {
42
+ list: ({ selList }, $el) => $(selList, $el),
43
+ items() {
44
+ return children(this.list);
45
+ },
46
+ },
47
+
48
+ observe: [
49
+ resize({
50
+ target: ({ $el, items }) => [$el, ...items],
51
+ }),
52
+ intersection({
53
+ handler(entries) {
54
+ for (const entry of entries) {
55
+ entry.target.inert = !entry.isIntersecting;
56
+ }
57
+ },
58
+ target: ({ items }) => items,
59
+ args: { intersecting: false },
60
+ options: ({ $el }) => ({ root: $el }),
61
+ }),
62
+ ],
63
+
64
+ events: {
65
+ name: [pointerEnter, pointerLeave],
66
+ el: ({ $el }) => $el,
67
+ self: true,
68
+ filter: ({ pause }) => hasAnimationApi && pause,
69
+ handler(e) {
70
+ for (const el of this.items) {
71
+ for (const animation of el.getAnimations()) {
72
+ animation.playbackRate =
73
+ e.type === pointerEnter ? this.pauseVelocity / this.velocity : 1;
74
+ }
75
+ }
76
+ },
77
+ },
78
+
79
+ update: {
80
+ write() {
81
+ const prefix = this.$options.id;
82
+ const items = this.items;
83
+ const vertical = hasClass(this.$el, `${prefix}-vertical`);
84
+
85
+ css(items, 'offset', 'none');
86
+
87
+ const dir = vertical ? ['top', 'bottom'] : ['left', 'right'];
88
+ if (!vertical && isRtl) {
89
+ dir.reverse();
90
+ }
91
+
92
+ const listStart = dimensions(this.list)[dir[0]];
93
+ const listEnd = Math[!vertical && isRtl ? 'min' : 'max'](
94
+ ...items.map((el) => dimensions(el)[dir[1]]),
95
+ );
96
+
97
+ for (const el of items) {
98
+ const elEnd = dimensions(el)[dir[1]];
99
+ const line1 = listEnd - elEnd;
100
+ const line2 = elEnd - listStart;
101
+ const path = vertical
102
+ ? `"M0 0 v${line1}M0 ${-line2} v${line2}"`
103
+ : `"M0 0 h${line1}M${-line2} 0 h${line2}"`;
104
+ css(el, `--${prefix}-path`, path);
105
+ }
106
+
107
+ css(this.$el, {
108
+ [`--${prefix}-duration`]: `${Math.abs(listStart - listEnd) / this.velocity}s`,
109
+ [`--${prefix}-start`]: this.start,
110
+ [`--${prefix}-direction`]: this.reverse ? 'reverse' : 'normal',
111
+ '--uk-overflow-fade-size': this.fadeSize
112
+ ? `${toPx(this.fadeSize, vertical ? 'height' : 'width', this.$el, true)}px`
113
+ : '',
114
+ });
115
+
116
+ toggleClass(this.$el, `${prefix}-fade`, this.fadeSize);
117
+
118
+ css(items, 'offset', '');
119
+ },
120
+
121
+ events: ['resize'],
122
+ },
123
+ };
@@ -176,8 +176,10 @@ function getAlignment(el, target, [dir, align]) {
176
176
 
177
177
  function parseProps(options) {
178
178
  const { el, id, data } = options;
179
- return ['delay', 'title'].reduce((obj, key) => ({ [key]: getData(el, key), ...obj }), {
179
+ return {
180
+ delay: getData(el, 'delay'),
181
+ title: getData(el, 'title'),
180
182
  ...parseOptions(getData(el, id), ['title']),
181
183
  ...data,
182
- });
184
+ };
183
185
  }