uikit 3.25.27-dev.9e97c1f → 3.25.27

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 (222) hide show
  1. package/CHANGELOG.md +2 -34
  2. package/build/prefix.js +1 -1
  3. package/build/publishDev.js +1 -1
  4. package/build/scope.js +1 -1
  5. package/build/scss.js +1 -1
  6. package/dist/css/uikit-core-rtl.css +1569 -1692
  7. package/dist/css/uikit-core-rtl.min.css +1 -1
  8. package/dist/css/uikit-core.css +1569 -1692
  9. package/dist/css/uikit-core.min.css +1 -1
  10. package/dist/css/uikit-rtl.css +1210 -1326
  11. package/dist/css/uikit-rtl.min.css +1 -1
  12. package/dist/css/uikit.css +1210 -1326
  13. package/dist/css/uikit.min.css +1 -1
  14. package/dist/js/components/countdown.js +1 -1
  15. package/dist/js/components/countdown.min.js +1 -1
  16. package/dist/js/components/filter.js +1 -1
  17. package/dist/js/components/filter.min.js +1 -1
  18. package/dist/js/components/lightbox-panel.js +135 -134
  19. package/dist/js/components/lightbox-panel.min.js +1 -1
  20. package/dist/js/components/lightbox.js +136 -135
  21. package/dist/js/components/lightbox.min.js +1 -1
  22. package/dist/js/components/notification.js +6 -8
  23. package/dist/js/components/notification.min.js +1 -1
  24. package/dist/js/components/parallax.js +12 -8
  25. package/dist/js/components/parallax.min.js +1 -1
  26. package/dist/js/components/slider-parallax.js +12 -8
  27. package/dist/js/components/slider-parallax.min.js +1 -1
  28. package/dist/js/components/slider.js +25 -51
  29. package/dist/js/components/slider.min.js +1 -1
  30. package/dist/js/components/slideshow-parallax.js +12 -8
  31. package/dist/js/components/slideshow-parallax.min.js +1 -1
  32. package/dist/js/components/slideshow.js +102 -81
  33. package/dist/js/components/slideshow.min.js +1 -1
  34. package/dist/js/components/sortable.js +1 -1
  35. package/dist/js/components/sortable.min.js +1 -1
  36. package/dist/js/components/tooltip.js +17 -15
  37. package/dist/js/components/tooltip.min.js +1 -1
  38. package/dist/js/components/upload.js +1 -1
  39. package/dist/js/components/upload.min.js +1 -1
  40. package/dist/js/uikit-core.js +313 -856
  41. package/dist/js/uikit-core.min.js +1 -1
  42. package/dist/js/uikit-icons.js +1 -1
  43. package/dist/js/uikit-icons.min.js +1 -1
  44. package/dist/js/uikit.js +377 -711
  45. package/dist/js/uikit.min.js +1 -1
  46. package/package.json +2 -2
  47. package/src/js/api/component.js +3 -2
  48. package/src/js/api/observables.js +4 -16
  49. package/src/js/api/options.js +3 -6
  50. package/src/js/api/props.js +3 -1
  51. package/src/js/api/state.js +8 -7
  52. package/src/js/components/index.js +0 -1
  53. package/src/js/components/internal/lightbox-animations.js +26 -7
  54. package/src/js/components/internal/slider-preload.js +0 -1
  55. package/src/js/components/internal/slideshow-animations.js +62 -15
  56. package/src/js/components/lightbox-panel.js +96 -121
  57. package/src/js/components/lightbox.js +8 -5
  58. package/src/js/components/notification.js +5 -7
  59. package/src/js/core/accordion.js +31 -62
  60. package/src/js/core/drop.js +3 -4
  61. package/src/js/core/dropnav.js +3 -3
  62. package/src/js/core/grid.js +19 -5
  63. package/src/js/core/margin.js +0 -3
  64. package/src/js/core/scroll.js +11 -0
  65. package/src/js/core/sticky.js +1 -1
  66. package/src/js/core/switcher.js +49 -12
  67. package/src/js/core/video.js +21 -236
  68. package/src/js/mixin/internal/slideshow-animations.js +13 -5
  69. package/src/js/mixin/internal/slideshow-transitioner.js +2 -2
  70. package/src/js/mixin/parallax.js +4 -1
  71. package/src/js/mixin/position.js +1 -1
  72. package/src/js/mixin/slider-parallax.js +38 -9
  73. package/src/js/mixin/togglable.js +14 -13
  74. package/src/js/util/attr.js +7 -7
  75. package/src/js/util/dom.js +4 -3
  76. package/src/js/util/lang.js +2 -2
  77. package/src/js/util/player.js +2 -4
  78. package/src/js/util/style.js +13 -12
  79. package/src/js/util/viewport.js +25 -22
  80. package/src/less/components/_import.less +3 -8
  81. package/src/less/components/animation.less +1 -1
  82. package/src/less/components/base.less +1 -1
  83. package/src/less/components/button.less +1 -1
  84. package/src/less/components/card.less +8 -8
  85. package/src/less/components/form.less +15 -15
  86. package/src/less/components/grid.less +65 -58
  87. package/src/less/components/lightbox.less +8 -2
  88. package/src/less/components/margin.less +124 -155
  89. package/src/less/components/modal.less +4 -1
  90. package/src/less/components/nav.less +1 -1
  91. package/src/less/components/navbar.less +1 -1
  92. package/src/less/components/padding.less +9 -9
  93. package/src/less/components/position.less +4 -9
  94. package/src/less/components/search.less +1 -1
  95. package/src/less/components/slideshow.less +4 -1
  96. package/src/less/components/switcher.less +2 -5
  97. package/src/less/components/table.less +4 -4
  98. package/src/less/components/text.less +4 -10
  99. package/src/less/components/utility.less +163 -0
  100. package/src/less/components/visibility.less +4 -4
  101. package/src/less/theme/_import.less +2 -6
  102. package/src/less/theme/alert.less +5 -0
  103. package/src/less/theme/thumbnav.less +4 -1
  104. package/src/less/theme/utility.less +32 -0
  105. package/src/scss/components/_import.scss +3 -8
  106. package/src/scss/components/animation.scss +1 -1
  107. package/src/scss/components/base.scss +1 -1
  108. package/src/scss/components/button.scss +1 -1
  109. package/src/scss/components/card.scss +8 -8
  110. package/src/scss/components/form.scss +14 -14
  111. package/src/scss/components/grid.scss +64 -57
  112. package/src/scss/components/lightbox.scss +8 -2
  113. package/src/scss/components/margin.scss +124 -155
  114. package/src/scss/components/modal.scss +4 -1
  115. package/src/scss/components/nav.scss +1 -1
  116. package/src/scss/components/navbar.scss +1 -1
  117. package/src/scss/components/padding.scss +9 -9
  118. package/src/scss/components/position.scss +4 -9
  119. package/src/scss/components/search.scss +1 -1
  120. package/src/scss/components/slideshow.scss +4 -1
  121. package/src/scss/components/switcher.scss +2 -5
  122. package/src/scss/components/table.scss +4 -4
  123. package/src/scss/components/text.scss +4 -10
  124. package/src/scss/components/utility.scss +129 -0
  125. package/src/scss/components/visibility.scss +4 -4
  126. package/src/scss/mixins-theme.scss +43 -44
  127. package/src/scss/mixins.scss +31 -40
  128. package/src/scss/variables-theme.scss +14 -14
  129. package/src/scss/variables.scss +14 -14
  130. package/tests/accordion.html +10 -77
  131. package/tests/alert.html +1 -1
  132. package/tests/align.html +5 -5
  133. package/tests/animation.html +4 -4
  134. package/tests/article.html +7 -7
  135. package/tests/background.html +2 -2
  136. package/tests/badge.html +1 -1
  137. package/tests/base.html +2 -2
  138. package/tests/button.html +1 -1
  139. package/tests/card.html +15 -15
  140. package/tests/close.html +2 -2
  141. package/tests/comment.html +9 -9
  142. package/tests/container.html +2 -2
  143. package/tests/countdown.html +21 -21
  144. package/tests/cover.html +3 -3
  145. package/tests/description-list.html +1 -1
  146. package/tests/divider.html +3 -3
  147. package/tests/dotnav.html +1 -1
  148. package/tests/drop.html +7 -7
  149. package/tests/dropbar.html +5 -5
  150. package/tests/dropdown.html +1 -1
  151. package/tests/dropnav.html +18 -18
  152. package/tests/filter.html +3 -3
  153. package/tests/form.html +14 -14
  154. package/tests/grid.html +47 -41
  155. package/tests/heading.html +2 -2
  156. package/tests/height-viewport.html +4 -4
  157. package/tests/height.html +5 -5
  158. package/tests/icon.html +8 -8
  159. package/tests/image.html +6 -6
  160. package/tests/index.html +13 -13
  161. package/tests/js/index.js +1 -1
  162. package/tests/leader.html +5 -5
  163. package/tests/lightbox.html +6 -6
  164. package/tests/link.html +1 -1
  165. package/tests/list.html +4 -4
  166. package/tests/margin.html +7 -59
  167. package/tests/marker.html +3 -3
  168. package/tests/modal.html +3 -3
  169. package/tests/nav.html +5 -5
  170. package/tests/navbar.html +27 -27
  171. package/tests/notification.html +2 -8
  172. package/tests/offcanvas.html +12 -12
  173. package/tests/overlay.html +3 -3
  174. package/tests/padding.html +1 -1
  175. package/tests/pagination.html +3 -3
  176. package/tests/parallax.html +1 -1
  177. package/tests/position.html +6 -6
  178. package/tests/scrollspy.html +13 -13
  179. package/tests/search.html +5 -5
  180. package/tests/section.html +17 -17
  181. package/tests/slidenav.html +3 -3
  182. package/tests/slider.html +5 -5
  183. package/tests/slideshow.html +3 -33
  184. package/tests/sortable.html +15 -15
  185. package/tests/sticky-navbar.html +4 -4
  186. package/tests/sticky-parallax.html +3 -3
  187. package/tests/sticky.html +3 -3
  188. package/tests/svg.html +2 -3
  189. package/tests/switcher.html +7 -7
  190. package/tests/tab.html +5 -5
  191. package/tests/text.html +3 -9
  192. package/tests/tile.html +4 -4
  193. package/tests/toggle.html +1 -1
  194. package/tests/tooltip.html +3 -3
  195. package/tests/totop.html +2 -2
  196. package/tests/transition.html +1 -1
  197. package/tests/upload.html +5 -5
  198. package/tests/utility.html +116 -16
  199. package/tests/video.html +24 -224
  200. package/tests/visibility.html +4 -4
  201. package/tests/width.html +12 -12
  202. package/dist/js/components/marquee.js +0 -215
  203. package/dist/js/components/marquee.min.js +0 -1
  204. package/src/js/components/marquee.js +0 -156
  205. package/src/js/mixin/connect.js +0 -90
  206. package/src/js/mixin/scroll-driven.js +0 -57
  207. package/src/less/components/dropcap.less +0 -71
  208. package/src/less/components/floating-shadow.less +0 -66
  209. package/src/less/components/logo.less +0 -94
  210. package/src/less/components/marquee.less +0 -133
  211. package/src/less/theme/dropcap.less +0 -29
  212. package/src/less/theme/floating-shadow.less +0 -20
  213. package/src/less/theme/logo.less +0 -29
  214. package/src/less/theme/marquee.less +0 -14
  215. package/src/scss/components/dropcap.scss +0 -63
  216. package/src/scss/components/floating-shadow.scss +0 -63
  217. package/src/scss/components/logo.scss +0 -75
  218. package/src/scss/components/marquee.scss +0 -136
  219. package/tests/dropcap.html +0 -26
  220. package/tests/floating-shadow.html +0 -44
  221. package/tests/logo.html +0 -84
  222. package/tests/marquee.html +0 -617
@@ -1,10 +1,8 @@
1
1
  import {
2
2
  hasAttr,
3
- isFocusable,
4
3
  isTag,
5
4
  isTouch,
6
5
  mute,
7
- observeIntersection,
8
6
  parent,
9
7
  pause,
10
8
  play,
@@ -13,62 +11,27 @@ import {
13
11
  query,
14
12
  } from 'uikit-util';
15
13
  import { intersection } from '../api/observables';
16
- import Media from '../mixin/media';
17
- import ScrollDriven from '../mixin/scroll-driven';
18
-
19
- const loopKey = Symbol();
20
14
 
21
15
  export default {
22
- mixins: [Media, ScrollDriven],
23
-
24
16
  args: 'autoplay',
25
17
 
26
18
  props: {
27
19
  automute: Boolean,
28
20
  autoplay: Boolean,
29
21
  restart: Boolean,
30
- inviewMargin: String,
31
- inviewQueued: Number,
32
22
  hoverTarget: Boolean,
33
- hoverRewind: Number,
34
- reducedMotionTime: Number,
35
23
  },
36
24
 
37
25
  data: {
38
26
  automute: false,
39
27
  autoplay: true,
40
28
  restart: false,
41
- inviewMargin: '0px',
42
- inviewQueued: 0,
43
29
  hoverTarget: false,
44
- hoverRewind: 0,
45
- reducedMotionTime: 0,
46
- media: '(prefers-reduced-motion: reduce)',
47
30
  },
48
31
 
49
32
  beforeConnect() {
50
- const isVideo = (this.isVideo = isTag(this.$el, 'video'));
51
-
52
- this.interactionDriven = ['hover', 'parallax'].includes(this.autoplay);
53
-
54
- if (this.interactionDriven && !isVideo) {
55
- this.interactionDriven = this.autoplay = false;
56
- }
57
-
58
- this.restart = isVideo && this.restart;
59
- this.parallax = this.autoplay === 'parallax';
60
- this.inviewQueued = isVideo && this.autoplay === 'inview' && this.inviewQueued;
61
-
62
- if (this.inviewQueued) {
63
- this.$el[loopKey] = this.$el.loop;
64
- this.$el.loop = false;
65
- }
66
-
67
- if (
68
- ['hover', 'inview'].includes(this.autoplay) &&
69
- isVideo &&
70
- !hasAttr(this.$el, 'preload')
71
- ) {
33
+ const isVideo = isTag(this.$el, 'video');
34
+ if (this.autoplay === 'inview' && isVideo && !hasAttr(this.$el, 'preload')) {
72
35
  this.$el.preload = 'none';
73
36
  }
74
37
 
@@ -77,10 +40,10 @@ export default {
77
40
  }
78
41
 
79
42
  if (this.autoplay === 'hover') {
80
- this.hoverTarget = query(this.hoverTarget, this.$el) || this.$el;
81
-
82
- if (!isFocusable(this.hoverTarget)) {
83
- this.hoverTarget.tabIndex = 0;
43
+ if (isVideo) {
44
+ this.$el.tabIndex = 0;
45
+ } else {
46
+ this.autoplay = true;
84
47
  }
85
48
  }
86
49
 
@@ -90,44 +53,19 @@ export default {
90
53
  }
91
54
  },
92
55
 
93
- connected() {
94
- if (
95
- !this.$el.controls &&
96
- !this.$el.poster &&
97
- (this.interactionDriven || this.inviewQueued)
98
- ) {
99
- this.cancelPreview = preview(this.$el);
100
- }
101
- },
102
-
103
- disconnected() {
104
- this._reverseAbort?.abort();
105
-
106
- this.cancelPreview?.();
107
- this.cancelPreview = null;
108
-
109
- if (this.$el[loopKey]) {
110
- this.$el.loop = true;
111
- }
112
-
113
- queue.delete(this.$el);
114
- },
115
-
116
56
  events: [
117
57
  {
118
58
  name: `${pointerEnter} focusin`,
119
59
 
120
- el: ({ hoverTarget }) => hoverTarget,
60
+ el: ({ hoverTarget, $el }) => query(hoverTarget, $el) || $el,
121
61
 
122
62
  filter: ({ autoplay }) => autoplay === 'hover',
123
63
 
124
64
  handler(e) {
125
- this._reverseAbort?.abort();
126
-
127
65
  if (!isTouch(e) || !isPlaying(this.$el)) {
128
- this.play();
66
+ play(this.$el);
129
67
  } else {
130
- this.pause();
68
+ pauseHover(this.$el, this.restart);
131
69
  }
132
70
  },
133
71
  },
@@ -135,34 +73,14 @@ export default {
135
73
  {
136
74
  name: `${pointerLeave} focusout`,
137
75
 
138
- el: ({ hoverTarget }) => hoverTarget,
76
+ el: ({ hoverTarget, $el }) => query(hoverTarget, $el) || $el,
139
77
 
140
78
  filter: ({ autoplay }) => autoplay === 'hover',
141
79
 
142
80
  handler(e) {
143
- if (!isTouch(e) && !this.matchMedia) {
144
- this._reverseAbort?.abort();
145
- this.pause();
146
- this._reverseAbort = playReverse(this.$el, this.hoverRewind);
147
- }
148
- },
149
- },
150
- {
151
- name: 'loadedmetadata durationchange',
152
- filter: ({ parallax }) => parallax,
153
- handler() {
154
- this.$emit('resize');
155
- },
156
- },
157
- {
158
- name: 'error pause ended',
159
- filter: ({ inviewQueued }) => inviewQueued,
160
- handler(e) {
161
- if (e.type === 'error' || (e.type === 'ended' && !this.$el[loopKey])) {
162
- queue.delete(this.$el);
81
+ if (!isTouch(e)) {
82
+ pauseHover(this.$el, this.restart);
163
83
  }
164
-
165
- playNextQueued();
166
84
  },
167
85
  },
168
86
  ],
@@ -177,166 +95,33 @@ export default {
177
95
  }),
178
96
 
179
97
  intersection({
180
- filter: ({ $el, interactionDriven }) => !interactionDriven && $el.preload !== 'none',
181
- handler([{ isIntersecting }]) {
98
+ filter: ({ $el, autoplay }) => autoplay !== 'hover' && $el.preload !== 'none',
99
+ handler([{ isIntersecting, target }]) {
182
100
  if (!document.fullscreenElement) {
183
101
  if (isIntersecting) {
184
102
  if (this.autoplay) {
185
- this.play();
103
+ play(target);
186
104
  }
187
105
  } else {
188
- this.pause();
106
+ pauseHover(target, this.restart);
189
107
  }
190
108
  }
191
109
  },
192
110
  args: { intersecting: false },
193
- options: ({ $el, autoplay, inviewMargin }) => ({
111
+ options: ({ $el, autoplay }) => ({
194
112
  root: autoplay === 'inview' ? null : parent($el).closest(':not(a)'),
195
- rootMargin: autoplay === 'inview' ? inviewMargin : '0px',
196
113
  }),
197
114
  }),
198
115
  ],
199
-
200
- update: {
201
- write({ percent }) {
202
- if (!this.parallax) {
203
- return;
204
- }
205
-
206
- const { duration, seeking } = this.$el;
207
- if (!isNaN(duration) && !seeking) {
208
- const value = this.matchMedia ? this.reducedMotionTime : percent * duration;
209
- setCurrentTime(this.$el, value);
210
- }
211
- },
212
-
213
- events: ['scroll', 'resize'],
214
- },
215
-
216
- methods: {
217
- play() {
218
- if (this.matchMedia) {
219
- this.pause();
220
-
221
- if (this.isVideo) {
222
- setCurrentTime(this.$el, this.reducedMotionTime);
223
- }
224
- } else if (this.inviewQueued) {
225
- queue.set(this.$el, this.inviewQueued);
226
- playNextQueued();
227
- } else {
228
- this.cancelPreview?.();
229
- play(this.$el);
230
- }
231
- },
232
-
233
- pause() {
234
- pause(this.$el);
235
-
236
- queue.delete(this.$el);
237
-
238
- if (this.restart) {
239
- setCurrentTime(this.$el, 0);
240
- }
241
- },
242
- },
243
116
  };
244
117
 
245
- function setCurrentTime(videoEl, time) {
246
- if (videoEl.currentTime !== time) {
247
- videoEl.currentTime = time;
248
- }
249
- }
250
-
251
118
  function isPlaying(videoEl) {
252
119
  return !videoEl.paused && !videoEl.ended;
253
120
  }
254
121
 
255
- function preview($el) {
256
- if (!$el.requestVideoFrameCallback) {
257
- return;
122
+ function pauseHover(el, restart) {
123
+ pause(el);
124
+ if (restart && isTag(el, 'video')) {
125
+ el.currentTime = 0;
258
126
  }
259
-
260
- let frame;
261
- const pausePreview = () => {
262
- disconnect();
263
- pause($el);
264
- };
265
-
266
- const observer = observeIntersection($el, () => {
267
- observer.disconnect();
268
- frame = $el.requestVideoFrameCallback(pausePreview);
269
- play($el);
270
- });
271
-
272
- const disconnect = () => {
273
- observer.disconnect();
274
- $el.cancelVideoFrameCallback(frame);
275
- };
276
-
277
- return disconnect;
278
- }
279
-
280
- const queue = new Map();
281
- const played = new WeakMap();
282
-
283
- let frame;
284
- function playNextQueued() {
285
- cancelAnimationFrame(frame);
286
- frame = requestAnimationFrame(() => {
287
- const getPlayed = (el) => played.get(el) ?? 0;
288
- const videos = shuffle(queue.keys()).sort((a, b) => getPlayed(a) - getPlayed(b));
289
- let active = videos.filter(isPlaying).length;
290
-
291
- for (const el of videos) {
292
- const maxQueued = queue.get(el);
293
-
294
- if (isPlaying(el) || active / queue.size >= maxQueued) {
295
- continue;
296
- }
297
-
298
- played.set(el, getPlayed(el) + 1);
299
- play(el);
300
- active++;
301
- }
302
- });
303
- }
304
-
305
- function shuffle(array) {
306
- array = [...array];
307
- for (let i = array.length - 1; i > 0; i--) {
308
- let j = Math.floor(Math.random() * (i + 1));
309
- [array[i], array[j]] = [array[j], array[i]];
310
- }
311
- return array;
312
- }
313
-
314
- function playReverse(el, playbackRate) {
315
- const start = el.currentTime;
316
-
317
- if (isNaN(start) || !playbackRate) {
318
- return;
319
- }
320
-
321
- playbackRate *= Math.max(1, start / 10 + 0.5);
322
-
323
- const controller = new AbortController();
324
- const time = Date.now();
325
- (function next() {
326
- requestAnimationFrame(() => {
327
- if (controller.signal.aborted) {
328
- return;
329
- }
330
-
331
- if (!el.seeking) {
332
- el.currentTime = Math.max(0, start - ((Date.now() - time) * playbackRate) / 1000);
333
- }
334
-
335
- if (el.currentTime > 0) {
336
- next();
337
- }
338
- });
339
- })();
340
-
341
- return controller;
342
127
  }
@@ -2,12 +2,20 @@ import { css } from 'uikit-util';
2
2
 
3
3
  export default {
4
4
  slide: {
5
- percent: translated,
5
+ show(dir) {
6
+ return [{ transform: translate(dir * -100) }, { transform: translate() }];
7
+ },
6
8
 
7
- translate: (percent, dir) => [
8
- { transform: translate(dir * -100 * percent) },
9
- { transform: translate(dir * 100 * (1 - percent)) },
10
- ],
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
+ },
11
19
  },
12
20
  };
13
21
 
@@ -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 } = animation;
5
- const props = translate(1, dir);
4
+ const { percent, translate, show = noop } = animation;
5
+ const props = show(dir);
6
6
 
7
7
  const { promise, resolve } = withResolvers();
8
8
 
@@ -382,7 +382,10 @@ function getCssValue(el, prop, value) {
382
382
  }
383
383
 
384
384
  function fillObject(keys, value) {
385
- return Object.fromEntries(keys.map((prop) => [prop, value]));
385
+ return keys.reduce((data, prop) => {
386
+ data[prop] = value;
387
+ return data;
388
+ }, {});
386
389
  }
387
390
 
388
391
  /*
@@ -27,7 +27,7 @@ export default {
27
27
  },
28
28
 
29
29
  connected() {
30
- this.pos = [...this.$props.pos.split('-'), 'center'].slice(0, 2);
30
+ this.pos = this.$props.pos.split('-').concat('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
  },
@@ -1,30 +1,59 @@
1
- import { hasClass, includes, trigger } from 'uikit-util';
2
- import ScrollDriven from './scroll-driven';
1
+ import { hasClass, includes, query, scrolledOver, toPx, trigger } from 'uikit-util';
2
+ import { resize, scroll } from '../api/observables';
3
+ import { ease } from './parallax';
3
4
 
4
5
  export default {
5
- mixins: [ScrollDriven],
6
-
7
6
  props: {
8
7
  parallax: Boolean,
8
+ parallaxTarget: Boolean,
9
+ parallaxStart: String,
10
+ parallaxEnd: String,
11
+ parallaxEasing: Number,
9
12
  },
10
13
 
11
14
  data: {
12
15
  parallax: false,
16
+ parallaxTarget: false,
17
+ parallaxStart: 0,
18
+ parallaxEnd: 0,
19
+ parallaxEasing: 0,
13
20
  },
14
21
 
22
+ observe: [
23
+ resize({
24
+ target: ({ $el, parallaxTarget }) => [$el, parallaxTarget],
25
+ filter: ({ parallax }) => parallax,
26
+ }),
27
+ scroll({ filter: ({ parallax }) => parallax }),
28
+ ],
29
+
15
30
  computed: {
16
- parallaxTargetFallback() {
17
- return this.list;
31
+ parallaxTarget({ parallaxTarget }, $el) {
32
+ return (parallaxTarget && query(parallaxTarget, $el)) || this.list;
18
33
  },
19
34
  },
20
35
 
21
36
  update: {
22
- write({ percent }) {
37
+ read() {
23
38
  if (!this.parallax) {
24
- return;
39
+ return false;
40
+ }
41
+
42
+ const target = this.parallaxTarget;
43
+
44
+ if (!target) {
45
+ return false;
25
46
  }
26
47
 
27
- const [prevIndex, slidePercent] = this.getIndexAt(percent);
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;
28
57
 
29
58
  const nextIndex = this.getValidIndex(prevIndex + Math.ceil(slidePercent));
30
59
 
@@ -9,7 +9,6 @@ import {
9
9
  isBoolean,
10
10
  isFunction,
11
11
  isVisible,
12
- pick,
13
12
  removeClass,
14
13
  startsWith,
15
14
  toFloat,
@@ -164,18 +163,20 @@ async function toggleTransition(el, show, { animation, duration, velocity, trans
164
163
  _toggle(el, true);
165
164
  }
166
165
 
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
- ]);
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
+ );
179
180
 
180
181
  const dim = dimensions(el);
181
182
  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
- }
14
-
15
- for (const el of toNodes(element)) {
16
- if (value === null) {
17
- removeAttr(el, name);
18
- } else {
19
- el.setAttribute(name, value);
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
+ }
20
20
  }
21
21
  }
22
22
  }
@@ -68,9 +68,10 @@ export function wrapInner(element, structure) {
68
68
  }
69
69
 
70
70
  export function unwrap(element) {
71
- for (const elementParent of new Set(toNodes(element).map(parent))) {
72
- elementParent.replaceWith(...elementParent.childNodes);
73
- }
71
+ toNodes(element)
72
+ .map(parent)
73
+ .filter((value, index, self) => self.indexOf(value) === index)
74
+ .forEach((parent) => parent.replaceWith(...parent.childNodes));
74
75
  }
75
76
 
76
77
  const singleTagRe = /^<(\w+)\s*\/?>(?:<\/\1>)?$/;
@@ -178,8 +178,8 @@ export function uniqueBy(array, prop) {
178
178
 
179
179
  export function pick(obj, props) {
180
180
  const result = {};
181
- for (const key of props) {
182
- result[key] = obj[key];
181
+ for (const prop of props) {
182
+ result[prop] = obj[prop];
183
183
  }
184
184
  return result;
185
185
  }
@@ -42,9 +42,7 @@ function isIFrame(el) {
42
42
  }
43
43
 
44
44
  function isYoutube(el) {
45
- return /\/\/.*?youtube(-nocookie)?\.[a-z]+\/(watch\?v=[^&\s]+|embed)|youtu\.be\/.*/.test(
46
- el.src,
47
- );
45
+ return /\/\/.*?youtube(-nocookie)?\.[a-z]+\/(watch\?v=[^&\s]+|embed)|youtu\.be\//.test(el.src);
48
46
  }
49
47
 
50
48
  function isVimeo(el) {
@@ -60,7 +58,7 @@ function post(el, cmd) {
60
58
  el.contentWindow.postMessage(JSON.stringify({ event: 'command', ...cmd }), '*');
61
59
  }
62
60
 
63
- const stateKey = Symbol();
61
+ const stateKey = '_ukPlayer';
64
62
  let counter = 0;
65
63
  function enableApi(el) {
66
64
  if (el[stateKey]) {
@@ -37,22 +37,23 @@ export function css(element, property, value, priority) {
37
37
 
38
38
  if (isUndefined(value)) {
39
39
  return getComputedStyle(element).getPropertyValue(property);
40
+ } else {
41
+ element.style.setProperty(
42
+ property,
43
+ isNumeric(value) && !cssNumber[property] && !isCustomProperty(property)
44
+ ? `${value}px`
45
+ : value || isNumber(value)
46
+ ? value
47
+ : '',
48
+ priority,
49
+ );
40
50
  }
41
- element.style.setProperty(
42
- property,
43
- isNumeric(value) && !cssNumber[property] && !isCustomProperty(property)
44
- ? `${value}px`
45
- : value || isNumber(value)
46
- ? value
47
- : '',
48
- priority,
49
- );
50
51
  } else if (isArray(property)) {
51
- const values = {};
52
+ const props = {};
52
53
  for (const prop of property) {
53
- values[prop] = css(element, prop);
54
+ props[prop] = css(element, prop);
54
55
  }
55
- return values;
56
+ return props;
56
57
  } else if (isObject(property)) {
57
58
  for (const prop in property) {
58
59
  css(element, prop, property[prop], value);
@@ -18,18 +18,20 @@ export function isInView(element, offsetTop = 0, offsetLeft = 0) {
18
18
  return false;
19
19
  }
20
20
 
21
- const rects = overflowParents(element).map((parent) => {
22
- const { top, left, bottom, right } = offsetViewport(parent);
23
-
24
- return {
25
- top: top - offsetTop,
26
- left: left - offsetLeft,
27
- bottom: bottom + offsetTop,
28
- right: right + offsetLeft,
29
- };
30
- });
31
-
32
- return intersectRect(...rects, offset(element));
21
+ return intersectRect(
22
+ ...overflowParents(element)
23
+ .map((parent) => {
24
+ const { top, left, bottom, right } = offsetViewport(parent);
25
+
26
+ return {
27
+ top: top - offsetTop,
28
+ left: left - offsetLeft,
29
+ bottom: bottom + offsetTop,
30
+ right: right + offsetLeft,
31
+ };
32
+ })
33
+ .concat(offset(element)),
34
+ );
33
35
  }
34
36
 
35
37
  export function scrollIntoView(element, { offset: offsetBy = 0 } = {}) {
@@ -143,16 +145,17 @@ export function scrollParents(element, scrollable = false, props = []) {
143
145
  ancestors = ancestors.slice(fixedIndex);
144
146
  }
145
147
 
146
- return [
147
- scrollEl,
148
- ...ancestors.filter(
149
- (parent) =>
150
- css(parent, 'overflow')
151
- .split(' ')
152
- .some((prop) => includes(['auto', 'scroll', ...props], prop)) &&
153
- (!scrollable || parent.scrollHeight > offsetViewport(parent).height),
154
- ),
155
- ].reverse();
148
+ return [scrollEl]
149
+ .concat(
150
+ ancestors.filter(
151
+ (parent) =>
152
+ css(parent, 'overflow')
153
+ .split(' ')
154
+ .some((prop) => includes(['auto', 'scroll', ...props], prop)) &&
155
+ (!scrollable || parent.scrollHeight > offsetViewport(parent).height),
156
+ ),
157
+ )
158
+ .reverse();
156
159
  }
157
160
 
158
161
  export function scrollParent(...args) {