fix: anchor overdue badge to icon via runtime wrapper (#56)
Root cause: the badge was `position: absolute` relative to the entire
`.nav-item`, which stretches to `flex: 1` on mobile (up to ~75 px wide).
With `right: 4px` the badge sat far from the icon on the bottom bar and
overlapped label text in the expanded desktop sidebar.
Fix: `updateOverdueBadge()` now wraps the nav icon in a
`.nav-item__icon-wrap` span (created once, reused on subsequent calls).
The badge is appended there instead of to the nav item root.
CSS changes:
- Remove `.nav-item .nav-badge` positional override
- Add `.nav-item__icon-wrap { position: relative; display: inline-flex }`
- Add `.nav-item__icon-wrap .nav-badge { position: absolute; top: -4px; right: -4px }`
The badge now consistently overlays the top-right corner of the icon
across all nav layouts (mobile column, collapsed sidebar row, expanded
sidebar row with label).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Regular → Executable
+14
-2
@@ -827,11 +827,23 @@ function updateOverdueBadge() {
|
|||||||
|
|
||||||
document.querySelectorAll('[data-route="/tasks"] .nav-badge').forEach((el) => el.remove());
|
document.querySelectorAll('[data-route="/tasks"] .nav-badge').forEach((el) => el.remove());
|
||||||
if (overdue > 0) {
|
if (overdue > 0) {
|
||||||
document.querySelectorAll('[data-route="/tasks"]').forEach((el) => {
|
document.querySelectorAll('[data-route="/tasks"]').forEach((navItem) => {
|
||||||
|
let anchor = navItem.querySelector('.nav-item__icon-wrap');
|
||||||
|
if (!anchor) {
|
||||||
|
const icon = navItem.querySelector('.nav-item__icon');
|
||||||
|
anchor = document.createElement('span');
|
||||||
|
anchor.className = 'nav-item__icon-wrap';
|
||||||
|
if (icon) {
|
||||||
|
icon.replaceWith(anchor);
|
||||||
|
anchor.appendChild(icon);
|
||||||
|
} else {
|
||||||
|
navItem.prepend(anchor);
|
||||||
|
}
|
||||||
|
}
|
||||||
const badge = document.createElement('span');
|
const badge = document.createElement('span');
|
||||||
badge.className = 'nav-badge';
|
badge.className = 'nav-badge';
|
||||||
badge.textContent = String(overdue);
|
badge.textContent = String(overdue);
|
||||||
el.appendChild(badge);
|
anchor.appendChild(badge);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Regular → Executable
+9
-3
@@ -196,10 +196,16 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-item .nav-badge {
|
.nav-item__icon-wrap {
|
||||||
|
position: relative;
|
||||||
|
display: inline-flex;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-item__icon-wrap .nav-badge {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: var(--space-1);
|
top: -4px;
|
||||||
right: var(--space-1);
|
right: -4px;
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user