maverick-wave 5.19.0 → 5.21.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.
@@ -126,7 +126,7 @@ The classes that mean something _other_ than "on" keep their own names:
126
126
  | Component | State class |
127
127
  | -------------------------------------------- | -------------------------------------------------------- |
128
128
  | Anything switchable, "on" | `mw-active` (`active` deprecated) |
129
- | Burger button + navbar drawer | `open` (no prefix) |
129
+ | Burger button + navbar panel | `open` (no prefix), plus `mw-nav-open` on `<body>` |
130
130
  | Stepper indicator / label / connector / step | `mw-active`, `mw-done` |
131
131
  | Checkbox list item (`li`) | `mw-selected` |
132
132
  | Calendar day, picked | `mw-selected` |
@@ -347,8 +347,10 @@ export class FaqComponent {
347
347
 
348
348
  ## Header with mobile navigation
349
349
 
350
- The drawer needs `open` on **both** the burger button and the navbar. Close it
351
- on every navigation.
350
+ The panel needs `open` on **both** the burger button and the navbar, plus
351
+ `mw-nav-open` on the `<body>` - the scrim, the scroll lock and the rules that
352
+ hold the bar and the burger in place all key off that one class, and nothing in
353
+ the template can reach the body element. Close it on every navigation.
352
354
 
353
355
  ```ts
354
356
  @Component({
@@ -406,8 +408,11 @@ on every navigation.
406
408
  })
407
409
  export class HeaderComponent {
408
410
  protected readonly menuOpen = signal(false);
411
+ private readonly body = inject(DOCUMENT).body;
409
412
 
410
413
  constructor(router: Router) {
414
+ effect(() => this.body.classList.toggle('mw-nav-open', this.menuOpen()));
415
+
411
416
  router.events
412
417
  .pipe(
413
418
  filter((e) => e instanceof NavigationEnd),
@@ -50,7 +50,7 @@ accordion FAQ.
50
50
  </div>
51
51
 
52
52
  <div class="mw-header-actions">
53
- <!-- Four links: mw-navbar-medium, so the drawer kicks in one
53
+ <!-- Four links: mw-navbar-medium, so the panel takes over one
54
54
  breakpoint later than the bare navbar would -->
55
55
  <nav class="mw-navbar mw-navbar-medium">
56
56
  <ul class="mw-navbar-list">
@@ -30,7 +30,7 @@ classes are the entire contract.
30
30
  | Accordion | Toggles `mw-active` on `mw-accordion-header` and the following `mw-accordion-content`, and writes `aria-expanded` when the header is a `<button>` | `[class.mw-active]="isOpen()"` and `[attr.aria-expanded]="isOpen()"` on the header, `mw-active` on the panel |
31
31
  | Tabs | `data-tab` → panel `id`; sets `mw-active` on nav item and panel, and wires the whole tablist: `role`, `aria-selected`, `aria-controls`, `aria-labelledby`, a roving `tabindex` and arrow/Home/End keys | Track the selected index/key, bind `mw-active` on both; drop `data-tab` |
32
32
  | Modal | `data-mw-modal="<id>"` on a trigger opens that modal; a click on `mw-modal-close` closes the `<dialog>` it sits in, or clears `mw-modal-open` on an overlay div | A `<dialog>` needs a directive calling `showModal()` - `[open]` only opens it non-modally. See `examples/angular-services.md` |
33
- | Mobile nav | Toggles `open` on `mw-menu-btn` and `mw-navbar`, writes `aria-expanded` when the button is a `<button>`, closes on anchor click and on Escape (focus returns to the button) | One signal, bound to both; reset it on navigation end |
33
+ | Mobile nav | Toggles `open` on `mw-menu-btn` and `mw-navbar` plus `mw-nav-open` on `<body>`, writes `aria-expanded` when the button is a `<button>`, closes on anchor click and on Escape (focus returns to the button) | One signal, bound to all three - the body class carries the scrim, the scroll lock and the pinning of the bar; reset it on navigation end |
34
34
  | Scroll spy | Sets `mw-active` on `mw-navbar-link` from the scroll position | Router-based: `routerLinkActive="mw-active"` |
35
35
  | Anchor scrolling | Intercepts `a[href^="#"]` and runs its own eased scroll - duration scales with distance, capped at 1.4s, cancelled by wheel or touch. Lands on `scroll-padding-top`, moves focus to the target, writes the hash with `replaceState`, and measures a sticky target unpinned | The router; for in-page anchors `scrollIntoView({ behavior: 'smooth' })` or your own animation |
36
36
  | Theme toggle | `localStorage['mw-theme']`, toggles `mw-theme-light` / `mw-theme-dark` on `<body>` and `mw-active` on the toggle, wrapped in `mw-theme-switching` on `<html>` so the flip starts no transitions. With nothing stored it takes `prefers-color-scheme` and keeps following it | A theme service - see `examples/angular-services.md` |
@@ -106,10 +106,21 @@ its children are styled through descendant selectors:
106
106
  - **Collapse breakpoint follows the item count**: default (1-3 items) collapses
107
107
  at `md`, `mw-navbar-medium` (4-5) at `lg`, `mw-navbar-large` (6+) at `xl`.
108
108
  Pick the class by how many links you have.
109
- - Below the breakpoint the list is hidden and `mw-menu-btn` appears. Opening the
110
- drawer means adding `open` to **both** `mw-menu-btn` and `mw-navbar`, and
111
- setting `aria-expanded` on the button - below the breakpoint it is the only
112
- route to the navigation, so it has to be a real `<button>`, not a `<div>`.
109
+ - Below the breakpoint the list becomes a panel under the bar, full width, and
110
+ `mw-menu-btn` appears. Opening it means `open` on **both** `mw-menu-btn` and
111
+ `mw-navbar`, `mw-nav-open` on the `<body>`, and `aria-expanded` on the button -
112
+ below the breakpoint it is the only route to the navigation, so it has to be a
113
+ real `<button>`, not a `<div>`.
114
+ - `mw-nav-open` is the state the scrim, the scroll lock and the rules that hold
115
+ the bar and the burger in place all key off. A class the script sets, not
116
+ `:has(.mw-navbar.open)`: the burger is the control that closes the panel, and
117
+ it cannot wait for a selector that has to re-match the document from a class
118
+ change several levels down. Forget it and the panel opens without a scrim, the
119
+ page behind it still scrolls, and on a `mw-header-reveal` bar the burger sits a
120
+ header height below the panel it belongs to.
121
+ - The rows stack and run the full width of the panel. From `sm` they turn into a
122
+ wrapping row of pills, so a wide screen below the collapse breakpoint does not
123
+ get a tall band with four links in its left corner.
113
124
  - The active link carries `mw-active` (bare `active` still works but is
114
125
  deprecated).
115
126
  - `mw-profile-btn` is the signed-in pill, next to or instead of the login button:
@@ -138,7 +149,7 @@ same height as the login and burger buttons.
138
149
  rides it in over the first 420px of scroll - for a page that opens on a
139
150
  full-bleed hero and wants nothing on top of it. It animates `top` and not a
140
151
  transform, because a transform on the header would make it the containing block
141
- of the off-canvas drawer inside it, at every value including the resting one.
152
+ for anything fixed inside it, at every value including the resting one.
142
153
  A fixed `mw-announcement` rides along without a class of its own - both cover
143
154
  the height of the pair, so they arrive as one block rather than the ribbon
144
155
  catching up. Focus inside either brings both back regardless of the scroll
@@ -152,9 +163,10 @@ login button, the burger - holds it in place while the bar rides in behind it:
152
163
  it travels the bar's own distance the other way, so it waits at the exact
153
164
  position it will hold in the arrived bar and nothing jumps at the end. On a
154
165
  narrow screen that is what puts the burger on the hero before the bar exists.
155
- Opening the drawer brings the bar in with it, because the drawer hangs off the
156
- header and would otherwise sit a header height too high. One consequence: the
157
- bar loses its fade as soon as one of these is on it, since a group's opacity
166
+ Opening the panel brings the bar in with it and parks the keep controls back on
167
+ their own positions - the panel hangs off the bar, and the burger is the X the
168
+ moment the panel is out, so it has to sit where the burger sat. One consequence:
169
+ the bar loses its fade as soon as one of these is on it, since a group's opacity
158
170
  cannot be taken back by a child.
159
171
 
160
172
  ```html
package/CHANGELOG.md CHANGED
@@ -6,6 +6,18 @@ Patch releases are only for test purposes - here I only document major and minor
6
6
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
7
7
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
8
8
 
9
+ ## [5.21.0] - 2026-09-19
10
+
11
+ ### Fixed
12
+
13
+ - mobile navigation - close button
14
+
15
+ ## [5.20.0] - 2026-09-18
16
+
17
+ ### Added
18
+
19
+ - new mobile navigation
20
+
9
21
  ## [5.19.0] - 2026-09-17
10
22
 
11
23
  ### Fixed
package/README.md CHANGED
@@ -45,12 +45,12 @@ The result is a framework that balances utility with simplicity, offering develo
45
45
  <title>My MaverickWave Project</title>
46
46
  <link
47
47
  rel="stylesheet"
48
- href="https://cdn.jsdelivr.net/npm/maverick-wave@5.19.0/maverick-wave.min.css"
48
+ href="https://cdn.jsdelivr.net/npm/maverick-wave@5.21.0/maverick-wave.min.css"
49
49
  />
50
50
  </head>
51
51
  <body>
52
52
  <!-- Your content here -->
53
- <script src="https://cdn.jsdelivr.net/npm/maverick-wave@5.19.0/maverick-wave.min.js"></script>
53
+ <script src="https://cdn.jsdelivr.net/npm/maverick-wave@5.21.0/maverick-wave.min.js"></script>
54
54
  </body>
55
55
  </html>
56
56
  ```
@@ -261,7 +261,7 @@ Everything that fills a surface with one of the six colours reads the matching
261
261
  token: buttons and mini buttons, the burger button, table and panel headers,
262
262
  card badges and ribbons, segmented and tab items, stepper dots, calendar
263
263
  selection, timeline dates, accordion headers and progress labels. The burger
264
- button switches to `--mw-secondary-accent-text-color` while the drawer is open,
264
+ button switches to `--mw-secondary-accent-text-color` while the panel is open,
265
265
  because its surface does the same - `--mw-header-burgerbutton-color` and
266
266
  `--mw-header-burgerbutton-open-color` override the two states individually.
267
267