uikit 3.14.2-dev.f917389f5 → 3.14.3-dev.68d38eb6d
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.
- package/CHANGELOG.md +17 -1
- package/dist/css/uikit-core-rtl.css +48 -3
- package/dist/css/uikit-core-rtl.min.css +1 -1
- package/dist/css/uikit-core.css +48 -3
- package/dist/css/uikit-core.min.css +1 -1
- package/dist/css/uikit-rtl.css +52 -3
- package/dist/css/uikit-rtl.min.css +1 -1
- package/dist/css/uikit.css +52 -3
- package/dist/css/uikit.min.css +1 -1
- package/dist/js/components/countdown.js +1 -1
- package/dist/js/components/countdown.min.js +1 -1
- package/dist/js/components/filter.js +1 -1
- package/dist/js/components/filter.min.js +1 -1
- package/dist/js/components/lightbox-panel.js +101 -17
- package/dist/js/components/lightbox-panel.min.js +1 -1
- package/dist/js/components/lightbox.js +101 -17
- package/dist/js/components/lightbox.min.js +1 -1
- package/dist/js/components/notification.js +1 -1
- package/dist/js/components/notification.min.js +1 -1
- package/dist/js/components/parallax.js +70 -35
- package/dist/js/components/parallax.min.js +1 -1
- package/dist/js/components/slider-parallax.js +55 -35
- package/dist/js/components/slider-parallax.min.js +1 -1
- package/dist/js/components/slider.js +1 -1
- package/dist/js/components/slider.min.js +1 -1
- package/dist/js/components/slideshow-parallax.js +55 -35
- package/dist/js/components/slideshow-parallax.min.js +1 -1
- package/dist/js/components/slideshow.js +1 -1
- package/dist/js/components/slideshow.min.js +1 -1
- package/dist/js/components/sortable.js +1 -1
- package/dist/js/components/sortable.min.js +1 -1
- package/dist/js/components/tooltip.js +135 -39
- package/dist/js/components/tooltip.min.js +1 -1
- package/dist/js/components/upload.js +1 -1
- package/dist/js/components/upload.min.js +1 -1
- package/dist/js/uikit-core.js +229 -105
- package/dist/js/uikit-core.min.js +1 -1
- package/dist/js/uikit-icons.js +1 -1
- package/dist/js/uikit-icons.min.js +1 -1
- package/dist/js/uikit.js +298 -139
- package/dist/js/uikit.min.js +1 -1
- package/package.json +1 -1
- package/src/js/components/parallax.js +15 -0
- package/src/js/core/accordion.js +3 -3
- package/src/js/core/alert.js +1 -1
- package/src/js/core/drop.js +40 -20
- package/src/js/core/height-viewport.js +14 -9
- package/src/js/core/navbar.js +19 -18
- package/src/js/core/scrollspy.js +4 -0
- package/src/js/core/toggle.js +5 -8
- package/src/js/mixin/parallax.js +54 -34
- package/src/js/mixin/position.js +44 -23
- package/src/js/mixin/togglable.js +105 -19
- package/src/js/util/animation.js +1 -0
- package/src/js/util/dom.js +4 -3
- package/src/js/util/viewport.js +1 -1
- package/src/less/components/drop.less +17 -4
- package/src/less/components/dropdown.less +19 -4
- package/src/less/components/margin.less +13 -14
- package/src/less/components/nav.less +1 -1
- package/src/less/components/navbar.less +32 -11
- package/src/less/components/position.less +1 -1
- package/src/less/components/sticky.less +7 -0
- package/src/less/components/utility.less +1 -2
- package/src/less/theme/dropdown.less +11 -0
- package/src/less/theme/navbar.less +7 -0
- package/src/scss/components/drop.scss +17 -4
- package/src/scss/components/dropdown.scss +19 -4
- package/src/scss/components/margin.scss +13 -14
- package/src/scss/components/nav.scss +1 -1
- package/src/scss/components/navbar.scss +21 -0
- package/src/scss/components/position.scss +1 -1
- package/src/scss/components/sticky.scss +7 -0
- package/src/scss/components/utility.scss +1 -2
- package/src/scss/mixins-theme.scss +8 -0
- package/src/scss/mixins.scss +2 -0
- package/src/scss/theme/dropdown.scss +8 -0
- package/src/scss/theme/navbar.scss +4 -0
- package/src/scss/variables-theme.scss +3 -0
- package/src/scss/variables.scss +1 -0
- package/tests/drop.html +145 -2
- package/tests/dropdown.html +228 -13
- package/tests/height-viewport.html +62 -0
- package/tests/navbar.html +321 -14
- package/tests/sticky-navbar.html +132 -0
- package/tests/sticky-parallax.html +2 -1
- package/tests/sticky.html +5 -4
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.14.
|
|
5
|
+
"version": "3.14.3-dev.68d38eb6d",
|
|
6
6
|
"main": "dist/js/uikit.js",
|
|
7
7
|
"style": "dist/css/uikit.css",
|
|
8
8
|
"sideEffects": [
|
|
@@ -73,6 +73,21 @@ export default {
|
|
|
73
73
|
},
|
|
74
74
|
};
|
|
75
75
|
|
|
76
|
+
/*
|
|
77
|
+
* Inspired by https://gist.github.com/gre/1650294?permalink_comment_id=3477425#gistcomment-3477425
|
|
78
|
+
*
|
|
79
|
+
* linear: 0
|
|
80
|
+
* easeInSine: 0.5
|
|
81
|
+
* easeOutSine: -0.5
|
|
82
|
+
* easeInQuad: 1
|
|
83
|
+
* easeOutQuad: -1
|
|
84
|
+
* easeInCubic: 2
|
|
85
|
+
* easeOutCubic: -2
|
|
86
|
+
* easeInQuart: 3
|
|
87
|
+
* easeOutQuart: -3
|
|
88
|
+
* easeInQuint: 4
|
|
89
|
+
* easeOutQuint: -4
|
|
90
|
+
*/
|
|
76
91
|
function ease(percent, easing) {
|
|
77
92
|
return easing >= 0 ? Math.pow(percent, easing + 1) : 1 - Math.pow(1 - percent, 1 - easing);
|
|
78
93
|
}
|
package/src/js/core/accordion.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import Class from '../mixin/class';
|
|
2
2
|
import Lazyload from '../mixin/lazyload';
|
|
3
|
-
import { default as Togglable
|
|
3
|
+
import { slide, default as Togglable } from '../mixin/togglable';
|
|
4
4
|
import {
|
|
5
5
|
$,
|
|
6
6
|
$$,
|
|
@@ -34,7 +34,7 @@ export default {
|
|
|
34
34
|
data: {
|
|
35
35
|
targets: '> *',
|
|
36
36
|
active: false,
|
|
37
|
-
animation: [
|
|
37
|
+
animation: ['slide'],
|
|
38
38
|
collapsible: true,
|
|
39
39
|
multiple: false,
|
|
40
40
|
clsOpen: 'uk-open',
|
|
@@ -144,7 +144,7 @@ export default {
|
|
|
144
144
|
}
|
|
145
145
|
|
|
146
146
|
hide(content, false);
|
|
147
|
-
await
|
|
147
|
+
await slide(this)(el._wrapper, show);
|
|
148
148
|
hide(content, !show);
|
|
149
149
|
|
|
150
150
|
delete el._wrapper;
|
package/src/js/core/alert.js
CHANGED
package/src/js/core/drop.js
CHANGED
|
@@ -8,7 +8,6 @@ import {
|
|
|
8
8
|
apply,
|
|
9
9
|
attr,
|
|
10
10
|
css,
|
|
11
|
-
getCssVar,
|
|
12
11
|
hasClass,
|
|
13
12
|
includes,
|
|
14
13
|
isTouch,
|
|
@@ -16,6 +15,7 @@ import {
|
|
|
16
15
|
MouseTracker,
|
|
17
16
|
observeResize,
|
|
18
17
|
offset,
|
|
18
|
+
offsetViewport,
|
|
19
19
|
on,
|
|
20
20
|
once,
|
|
21
21
|
parent,
|
|
@@ -28,7 +28,6 @@ import {
|
|
|
28
28
|
removeClass,
|
|
29
29
|
scrollParents,
|
|
30
30
|
toggleClass,
|
|
31
|
-
toPx,
|
|
32
31
|
within,
|
|
33
32
|
} from 'uikit-util';
|
|
34
33
|
|
|
@@ -48,6 +47,7 @@ export default {
|
|
|
48
47
|
delayHide: Number,
|
|
49
48
|
display: String,
|
|
50
49
|
clsDrop: String,
|
|
50
|
+
animateOut: Boolean,
|
|
51
51
|
},
|
|
52
52
|
|
|
53
53
|
data: {
|
|
@@ -62,6 +62,7 @@ export default {
|
|
|
62
62
|
animation: ['uk-animation-fade'],
|
|
63
63
|
cls: 'uk-open',
|
|
64
64
|
container: false,
|
|
65
|
+
animateOut: false,
|
|
65
66
|
},
|
|
66
67
|
|
|
67
68
|
created() {
|
|
@@ -249,7 +250,7 @@ export default {
|
|
|
249
250
|
}
|
|
250
251
|
}),
|
|
251
252
|
|
|
252
|
-
...(this.display === 'static'
|
|
253
|
+
...(this.display === 'static' && this.align !== 'stretch'
|
|
253
254
|
? []
|
|
254
255
|
: (() => {
|
|
255
256
|
const handler = () => this.$emit();
|
|
@@ -310,7 +311,7 @@ export default {
|
|
|
310
311
|
methods: {
|
|
311
312
|
show(target = this.target, delay = true) {
|
|
312
313
|
if (this.isToggled() && target && this.target && target !== this.target) {
|
|
313
|
-
this.hide(false);
|
|
314
|
+
this.hide(false, false);
|
|
314
315
|
}
|
|
315
316
|
|
|
316
317
|
this.target = target;
|
|
@@ -330,7 +331,7 @@ export default {
|
|
|
330
331
|
let prev;
|
|
331
332
|
while (active && prev !== active && !within(this.$el, active.$el)) {
|
|
332
333
|
prev = active;
|
|
333
|
-
active.hide(false);
|
|
334
|
+
active.hide(false, false);
|
|
334
335
|
}
|
|
335
336
|
}
|
|
336
337
|
|
|
@@ -344,8 +345,8 @@ export default {
|
|
|
344
345
|
);
|
|
345
346
|
},
|
|
346
347
|
|
|
347
|
-
hide(delay = true) {
|
|
348
|
-
const hide = () => this.toggleElement(this.$el, false,
|
|
348
|
+
hide(delay = true, animate = true) {
|
|
349
|
+
const hide = () => this.toggleElement(this.$el, false, this.animateOut && animate);
|
|
349
350
|
|
|
350
351
|
this.clearTimers();
|
|
351
352
|
|
|
@@ -377,40 +378,59 @@ export default {
|
|
|
377
378
|
position() {
|
|
378
379
|
removeClass(this.$el, `${this.clsDrop}-stack`);
|
|
379
380
|
toggleClass(this.$el, `${this.clsDrop}-boundary`, this.boundaryAlign);
|
|
381
|
+
toggleClass(this.$el, `${this.clsDrop}-stretch`, this.align === 'stretch');
|
|
380
382
|
|
|
381
383
|
const boundary = query(this.boundary, this.$el);
|
|
382
|
-
const
|
|
383
|
-
|
|
384
|
+
const target = boundary && this.boundaryAlign ? boundary : this.target;
|
|
385
|
+
const [scrollParent] = scrollParents(
|
|
386
|
+
boundary && this.boundaryAlign ? boundary : this.$el
|
|
384
387
|
);
|
|
388
|
+
const scrollParentOffset = offset(scrollParent);
|
|
385
389
|
const boundaryOffset = boundary ? offset(boundary) : scrollParentOffset;
|
|
390
|
+
const viewportOffset = this.getViewportOffset(this.$el);
|
|
386
391
|
|
|
387
392
|
css(this.$el, 'maxWidth', '');
|
|
388
|
-
const maxWidth =
|
|
389
|
-
scrollParentOffset.width -
|
|
390
|
-
2 * toPx(getCssVar('position-viewport-offset', this.$el));
|
|
393
|
+
const maxWidth = scrollParentOffset.width - 2 * viewportOffset;
|
|
391
394
|
|
|
392
|
-
if (this.
|
|
395
|
+
if (this.align === 'justify') {
|
|
393
396
|
const prop = this.axis === 'y' ? 'width' : 'height';
|
|
394
397
|
css(
|
|
395
398
|
this.$el,
|
|
396
399
|
prop,
|
|
397
400
|
Math.min(
|
|
398
401
|
(boundary ? boundaryOffset : offset(this.target))[prop],
|
|
399
|
-
scrollParentOffset[prop] -
|
|
400
|
-
2 * toPx(getCssVar('position-viewport-offset', this.$el))
|
|
402
|
+
scrollParentOffset[prop] - 2 * viewportOffset
|
|
401
403
|
)
|
|
402
404
|
);
|
|
405
|
+
} else if (this.align === 'stretch') {
|
|
406
|
+
this.flip = this.axis === 'y' ? 'x' : 'y';
|
|
407
|
+
this.display = 'static';
|
|
408
|
+
|
|
409
|
+
const viewport = offsetViewport(scrollParent);
|
|
410
|
+
const targetDim = offset(target);
|
|
411
|
+
const elOffset = Math.abs(this.getPositionOffset(this.$el)) + viewportOffset;
|
|
412
|
+
|
|
413
|
+
css(this.$el, {
|
|
414
|
+
width:
|
|
415
|
+
this.axis === 'y'
|
|
416
|
+
? viewport.width
|
|
417
|
+
: (this.dir === 'left'
|
|
418
|
+
? targetDim.left - viewport.left
|
|
419
|
+
: viewport.right - targetDim.right) - elOffset,
|
|
420
|
+
height:
|
|
421
|
+
this.axis === 'x'
|
|
422
|
+
? viewport.height
|
|
423
|
+
: (this.dir === 'top'
|
|
424
|
+
? targetDim.top - viewport.top
|
|
425
|
+
: viewport.bottom - targetDim.bottom) - elOffset,
|
|
426
|
+
});
|
|
403
427
|
} else if (this.$el.offsetWidth > maxWidth) {
|
|
404
428
|
addClass(this.$el, `${this.clsDrop}-stack`);
|
|
405
429
|
}
|
|
406
430
|
|
|
407
431
|
css(this.$el, 'maxWidth', maxWidth);
|
|
408
432
|
|
|
409
|
-
this.positionAt(
|
|
410
|
-
this.$el,
|
|
411
|
-
boundary && this.boundaryAlign ? boundary : this.target,
|
|
412
|
-
boundary
|
|
413
|
-
);
|
|
433
|
+
this.positionAt(this.$el, target, boundary);
|
|
414
434
|
},
|
|
415
435
|
},
|
|
416
436
|
};
|
|
@@ -4,12 +4,13 @@ import {
|
|
|
4
4
|
css,
|
|
5
5
|
dimensions,
|
|
6
6
|
endsWith,
|
|
7
|
-
height,
|
|
8
7
|
isNumeric,
|
|
9
8
|
isString,
|
|
10
9
|
isVisible,
|
|
11
|
-
|
|
10
|
+
offsetPosition,
|
|
11
|
+
offsetViewport,
|
|
12
12
|
query,
|
|
13
|
+
scrollParents,
|
|
13
14
|
toFloat,
|
|
14
15
|
} from 'uikit-util';
|
|
15
16
|
|
|
@@ -32,7 +33,7 @@ export default {
|
|
|
32
33
|
|
|
33
34
|
resizeTargets() {
|
|
34
35
|
// check for offsetTop change
|
|
35
|
-
return [this.$el,
|
|
36
|
+
return [this.$el, ...scrollParents(this.$el, /auto|scroll/)];
|
|
36
37
|
},
|
|
37
38
|
|
|
38
39
|
update: {
|
|
@@ -44,21 +45,25 @@ export default {
|
|
|
44
45
|
let minHeight = '';
|
|
45
46
|
const box = boxModelAdjust(this.$el, 'height', 'content-box');
|
|
46
47
|
|
|
48
|
+
const [scrollElement] = scrollParents(this.$el, /auto|scroll/);
|
|
49
|
+
const { height: viewportHeight } = offsetViewport(scrollElement);
|
|
50
|
+
|
|
47
51
|
if (this.expand) {
|
|
48
52
|
minHeight = Math.max(
|
|
49
|
-
|
|
50
|
-
(dimensions(
|
|
51
|
-
dimensions(this.$el).height) -
|
|
53
|
+
viewportHeight -
|
|
54
|
+
(dimensions(scrollElement).height - dimensions(this.$el).height) -
|
|
52
55
|
box,
|
|
53
56
|
0
|
|
54
57
|
);
|
|
55
58
|
} else {
|
|
56
59
|
// on mobile devices (iOS and Android) window.innerHeight !== 100vh
|
|
57
|
-
minHeight =
|
|
60
|
+
minHeight = `calc(${
|
|
61
|
+
document.scrollingElement === scrollElement ? '100vh' : `${viewportHeight}px`
|
|
62
|
+
}`;
|
|
58
63
|
|
|
59
64
|
if (this.offsetTop) {
|
|
60
|
-
const
|
|
61
|
-
minHeight += top > 0 && top <
|
|
65
|
+
const top = offsetPosition(this.$el)[0] - offsetPosition(scrollElement)[0];
|
|
66
|
+
minHeight += top > 0 && top < viewportHeight / 2 ? ` - ${top}px` : '';
|
|
62
67
|
}
|
|
63
68
|
|
|
64
69
|
if (this.offsetBottom === true) {
|
package/src/js/core/navbar.js
CHANGED
|
@@ -13,9 +13,9 @@ import {
|
|
|
13
13
|
height,
|
|
14
14
|
includes,
|
|
15
15
|
isRtl,
|
|
16
|
-
isVisible,
|
|
17
16
|
matches,
|
|
18
17
|
noop,
|
|
18
|
+
observeResize,
|
|
19
19
|
offset,
|
|
20
20
|
once,
|
|
21
21
|
parent,
|
|
@@ -285,8 +285,8 @@ export default {
|
|
|
285
285
|
return this.dropbar;
|
|
286
286
|
},
|
|
287
287
|
|
|
288
|
-
handler(_, { $el }) {
|
|
289
|
-
if (!hasClass($el, this.clsDrop)) {
|
|
288
|
+
handler(_, { $el, align }) {
|
|
289
|
+
if (!hasClass($el, this.clsDrop) || align === 'stretch') {
|
|
290
290
|
return;
|
|
291
291
|
}
|
|
292
292
|
|
|
@@ -309,19 +309,19 @@ export default {
|
|
|
309
309
|
return this.dropbar;
|
|
310
310
|
},
|
|
311
311
|
|
|
312
|
-
handler(_, { $el,
|
|
313
|
-
if (!hasClass($el, this.clsDrop)) {
|
|
312
|
+
handler(_, { $el, align }) {
|
|
313
|
+
if (!hasClass($el, this.clsDrop) || align === 'stretch') {
|
|
314
314
|
return;
|
|
315
315
|
}
|
|
316
316
|
|
|
317
|
-
|
|
317
|
+
this._observer = observeResize($el, () =>
|
|
318
318
|
this.transitionTo(
|
|
319
319
|
offset($el).bottom -
|
|
320
320
|
offset(this.dropbar).top +
|
|
321
321
|
toFloat(css($el, 'marginBottom')),
|
|
322
322
|
$el
|
|
323
|
-
)
|
|
324
|
-
|
|
323
|
+
)
|
|
324
|
+
);
|
|
325
325
|
},
|
|
326
326
|
},
|
|
327
327
|
|
|
@@ -360,11 +360,13 @@ export default {
|
|
|
360
360
|
return this.dropbar;
|
|
361
361
|
},
|
|
362
362
|
|
|
363
|
-
handler(_, { $el }) {
|
|
364
|
-
if (!hasClass($el, this.clsDrop)) {
|
|
363
|
+
handler(_, { $el, align }) {
|
|
364
|
+
if (!hasClass($el, this.clsDrop) || align === 'stretch') {
|
|
365
365
|
return;
|
|
366
366
|
}
|
|
367
367
|
|
|
368
|
+
this._observer.disconnect();
|
|
369
|
+
|
|
368
370
|
const active = this.getActive();
|
|
369
371
|
|
|
370
372
|
if (!active || active?.$el === $el) {
|
|
@@ -381,28 +383,27 @@ export default {
|
|
|
381
383
|
|
|
382
384
|
transitionTo(newHeight, el) {
|
|
383
385
|
const { dropbar } = this;
|
|
384
|
-
const oldHeight =
|
|
386
|
+
const oldHeight = height(dropbar);
|
|
385
387
|
|
|
386
388
|
el = oldHeight < newHeight && el;
|
|
387
389
|
|
|
388
|
-
css(el, '
|
|
390
|
+
css(el, 'clipPath', `polygon(0 0,100% 0,100% ${oldHeight}px,0 ${oldHeight}px)`);
|
|
389
391
|
|
|
390
392
|
height(dropbar, oldHeight);
|
|
391
393
|
|
|
392
394
|
Transition.cancel([el, dropbar]);
|
|
393
|
-
|
|
395
|
+
Promise.all([
|
|
394
396
|
Transition.start(dropbar, { height: newHeight }, this.duration),
|
|
395
397
|
Transition.start(
|
|
396
398
|
el,
|
|
397
|
-
{
|
|
399
|
+
{
|
|
400
|
+
clipPath: `polygon(0 0,100% 0,100% ${newHeight}px,0 ${newHeight}px)`,
|
|
401
|
+
},
|
|
398
402
|
this.duration
|
|
399
403
|
),
|
|
400
404
|
])
|
|
401
405
|
.catch(noop)
|
|
402
|
-
.then(() => {
|
|
403
|
-
css(el, { clip: '' });
|
|
404
|
-
this.$update(dropbar);
|
|
405
|
-
});
|
|
406
|
+
.then(() => css(el, { clipPath: '' }));
|
|
406
407
|
},
|
|
407
408
|
|
|
408
409
|
getDropdown(el) {
|
package/src/js/core/scrollspy.js
CHANGED
package/src/js/core/toggle.js
CHANGED
|
@@ -77,6 +77,8 @@ export default {
|
|
|
77
77
|
},
|
|
78
78
|
|
|
79
79
|
handler(e) {
|
|
80
|
+
this._preventClick = null;
|
|
81
|
+
|
|
80
82
|
if (!isTouch(e) || this._showState) {
|
|
81
83
|
return;
|
|
82
84
|
}
|
|
@@ -163,6 +165,7 @@ export default {
|
|
|
163
165
|
handler(e) {
|
|
164
166
|
let link;
|
|
165
167
|
if (
|
|
168
|
+
this._preventClick ||
|
|
166
169
|
closest(e.target, 'a[href="#"], a[href=""]') ||
|
|
167
170
|
((link = closest(e.target, 'a[href]')) &&
|
|
168
171
|
(attr(this.$el, 'aria-expanded') !== 'true' ||
|
|
@@ -171,15 +174,9 @@ export default {
|
|
|
171
174
|
e.preventDefault();
|
|
172
175
|
}
|
|
173
176
|
|
|
174
|
-
if (this._preventClick) {
|
|
175
|
-
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
if (!includes(this.mode, 'click')) {
|
|
179
|
-
return;
|
|
177
|
+
if (!this._preventClick && includes(this.mode, 'click')) {
|
|
178
|
+
this.toggle();
|
|
180
179
|
}
|
|
181
|
-
|
|
182
|
-
this.toggle();
|
|
183
180
|
},
|
|
184
181
|
},
|
|
185
182
|
|
package/src/js/mixin/parallax.js
CHANGED
|
@@ -47,12 +47,17 @@ export default {
|
|
|
47
47
|
|
|
48
48
|
computed: {
|
|
49
49
|
props(properties, $el) {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
const stops = {};
|
|
51
|
+
for (const prop in properties) {
|
|
52
|
+
if (prop in props && !isUndefined(properties[prop])) {
|
|
53
|
+
stops[prop] = properties[prop].slice();
|
|
53
54
|
}
|
|
54
|
-
|
|
55
|
-
|
|
55
|
+
}
|
|
56
|
+
const result = {};
|
|
57
|
+
for (const prop in stops) {
|
|
58
|
+
result[prop] = props[prop](prop, $el, stops[prop], stops);
|
|
59
|
+
}
|
|
60
|
+
return result;
|
|
56
61
|
},
|
|
57
62
|
},
|
|
58
63
|
|
|
@@ -181,58 +186,66 @@ function strokeFn(prop, el, stops) {
|
|
|
181
186
|
};
|
|
182
187
|
}
|
|
183
188
|
|
|
184
|
-
function backgroundFn(prop, el, stops) {
|
|
189
|
+
function backgroundFn(prop, el, stops, props) {
|
|
185
190
|
if (stops.length === 1) {
|
|
186
191
|
stops.unshift(0);
|
|
187
192
|
}
|
|
188
193
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
194
|
+
const attr = prop === 'bgy' ? 'height' : 'width';
|
|
195
|
+
props[prop] = parseStops(stops, (stop) => toPx(stop, attr, el));
|
|
196
|
+
|
|
197
|
+
const bgProps = ['bgx', 'bgy'].filter((prop) => prop in props);
|
|
198
|
+
if (bgProps.length === 2 && prop === 'bgx') {
|
|
199
|
+
return noop;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
if (getCssValue(el, 'backgroundSize', '') === 'cover') {
|
|
203
|
+
return backgroundCoverFn(prop, el, stops, props);
|
|
204
|
+
}
|
|
192
205
|
|
|
193
|
-
const
|
|
206
|
+
const positions = {};
|
|
207
|
+
for (const prop of bgProps) {
|
|
208
|
+
positions[prop] = getBackgroundPos(el, prop);
|
|
209
|
+
}
|
|
194
210
|
|
|
195
|
-
return
|
|
196
|
-
? backgroundCoverFn(prop, el, stops, bgPos, attr)
|
|
197
|
-
: setBackgroundPosFn(prop, stops, bgPos);
|
|
211
|
+
return setBackgroundPosFn(bgProps, positions, props);
|
|
198
212
|
}
|
|
199
213
|
|
|
200
|
-
function backgroundCoverFn(prop, el, stops,
|
|
214
|
+
function backgroundCoverFn(prop, el, stops, props) {
|
|
201
215
|
const dimImage = getBackgroundImageDimensions(el);
|
|
202
216
|
|
|
203
217
|
if (!dimImage.width) {
|
|
204
218
|
return noop;
|
|
205
219
|
}
|
|
206
220
|
|
|
207
|
-
const values = stops.map(([value]) => value);
|
|
208
|
-
const min = Math.min(...values);
|
|
209
|
-
const max = Math.max(...values);
|
|
210
|
-
const down = values.indexOf(min) < values.indexOf(max);
|
|
211
|
-
|
|
212
|
-
const diff = max - min;
|
|
213
|
-
let pos = (down ? -diff : 0) - (down ? min : max);
|
|
214
|
-
|
|
215
221
|
const dimEl = {
|
|
216
222
|
width: el.offsetWidth,
|
|
217
223
|
height: el.offsetHeight,
|
|
218
224
|
};
|
|
219
225
|
|
|
220
|
-
const
|
|
221
|
-
const span = baseDim[attr] - dimEl[attr];
|
|
226
|
+
const bgProps = ['bgx', 'bgy'].filter((prop) => prop in props);
|
|
222
227
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
const
|
|
228
|
+
const positions = {};
|
|
229
|
+
for (const prop of bgProps) {
|
|
230
|
+
const values = props[prop].map(([value]) => value);
|
|
231
|
+
const min = Math.min(...values);
|
|
232
|
+
const max = Math.max(...values);
|
|
233
|
+
const down = values.indexOf(min) < values.indexOf(max);
|
|
234
|
+
const diff = max - min;
|
|
227
235
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
}
|
|
236
|
+
positions[prop] = `${(down ? -diff : 0) - (down ? min : max)}px`;
|
|
237
|
+
dimEl[prop === 'bgy' ? 'height' : 'width'] += diff;
|
|
231
238
|
}
|
|
232
239
|
|
|
233
240
|
const dim = Dimensions.cover(dimImage, dimEl);
|
|
234
241
|
|
|
235
|
-
const
|
|
242
|
+
for (const prop of bgProps) {
|
|
243
|
+
const attr = prop === 'bgy' ? 'height' : 'width';
|
|
244
|
+
const overflow = dim[attr] - dimEl[attr];
|
|
245
|
+
positions[prop] = `max(${getBackgroundPos(el, prop)},-${overflow}px) + ${positions[prop]}`;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const fn = setBackgroundPosFn(bgProps, positions, props);
|
|
236
249
|
return (css, percent) => {
|
|
237
250
|
fn(css, percent);
|
|
238
251
|
css.backgroundSize = `${dim.width}px ${dim.height}px`;
|
|
@@ -240,9 +253,16 @@ function backgroundCoverFn(prop, el, stops, bgPos, attr) {
|
|
|
240
253
|
};
|
|
241
254
|
}
|
|
242
255
|
|
|
243
|
-
function
|
|
256
|
+
function getBackgroundPos(el, prop) {
|
|
257
|
+
return getCssValue(el, `background-position-${prop.substr(-1)}`, '');
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
function setBackgroundPosFn(bgProps, positions, props) {
|
|
244
261
|
return function (css, percent) {
|
|
245
|
-
|
|
262
|
+
for (const prop of bgProps) {
|
|
263
|
+
const value = getValue(props[prop], percent);
|
|
264
|
+
css[`background-position-${prop.substr(-1)}`] = `calc(${positions[prop]} + ${value}px)`;
|
|
265
|
+
}
|
|
246
266
|
};
|
|
247
267
|
}
|
|
248
268
|
|
package/src/js/mixin/position.js
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
css,
|
|
3
|
+
dimensions,
|
|
4
|
+
flipPosition,
|
|
5
|
+
getCssVar,
|
|
6
|
+
includes,
|
|
7
|
+
isRtl,
|
|
8
|
+
positionAt,
|
|
9
|
+
toPx,
|
|
10
|
+
} from 'uikit-util';
|
|
2
11
|
|
|
3
12
|
export default {
|
|
4
13
|
props: {
|
|
@@ -15,33 +24,17 @@ export default {
|
|
|
15
24
|
|
|
16
25
|
connected() {
|
|
17
26
|
this.pos = this.$props.pos.split('-').concat('center').slice(0, 2);
|
|
18
|
-
this.
|
|
27
|
+
[this.dir, this.align] = this.pos;
|
|
28
|
+
this.axis = includes(['top', 'bottom'], this.dir) ? 'y' : 'x';
|
|
19
29
|
},
|
|
20
30
|
|
|
21
31
|
methods: {
|
|
22
32
|
positionAt(element, target, boundary) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const mainAxisOffset =
|
|
26
|
-
toPx(
|
|
27
|
-
this.offset === false ? getCssVar('position-offset', element) : this.offset,
|
|
28
|
-
this.axis === 'x' ? 'width' : 'height',
|
|
29
|
-
element
|
|
30
|
-
) * (includes(['left', 'top'], dir) ? -1 : 1);
|
|
31
|
-
|
|
32
|
-
const crossAxisOffset = includes(['center', 'justify'], align)
|
|
33
|
-
? 0
|
|
34
|
-
: toPx(
|
|
35
|
-
getCssVar('position-shift-offset', element),
|
|
36
|
-
this.axis === 'y' ? 'width' : 'height',
|
|
37
|
-
element
|
|
38
|
-
) * (includes(['left', 'top'], align) ? 1 : -1);
|
|
39
|
-
|
|
40
|
-
let offset = [mainAxisOffset, crossAxisOffset];
|
|
33
|
+
let offset = [this.getPositionOffset(element), this.getShiftOffset(element)];
|
|
41
34
|
|
|
42
35
|
const attach = {
|
|
43
|
-
element: [flipPosition(dir), align],
|
|
44
|
-
target: [dir, align],
|
|
36
|
+
element: [flipPosition(this.dir), this.align],
|
|
37
|
+
target: [this.dir, this.align],
|
|
45
38
|
};
|
|
46
39
|
|
|
47
40
|
if (this.axis === 'y') {
|
|
@@ -51,13 +44,41 @@ export default {
|
|
|
51
44
|
offset = offset.reverse();
|
|
52
45
|
}
|
|
53
46
|
|
|
47
|
+
// Ensure none positioned element does not generate scrollbars
|
|
48
|
+
const elDim = dimensions(element);
|
|
49
|
+
css(element, { top: -elDim.height, left: -elDim.width });
|
|
50
|
+
|
|
54
51
|
positionAt(element, target, {
|
|
55
52
|
attach,
|
|
56
53
|
offset,
|
|
57
54
|
boundary,
|
|
58
55
|
flip: this.flip,
|
|
59
|
-
viewportOffset:
|
|
56
|
+
viewportOffset: this.getViewportOffset(element),
|
|
60
57
|
});
|
|
61
58
|
},
|
|
59
|
+
|
|
60
|
+
getPositionOffset(element) {
|
|
61
|
+
return (
|
|
62
|
+
toPx(
|
|
63
|
+
this.offset === false ? getCssVar('position-offset', element) : this.offset,
|
|
64
|
+
this.axis === 'x' ? 'width' : 'height',
|
|
65
|
+
element
|
|
66
|
+
) * (includes(['left', 'top'], this.dir) ? -1 : 1)
|
|
67
|
+
);
|
|
68
|
+
},
|
|
69
|
+
|
|
70
|
+
getShiftOffset(element) {
|
|
71
|
+
return includes(['center', 'justify', 'stretch'], this.align)
|
|
72
|
+
? 0
|
|
73
|
+
: toPx(
|
|
74
|
+
getCssVar('position-shift-offset', element),
|
|
75
|
+
this.axis === 'y' ? 'width' : 'height',
|
|
76
|
+
element
|
|
77
|
+
) * (includes(['left', 'top'], this.align) ? 1 : -1);
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
getViewportOffset(element) {
|
|
81
|
+
return toPx(getCssVar('position-viewport-offset', element));
|
|
82
|
+
},
|
|
62
83
|
},
|
|
63
84
|
};
|