Tab layout: no side shade on phones; a disabled tab looks disabled
- The closed phone drawer casts no shadow. Parked off-screen at translateX(-100%), its 28px blur still darkened the start edge of every map (measured at 390: the left 30px about 22 luminance levels darker than with the shadow off, a repeat shot identical). The shadow now belongs to the open drawer only; in Arabic the same rule covers the drawer parked off the right edge. - A row with disabled (a desktop-only map on a phone, e.g. Big Picture) renders greyed, with aria-disabled and a not-allowed cursor; its badge keeps its accent colour. pick() is unchanged, so the consumer still receives the click and can say why the row does not open. Both CSS copies change identically.
This commit is contained in:
parent
86a9ee66c1
commit
a88ae76aeb
1 changed files with 20 additions and 6 deletions
|
|
@ -186,8 +186,9 @@
|
|||
<div class="vtl-rows" v-show="!grp.folder || !isFolderClosed(grp)">
|
||||
<button
|
||||
v-for="row in grp.rows" :key="row.key" type="button" role="tab"
|
||||
class="vtl-tab" :class="{ active: row.key === active }"
|
||||
class="vtl-tab" :class="{ active: row.key === active, disabled: row.disabled }"
|
||||
:aria-selected="String(row.key === active)"
|
||||
:aria-disabled="row.disabled ? 'true' : null"
|
||||
:tabindex="row.key === active ? 0 : -1"
|
||||
:ref="el => registerTab(row.key, el)"
|
||||
@click="pick(row.key)" @keydown="onKey($event)">
|
||||
|
|
@ -210,8 +211,9 @@
|
|||
<template v-else>
|
||||
<button
|
||||
v-for="row in items" :key="row.key" type="button" role="tab"
|
||||
class="vtl-tab" :class="{ active: row.key === active }"
|
||||
class="vtl-tab" :class="{ active: row.key === active, disabled: row.disabled }"
|
||||
:aria-selected="String(row.key === active)"
|
||||
:aria-disabled="row.disabled ? 'true' : null"
|
||||
:tabindex="row.key === active ? 0 : -1"
|
||||
:ref="el => registerTab(row.key, el)"
|
||||
@click="pick(row.key)" @keydown="onKey($event)">
|
||||
|
|
@ -402,6 +404,10 @@ const VTL_SHADOW_CSS = `
|
|||
.vtl-tab:hover { background:var(--vtl-accented); color:#3b463d; }
|
||||
.vtl-tab:focus-visible { outline:2px solid var(--vtl-accent); outline-offset:-2px; }
|
||||
.vtl-tab.active { background:var(--vtl-accented); color:#3b463d; font-weight:500; }
|
||||
/* A DISABLED ROW (row.disabled, e.g. a desktop-only map on a phone) stays in the rail, greyed, with its badge
|
||||
still readable. The click still reaches the consumer, so it can say WHY the row does not open. */
|
||||
.vtl-tab.disabled, .vtl-tab.disabled:hover { background:none; color:#a3a8a4; cursor:not-allowed; }
|
||||
.vtl-tab.disabled .vtl-tab-ic, .vtl-tab.disabled .vtl-tab-emoji, .vtl-tab.disabled .vtl-tab-fallback { opacity:.45; }
|
||||
.vtl-tab.active .vtl-tab-ic { color:var(--vtl-accent); }
|
||||
.vtl-tab-ic { flex:0 0 auto; display:inline-flex; color:var(--vtl-muted); }
|
||||
.vtl-tab-ic svg { width:20px; height:20px; }
|
||||
|
|
@ -505,13 +511,15 @@ const VTL_SHADOW_CSS = `
|
|||
/* MOBILE = the SAME composited-transform model, taken to its full-off-canvas extreme: a full-width
|
||||
drawer that slides in/out via transform (never a layout property), so opening/closing the drawer
|
||||
never reflows the content. Content is full-width (left:0) and stays put; the drawer floats over it. */
|
||||
.vtl-nav { z-index:20; width:256px; box-shadow:0 0 28px rgba(0,0,0,.55); transform:translateX(-100%); }
|
||||
/* NO SHADOW WHILE CLOSED: parked at translateX(-100%), a 28px blur still bleeds into the screen along the start
|
||||
edge (measured at 390: the left 30px ~22 luminance levels darker). The shadow belongs to the OPEN drawer only. */
|
||||
.vtl-nav { z-index:20; width:256px; box-shadow:none; transform:translateX(-100%); }
|
||||
/* OPEN DRAWER ABOVE THE PLUGIN'S OWN LAYERS. Mounted content shares this stacking context, and
|
||||
plugins raise their chrome (the research dashboard's filter bar is z-index:55), so at z-index 20
|
||||
the open drawer had a plugin's filter row painted across it — measured 2026-09-25 at 390px.
|
||||
Only while OPEN on a phone: that is when the drawer is the one thing you can use, and desktop
|
||||
and plugin modal scrims keep their existing order. */
|
||||
.vtl.nav-open .vtl-nav { transform:translateX(0); z-index:1000; }
|
||||
.vtl.nav-open .vtl-nav { transform:translateX(0); z-index:1000; box-shadow:0 0 28px rgba(0,0,0,.55); }
|
||||
.vtl-main { left:0; }
|
||||
/* The desktop slim-rail collapse has no meaning on a phone — reconcileForWidth() clears railCollapsed
|
||||
at this width, but neutralize its CSS too (belt-and-suspenders) so a full labelled drawer always
|
||||
|
|
@ -968,6 +976,10 @@ export default defineComponent({
|
|||
.vtl-tab:hover { background:var(--vtl-accented); color:#3b463d; }
|
||||
.vtl-tab:focus-visible { outline:2px solid var(--vtl-accent); outline-offset:-2px; }
|
||||
.vtl-tab.active { background:var(--vtl-accented); color:#3b463d; font-weight:500; }
|
||||
/* A DISABLED ROW (row.disabled, e.g. a desktop-only map on a phone) stays in the rail, greyed, with its badge
|
||||
still readable. The click still reaches the consumer, so it can say WHY the row does not open. */
|
||||
.vtl-tab.disabled, .vtl-tab.disabled:hover { background:none; color:#a3a8a4; cursor:not-allowed; }
|
||||
.vtl-tab.disabled .vtl-tab-ic, .vtl-tab.disabled .vtl-tab-emoji, .vtl-tab.disabled .vtl-tab-fallback { opacity:.45; }
|
||||
.vtl-tab.active .vtl-tab-ic { color:var(--vtl-accent); }
|
||||
.vtl-tab-ic { flex:0 0 auto; display:inline-flex; color:var(--vtl-muted); }
|
||||
.vtl-tab-ic svg { width:20px; height:20px; }
|
||||
|
|
@ -1071,13 +1083,15 @@ export default defineComponent({
|
|||
/* MOBILE = the SAME composited-transform model, taken to its full-off-canvas extreme: a full-width
|
||||
drawer that slides in/out via transform (never a layout property), so opening/closing the drawer
|
||||
never reflows the content. Content is full-width (left:0) and stays put; the drawer floats over it. */
|
||||
.vtl-nav { z-index:20; width:256px; box-shadow:0 0 28px rgba(0,0,0,.55); transform:translateX(-100%); }
|
||||
/* NO SHADOW WHILE CLOSED: parked at translateX(-100%), a 28px blur still bleeds into the screen along the start
|
||||
edge (measured at 390: the left 30px ~22 luminance levels darker). The shadow belongs to the OPEN drawer only. */
|
||||
.vtl-nav { z-index:20; width:256px; box-shadow:none; transform:translateX(-100%); }
|
||||
/* OPEN DRAWER ABOVE THE PLUGIN'S OWN LAYERS. Mounted content shares this stacking context, and
|
||||
plugins raise their chrome (the research dashboard's filter bar is z-index:55), so at z-index 20
|
||||
the open drawer had a plugin's filter row painted across it — measured 2026-09-25 at 390px.
|
||||
Only while OPEN on a phone: that is when the drawer is the one thing you can use, and desktop
|
||||
and plugin modal scrims keep their existing order. */
|
||||
.vtl.nav-open .vtl-nav { transform:translateX(0); z-index:1000; }
|
||||
.vtl.nav-open .vtl-nav { transform:translateX(0); z-index:1000; box-shadow:0 0 28px rgba(0,0,0,.55); }
|
||||
.vtl-main { left:0; }
|
||||
/* The desktop slim-rail collapse has no meaning on a phone — reconcileForWidth() clears railCollapsed
|
||||
at this width, but neutralize its CSS too (belt-and-suspenders) so a full labelled drawer always
|
||||
|
|
|
|||
Loading…
Reference in a new issue