uikit 3.14.4-dev.4bd89c5ca → 3.14.4-dev.6923b7e2c

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 (129) hide show
  1. package/CHANGELOG.md +34 -17
  2. package/dist/css/uikit-core-rtl.css +337 -159
  3. package/dist/css/uikit-core-rtl.min.css +1 -1
  4. package/dist/css/uikit-core.css +337 -159
  5. package/dist/css/uikit-core.min.css +1 -1
  6. package/dist/css/uikit-rtl.css +357 -163
  7. package/dist/css/uikit-rtl.min.css +1 -1
  8. package/dist/css/uikit.css +357 -163
  9. package/dist/css/uikit.min.css +1 -1
  10. package/dist/js/components/countdown.js +1 -1
  11. package/dist/js/components/countdown.min.js +1 -1
  12. package/dist/js/components/filter.js +1 -1
  13. package/dist/js/components/filter.min.js +1 -1
  14. package/dist/js/components/lightbox-panel.js +69 -114
  15. package/dist/js/components/lightbox-panel.min.js +1 -1
  16. package/dist/js/components/lightbox.js +69 -114
  17. package/dist/js/components/lightbox.min.js +1 -1
  18. package/dist/js/components/notification.js +1 -1
  19. package/dist/js/components/notification.min.js +1 -1
  20. package/dist/js/components/parallax.js +4 -5
  21. package/dist/js/components/parallax.min.js +1 -1
  22. package/dist/js/components/slider-parallax.js +4 -5
  23. package/dist/js/components/slider-parallax.min.js +1 -1
  24. package/dist/js/components/slider.js +1 -1
  25. package/dist/js/components/slider.min.js +1 -1
  26. package/dist/js/components/slideshow-parallax.js +4 -5
  27. package/dist/js/components/slideshow-parallax.min.js +1 -1
  28. package/dist/js/components/slideshow.js +1 -1
  29. package/dist/js/components/slideshow.min.js +1 -1
  30. package/dist/js/components/sortable.js +1 -1
  31. package/dist/js/components/sortable.min.js +1 -1
  32. package/dist/js/components/tooltip.js +88 -134
  33. package/dist/js/components/tooltip.min.js +1 -1
  34. package/dist/js/components/upload.js +1 -1
  35. package/dist/js/components/upload.min.js +1 -1
  36. package/dist/js/uikit-core.js +366 -361
  37. package/dist/js/uikit-core.min.js +14 -1
  38. package/dist/js/uikit-icons.js +1 -1
  39. package/dist/js/uikit-icons.min.js +1 -1
  40. package/dist/js/uikit.js +366 -361
  41. package/dist/js/uikit.min.js +14 -1
  42. package/package.json +1 -1
  43. package/src/images/{backgrounds/nav-parent-close.svg → components/nav-parent-icon-large.svg} +0 -0
  44. package/src/images/{backgrounds/navbar-parent-close.svg → components/nav-parent-icon.svg} +0 -0
  45. package/src/images/{backgrounds/navbar-parent-open.svg → components/navbar-parent-icon.svg} +1 -1
  46. package/src/images/components/navbar-toggle-icon.svg +22 -3
  47. package/src/js/api/state.js +1 -1
  48. package/src/js/core/accordion.js +9 -17
  49. package/src/js/core/alert.js +35 -14
  50. package/src/js/core/drop.js +87 -61
  51. package/src/js/core/height-viewport.js +4 -2
  52. package/src/js/core/icon.js +16 -0
  53. package/src/js/core/index.js +2 -0
  54. package/src/js/core/leader.js +2 -2
  55. package/src/js/core/navbar.js +28 -45
  56. package/src/js/core/scroll.js +37 -10
  57. package/src/js/mixin/media.js +4 -5
  58. package/src/js/mixin/position.js +21 -24
  59. package/src/js/mixin/togglable.js +80 -124
  60. package/src/js/util/animation.js +4 -3
  61. package/src/js/util/filter.js +3 -7
  62. package/src/js/util/position.js +42 -47
  63. package/src/js/util/style.js +4 -13
  64. package/src/js/util/viewport.js +3 -5
  65. package/src/less/components/_import.less +1 -0
  66. package/src/less/components/drop.less +1 -18
  67. package/src/less/components/dropbar.less +115 -0
  68. package/src/less/components/dropdown.less +11 -19
  69. package/src/less/components/leader.less +1 -1
  70. package/src/less/components/nav.less +218 -59
  71. package/src/less/components/navbar.less +36 -82
  72. package/src/less/components/utility.less +10 -2
  73. package/src/less/theme/_import.less +1 -0
  74. package/src/less/theme/dropbar.less +44 -0
  75. package/src/less/theme/dropdown.less +0 -11
  76. package/src/less/theme/nav.less +45 -7
  77. package/src/less/theme/navbar.less +1 -13
  78. package/src/scss/components/_import.scss +1 -0
  79. package/src/scss/components/drop.scss +1 -18
  80. package/src/scss/components/dropbar.scss +115 -0
  81. package/src/scss/components/dropdown.scss +11 -19
  82. package/src/scss/components/leader.scss +1 -1
  83. package/src/scss/components/nav.scss +167 -47
  84. package/src/scss/components/navbar.scss +36 -70
  85. package/src/scss/components/utility.scss +8 -1
  86. package/src/scss/mixins-theme.scss +80 -33
  87. package/src/scss/mixins.scss +77 -29
  88. package/src/scss/theme/_import.scss +1 -0
  89. package/src/scss/theme/dropbar.scss +44 -0
  90. package/src/scss/theme/dropdown.scss +0 -8
  91. package/src/scss/theme/nav.scss +43 -7
  92. package/src/scss/theme/navbar.scss +1 -13
  93. package/src/scss/variables-theme.scss +54 -22
  94. package/src/scss/variables.scss +43 -20
  95. package/tests/accordion.html +2 -2
  96. package/tests/alert.html +2 -2
  97. package/tests/countdown.html +1 -1
  98. package/tests/drop.html +442 -412
  99. package/tests/drop2.html +475 -0
  100. package/tests/dropbar.html +456 -0
  101. package/tests/dropdown.html +8 -470
  102. package/tests/filter.html +9 -12
  103. package/tests/form.html +1 -1
  104. package/tests/index.html +126 -107
  105. package/tests/lightbox.html +5 -5
  106. package/tests/list.html +8 -8
  107. package/tests/modal.html +13 -13
  108. package/tests/nav.html +117 -75
  109. package/tests/navbar.html +94 -241
  110. package/tests/offcanvas.html +17 -21
  111. package/tests/parallax.html +1 -1
  112. package/tests/position.html +13 -24
  113. package/tests/progress.html +9 -9
  114. package/tests/scroll.html +7 -10
  115. package/tests/search.html +5 -5
  116. package/tests/slide.html +191 -0
  117. package/tests/slider.html +6 -5
  118. package/tests/slideshow.html +8 -8
  119. package/tests/sortable.html +6 -8
  120. package/tests/sticky-navbar.html +6 -6
  121. package/tests/sticky.html +8 -8
  122. package/tests/switcher.html +1 -1
  123. package/tests/tab.html +1 -1
  124. package/tests/table.html +7 -7
  125. package/tests/toggle.html +2 -2
  126. package/tests/tooltip.html +1 -1
  127. package/tests/upload.html +11 -11
  128. package/tests/utility.html +19 -0
  129. package/src/images/backgrounds/nav-parent-open.svg +0 -3
@@ -19,6 +19,7 @@ import {
19
19
  offset,
20
20
  once,
21
21
  parent,
22
+ parents,
22
23
  query,
23
24
  remove,
24
25
  selFocusable,
@@ -36,7 +37,7 @@ export default {
36
37
  align: String,
37
38
  offset: Number,
38
39
  boundary: Boolean,
39
- boundaryAlign: Boolean,
40
+ target: Boolean,
40
41
  clsDrop: String,
41
42
  delayShow: Number,
42
43
  delayHide: Number,
@@ -53,9 +54,12 @@ export default {
53
54
  offset: undefined,
54
55
  delayShow: undefined,
55
56
  delayHide: undefined,
56
- boundaryAlign: undefined,
57
- flip: 'x',
57
+ flip: false,
58
+ shift: true,
58
59
  boundary: true,
60
+ target: false,
61
+ targetX: false,
62
+ targetY: false,
59
63
  dropbar: false,
60
64
  dropbarAnchor: false,
61
65
  duration: 200,
@@ -90,7 +94,7 @@ export default {
90
94
  },
91
95
 
92
96
  watch(dropbar) {
93
- addClass(dropbar, 'uk-navbar-dropbar');
97
+ addClass(dropbar, 'uk-dropbar', 'uk-dropbar-top', 'uk-navbar-dropbar');
94
98
  },
95
99
 
96
100
  immediate: true,
@@ -106,7 +110,7 @@ export default {
106
110
 
107
111
  if (this.dropContainer !== $el) {
108
112
  for (const el of $$(`.${clsDrop}`, this.dropContainer)) {
109
- const target = this.getDropdown(el)?.target;
113
+ const target = this.getDropdown(el)?.targetEl;
110
114
  if (!includes(dropdowns, el) && target && within(target, this.$el)) {
111
115
  dropdowns.push(el);
112
116
  }
@@ -168,8 +172,8 @@ export default {
168
172
  if (
169
173
  active &&
170
174
  includes(active.mode, 'hover') &&
171
- active.target &&
172
- !within(active.target, current) &&
175
+ active.targetEl &&
176
+ !within(active.targetEl, current) &&
173
177
  !active.isDelaying
174
178
  ) {
175
179
  active.hide(false);
@@ -191,7 +195,7 @@ export default {
191
195
  if (keyCode === keyMap.DOWN && hasAttr(current, 'aria-expanded')) {
192
196
  e.preventDefault();
193
197
 
194
- if (!active || active.target !== current) {
198
+ if (!active || active.targetEl !== current) {
195
199
  current.click();
196
200
  once(this.dropContainer, 'show', ({ target }) =>
197
201
  focusFirstFocusableElement(target)
@@ -242,7 +246,7 @@ export default {
242
246
  }
243
247
 
244
248
  if (keyCode === keyMap.ESC) {
245
- active?.target?.focus();
249
+ active?.targetEl?.focus();
246
250
  }
247
251
 
248
252
  handleNavItemNavigation(e, this.toggles, active);
@@ -313,39 +317,19 @@ export default {
313
317
  return;
314
318
  }
315
319
 
316
- this._observer = observeResize(target, () =>
320
+ this._observer = observeResize(target, () => {
321
+ const targetOffsets = parents(target, `.${this.clsDrop}`)
322
+ .concat(target)
323
+ .map((el) => offset(el));
324
+ const minTop = Math.min(...targetOffsets.map(({ top }) => top));
325
+ const maxBottom = Math.max(...targetOffsets.map(({ bottom }) => bottom));
326
+ const dropbarOffset = offset(this.dropbar);
327
+ css(this.dropbar, 'top', this.dropbar.offsetTop - (dropbarOffset.top - minTop));
317
328
  this.transitionTo(
318
- offset(target).bottom -
319
- offset(this.dropbar).top +
320
- toFloat(css(target, 'marginBottom')),
329
+ maxBottom - minTop + toFloat(css(target, 'marginBottom')),
321
330
  target
322
- )
323
- );
324
- },
325
- },
326
-
327
- {
328
- name: 'beforeposition',
329
-
330
- el() {
331
- return this.dropContainer;
332
- },
333
-
334
- filter() {
335
- return this.dropbar;
336
- },
337
-
338
- handler(e, element, target, options) {
339
- if (!this.isDropbarDrop(element)) {
340
- return;
341
- }
342
-
343
- const dropbarOffset = offset(this.dropbar);
344
-
345
- css(element, 'maxWidth', dropbarOffset.width - options.viewportOffset * 2);
346
-
347
- options.offset[1] = dropbarOffset.top - offset(target).bottom;
348
- options.viewportOffset += dropbarOffset.left;
331
+ );
332
+ });
349
333
  },
350
334
  },
351
335
 
@@ -366,7 +350,7 @@ export default {
366
350
  if (
367
351
  matches(this.dropbar, ':hover') &&
368
352
  active?.$el === e.target &&
369
- !this.toggles.some((el) => active.target !== el && matches(el, ':focus'))
353
+ !this.toggles.some((el) => active.targetEl !== el && matches(el, ':focus'))
370
354
  ) {
371
355
  e.preventDefault();
372
356
  }
@@ -402,7 +386,7 @@ export default {
402
386
 
403
387
  methods: {
404
388
  getActive() {
405
- return active && within(active.target, this.$el) && active;
389
+ return active && within(active.targetEl, this.$el) && active;
406
390
  },
407
391
 
408
392
  transitionTo(newHeight, el) {
@@ -435,15 +419,14 @@ export default {
435
419
  },
436
420
 
437
421
  isDropbarDrop(el) {
438
- const drop = this.getDropdown(el);
439
- return drop && hasClass(el, this.clsDrop) && drop.align !== 'stretch';
422
+ return this.getDropdown(el) && hasClass(el, this.clsDrop);
440
423
  },
441
424
  },
442
425
  };
443
426
 
444
427
  function handleNavItemNavigation(e, toggles, active) {
445
428
  const { current, keyCode } = e;
446
- const target = active?.target || current;
429
+ const target = active?.targetEl || current;
447
430
  const i = toggles.indexOf(target);
448
431
 
449
432
  // Left
@@ -1,4 +1,4 @@
1
- import { $, scrollIntoView, trigger } from 'uikit-util';
1
+ import { $, off, on, scrollIntoView, trigger, within } from 'uikit-util';
2
2
 
3
3
  export default {
4
4
  props: {
@@ -9,6 +9,14 @@ export default {
9
9
  offset: 0,
10
10
  },
11
11
 
12
+ connected() {
13
+ registerClick(this);
14
+ },
15
+
16
+ disconnected() {
17
+ unregisterClick(this);
18
+ },
19
+
12
20
  methods: {
13
21
  async scrollTo(el) {
14
22
  el = (el && $(el)) || document.body;
@@ -19,18 +27,37 @@ export default {
19
27
  }
20
28
  },
21
29
  },
30
+ };
22
31
 
23
- events: {
24
- click(e) {
25
- if (e.defaultPrevented) {
26
- return;
27
- }
32
+ const components = new Set();
33
+ function registerClick(cmp) {
34
+ if (!components.size) {
35
+ on(document, 'click', clickHandler);
36
+ }
37
+
38
+ components.add(cmp);
39
+ }
28
40
 
41
+ function unregisterClick(cmp) {
42
+ components.delete(cmp);
43
+
44
+ if (!components.length) {
45
+ off(document, 'click', clickHandler);
46
+ }
47
+ }
48
+
49
+ function clickHandler(e) {
50
+ if (e.defaultPrevented) {
51
+ return;
52
+ }
53
+
54
+ for (const component of components) {
55
+ if (within(e.target, component.$el)) {
29
56
  e.preventDefault();
30
- this.scrollTo(getTargetElement(this.$el));
31
- },
32
- },
33
- };
57
+ component.scrollTo(getTargetElement(component.$el));
58
+ }
59
+ }
60
+ }
34
61
 
35
62
  export function getTargetElement(el) {
36
63
  return document.getElementById(decodeURIComponent(el.hash).substring(1));
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createEvent,
3
- getCssVar,
3
+ css,
4
4
  isNumeric,
5
5
  isString,
6
6
  on,
@@ -19,7 +19,7 @@ export default {
19
19
  },
20
20
 
21
21
  connected() {
22
- const media = toMedia(this.media);
22
+ const media = toMedia(this.media, this.$el);
23
23
  this.matchMedia = true;
24
24
  if (media) {
25
25
  this.mediaObj = window.matchMedia(media);
@@ -40,11 +40,10 @@ export default {
40
40
  },
41
41
  };
42
42
 
43
- function toMedia(value) {
43
+ function toMedia(value, element) {
44
44
  if (isString(value)) {
45
45
  if (startsWith(value, '@')) {
46
- const name = `breakpoint-${value.substr(1)}`;
47
- value = toFloat(getCssVar(name));
46
+ value = toFloat(css(element, `--uk-breakpoint-${value.substr(1)}`));
48
47
  } else if (isNaN(value)) {
49
48
  return value;
50
49
  }
@@ -2,13 +2,11 @@ import {
2
2
  css,
3
3
  dimensions,
4
4
  flipPosition,
5
- getCssVar,
6
5
  includes,
7
6
  isRtl,
8
7
  positionAt,
9
8
  scrollParents,
10
9
  toPx,
11
- trigger,
12
10
  } from 'uikit-util';
13
11
 
14
12
  export default {
@@ -16,12 +14,16 @@ export default {
16
14
  pos: String,
17
15
  offset: null,
18
16
  flip: Boolean,
17
+ shift: Boolean,
18
+ inset: Boolean,
19
19
  },
20
20
 
21
21
  data: {
22
22
  pos: `bottom-${isRtl ? 'right' : 'left'}`,
23
- flip: true,
24
23
  offset: false,
24
+ flip: true,
25
+ shift: true,
26
+ inset: false,
25
27
  },
26
28
 
27
29
  connected() {
@@ -35,7 +37,7 @@ export default {
35
37
  let offset = [this.getPositionOffset(element), this.getShiftOffset(element)];
36
38
 
37
39
  const attach = {
38
- element: [flipPosition(this.dir), this.align],
40
+ element: [this.inset ? this.dir : flipPosition(this.dir), this.align],
39
41
  target: [this.dir, this.align],
40
42
  };
41
43
 
@@ -53,21 +55,14 @@ export default {
53
55
  const elDim = dimensions(element);
54
56
  css(element, { top: -elDim.height, left: -elDim.width });
55
57
 
56
- const args = [
57
- element,
58
- target,
59
- {
60
- attach,
61
- offset,
62
- boundary,
63
- flip: this.flip,
64
- viewportOffset: this.getViewportOffset(element),
65
- },
66
- ];
67
-
68
- trigger(element, 'beforeposition', args);
69
-
70
- positionAt(...args);
58
+ positionAt(element, target, {
59
+ attach,
60
+ offset,
61
+ boundary,
62
+ flip: this.flip,
63
+ shift: this.shift,
64
+ viewportOffset: this.getViewportOffset(element),
65
+ });
71
66
 
72
67
  // Restore scroll position
73
68
  scrollElement.scrollTop = scrollTop;
@@ -77,25 +72,27 @@ export default {
77
72
  getPositionOffset(element) {
78
73
  return (
79
74
  toPx(
80
- this.offset === false ? getCssVar('position-offset', element) : this.offset,
75
+ this.offset === false ? css(element, '--uk-position-offset') : this.offset,
81
76
  this.axis === 'x' ? 'width' : 'height',
82
77
  element
83
- ) * (includes(['left', 'top'], this.dir) ? -1 : 1)
78
+ ) *
79
+ (includes(['left', 'top'], this.dir) ? -1 : 1) *
80
+ (this.inset ? -1 : 1)
84
81
  );
85
82
  },
86
83
 
87
84
  getShiftOffset(element) {
88
- return includes(['center', 'justify', 'stretch'], this.align)
85
+ return this.align === 'center'
89
86
  ? 0
90
87
  : toPx(
91
- getCssVar('position-shift-offset', element),
88
+ css(element, '--uk-position-shift-offset'),
92
89
  this.axis === 'y' ? 'width' : 'height',
93
90
  element
94
91
  ) * (includes(['left', 'top'], this.align) ? 1 : -1);
95
92
  },
96
93
 
97
94
  getViewportOffset(element) {
98
- return toPx(getCssVar('position-viewport-offset', element));
95
+ return toPx(css(element, '--uk-position-viewport-offset'));
99
96
  },
100
97
  },
101
98
  };
@@ -3,7 +3,7 @@ import {
3
3
  addClass,
4
4
  Animation,
5
5
  css,
6
- fastdom,
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], 'slide');
51
+ return ['slide', 'reveal'].some((transition) => startsWith(animation[0], transition));
71
52
  },
72
53
  },
73
54
 
@@ -160,122 +141,97 @@ function toggleInstant({ _toggle }) {
160
141
  };
161
142
  }
162
143
 
163
- function toggleTransition(cmp) {
164
- switch (cmp.animation[0]) {
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
- export function slide({
174
- isToggled,
175
- duration,
176
- velocity,
177
- initProps,
178
- hideProps,
179
- transition,
180
- _toggle,
181
- }) {
182
- return (el, show) => {
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
- const props = inProgress ? css(el, Object.keys(initProps)) : show ? hideProps : initProps;
158
+ return async (el, show) => {
159
+ let { duration, velocity, transition, _toggle } = cmp;
192
160
 
193
- Transition.cancel(el);
161
+ let currentDim = dimensions(el)[dimProp];
162
+
163
+ const inProgress = Transition.inProgress(el);
164
+ await Transition.cancel(el);
194
165
 
195
- if (!isToggled(el)) {
166
+ if (show) {
196
167
  _toggle(el, true);
197
168
  }
198
169
 
199
- css(el, 'maxHeight', '');
200
-
201
- // Update child components first
202
- fastdom.flush();
203
-
204
- const endHeight = toFloat(css(el, 'height')) + inner;
205
- duration = velocity * endHeight + duration;
206
-
207
- css(el, { ...props, maxHeight: currentHeight });
208
-
209
- return (
210
- show
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
+ ['padding', 'border', 'width', 'height', 'overflow', marginProp, marginStartProp].map(
172
+ (key) => [key, el.style[key]]
173
+ )
174
+ );
233
175
 
234
- const [scrollElement] = scrollParents(el.offsetParent);
235
- css(scrollElement, 'overflowX', 'hidden');
176
+ const dim = dimensions(el);
177
+ const currentMargin = toFloat(css(el, marginProp));
178
+ const marginStart = toFloat(css(el, marginStartProp));
179
+ const endDim = dim[dimProp] + marginStart;
236
180
 
237
- if (!isToggled(el)) {
238
- _toggle(el, true);
181
+ if (!inProgress && !show) {
182
+ currentDim += marginStart;
239
183
  }
240
184
 
241
- const width = toFloat(css(el, 'width'));
242
- duration = velocity * width + duration;
243
-
244
- const percent = visible ? ((width + marginLeft * (right ? -1 : 1)) / width) * 100 : 0;
185
+ const [wrapper] = wrapInner(el, '<div>');
186
+ css(wrapper, {
187
+ boxSizing: 'border-box',
188
+ height: dim.height,
189
+ width: dim.width,
190
+ ...css(el, [
191
+ 'padding',
192
+ 'borderTop',
193
+ 'borderRight',
194
+ 'borderBottom',
195
+ 'borderLeft',
196
+ 'borderImage',
197
+ marginStartProp,
198
+ ]),
199
+ });
245
200
 
246
201
  css(el, {
247
- clipPath: right
248
- ? `polygon(0 0,${percent}% 0,${percent}% 100%,0 100%)`
249
- : `polygon(${100 - percent}% 0,100% 0,100% 100%,${100 - percent}% 100%)`,
250
- marginLeft: (((100 - percent) * (right ? 1 : -1)) / 100) * width,
202
+ padding: 0,
203
+ border: 0,
204
+ [marginStartProp]: 0,
205
+ width: dim.width,
206
+ height: dim.height,
207
+ overflow: 'hidden',
208
+ [dimProp]: currentDim,
251
209
  });
252
210
 
253
- return (
254
- show
255
- ? Transition.start(
256
- el,
257
- {
258
- clipPath: `polygon(0 0,100% 0,100% 100%,0 100%)`,
259
- marginLeft: 0,
260
- },
261
- duration * (1 - percent / 100),
262
- transition
263
- )
264
- : Transition.start(
265
- el,
266
- {
267
- clipPath: right
268
- ? `polygon(0 0,0 0,0 100%,0 100%)`
269
- : `polygon(100% 0,100% 0,100% 100%,100% 100%)`,
270
- marginLeft: (right ? 1 : -1) * width,
271
- },
272
- duration * (percent / 100),
273
- transition
274
- ).then(() => _toggle(el, false))
275
- ).then(() => {
276
- css(scrollElement, 'overflowX', '');
277
- css(el, { clipPath: '', marginLeft: '' });
278
- });
211
+ const percent = currentDim / endDim;
212
+ duration = (velocity * endDim + duration) * (show ? 1 - percent : percent);
213
+ const endProps = { [dimProp]: show ? endDim : 0 };
214
+
215
+ if (end) {
216
+ css(el, marginProp, endDim - currentDim + currentMargin);
217
+ endProps[marginProp] = show ? currentMargin : endDim + currentMargin;
218
+ }
219
+
220
+ if (!end ^ (mode === 'reveal')) {
221
+ css(wrapper, marginProp, -endDim + currentDim);
222
+ Transition.start(wrapper, { [marginProp]: show ? 0 : -endDim }, duration, transition);
223
+ }
224
+
225
+ try {
226
+ await Transition.start(el, endProps, duration, transition);
227
+ } finally {
228
+ css(el, prevProps);
229
+ unwrap(wrapper.firstChild);
230
+
231
+ if (!show) {
232
+ _toggle(el, false);
233
+ }
234
+ }
279
235
  };
280
236
  }
281
237
 
@@ -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
- return Promise.resolve();
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) {
@@ -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
- ? matches(element, selector) || !!closest(element, selector)
68
- : element === selector || toNode(selector).contains(toNode(element));
63
+ ? !!closest(element, selector)
64
+ : toNode(selector).contains(toNode(element));
69
65
  }
70
66
 
71
67
  export function parents(element, selector) {