diff --git a/apps/web/src/components/chat/ModelPickerContent.tsx b/apps/web/src/components/chat/ModelPickerContent.tsx index 70181947bc4a7352f3b64fe53f47f2c85f585511..53a2e9c45bacf7da154c077388b5af7d2ad6239d 100644 --- a/apps/web/src/components/chat/ModelPickerContent.tsx +++ b/apps/web/src/components/chat/ModelPickerContent.tsx @@ -144,6 +144,7 @@ export function adjacentModelPickerProvider(input: { } const EMPTY_MODEL_JUMP_LABELS = new Map(); +const MODEL_LIST_ESTIMATED_ITEM_SIZE = 52; function ModelListSeparator() { return
; @@ -197,6 +198,7 @@ export const ModelPickerContent = memo(function ModelPickerContent(props: { const [showBottomScrollFade, setShowBottomScrollFade] = useState(false); const searchInputRef = useRef(null); const modelListRef = useRef(null); + const pickerContentRef = useRef(null); const highlightedModelKeyRef = useRef(null); const favorites = useClientSettings((s) => s.favorites ?? []); const activeEntry = props.instanceEntries.find( @@ -699,6 +701,17 @@ export const ModelPickerContent = memo(function ModelPickerContent(props: { ), [visibleModels], ); + const [modelListContentSize, setModelListContentSize] = useState( + () => filteredItemKeys.length * MODEL_LIST_ESTIMATED_ITEM_SIZE, + ); + const [searchHeight, setSearchHeight] = useState(0); + useLayoutEffect( + () => modelListRef.current?.getState().listen("totalSize", setModelListContentSize), + [], + ); + // Fit the list to its rows plus the combobox list `py-1` and LegendList `py-1.5`. + const modelListHeight = + filteredItemKeys.length === 0 ? 0 : `calc(${modelListContentSize}px + var(--spacing) * 5)`; const updateModelListScrollFades = useCallback(() => { const scrollElement = modelListRef.current?.getScrollableNode(); if (!(scrollElement instanceof HTMLElement)) { @@ -815,7 +828,10 @@ export const ModelPickerContent = memo(function ModelPickerContent(props: { return (
{/* Sidebar */} @@ -890,7 +906,10 @@ export const ModelPickerContent = memo(function ModelPickerContent(props: { ref={searchInputRef} placeholder="Search models..." value={searchQuery} - onChange={(e) => setSearchQuery(e.target.value)} + onChange={(e) => { + if (!isSearching) setSearchHeight(pickerContentRef.current?.offsetHeight ?? 0); + setSearchQuery(e.target.value); + }} onKeyDown={(e) => { if ( showSidebar && @@ -944,7 +963,10 @@ export const ModelPickerContent = memo(function ModelPickerContent(props: { /> {/* Model list */} -
+
ref={modelListRef} @@ -1013,7 +1035,7 @@ export const ModelPickerContent = memo(function ModelPickerContent(props: { /> ); }} - estimatedItemSize={52} + estimatedItemSize={MODEL_LIST_ESTIMATED_ITEM_SIZE} drawDistance={480} recycleItems contentContainerClassName="pl-2 pr-px"