fix(ai): cap agent composer height

This commit is contained in:
lucaronin
2026-05-02 20:41:08 +02:00
parent b6dd6189a2
commit 4f86b97e8d
5 changed files with 30 additions and 2 deletions

View File

@@ -197,6 +197,18 @@ describe('AiPanel', () => {
expect(screen.getByTestId('ai-panel')).toBeTruthy()
})
it('caps long AI agent drafts inside a scrollable composer while keeping send visible', () => {
render(<AiPanel onClose={vi.fn()} vaultPath="/tmp/vault" />)
const editor = screen.getByTestId('agent-input')
editor.textContent = Array.from({ length: 40 }, (_, index) => `Line ${index + 1}`).join('\n')
fireEvent.input(editor)
expect(editor).toHaveClass('max-h-[160px]', 'overflow-y-auto', 'overscroll-contain')
expect(editor).toHaveStyle({ maxHeight: '160px', overflowY: 'auto' })
expect(screen.getByTestId('agent-send')).toBeVisible()
})
it('calls onClose when close button is clicked', () => {
const onClose = vi.fn()
render(<AiPanel onClose={onClose} vaultPath="/tmp/vault" />)

View File

@@ -369,7 +369,7 @@ export function AiPanelComposer({
style={{ padding: '8px 12px' }}
>
<div className="flex items-end gap-2">
<div className="flex-1">
<div className="min-w-0 flex-1">
<WikilinkChatInput
entries={entries}
value={input}
@@ -379,6 +379,8 @@ export function AiPanelComposer({
disabled={composerDisabled}
placeholder={placeholder}
inputRef={inputRef}
editorClassName="max-h-[160px] overflow-y-auto overscroll-contain"
editorStyle={{ maxHeight: 160, overflowY: 'auto', overscrollBehavior: 'contain' }}
/>
</div>
<Button

View File

@@ -4,6 +4,7 @@ import {
useMemo,
useRef,
useState,
type CSSProperties,
type ReactNode,
} from 'react'
import type { VaultEntry } from '../types'
@@ -57,6 +58,7 @@ interface InlineWikilinkInputProps {
inputRef?: React.RefObject<HTMLDivElement | null>
dataTestId?: string
editorClassName?: string
editorStyle?: CSSProperties
suggestionListVariant?: 'floating' | 'palette'
suggestionEmptyLabel?: string
paletteHeader?: ReactNode
@@ -168,6 +170,7 @@ export function InlineWikilinkInput({
inputRef,
dataTestId = 'agent-input',
editorClassName,
editorStyle,
suggestionListVariant = 'floating',
suggestionEmptyLabel = 'No matching notes',
paletteHeader,
@@ -472,6 +475,7 @@ export function InlineWikilinkInput({
inputRef={setCombinedRef}
dataTestId={dataTestId}
editorClassName={editorClassName}
editorStyle={editorStyle}
onCompositionEnd={handleCompositionEnd}
onCompositionStart={handleCompositionStart}
onInput={handleInput}

View File

@@ -1,4 +1,5 @@
import { Fragment, createElement } from 'react'
import type { CSSProperties } from 'react'
import type { VaultEntry } from '../types'
import { getTypeColor, getTypeLightColor } from '../utils/typeColors'
import { NoteTitleIcon } from './NoteTitleIcon'
@@ -158,6 +159,7 @@ export function InlineWikilinkEditorField({
inputRef,
dataTestId,
editorClassName,
editorStyle,
onCompositionEnd,
onCompositionStart,
onInput,
@@ -175,6 +177,7 @@ export function InlineWikilinkEditorField({
inputRef: React.Ref<HTMLDivElement>
dataTestId: string
editorClassName?: string
editorStyle?: CSSProperties
onCompositionEnd: () => void
onCompositionStart: () => void
onInput: () => void
@@ -222,7 +225,7 @@ export function InlineWikilinkEditorField({
onClick={onSelectionChange}
onKeyUp={onSelectionChange}
onMouseUp={onSelectionChange}
style={{ whiteSpace: 'pre-wrap', wordBreak: 'break-word' }}
style={{ ...editorStyle, whiteSpace: 'pre-wrap', wordBreak: 'break-word' }}
>
{segments.map((segment, index) => (
segment.kind === 'text'

View File

@@ -1,3 +1,4 @@
import type { CSSProperties } from 'react'
import type { VaultEntry } from '../types'
import type { NoteReference } from '../utils/ai-context'
import { InlineWikilinkInput } from './InlineWikilinkInput'
@@ -11,6 +12,8 @@ interface WikilinkChatInputProps {
disabled?: boolean
placeholder?: string
inputRef?: React.RefObject<HTMLDivElement | null>
editorClassName?: string
editorStyle?: CSSProperties
}
export function WikilinkChatInput({
@@ -22,6 +25,8 @@ export function WikilinkChatInput({
disabled,
placeholder,
inputRef,
editorClassName,
editorStyle,
}: WikilinkChatInputProps) {
return (
<InlineWikilinkInput
@@ -33,6 +38,8 @@ export function WikilinkChatInput({
disabled={disabled}
placeholder={placeholder}
inputRef={inputRef}
editorClassName={editorClassName}
editorStyle={editorStyle}
/>
)
}