fix: make model selector dropdowns responsive to viewport

This commit is contained in:
Bohdan Triapitsyn
2026-01-04 01:24:29 +02:00
parent d86105fcb2
commit 9d1aceeb6d
4 changed files with 21 additions and 4 deletions
+1 -1
View File
@@ -2847,7 +2847,7 @@ dependencies = [
[[package]]
name = "openchamber-desktop"
version = "1.4.1"
version = "1.4.3"
dependencies = [
"anyhow",
"axum",
@@ -1870,7 +1870,7 @@ export const ModelControls: React.FC<ModelControlsProps> = ({ className }) => {
</div>
{/* Scrollable content */}
<ScrollableOverlay outerClassName="max-h-[400px] flex-1">
<ScrollableOverlay outerClassName="max-h-[min(400px,calc(100dvh-12rem))] flex-1">
<div className="p-1">
{!hasResults && (
<div className="px-2 py-4 text-center typography-meta text-muted-foreground">
@@ -111,8 +111,10 @@ export const ModelMultiSelect: React.FC<ModelMultiSelectProps> = ({
const [isOpen, setIsOpen] = React.useState(false);
const [searchQuery, setSearchQuery] = React.useState('');
const [selectedIndex, setSelectedIndex] = React.useState(0);
const [availableHeight, setAvailableHeight] = React.useState<number | null>(null);
const searchInputRef = React.useRef<HTMLInputElement>(null);
const dropdownRef = React.useRef<HTMLDivElement>(null);
const triggerRef = React.useRef<HTMLButtonElement>(null);
const itemRefs = React.useRef<(HTMLButtonElement | null)[]>([]);
// Count occurrences of each model for display purposes
@@ -193,6 +195,17 @@ export const ModelMultiSelect: React.FC<ModelMultiSelectProps> = ({
const hasResults = filteredFavorites.length > 0 || filteredRecents.length > 0 || filteredProviders.length > 0;
// Calculate available height when dropdown opens
React.useEffect(() => {
if (isOpen && triggerRef.current) {
const rect = triggerRef.current.getBoundingClientRect();
// Space above trigger minus padding from top edge
const spaceAbove = rect.top - 100;
// Cap at 400px max, minimum 150px
setAvailableHeight(Math.max(150, Math.min(400, spaceAbove)));
}
}, [isOpen]);
// Focus search input when opened
React.useEffect(() => {
if (isOpen && searchInputRef.current) {
@@ -280,6 +293,7 @@ export const ModelMultiSelect: React.FC<ModelMultiSelectProps> = ({
{/* Add model button (dropdown trigger) */}
<div className="relative" ref={dropdownRef}>
<Button
ref={triggerRef}
type="button"
variant="outline"
size="sm"
@@ -369,7 +383,10 @@ export const ModelMultiSelect: React.FC<ModelMultiSelectProps> = ({
</div>
{/* Models list */}
<ScrollableOverlay outerClassName="max-h-[400px] flex-1">
<ScrollableOverlay
outerClassName="flex-1"
style={{ maxHeight: availableHeight ? `${availableHeight}px` : '300px' }}
>
<div className="p-1">
{!hasResults && (
<div className="px-2 py-4 text-center typography-meta text-muted-foreground">
@@ -563,7 +563,7 @@ export const ModelSelector: React.FC<ModelSelectorProps> = ({
</div>
{/* Scrollable content */}
<ScrollableOverlay outerClassName="max-h-[400px] flex-1">
<ScrollableOverlay outerClassName="max-h-[min(400px,calc(100dvh-12rem))] flex-1">
<div className="p-1">
{/* Not selected option */}
<div