uikit 3.14.4-dev.4bd89c5ca → 3.14.4-dev.6002e7046
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 +39 -18
- package/build/util.js +1 -0
- package/dist/css/uikit-core-rtl.css +349 -160
- package/dist/css/uikit-core-rtl.min.css +1 -1
- package/dist/css/uikit-core.css +349 -160
- package/dist/css/uikit-core.min.css +1 -1
- package/dist/css/uikit-rtl.css +372 -190
- package/dist/css/uikit-rtl.min.css +1 -1
- package/dist/css/uikit.css +372 -190
- 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 +96 -131
- package/dist/js/components/lightbox-panel.min.js +1 -1
- package/dist/js/components/lightbox.js +96 -131
- package/dist/js/components/lightbox.min.js +1 -1
- package/dist/js/components/notification.js +4 -2
- package/dist/js/components/notification.min.js +1 -1
- package/dist/js/components/parallax.js +4 -5
- package/dist/js/components/parallax.min.js +1 -1
- package/dist/js/components/slider-parallax.js +4 -5
- 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 +4 -5
- 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 +102 -139
- 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 +527 -486
- package/dist/js/uikit-core.min.js +17 -1
- package/dist/js/uikit-icons.js +1 -1
- package/dist/js/uikit-icons.min.js +1 -1
- package/dist/js/uikit.js +530 -487
- package/dist/js/uikit.min.js +17 -1
- package/package.json +11 -11
- package/src/images/{backgrounds/nav-parent-close.svg → components/nav-parent-icon-large.svg} +0 -0
- package/src/images/{backgrounds/navbar-parent-close.svg → components/nav-parent-icon.svg} +0 -0
- package/src/images/{backgrounds/navbar-parent-open.svg → components/navbar-parent-icon.svg} +1 -1
- package/src/images/components/navbar-toggle-icon.svg +25 -3
- package/src/js/api/hooks.js +5 -1
- package/src/js/api/state.js +2 -2
- package/src/js/components/notification.js +3 -1
- package/src/js/core/accordion.js +9 -17
- package/src/js/core/alert.js +35 -14
- package/src/js/core/drop.js +110 -82
- package/src/js/core/height-viewport.js +4 -2
- package/src/js/core/icon.js +16 -0
- package/src/js/core/index.js +2 -0
- package/src/js/core/leader.js +2 -2
- package/src/js/core/navbar.js +30 -45
- package/src/js/core/offcanvas.js +8 -4
- package/src/js/core/scroll.js +37 -10
- package/src/js/core/toggle.js +3 -5
- package/src/js/mixin/media.js +4 -5
- package/src/js/mixin/modal.js +15 -12
- package/src/js/mixin/position.js +24 -26
- package/src/js/mixin/style.js +11 -0
- package/src/js/mixin/togglable.js +88 -124
- package/src/js/util/animation.js +9 -7
- package/src/js/util/class.js +3 -1
- package/src/js/util/filter.js +3 -7
- package/src/js/util/position.js +115 -114
- package/src/js/util/style.js +4 -13
- package/src/js/util/viewport.js +3 -5
- package/src/less/components/_import.less +1 -0
- package/src/less/components/drop.less +1 -18
- package/src/less/components/dropbar.less +126 -0
- package/src/less/components/dropdown.less +11 -19
- package/src/less/components/leader.less +1 -1
- package/src/less/components/nav.less +219 -58
- package/src/less/components/navbar.less +49 -81
- package/src/less/components/utility.less +10 -2
- package/src/less/theme/_import.less +1 -0
- package/src/less/theme/dropbar.less +44 -0
- package/src/less/theme/dropdown.less +0 -11
- package/src/less/theme/nav.less +45 -7
- package/src/less/theme/navbar.less +5 -44
- package/src/scss/components/_import.scss +1 -0
- package/src/scss/components/drop.scss +1 -18
- package/src/scss/components/dropbar.scss +126 -0
- package/src/scss/components/dropdown.scss +11 -19
- package/src/scss/components/leader.scss +1 -1
- package/src/scss/components/nav.scss +168 -46
- package/src/scss/components/navbar.scss +49 -69
- package/src/scss/components/utility.scss +8 -1
- package/src/scss/mixins-theme.scss +83 -61
- package/src/scss/mixins.scss +79 -29
- package/src/scss/theme/_import.scss +1 -0
- package/src/scss/theme/dropbar.scss +44 -0
- package/src/scss/theme/dropdown.scss +0 -8
- package/src/scss/theme/nav.scss +43 -7
- package/src/scss/theme/navbar.scss +4 -16
- package/src/scss/variables-theme.scss +62 -26
- package/src/scss/variables.scss +50 -21
- package/tests/accordion.html +2 -2
- package/tests/alert.html +2 -2
- package/tests/countdown.html +1 -1
- package/tests/drop.html +446 -416
- package/tests/dropbar.html +458 -0
- package/tests/dropdown.html +8 -470
- package/tests/filter.html +9 -12
- package/tests/form.html +1 -1
- package/tests/index.html +126 -107
- package/tests/js/index.js +1 -4
- package/tests/lightbox.html +5 -5
- package/tests/list.html +8 -8
- package/tests/modal.html +13 -13
- package/tests/nav.html +117 -75
- package/tests/navbar.html +129 -249
- package/tests/offcanvas.html +17 -21
- package/tests/parallax.html +1 -1
- package/tests/position.html +18 -16
- package/tests/progress.html +9 -9
- package/tests/scroll.html +7 -10
- package/tests/search.html +6 -6
- package/tests/slider.html +6 -5
- package/tests/slideshow.html +8 -8
- package/tests/sortable.html +6 -8
- package/tests/sticky-navbar.html +15 -15
- package/tests/sticky.html +8 -8
- package/tests/switcher.html +1 -1
- package/tests/tab.html +1 -1
- package/tests/table.html +7 -7
- package/tests/toggle.html +2 -2
- package/tests/tooltip.html +1 -1
- package/tests/upload.html +11 -11
- package/tests/utility.html +19 -0
- package/src/images/backgrounds/nav-parent-open.svg +0 -3
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
addClass,
|
|
4
4
|
Animation,
|
|
5
5
|
css,
|
|
6
|
-
|
|
6
|
+
dimensions,
|
|
7
7
|
hasClass,
|
|
8
8
|
includes,
|
|
9
9
|
isBoolean,
|
|
@@ -11,13 +11,14 @@ import {
|
|
|
11
11
|
isVisible,
|
|
12
12
|
noop,
|
|
13
13
|
removeClass,
|
|
14
|
-
scrollParents,
|
|
15
14
|
startsWith,
|
|
16
15
|
toFloat,
|
|
17
16
|
toggleClass,
|
|
18
17
|
toNodes,
|
|
19
18
|
Transition,
|
|
20
19
|
trigger,
|
|
20
|
+
unwrap,
|
|
21
|
+
wrapInner,
|
|
21
22
|
} from 'uikit-util';
|
|
22
23
|
|
|
23
24
|
export default {
|
|
@@ -39,26 +40,6 @@ export default {
|
|
|
39
40
|
transition: 'ease',
|
|
40
41
|
clsEnter: 'uk-togglabe-enter',
|
|
41
42
|
clsLeave: 'uk-togglabe-leave',
|
|
42
|
-
|
|
43
|
-
initProps: {
|
|
44
|
-
overflow: '',
|
|
45
|
-
maxHeight: '',
|
|
46
|
-
paddingTop: '',
|
|
47
|
-
paddingBottom: '',
|
|
48
|
-
marginTop: '',
|
|
49
|
-
marginBottom: '',
|
|
50
|
-
boxShadow: '',
|
|
51
|
-
},
|
|
52
|
-
|
|
53
|
-
hideProps: {
|
|
54
|
-
overflow: 'hidden',
|
|
55
|
-
maxHeight: 0,
|
|
56
|
-
paddingTop: 0,
|
|
57
|
-
paddingBottom: 0,
|
|
58
|
-
marginTop: 0,
|
|
59
|
-
marginBottom: 0,
|
|
60
|
-
boxShadow: 'none',
|
|
61
|
-
},
|
|
62
43
|
},
|
|
63
44
|
|
|
64
45
|
computed: {
|
|
@@ -67,7 +48,7 @@ export default {
|
|
|
67
48
|
},
|
|
68
49
|
|
|
69
50
|
hasTransition({ animation }) {
|
|
70
|
-
return startsWith(animation[0],
|
|
51
|
+
return ['slide', 'reveal'].some((transition) => startsWith(animation[0], transition));
|
|
71
52
|
},
|
|
72
53
|
},
|
|
73
54
|
|
|
@@ -160,122 +141,105 @@ function toggleInstant({ _toggle }) {
|
|
|
160
141
|
};
|
|
161
142
|
}
|
|
162
143
|
|
|
163
|
-
function toggleTransition(cmp) {
|
|
164
|
-
|
|
165
|
-
case 'slide-left':
|
|
166
|
-
return slideHorizontal(cmp);
|
|
167
|
-
case 'slide-right':
|
|
168
|
-
return slideHorizontal(cmp, true);
|
|
169
|
-
}
|
|
170
|
-
return slide(cmp);
|
|
171
|
-
}
|
|
144
|
+
export function toggleTransition(cmp) {
|
|
145
|
+
const [mode = 'reveal', startProp = 'top'] = cmp.animation[0]?.split('-') || [];
|
|
172
146
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
const inProgress = Transition.inProgress(el);
|
|
184
|
-
const inner =
|
|
185
|
-
!inProgress && el.hasChildNodes()
|
|
186
|
-
? toFloat(css(el.firstElementChild, 'marginTop')) +
|
|
187
|
-
toFloat(css(el.lastElementChild, 'marginBottom'))
|
|
188
|
-
: 0;
|
|
189
|
-
const currentHeight = isVisible(el) ? toFloat(css(el, 'height')) + inner : 0;
|
|
147
|
+
const dirs = [
|
|
148
|
+
['left', 'right'],
|
|
149
|
+
['top', 'bottom'],
|
|
150
|
+
];
|
|
151
|
+
const dir = dirs[includes(dirs[0], startProp) ? 0 : 1];
|
|
152
|
+
const end = dir[1] === startProp;
|
|
153
|
+
const props = ['width', 'height'];
|
|
154
|
+
const dimProp = props[dirs.indexOf(dir)];
|
|
155
|
+
const marginProp = `margin-${dir[0]}`;
|
|
156
|
+
const marginStartProp = `margin-${startProp}`;
|
|
190
157
|
|
|
191
|
-
|
|
158
|
+
return async (el, show) => {
|
|
159
|
+
let { duration, velocity, transition, _toggle } = cmp;
|
|
192
160
|
|
|
193
|
-
|
|
161
|
+
let currentDim = dimensions(el)[dimProp];
|
|
162
|
+
|
|
163
|
+
const inProgress = Transition.inProgress(el);
|
|
164
|
+
await Transition.cancel(el);
|
|
194
165
|
|
|
195
|
-
if (
|
|
166
|
+
if (show) {
|
|
196
167
|
_toggle(el, true);
|
|
197
168
|
}
|
|
198
169
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
? Transition.start(
|
|
212
|
-
el,
|
|
213
|
-
{ ...initProps, overflow: 'hidden', maxHeight: endHeight },
|
|
214
|
-
duration * (1 - currentHeight / endHeight),
|
|
215
|
-
transition
|
|
216
|
-
)
|
|
217
|
-
: Transition.start(
|
|
218
|
-
el,
|
|
219
|
-
hideProps,
|
|
220
|
-
duration * (currentHeight / endHeight),
|
|
221
|
-
transition
|
|
222
|
-
).then(() => _toggle(el, false))
|
|
223
|
-
).then(() => css(el, initProps));
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
function slideHorizontal({ isToggled, duration, velocity, transition, _toggle }, right) {
|
|
228
|
-
return (el, show) => {
|
|
229
|
-
const visible = isVisible(el);
|
|
230
|
-
const marginLeft = toFloat(css(el, 'marginLeft'));
|
|
231
|
-
|
|
232
|
-
Transition.cancel(el);
|
|
170
|
+
const prevProps = Object.fromEntries(
|
|
171
|
+
[
|
|
172
|
+
'padding',
|
|
173
|
+
'border',
|
|
174
|
+
'width',
|
|
175
|
+
'height',
|
|
176
|
+
'overflowY',
|
|
177
|
+
'overflowX',
|
|
178
|
+
marginProp,
|
|
179
|
+
marginStartProp,
|
|
180
|
+
].map((key) => [key, el.style[key]])
|
|
181
|
+
);
|
|
233
182
|
|
|
234
|
-
const
|
|
235
|
-
css(
|
|
183
|
+
const dim = dimensions(el);
|
|
184
|
+
const currentMargin = toFloat(css(el, marginProp));
|
|
185
|
+
const marginStart = toFloat(css(el, marginStartProp));
|
|
186
|
+
const endDim = dim[dimProp] + marginStart;
|
|
236
187
|
|
|
237
|
-
if (!
|
|
238
|
-
|
|
188
|
+
if (!inProgress && !show) {
|
|
189
|
+
currentDim += marginStart;
|
|
239
190
|
}
|
|
240
191
|
|
|
241
|
-
const
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
192
|
+
const [wrapper] = wrapInner(el, '<div>');
|
|
193
|
+
css(wrapper, {
|
|
194
|
+
boxSizing: 'border-box',
|
|
195
|
+
height: dim.height,
|
|
196
|
+
width: dim.width,
|
|
197
|
+
...css(el, [
|
|
198
|
+
'overflow',
|
|
199
|
+
'padding',
|
|
200
|
+
'borderTop',
|
|
201
|
+
'borderRight',
|
|
202
|
+
'borderBottom',
|
|
203
|
+
'borderLeft',
|
|
204
|
+
'borderImage',
|
|
205
|
+
marginStartProp,
|
|
206
|
+
]),
|
|
207
|
+
});
|
|
245
208
|
|
|
246
209
|
css(el, {
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
210
|
+
padding: 0,
|
|
211
|
+
border: 0,
|
|
212
|
+
[marginStartProp]: 0,
|
|
213
|
+
width: dim.width,
|
|
214
|
+
height: dim.height,
|
|
215
|
+
overflow: 'hidden',
|
|
216
|
+
[dimProp]: currentDim,
|
|
251
217
|
});
|
|
252
218
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
css(el, { clipPath: '', marginLeft: '' });
|
|
278
|
-
});
|
|
219
|
+
const percent = currentDim / endDim;
|
|
220
|
+
duration = (velocity * endDim + duration) * (show ? 1 - percent : percent);
|
|
221
|
+
const endProps = { [dimProp]: show ? endDim : 0 };
|
|
222
|
+
|
|
223
|
+
if (end) {
|
|
224
|
+
css(el, marginProp, endDim - currentDim + currentMargin);
|
|
225
|
+
endProps[marginProp] = show ? currentMargin : endDim + currentMargin;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
if (!end ^ (mode === 'reveal')) {
|
|
229
|
+
css(wrapper, marginProp, -endDim + currentDim);
|
|
230
|
+
Transition.start(wrapper, { [marginProp]: show ? 0 : -endDim }, duration, transition);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
try {
|
|
234
|
+
await Transition.start(el, endProps, duration, transition);
|
|
235
|
+
} finally {
|
|
236
|
+
css(el, prevProps);
|
|
237
|
+
unwrap(wrapper.firstChild);
|
|
238
|
+
|
|
239
|
+
if (!show) {
|
|
240
|
+
_toggle(el, false);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
279
243
|
};
|
|
280
244
|
}
|
|
281
245
|
|
package/src/js/util/animation.js
CHANGED
|
@@ -4,7 +4,7 @@ import { css, propName } from './style';
|
|
|
4
4
|
import { startsWith, toNodes } from './lang';
|
|
5
5
|
import { addClass, hasClass, removeClass, removeClasses } from './class';
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
function transition(element, props, duration = 400, timing = 'linear') {
|
|
8
8
|
duration = Math.round(duration);
|
|
9
9
|
return Promise.all(
|
|
10
10
|
toNodes(element).map(
|
|
@@ -50,13 +50,14 @@ export function transition(element, props, duration = 400, timing = 'linear') {
|
|
|
50
50
|
export const Transition = {
|
|
51
51
|
start: transition,
|
|
52
52
|
|
|
53
|
-
stop(element) {
|
|
53
|
+
async stop(element) {
|
|
54
54
|
trigger(element, 'transitionend');
|
|
55
|
-
|
|
55
|
+
await Promise.resolve();
|
|
56
56
|
},
|
|
57
57
|
|
|
58
|
-
cancel(element) {
|
|
58
|
+
async cancel(element) {
|
|
59
59
|
trigger(element, 'transitioncanceled');
|
|
60
|
+
await Promise.resolve();
|
|
60
61
|
},
|
|
61
62
|
|
|
62
63
|
inProgress(element) {
|
|
@@ -66,7 +67,7 @@ export const Transition = {
|
|
|
66
67
|
|
|
67
68
|
const animationPrefix = 'uk-animation-';
|
|
68
69
|
|
|
69
|
-
|
|
70
|
+
function animate(element, animation, duration = 200, origin, out) {
|
|
70
71
|
return Promise.all(
|
|
71
72
|
toNodes(element).map(
|
|
72
73
|
(element) =>
|
|
@@ -100,7 +101,8 @@ export function animate(element, animation, duration = 200, origin, out) {
|
|
|
100
101
|
);
|
|
101
102
|
}
|
|
102
103
|
|
|
103
|
-
const
|
|
104
|
+
const inProgressRe = new RegExp(`${animationPrefix}(enter|leave)`);
|
|
105
|
+
|
|
104
106
|
export const Animation = {
|
|
105
107
|
in: animate,
|
|
106
108
|
|
|
@@ -109,7 +111,7 @@ export const Animation = {
|
|
|
109
111
|
},
|
|
110
112
|
|
|
111
113
|
inProgress(element) {
|
|
112
|
-
return
|
|
114
|
+
return inProgressRe.test(attr(element, 'class'));
|
|
113
115
|
},
|
|
114
116
|
|
|
115
117
|
cancel(element) {
|
package/src/js/util/class.js
CHANGED
|
@@ -10,7 +10,9 @@ export function removeClass(element, ...args) {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
export function removeClasses(element, cls) {
|
|
13
|
-
attr(element, 'class', (value) =>
|
|
13
|
+
attr(element, 'class', (value) =>
|
|
14
|
+
(value || '').replace(new RegExp(`\\b${cls}\\b\\s?`, 'g'), '')
|
|
15
|
+
);
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
export function replaceClass(element, ...args) {
|
package/src/js/util/filter.js
CHANGED
|
@@ -51,12 +51,8 @@ export function matches(element, selector) {
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
export function closest(element, selector) {
|
|
54
|
-
if (startsWith(selector, '>')) {
|
|
55
|
-
selector = selector.slice(1);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
54
|
return isElement(element)
|
|
59
|
-
? element.closest(selector)
|
|
55
|
+
? element.closest(startsWith(selector, '>') ? selector.slice(1) : selector)
|
|
60
56
|
: toNodes(element)
|
|
61
57
|
.map((element) => closest(element, selector))
|
|
62
58
|
.filter(Boolean);
|
|
@@ -64,8 +60,8 @@ export function closest(element, selector) {
|
|
|
64
60
|
|
|
65
61
|
export function within(element, selector) {
|
|
66
62
|
return isString(selector)
|
|
67
|
-
?
|
|
68
|
-
:
|
|
63
|
+
? !!closest(element, selector)
|
|
64
|
+
: toNode(selector).contains(toNode(element));
|
|
69
65
|
}
|
|
70
66
|
|
|
71
67
|
export function parents(element, selector) {
|
package/src/js/util/position.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { offset } from './dimensions';
|
|
2
|
-
import { clamp,
|
|
2
|
+
import { clamp, isArray, ucfirst } from './lang';
|
|
3
3
|
import { offsetViewport, scrollParents } from './viewport';
|
|
4
4
|
|
|
5
5
|
const dirs = [
|
|
@@ -15,127 +15,63 @@ export function positionAt(element, target, options) {
|
|
|
15
15
|
...options.attach,
|
|
16
16
|
},
|
|
17
17
|
offset: [0, 0],
|
|
18
|
+
placement: [],
|
|
18
19
|
...options,
|
|
19
20
|
};
|
|
20
21
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
: attachTo(element, target, options);
|
|
24
|
-
|
|
25
|
-
offset(element, dim);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function attachTo(element, target, options) {
|
|
29
|
-
let { attach, offset: offsetBy } = {
|
|
30
|
-
attach: {
|
|
31
|
-
element: ['left', 'top'],
|
|
32
|
-
target: ['left', 'top'],
|
|
33
|
-
...options.attach,
|
|
34
|
-
},
|
|
35
|
-
offset: [0, 0],
|
|
36
|
-
...options,
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
const position = offset(element);
|
|
40
|
-
const targetOffset = offset(target);
|
|
41
|
-
for (const [i, [prop, dir, start, end]] of Object.entries(dirs)) {
|
|
42
|
-
position[start] = position[dir] =
|
|
43
|
-
targetOffset[start] +
|
|
44
|
-
moveBy(attach.target[i], end, targetOffset[prop]) -
|
|
45
|
-
moveBy(attach.element[i], end, position[prop]) +
|
|
46
|
-
+offsetBy[i];
|
|
47
|
-
position[end] = position[start] + position[prop];
|
|
22
|
+
if (!isArray(target)) {
|
|
23
|
+
target = [target, target];
|
|
48
24
|
}
|
|
49
|
-
return position;
|
|
50
|
-
}
|
|
51
25
|
|
|
52
|
-
|
|
53
|
-
return start === 'center' ? dim / 2 : start === end ? dim : 0;
|
|
26
|
+
offset(element, getPosition(element, target, options));
|
|
54
27
|
}
|
|
55
28
|
|
|
56
|
-
function
|
|
29
|
+
function getPosition(element, target, options) {
|
|
57
30
|
const position = attachTo(element, target, options);
|
|
58
|
-
const targetDim = offset(target);
|
|
59
31
|
|
|
60
32
|
let {
|
|
61
|
-
flip,
|
|
62
33
|
attach: { element: elAttach, target: targetAttach },
|
|
63
34
|
offset: elOffset,
|
|
64
35
|
boundary,
|
|
65
|
-
viewport,
|
|
66
36
|
viewportOffset,
|
|
37
|
+
placement,
|
|
67
38
|
} = options;
|
|
68
39
|
|
|
69
|
-
let
|
|
70
|
-
|
|
71
|
-
viewports =
|
|
72
|
-
|
|
73
|
-
const [scrollElement] = viewports;
|
|
74
|
-
viewports.push(viewport);
|
|
40
|
+
let offsetPosition = position;
|
|
41
|
+
for (const [i, [prop, , start, end]] of Object.entries(dirs)) {
|
|
42
|
+
let viewports = scrollParents(target[i]);
|
|
43
|
+
const scrollArea = getScrollArea(viewports[0], viewportOffset, i);
|
|
75
44
|
|
|
76
|
-
|
|
77
|
-
for (const [i, [prop, dir, start, end]] of Object.entries(dirs)) {
|
|
78
|
-
if (flip !== true && !includes(flip, dir)) {
|
|
79
|
-
continue;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
const willFlip =
|
|
83
|
-
!intersectLine(position, targetDim, i) && intersectLine(position, targetDim, 1 - i);
|
|
84
|
-
|
|
85
|
-
viewport = getIntersectionArea(...viewports.filter(Boolean).map(offsetViewport));
|
|
45
|
+
let viewport = getIntersectionArea(...viewports.map(offsetViewport));
|
|
86
46
|
|
|
87
47
|
if (viewportOffset) {
|
|
88
48
|
viewport[start] += viewportOffset;
|
|
89
49
|
viewport[end] -= viewportOffset;
|
|
90
50
|
}
|
|
91
51
|
|
|
92
|
-
if (boundary
|
|
52
|
+
if (boundary) {
|
|
93
53
|
viewport = getIntersectionArea(viewport, offset(boundary));
|
|
94
54
|
}
|
|
95
55
|
|
|
96
|
-
|
|
97
|
-
const isInEndBoundary = position[end] <= viewport[end];
|
|
98
|
-
|
|
99
|
-
if (isInStartBoundary && isInEndBoundary) {
|
|
56
|
+
if (isWithin(position, viewport, i)) {
|
|
100
57
|
continue;
|
|
101
58
|
}
|
|
102
59
|
|
|
103
|
-
let offsetBy;
|
|
60
|
+
let offsetBy = 0;
|
|
104
61
|
|
|
105
62
|
// Flip
|
|
106
|
-
if (
|
|
63
|
+
if (placement[i] === 'flip') {
|
|
107
64
|
if (
|
|
108
|
-
(
|
|
109
|
-
(
|
|
65
|
+
(targetAttach[i] === end && position[end] <= viewport[end]) ||
|
|
66
|
+
(targetAttach[i] === start && position[start] >= viewport[start])
|
|
110
67
|
) {
|
|
111
68
|
continue;
|
|
112
69
|
}
|
|
113
70
|
|
|
114
|
-
offsetBy =
|
|
115
|
-
(elAttach[i] === start
|
|
116
|
-
? -position[prop]
|
|
117
|
-
: elAttach[i] === end
|
|
118
|
-
? position[prop]
|
|
119
|
-
: 0) +
|
|
120
|
-
(targetAttach[i] === start
|
|
121
|
-
? targetDim[prop]
|
|
122
|
-
: targetAttach[i] === end
|
|
123
|
-
? -targetDim[prop]
|
|
124
|
-
: 0) -
|
|
125
|
-
elOffset[i] * 2;
|
|
71
|
+
offsetBy = flip(element, target, options, i)[start] - position[start];
|
|
126
72
|
|
|
127
|
-
if (
|
|
128
|
-
|
|
129
|
-
{
|
|
130
|
-
...position,
|
|
131
|
-
[start]: position[start] + offsetBy,
|
|
132
|
-
[end]: position[end] + offsetBy,
|
|
133
|
-
},
|
|
134
|
-
scrollElement,
|
|
135
|
-
i
|
|
136
|
-
)
|
|
137
|
-
) {
|
|
138
|
-
if (isInScrollArea(position, scrollElement, i)) {
|
|
73
|
+
if (!isWithin(applyOffset(position, offsetBy, i), scrollArea, i)) {
|
|
74
|
+
if (isWithin(position, scrollArea, i)) {
|
|
139
75
|
continue;
|
|
140
76
|
}
|
|
141
77
|
|
|
@@ -143,27 +79,27 @@ function attachToWithFlip(element, target, options) {
|
|
|
143
79
|
return false;
|
|
144
80
|
}
|
|
145
81
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
return newPos;
|
|
160
|
-
}
|
|
82
|
+
const newPos = getPosition(element, target, {
|
|
83
|
+
...options,
|
|
84
|
+
attach: {
|
|
85
|
+
element: elAttach.map(flipAxis).reverse(),
|
|
86
|
+
target: targetAttach.map(flipAxis).reverse(),
|
|
87
|
+
},
|
|
88
|
+
offset: elOffset.reverse(),
|
|
89
|
+
placement: placement.reverse(),
|
|
90
|
+
recursion: true,
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
if (newPos && isWithin(newPos, scrollArea, 1 - i)) {
|
|
94
|
+
return newPos;
|
|
161
95
|
}
|
|
96
|
+
|
|
162
97
|
continue;
|
|
163
98
|
}
|
|
164
99
|
|
|
165
|
-
//
|
|
166
|
-
} else {
|
|
100
|
+
// Shift
|
|
101
|
+
} else if (placement[i] === 'shift') {
|
|
102
|
+
const targetDim = offset(target[i]);
|
|
167
103
|
offsetBy =
|
|
168
104
|
clamp(
|
|
169
105
|
clamp(position[start], viewport[start], viewport[end] - position[prop]),
|
|
@@ -172,13 +108,54 @@ function attachToWithFlip(element, target, options) {
|
|
|
172
108
|
) - position[start];
|
|
173
109
|
}
|
|
174
110
|
|
|
175
|
-
offsetPosition
|
|
176
|
-
offsetPosition[end] += offsetBy;
|
|
111
|
+
offsetPosition = applyOffset(offsetPosition, offsetBy, i);
|
|
177
112
|
}
|
|
178
113
|
|
|
179
114
|
return offsetPosition;
|
|
180
115
|
}
|
|
181
116
|
|
|
117
|
+
function attachTo(element, target, options) {
|
|
118
|
+
let { attach, offset: offsetBy } = {
|
|
119
|
+
attach: {
|
|
120
|
+
element: ['left', 'top'],
|
|
121
|
+
target: ['left', 'top'],
|
|
122
|
+
...options.attach,
|
|
123
|
+
},
|
|
124
|
+
offset: [0, 0],
|
|
125
|
+
...options,
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
let elOffset = offset(element);
|
|
129
|
+
|
|
130
|
+
for (const [i, [prop, , start, end]] of Object.entries(dirs)) {
|
|
131
|
+
const targetOffset =
|
|
132
|
+
attach.target[i] === attach.element[i] ? offsetViewport(target[i]) : offset(target[i]);
|
|
133
|
+
|
|
134
|
+
elOffset = applyOffset(
|
|
135
|
+
elOffset,
|
|
136
|
+
targetOffset[start] -
|
|
137
|
+
elOffset[start] +
|
|
138
|
+
moveBy(attach.target[i], end, targetOffset[prop]) -
|
|
139
|
+
moveBy(attach.element[i], end, elOffset[prop]) +
|
|
140
|
+
+offsetBy[i],
|
|
141
|
+
i
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
return elOffset;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function applyOffset(position, offset, i) {
|
|
148
|
+
const [, dir, start, end] = dirs[i];
|
|
149
|
+
const newPos = { ...position };
|
|
150
|
+
newPos[start] = position[dir] = position[start] + offset;
|
|
151
|
+
newPos[end] += offset;
|
|
152
|
+
return newPos;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function moveBy(attach, end, dim) {
|
|
156
|
+
return attach === 'center' ? dim / 2 : attach === end ? dim : 0;
|
|
157
|
+
}
|
|
158
|
+
|
|
182
159
|
function getIntersectionArea(...rects) {
|
|
183
160
|
let area = {};
|
|
184
161
|
for (const rect of rects) {
|
|
@@ -190,21 +167,45 @@ function getIntersectionArea(...rects) {
|
|
|
190
167
|
return area;
|
|
191
168
|
}
|
|
192
169
|
|
|
193
|
-
function
|
|
194
|
-
const
|
|
195
|
-
const
|
|
196
|
-
viewport[start] -= scrollElement[`scroll${ucfirst(start)}`];
|
|
197
|
-
viewport[end] = viewport[start] + scrollElement[`scroll${ucfirst(prop)}`];
|
|
170
|
+
function getScrollArea(scrollElement, viewportOffset, i) {
|
|
171
|
+
const [prop, , start, end] = dirs[i];
|
|
172
|
+
const viewport = offsetViewport(scrollElement);
|
|
173
|
+
viewport[start] -= scrollElement[`scroll${ucfirst(start)}`] - viewportOffset;
|
|
174
|
+
viewport[end] = viewport[start] + scrollElement[`scroll${ucfirst(prop)}`] - viewportOffset;
|
|
175
|
+
return viewport;
|
|
176
|
+
}
|
|
198
177
|
|
|
199
|
-
|
|
178
|
+
function isWithin(positionA, positionB, i) {
|
|
179
|
+
const [, , start, end] = dirs[i];
|
|
180
|
+
return positionA[start] >= positionB[start] && positionA[end] <= positionB[end];
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function flip(element, target, { offset, attach }, i) {
|
|
184
|
+
return attachTo(element, target, {
|
|
185
|
+
attach: {
|
|
186
|
+
element: flipAttach(attach.element, i),
|
|
187
|
+
target: flipAttach(attach.target, i),
|
|
188
|
+
},
|
|
189
|
+
offset: flipOffset(offset, i),
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function flipAttach(attach, i) {
|
|
194
|
+
const newAttach = [...attach];
|
|
195
|
+
const index = dirs[i].indexOf(attach[i]);
|
|
196
|
+
if (~index) {
|
|
197
|
+
newAttach[i] = dirs[i][1 - (index % 2) + 2];
|
|
198
|
+
}
|
|
199
|
+
return newAttach;
|
|
200
200
|
}
|
|
201
201
|
|
|
202
|
-
function
|
|
203
|
-
|
|
204
|
-
|
|
202
|
+
function flipOffset(offset, i) {
|
|
203
|
+
offset = [...offset];
|
|
204
|
+
offset[i] *= -1;
|
|
205
|
+
return offset;
|
|
205
206
|
}
|
|
206
207
|
|
|
207
|
-
function
|
|
208
|
+
function flipAxis(prop) {
|
|
208
209
|
for (let i = 0; i < dirs.length; i++) {
|
|
209
210
|
const index = dirs[i].indexOf(prop);
|
|
210
211
|
if (~index) {
|