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
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  hasAttr,
3
+ isFocusable,
3
4
  isTag,
4
5
  isTouch,
5
6
  mute,
@@ -11,26 +12,50 @@ import {
11
12
  query,
12
13
  } from 'uikit-util';
13
14
  import { intersection } from '../api/observables';
15
+ import ScrollDriven from '../mixin/scroll-driven';
16
+
17
+ const loopKey = Symbol();
14
18
 
15
19
  export default {
20
+ mixins: [ScrollDriven],
21
+
16
22
  args: 'autoplay',
17
23
 
18
24
  props: {
19
25
  automute: Boolean,
20
26
  autoplay: Boolean,
21
27
  restart: Boolean,
28
+ inviewMargin: String,
29
+ inviewQueued: Number,
22
30
  hoverTarget: Boolean,
31
+ hoverRewind: Number,
32
+ reducedMotionTime: Number,
23
33
  },
24
34
 
25
35
  data: {
26
36
  automute: false,
27
37
  autoplay: true,
28
38
  restart: false,
39
+ inviewMargin: '0px',
40
+ inviewQueued: 0,
29
41
  hoverTarget: false,
42
+ hoverRewind: 0,
43
+ reducedMotionTime: 0,
30
44
  },
31
45
 
32
46
  beforeConnect() {
33
47
  const isVideo = isTag(this.$el, 'video');
48
+
49
+ this.restart = isVideo && this.restart;
50
+ this.parallax = isVideo && this.autoplay === 'parallax';
51
+ this.manualControl = ['hover', 'parallax'].includes(this.autoplay);
52
+ this.inviewQueued = this.autoplay === 'inview' && this.inviewQueued;
53
+
54
+ if (this.inviewQueued) {
55
+ this.$el[loopKey] = this.$el.loop;
56
+ this.$el.loop = false;
57
+ }
58
+
34
59
  if (this.autoplay === 'inview' && isVideo && !hasAttr(this.$el, 'preload')) {
35
60
  this.$el.preload = 'none';
36
61
  }
@@ -41,7 +66,11 @@ export default {
41
66
 
42
67
  if (this.autoplay === 'hover') {
43
68
  if (isVideo) {
44
- this.$el.tabIndex = 0;
69
+ this.hoverTarget = query(this.hoverTarget, this.$el) || this.$el;
70
+
71
+ if (!isFocusable(this.hoverTarget)) {
72
+ this.hoverTarget.tabIndex = 0;
73
+ }
45
74
  } else {
46
75
  this.autoplay = true;
47
76
  }
@@ -53,19 +82,29 @@ export default {
53
82
  }
54
83
  },
55
84
 
85
+ disconnected() {
86
+ if (this.$el[loopKey]) {
87
+ this.$el.loop = true;
88
+ }
89
+
90
+ queue.delete(this.$el);
91
+ },
92
+
56
93
  events: [
57
94
  {
58
95
  name: `${pointerEnter} focusin`,
59
96
 
60
- el: ({ hoverTarget, $el }) => query(hoverTarget, $el) || $el,
97
+ el: ({ hoverTarget }) => hoverTarget,
61
98
 
62
99
  filter: ({ autoplay }) => autoplay === 'hover',
63
100
 
64
101
  handler(e) {
102
+ this._reverseAbort?.abort();
103
+
65
104
  if (!isTouch(e) || !isPlaying(this.$el)) {
66
- play(this.$el);
105
+ this.play();
67
106
  } else {
68
- pauseHover(this.$el, this.restart);
107
+ this.pause();
69
108
  }
70
109
  },
71
110
  },
@@ -73,14 +112,27 @@ export default {
73
112
  {
74
113
  name: `${pointerLeave} focusout`,
75
114
 
76
- el: ({ hoverTarget, $el }) => query(hoverTarget, $el) || $el,
115
+ el: ({ hoverTarget }) => hoverTarget,
77
116
 
78
117
  filter: ({ autoplay }) => autoplay === 'hover',
79
118
 
80
119
  handler(e) {
81
120
  if (!isTouch(e)) {
82
- pauseHover(this.$el, this.restart);
121
+ this._reverseAbort?.abort();
122
+ this.pause();
123
+ this._reverseAbort = playReverse(this.$el, this.hoverRewind);
124
+ }
125
+ },
126
+ },
127
+ {
128
+ name: 'error pause ended',
129
+ filter: ({ inviewQueued }) => inviewQueued,
130
+ handler(e) {
131
+ if (e.type === 'error' || (e.type === 'ended' && !this.$el[loopKey])) {
132
+ queue.delete(this.$el);
83
133
  }
134
+
135
+ playNextQueued();
84
136
  },
85
137
  },
86
138
  ],
@@ -95,33 +147,138 @@ export default {
95
147
  }),
96
148
 
97
149
  intersection({
98
- filter: ({ $el, autoplay }) => autoplay !== 'hover' && $el.preload !== 'none',
99
- handler([{ isIntersecting, target }]) {
150
+ filter: ({ $el, manualControl }) => !manualControl && $el.preload !== 'none',
151
+ handler([{ isIntersecting }]) {
100
152
  if (!document.fullscreenElement) {
101
153
  if (isIntersecting) {
102
154
  if (this.autoplay) {
103
- play(target);
155
+ this._autoplay();
104
156
  }
105
157
  } else {
106
- pauseHover(target, this.restart);
158
+ this.pause();
107
159
  }
108
160
  }
109
161
  },
110
162
  args: { intersecting: false },
111
- options: ({ $el, autoplay }) => ({
163
+ options: ({ $el, autoplay, inviewMargin }) => ({
112
164
  root: autoplay === 'inview' ? null : parent($el).closest(':not(a)'),
165
+ rootMargin: autoplay === 'inview' ? inviewMargin : '0px',
113
166
  }),
114
167
  }),
115
168
  ],
169
+
170
+ update: {
171
+ write({ percent }) {
172
+ if (!this.parallax) {
173
+ return;
174
+ }
175
+
176
+ const { duration, seeking } = this.$el;
177
+
178
+ if (!isNaN(duration) && !seeking) {
179
+ this.$el.currentTime = percent * duration;
180
+ }
181
+ },
182
+
183
+ events: ['scroll', 'resize'],
184
+ },
185
+
186
+ methods: {
187
+ _autoplay() {
188
+ if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
189
+ this.pause();
190
+
191
+ if (isTag(this.$el, 'video')) {
192
+ this.$el.currentTime = this.reducedMotionTime;
193
+ }
194
+ } else {
195
+ this.play();
196
+ }
197
+ },
198
+
199
+ play() {
200
+ if (this.inviewQueued) {
201
+ queue.set(this.$el, this.inviewQueued);
202
+ playNextQueued();
203
+ } else {
204
+ play(this.$el);
205
+ }
206
+ },
207
+
208
+ pause() {
209
+ pause(this.$el);
210
+
211
+ queue.delete(this.$el);
212
+
213
+ if (this.restart) {
214
+ this.$el.currentTime = 0;
215
+ }
216
+ },
217
+ },
116
218
  };
117
219
 
118
220
  function isPlaying(videoEl) {
119
221
  return !videoEl.paused && !videoEl.ended;
120
222
  }
121
223
 
122
- function pauseHover(el, restart) {
123
- pause(el);
124
- if (restart && isTag(el, 'video')) {
125
- el.currentTime = 0;
224
+ const queue = new Map();
225
+ const played = new WeakMap();
226
+
227
+ let frame;
228
+ async function playNextQueued() {
229
+ cancelAnimationFrame(frame);
230
+ await new Promise((resolve) => (frame = requestAnimationFrame(resolve)));
231
+
232
+ const getPlayed = (el) => played.get(el) ?? 0;
233
+ const videos = shuffle(queue.keys()).sort((a, b) => getPlayed(a) - getPlayed(b));
234
+
235
+ for (const el of videos) {
236
+ const maxQueued = queue.get(el);
237
+
238
+ if (isPlaying(el) || videos.filter(isPlaying).length / queue.size >= maxQueued) {
239
+ continue;
240
+ }
241
+
242
+ played.set(el, getPlayed(el) + 1);
243
+ play(el);
244
+ }
245
+ }
246
+
247
+ function shuffle(array) {
248
+ array = [...array];
249
+ for (let i = array.length - 1; i > 0; i--) {
250
+ let j = Math.floor(Math.random() * (i + 1));
251
+ [array[i], array[j]] = [array[j], array[i]];
252
+ }
253
+ return array;
254
+ }
255
+
256
+ function playReverse(el, playbackRate) {
257
+ const start = el.currentTime;
258
+
259
+ if (isNaN(start) || !playbackRate) {
260
+ return;
126
261
  }
262
+
263
+ playbackRate *= Math.max(1, start / 10 + 0.5);
264
+
265
+ const controller = new AbortController();
266
+ const time = Date.now();
267
+ (function next() {
268
+ requestAnimationFrame(() => {
269
+ if (controller.signal.aborted) {
270
+ return;
271
+ }
272
+
273
+ if (!el.seeking) {
274
+ el.currentTime = Math.max(0, start - ((Date.now() - time) * playbackRate) / 1000);
275
+ }
276
+
277
+ if (el.currentTime > 0) {
278
+ next();
279
+ }
280
+ });
281
+ })();
282
+
283
+ return controller;
127
284
  }
@@ -0,0 +1,57 @@
1
+ import { children, hasClass, isTag, queryAll, toArray } from 'uikit-util';
2
+ import { lazyload } from '../api/observables';
3
+ import Togglable from '../mixin/togglable';
4
+
5
+ export default {
6
+ mixins: [Togglable],
7
+
8
+ props: {
9
+ connect: String,
10
+ },
11
+
12
+ data: {
13
+ connect: '',
14
+ cls: 'uk-active',
15
+ },
16
+
17
+ computed: {
18
+ connects: {
19
+ get: ({ connect }, $el) => (connect ? queryAll(connect, $el) : []),
20
+ observe: ({ connect }) => connect,
21
+ },
22
+
23
+ connectChildren() {
24
+ return this.connects.flatMap((el) => children(el));
25
+ },
26
+ },
27
+
28
+ watch: {
29
+ connects(connects) {
30
+ for (const el of connects) {
31
+ if (isTag(el, 'ul')) {
32
+ el.role = 'presentation';
33
+ }
34
+ }
35
+ },
36
+ },
37
+
38
+ observe: lazyload({ targets: ({ connectChildren }) => connectChildren }),
39
+
40
+ methods: {
41
+ showConnects(index, animate) {
42
+ const toggle = async ({ children }) => {
43
+ const actives = toArray(children).filter(
44
+ (child, i) => i !== index && hasClass(child, this.cls),
45
+ );
46
+
47
+ if (await this.toggleElement(actives, false, animate)) {
48
+ if (!hasClass(children[index], this.cls)) {
49
+ await this.toggleElement(children[index], true, animate);
50
+ }
51
+ }
52
+ };
53
+
54
+ return Promise.all(this.connects.map(toggle));
55
+ },
56
+ },
57
+ };
@@ -2,20 +2,12 @@ import { css } from 'uikit-util';
2
2
 
3
3
  export default {
4
4
  slide: {
5
- show(dir) {
6
- return [{ transform: translate(dir * -100) }, { transform: translate() }];
7
- },
5
+ percent: translated,
8
6
 
9
- percent(current) {
10
- return translated(current);
11
- },
12
-
13
- translate(percent, dir) {
14
- return [
15
- { transform: translate(dir * -100 * percent) },
16
- { transform: translate(dir * 100 * (1 - percent)) },
17
- ];
18
- },
7
+ translate: (percent, dir) => [
8
+ { transform: translate(dir * -100 * percent) },
9
+ { transform: translate(dir * 100 * (1 - percent)) },
10
+ ],
19
11
  },
20
12
  };
21
13
 
@@ -1,8 +1,8 @@
1
1
  import { clamp, createEvent, css, noop, resetProps, Transition, trigger } from 'uikit-util';
2
2
 
3
3
  export default function Transitioner(prev, next, dir, { animation, easing }) {
4
- const { percent, translate, show = noop } = animation;
5
- const props = show(dir);
4
+ const { percent, translate } = animation;
5
+ const props = translate(1, dir);
6
6
 
7
7
  const { promise, resolve } = withResolvers();
8
8
 
@@ -229,11 +229,12 @@ export default {
229
229
  },
230
230
  };
231
231
 
232
+ const rejectKey = Symbol();
232
233
  function animate(el, show, { transitionElement, _toggle }) {
233
234
  return new Promise((resolve, reject) =>
234
235
  once(el, 'show hide', () => {
235
- el._reject?.();
236
- el._reject = reject;
236
+ el[rejectKey]?.();
237
+ el[rejectKey] = reject;
237
238
 
238
239
  _toggle(el, show);
239
240
 
@@ -257,7 +258,7 @@ function animate(el, show, { transitionElement, _toggle }) {
257
258
  toMs(css(transitionElement, 'transitionDuration')),
258
259
  );
259
260
  }),
260
- ).then(() => delete el._reject);
261
+ ).then(() => delete el[rejectKey]);
261
262
  }
262
263
 
263
264
  function toMs(time) {
@@ -382,10 +382,7 @@ function getCssValue(el, prop, value) {
382
382
  }
383
383
 
384
384
  function fillObject(keys, value) {
385
- return keys.reduce((data, prop) => {
386
- data[prop] = value;
387
- return data;
388
- }, {});
385
+ return Object.fromEntries(keys.map((prop) => [prop, value]));
389
386
  }
390
387
 
391
388
  /*
@@ -27,7 +27,7 @@ export default {
27
27
  },
28
28
 
29
29
  connected() {
30
- this.pos = this.$props.pos.split('-').concat('center').slice(0, 2);
30
+ this.pos = [...this.$props.pos.split('-'), 'center'].slice(0, 2);
31
31
  [this.dir, this.align] = this.pos;
32
32
  this.axis = includes(['top', 'bottom'], this.dir) ? 'y' : 'x';
33
33
  },
@@ -0,0 +1,57 @@
1
+ import { query, scrolledOver, toPx } from 'uikit-util';
2
+ import { resize, scroll } from '../api/observables';
3
+ import { ease } from './parallax';
4
+
5
+ export default {
6
+ props: {
7
+ parallaxTarget: Boolean,
8
+ parallaxStart: String,
9
+ parallaxEnd: String,
10
+ parallaxEasing: Number,
11
+ },
12
+
13
+ data: {
14
+ parallaxTarget: false,
15
+ parallaxStart: 0,
16
+ parallaxEnd: 0,
17
+ parallaxEasing: 0,
18
+ },
19
+
20
+ observe: [
21
+ resize({
22
+ target: ({ $el, parallaxTarget }) => [$el, parallaxTarget],
23
+ filter: ({ parallax }) => parallax,
24
+ }),
25
+ scroll({ filter: ({ parallax }) => parallax }),
26
+ ],
27
+
28
+ computed: {
29
+ parallaxTargetFallback: ($props, $el) => $el,
30
+
31
+ parallaxTarget({ parallaxTarget }, $el) {
32
+ return (parallaxTarget && query(parallaxTarget, $el)) || this.parallaxTargetFallback;
33
+ },
34
+ },
35
+
36
+ update: {
37
+ read() {
38
+ if (!this.parallax) {
39
+ return;
40
+ }
41
+
42
+ const target = this.parallaxTarget;
43
+
44
+ if (!target) {
45
+ return;
46
+ }
47
+
48
+ const start = toPx(this.parallaxStart, 'height', target, true);
49
+ const end = toPx(this.parallaxEnd, 'height', target, true);
50
+ const percent = ease(scrolledOver(target, start, end), this.parallaxEasing);
51
+
52
+ return { percent };
53
+ },
54
+
55
+ events: ['scroll', 'resize'],
56
+ },
57
+ };
@@ -35,7 +35,7 @@ export default {
35
35
  nav: ({ selNav }, $el) => $$(selNav, $el),
36
36
 
37
37
  navChildren() {
38
- return this.nav.map((nav) => children(nav)).flat();
38
+ return this.nav.flatMap((nav) => children(nav));
39
39
  },
40
40
 
41
41
  selNavItem: ({ attrItem }) => `[${attrItem}],[data-${attrItem}]`,
@@ -1,59 +1,30 @@
1
- import { hasClass, includes, query, scrolledOver, toPx, trigger } from 'uikit-util';
2
- import { resize, scroll } from '../api/observables';
3
- import { ease } from './parallax';
1
+ import { hasClass, includes, trigger } from 'uikit-util';
2
+ import ScrollDriven from './scroll-driven';
4
3
 
5
4
  export default {
5
+ mixins: [ScrollDriven],
6
+
6
7
  props: {
7
8
  parallax: Boolean,
8
- parallaxTarget: Boolean,
9
- parallaxStart: String,
10
- parallaxEnd: String,
11
- parallaxEasing: Number,
12
9
  },
13
10
 
14
11
  data: {
15
12
  parallax: false,
16
- parallaxTarget: false,
17
- parallaxStart: 0,
18
- parallaxEnd: 0,
19
- parallaxEasing: 0,
20
13
  },
21
14
 
22
- observe: [
23
- resize({
24
- target: ({ $el, parallaxTarget }) => [$el, parallaxTarget],
25
- filter: ({ parallax }) => parallax,
26
- }),
27
- scroll({ filter: ({ parallax }) => parallax }),
28
- ],
29
-
30
15
  computed: {
31
- parallaxTarget({ parallaxTarget }, $el) {
32
- return (parallaxTarget && query(parallaxTarget, $el)) || this.list;
16
+ parallaxTargetFallback() {
17
+ return this.list;
33
18
  },
34
19
  },
35
20
 
36
21
  update: {
37
- read() {
22
+ write({ percent }) {
38
23
  if (!this.parallax) {
39
- return false;
40
- }
41
-
42
- const target = this.parallaxTarget;
43
-
44
- if (!target) {
45
- return false;
24
+ return;
46
25
  }
47
26
 
48
- const start = toPx(this.parallaxStart, 'height', target, true);
49
- const end = toPx(this.parallaxEnd, 'height', target, true);
50
- const percent = ease(scrolledOver(target, start, end), this.parallaxEasing);
51
-
52
- return { parallax: this.getIndexAt(percent) };
53
- },
54
-
55
- write({ parallax }) {
56
- const [prevIndex, slidePercent] = parallax;
27
+ const [prevIndex, slidePercent] = this.getIndexAt(percent);
57
28
 
58
29
  const nextIndex = this.getValidIndex(prevIndex + Math.ceil(slidePercent));
59
30
 
@@ -9,6 +9,7 @@ import {
9
9
  isBoolean,
10
10
  isFunction,
11
11
  isVisible,
12
+ pick,
12
13
  removeClass,
13
14
  startsWith,
14
15
  toFloat,
@@ -163,20 +164,18 @@ async function toggleTransition(el, show, { animation, duration, velocity, trans
163
164
  _toggle(el, true);
164
165
  }
165
166
 
166
- const prevProps = Object.fromEntries(
167
- [
168
- 'padding',
169
- 'border',
170
- 'width',
171
- 'height',
172
- 'minWidth',
173
- 'minHeight',
174
- 'overflowY',
175
- 'overflowX',
176
- marginProp,
177
- marginStartProp,
178
- ].map((key) => [key, el.style[key]]),
179
- );
167
+ const prevProps = pick(el.style, [
168
+ 'padding',
169
+ 'border',
170
+ 'width',
171
+ 'height',
172
+ 'minWidth',
173
+ 'minHeight',
174
+ 'overflowY',
175
+ 'overflowX',
176
+ marginProp,
177
+ marginStartProp,
178
+ ]);
180
179
 
181
180
  const dim = dimensions(el);
182
181
  const currentMargin = toFloat(css(el, marginProp));
@@ -10,13 +10,13 @@ export function attr(element, name, value) {
10
10
 
11
11
  if (isUndefined(value)) {
12
12
  return toNode(element)?.getAttribute(name);
13
- } else {
14
- for (const el of toNodes(element)) {
15
- if (value === null) {
16
- removeAttr(el, name);
17
- } else {
18
- el.setAttribute(name, value);
19
- }
13
+ }
14
+
15
+ for (const el of toNodes(element)) {
16
+ if (value === null) {
17
+ removeAttr(el, name);
18
+ } else {
19
+ el.setAttribute(name, value);
20
20
  }
21
21
  }
22
22
  }
@@ -47,7 +47,7 @@ export function toggleClass(element, cls, force) {
47
47
  function toClasses(str) {
48
48
  return str
49
49
  ? isArray(str)
50
- ? str.map(toClasses).flat()
50
+ ? str.flatMap(toClasses)
51
51
  : String(str).split(' ').filter(Boolean)
52
52
  : [];
53
53
  }
@@ -68,10 +68,9 @@ export function wrapInner(element, structure) {
68
68
  }
69
69
 
70
70
  export function unwrap(element) {
71
- toNodes(element)
72
- .map(parent)
73
- .filter((value, index, self) => self.indexOf(value) === index)
74
- .forEach((parent) => parent.replaceWith(...parent.childNodes));
71
+ for (const elementParent of new Set(toNodes(element).map(parent))) {
72
+ elementParent.replaceWith(...elementParent.childNodes);
73
+ }
75
74
  }
76
75
 
77
76
  const singleTagRe = /^<(\w+)\s*\/?>(?:<\/\1>)?$/;
@@ -177,7 +177,7 @@ export function uniqueBy(array, prop) {
177
177
  }
178
178
 
179
179
  export function pick(obj, props) {
180
- return props.reduce((res, prop) => ({ ...res, [prop]: obj[prop] }), {});
180
+ return Object.fromEntries(props.map((key) => [key, obj[key]]));
181
181
  }
182
182
 
183
183
  export function clamp(number, min = 0, max = 1) {
@@ -42,13 +42,13 @@ function isIFrame(el) {
42
42
  }
43
43
 
44
44
  function isYoutube(el) {
45
- return !!el.src.match(
46
- /\/\/.*?youtube(-nocookie)?\.[a-z]+\/(watch\?v=[^&\s]+|embed)|youtu\.be\/.*/,
45
+ return /\/\/.*?youtube(-nocookie)?\.[a-z]+\/(watch\?v=[^&\s]+|embed)|youtu\.be\/.*/.test(
46
+ el.src,
47
47
  );
48
48
  }
49
49
 
50
50
  function isVimeo(el) {
51
- return !!el.src.match(/vimeo\.com\/video\/.*/);
51
+ return /vimeo\.com\/video\/.*/.test(el.src);
52
52
  }
53
53
 
54
54
  async function call(el, cmd) {
@@ -60,7 +60,7 @@ function post(el, cmd) {
60
60
  el.contentWindow.postMessage(JSON.stringify({ event: 'command', ...cmd }), '*');
61
61
  }
62
62
 
63
- const stateKey = '_ukPlayer';
63
+ const stateKey = Symbol();
64
64
  let counter = 0;
65
65
  function enableApi(el) {
66
66
  if (el[stateKey]) {