diff --git a/packages/frontend/@n8n/design-system/src/components/AskAssistantChat/AskAssistantChat.vue b/packages/frontend/@n8n/design-system/src/components/AskAssistantChat/AskAssistantChat.vue index 5300615fb15..b2d35f4c157 100644 --- a/packages/frontend/@n8n/design-system/src/components/AskAssistantChat/AskAssistantChat.vue +++ b/packages/frontend/@n8n/design-system/src/components/AskAssistantChat/AskAssistantChat.vue @@ -499,6 +499,7 @@ defineExpose({ :max-length="maxCharacterLength" :min-lines="2" data-test-id="chat-suggestions-input" + autofocus @upgrade-click="emit('upgrade-click')" @submit="onSendMessage" @stop="emit('stop')" @@ -549,6 +550,7 @@ defineExpose({ :max-length="maxCharacterLength" :refocus-after-send="true" data-test-id="chat-input" + autofocus @upgrade-click="emit('upgrade-click')" @submit="onSendMessage" @stop="emit('stop')" diff --git a/packages/frontend/@n8n/design-system/src/components/AskAssistantChat/__snapshots__/AskAssistantChat.test.ts.snap b/packages/frontend/@n8n/design-system/src/components/AskAssistantChat/__snapshots__/AskAssistantChat.test.ts.snap index 8e65281bc53..08f8d6fb67a 100644 --- a/packages/frontend/@n8n/design-system/src/components/AskAssistantChat/__snapshots__/AskAssistantChat.test.ts.snap +++ b/packages/frontend/@n8n/design-system/src/components/AskAssistantChat/__snapshots__/AskAssistantChat.test.ts.snap @@ -86,6 +86,7 @@ exports[`AskAssistantChat > limits maximum input length when maxCharacterLength data-test-id="chat-input-wrapper" > renders chat with messages correctly 1`] = ` data-test-id="chat-input-wrapper" > renders default placeholder chat correctly 1`] = ` data-test-id="chat-input-wrapper" > renders end of session chat correctly 1`] = ` data-test-id="chat-input-wrapper" > renders error message correctly with retry button 1` data-test-id="chat-input-wrapper" > renders message with code snippet 1`] = ` data-test-id="chat-input-wrapper" > renders streaming chat correctly 1`] = ` data-test-id="chat-input-wrapper" > { wrapper.unmount(); }); }); + + describe('autofocus', () => { + it('should be focused if enabled', async () => { + const { emitted } = renderComponent({ + props: { + autofocus: true, + }, + global: { + stubs: ['N8nCallout', 'N8nScrollArea', 'N8nSendStopButton'], + }, + }); + + expect(emitted('focus')).toBeTruthy(); + }); + + it('should not be focused if disabled', () => { + const { emitted } = renderComponent({ + global: { + stubs: ['N8nCallout', 'N8nScrollArea', 'N8nSendStopButton'], + }, + }); + expect(emitted('focus')).toBeFalsy(); + }); + }); }); diff --git a/packages/frontend/@n8n/design-system/src/components/N8nPromptInput/N8nPromptInput.vue b/packages/frontend/@n8n/design-system/src/components/N8nPromptInput/N8nPromptInput.vue index d965aef99f6..f5562d5a07f 100644 --- a/packages/frontend/@n8n/design-system/src/components/N8nPromptInput/N8nPromptInput.vue +++ b/packages/frontend/@n8n/design-system/src/components/N8nPromptInput/N8nPromptInput.vue @@ -22,6 +22,7 @@ export interface N8nPromptInputProps { creditsRemaining?: number; showAskOwnerTooltip?: boolean; refocusAfterSend?: boolean; + autofocus?: boolean; } const INFINITE_CREDITS = -1; @@ -38,6 +39,7 @@ const props = withDefaults(defineProps(), { creditsRemaining: undefined, showAskOwnerTooltip: false, refocusAfterSend: false, + autofocus: false, }); const emit = defineEmits<{ @@ -314,6 +316,10 @@ function focusInput() { onMounted(() => { // Adjust height on mount to respect minLines or initial content void nextTick(() => adjustHeight()); + + if (props.autofocus) { + focusInput(); + } }); defineExpose({