spotlight showed eight items, so every plugin was unreachable
MAX_RESULTS was 8. Core items alone fill eight slots, so on a populated server the empty-query list stopped at Browser and none of the fourteen plugin tiles below it could be reached — unless you already knew the name well enough to type it, which is not a thing a launcher gets to require. The owner caught it on alpha with the dock and the launcher side by side; on this machine, which has few plugins, it looked complete. The items were there the whole time. This was not a missing source — it was a silent truncation, with nothing on screen saying "and 20 more", which is exactly how a cap reads as an absent feature. There was never a layout reason for it either: the results container has scrolled since it was written. Removed, and the active row now scrolls itself into view with `block: 'nearest'` so arrowing past the fold works and arrowing through the visible middle does not jump the list. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -25,7 +25,18 @@ import { useSpotlightItems, type SpotlightItem } from './useSpotlightItems';
|
|||||||
//
|
//
|
||||||
// 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.
|
||||||
|
|
||||||
const MAX_RESULTS = 8;
|
/*
|
||||||
|
No cap, deliberately, and it used to be 8.
|
||||||
|
|
||||||
|
Eight was fine on the machine it was written on, which has few plugins. On a populated server the dock
|
||||||
|
carries fourteen plugin tiles and the core items alone fill all eight slots — so with an empty query the
|
||||||
|
list stopped at Browser and every plugin was unreachable unless you already knew its name well enough to
|
||||||
|
type it. A launcher you can only use for things you can already name is not doing the job.
|
||||||
|
|
||||||
|
The container has scrolled since it was written (`max-h-[52vh] overflow-y-auto`), so there was never a
|
||||||
|
layout reason for the limit, and the truncation was silent — nothing said "and 20 more", which is how a
|
||||||
|
cap becomes indistinguishable from a missing feature.
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is the user typing into something?
|
* Is the user typing into something?
|
||||||
@@ -71,8 +82,15 @@ const Row = ({
|
|||||||
onPick: () => void;
|
onPick: () => void;
|
||||||
}) => {
|
}) => {
|
||||||
const Icon = item.icon;
|
const Icon = item.icon;
|
||||||
|
// Keyboard navigation has to survive a list taller than the box. `block: 'nearest'` scrolls only when the
|
||||||
|
// row is actually out of sight, so arrowing through the visible middle of the list does not jump it.
|
||||||
|
const ref = useRef<HTMLButtonElement | null>(null);
|
||||||
|
useEffect(() => {
|
||||||
|
if (active) ref.current?.scrollIntoView({ block: 'nearest' });
|
||||||
|
}, [active]);
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
|
ref={ref}
|
||||||
type="button"
|
type="button"
|
||||||
// `onMouseDown`, not `onClick`: the input holds focus and a click would blur it first, closing the
|
// `onMouseDown`, not `onClick`: the input holds focus and a click would blur it first, closing the
|
||||||
// overlay on the blur handler before the navigation ever ran.
|
// overlay on the blur handler before the navigation ever ran.
|
||||||
@@ -136,7 +154,7 @@ export const Spotlight = () => {
|
|||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const items = useSpotlightItems();
|
const items = useSpotlightItems();
|
||||||
|
|
||||||
const results = useMemo(() => rank(items, query).slice(0, MAX_RESULTS), [items, query]);
|
const results = useMemo(() => rank(items, query), [items, query]);
|
||||||
|
|
||||||
const close = useCallback(() => {
|
const close = useCallback(() => {
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
|
|||||||
Reference in New Issue
Block a user