a11y: add ARIA live regions for status announcements and errors

This commit is contained in:
TypoGenie
2026-02-18 23:35:52 +02:00
parent d0f88625b5
commit e460f4df68
4 changed files with 40 additions and 17 deletions

View File

@@ -141,6 +141,7 @@ export const Preview: React.FC<PreviewProps> = ({
const [successMsg, setSuccessMsg] = useState(false);
const [showExportModal, setShowExportModal] = useState(false);
const [focusedElement, setFocusedElement] = useState<'back' | 'fonts' | 'save'>('save');
const [exportError, setExportError] = useState<string | null>(null);
// Get current style from templates
const style = templates.find(s => s.id === selectedStyleId) || templates[0] || null;
@@ -242,7 +243,7 @@ export const Preview: React.FC<PreviewProps> = ({
}
} catch (e) {
console.error("Docx Gen Error", e);
alert("Failed to generate DOCX: " + e);
setExportError("Failed to generate DOCX: " + e);
} finally {
setIsExporting(false);
}
@@ -375,7 +376,7 @@ export const Preview: React.FC<PreviewProps> = ({
}, [htmlContent, paperSize, selectedStyleId, templates, style]);
if (!style) {
return <div className="h-screen flex items-center justify-center text-white">Loading...</div>;
return <div className="h-screen flex items-center justify-center text-white" role="status">Loading...</div>;
}
return (
@@ -399,6 +400,7 @@ export const Preview: React.FC<PreviewProps> = ({
onClick={handleSave}
onFocus={() => setFocusedElement('save')}
disabled={isExporting}
aria-live="polite"
whileHover={{ scale: 1.05, boxShadow: '0 0 20px rgba(59, 130, 246, 0.4)' }}
whileTap={{ scale: 0.95 }}
className={`flex items-center gap-2 px-5 py-2.5 rounded-lg font-semibold transition-colors shadow-lg ${successMsg ? 'bg-emerald-600 text-white' : 'bg-blue-600 text-white hover:bg-blue-500'} ${isExporting ? 'opacity-50 cursor-wait' : ''}`}
@@ -431,6 +433,12 @@ export const Preview: React.FC<PreviewProps> = ({
onClose={() => setShowExportModal(false)}
onExport={handleExportConfirm}
/>
{exportError && (
<div role="alert" className="fixed bottom-4 right-4 z-50 p-4 bg-red-900/90 border border-red-800 rounded-xl text-red-200 max-w-md">
{exportError}
<button onClick={() => setExportError(null)} className="ml-3 text-red-400 hover:text-white" aria-label="Dismiss error">&#10005;</button>
</div>
)}
</motion.div>
);
};