fix(ui): restore composer focus after CodeMirror migration
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import React from 'react';
|
||||
import { focusChatInput } from './composer/editor/dom';
|
||||
import type { EditPermissionMode } from '@/stores/types/sessionTypes';
|
||||
import type { ModelMetadata } from '@/types';
|
||||
import {
|
||||
@@ -478,10 +479,7 @@ export const ModelControls: React.FC<ModelControlsProps> = ({
|
||||
|
||||
// Restore focus to chat input when model selector closes
|
||||
if (wasOpen && !isCompact) {
|
||||
requestAnimationFrame(() => {
|
||||
const textarea = document.querySelector<HTMLTextAreaElement>('textarea[data-chat-input="true"]');
|
||||
textarea?.focus();
|
||||
});
|
||||
requestAnimationFrame(focusChatInput);
|
||||
}
|
||||
}
|
||||
}, [isModelSelectorOpen, isCompact]);
|
||||
@@ -492,10 +490,7 @@ export const ModelControls: React.FC<ModelControlsProps> = ({
|
||||
if (!isAgentSelectorOpen) {
|
||||
setAgentSearchQuery('');
|
||||
if (!isCompact) {
|
||||
requestAnimationFrame(() => {
|
||||
const textarea = document.querySelector<HTMLTextAreaElement>('textarea[data-chat-input="true"]');
|
||||
textarea?.focus();
|
||||
});
|
||||
requestAnimationFrame(focusChatInput);
|
||||
}
|
||||
}
|
||||
}, [isAgentSelectorOpen, isCompact]);
|
||||
@@ -1264,10 +1259,7 @@ export const ModelControls: React.FC<ModelControlsProps> = ({
|
||||
closeMobilePanel();
|
||||
}
|
||||
// Restore focus to chat input after model selection.
|
||||
requestAnimationFrame(() => {
|
||||
const textarea = document.querySelector<HTMLTextAreaElement>('textarea[data-chat-input="true"]');
|
||||
textarea?.focus();
|
||||
});
|
||||
requestAnimationFrame(focusChatInput);
|
||||
} catch (error) {
|
||||
console.error('[ModelControls] Handle model change error:', error);
|
||||
}
|
||||
@@ -1605,13 +1597,6 @@ export const ModelControls: React.FC<ModelControlsProps> = ({
|
||||
}
|
||||
}
|
||||
|
||||
const focusMobileComposer = () => {
|
||||
requestAnimationFrame(() => {
|
||||
const textarea = document.querySelector<HTMLTextAreaElement>('textarea[data-chat-input="true"]');
|
||||
textarea?.focus();
|
||||
});
|
||||
};
|
||||
|
||||
const handleMobileModelApply = (providerId: string, modelId: string, variant: string | undefined) => {
|
||||
const result = applyModelSelectionWithVariant(providerId, modelId, variant);
|
||||
if (result !== 'applied') {
|
||||
@@ -1625,7 +1610,7 @@ export const ModelControls: React.FC<ModelControlsProps> = ({
|
||||
|
||||
setExpandedMobileModelKey(null);
|
||||
closeMobilePanel();
|
||||
focusMobileComposer();
|
||||
requestAnimationFrame(focusChatInput);
|
||||
};
|
||||
|
||||
const openMobileVariantOverflow = (providerId: string, modelId: string) => {
|
||||
@@ -1961,10 +1946,7 @@ export const ModelControls: React.FC<ModelControlsProps> = ({
|
||||
}
|
||||
|
||||
closeMobilePanel();
|
||||
requestAnimationFrame(() => {
|
||||
const textarea = document.querySelector<HTMLTextAreaElement>('textarea[data-chat-input="true"]');
|
||||
textarea?.focus();
|
||||
});
|
||||
requestAnimationFrame(focusChatInput);
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -504,6 +504,7 @@ export const ComposerEditor = React.forwardRef<ComposerEditorHandle, ComposerEdi
|
||||
<div
|
||||
ref={hostRef}
|
||||
data-testid={props['data-testid']}
|
||||
data-chat-input="true"
|
||||
onMouseDown={handleHostMouseDown}
|
||||
className={cn(
|
||||
'composer-editor w-full',
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
import { afterEach, expect, test } from 'bun:test';
|
||||
|
||||
import { focusChatInput } from '../dom';
|
||||
|
||||
const originalDocument = globalThis.document;
|
||||
|
||||
afterEach(() => {
|
||||
globalThis.document = originalDocument;
|
||||
});
|
||||
|
||||
test('focuses the CodeMirror chat input content', () => {
|
||||
let selector = '';
|
||||
let focused = false;
|
||||
globalThis.document = {
|
||||
querySelector: (value: string) => {
|
||||
selector = value;
|
||||
return { focus: () => { focused = true; } };
|
||||
},
|
||||
} as unknown as Document;
|
||||
|
||||
focusChatInput();
|
||||
|
||||
expect(selector).toBe('[data-chat-input="true"] .cm-content');
|
||||
expect(focused).toBe(true);
|
||||
});
|
||||
@@ -0,0 +1,5 @@
|
||||
const CHAT_INPUT_EDITOR_SELECTOR = '[data-chat-input="true"] .cm-content';
|
||||
|
||||
export function focusChatInput(): void {
|
||||
document.querySelector<HTMLElement>(CHAT_INPUT_EDITOR_SELECTOR)?.focus();
|
||||
}
|
||||
Reference in New Issue
Block a user