fix(connection): fix new connection dialog title focus

This commit is contained in:
zipg 2026-07-24 23:49:53 +08:00 committed by GitHub
parent f2ce70dd68
commit 80ef2e579e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 15 additions and 12 deletions

View File

@ -1,4 +1,5 @@
<script setup lang="ts">
import type { ObjectDirective } from "vue";
import { computed, nextTick, onMounted, onUnmounted, ref, watch } from "vue";
import { uuid } from "@/lib/common/utils";
import { useI18n } from "vue-i18n";
@ -2749,11 +2750,11 @@ function backToDatabasePicker() {
resetTestState();
}
function handleDialogOpenAutoFocus(event: Event) {
event.preventDefault();
if (!(event.currentTarget instanceof HTMLElement)) return;
event.currentTarget.querySelector<HTMLElement>("[data-connection-dialog-title]")?.focus({ preventScroll: true });
}
const vConnectionDialogAutoFocus: ObjectDirective<HTMLInputElement> = {
mounted(input) {
input.focus({ preventScroll: true });
},
};
function handleDialogEscape(event: KeyboardEvent) {
if (dialogStep.value !== "config" || editingId.value) return;
@ -4512,9 +4513,9 @@ function openExternalUrl(url: string) {
<template>
<Dialog v-model:open="open">
<DialogContent class="connection-dialog-content" :class="connectionDialogContentClass" :data-wide="shouldUseWideConnectionDialog ? 'true' : undefined" @interact-outside.prevent @open-auto-focus="handleDialogOpenAutoFocus" @escape-key-down="handleDialogEscape">
<DialogContent class="connection-dialog-content" :class="connectionDialogContentClass" :data-wide="shouldUseWideConnectionDialog ? 'true' : undefined" @interact-outside.prevent @escape-key-down="handleDialogEscape">
<DialogHeader>
<DialogTitle data-connection-dialog-title tabindex="-1">{{ editingId ? t("connection.editTitle") : t("connection.title") }}</DialogTitle>
<DialogTitle>{{ editingId ? t("connection.editTitle") : t("connection.title") }}</DialogTitle>
</DialogHeader>
<template v-if="dialogStep === 'select'">
@ -4549,7 +4550,7 @@ function openExternalUrl(url: string) {
</div>
<div class="relative w-full sm:w-64">
<Search class="absolute left-2.5 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
<Input v-model="dbSearchQuery" class="h-9 pl-8" :placeholder="t('connection.searchDatabasePlaceholder')" />
<Input v-model="dbSearchQuery" v-connection-dialog-auto-focus class="h-9 pl-8" :placeholder="t('connection.searchDatabasePlaceholder')" />
</div>
</div>
<Button data-jdbc-connection-entry type="button" variant="outline" class="h-9 shrink-0 gap-2" @click="goToConnectionStep('jdbc')">
@ -4665,7 +4666,7 @@ function openExternalUrl(url: string) {
<div class="grid grid-cols-4 items-center gap-4">
<Label :class="connectionLabelClass">{{ t("connection.name") }}</Label>
<Input v-model="form.name" class="col-span-3" :placeholder="t('connection.namePlaceholder')" />
<Input v-model="form.name" v-connection-dialog-auto-focus class="col-span-3" :placeholder="t('connection.namePlaceholder')" />
</div>
<div class="grid grid-cols-4 items-center gap-4">

View File

@ -4,9 +4,11 @@ import { describe, expect, it } from "vitest";
const dialogSource = readFileSync(new URL("../../../components/connection/ConnectionDialog.vue", import.meta.url), "utf8");
describe("connection dialog accessibility", () => {
it("moves initial focus to the dialog title instead of the dialog container", () => {
expect(dialogSource).toContain('<DialogTitle data-connection-dialog-title tabindex="-1">');
expect(dialogSource).toContain('querySelector<HTMLElement>("[data-connection-dialog-title]")?.focus({ preventScroll: true })');
it("moves initial focus to an input inside the dialog", () => {
expect(dialogSource).toContain('<Input v-model="dbSearchQuery" v-connection-dialog-auto-focus');
expect(dialogSource).toContain('<Input v-model="form.name" v-connection-dialog-auto-focus');
expect(dialogSource).toContain("const vConnectionDialogAutoFocus: ObjectDirective<HTMLInputElement>");
expect(dialogSource).toContain("input.focus({ preventScroll: true })");
expect(dialogSource).not.toMatch(/<DialogContent[^>]*\stabindex="-1"/);
});