diff --git a/web/src/shared/ui/select.test.ts b/web/src/shared/ui/select.test.ts index 0768fd3a..9da2727f 100644 --- a/web/src/shared/ui/select.test.ts +++ b/web/src/shared/ui/select.test.ts @@ -40,6 +40,14 @@ describe('shared select contract', () => { expect(SELECT_ITEM_CLASS_NAME).toContain('rounded-md') }) + it('keeps long option lists inside the available viewport', () => { + expect(SELECT_CONTENT_CLASS_NAME).toContain( + 'max-h-[var(--radix-select-content-available-height)]' + ) + expect(SELECT_CONTENT_CLASS_NAME).toContain('overflow-y-auto') + expect(SELECT_CONTENT_CLASS_NAME).toContain('overflow-x-hidden') + }) + it('uses pointer cursors for expanded select interactions', () => { expect(SELECT_ITEM_CLASS_NAME).toContain('cursor-pointer') expect(SELECT_SCROLL_BUTTON_CLASS_NAME).toContain('cursor-pointer') diff --git a/web/src/shared/ui/select.tsx b/web/src/shared/ui/select.tsx index f45cc4f5..3f0c72ba 100644 --- a/web/src/shared/ui/select.tsx +++ b/web/src/shared/ui/select.tsx @@ -12,7 +12,7 @@ export const SELECT_TRIGGER_CLASS_NAME = cn( ) export const SELECT_CONTENT_CLASS_NAME = cn( - 'z-50 overflow-hidden rounded-lg border border-border bg-popover text-popover-foreground shadow-md', + 'z-50 max-h-[var(--radix-select-content-available-height)] overflow-x-hidden overflow-y-auto rounded-lg border border-border bg-popover text-popover-foreground shadow-md', // In-tree (no Portal): avoids React 19 removeChild races on route unmount. // No exit animations: delayed unmount still races commits when Content was portaled. 'data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95',