confidence slider UI round: global ←/→, fraction positions, color ramp; plan-flank phantom fix
Owner UI round 2026-10-01, three rulings on the slider plus one en-route bug: - GLOBAL ←/→, the ↑/↓ pattern: confidence adjusts wherever focus sits (window keydown, typing-guarded), no click-in, no focus ring. The slider itself takes NO focus — tabIndex -1, mousedown prevented, removed from the Tab chain (rows → thinking directly again). - Position = fraction: the thumb's scale is 0-100 with the rendered value the stop's own percent, so 50 sits halfway; onChange snaps to the nearest stop (magnet feel while dragged). - Six-step ramp (owner pick over three bands): 0 red, 30 orange, 50 yellow (the coin flip), 70 lime, 90 green, 100 emerald — fill AND handle wear the stop's color; taller 10px pill bar, custom track/thumb (webkit + moz), muted remainder via --muted. - Plan-flank phantom: gating the marginalia button on a JSX element (always truthy) mounted an invisible clickable button in the bottom-right whenever a question was pending with no plan. planExists() now gates it (pinned in plan-window tests).
This commit is contained in:
+7
-2
@@ -26,7 +26,7 @@ import { StatsBar } from "@/components/stats-bar";
|
||||
import { useActivity } from "@/components/activity-dock";
|
||||
import { isProviderKeyRefusal, needsContinuation, type ChatInput, type ChatSettings, type LhMessage, type ModelSlotName } from "@/src/core";
|
||||
import { PlanBlock, PlanPopup, latestTree } from "@/components/plan-block";
|
||||
import { PlanMarginalia } from "@/components/plan-window";
|
||||
import { PlanMarginalia, planExists } from "@/components/plan-window";
|
||||
import { MermaidOverlay, SessionMermaidContext } from "@/components/session-overlay";
|
||||
import { WaypointsIcon } from "lucide-react";
|
||||
import type { PlanBlockData } from "@/src/core";
|
||||
@@ -563,6 +563,11 @@ export function Chat({
|
||||
// The live plan popup (wave 4): opened by any transcript plan block, the
|
||||
// top-bar plan chip, and the dock band's marginalia.
|
||||
const [planOpen, setPlanOpen] = useState(false);
|
||||
// Real plan presence — gates the marginalia's clickable flank. A JSX
|
||||
// element is always truthy; gating on the node alone mounted a phantom
|
||||
// (invisible, clickable) button in the bottom-right whenever a question
|
||||
// was pending with no plan yet (owner report, UI round 2026-10-01).
|
||||
const hasPlan = useMemo(() => planExists(messages), [messages]);
|
||||
// The coverage ring's refresh chain (extraction-UX redesign): bumped at
|
||||
// turn settle — the moment this session's uncovered mass changes.
|
||||
const [coverageTick, setCoverageTick] = useState(0);
|
||||
@@ -1163,7 +1168,7 @@ export function Chat({
|
||||
<DockOverlay
|
||||
pending={pending}
|
||||
chatId={chatId}
|
||||
plan={<PlanMarginalia messages={messages} />}
|
||||
plan={hasPlan ? <PlanMarginalia messages={messages} /> : undefined}
|
||||
onOpenPlan={() => setPlanOpen(true)}
|
||||
requiresReveal={requiresReveal}
|
||||
phase={phases.at(-1) ?? "probe"}
|
||||
|
||||
Reference in New Issue
Block a user