T2.3 - B2: a breakpoint plan for the project switcher, not an ellipsis
"Micron EUV Cleanroom Enable 2667008" did not fit. The switcher capped the name
at 240px inside a 280px button, so the real project name was ellipsised to
"Micron EUV Clean..." on the one control whose job is to tell you which job you
are in - which is the failure this item exists to prevent.
The plan, now written into docs/reference/file-map.md so it is not re-litigated:
>= 1024px the full project NAME. Caps raised to 400px / 340px, which is
enough for a real name with no ellipsis.
< 1024px the project NUMBER alone, e.g. 2667008. Dropping the name beats
shortening it: short, stable, unambiguous.
The number is no longer prefixed to the name at wide widths. Real names already
end with their number, so the old format printed it twice - the test project
rendered as "2667008 - Micron EUV Cleanroom Enable 2667008".
The full name stays reachable at every width by three routes, none hover-only,
because the Field View is a touch surface:
- the drawer, which now shows the active project under its head, wrapping onto
as many lines as it needs and never truncated. This is the guaranteed route,
and it subscribes to ProjectData.onActiveChange so it does not go stale when
the launcher switches project without reloading.
- the switcher's title attribute, carrying the full number and name, which
surfaces on keyboard focus as well as hover.
- the switcher popover, which lists every project in full.
Crossing the breakpoint re-labels, so a resized window does not keep whichever
form was chosen at load.
Verified with the real long name at 390, 768, 1024 and 1440: nothing truncated
at any width (scrollWidth vs clientWidth, not by eye), and the drawer carries
the whole name at all four. T1.1 correctness holds - the switcher never reads
"Select a project" while a project is active.
f_items: F1-F5 FIXED, F3 still passing at all four widths with the wider
switcher. browser_check 71/71.
Wave 2 complete: one drawer on six pages, no flat strip, F2 resolved for real,
S4 closed.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -229,6 +229,35 @@ cannot decide says `INCONCLUSIVE`.
|
||||
|
||||
---
|
||||
|
||||
## The project switcher: what it shows at each width (`B2`, `T2.3`)
|
||||
|
||||
Written here because `T2.3` says to, so it is not re-litigated. Test name is always
|
||||
**"Micron EUV Cleanroom Enable 2667008"** — the real one, and the one that breaks things.
|
||||
|
||||
| Width | The app bar shows | Why |
|
||||
|---|---|---|
|
||||
| **≥ 1024px** | the full project **name** | There is room. The cap is raised to 400px (button) / 340px (name) so a real name fits without an ellipsis. |
|
||||
| **< 1024px** | the project **number** alone, e.g. `2667008` | Short, stable, unambiguous. Dropping the name entirely beats shortening it to "Micron EUV Clean…" on the one control whose job is to tell you which job you are in. |
|
||||
|
||||
The number is not prefixed to the name at wide widths. Real project names already end
|
||||
with their number, so `2667008 — Micron EUV Cleanroom Enable 2667008` printed it twice.
|
||||
|
||||
**The full name is reachable at every width by three routes**, none of them hover-only
|
||||
(Field View is a touch surface — `C1`):
|
||||
|
||||
1. **The drawer** — `.wp-sidenav-proj`, under the drawer head, on every page. Wraps onto
|
||||
as many lines as it needs and is never truncated. This is the guaranteed one.
|
||||
2. **The switcher's `title`** — the full `number — name`, so it surfaces on hover *and*
|
||||
on keyboard focus.
|
||||
3. **The switcher popover** — every project is listed with its full name and number.
|
||||
|
||||
The ellipsis is kept only as a backstop for a name longer than anything real. Verified
|
||||
at 390, 768, 1024 and 1440: no truncation at any of them, and the drawer carries the
|
||||
whole name at all four.
|
||||
|
||||
`T1.1` correctness is preserved — with a project active the switcher never reads
|
||||
"Select a project"; with none active it reads exactly that at every width.
|
||||
|
||||
## Discrepancies
|
||||
|
||||
Things the plan asserts that the repo contradicts. Listed per T0.1's fourth done-when.
|
||||
|
||||
@@ -90,6 +90,13 @@
|
||||
text-transform: uppercase;
|
||||
color: var(--wpc-fg-dim);
|
||||
}
|
||||
/* B2. These two caps are the "does not fit 280px" the review measured: a real name
|
||||
ran past 240px and was ellipsised on the one control whose job is to say which job
|
||||
you are in. Above 1024px the bar has the room, so the caps are raised until a real
|
||||
project name fits — "Micron EUV Cleanroom Enable 2667008" is the one to test with.
|
||||
Below 1024px the label is the project number instead (see wp-chrome.js), which is
|
||||
short enough that these caps never bite. The ellipsis stays only as a backstop for
|
||||
a name longer than anything real. */
|
||||
.wpc-proj-name {
|
||||
display: block;
|
||||
font-weight: 600;
|
||||
@@ -98,6 +105,10 @@
|
||||
text-overflow: ellipsis;
|
||||
max-width: 240px;
|
||||
}
|
||||
@media (min-width: 1024px) {
|
||||
.wpc-proj-btn { max-width: 400px; }
|
||||
.wpc-proj-name { max-width: 340px; }
|
||||
}
|
||||
.wpc-caret { flex: 0 0 auto; align-self: flex-end; margin-bottom: 3px; font-size: 10px;
|
||||
line-height: 1; color: var(--wpc-fg-dim); }
|
||||
|
||||
|
||||
@@ -67,10 +67,31 @@
|
||||
try { return (window.ProjectData && ProjectData.getActive()) || null; } catch (e) { return null; }
|
||||
}
|
||||
|
||||
// B2 breakpoint plan. "Micron EUV Cleanroom Enable 2667008" does not fit the bar,
|
||||
// and an ellipsis at every width gives you "Micron EUV Clean…" on the one control
|
||||
// whose job is to tell you which job you are in. So the bar drops the name rather
|
||||
// than shortening it: below 1024px it shows the project NUMBER alone, which is
|
||||
// short, stable and unambiguous. The full name is never more than a hover, a focus
|
||||
// or the drawer away — see projectTitle() and the drawer head.
|
||||
// Documented in docs/reference/file-map.md.
|
||||
var WIDE = '(min-width: 1024px)';
|
||||
function isWide() {
|
||||
try { return window.matchMedia(WIDE).matches; } catch (e) { return true; }
|
||||
}
|
||||
function projectLabel(p) {
|
||||
if (!p) return 'Select a project';
|
||||
var n = p.name || '(unnamed)';
|
||||
return p.number ? (p.number + ' — ' + n) : n;
|
||||
if (!p.number) return n; // no number to fall back to
|
||||
// Wide: the name, which is what people recognise, and which usually carries the
|
||||
// number inside it anyway ("Micron EUV Cleanroom Enable 2667008") — prefixing the
|
||||
// number there printed it twice. Narrow: the number alone.
|
||||
return isWide() ? n : p.number;
|
||||
}
|
||||
// Always the whole thing, whatever the bar is showing.
|
||||
function projectTitle(p) {
|
||||
if (!p) return 'Select a project';
|
||||
var n = p.name || '(unnamed)';
|
||||
return (p.number ? (p.number + ' — ' + n) : n) + ' — switch project';
|
||||
}
|
||||
|
||||
// Switching project reloads the current page with ?project=<id>. Every page
|
||||
@@ -146,8 +167,18 @@
|
||||
var c = activeProject();
|
||||
var nameEl = btn.querySelector('.wpc-proj-name');
|
||||
if (nameEl) nameEl.textContent = projectLabel(c);
|
||||
// The full name stays reachable at every width, by hover and by keyboard focus.
|
||||
btn.title = projectTitle(c);
|
||||
if (!pop.hidden) render();
|
||||
};
|
||||
// Crossing the breakpoint has to re-label, or a resized window keeps whichever
|
||||
// form was picked at load.
|
||||
try {
|
||||
var mq = window.matchMedia(WIDE);
|
||||
var onChange = function () { wrap.wpcRefresh(); };
|
||||
if (mq.addEventListener) mq.addEventListener('change', onChange);
|
||||
else if (mq.addListener) mq.addListener(onChange);
|
||||
} catch (e) {}
|
||||
return wrap;
|
||||
}
|
||||
|
||||
|
||||
@@ -51,6 +51,24 @@
|
||||
.wp-sidenav-head .wp-logo-chip{ flex: 0 0 auto; }
|
||||
.wp-sidenav-title{ font-size: 13px; font-weight: 600; line-height: 1.25; }
|
||||
.wp-sidenav-title span{ display: block; font-size: 11px; font-weight: 400; color: #a8a8a8; }
|
||||
|
||||
/* The active project, in full (B2). Below 1024px the app bar shows the project
|
||||
number alone, so this is where the whole name has to be readable — it wraps on
|
||||
as many lines as it needs and is never truncated. */
|
||||
.wp-sidenav-proj{
|
||||
padding: 12px 14px; border-bottom: 1px solid #393939; flex: 0 0 auto;
|
||||
display: flex; flex-direction: column; gap: 2px;
|
||||
}
|
||||
.wp-sidenav-proj[hidden]{ display: none; }
|
||||
.wp-sidenav-proj-k{
|
||||
font-size: 10px; font-weight: 600; letter-spacing: .08em;
|
||||
text-transform: uppercase; color: #a8a8a8;
|
||||
}
|
||||
.wp-sidenav-proj strong{
|
||||
font-size: 13px; font-weight: 600; line-height: 1.3; color: #f4f4f4;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
.wp-sidenav-proj-n{ font-size: 11px; color: #c6c6c6; }
|
||||
.wp-sidenav-close{
|
||||
margin-left: auto; width: 32px; height: 32px; padding: 0; flex: 0 0 auto;
|
||||
background: none; border: none; border-radius: 0; color: #c6c6c6;
|
||||
|
||||
@@ -142,6 +142,10 @@
|
||||
'<span class="wp-sidenav-title">Work Package Suite<span>Prime Controls</span></span>' +
|
||||
'<button type="button" class="wp-sidenav-close" title="Close" aria-label="Close navigation">✕</button>' +
|
||||
'</div>' +
|
||||
// The active project in full, wrapped rather than truncated. Below 1024px the
|
||||
// app bar shows the project NUMBER alone (B2), so this is where the whole name
|
||||
// is always readable. It is also the only place it is guaranteed to fit.
|
||||
'<div class="wp-sidenav-proj" id="wp-sidenav-proj"></div>' +
|
||||
'<div class="wp-sidenav-body">' + rows + '</div>' +
|
||||
'<div class="wp-sidenav-foot">' +
|
||||
(who ? '<div class="wp-sidenav-who">Signed in as<strong>' + esc(who) + '</strong></div>' : '') +
|
||||
@@ -167,6 +171,28 @@
|
||||
});
|
||||
document.body.appendChild(scrim);
|
||||
document.body.appendChild(drawer);
|
||||
paintProject();
|
||||
// Selecting a project on the launcher does not reload, so subscribe rather than
|
||||
// paint once — the same single source T1.1 established.
|
||||
try {
|
||||
if (window.ProjectData && ProjectData.onActiveChange) {
|
||||
ProjectData.onActiveChange(paintProject);
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
// Full name, never abbreviated. Absent rather than empty when no project is active,
|
||||
// so the drawer does not carry a stray blank band.
|
||||
function paintProject() {
|
||||
var box = document.getElementById('wp-sidenav-proj');
|
||||
if (!box) return;
|
||||
var p = null;
|
||||
try { p = (window.ProjectData && ProjectData.getActive && ProjectData.getActive()) || null; } catch (e) {}
|
||||
if (!p || !(p.name || p.number)) { box.innerHTML = ''; box.hidden = true; return; }
|
||||
box.hidden = false;
|
||||
box.innerHTML = '<span class="wp-sidenav-proj-k">Project</span>' +
|
||||
'<strong>' + esc(p.name || '(unnamed)') + '</strong>' +
|
||||
(p.number ? '<span class="wp-sidenav-proj-n">' + esc(p.number) + '</span>' : '');
|
||||
}
|
||||
|
||||
function focusables() {
|
||||
|
||||
Reference in New Issue
Block a user