main
tag: launch-2026-06-01
tag: magicmirror-v0.1.1
tag: magicmirror-v0.3.0
tag: mnw-cli-v0.1.2
tag: mnw-cli-v0.1.3
tag: mnw-cli-v0.1.4
tag: pom-v0.4.1
tag: pom-v0.4.2
tag: pom-v0.4.3
tag: pom-v0.4.4
tag: pom-v0.4.5
tag: wam-v0.3.0
tag: wam-v0.3.1
Files
Commits
Tags
Notes
Issues
Move the cart badge out of initTabs
It fetches /api/cart/count and fills the header link on every page, from
inside the one-time tab wiring. It is not tab behaviour and it is the only
reference to nav-cart-link in the tree; it sat there because initTabs was
already the thing that ran everywhere.
Its own module now, so deleting core/tabs.ts once the last hand-written strip
is described is a deletion rather than a migration.
Co-Authored-By
Claude Opus 5 (1M context) <noreply@anthropic.com>
3 files changed,
+25 insertions,
-15 deletions
18
18
import { resolveHtmxLoadingButton, withLoadingState } from './loading.ts';
19
19
import { initActionDispatcher, initAfterRequestDispatcher } from './dispatch.ts';
20
20
import { setActiveTab, initTabs } from './tabs.ts';
21
+
import { initCartBadge } from './cart-badge.ts';
21
22
import { initShowing } from './showing.ts';
22
23
import { toggleShortcutsHelp, initKeyboard } from './keyboard.ts';
23
24
import { initRestartBanner } from './restart-banner.ts';
73
74
initCopyLink();
74
75
initKeyboard();
75
76
initTabs();
77
+
initCartBadge();
76
78
initShowing();
77
79
initRestartBanner();
78
80
}
130
130
}
131
131
132
132
/** One-time tab wiring: hover preload, overflow init, hash restore, outside-
133
-
* click close, cart-count badge. Ported from mnw.js:227. */
133
+
* click close. Ported from mnw.js:227. */
134
134
export function initTabs(): void {
135
135
document.querySelectorAll<HTMLElement>('.tab').forEach((btn) => {
136
136
btn.addEventListener('mouseenter', function (this: HTMLElement) {
156
156
});
157
157
document.querySelectorAll('.tab-more-btn').forEach((b) => b.setAttribute('aria-expanded', 'false'));
158
158
});
159
-
160
-
const cartLink = document.getElementById('nav-cart-link');
161
-
if (cartLink) {
162
-
fetch('/api/cart/count', { credentials: 'same-origin' })
163
-
.then((r) => (r.ok ? r.json() : null))
164
-
.then((data: { count?: number } | null) => {
165
-
if (data && typeof data.count === 'number' && data.count > 0) {
166
-
cartLink.classList.remove('hidden');
167
-
const badge = document.getElementById('cart-badge');
168
-
if (badge) badge.textContent = ' (' + data.count + ')';
169
-
}
170
-
})
171
-
.catch(() => {});
172
-
}
173
159
}
1
+
// Cart count badge in the site header. Lived inside `initTabs()` until the
2
+
// dashboard strips became described regions and `core/tabs.ts` went away; it
3
+
// was never tab behaviour, it just ran on every page from the one place that
4
+
// already did.
5
+
6
+
/** Fill the header cart link with its item count, and reveal it when non-zero.
7
+
* Inert on pages without `#nav-cart-link` (`partials/site_header.html`). */
8
+
export function initCartBadge(): void {
9
+
const cartLink = document.getElementById('nav-cart-link');
10
+
if (!cartLink) return;
11
+
12
+
fetch('/api/cart/count', { credentials: 'same-origin' })
13
+
.then((r) => (r.ok ? r.json() : null))
14
+
.then((data: { count?: number } | null) => {
15
+
if (data && typeof data.count === 'number' && data.count > 0) {
16
+
cartLink.classList.remove('hidden');
17
+
const badge = document.getElementById('cart-badge');
18
+
if (badge) badge.textContent = ' (' + data.count + ')';
19
+
}
20
+
})
21
+
.catch(() => {});
22
+
}