feat(ui): refine plan hover timing

This commit is contained in:
vyctorbrzezowski
2026-08-22 08:25:51 -03:00
parent 9285d168ad
commit acca44db5b
4 changed files with 70 additions and 8 deletions
+1
View File
@@ -238,3 +238,4 @@
2026-08-22 08:08 · Colored the completed Plan summary check with the canonical success token while leaving active and pending indicators unchanged · ui/src/components/session-progress-card.ts, ui/src/styles/chat/progress-card.css · COMPONENT #124301 multiline | BENCH
2026-08-22 08:08 · Moved a failed queue item's delivery-state pill onto the diagnostic line before its error copy without moving the row actions · ui/src/pages/chat/components/chat-composer-queue.ts, ui/src/styles/components.css · COMPONENT #124301 multiline | BENCH
2026-08-22 09:13 · Reduced the composer underlap to one precedence-ordered status lane, kept terminal interruption with the assistant transcript, and added the three mixed-state sweep fixtures · ui/src/pages/chat/chat-pane-render.ts, ui/src/pages/chat/chat-view.ts, ui/src/pages/chat/components/chat-composer-types.ts, ui/src/pages/chat/components/chat-composer-view.ts, ui/src/pages/chat/components/chat-message-group.ts, ui/src/pages/chat/components/chat-thread-interactions.ts, ui/src/pages/chat/components/chat-transcript-projection.ts, ui/src/pages/chat/components/chat-working-indicator.ts, ui/src/styles/chat/layout.css, ui/src/styles/chat/tool-cards.css, ui/src/test-helpers/composer-bench.ts · COMPONENT #124301 multiline | BENCH
2026-08-22 09:22 · Matched the Plan hover card to the 600ms open, 300ms close and 100ms fade-scale-slide interaction contract while preserving hover across the card · ui/src/components/session-progress-card.ts, ui/src/styles/chat/progress-card.css · COMPONENT #124301 multiline | BENCH
+1
View File
@@ -130,6 +130,7 @@ Local-only working ledger. Re-read after every implementation block; move an ite
- [x] Keep failed queue actions on the primary row and move the delivery-state pill before the diagnostic copy.
- [x] Enforce one precedence-ordered composer status lane and keep Interrupted with its assistant turn.
- [x] Add Interrupted + members, offline + read-only and approval + offline sweep fixtures.
- [x] Match the Plan hover card delays and 100ms fade, scale and upward-slide transition.
## Observed queue contract
@@ -7,6 +7,48 @@ import { toSanitizedMarkdownHtml } from "./markdown.ts";
type SessionProgressCardPlacement = "board" | "composer" | "hovercard" | "rail";
type ComposerProgressHoverTimers = {
open?: ReturnType<typeof setTimeout>;
close?: ReturnType<typeof setTimeout>;
};
const composerProgressHoverTimers = new WeakMap<HTMLElement, ComposerProgressHoverTimers>();
function scheduleComposerProgressOpen(event: PointerEvent) {
const root = event.currentTarget as HTMLElement;
const timers = composerProgressHoverTimers.get(root) ?? {};
if (timers.close) {
clearTimeout(timers.close);
timers.close = undefined;
}
if (root.dataset.open === "true" || timers.open) {
composerProgressHoverTimers.set(root, timers);
return;
}
timers.open = setTimeout(() => {
root.dataset.open = "true";
timers.open = undefined;
}, 600);
composerProgressHoverTimers.set(root, timers);
}
function scheduleComposerProgressClose(event: PointerEvent) {
const root = event.currentTarget as HTMLElement;
const timers = composerProgressHoverTimers.get(root) ?? {};
if (timers.open) {
clearTimeout(timers.open);
timers.open = undefined;
}
if (timers.close) {
clearTimeout(timers.close);
}
timers.close = setTimeout(() => {
root.dataset.open = "false";
timers.close = undefined;
}, 300);
composerProgressHoverTimers.set(root, timers);
}
const STATUS_LABEL_KEYS: Record<ProgressCardStep["status"], Parameters<typeof t>[0]> = {
completed: "sessionProgressCard.status.completed",
in_progress: "sessionProgressCard.status.inProgress",
@@ -138,6 +180,8 @@ export function renderSessionProgressCard(
class="session-progress-card session-progress-card--composer"
data-progress-card-placement="composer"
data-open="false"
@pointerenter=${scheduleComposerProgressOpen}
@pointerleave=${scheduleComposerProgressClose}
>
<div
class="session-progress-card__summary"
+24 -8
View File
@@ -177,10 +177,6 @@
margin-bottom: 4px;
}
.session-progress-card--composer[data-open="false"] .session-progress-card__body {
display: none;
}
.session-progress-card--rail {
flex: 0 0 auto;
margin: 10px 14px 0;
@@ -336,6 +332,26 @@
box-shadow:
0 1px 2px rgb(0 0 0 / 8%),
0 12px 32px rgb(0 0 0 / 14%);
opacity: 0;
visibility: hidden;
pointer-events: none;
transform: translateY(8px) scale(0.95);
transform-origin: center bottom;
transition:
opacity 100ms ease,
transform 100ms ease,
visibility 0ms linear 100ms;
}
.session-progress-card--composer[data-open="true"] .session-progress-card__body {
opacity: 1;
visibility: visible;
pointer-events: auto;
transform: translateY(0) scale(1);
transition:
opacity 100ms ease,
transform 100ms ease,
visibility 0ms linear 0ms;
}
.session-progress-card--composer .session-progress-card__heading {
@@ -476,10 +492,6 @@
justify-self: center;
}
.session-progress-card--composer:hover .session-progress-card__body {
display: block;
}
.session-progress-card__summary:hover {
background: color-mix(
in srgb,
@@ -507,4 +519,8 @@
animation: none;
transition: none;
}
.session-progress-card--composer .session-progress-card__body {
transition: none;
}
}