fix(web): paint session row highlight as one chip including the menu
Selected and hover fill stay on the whole row. The title and ⋯ no longer draw their own canvas or radius, so they stop looking like two controls (BUG-993, recurrence of BUG-024).
This commit is contained in:
+1
-1
@@ -357,7 +357,7 @@ The birth-time rectification session is the consultation transcript plus a house
|
||||
- **States:** default, hover, current, focus, disabled.
|
||||
- **Hierarchy:** section labels stay tertiary; session titles and primary actions use ink so history rows do not collapse into the same gray as “收藏对话 / 历史对话”. History groups use the overline token for “今天 / 昨天 / 最近 7 天 / 最近 30 天 / 更早”. When the chart is not the account holder, a secondary line shows the chart name under the title. A session title is named when it is created; opening a stored session must not rename it. `updatedAt` advances only on conversation activity, including rectification turns, choice, adopt, and stop. Opening, refresh, and metadata PATCH do not bump it. A `?c=` that is not on the loaded page is looked up with `GET /api/sessions/{id}` before anyone may say it was deleted. Locked by `frontend/tests/session-open-preserves-identity.test.ts` and `frontend/tests/session-lookup-unlisted.test.ts`.
|
||||
- **Request behavior:** existing sessions remain selectable for reading while a request is active; creating or sending another request stays locked until the active request settles.
|
||||
- **Surface:** translucent warm-gray sidebar; current uses a white glass surface and deep-brown marker.
|
||||
- **Surface:** translucent warm-gray sidebar. Current and hover fill the whole `.session-row` — title and the ⋯ share one chip. The menu trigger has no canvas of its own.
|
||||
|
||||
### Sidebar shell
|
||||
|
||||
|
||||
@@ -816,10 +816,10 @@ button:disabled { cursor: default; opacity: .45; }
|
||||
.sidebar-empty { margin: 0; padding: 0 0 var(--space-2); color: var(--color-ink-tertiary); font-size: var(--type-caption); line-height: 1.35; }
|
||||
/* Visual chip stays 32px; wrap gap is 8px, so a 44px overlay would overlap. */
|
||||
.session-list { min-height: 0; display: flex; flex-direction: column; gap: var(--space-1); }
|
||||
.session-row { position: relative; display: grid; grid-template-columns: minmax(0, 1fr) 44px; align-items: center; border-radius: var(--radius-lg); color: var(--sidebar-foreground); transition: background-color 120ms ease-out, box-shadow 120ms ease-out, color 120ms ease-out; }
|
||||
.session-row { position: relative; display: grid; grid-template-columns: minmax(0, 1fr) 44px; align-items: stretch; overflow: hidden; border-radius: var(--radius-lg); color: var(--sidebar-foreground); transition: background-color 120ms ease-out, box-shadow 120ms ease-out, color 120ms ease-out; }
|
||||
.session-row:hover, .session-row:focus-within { background: var(--sidebar-accent); color: var(--sidebar-accent-foreground); }
|
||||
.session-row:has(.session-main[data-active="true"]) { background: var(--sidebar-accent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--sidebar-ring) 22%, transparent); color: var(--sidebar-accent-foreground); }
|
||||
.session-main { position: relative; width: 100%; min-height: 44px; display: grid; gap: 2px; padding: var(--space-2); border: 0; border-radius: var(--radius-md); background: transparent; color: inherit; cursor: pointer; text-align: left; text-decoration: none; transition: background-color 120ms ease-out, color 120ms ease-out, transform 120ms ease-out; }
|
||||
.session-main { position: relative; width: 100%; min-height: 44px; display: grid; gap: 2px; padding: var(--space-2); border: 0; border-radius: 0; background: transparent; color: inherit; cursor: pointer; text-align: left; text-decoration: none; transition: color 120ms ease-out, transform 120ms ease-out; }
|
||||
.session-main[data-active="true"] { color: var(--sidebar-accent-foreground); background: transparent; }
|
||||
.session-main[data-active="true"]::before { position: absolute; border-radius: 3px; content: ""; top: var(--space-3); bottom: var(--space-3); left: 0; width: 2px; background: var(--sidebar-ring); }
|
||||
/* Read-only rows (the secondary pages) render no menu trigger, so the 44px
|
||||
@@ -852,10 +852,10 @@ button:disabled { cursor: default; opacity: .45; }
|
||||
.sidebar-group-label { display: flex; align-items: center; gap: 5px; margin: var(--space-2) 0 var(--space-1); color: var(--color-ink-tertiary); font-size: var(--type-overline); font-weight: 500; letter-spacing: .02em; }
|
||||
.sidebar-group-label > svg { flex: 0 0 auto; color: var(--color-action); }
|
||||
.session-list-sentinel { height: 1px; }
|
||||
.session-menu-trigger { width: 44px; height: 44px; display: grid; place-items: center; justify-self: center; padding: 0; border: 0; border-radius: 0; background: transparent; color: inherit; cursor: pointer; opacity: .64; transition: background-color 120ms ease-out, color 120ms ease-out, opacity 120ms ease-out, transform 120ms ease-out; }
|
||||
.session-menu-trigger { width: 44px; min-height: 44px; align-self: stretch; display: grid; place-items: center; justify-self: stretch; padding: 0; border: 0; border-radius: 0; background: transparent; color: inherit; cursor: pointer; opacity: .64; transition: color 120ms ease-out, opacity 120ms ease-out; }
|
||||
.session-menu-trigger > svg { width: 18px; height: 18px; }
|
||||
.session-row:hover .session-menu-trigger, .session-row:focus-within .session-menu-trigger, .session-menu-trigger[aria-expanded="true"] { opacity: 1; }
|
||||
.session-menu-trigger:hover, .session-menu-trigger[aria-expanded="true"] { background: var(--color-canvas); color: var(--color-ink); }
|
||||
.session-menu-trigger:hover, .session-menu-trigger[aria-expanded="true"] { background: transparent; color: inherit; }
|
||||
.session-actions-positioner { z-index: 30; max-width: calc(100vw - var(--space-6)); max-height: calc(100dvh - var(--space-6)); outline: 0; }
|
||||
.session-actions { min-width: 176px; max-height: var(--available-height); overflow-y: auto; display: grid; gap: var(--space-1); padding: var(--space-2); border: 1px solid var(--sidebar-border); border-radius: var(--radius-xl); background: var(--color-canvas); box-shadow: var(--shadow-elevated); transform-origin: var(--transform-origin); transition: opacity 120ms ease-out, transform 120ms var(--ease-out); }
|
||||
.session-actions[data-starting-style], .session-actions[data-ending-style] { opacity: 0; transform: translateY(var(--space-1)) scale(.98); }
|
||||
|
||||
@@ -494,10 +494,18 @@ test("nests sidebar lists under one heading scale without an archive toggle", ()
|
||||
|
||||
test("renders each session title and menu as one unified row surface", () => {
|
||||
assert.match(cssBlock(".session-row"), /grid-template-columns:\s*minmax\(0,\s*1fr\)\s+44px/);
|
||||
assert.match(cssBlock(".session-row"), /overflow:\s*hidden/);
|
||||
assert.match(globalStyles, /\.session-row:has\(\.session-main\[data-active="true"\]\)[^{]*\{[^}]*background:\s*var\(--sidebar-accent\)/);
|
||||
assert.match(cssBlock(".session-main"), /border-radius:\s*0/);
|
||||
assert.match(cssBlock('.session-main[data-active="true"]'), /background:\s*transparent/);
|
||||
assert.match(cssBlock(".session-menu-trigger"), /border-radius:\s*0/);
|
||||
assert.match(cssBlock(".session-menu-trigger"), /align-self:\s*stretch/);
|
||||
assert.match(cssBlock(".session-menu-trigger"), /min-height:\s*44px/);
|
||||
assert.doesNotMatch(cssBlock(".session-menu-trigger"), /border-radius:\s*50%/);
|
||||
assert.doesNotMatch(cssBlock(".session-menu-trigger"), /(?<!min-)height:\s*44px/);
|
||||
const triggerHover = cssBlock(".session-menu-trigger:hover, .session-menu-trigger[aria-expanded=\"true\"]");
|
||||
assert.match(triggerHover, /background:\s*transparent/);
|
||||
assert.doesNotMatch(triggerHover, /--color-canvas/);
|
||||
});
|
||||
|
||||
test("styles the non-mobile collapsed rail without repeated session rows", () => {
|
||||
|
||||
Reference in New Issue
Block a user