@andreyshpigunov/x 0.3.89 → 0.4.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.
- package/.github/workflows/publish.yml +1 -1
- package/README.md +1 -1
- package/assets/css/app.css +1 -0
- package/assets/img/github-mark-white.png +0 -0
- package/assets/img/github-mark.png +0 -0
- package/assets/js/app.js +1 -0
- package/cheatsheet.html +427 -0
- package/dist/x.css +1 -1
- package/dist/x.js +1 -3
- package/index.html +34 -38
- package/package.json +52 -47
- package/postcss.config.cjs +0 -2
- package/src/components/x/animate.js +39 -45
- package/src/components/x/appear.js +19 -26
- package/src/components/x/autocomplete.js +22 -10
- package/src/components/x/buttons.css +38 -16
- package/src/components/x/colors.css +47 -41
- package/src/components/x/debug.css +2 -2
- package/src/components/x/device.js +39 -33
- package/src/components/x/dropdown.css +2 -3
- package/src/components/x/dropdown.js +16 -9
- package/src/components/x/flex.css +146 -109
- package/src/components/x/flow.css +12 -6
- package/src/components/x/form.css +3 -3
- package/src/components/x/form.js +12 -9
- package/src/components/x/grid.css +78 -42
- package/src/components/x/helpers.css +601 -438
- package/src/components/x/hover.js +20 -9
- package/src/components/x/icons.css +12 -12
- package/src/components/x/lazyload.js +17 -8
- package/src/components/x/lib.js +15 -1
- package/src/components/x/links.css +2 -6
- package/src/components/x/loadmore.js +17 -5
- package/src/components/x/modal.css +4 -22
- package/src/components/x/modal.js +14 -5
- package/src/components/x/reset.css +1 -15
- package/src/components/x/scroll.css +4 -9
- package/src/components/x/scroll.js +14 -1
- package/src/components/x/sheets.css +0 -3
- package/src/components/x/sheets.js +157 -37
- package/src/components/x/slider.css +10 -1
- package/src/components/x/slider.js +15 -0
- package/src/components/x/space.css +22 -2
- package/src/components/x/sticky.css +10 -15
- package/src/components/x/sticky.js +21 -4
- package/src/components/x/typo.css +14 -40
- package/src/css/app.css +92 -93
- package/src/css/x.css +191 -213
- package/src/js/app.js +9 -9
- package/src/js/x.js +37 -41
- package/assets/github-mark-white.png +0 -0
- package/assets/github-mark.png +0 -0
- package/assets/logo-inverse.png +0 -0
- package/babel.config.cjs +0 -4
- package/dist/app.css +0 -1
- package/dist/app.js +0 -1
- package/dist/index.html +0 -2182
- package/dist/logo.png +0 -0
- package/jest.config.mjs +0 -7
- package/jsdoc.json +0 -11
- package/vite.config.js +0 -31
- /package/assets/{alpha.png → img/alpha.png} +0 -0
- /package/assets/{apple-touch-icon.png → img/apple-touch-icon.png} +0 -0
- /package/assets/{logo.png → img/logo.png} +0 -0
- /package/assets/{logo.svg → img/logo.svg} +0 -0
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
* Attaches event listeners to the document for mouseenter and mouseleave events.
|
|
60
60
|
* Safe to call multiple times (no-op after first call). SSR-safe: no-op when document is undefined.
|
|
61
61
|
*
|
|
62
|
-
* @method destroy() - Removes document listeners and resets state. Use on SPA unmount /
|
|
62
|
+
* @method destroy() - Removes document listeners and resets state. Use on SPA unmount / page change.
|
|
63
63
|
*
|
|
64
64
|
* @example
|
|
65
65
|
* import { hover } from './hover.js';
|
|
@@ -85,14 +85,25 @@
|
|
|
85
85
|
* - Efficient CSS selector matching with `CSS.escape()` for special characters
|
|
86
86
|
* - Minimal DOM manipulation (only toggles class on matching elements)
|
|
87
87
|
*
|
|
88
|
-
* Next.js: call hover.init() in useEffect; in cleanup call hover.destroy().
|
|
89
|
-
*
|
|
90
88
|
* @example
|
|
91
|
-
* //
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
89
|
+
* // Vanilla JS — plain HTML
|
|
90
|
+
* // index.html:
|
|
91
|
+
* // <nav>
|
|
92
|
+
* // <a href="/about" x-hover>About</a>
|
|
93
|
+
* // </nav>
|
|
94
|
+
* // <footer>
|
|
95
|
+
* // <a href="/about" x-hover>Learn More</a>
|
|
96
|
+
* // </footer>
|
|
97
|
+
* //
|
|
98
|
+
* // <style>
|
|
99
|
+
* // a.hover { text-decoration: underline; }
|
|
100
|
+
* // </style>
|
|
101
|
+
* //
|
|
102
|
+
* // <script type="module">
|
|
103
|
+
* // import { hover } from './src/components/x/hover.js';
|
|
104
|
+
* // window.addEventListener('DOMContentLoaded', () => hover.init());
|
|
105
|
+
* // window.addEventListener('pagehide', () => hover.destroy());
|
|
106
|
+
* // </script>
|
|
96
107
|
*
|
|
97
108
|
* @author Andrey Shpigunov
|
|
98
109
|
* @version 0.3
|
|
@@ -129,7 +140,7 @@ export class Hover {
|
|
|
129
140
|
}
|
|
130
141
|
|
|
131
142
|
/**
|
|
132
|
-
* Removes document listeners and resets state. Use on SPA unmount
|
|
143
|
+
* Removes document listeners and resets state. Use on SPA unmount / page change.
|
|
133
144
|
* SSR-safe: no-op when document is undefined.
|
|
134
145
|
*/
|
|
135
146
|
destroy() {
|
|
@@ -9,7 +9,7 @@ All right reserved.
|
|
|
9
9
|
|
|
10
10
|
/*
|
|
11
11
|
.icon - base icon style
|
|
12
|
-
.icon
|
|
12
|
+
.icon.s[10-60] step 2 (m,l) - icon size in px
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
.icon,
|
|
@@ -27,30 +27,30 @@ All right reserved.
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
@for $i from 10 to 60 by 2 {
|
|
30
|
-
.icon
|
|
31
|
-
.icon
|
|
32
|
-
.icon
|
|
30
|
+
.icon.s$(i),
|
|
31
|
+
.icon.s$(i) > svg,
|
|
32
|
+
.icon.s$(i) > img {
|
|
33
33
|
width: calc($(i)rem / 10);
|
|
34
34
|
height: calc($(i)rem / 10);
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
@media (
|
|
38
|
+
@media (min-width: 768px) {
|
|
39
39
|
@for $i from 10 to 60 by 2 {
|
|
40
|
-
.m\:icon
|
|
41
|
-
.m\:icon
|
|
42
|
-
.m\:icon
|
|
40
|
+
.m\:icon.s$(i),
|
|
41
|
+
.m\:icon.s$(i) > svg,
|
|
42
|
+
.m\:icon.s$(i) > img {
|
|
43
43
|
width: calc($(i)rem / 10);
|
|
44
44
|
height: calc($(i)rem / 10);
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
@media (
|
|
49
|
+
@media (min-width: 1024px) {
|
|
50
50
|
@for $i from 10 to 60 by 2 {
|
|
51
|
-
.l\:icon
|
|
52
|
-
.l\:icon
|
|
53
|
-
.l\:icon
|
|
51
|
+
.l\:icon.s$(i),
|
|
52
|
+
.l\:icon.s$(i) > svg,
|
|
53
|
+
.l\:icon.s$(i) > img {
|
|
54
54
|
width: calc($(i)rem / 10);
|
|
55
55
|
height: calc($(i)rem / 10);
|
|
56
56
|
}
|
|
@@ -89,14 +89,23 @@
|
|
|
89
89
|
* - Use `data-srcset` for responsive images to reduce bandwidth
|
|
90
90
|
* - Images are automatically unobserved after loading to reduce overhead
|
|
91
91
|
*
|
|
92
|
-
* Next.js: call lazyload.init() in useEffect; in cleanup call lazyload.destroy().
|
|
93
|
-
*
|
|
94
92
|
* @example
|
|
95
|
-
* //
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
93
|
+
* // Vanilla JS — plain HTML
|
|
94
|
+
* // index.html:
|
|
95
|
+
* // <img
|
|
96
|
+
* // x-lazyload
|
|
97
|
+
* // width="800"
|
|
98
|
+
* // height="450"
|
|
99
|
+
* // src="placeholder.jpg"
|
|
100
|
+
* // data-src="image.jpg"
|
|
101
|
+
* // alt="Lazy image"
|
|
102
|
+
* // />
|
|
103
|
+
* //
|
|
104
|
+
* // <script type="module">
|
|
105
|
+
* // import { lazyload } from './src/components/x/lazyload.js';
|
|
106
|
+
* // window.addEventListener('DOMContentLoaded', () => lazyload.init());
|
|
107
|
+
* // window.addEventListener('pagehide', () => lazyload.destroy());
|
|
108
|
+
* // </script>
|
|
100
109
|
*
|
|
101
110
|
* @author Andrey Shpigunov
|
|
102
111
|
* @version 0.2
|
|
@@ -149,7 +158,7 @@ class Lazyload {
|
|
|
149
158
|
}
|
|
150
159
|
|
|
151
160
|
/**
|
|
152
|
-
* Disconnects observer and clears reference. Use on SPA unmount
|
|
161
|
+
* Disconnects observer and clears reference. Use on SPA unmount / page change.
|
|
153
162
|
* SSR-safe: no-op when window is undefined.
|
|
154
163
|
*/
|
|
155
164
|
destroy() {
|
package/src/components/x/lib.js
CHANGED
|
@@ -156,7 +156,21 @@
|
|
|
156
156
|
* - Implement Content Security Policy (CSP) headers
|
|
157
157
|
* - Consider using a proper HTML sanitization library for complex cases
|
|
158
158
|
*
|
|
159
|
-
*
|
|
159
|
+
* SSR-safe: DOM methods no-op or return safe defaults when document/window undefined.
|
|
160
|
+
*
|
|
161
|
+
* @example
|
|
162
|
+
* // Vanilla JS — plain HTML
|
|
163
|
+
* // index.html:
|
|
164
|
+
* // <p id="out"></p>
|
|
165
|
+
* // <div x-render="'Hello from x-render'"></div>
|
|
166
|
+
* //
|
|
167
|
+
* // <script type="module">
|
|
168
|
+
* // import { lib } from './src/components/x/lib.js';
|
|
169
|
+
* // window.addEventListener('DOMContentLoaded', () => {
|
|
170
|
+
* // const el = lib.qs('#out');
|
|
171
|
+
* // if (el) el.textContent = lib.price(1234.56);
|
|
172
|
+
* // });
|
|
173
|
+
* // </script>
|
|
160
174
|
*
|
|
161
175
|
* @author Andrey Shpigunov
|
|
162
176
|
* @version 0.3
|
|
@@ -9,7 +9,6 @@ All right reserved.
|
|
|
9
9
|
|
|
10
10
|
/* !- Links styles */
|
|
11
11
|
|
|
12
|
-
|
|
13
12
|
/*
|
|
14
13
|
a
|
|
15
14
|
a.link
|
|
@@ -22,7 +21,6 @@ All right reserved.
|
|
|
22
21
|
a.link--wavy
|
|
23
22
|
*/
|
|
24
23
|
|
|
25
|
-
|
|
26
24
|
:root {
|
|
27
25
|
--link-color: #0060cc;
|
|
28
26
|
--link-decoration-line: underline;
|
|
@@ -43,7 +41,6 @@ All right reserved.
|
|
|
43
41
|
*/
|
|
44
42
|
}
|
|
45
43
|
|
|
46
|
-
|
|
47
44
|
a {
|
|
48
45
|
|
|
49
46
|
&[role=button] {
|
|
@@ -83,7 +80,6 @@ a {
|
|
|
83
80
|
text-decoration-color: var(--link-decoration-color-hover, currentcolor);
|
|
84
81
|
}
|
|
85
82
|
|
|
86
|
-
|
|
87
83
|
/* Link predefined styles */
|
|
88
84
|
|
|
89
85
|
&.link--noline {
|
|
@@ -109,6 +105,6 @@ a {
|
|
|
109
105
|
a[href^="tel"],
|
|
110
106
|
a[href^="tel"]:hover,
|
|
111
107
|
a[href^="tel"]:active {
|
|
112
|
-
color: inherit
|
|
113
|
-
text-decoration: inherit
|
|
108
|
+
color: inherit;
|
|
109
|
+
text-decoration: inherit;
|
|
114
110
|
}
|
|
@@ -120,14 +120,26 @@
|
|
|
120
120
|
* - Handle errors gracefully in callback functions
|
|
121
121
|
* - Consider rate limiting for API calls
|
|
122
122
|
*
|
|
123
|
-
* Next.js: call init() in useEffect; call destroy() in cleanup (e.g. on unmount).
|
|
124
123
|
* SSR-safe: init/destroy no-op when window/document is undefined.
|
|
125
124
|
*
|
|
126
125
|
* @example
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
* }
|
|
126
|
+
* // Vanilla JS — plain HTML
|
|
127
|
+
* // index.html:
|
|
128
|
+
* // <div class="items"></div>
|
|
129
|
+
* // <div x-loadmore='{"functionName": "loadMoreData"}'></div>
|
|
130
|
+
* //
|
|
131
|
+
* // <script type="module">
|
|
132
|
+
* // import { loadmore } from './src/components/x/loadmore.js';
|
|
133
|
+
* // window.loadMoreData = async (page) => {
|
|
134
|
+
* // const r = await fetch(`/api/items?page=${page}`);
|
|
135
|
+
* // const items = await r.json();
|
|
136
|
+
* // const el = document.querySelector('.items');
|
|
137
|
+
* // items.forEach((item) => el.appendChild(Object.assign(document.createElement('div'), { textContent: item.name })));
|
|
138
|
+
* // return items.length > 0;
|
|
139
|
+
* // };
|
|
140
|
+
* // window.addEventListener('DOMContentLoaded', () => loadmore.init());
|
|
141
|
+
* // window.addEventListener('pagehide', () => loadmore.destroy());
|
|
142
|
+
* // </script>
|
|
131
143
|
*
|
|
132
144
|
* @author Andrey Shpigunov
|
|
133
145
|
* @version 0.3
|
|
@@ -7,9 +7,6 @@ All right reserved.
|
|
|
7
7
|
----------------------------------------*/
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
/* !- Modal windows */
|
|
11
|
-
|
|
12
|
-
|
|
13
10
|
:root {
|
|
14
11
|
--modal-margin-top: 3vw;
|
|
15
12
|
--modal-margin-bottom: 3vw;
|
|
@@ -31,18 +28,15 @@ All right reserved.
|
|
|
31
28
|
--modal-overlay-background-color: #00000066;
|
|
32
29
|
}
|
|
33
30
|
|
|
34
|
-
|
|
35
31
|
html.modal--active body {
|
|
36
32
|
overflow: hidden;
|
|
37
33
|
}
|
|
38
34
|
|
|
39
|
-
|
|
40
35
|
/* !- Modal window content */
|
|
41
36
|
[x-modal] {
|
|
42
37
|
display: none;
|
|
43
38
|
}
|
|
44
39
|
|
|
45
|
-
|
|
46
40
|
/* !- Modal wrapper */
|
|
47
41
|
.modal {
|
|
48
42
|
position: fixed;
|
|
@@ -71,7 +65,6 @@ html.modal--active body {
|
|
|
71
65
|
.modal--z9 { z-index: 10009 }
|
|
72
66
|
.modal--z10 { z-index: 10010 }
|
|
73
67
|
|
|
74
|
-
|
|
75
68
|
/* !- Overlay */
|
|
76
69
|
.modal-overlay {
|
|
77
70
|
position: absolute;
|
|
@@ -83,7 +76,6 @@ html.modal--active body {
|
|
|
83
76
|
background-color: var(--modal-overlay-background-color);
|
|
84
77
|
}
|
|
85
78
|
|
|
86
|
-
|
|
87
79
|
/* ! -Main structure */
|
|
88
80
|
.modal-outer {
|
|
89
81
|
position: relative;
|
|
@@ -104,7 +96,6 @@ html.modal--active body {
|
|
|
104
96
|
min-height: 100%;
|
|
105
97
|
}
|
|
106
98
|
|
|
107
|
-
|
|
108
99
|
/* !- Modal window */
|
|
109
100
|
.modal-window {
|
|
110
101
|
position: relative;
|
|
@@ -122,7 +113,6 @@ html.modal--active body {
|
|
|
122
113
|
border-radius: var(--modal-border-radius);
|
|
123
114
|
}
|
|
124
115
|
|
|
125
|
-
|
|
126
116
|
/* !- Close cross */
|
|
127
117
|
.modal-rail {
|
|
128
118
|
position: absolute;
|
|
@@ -187,11 +177,10 @@ html.modal--active body {
|
|
|
187
177
|
}
|
|
188
178
|
}
|
|
189
179
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
180
|
+
/*
|
|
181
|
+
!- Effects
|
|
182
|
+
https://github.com/codrops/ModalWindowEffects
|
|
183
|
+
*/
|
|
195
184
|
.modal {
|
|
196
185
|
& .modal-overlay {
|
|
197
186
|
will-change: opacity;
|
|
@@ -203,7 +192,6 @@ html.modal--active body {
|
|
|
203
192
|
}
|
|
204
193
|
}
|
|
205
194
|
|
|
206
|
-
|
|
207
195
|
/* !- Default */
|
|
208
196
|
.modal {
|
|
209
197
|
& .modal-window {
|
|
@@ -219,7 +207,6 @@ html.modal--active body {
|
|
|
219
207
|
}
|
|
220
208
|
}
|
|
221
209
|
|
|
222
|
-
|
|
223
210
|
/* !- Zoom in */
|
|
224
211
|
.modal--effect-in {
|
|
225
212
|
& .modal-window {
|
|
@@ -230,7 +217,6 @@ html.modal--active body {
|
|
|
230
217
|
}
|
|
231
218
|
}
|
|
232
219
|
|
|
233
|
-
|
|
234
220
|
/* !- Zoom out */
|
|
235
221
|
.modal--effect-out {
|
|
236
222
|
& .modal-window {
|
|
@@ -241,7 +227,6 @@ html.modal--active body {
|
|
|
241
227
|
}
|
|
242
228
|
}
|
|
243
229
|
|
|
244
|
-
|
|
245
230
|
/* !- Slide up */
|
|
246
231
|
.modal--effect-up {
|
|
247
232
|
& .modal-window {
|
|
@@ -252,7 +237,6 @@ html.modal--active body {
|
|
|
252
237
|
}
|
|
253
238
|
}
|
|
254
239
|
|
|
255
|
-
|
|
256
240
|
/* !- Slide down */
|
|
257
241
|
.modal--effect-down {
|
|
258
242
|
& .modal-window {
|
|
@@ -263,7 +247,6 @@ html.modal--active body {
|
|
|
263
247
|
}
|
|
264
248
|
}
|
|
265
249
|
|
|
266
|
-
|
|
267
250
|
/* !- Slide from left */
|
|
268
251
|
.modal--effect-left {
|
|
269
252
|
& .modal-window {
|
|
@@ -274,7 +257,6 @@ html.modal--active body {
|
|
|
274
257
|
}
|
|
275
258
|
}
|
|
276
259
|
|
|
277
|
-
|
|
278
260
|
/* !- Slide from right */
|
|
279
261
|
.modal--effect-right {
|
|
280
262
|
& .modal-window {
|
|
@@ -131,14 +131,23 @@
|
|
|
131
131
|
* - Test modal behavior with nested modals
|
|
132
132
|
* - Handle errors in event listeners gracefully
|
|
133
133
|
*
|
|
134
|
-
* Next.js: call modal.init() in useEffect; call modal.destroy() in cleanup (e.g. on unmount).
|
|
135
134
|
* SSR-safe: init/destroy and DOM methods no-op when document/window is undefined.
|
|
136
135
|
*
|
|
137
136
|
* @example
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
137
|
+
* // Vanilla JS — plain HTML
|
|
138
|
+
* // index.html:
|
|
139
|
+
* // <div x-modal="myModal" class="modal--hash" data-window-class="max800">
|
|
140
|
+
* // <h2>Title</h2>
|
|
141
|
+
* // <p>Content</p>
|
|
142
|
+
* // <button type="button" class="modal-close">Close</button>
|
|
143
|
+
* // </div>
|
|
144
|
+
* // <a href="#myModal" x-modal-open="myModal">Open</a>
|
|
145
|
+
* //
|
|
146
|
+
* // <script type="module">
|
|
147
|
+
* // import { modal } from './src/components/x/modal.js';
|
|
148
|
+
* // window.addEventListener('DOMContentLoaded', () => modal.init());
|
|
149
|
+
* // window.addEventListener('pagehide', () => modal.destroy());
|
|
150
|
+
* // </script>
|
|
142
151
|
*
|
|
143
152
|
* @author Andrey Shpigunov
|
|
144
153
|
* @version 0.3
|
|
@@ -14,12 +14,11 @@ All right reserved.
|
|
|
14
14
|
---------------------------
|
|
15
15
|
| s | m | l | xl | - main breakpoints
|
|
16
16
|
---------------------------
|
|
17
|
-
| 640 | 768 | 1024 |
|
|
17
|
+
| 640 | 768 | 1024 | 1280 | - min viewport size
|
|
18
18
|
---------------------------
|
|
19
19
|
All queries are mobile first.
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
-
|
|
23
22
|
:root {
|
|
24
23
|
/* Base variables */
|
|
25
24
|
--font-family: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif,
|
|
@@ -46,19 +45,6 @@ All right reserved.
|
|
|
46
45
|
--space-10: 6.4rem;
|
|
47
46
|
}
|
|
48
47
|
|
|
49
|
-
|
|
50
|
-
/* PostCSS custom media */
|
|
51
|
-
/* https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-custom-media */
|
|
52
|
-
|
|
53
|
-
/* Breakpoints */
|
|
54
|
-
@custom-media --small (min-width: 640px); /* Small screen [s] */
|
|
55
|
-
@custom-media --medium (min-width: 768px); /* Medium screen [m] */
|
|
56
|
-
@custom-media --large (min-width: 1024px); /* Large screen [l] */
|
|
57
|
-
@custom-media --xlarge (min-width: 1440px); /* XLarge screen [xl] */
|
|
58
|
-
/* Dark mode */
|
|
59
|
-
@custom-media --dark (prefers-color-scheme: dark);
|
|
60
|
-
|
|
61
|
-
|
|
62
48
|
html, body, main, div, span, object, iframe,
|
|
63
49
|
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
|
64
50
|
a, abbr, acronym, address, big, cite, code,
|
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
/*----------------------------------------
|
|
2
2
|
scroll.css / x
|
|
3
|
-
Scroll
|
|
3
|
+
Scroll — native CSS horizontal scroller
|
|
4
4
|
|
|
5
5
|
Created by Andrey Shpigunov at 20.03.2025
|
|
6
6
|
All right reserved.
|
|
7
7
|
----------------------------------------*/
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
/* !- Scroll - native CSS horizontal scroller */
|
|
11
|
-
|
|
12
|
-
|
|
13
10
|
/*
|
|
14
11
|
.scroll
|
|
15
12
|
.scroll--contain
|
|
@@ -17,14 +14,12 @@ All right reserved.
|
|
|
17
14
|
.scroll--x-mandatory
|
|
18
15
|
*/
|
|
19
16
|
|
|
20
|
-
|
|
21
17
|
:root {
|
|
22
18
|
--scroll-scrollbar-size: 6px;
|
|
23
19
|
--scroll-scrollbar-thumb-background: #00000011;
|
|
24
20
|
--scroll-scrollbar-thumb-background-hover: #00000022;
|
|
25
21
|
}
|
|
26
22
|
|
|
27
|
-
|
|
28
23
|
.scroll {
|
|
29
24
|
flex-wrap: nowrap;
|
|
30
25
|
overflow-x: scroll;
|
|
@@ -34,7 +29,7 @@ All right reserved.
|
|
|
34
29
|
-ms-overflow-style: none;
|
|
35
30
|
/* Hide scrollbar in Firefox */
|
|
36
31
|
scrollbar-width: none;
|
|
37
|
-
touch-action: pan-x
|
|
32
|
+
touch-action: pan-x;
|
|
38
33
|
|
|
39
34
|
&::-webkit-scrollbar {
|
|
40
35
|
width: var(--scroll-scrollbar-size);
|
|
@@ -69,13 +64,13 @@ All right reserved.
|
|
|
69
64
|
.scroll.scroll--x {
|
|
70
65
|
overflow-x: scroll;
|
|
71
66
|
overflow-y: hidden;
|
|
72
|
-
touch-action: pan-x
|
|
67
|
+
touch-action: pan-x;
|
|
73
68
|
}
|
|
74
69
|
|
|
75
70
|
.scroll.scroll--y {
|
|
76
71
|
overflow-x: hidden;
|
|
77
72
|
overflow-y: scroll;
|
|
78
|
-
touch-action: pan-y
|
|
73
|
+
touch-action: pan-y;
|
|
79
74
|
}
|
|
80
75
|
|
|
81
76
|
.scroll--contain {
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
* @example
|
|
48
48
|
* scroll.destroy();
|
|
49
49
|
*
|
|
50
|
-
* @method scrollTo
|
|
50
|
+
* @method scrollTo - Scrolls to element by id, selector, or options object.
|
|
51
51
|
* @param {string|HTMLElement|Object} params - Target element, selector, or options object.
|
|
52
52
|
* Options format:
|
|
53
53
|
* {
|
|
@@ -98,6 +98,19 @@
|
|
|
98
98
|
* - Handle errors gracefully in scroll callbacks
|
|
99
99
|
* - Consider accessibility (keyboard navigation, focus management)
|
|
100
100
|
*
|
|
101
|
+
* @example
|
|
102
|
+
* // Vanilla JS — plain HTML
|
|
103
|
+
* // index.html:
|
|
104
|
+
* // <a x-scrollto='{"target":"#section","offset":80,"hash":true,"classActive":"active"}'>Go</a>
|
|
105
|
+
* // <div style="height: 120vh"></div>
|
|
106
|
+
* // <section id="section" style="height: 50vh; border: 1px solid #ccc;">Target</section>
|
|
107
|
+
* //
|
|
108
|
+
* // <script type="module">
|
|
109
|
+
* // import { scroll } from './src/components/x/scroll.js';
|
|
110
|
+
* // window.addEventListener('DOMContentLoaded', () => scroll.init());
|
|
111
|
+
* // window.addEventListener('pagehide', () => scroll.destroy());
|
|
112
|
+
* // </script>
|
|
113
|
+
*
|
|
101
114
|
* @author Andrey Shpigunov
|
|
102
115
|
* @version 0.3
|
|
103
116
|
* @since 2025-07-18
|