Skip to content

Commit 9883570

Browse files
committed
feat(web): match bud's Models design — rounded tree connector, inset hover, key states
Copied from bud.app/models (CDP-inspected): - Row list: drop overflow-hidden so hover corners are rounded (was clipped/edge- to-edge); model name 15px/500, section label 14px/500 #585858. - Source dropdown: bud's rounded-elbow tree connector (border-l+border-b rounded-bl, 1.5px) with a dark accent on the selected branch + a filled check node; drop the white selected-row bg (items are transparent now, selection is the check). - API keys: 'Edit' (outlined) when a key exists vs 'Configure' (dark) when not. Functionality (toggle/connect/save) unchanged.
1 parent 0c8f0b1 commit 9883570

2 files changed

Lines changed: 45 additions & 31 deletions

File tree

apps/web/src/components/settings/agents-panel.tsx

Lines changed: 38 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,9 @@ export function AgentsPanel() {
110110
/>
111111
<section className="rounded-3xl bg-[#f7f7f7] p-1">
112112
<div className="flex items-center px-4 pt-2 pb-3">
113-
<span className="font-medium text-[#707070] text-[14px]">Agent Models</span>
113+
<span className="font-medium text-[#585858] text-[14px]">Agent Models</span>
114114
</div>
115-
<div className="overflow-hidden rounded-[21px] bg-white ring-1 ring-[#f1f1f1]/70">
115+
<div className="flex flex-col rounded-[21px] bg-white ring-1 ring-[#f1f1f1]/70">
116116
<ModelRow
117117
control={<span className="text-[#707070] text-[13px] underline">Always on</span>}
118118
expanded={expandedSourceId === "auto"}
@@ -321,7 +321,9 @@ function ModelRow({
321321
<div className="flex min-w-0 items-center gap-3">
322322
{icon}
323323
<div className="min-w-0">
324-
<div className="truncate font-medium text-[#1b1b1b] text-[16px] leading-6">{label}</div>
324+
<div className="truncate font-medium text-[#1b1b1b] text-[15px] leading-[19px]">
325+
{label}
326+
</div>
325327
<button
326328
aria-expanded={expanded}
327329
className="flex max-w-full items-center gap-1 rounded-full text-[#666666] text-[14px] leading-5 outline-none transition-colors duration-150 hover:text-[#1b1b1b] focus-visible:ring-2 focus-visible:ring-[#1b1b1b]/10"
@@ -377,45 +379,52 @@ function ModelSourceList({
377379
open ? "translate-y-0 opacity-100" : "-translate-y-1 opacity-0",
378380
)}
379381
>
380-
<div className="relative pl-5">
381-
<span
382-
aria-hidden="true"
383-
className="absolute top-0 bottom-[17px] left-0 w-px bg-[#e7e7e7]"
384-
/>
385-
<div className="flex flex-col gap-1">
386-
{choices.map((choice) => (
382+
<div className="relative flex flex-col pl-8">
383+
{choices.map((choice, index) => {
384+
const isLast = index === choices.length - 1;
385+
const branch = choice.active ? "#1b1b1b" : "#e3e3e3";
386+
return (
387387
<div className="group/item relative z-10" key={choice.id}>
388+
{/* rounded elbow from the tree line into this item */}
388389
<span
389390
aria-hidden="true"
390-
className="absolute top-1/2 left-0 h-px w-3 -translate-x-5 -translate-y-1/2 bg-[#e7e7e7]"
391+
className="absolute top-2 -left-8 z-10 h-2.5 w-4 rounded-bl-[10px] border-b-[1.5px] border-l-[1.5px]"
392+
style={{ borderColor: branch }}
391393
/>
394+
{/* line segment above the elbow (dark on the selected branch) */}
395+
<span
396+
aria-hidden="true"
397+
className="absolute top-0 -left-8 h-2 w-[1.5px]"
398+
style={{ backgroundColor: branch }}
399+
/>
400+
{/* line segment continuing down to the next item */}
401+
{isLast ? null : (
402+
<span
403+
aria-hidden="true"
404+
className="absolute top-2 -bottom-1 -left-8 w-[1.5px] bg-[#e3e3e3]"
405+
/>
406+
)}
407+
{/* filled check node at the elbow end, only for the active source */}
408+
{choice.active ? (
409+
<span
410+
aria-hidden="true"
411+
className="absolute top-[18px] -left-3.5 z-10 flex size-4 -translate-x-1/2 -translate-y-1/2 items-center justify-center rounded-full bg-[#1b1b1b] text-white"
412+
>
413+
<Check aria-hidden="true" className="size-2.5" strokeWidth={2.5} />
414+
</span>
415+
) : null}
392416
<button
393417
aria-current={choice.active ? "true" : undefined}
394-
className={cn(
395-
"-ml-3 flex h-[35px] w-full items-center gap-3 rounded-[10px] px-3 py-[5.5px] text-left font-medium text-[#1b1b1b] text-[16px] leading-6 outline-none transition-[background-color,box-shadow] duration-150",
396-
choice.active
397-
? "bg-white shadow-[inset_0_0_0_1px_rgba(0,0,0,0.03)]"
398-
: "hover:bg-white/80",
399-
)}
418+
className="flex h-[35px] w-full items-center rounded-[10px] px-3 text-left font-medium text-[#1b1b1b] text-[15px] leading-[19px] outline-none transition-colors duration-150 hover:bg-black/[0.04]"
400419
onClick={() => onSelect(choice)}
401420
tabIndex={open ? 0 : -1}
402421
type="button"
403422
>
404-
<span
405-
className={cn(
406-
"flex size-4 shrink-0 items-center justify-center rounded-full",
407-
choice.active ? "bg-[#222222] text-white" : "bg-transparent",
408-
)}
409-
>
410-
{choice.active ? (
411-
<Check aria-hidden="true" className="size-3" strokeWidth={2.5} />
412-
) : null}
413-
</span>
414423
<span className="min-w-0 truncate">{choice.label}</span>
415424
</button>
416425
</div>
417-
))}
418-
</div>
426+
);
427+
})}
419428
</div>
420429
</div>
421430
);

apps/web/src/components/settings/provider-keys-panel.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -304,11 +304,16 @@ function CompactProviderKeysPanel({
304304
<button
305305
aria-controls={providerPanelId(provider)}
306306
aria-expanded={isExpanded}
307-
className="inline-flex h-8 items-center justify-center rounded-full bg-[#1b1b1b] px-3 font-medium text-[14px] text-white shadow-[inset_0_1px_0_rgba(255,255,255,0.18),0_1px_3px_rgba(0,0,0,0.2)] transition-colors hover:bg-black"
307+
className={cn(
308+
"inline-flex h-8 items-center justify-center rounded-full px-4 font-medium text-[14px] transition-colors",
309+
summary
310+
? "border border-[#e6e6e6] bg-white text-[#1b1b1b] hover:bg-[#f7f7f7]"
311+
: "bg-[#1b1b1b] text-white shadow-[inset_0_1px_0_rgba(255,255,255,0.18),0_1px_3px_rgba(0,0,0,0.2)] hover:bg-black",
312+
)}
308313
onClick={() => onSelect(provider)}
309314
type="button"
310315
>
311-
{summary ? "Manage" : "Configure"}
316+
{summary ? "Edit" : "Configure"}
312317
</button>
313318
</div>
314319
{isExpanded ? (

0 commit comments

Comments
 (0)