@andreyshpigunov/x 0.3.89 → 0.4.0
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/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 +20 -24
- 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 +40 -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 +7 -8
- package/src/css/x.css +191 -213
- package/src/js/app.js +8 -8
- 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
|
@@ -44,10 +44,11 @@
|
|
|
44
44
|
*
|
|
45
45
|
* Breakpoints:
|
|
46
46
|
*
|
|
47
|
-
* -
|
|
48
|
-
* -
|
|
49
|
-
* -
|
|
50
|
-
* -
|
|
47
|
+
* - xs (xsmall): >= 0px
|
|
48
|
+
* - s (small): >= 640px
|
|
49
|
+
* - m (medium): >= 768px
|
|
50
|
+
* - l (large): >= 1024px
|
|
51
|
+
* - xl (xlarge): >= 1280px
|
|
51
52
|
*
|
|
52
53
|
* Public API:
|
|
53
54
|
*
|
|
@@ -61,8 +62,9 @@
|
|
|
61
62
|
* @property {boolean} touch - true if touch support is available
|
|
62
63
|
* @property {number} width - Current window width in pixels
|
|
63
64
|
* @property {number} height - Current window height in pixels
|
|
64
|
-
* @property {string} breakpoint - Current responsive breakpoint: 's', 'm', 'l', or 'xl'
|
|
65
|
+
* @property {string} breakpoint - Current responsive breakpoint: 'xs', 's', 'm', 'l', or 'xl'
|
|
65
66
|
* @property {Object} size - Boolean flags for each breakpoint:
|
|
67
|
+
* - size.xs - true if xsmall breakpoint
|
|
66
68
|
* - size.s - true if small breakpoint
|
|
67
69
|
* - size.m - true if medium breakpoint
|
|
68
70
|
* - size.l - true if large breakpoint
|
|
@@ -70,9 +72,8 @@
|
|
|
70
72
|
*
|
|
71
73
|
* @method init() - Initializes or re-initializes detection, CSS classes, and resize listeners.
|
|
72
74
|
* Safe to call multiple times. Automatically cleans up previous state.
|
|
73
|
-
* @method destroy() - Removes listeners and CSS classes. Use when unmounting (
|
|
75
|
+
* @method destroy() - Removes listeners and CSS classes. Use when unmounting (page change / removing DOM).
|
|
74
76
|
*
|
|
75
|
-
* Next.js: call init() in useEffect() on client; optionally call destroy() in cleanup on route change.
|
|
76
77
|
* SSR-safe: constructor/init/destroy no-op or safe when window is undefined.
|
|
77
78
|
*
|
|
78
79
|
* @event window.breakpointchange - Fired when the responsive breakpoint changes.
|
|
@@ -99,11 +100,13 @@
|
|
|
99
100
|
* }
|
|
100
101
|
*
|
|
101
102
|
* @example
|
|
102
|
-
* //
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
103
|
+
* // Vanilla JS — plain HTML
|
|
104
|
+
* // index.html:
|
|
105
|
+
* // <script type="module">
|
|
106
|
+
* // import { device } from './src/components/x/device.js';
|
|
107
|
+
* // window.addEventListener('DOMContentLoaded', () => device.init());
|
|
108
|
+
* // window.addEventListener('breakpointchange', (e) => console.log(e.detail));
|
|
109
|
+
* // </script>
|
|
107
110
|
*
|
|
108
111
|
* @author Andrey Shpigunov
|
|
109
112
|
* @version 0.7
|
|
@@ -119,10 +122,11 @@ const CLASSES_TO_REMOVE = [
|
|
|
119
122
|
];
|
|
120
123
|
|
|
121
124
|
const SIZE_FLAGS = {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
125
|
+
xs: { xs: true, s: false, m: false, l: false, xl: false },
|
|
126
|
+
s: { xs: false, s: true, m: false, l: false, xl: false },
|
|
127
|
+
m: { xs: false, s: false, m: true, l: false, xl: false },
|
|
128
|
+
l: { xs: false, s: false, m: false, l: true, xl: false },
|
|
129
|
+
xl: { xs: false, s: false, m: false, l: false, xl: true }
|
|
126
130
|
};
|
|
127
131
|
|
|
128
132
|
export class Device {
|
|
@@ -135,8 +139,8 @@ export class Device {
|
|
|
135
139
|
this.touch = false;
|
|
136
140
|
this.width = 0;
|
|
137
141
|
this.height = 0;
|
|
138
|
-
this.breakpoint = '
|
|
139
|
-
this.size = SIZE_FLAGS.
|
|
142
|
+
this.breakpoint = 'xs';
|
|
143
|
+
this.size = SIZE_FLAGS.xs;
|
|
140
144
|
this._html = null;
|
|
141
145
|
this._onResize = this._onResize.bind(this);
|
|
142
146
|
this._debouncedResize = lib.debounce(this._onResize, 200);
|
|
@@ -147,7 +151,7 @@ export class Device {
|
|
|
147
151
|
this.width = window.innerWidth;
|
|
148
152
|
this.height = window.innerHeight;
|
|
149
153
|
this.breakpoint = this._getBreakpointName(this.width);
|
|
150
|
-
this.size = SIZE_FLAGS[this.breakpoint] || SIZE_FLAGS.
|
|
154
|
+
this.size = SIZE_FLAGS[this.breakpoint] || SIZE_FLAGS.xs;
|
|
151
155
|
this._html = document.documentElement;
|
|
152
156
|
}
|
|
153
157
|
|
|
@@ -168,7 +172,7 @@ export class Device {
|
|
|
168
172
|
}
|
|
169
173
|
|
|
170
174
|
/**
|
|
171
|
-
* Removes listeners and CSS classes. Use when unmounting (
|
|
175
|
+
* Removes listeners and CSS classes. Use when unmounting (page change / removing DOM).
|
|
172
176
|
*/
|
|
173
177
|
destroy() {
|
|
174
178
|
if (typeof window === 'undefined') return;
|
|
@@ -188,30 +192,32 @@ export class Device {
|
|
|
188
192
|
/**
|
|
189
193
|
* Returns a breakpoint name based on current width.
|
|
190
194
|
* Breakpoint map:
|
|
191
|
-
* -
|
|
192
|
-
* -
|
|
193
|
-
* -
|
|
194
|
-
* -
|
|
195
|
+
* - xs: ≥0px and <640px
|
|
196
|
+
* - s: ≥640px and <768px
|
|
197
|
+
* - m: ≥768px and <1024px
|
|
198
|
+
* - l: ≥1024px and <1280px
|
|
199
|
+
* - xl: ≥1280px
|
|
195
200
|
*
|
|
196
201
|
* @param {number} width - Current viewport width
|
|
197
|
-
* @return {'s'|'m'|'l'|'xl'}
|
|
202
|
+
* @return {'xs'|'s'|'m'|'l'|'xl'}
|
|
198
203
|
* @private
|
|
199
204
|
*/
|
|
200
205
|
_getBreakpointName(width) {
|
|
201
|
-
if (width >=
|
|
202
|
-
if (width >=
|
|
203
|
-
if (width >=
|
|
204
|
-
return 's';
|
|
206
|
+
if (width >= 1280) return 'xl';
|
|
207
|
+
if (width >= 1024) return 'l';
|
|
208
|
+
if (width >= 768) return 'm';
|
|
209
|
+
if (width >= 640) return 's';
|
|
210
|
+
return 'xs';
|
|
205
211
|
}
|
|
206
212
|
|
|
207
213
|
/**
|
|
208
214
|
* Converts breakpoint string into boolean flags for convenience.
|
|
209
|
-
* @param {'s'|'m'|'l'|'xl'} bp - Breakpoint name
|
|
210
|
-
* @return {{s:boolean,m:boolean,l:boolean,xl:boolean}}
|
|
215
|
+
* @param {'xs'|'s'|'m'|'l'|'xl'} bp - Breakpoint name
|
|
216
|
+
* @return {{xs:boolean,s:boolean,m:boolean,l:boolean,xl:boolean}}
|
|
211
217
|
* @private
|
|
212
218
|
*/
|
|
213
219
|
_getSizeFlags(bp) {
|
|
214
|
-
return SIZE_FLAGS[bp] || SIZE_FLAGS.
|
|
220
|
+
return SIZE_FLAGS[bp] || SIZE_FLAGS.xs;
|
|
215
221
|
}
|
|
216
222
|
|
|
217
223
|
/**
|
|
@@ -229,7 +235,7 @@ export class Device {
|
|
|
229
235
|
this.width = w;
|
|
230
236
|
this.height = h;
|
|
231
237
|
this.breakpoint = next;
|
|
232
|
-
this.size = SIZE_FLAGS[next] || SIZE_FLAGS.
|
|
238
|
+
this.size = SIZE_FLAGS[next] || SIZE_FLAGS.xs;
|
|
233
239
|
|
|
234
240
|
if (prev !== next) {
|
|
235
241
|
window.dispatchEvent(new CustomEvent('breakpointchange', {
|
|
@@ -21,7 +21,6 @@ All right reserved.
|
|
|
21
21
|
--dropdown-divider-color: var(--color-grey);
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
|
|
25
24
|
[x-dropdown] {
|
|
26
25
|
display: none;
|
|
27
26
|
list-style: none;
|
|
@@ -47,8 +46,8 @@ All right reserved.
|
|
|
47
46
|
pointer-events: none;
|
|
48
47
|
overscroll-behavior: contain;
|
|
49
48
|
|
|
50
|
-
@media (
|
|
51
|
-
--dropdown-max-width
|
|
49
|
+
@media (min-width: 768px) {
|
|
50
|
+
max-width: calc(var(--dropdown-max-width) * 1.2);
|
|
52
51
|
}
|
|
53
52
|
|
|
54
53
|
& > li {
|
|
@@ -10,9 +10,7 @@
|
|
|
10
10
|
*
|
|
11
11
|
* - `dropdown.init()` – Initializes all dropdown menus in the DOM.
|
|
12
12
|
* - `dropdown.closeAllDropdowns()` – Closes all open dropdown menus.
|
|
13
|
-
* - `dropdown.destroy()` – Full teardown (listeners + global). Use on SPA unmount /
|
|
14
|
-
*
|
|
15
|
-
* Next.js: call init() in useEffect() on client; call destroy() in cleanup (e.g. on unmount or route change).
|
|
13
|
+
* - `dropdown.destroy()` – Full teardown (listeners + global). Use on SPA unmount / page change.
|
|
16
14
|
* SSR-safe: init/destroy no-op when document is undefined.
|
|
17
15
|
*
|
|
18
16
|
* Usage:
|
|
@@ -97,11 +95,20 @@
|
|
|
97
95
|
* - Screen reader friendly
|
|
98
96
|
*
|
|
99
97
|
* @example
|
|
100
|
-
* //
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
98
|
+
* // Vanilla JS — plain HTML
|
|
99
|
+
* // index.html:
|
|
100
|
+
* // <div class="dropdown">
|
|
101
|
+
* // <button x-dropdown-open>Menu</button>
|
|
102
|
+
* // <ul x-dropdown>
|
|
103
|
+
* // <li><a href="#" role="menuitem">Item 1</a></li>
|
|
104
|
+
* // <li><a href="#" role="menuitem">Item 2</a></li>
|
|
105
|
+
* // </ul>
|
|
106
|
+
* // </div>
|
|
107
|
+
* //
|
|
108
|
+
* // <script type="module">
|
|
109
|
+
* // import { dropdown } from './src/components/x/dropdown.js';
|
|
110
|
+
* // window.addEventListener('DOMContentLoaded', () => dropdown.init());
|
|
111
|
+
* // </script>
|
|
105
112
|
*
|
|
106
113
|
* @author Andrey Shpigunov
|
|
107
114
|
* @version 0.2
|
|
@@ -553,7 +560,7 @@ class Dropdown {
|
|
|
553
560
|
}
|
|
554
561
|
|
|
555
562
|
/**
|
|
556
|
-
* Full teardown: cleanup and remove global listener. Use on SPA unmount
|
|
563
|
+
* Full teardown: cleanup and remove global listener. Use on SPA unmount / page change.
|
|
557
564
|
* SSR-safe: no-op when document is undefined.
|
|
558
565
|
*/
|
|
559
566
|
destroy() {
|
|
@@ -6,54 +6,36 @@ Created by Andrey Shpigunov at 20.03.2025
|
|
|
6
6
|
All right reserved.
|
|
7
7
|
----------------------------------------*/
|
|
8
8
|
|
|
9
|
-
|
|
10
9
|
/*
|
|
11
|
-
.flex
|
|
12
|
-
|
|
13
|
-
.flex.fr (m,l,xl) - flex row
|
|
14
|
-
.flex.fc (m,l,xl) - flex column
|
|
15
|
-
.flex.fw (m,l,xl) - flex wrap
|
|
16
|
-
.flex.fnw (m,l,xl) - flex nowrap
|
|
17
|
-
|
|
18
|
-
.flex.ais (m,l,xl) - stretch
|
|
19
|
-
.flex.aifs (m,l,xl) - flex start
|
|
20
|
-
.flex.aic (m,l,xl) - center
|
|
21
|
-
.flex.aife (m,l,xl) - flex end
|
|
22
|
-
|
|
23
|
-
.flex.jcfs (m,l,xl) - flex start
|
|
24
|
-
.flex.jcc (m,l,xl) - center
|
|
25
|
-
.flex.jcfe (m,l,xl) - flex end
|
|
26
|
-
.flex.jcsb (m,l,xl) - space between
|
|
27
|
-
.flex.jcsa (m,l,xl) - space around
|
|
28
|
-
.flex.jcse (m,l,xl) - space evenly
|
|
29
|
-
|
|
30
|
-
.flex > .c[1-12]/[1-12] (m,l,xl) - column width "column/columns"
|
|
31
|
-
*/
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
.flex {
|
|
35
|
-
display: flex;
|
|
36
|
-
|
|
37
|
-
&.fr { flex-direction: row }
|
|
38
|
-
&.fc { flex-direction: column }
|
|
39
|
-
&.fw { flex-wrap: wrap }
|
|
40
|
-
&.fnw { flex-wrap: nowrap }
|
|
10
|
+
.flex (s,m,l,xl)
|
|
41
11
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
12
|
+
.flex.fr (s,m,l,xl) - flex row
|
|
13
|
+
.flex.fc (s,m,l,xl) - flex column
|
|
14
|
+
.flex.fw (s,m,l,xl) - flex wrap
|
|
15
|
+
.flex.fnw (s,m,l,xl) - flex nowrap
|
|
46
16
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
&.jcsa { justify-content: space-around }
|
|
52
|
-
&.jcse { justify-content: space-evenly }
|
|
17
|
+
.flex.ais (s,m,l,xl) - stretch
|
|
18
|
+
.flex.aifs (s,m,l,xl) - flex start
|
|
19
|
+
.flex.aic (s,m,l,xl) - center
|
|
20
|
+
.flex.aife (s,m,l,xl) - flex end
|
|
53
21
|
|
|
54
|
-
|
|
55
|
-
|
|
22
|
+
.flex.jcfs (s,m,l,xl) - flex start
|
|
23
|
+
.flex.jcc (s,m,l,xl) - center
|
|
24
|
+
.flex.jcfe (s,m,l,xl) - flex end
|
|
25
|
+
.flex.jcsb (s,m,l,xl) - space between
|
|
26
|
+
.flex.jcsa (s,m,l,xl) - space around
|
|
27
|
+
.flex.jcse (s,m,l,xl) - space evenly
|
|
56
28
|
|
|
29
|
+
.flex > .c[1-12]/[1-12] (s,m,l,xl) - column width "column/columns"
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
.flex { display: flex }
|
|
33
|
+
@media (min-width: 640px) { .s\:flex { display: flex } }
|
|
34
|
+
@media (min-width: 768px) { .m\:flex { display: flex } }
|
|
35
|
+
@media (min-width: 1024px) { .l\:flex { display: flex } }
|
|
36
|
+
@media (min-width: 1280px) { .xl\:flex { display: flex } }
|
|
37
|
+
|
|
38
|
+
[class*=flex] {
|
|
57
39
|
/* Columns */
|
|
58
40
|
@for $cols from 1 to 12 {
|
|
59
41
|
@for $col from 1 to $cols {
|
|
@@ -64,28 +46,18 @@ All right reserved.
|
|
|
64
46
|
}
|
|
65
47
|
}
|
|
66
48
|
|
|
67
|
-
@media (
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
&.m\:jcfs { justify-content: flex-start }
|
|
80
|
-
&.m\:jcc { justify-content: center }
|
|
81
|
-
&.m\:jcfe { justify-content: flex-end }
|
|
82
|
-
&.m\:jcsb { justify-content: space-between }
|
|
83
|
-
&.m\:jcsa { justify-content: space-around }
|
|
84
|
-
&.m\:jcse { justify-content: space-evenly }
|
|
85
|
-
|
|
86
|
-
& > .m\:noshrink { flex-shrink: 0 }
|
|
87
|
-
& > .m\:nogrow { flex-grow: 0 }
|
|
88
|
-
|
|
49
|
+
@media (min-width: 640px) {
|
|
50
|
+
@for $cols from 1 to 12 {
|
|
51
|
+
@for $col from 1 to $cols {
|
|
52
|
+
& > .s\:c$(col)\/$(cols) {
|
|
53
|
+
flex-basis: calc($(col) / $(cols) * 100%);
|
|
54
|
+
max-width: calc($(col) / $(cols) * 100%);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
@media (min-width: 768px) {
|
|
89
61
|
@for $cols from 1 to 12 {
|
|
90
62
|
@for $col from 1 to $cols {
|
|
91
63
|
& > .m\:c$(col)\/$(cols) {
|
|
@@ -96,28 +68,7 @@ All right reserved.
|
|
|
96
68
|
}
|
|
97
69
|
}
|
|
98
70
|
|
|
99
|
-
@media (
|
|
100
|
-
|
|
101
|
-
&.l\:fr { flex-direction: row }
|
|
102
|
-
&.l\:fc { flex-direction: column }
|
|
103
|
-
&.l\:fw { flex-wrap: wrap }
|
|
104
|
-
&.l\:fnw { flex-wrap: nowrap }
|
|
105
|
-
|
|
106
|
-
&.l\:ais { align-items: stretch }
|
|
107
|
-
&.l\:aifs { align-items: flex-start }
|
|
108
|
-
&.l\:aic { align-items: center }
|
|
109
|
-
&.l\:aife { align-items: flex-end }
|
|
110
|
-
|
|
111
|
-
&.l\:jcfs { justify-content: flex-start }
|
|
112
|
-
&.l\:jcc { justify-content: center }
|
|
113
|
-
&.l\:jcfe { justify-content: flex-end }
|
|
114
|
-
&.l\:jcsb { justify-content: space-between }
|
|
115
|
-
&.l\:jcsa { justify-content: space-around }
|
|
116
|
-
&.l\:jcse { justify-content: space-evenly }
|
|
117
|
-
|
|
118
|
-
& > .l\:noshrink { flex-shrink: 0 }
|
|
119
|
-
& > .l\:nogrow { flex-grow: 0 }
|
|
120
|
-
|
|
71
|
+
@media (min-width: 1024px) {
|
|
121
72
|
@for $cols from 1 to 12 {
|
|
122
73
|
@for $col from 1 to $cols {
|
|
123
74
|
& > .l\:c$(col)\/$(cols) {
|
|
@@ -128,28 +79,7 @@ All right reserved.
|
|
|
128
79
|
}
|
|
129
80
|
}
|
|
130
81
|
|
|
131
|
-
@media (
|
|
132
|
-
|
|
133
|
-
&.xl\:fr { flex-direction: row }
|
|
134
|
-
&.xl\:fc { flex-direction: column }
|
|
135
|
-
&.xl\:fw { flex-wrap: wrap }
|
|
136
|
-
&.xl\:fnw { flex-wrap: nowrap }
|
|
137
|
-
|
|
138
|
-
&.xl\:ais { align-items: stretch }
|
|
139
|
-
&.xl\:aifs { align-items: flex-start }
|
|
140
|
-
&.xl\:aic { align-items: center }
|
|
141
|
-
&.xl\:aife { align-items: flex-end }
|
|
142
|
-
|
|
143
|
-
&.xl\:jcfs { justify-content: flex-start }
|
|
144
|
-
&.xl\:jcc { justify-content: center }
|
|
145
|
-
&.xl\:jcfe { justify-content: flex-end }
|
|
146
|
-
&.xl\:jcsb { justify-content: space-between }
|
|
147
|
-
&.xl\:jcsa { justify-content: space-around }
|
|
148
|
-
&.xl\:jcse { justify-content: space-evenly }
|
|
149
|
-
|
|
150
|
-
& > .xl\:noshrink { flex-shrink: 0 }
|
|
151
|
-
& > .xl\:nogrow { flex-grow: 0 }
|
|
152
|
-
|
|
82
|
+
@media (min-width: 1280px) {
|
|
153
83
|
@for $cols from 1 to 12 {
|
|
154
84
|
@for $col from 1 to $cols {
|
|
155
85
|
& > .xl\:c$(col)\/$(cols) {
|
|
@@ -159,5 +89,112 @@ All right reserved.
|
|
|
159
89
|
}
|
|
160
90
|
}
|
|
161
91
|
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.fr { flex-direction: row }
|
|
95
|
+
.fc { flex-direction: column }
|
|
96
|
+
.fw { flex-wrap: wrap }
|
|
97
|
+
.fnw { flex-wrap: nowrap }
|
|
98
|
+
|
|
99
|
+
.ais { align-items: stretch }
|
|
100
|
+
.aifs { align-items: flex-start }
|
|
101
|
+
.aic { align-items: center }
|
|
102
|
+
.aife { align-items: flex-end }
|
|
103
|
+
|
|
104
|
+
.jcfs { justify-content: flex-start }
|
|
105
|
+
.jcc { justify-content: center }
|
|
106
|
+
.jcfe { justify-content: flex-end }
|
|
107
|
+
.jcsb { justify-content: space-between }
|
|
108
|
+
.jcsa { justify-content: space-around }
|
|
109
|
+
.jcse { justify-content: space-evenly }
|
|
110
|
+
|
|
111
|
+
.no-shrink { flex-shrink: 0 }
|
|
112
|
+
.no-grow { flex-grow: 0 }
|
|
113
|
+
|
|
114
|
+
@media (min-width: 640px) {
|
|
115
|
+
.s\:fr { flex-direction: row }
|
|
116
|
+
.s\:fc { flex-direction: column }
|
|
117
|
+
.s\:fw { flex-wrap: wrap }
|
|
118
|
+
.s\:fnw { flex-wrap: nowrap }
|
|
119
|
+
|
|
120
|
+
.s\:ais { align-items: stretch }
|
|
121
|
+
.s\:aifs { align-items: flex-start }
|
|
122
|
+
.s\:aic { align-items: center }
|
|
123
|
+
.s\:aife { align-items: flex-end }
|
|
124
|
+
|
|
125
|
+
.s\:jcfs { justify-content: flex-start }
|
|
126
|
+
.s\:jcc { justify-content: center }
|
|
127
|
+
.s\:jcfe { justify-content: flex-end }
|
|
128
|
+
.s\:jcsb { justify-content: space-between }
|
|
129
|
+
.s\:jcsa { justify-content: space-around }
|
|
130
|
+
.s\:jcse { justify-content: space-evenly }
|
|
131
|
+
|
|
132
|
+
.s\:no-shrink { flex-shrink: 0 }
|
|
133
|
+
.s\:no-grow { flex-grow: 0 }
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
@media (min-width: 768px) {
|
|
137
|
+
.m\:fr { flex-direction: row }
|
|
138
|
+
.m\:fc { flex-direction: column }
|
|
139
|
+
.m\:fw { flex-wrap: wrap }
|
|
140
|
+
.m\:fnw { flex-wrap: nowrap }
|
|
141
|
+
|
|
142
|
+
.m\:ais { align-items: stretch }
|
|
143
|
+
.m\:aifs { align-items: flex-start }
|
|
144
|
+
.m\:aic { align-items: center }
|
|
145
|
+
.m\:aife { align-items: flex-end }
|
|
146
|
+
|
|
147
|
+
.m\:jcfs { justify-content: flex-start }
|
|
148
|
+
.m\:jcc { justify-content: center }
|
|
149
|
+
.m\:jcfe { justify-content: flex-end }
|
|
150
|
+
.m\:jcsb { justify-content: space-between }
|
|
151
|
+
.m\:jcsa { justify-content: space-around }
|
|
152
|
+
.m\:jcse { justify-content: space-evenly }
|
|
153
|
+
|
|
154
|
+
.m\:no-shrink { flex-shrink: 0 }
|
|
155
|
+
.m\:no-grow { flex-grow: 0 }
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
@media (min-width: 1024px) {
|
|
159
|
+
.l\:fr { flex-direction: row }
|
|
160
|
+
.l\:fc { flex-direction: column }
|
|
161
|
+
.l\:fw { flex-wrap: wrap }
|
|
162
|
+
.l\:fnw { flex-wrap: nowrap }
|
|
163
|
+
|
|
164
|
+
.l\:ais { align-items: stretch }
|
|
165
|
+
.l\:aifs { align-items: flex-start }
|
|
166
|
+
.l\:aic { align-items: center }
|
|
167
|
+
.l\:aife { align-items: flex-end }
|
|
168
|
+
|
|
169
|
+
.l\:jcfs { justify-content: flex-start }
|
|
170
|
+
.l\:jcc { justify-content: center }
|
|
171
|
+
.l\:jcfe { justify-content: flex-end }
|
|
172
|
+
.l\:jcsb { justify-content: space-between }
|
|
173
|
+
.l\:jcsa { justify-content: space-around }
|
|
174
|
+
.l\:jcse { justify-content: space-evenly }
|
|
175
|
+
|
|
176
|
+
.l\:no-shrink { flex-shrink: 0 }
|
|
177
|
+
.l\:no-grow { flex-grow: 0 }
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
@media (min-width: 1280px) {
|
|
181
|
+
.xl\:fr { flex-direction: row }
|
|
182
|
+
.xl\:fc { flex-direction: column }
|
|
183
|
+
.xl\:fw { flex-wrap: wrap }
|
|
184
|
+
.xl\:fnw { flex-wrap: nowrap }
|
|
185
|
+
|
|
186
|
+
.xl\:ais { align-items: stretch }
|
|
187
|
+
.xl\:aifs { align-items: flex-start }
|
|
188
|
+
.xl\:aic { align-items: center }
|
|
189
|
+
.xl\:aife { align-items: flex-end }
|
|
190
|
+
|
|
191
|
+
.xl\:jcfs { justify-content: flex-start }
|
|
192
|
+
.xl\:jcc { justify-content: center }
|
|
193
|
+
.xl\:jcfe { justify-content: flex-end }
|
|
194
|
+
.xl\:jcsb { justify-content: space-between }
|
|
195
|
+
.xl\:jcsa { justify-content: space-around }
|
|
196
|
+
.xl\:jcse { justify-content: space-evenly }
|
|
162
197
|
|
|
198
|
+
.xl\:no-shrink { flex-shrink: 0 }
|
|
199
|
+
.xl\:no-grow { flex-grow: 0 }
|
|
163
200
|
}
|
|
@@ -6,13 +6,11 @@ Created by Andrey Shpigunov at 20.03.2025
|
|
|
6
6
|
All right reserved.
|
|
7
7
|
----------------------------------------*/
|
|
8
8
|
|
|
9
|
-
|
|
10
9
|
/*
|
|
11
10
|
.flow
|
|
12
|
-
.flow.s[0-10] (m,l,xl) - vertical space
|
|
11
|
+
.flow.s[0-10] (s,m,l,xl) - vertical space
|
|
13
12
|
*/
|
|
14
13
|
|
|
15
|
-
|
|
16
14
|
.flow {
|
|
17
15
|
|
|
18
16
|
& > * { margin: 0 }
|
|
@@ -23,7 +21,15 @@ All right reserved.
|
|
|
23
21
|
}
|
|
24
22
|
}
|
|
25
23
|
|
|
26
|
-
@media(
|
|
24
|
+
@media (min-width: 640px) {
|
|
25
|
+
@for $i from 0 to 10 {
|
|
26
|
+
&.s\:s$(i) > * {
|
|
27
|
+
margin-bottom: var(--space-$(i));
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
@media (min-width: 768px) {
|
|
27
33
|
@for $i from 0 to 10 {
|
|
28
34
|
&.m\:s$(i) > * {
|
|
29
35
|
margin-bottom: var(--space-$(i));
|
|
@@ -31,7 +37,7 @@ All right reserved.
|
|
|
31
37
|
}
|
|
32
38
|
}
|
|
33
39
|
|
|
34
|
-
@media(
|
|
40
|
+
@media (min-width: 1024px) {
|
|
35
41
|
@for $i from 0 to 10 {
|
|
36
42
|
&.l\:s$(i) > * {
|
|
37
43
|
margin-bottom: var(--space-$(i));
|
|
@@ -39,7 +45,7 @@ All right reserved.
|
|
|
39
45
|
}
|
|
40
46
|
}
|
|
41
47
|
|
|
42
|
-
@media(
|
|
48
|
+
@media (min-width: 1280px) {
|
|
43
49
|
@for $i from 0 to 10 {
|
|
44
50
|
&.xl\:s$(i) > * {
|
|
45
51
|
margin-bottom: var(--space-$(i));
|
|
@@ -80,7 +80,7 @@ select {
|
|
|
80
80
|
color: var(--form-font-color-disabled);
|
|
81
81
|
border-color: var(--form-border-color-disabled);
|
|
82
82
|
background-color: var(--form-background-color-disabled);
|
|
83
|
-
cursor: not-allowed
|
|
83
|
+
cursor: not-allowed;
|
|
84
84
|
box-shadow: none;
|
|
85
85
|
}
|
|
86
86
|
|
|
@@ -99,9 +99,9 @@ select {
|
|
|
99
99
|
|
|
100
100
|
select {
|
|
101
101
|
padding-right: calc(var(--form-side-padding) * 2.6);
|
|
102
|
-
background-image: url(
|
|
103
|
-
background-repeat: no-repeat;
|
|
102
|
+
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%23888' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' class='lucide lucide-chevrons-up-down-icon lucide-chevrons-up-down'%3E%3Cpath d='m7 15 5 5 5-5M7 9l5-5 5 5'/%3E%3C/svg%3E");
|
|
104
103
|
background-position: right calc(var(--form-side-padding) - 4px) top 52%, 0 0;
|
|
104
|
+
background-repeat: no-repeat;
|
|
105
105
|
background-size: 1.6rem;
|
|
106
106
|
}
|
|
107
107
|
|
package/src/components/x/form.js
CHANGED
|
@@ -85,7 +85,7 @@
|
|
|
85
85
|
* @example
|
|
86
86
|
* form.offUpdate('input[name="email"]');
|
|
87
87
|
*
|
|
88
|
-
* @method destroy() - Removes all update listeners and clears internal state. Use on SPA unmount /
|
|
88
|
+
* @method destroy() - Removes all update listeners and clears internal state. Use on SPA unmount / page change.
|
|
89
89
|
*
|
|
90
90
|
* @method update(selector) - Manually dispatches input/change events.
|
|
91
91
|
* @param {string} selector - CSS selector for elements.
|
|
@@ -114,14 +114,17 @@
|
|
|
114
114
|
* - Input elements and contenteditable: 'input' event
|
|
115
115
|
* - Select elements: 'change' event
|
|
116
116
|
*
|
|
117
|
-
* Next.js: call destroy() in useEffect cleanup (e.g. on unmount). All DOM methods no-op when document is undefined.
|
|
118
|
-
*
|
|
119
117
|
* @example
|
|
120
|
-
* //
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
* }
|
|
118
|
+
* // Vanilla JS — plain HTML
|
|
119
|
+
* // index.html:
|
|
120
|
+
* // <input name="email" type="email" />
|
|
121
|
+
* // <script type="module">
|
|
122
|
+
* // import { form } from './src/components/x/form.js';
|
|
123
|
+
* // window.addEventListener('DOMContentLoaded', () => {
|
|
124
|
+
* // form.onUpdate('input[name="email"]', (el) => console.log('Email:', el.value));
|
|
125
|
+
* // });
|
|
126
|
+
* // window.addEventListener('pagehide', () => form.destroy());
|
|
127
|
+
* // </script>
|
|
125
128
|
*
|
|
126
129
|
* @author Andrey Shpigunov
|
|
127
130
|
* @version 0.3
|
|
@@ -310,7 +313,7 @@ class Form {
|
|
|
310
313
|
}
|
|
311
314
|
|
|
312
315
|
/**
|
|
313
|
-
* Removes all update listeners and clears internal state. Use on SPA unmount
|
|
316
|
+
* Removes all update listeners and clears internal state. Use on SPA unmount / page change.
|
|
314
317
|
* SSR-safe: no-op when document is undefined.
|
|
315
318
|
*/
|
|
316
319
|
destroy() {
|