fix(web): keep browser autofill out of config forms; drop the closed panel's stray divider (#114)
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -65,6 +65,7 @@ import { resolveContextWindow } from "../../lib/context";
|
||||
import { useLocale } from "../../state/locale";
|
||||
import { Dropdown } from "../../components/ui/dropdown";
|
||||
import { GlyphIcon } from "../../components/ui/glyph-icon";
|
||||
import { noAutofill } from "../../components/ui/input";
|
||||
import { SkillIcon } from "../skills/skill-icon-view";
|
||||
import { ZoomableImage } from "../../components/ui/image-zoom";
|
||||
import { ProviderLogo } from "../../components/ui/provider-logo";
|
||||
@@ -280,6 +281,7 @@ function ModelMenuList({
|
||||
onChange={(e) => setQuery(e.target.value)}
|
||||
placeholder={S.models.searchPlaceholder}
|
||||
aria-label={S.models.searchPlaceholder}
|
||||
{...noAutofill}
|
||||
className="w-full rounded border border-transparent bg-transparent px-1 py-0.5 text-xs text-gray-700 placeholder:text-gray-400 focus:outline-none dark:text-gray-200 dark:placeholder:text-gray-500"
|
||||
/>
|
||||
</div>
|
||||
@@ -680,6 +682,7 @@ function SkillSelect({
|
||||
onChange={(e) => setQuery(e.target.value)}
|
||||
placeholder={S.chat.skillsSearchPlaceholder}
|
||||
aria-label={S.chat.skillsSearchPlaceholder}
|
||||
{...noAutofill}
|
||||
className="w-full rounded border border-transparent bg-transparent px-1 py-0.5 text-xs text-gray-700 placeholder:text-gray-400 focus:outline-none dark:text-gray-200 dark:placeholder:text-gray-500"
|
||||
/>
|
||||
</div>
|
||||
@@ -2022,6 +2025,7 @@ export function ChatInput({
|
||||
placeholder={S.chat.goalBudgetPlaceholder}
|
||||
aria-invalid={goalBudgetDraftInvalid}
|
||||
aria-describedby="goal-budget-hint"
|
||||
{...noAutofill}
|
||||
title={
|
||||
goalBudgetDraftInvalid ? S.chat.goalBudgetInvalid : S.chat.goalBudgetHint
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ import { useSessions } from "../../state/sessions";
|
||||
import { AgentAvatar } from "../../components/ui/agent-avatar";
|
||||
import { Chevron } from "../../components/ui/chevron";
|
||||
import { Dropdown } from "../../components/ui/dropdown";
|
||||
import { noAutofill } from "../../components/ui/input";
|
||||
import { PenguinLogo } from "../../components/ui/penguin-logo";
|
||||
import { toastError } from "../../components/ui/toast";
|
||||
import { useVersionInfo } from "../../lib/use-version-info";
|
||||
@@ -967,6 +968,7 @@ function WorkspaceSelect({
|
||||
value={pathDraft}
|
||||
placeholder="…"
|
||||
aria-label={S.chat.workspace}
|
||||
{...noAutofill}
|
||||
onChange={(e) => setPathDraft(e.target.value)}
|
||||
onBlur={() => void commitPathEdit()}
|
||||
onKeyDown={(e) => {
|
||||
|
||||
@@ -74,9 +74,15 @@ export function FilesPanel({ session, panel }: { session: SessionInfo; panel: Fi
|
||||
// input) anchored to the nearest initial containing block instead, it would bypass this
|
||||
// overflow-hidden and stretch the **document** wide, making a horizontal scrollbar
|
||||
// appear out of nowhere.
|
||||
className={`relative flex min-h-0 shrink-0 flex-col overflow-hidden border-l border-gray-200 dark:border-gray-800 ${
|
||||
panel.resizing ? "pointer-events-none" : "transition-[width] duration-200"
|
||||
}`}
|
||||
//
|
||||
// The divider belongs to the OPEN state only: with border-box sizing a closed panel's
|
||||
// border still paints its 1px even at width 0, and since both docked panels stay
|
||||
// mounted, the closed one left a stray line beside the open one — a hairline, a gap
|
||||
// (the open panel's resize handle) and then the real divider, which reads as an extra
|
||||
// empty panel wedged in. Both closed, the two leftover lines stacked at the window edge.
|
||||
className={`relative flex min-h-0 shrink-0 flex-col overflow-hidden ${
|
||||
panel.open ? "border-l border-gray-200 dark:border-gray-800" : ""
|
||||
} ${panel.resizing ? "pointer-events-none" : "transition-[width] duration-200"}`}
|
||||
>
|
||||
{/* Content is fixed at the target width; the outer element is only a clipping window:
|
||||
during the open/close animation the outer element passes through intermediate
|
||||
|
||||
@@ -80,11 +80,13 @@ export function SubagentsPanel({
|
||||
<div
|
||||
ref={panel.panelRef}
|
||||
style={{ width: panel.open ? panel.width : 0 }}
|
||||
// Same inert + clipping-window handling as the Files panel (see files-panel.tsx).
|
||||
// Same inert + clipping-window handling as the Files panel, and the same open-only
|
||||
// divider (a closed panel's 1px border would otherwise paint next to the open one —
|
||||
// see files-panel.tsx).
|
||||
inert={!panel.open}
|
||||
className={`relative flex min-h-0 shrink-0 flex-col overflow-hidden border-l border-gray-200 dark:border-gray-800 ${
|
||||
panel.resizing ? "pointer-events-none" : "transition-[width] duration-200"
|
||||
}`}
|
||||
className={`relative flex min-h-0 shrink-0 flex-col overflow-hidden ${
|
||||
panel.open ? "border-l border-gray-200 dark:border-gray-800" : ""
|
||||
} ${panel.resizing ? "pointer-events-none" : "transition-[width] duration-200"}`}
|
||||
>
|
||||
<div style={{ width: panel.width }} className="flex h-full min-h-0 flex-col">
|
||||
<div className="flex shrink-0 items-center gap-1 px-3 pt-2">
|
||||
|
||||
Reference in New Issue
Block a user