fix(cli): extensions dialog UX polish (#19685)

This commit is contained in:
Jacob Richman
2026-02-20 13:08:24 -08:00
committed by GitHub
parent 089aec8b8d
commit 9a8e5d3940
8 changed files with 203 additions and 80 deletions

View File

@@ -4,16 +4,10 @@
* SPDX-License-Identifier: Apache-2.0
*/
import { useState, useEffect } from 'react';
import {
useTextBuffer,
type TextBuffer,
} from '../components/shared/text-buffer.js';
import { useUIState } from '../contexts/UIStateContext.js';
import { useState, useEffect, useRef } from 'react';
import type { TextBuffer } from '../components/shared/text-buffer.js';
import type { GenericListItem } from '../components/shared/SearchableList.js';
const MIN_VIEWPORT_WIDTH = 20;
const VIEWPORT_WIDTH_OFFSET = 8;
import { useSearchBuffer } from './useSearchBuffer.js';
export interface UseRegistrySearchResult<T extends GenericListItem> {
filteredItems: T[];
@@ -31,26 +25,22 @@ export function useRegistrySearch<T extends GenericListItem>(props: {
const { items, initialQuery = '', onSearch } = props;
const [searchQuery, setSearchQuery] = useState(initialQuery);
const isFirstRender = useRef(true);
const onSearchRef = useRef(onSearch);
onSearchRef.current = onSearch;
useEffect(() => {
onSearch?.(searchQuery);
}, [searchQuery, onSearch]);
if (isFirstRender.current) {
isFirstRender.current = false;
return;
}
onSearchRef.current?.(searchQuery);
}, [searchQuery]);
const { mainAreaWidth } = useUIState();
const viewportWidth = Math.max(
MIN_VIEWPORT_WIDTH,
mainAreaWidth - VIEWPORT_WIDTH_OFFSET,
);
const searchBuffer = useTextBuffer({
const searchBuffer = useSearchBuffer({
initialText: searchQuery,
initialCursorOffset: searchQuery.length,
viewport: {
width: viewportWidth,
height: 1,
},
singleLine: true,
onChange: (text) => setSearchQuery(text),
onChange: setSearchQuery,
});
const maxLabelWidth = 0;

View File

@@ -0,0 +1,41 @@
/**
* @license
* Copyright 2026 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import {
useTextBuffer,
type TextBuffer,
} from '../components/shared/text-buffer.js';
import { useUIState } from '../contexts/UIStateContext.js';
const MIN_VIEWPORT_WIDTH = 20;
const VIEWPORT_WIDTH_OFFSET = 8;
export interface UseSearchBufferProps {
initialText?: string;
onChange: (text: string) => void;
}
export function useSearchBuffer({
initialText = '',
onChange,
}: UseSearchBufferProps): TextBuffer {
const { mainAreaWidth } = useUIState();
const viewportWidth = Math.max(
MIN_VIEWPORT_WIDTH,
mainAreaWidth - VIEWPORT_WIDTH_OFFSET,
);
return useTextBuffer({
initialText,
initialCursorOffset: initialText.length,
viewport: {
width: viewportWidth,
height: 1,
},
singleLine: true,
onChange,
});
}