spotlight had list metrics, and it is not a list
It read as cramped because the first pass reused the app's own list sizing — a 7px tile, text-sm, py-2 — which is right for a row inside a panel competing with everything around it, and wrong for a modal you look at for two seconds with nothing else on screen. So the search input leads at text-base with a 5px glyph, rows are py-2.5 with a 9px tile, and the label is text-[15px] with the hint and the route kept deliberately subordinate rather than scaled with it. Two knock-on changes that are arithmetic rather than taste. The panel widened 560 → 640, because a row now carries a label, a hint and a route on one line and the route is the first thing squeezed out — it is also what disambiguates two rows with the same name. And the results box grew 52vh → 60vh, because taller rows in the same box show fewer results, which would have quietly undone removing the eight-item cap. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -33,6 +33,20 @@ import { useSpotlightItems, type SpotlightItem } from './useSpotlightItems';
|
|||||||
// things to collide with, and this one moved twice already.
|
// things to collide with, and this one moved twice already.
|
||||||
//
|
//
|
||||||
// Escape closes, arrows move, enter goes. The mouse works, but nothing here is designed around it.
|
// Escape closes, arrows move, enter goes. The mouse works, but nothing here is designed around it.
|
||||||
|
//
|
||||||
|
// ── Sizing ──
|
||||||
|
//
|
||||||
|
// Loosened 2026-08-22: the first pass reused the app's list metrics (7px tile, text-sm, py-2) and read as
|
||||||
|
// cramped, because this is not a list inside a panel — it is a modal you look at for two seconds with
|
||||||
|
// nothing else competing for the eye. So the search input leads at `text-base`, rows are `py-2.5` with a
|
||||||
|
// 9px tile, and the label is `text-[15px]` with the hint and path kept deliberately subordinate.
|
||||||
|
//
|
||||||
|
// The panel widened with them (560 → 640). Rows now carry a label, a hint and a route on one line, and the
|
||||||
|
// route is the first thing to be squeezed out — it is also the thing that disambiguates two rows with the
|
||||||
|
// same name.
|
||||||
|
//
|
||||||
|
// The results box grew 52vh → 60vh for the arithmetic reason: taller rows in the same box show fewer
|
||||||
|
// results, and the cap on how many are listed was removed for a reason.
|
||||||
|
|
||||||
/*
|
/*
|
||||||
No cap, deliberately, and it used to be 8.
|
No cap, deliberately, and it used to be 8.
|
||||||
@@ -94,7 +108,7 @@ const Row = ({
|
|||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
onPick();
|
onPick();
|
||||||
}}
|
}}
|
||||||
className={`flex w-full items-center gap-3 rounded-lg px-3 py-2 text-left transition-colors ${
|
className={`flex w-full items-center gap-3.5 rounded-lg px-3.5 py-2.5 text-left transition-colors ${
|
||||||
active ? 'bg-accent' : 'hover:bg-accent/50'
|
active ? 'bg-accent' : 'hover:bg-accent/50'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
@@ -112,7 +126,7 @@ const Row = ({
|
|||||||
it put a coloured pane behind Calendar, Contacts and every plugin logo.
|
it put a coloured pane behind Calendar, Contacts and every plugin logo.
|
||||||
*/}
|
*/}
|
||||||
<span
|
<span
|
||||||
className="flex h-7 w-7 shrink-0 items-center justify-center rounded-md"
|
className="flex h-9 w-9 shrink-0 items-center justify-center rounded-md"
|
||||||
style={{
|
style={{
|
||||||
background: item.tile === 'bare' ? 'transparent' : (item.color ?? 'transparent'),
|
background: item.tile === 'bare' ? 'transparent' : (item.color ?? 'transparent'),
|
||||||
// No colour at all is a settings row: keep the muted glyph rather than inventing a swatch.
|
// No colour at all is a settings row: keep the muted glyph rather than inventing a swatch.
|
||||||
@@ -126,18 +140,20 @@ const Row = ({
|
|||||||
className={item.tile === 'bare' ? 'h-full w-full object-contain' : 'h-5 w-5 object-contain'}
|
className={item.tile === 'bare' ? 'h-full w-full object-contain' : 'h-5 w-5 object-contain'}
|
||||||
/>
|
/>
|
||||||
) : Icon ? (
|
) : Icon ? (
|
||||||
<Icon className={`h-4 w-4 ${item.color ? '' : 'text-muted-foreground'}`} />
|
<Icon className={`h-[18px] w-[18px] ${item.color ? '' : 'text-muted-foreground'}`} />
|
||||||
) : (
|
) : (
|
||||||
<Search className="h-4 w-4 text-muted-foreground" />
|
<Search className="h-[18px] w-[18px] text-muted-foreground" />
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
<span className="min-w-0 flex-1">
|
<span className="min-w-0 flex-1">
|
||||||
<span className="block truncate text-sm text-foreground">
|
<span className="block truncate text-[15px] leading-snug text-foreground">
|
||||||
<Highlighted label={item.label} hits={hits} />
|
<Highlighted label={item.label} hits={hits} />
|
||||||
</span>
|
</span>
|
||||||
{item.hint ? <span className="block truncate text-xs text-muted-foreground">{item.hint}</span> : null}
|
{item.hint ? (
|
||||||
|
<span className="block truncate text-[13px] leading-snug text-muted-foreground">{item.hint}</span>
|
||||||
|
) : null}
|
||||||
</span>
|
</span>
|
||||||
<span className="shrink-0 font-mono text-[10px] text-muted-foreground/60">{item.to}</span>
|
<span className="shrink-0 font-mono text-[11px] text-muted-foreground/60">{item.to}</span>
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -205,12 +221,12 @@ export const Spotlight = () => {
|
|||||||
onMouseDown={close}
|
onMouseDown={close}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="w-[min(92vw,560px)] overflow-hidden rounded-2xl border border-border bg-background/95 shadow-2xl"
|
className="w-[min(92vw,640px)] overflow-hidden rounded-2xl border border-border bg-background/95 shadow-2xl"
|
||||||
// The backdrop closes on mousedown; this stops a click INSIDE the panel counting as one.
|
// The backdrop closes on mousedown; this stops a click INSIDE the panel counting as one.
|
||||||
onMouseDown={(ev) => ev.stopPropagation()}
|
onMouseDown={(ev) => ev.stopPropagation()}
|
||||||
>
|
>
|
||||||
<div className="flex items-center gap-2 border-b border-border px-4">
|
<div className="flex items-center gap-2 border-b border-border px-4">
|
||||||
<Search className="h-4 w-4 shrink-0 text-muted-foreground" />
|
<Search className="h-5 w-5 shrink-0 text-muted-foreground" />
|
||||||
<input
|
<input
|
||||||
ref={inputRef}
|
ref={inputRef}
|
||||||
value={query}
|
value={query}
|
||||||
@@ -228,11 +244,11 @@ export const Spotlight = () => {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
placeholder="Go to…"
|
placeholder="Go to…"
|
||||||
className="w-full bg-transparent py-3.5 text-sm text-foreground outline-none placeholder:text-muted-foreground"
|
className="w-full bg-transparent py-4 text-base text-foreground outline-none placeholder:text-muted-foreground"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="max-h-[52vh] overflow-y-auto p-2">
|
<div className="max-h-[60vh] overflow-y-auto p-2">
|
||||||
{results.length === 0 ? (
|
{results.length === 0 ? (
|
||||||
<p className="px-3 py-6 text-center text-sm text-muted-foreground">Nothing matches “{query}”.</p>
|
<p className="px-3 py-6 text-center text-sm text-muted-foreground">Nothing matches “{query}”.</p>
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
Reference in New Issue
Block a user