fix: manage guide and profile modal keyboard focus
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import {HealthPortfolioEditor} from './HealthPortfolioEditor';
|
||||
import React,{useState,useEffect,useRef,useId} from 'react';
|
||||
import {useModalFocus} from '../hooks/useModalFocus';
|
||||
import {useApp} from '../context/AppContext';
|
||||
import {getToken} from '../services/auth';
|
||||
import {X,Loader2} from 'lucide-react';
|
||||
@@ -13,10 +14,11 @@ function ProfileEditor(){
|
||||
const [url,setUrl]=useState(userProfile.website || ''),[caps,setCaps]=useState(userProfile.scrapedCapabilities || {});
|
||||
const [threshold,setThreshold]=useState(uyumEsigi),[busy,setBusy]=useState(''),[error,setError]=useState(null),[message,setMessage]=useState('');
|
||||
const [entries,setEntries]=useState({});
|
||||
const alive=useRef(true),controller=useRef(null),locked=useRef(false),root=useRef(null),titleId=useId();
|
||||
const alive=useRef(true),controller=useRef(null),locked=useRef(false),titleId=useId();
|
||||
const modalFocus=useModalFocus(true,()=>setIsCompanyScannerOpen(false));
|
||||
useEffect(()=>{
|
||||
alive.current=true;const opener=document.activeElement;root.current?.querySelector('button')?.focus();
|
||||
return()=>{alive.current=false;controller.current?.abort();if(opener?.isConnected)opener.focus();};
|
||||
alive.current=true;
|
||||
return()=>{alive.current=false;controller.current?.abort();};
|
||||
},[]);
|
||||
const run=async(kind,operation)=>{
|
||||
if(locked.current)return;locked.current=true;setBusy(kind);setError(null);setMessage('');
|
||||
@@ -32,16 +34,8 @@ function ProfileEditor(){
|
||||
if(alive.current)setMessage('Firma profili sunucuya kaydedildi. Eşleşmeler kayıtlı profilinizle güncellenir.');
|
||||
});
|
||||
const edit=(key,values)=>{setCaps(previous=>({...previous,[key]:values}));setMessage('Kaydedilmemiş değişiklikler var.');};
|
||||
const keyDown=e=>{
|
||||
if(e.key==='Escape'){e.preventDefault();e.stopPropagation();setIsCompanyScannerOpen(false);}
|
||||
if(e.key!=='Tab')return;
|
||||
const controls=[...root.current.querySelectorAll('button,input,select,textarea,a[href]')].filter(el=>!el.disabled&&el.getClientRects().length);
|
||||
const first=controls[0],last=controls.at(-1);
|
||||
if(e.shiftKey&&document.activeElement===first){e.preventDefault();last?.focus();}
|
||||
else if(!e.shiftKey&&document.activeElement===last){e.preventDefault();first?.focus();}
|
||||
};
|
||||
return <div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-slate-900/70">
|
||||
<section ref={root} role="dialog" aria-modal="true" aria-labelledby={titleId} onKeyDown={keyDown} className="bg-white rounded-2xl w-full max-w-3xl max-h-[92vh] overflow-y-auto p-5 space-y-4">
|
||||
<section {...modalFocus} role="dialog" aria-modal="true" aria-labelledby={titleId} tabIndex={-1} className="bg-white rounded-2xl w-full max-w-3xl max-h-[92vh] overflow-y-auto p-5 space-y-4">
|
||||
<div className="flex justify-between gap-3"><h2 id={titleId} className="font-bold text-lg">Firma ürün ve faaliyet profili</h2><button aria-label="Firma profilini kapat" onClick={()=>setIsCompanyScannerOpen(false)}><X/></button></div>
|
||||
<p className="text-sm text-slate-600">Ürünlerinizi elle ekleyebilir veya web sitenizden öneri alabilirsiniz. Tarama, ürün uygunluğunu ya da ÜTS/sertifika geçerliliğini doğrulamaz. Kaydetmeden kapatırsanız bu ekrandaki değişiklikler uygulanmaz.</p>
|
||||
<form onSubmit={scan} className="flex gap-2 items-end flex-wrap">
|
||||
|
||||
Reference in New Issue
Block a user