diff --git a/docs/quality/uygulama-durumu.md b/docs/quality/uygulama-durumu.md index 531ca94..d8d02d6 100644 --- a/docs/quality/uygulama-durumu.md +++ b/docs/quality/uygulama-durumu.md @@ -1199,3 +1199,12 @@ Taslak türü seçicisine erişilebilir ad eklendi. Üretim derlemesi geçti. Ö - Güncel iki favorinin filtresi yalnız Giresun/Kayseri ihalelerini gösterdi. Güncel sürümden Giresun kaldırılınca filtre tek Kayseri sonucuna düştü; diğer sekmenin yenilenmesinden sonra da aynı kayıt görüldü. Çakışma mesajı kullanıcıya değişikliklerini koruyup yenilemesi gerektiğini belirtiyor. Dokuz kontrol geçti: `rapor/qa-favorite-two-tabs.json`. - Kartlardaki kurum yıldızları aynı erişilebilir ada sahipti. Ekran okuyucu ve klavye kullanıcılarının eylemin hangi kuruma ait olduğunu ayırt edebilmesi için erişilebilir ada kurum unvanı eklendi; ekle/çıkar ve basılı durum bilgisi korunuyor. Derleme başarılı. Bu etiket değişimi için davranışı tekrar eden birim testi eklenmedi; önceki 275 test sonucu geçerli, tüm paket yeniden çalıştırılmadı. - Bu kabul iki sekmede favori ekleme/kaldırma ve filtre kalıcılığını kapsar. Bildirim gönderimi, ayrı firma rolleri veya bütün ekran okuyucu/klavye akışının kabulü değildir. Genel plan açık. + + +### 2026-09-06 — İhale ve analiz pencerelerinde klavye odağı + +- İhale detayının açılış kodu ilk button öğesini seçiyordu. Kaynak geçmişi eklendikten sonra bu öğe kapalı details içindeki Geçmişi yükle düğmesi oldu; odaklanma başarısız kalıyor ve klavyede Shift+Tab arka plandaki Excel Hazırla düğmesine gidiyordu. Tarayıcıda doğrudan tekrar üretildi. Kapalı details içindeki öğenin getClientRects değeri de boş değildi; yalnız geometri filtresi yeterli değildi. +- Ortak useModalFocus kancası görünür/etkin kontrolleri seçiyor, kapalı details içindeki summary dışı öğeleri, inert alanları ve devre dışı kontrolleri atlıyor. Tab/Shift+Tab sınırları, Escape ve açan öğeye dönüş ortaklaştırıldı. İhale detayının ilk odağı görünür kaynak geçmişi summary öğesinde; kapalı yükleme düğmesine odaklanılmıyor. +- Teknik şartname analiz penceresinde eksik olan dialog rolü, modal bilgisi, başlık bağlantısı ve odak yönetimi eklendi. Escape devam eden AI işini iptal etmiyor; mevcut Kapat düğmesiyle aynı pencere kapanışını yapıyor. +- On gerçek tarayıcı kontrolü geçti: iki pencerede başlangıç odağı, ileri/geri sarma, Escape sonrası açana dönüş; ihale üstünde analiz açılması ve Escape ile yalnız analiz kapanıp odağın alttaki açan düğmeye dönmesi. Kanıt `rapor/qa-modal-keyboard-focus.json`. Analiz için ilk sıcak yenileme denemesi eski görünümü gösterdiğinden sunucu yeniden başlatıldı ve güncel kodla tekrar doğrulandı; başarısız ilk deneme kabul sayılmadı. +- 275 test ve build başarılı. Bu kabul odak/klavye davranışını kapsar; bütün modallar, mobil klavye ve gerçek ekran okuyucunun sanal imleç davranışı henüz tamamlanmış sayılmaz. Genel plan açık. diff --git a/src/components/AiSpecAnalyzerModal.jsx b/src/components/AiSpecAnalyzerModal.jsx index d41de2b..3c4f937 100644 --- a/src/components/AiSpecAnalyzerModal.jsx +++ b/src/components/AiSpecAnalyzerModal.jsx @@ -1,6 +1,7 @@ import { AiJobHistory } from './AiJobHistory'; import {getToken} from '../services/auth'; -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, useId } from 'react'; +import {useModalFocus} from '../hooks/useModalFocus'; import { useApp } from '../context/AppContext'; import { Sparkles, Upload, FileText, CheckCircle2, AlertTriangle, X, Loader2, TrendingUp, Sliders, Info } from 'lucide-react'; import confetti from 'canvas-confetti'; @@ -14,6 +15,8 @@ export const AiSpecAnalyzerModal = () => { isAiSpecAnalyzerOpen, setIsAiSpecAnalyzerOpen, analyzeSpecPdfWithGemini, openSavedAnalysis, authUser, aiAnalysisResults, aiAnalyzing, aiJobStatus, activeAiModel, activeTenderDetail, } = useApp(); + const dialogTitleId=useId(); + const modalFocus=useModalFocus(isAiSpecAnalyzerOpen,()=>setIsAiSpecAnalyzerOpen(false)); const [isAnalyzing, setIsAnalyzing] = useState(false); const [selectedFile, setSelectedFile] = useState(null); @@ -96,7 +99,7 @@ export const AiSpecAnalyzerModal = () => { return (