@andreyshpigunov/x 0.4.4 → 0.5.1

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.
@@ -21,143 +21,147 @@ All right reserved.
21
21
  --dropdown-divider-color: var(--color-grey);
22
22
  }
23
23
 
24
- [x-dropdown] {
25
- display: none;
26
- list-style: none;
27
- position: absolute;
28
- top: 100%;
29
- z-index: 1000;
30
- opacity: 0;
31
- min-width: 22rem;
32
- max-width: var(--dropdown-max-width);
33
- max-height: clamp(0px, 80vh, 500px);
34
- overflow: auto;
35
- list-style: none;
36
- padding: var(--dropdown-padding);
37
- margin: 0;
38
- background-color: var(--dropdown-backgroud-color);
39
- border: none;
40
- box-shadow: var(--dropdown-box-shadow);
41
- border-radius: var(--dropdown-border-radius);
42
- transform: scale(.95);
43
- transform-origin: top;
44
- transition: opacity .15s ease-out,
45
- transform .15s ease-out;
46
- pointer-events: none;
47
- overscroll-behavior: contain;
24
+ @layer dropdown {
48
25
 
49
- @media (min-width: 768px) {
50
- max-width: calc(var(--dropdown-max-width) * 1.2);
51
- }
52
-
53
- & > li {
54
- margin: 0;
55
- }
56
-
57
- &::-webkit-scrollbar {
58
- width: var(--scroll-scrollbar-size);
59
- height: var(--scroll-scrollbar-size);
60
- }
61
-
62
- &::-webkit-scrollbar-track {
63
- background-color: none;
64
- border-radius: var(--scroll-scrollbar-size);
65
- }
66
-
67
- &::-webkit-scrollbar-thumb {
68
- border-radius: var(--scroll-scrollbar-size);
69
- background-color: var(--scroll-scrollbar-thumb-background);
70
- will-change: background-color;
71
- transition: background .2s ease-out;
72
- cursor: pointer;
73
- }
74
-
75
- &::-webkit-scrollbar-thumb:hover {
76
- background-color: var(--scroll-scrollbar-thumb-background-hover);
77
- }
78
-
79
- &::-webkit-scrollbar-button,
80
- &::-webkit-scrollbar-track-piece,
81
- &::-webkit-scrollbar-corner,
82
- &::-webkit-resizer {
26
+ [x-dropdown] {
83
27
  display: none;
84
- }
85
- }
86
-
87
- .dropdown {
88
- position: relative;
89
-
90
- &.dropdown--right > [x-dropdown] {
91
- right: 0;
92
- left: auto;
93
- }
94
- &.dropdown--bottom > [x-dropdown] {
95
- bottom: 100%;
96
- top: auto;
97
- transform-origin: bottom;
98
- }
99
- &.dropdown--ready > [x-dropdown] {
100
- display: block;
101
- pointer-events: auto;
102
- }
103
- &.dropdown--open > [x-dropdown] {
104
- opacity: 1;
105
- transform: scale(1);
106
- }
107
- &.dropdown--wrap > [x-dropdown] li {
108
- & > a,
109
- & > span {
110
- white-space: wrap;
28
+ list-style: none;
29
+ position: absolute;
30
+ top: 100%;
31
+ z-index: 1000;
32
+ opacity: 0;
33
+ min-width: 22rem;
34
+ max-width: var(--dropdown-max-width);
35
+ max-height: clamp(0px, 80vh, 500px);
36
+ overflow: auto;
37
+ list-style: none;
38
+ padding: var(--dropdown-padding);
39
+ margin: 0;
40
+ background-color: var(--dropdown-backgroud-color);
41
+ border: none;
42
+ box-shadow: var(--dropdown-box-shadow);
43
+ border-radius: var(--dropdown-border-radius);
44
+ transform: scale(.95);
45
+ transform-origin: top;
46
+ transition: opacity .15s ease-out,
47
+ transform .15s ease-out;
48
+ pointer-events: none;
49
+ overscroll-behavior: contain;
50
+
51
+ @media (min-width: 768px) {
52
+ max-width: calc(var(--dropdown-max-width) * 1.2);
53
+ }
54
+
55
+ & > li {
56
+ margin: 0;
57
+ }
58
+
59
+ &::-webkit-scrollbar {
60
+ width: var(--scroll-scrollbar-size);
61
+ height: var(--scroll-scrollbar-size);
62
+ }
63
+
64
+ &::-webkit-scrollbar-track {
65
+ background-color: none;
66
+ border-radius: var(--scroll-scrollbar-size);
67
+ }
68
+
69
+ &::-webkit-scrollbar-thumb {
70
+ border-radius: var(--scroll-scrollbar-size);
71
+ background-color: var(--scroll-scrollbar-thumb-background);
72
+ will-change: background-color;
73
+ transition: background .2s ease-out;
74
+ cursor: pointer;
75
+ }
76
+
77
+ &::-webkit-scrollbar-thumb:hover {
78
+ background-color: var(--scroll-scrollbar-thumb-background-hover);
79
+ }
80
+
81
+ &::-webkit-scrollbar-button,
82
+ &::-webkit-scrollbar-track-piece,
83
+ &::-webkit-scrollbar-corner,
84
+ &::-webkit-resizer {
85
+ display: none;
111
86
  }
112
87
  }
113
- }
114
-
115
-
116
- [x-dropdown] {
117
88
 
118
- & li {
89
+ .dropdown {
90
+ position: relative;
119
91
 
120
- &.divider {
121
- height: 0;
122
- padding: 0;
123
- margin: var(--dropdown-padding) calc(-1 * var(--dropdown-padding));
124
- border-bottom: 1px solid var(--dropdown-divider-color);
92
+ &.dropdown_right > [x-dropdown] {
93
+ right: 0;
94
+ left: auto;
125
95
  }
126
-
127
- & > a,
128
- & > span {
96
+ &.dropdown_bottom > [x-dropdown] {
97
+ bottom: 100%;
98
+ top: auto;
99
+ transform-origin: bottom;
100
+ }
101
+ &.dropdown_ready > [x-dropdown] {
129
102
  display: block;
130
- padding: var(--dropdown-item-padding);
131
- line-height: 1.4;
132
- color: var(--dropdown-item-font-color);
133
- white-space: nowrap;
134
- text-overflow: ellipsis;
135
- text-decoration: none;
136
- overflow: hidden;
137
- border: none;
138
- border-radius: calc(var(--dropdown-border-radius) / 2);
139
- background: var(--dropdown-item-background-color);
103
+ pointer-events: auto;
140
104
  }
141
-
142
- & > a {
143
- will-change: color, background, transform;
144
- transition: all .1s ease-out;
105
+ &.dropdown_open > [x-dropdown] {
106
+ opacity: 1;
145
107
  transform: scale(1);
146
- transform-origin: bottom center;
108
+ }
109
+ &.dropdown_wrap > [x-dropdown] li {
110
+ & > a,
111
+ & > span {
112
+ white-space: wrap;
113
+ }
114
+ }
115
+ }
116
+
117
+
118
+ [x-dropdown] {
119
+
120
+ & li {
147
121
 
148
- &:focus-visible,
149
- &.focus-visible,
150
- &:hover,
151
- &.hover,
152
- &:active,
153
- &.active {
154
- color: var(--dropdown-item-font-color-hover);
155
- background: var(--dropdown-item-background-color-hover);
122
+ &.divider {
123
+ height: 0;
124
+ padding: 0;
125
+ margin: var(--dropdown-padding) calc(-1 * var(--dropdown-padding));
126
+ border-bottom: 1px solid var(--dropdown-divider-color);
156
127
  }
157
128
 
158
- &:active {
159
- transform: scale(.99);
129
+ & > a,
130
+ & > span {
131
+ display: block;
132
+ padding: var(--dropdown-item-padding);
133
+ line-height: 1.4;
134
+ color: var(--dropdown-item-font-color);
135
+ white-space: nowrap;
136
+ text-overflow: ellipsis;
137
+ text-decoration: none;
138
+ overflow: hidden;
139
+ border: none;
140
+ border-radius: calc(var(--dropdown-border-radius) / 2);
141
+ background: var(--dropdown-item-background-color);
142
+ }
143
+
144
+ & > a {
145
+ will-change: color, background, transform;
146
+ transition: all .1s ease-out;
147
+ transform: scale(1);
148
+ transform-origin: bottom center;
149
+
150
+ &:focus-visible,
151
+ &.focus-visible,
152
+ &:hover,
153
+ &.hover,
154
+ &:active,
155
+ &.active {
156
+ color: var(--dropdown-item-font-color-hover);
157
+ background: var(--dropdown-item-background-color-hover);
158
+ }
159
+
160
+ &:active {
161
+ transform: scale(.99);
162
+ }
160
163
  }
161
164
  }
162
165
  }
166
+
163
167
  }
@@ -46,7 +46,7 @@
46
46
  * Preventing auto-close on click:
47
47
  * ```html
48
48
  * <ul x-dropdown>
49
- * <li class="dropdown--stay">
49
+ * <li class="dropdown_stay">
50
50
  * <button>This area won't close dropdown</button>
51
51
  * </li>
52
52
  * </ul>
@@ -80,10 +80,10 @@
80
80
  * CSS classes:
81
81
  *
82
82
  * - `.dropdown` – Added to parent container
83
- * - `.dropdown--open` – Added when dropdown is open
84
- * - `.dropdown--right` – Added when menu needs to align right (overflow prevention)
85
- * - `.dropdown--bottom` – Added when menu needs to align bottom (overflow prevention)
86
- * - `.dropdown--ready` – Temporarily added during position calculation
83
+ * - `.dropdown_open` – Added when dropdown is open
84
+ * - `.dropdown_right` – Added when menu needs to align right (overflow prevention)
85
+ * - `.dropdown_bottom` – Added when menu needs to align bottom (overflow prevention)
86
+ * - `.dropdown_ready` – Temporarily added during position calculation
87
87
  * - `.active` – Added to trigger when dropdown is open
88
88
  * - `.hover` – Added on focus for better visual feedback
89
89
  *
@@ -123,7 +123,7 @@ import { lib } from './lib';
123
123
  * Features:
124
124
  * - Supports multiple dropdowns on the page.
125
125
  * - Keyboard navigation (Enter, Space, ArrowDown, ArrowUp, Home, End, Escape).
126
- * - Automatic positioning with overflow handling (adds `.dropdown--right`, `.dropdown--bottom`).
126
+ * - Automatic positioning with overflow handling (adds `.dropdown_right`, `.dropdown_bottom`).
127
127
  * - Adds `.hover` class on focus for triggers and menu items.
128
128
  * - Safe `init()` with cleanup and reinitialization support.
129
129
  *
@@ -412,7 +412,7 @@ class Dropdown {
412
412
  * @private
413
413
  */
414
414
  _toggleDropdown(parent, trigger) {
415
- const isOpen = parent.classList.contains('dropdown--open');
415
+ const isOpen = parent.classList.contains('dropdown_open');
416
416
  this.closeAllDropdowns();
417
417
  if (!isOpen) this._open(parent, trigger);
418
418
  }
@@ -432,7 +432,7 @@ class Dropdown {
432
432
  this._adjustPosition(parent, menu);
433
433
 
434
434
  lib.addClass(trigger, 'active');
435
- lib.addClass(parent, 'dropdown--open', 20);
435
+ lib.addClass(parent, 'dropdown_open', 20);
436
436
  trigger.setAttribute('aria-expanded', 'true');
437
437
 
438
438
  this._fireEvent(parent, 'aftershow');
@@ -446,22 +446,22 @@ class Dropdown {
446
446
  * @private
447
447
  */
448
448
  _adjustPosition(parent, menu) {
449
- parent.classList.add('dropdown--ready');
449
+ parent.classList.add('dropdown_ready');
450
450
  const rect = menu.getBoundingClientRect();
451
- parent.classList.remove('dropdown--ready');
451
+ parent.classList.remove('dropdown_ready');
452
452
 
453
453
  const vw = window.innerWidth;
454
454
  const docHeight = document.documentElement.scrollHeight;
455
455
 
456
- parent.classList.remove('dropdown--right', 'dropdown--bottom');
456
+ parent.classList.remove('dropdown_right', 'dropdown_bottom');
457
457
 
458
458
  if (rect.right > vw) {
459
- parent.classList.add('dropdown--right');
459
+ parent.classList.add('dropdown_right');
460
460
  }
461
461
 
462
462
  const menuBottomInDoc = window.scrollY + rect.bottom;
463
463
  if (menuBottomInDoc > docHeight) {
464
- parent.classList.add('dropdown--bottom');
464
+ parent.classList.add('dropdown_bottom');
465
465
  }
466
466
  }
467
467
 
@@ -498,8 +498,8 @@ class Dropdown {
498
498
  * dropdown.closeAllDropdowns();
499
499
  */
500
500
  closeAllDropdowns() {
501
- if (!document.querySelector('.dropdown--open')) return;
502
- const openDropdowns = lib.qsa('.dropdown--open');
501
+ if (!document.querySelector('.dropdown_open')) return;
502
+ const openDropdowns = lib.qsa('.dropdown_open');
503
503
  for (const parent of openDropdowns) {
504
504
  this._close(parent);
505
505
  }
@@ -523,8 +523,8 @@ class Dropdown {
523
523
  trigger.setAttribute('aria-expanded', 'false');
524
524
  }
525
525
 
526
- await lib.removeClass(parent, 'dropdown--open', 200);
527
- parent.classList.remove('dropdown--right', 'dropdown--bottom');
526
+ await lib.removeClass(parent, 'dropdown_open', 200);
527
+ parent.classList.remove('dropdown_right', 'dropdown_bottom');
528
528
 
529
529
  this._fireEvent(parent, 'afterhide');
530
530
 
@@ -551,8 +551,8 @@ class Dropdown {
551
551
  if (Dropdown._globalListenersAttached) return;
552
552
 
553
553
  this._globalClickHandler = e => {
554
- if (e.target.closest('[x-dropdown-open]') || e.target.closest('[x-dropdown] .dropdown--stay')) return;
555
- if (!document.querySelector('.dropdown--open')) return;
554
+ if (e.target.closest('[x-dropdown-open]') || e.target.closest('[x-dropdown] .dropdown_stay')) return;
555
+ if (!document.querySelector('.dropdown_open')) return;
556
556
  this.closeAllDropdowns();
557
557
  };
558
558
  document.addEventListener('click', this._globalClickHandler);