maverick-wave 3.3.1 → 3.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.
@@ -109,9 +109,6 @@
109
109
 
110
110
  &.open {
111
111
  background: var(--mw-secondary-color);
112
- position: fixed;
113
- top: 14px;
114
- right: 6%;
115
112
  z-index: z-index('header') + 10;
116
113
 
117
114
  &:hover {
@@ -165,56 +162,144 @@
165
162
  }
166
163
  }
167
164
 
168
- @mixin navbar-open-state {
165
+ // Header bar height: 42px logo + 2 × spacing('3') padding + 1px border.
166
+ // Overridable via --mw-header-height for projects with a taller bar.
167
+ $_header-height: 59px;
168
+
169
+ // Off-canvas drawer for the collapsed navbar (mobile only)
170
+ @mixin navbar-off-canvas {
171
+ position: fixed;
172
+ top: 0;
173
+ right: 0;
174
+ --mw-navbar-drawer-width: 250px;
175
+ width: var(--mw-navbar-drawer-width);
176
+ height: 100dvh;
177
+ background: var(--mw-header-background);
178
+ border-left: 1px solid var(--mw-header-border);
179
+ box-shadow: -10px 0 30px var(--mw-shadow);
180
+ z-index: z-index('header') + 3;
181
+
182
+ transform: translateX(100%);
183
+ visibility: hidden;
184
+ transition:
185
+ transform 0.3s cubic-bezier(0.32, 0.72, 0, 1),
186
+ visibility 0.3s;
187
+
188
+ .mw-navbar-list {
189
+ display: flex;
190
+ flex-direction: column;
191
+ align-items: stretch;
192
+ gap: spacing('1');
193
+ height: 100%;
194
+ overflow-y: auto;
195
+ // Keeps a rubber-band scroll inside the panel from moving the page
196
+ overscroll-behavior: contain;
197
+ padding: calc(
198
+ var(--mw-header-height, #{$_header-height}) + #{spacing('6')} +
199
+ env(safe-area-inset-top)
200
+ )
201
+ spacing('4') calc(#{spacing('6')} + env(safe-area-inset-bottom));
202
+ }
203
+
204
+ .mw-navbar-item {
205
+ width: 100%;
206
+ margin: spacing('0');
207
+ opacity: 0;
208
+ transform: translateX(12px);
209
+ }
210
+
211
+ .mw-navbar-link {
212
+ display: flex;
213
+ align-items: center;
214
+ min-height: 48px;
215
+ width: 100%;
216
+ padding: spacing('3') spacing('4');
217
+ border-radius: radius('md');
218
+ font-size: font-size('md');
219
+ text-align: left;
220
+ color: var(--mw-header-text-color);
221
+
222
+ // The sliding underline is a hover affordance and has no place on touch
223
+ &::after {
224
+ display: none;
225
+ }
226
+
227
+ // Restated here: the plain color above already outranks the base
228
+ &:hover {
229
+ color: var(--mw-header-navbar-list-active-color);
230
+ background: var(--mw-primary-background);
231
+ }
232
+
233
+ &:active {
234
+ background: var(--mw-primary-background-hover);
235
+ }
236
+
237
+ // Last, so the current page keeps its look while being hovered
238
+ &.active {
239
+ color: var(--mw-header-navbar-list-active-color);
240
+ background: var(--mw-primary-background);
241
+ box-shadow: inset 3px 0 0 var(--mw-primary-color);
242
+ font-weight: font-weight('medium');
243
+ }
244
+ }
245
+
169
246
  &.open {
170
- position: fixed;
171
- top: 0;
172
- right: 0;
173
- width: 80%;
174
- max-width: 280px;
175
- height: 100dvh;
176
- background: var(--mw-header-background);
177
247
  transform: translateX(0);
178
- transition: transform 0.3s ease;
179
- z-index: z-index('header') + 3;
180
- border-left: 1px solid var(--mw-header-border);
248
+ visibility: visible;
181
249
 
182
- .mw-navbar-list {
183
- display: flex;
184
- flex-direction: column;
185
- align-items: flex-start;
186
- gap: spacing('0');
187
- padding-top: 80px;
188
- padding-left: spacing('3');
189
- padding-right: spacing('3');
190
- height: 100%;
191
- overflow-y: auto;
250
+ // Items follow the panel in, slightly staggered
251
+ .mw-navbar-item {
252
+ animation: mw-navbar-item-in 0.3s ease forwards;
253
+
254
+ @for $i from 1 through 10 {
255
+ &:nth-child(#{$i}) {
256
+ animation-delay: 0.1s + $i * 0.035s;
257
+ }
258
+ }
192
259
  }
260
+ }
261
+
262
+ @media (prefers-reduced-motion: reduce) {
263
+ transition-duration: 0.01ms;
193
264
 
194
265
  .mw-navbar-item {
195
- width: 100%;
196
- margin: spacing('0');
266
+ opacity: 1;
267
+ transform: none;
268
+ animation: none;
197
269
  }
270
+ }
271
+ }
198
272
 
199
- .mw-navbar-link {
200
- display: block;
201
- padding: spacing('3') spacing('0');
202
- border-bottom: 1px solid var(--mw-header-border);
203
- width: 100%;
204
- text-align: left;
205
-
206
- &::after {
207
- display: none;
208
- }
273
+ // Page scrim behind the drawer
274
+ @mixin navbar-scrim($navbar-selector) {
275
+ body:has(#{$navbar-selector}.open) {
276
+ overflow: hidden;
209
277
 
210
- &.active {
211
- color: var(--mw-header-navbar-list-active-color);
212
- font-weight: font-weight('medium');
213
- }
278
+ &::after {
279
+ content: '';
280
+ position: fixed;
281
+ inset: 0;
282
+ background: var(--mw-overlay-background);
283
+ backdrop-filter: blur(2px);
284
+ z-index: z-index('header') - 1;
285
+ animation: mw-navbar-scrim-in 0.3s ease;
214
286
  }
215
287
  }
216
288
  }
217
289
 
290
+ @keyframes mw-navbar-item-in {
291
+ to {
292
+ opacity: 1;
293
+ transform: translateX(0);
294
+ }
295
+ }
296
+
297
+ @keyframes mw-navbar-scrim-in {
298
+ from {
299
+ opacity: 0;
300
+ }
301
+ }
302
+
218
303
  // Navbar with built-in auto-detection
219
304
  .mw-navbar {
220
305
  display: flex;
@@ -279,36 +364,37 @@
279
364
  // Auto-responsive behavior based on nav item count
280
365
  // Default behavior (1-3 items): collapse at md
281
366
  @include media-down('md') {
282
- .mw-navbar-list {
283
- display: none;
284
- }
285
-
286
- @include navbar-open-state;
367
+ @include navbar-off-canvas;
287
368
  }
288
369
 
289
370
  // Medium (4-5 items): collapse at lg
290
371
  &.mw-navbar-medium {
291
372
  @include media-down('lg') {
292
- .mw-navbar-list {
293
- display: none;
294
- }
295
-
296
- @include navbar-open-state;
373
+ @include navbar-off-canvas;
297
374
  }
298
375
  }
299
376
 
300
377
  // Large (6+ items): collapse at xl
301
378
  &.mw-navbar-large {
302
379
  @include media-down('xl') {
303
- .mw-navbar-list {
304
- display: none;
305
- }
306
-
307
- @include navbar-open-state;
380
+ @include navbar-off-canvas;
308
381
  }
309
382
  }
310
383
  }
311
384
 
385
+ // Every variant is collapsed at md, so the default selector covers them all
386
+ @include media-down('md') {
387
+ @include navbar-scrim('.mw-navbar');
388
+ }
389
+
390
+ @include media-down('lg') {
391
+ @include navbar-scrim('.mw-navbar-medium');
392
+ }
393
+
394
+ @include media-down('xl') {
395
+ @include navbar-scrim('.mw-navbar-large');
396
+ }
397
+
312
398
  // Show burger button based on navbar size
313
399
  .mw-navbar {
314
400
  // Default (1-3 items): show burger at md
@@ -76,3 +76,22 @@
76
76
  align-items: stretch;
77
77
  }
78
78
  }
79
+
80
+ // Align self — the per-item counterpart to .mw-items-*
81
+ .mw-self {
82
+ &-start {
83
+ align-self: flex-start;
84
+ }
85
+
86
+ &-end {
87
+ align-self: flex-end;
88
+ }
89
+
90
+ &-center {
91
+ align-self: center;
92
+ }
93
+
94
+ &-stretch {
95
+ align-self: stretch;
96
+ }
97
+ }
@@ -1,7 +1,15 @@
1
+ @use 'sass:map';
1
2
  @use '../abstracts' as *;
2
3
 
4
+ $_margin-values: map.merge(
5
+ $spacing,
6
+ (
7
+ 'auto': auto,
8
+ )
9
+ );
10
+
3
11
  // Margin utilities
4
- @each $key, $value in $spacing {
12
+ @each $key, $value in $_margin-values {
5
13
  .mw-m-#{$key} {
6
14
  margin: $value;
7
15
  }
@@ -35,46 +43,44 @@
35
43
 
36
44
  // Padding utilities
37
45
  @each $key, $value in $spacing {
38
- .mw-p-#{$key} {
39
- padding: $value;
40
- }
46
+ @if $value >= 0 {
47
+ .mw-p-#{$key} {
48
+ padding: $value;
49
+ }
41
50
 
42
- .mw-pt-#{$key} {
43
- padding-top: $value;
44
- }
51
+ .mw-pt-#{$key} {
52
+ padding-top: $value;
53
+ }
45
54
 
46
- .mw-pb-#{$key} {
47
- padding-bottom: $value;
48
- }
55
+ .mw-pb-#{$key} {
56
+ padding-bottom: $value;
57
+ }
49
58
 
50
- .mw-pl-#{$key} {
51
- padding-left: $value;
52
- }
59
+ .mw-pl-#{$key} {
60
+ padding-left: $value;
61
+ }
53
62
 
54
- .mw-pr-#{$key} {
55
- padding-right: $value;
56
- }
63
+ .mw-pr-#{$key} {
64
+ padding-right: $value;
65
+ }
57
66
 
58
- .mw-px-#{$key} {
59
- padding-left: $value;
60
- padding-right: $value;
61
- }
67
+ .mw-px-#{$key} {
68
+ padding-left: $value;
69
+ padding-right: $value;
70
+ }
62
71
 
63
- .mw-py-#{$key} {
64
- padding-top: $value;
65
- padding-bottom: $value;
72
+ .mw-py-#{$key} {
73
+ padding-top: $value;
74
+ padding-bottom: $value;
75
+ }
66
76
  }
67
77
  }
68
78
 
69
- // Gap utilities (positive values only — negative gap is invalid CSS)
79
+ // Gap utilities
70
80
  @each $key, $value in $spacing {
71
81
  @if $value >= 0 {
72
82
  .mw-gap-#{$key} {
73
83
  gap: $value;
74
-
75
- @include media-down('sm') {
76
- gap: calc($value * 0.75);
77
- }
78
84
  }
79
85
  }
80
86
  }