fix(native-chat): open composer pickers upward

This commit is contained in:
Brennan Benson
2026-08-10 22:56:46 -07:00
parent 23c803a1a6
commit 5acca9fce8
2 changed files with 36 additions and 3 deletions
@@ -40,7 +40,23 @@ vi.mock('@/components/ui/dropdown-menu', () => {
children: React.ReactNode
disabled?: boolean
}) => <div data-disabled={disabled || undefined}>{children}</div>,
DropdownMenuContent: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
DropdownMenuContent: ({
children,
side,
collisionPadding
}: {
children: React.ReactNode
side?: string
collisionPadding?: number
}) => (
<div
data-testid="session-option-menu"
data-side={side}
data-collision-padding={collisionPadding}
>
{children}
</div>
),
DropdownMenuLabel: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
DropdownMenuSeparator: () => <hr />,
DropdownMenuItem: ({
@@ -172,6 +188,23 @@ const fast: SessionOptionDescriptor = {
afterEach(() => cleanup())
describe('NativeChatSessionOptionPickers', () => {
it('prefers collision-aware upward placement for model and option menus', () => {
render(
<NativeChatSessionOptionPickers
surface={surface}
snapshot={[model(), effort]}
isWorking={false}
/>
)
const menus = screen.getAllByTestId('session-option-menu')
expect(menus).toHaveLength(2)
for (const menu of menus) {
expect(menu.getAttribute('data-side')).toBe('top')
expect(menu.getAttribute('data-collision-padding')).toBe('8')
}
})
it('renders model and joined option labels, and hides an empty options pill', () => {
const { rerender } = render(
<NativeChatSessionOptionPickers
@@ -242,7 +242,7 @@ function NativeChatSessionOptionPickersInner({
disabledReason={optionsReason}
dispatched={options.some((descriptor) => descriptor.valueSource === 'dispatched')}
/>
<DropdownMenuContent align="start" className="w-60">
<DropdownMenuContent align="start" side="top" collisionPadding={8} className="w-60">
{options.map((descriptor, index) => {
const reason = nativeChatSessionOptionDisabledReason(descriptor.disabledReason)
return (
@@ -272,7 +272,7 @@ function NativeChatSessionOptionPickersInner({
disabledReason={modelReason}
dispatched={model.valueSource === 'dispatched'}
/>
<DropdownMenuContent align="start" className="w-64">
<DropdownMenuContent align="start" side="top" collisionPadding={8} className="w-64">
{modelReason && !model.settable ? (
<DropdownMenuLabel className="font-normal">{modelReason}</DropdownMenuLabel>
) : null}