fix: localize UI to English and add ARIA accessibility attributes
- Replace all French UI strings with English (Connected, Thinking, Result, Send, etc.) - Add role="log" + aria-live="polite" to chat message area - Add role="form" + aria-label to message input area - Add aria-label to sidebar toggle, attach file, send, and textarea - Add role="banner" to header, role="navigation" to sidebar - Add role="application" to app root
This commit is contained in:
@@ -43,7 +43,7 @@ export function Chat({ messages, isGenerating, status, onSend, onAbort }: Props)
|
||||
|
||||
return (
|
||||
<div className="flex-1 flex flex-col min-h-0">
|
||||
<div className="flex-1 overflow-y-auto">
|
||||
<div className="flex-1 overflow-y-auto" role="log" aria-label="Chat messages" aria-live="polite">
|
||||
<div className="max-w-4xl mx-auto py-4">
|
||||
{messages.length === 0 && (
|
||||
<div className="flex flex-col items-center justify-center h-[60vh] text-zinc-500">
|
||||
@@ -54,7 +54,7 @@ export function Chat({ messages, isGenerating, status, onSend, onAbort }: Props)
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-lg text-zinc-200 font-semibold">PinchChat</div>
|
||||
<div className="text-sm mt-1 text-zinc-500">Envoie un message pour commencer</div>
|
||||
<div className="text-sm mt-1 text-zinc-500">Send a message to get started</div>
|
||||
</div>
|
||||
)}
|
||||
{messages.filter(hasVisibleContent).map(msg => (
|
||||
|
||||
@@ -179,6 +179,8 @@ export function ChatInput({ onSend, onAbort, isGenerating, disabled }: Props) {
|
||||
return (
|
||||
<div
|
||||
className="border-t border-white/8 bg-[#1a1a20]/60 backdrop-blur-xl p-4"
|
||||
role="form"
|
||||
aria-label="Message input"
|
||||
onDragOver={handleDragOver}
|
||||
onDragLeave={handleDragLeave}
|
||||
onDrop={handleDrop}
|
||||
@@ -216,7 +218,8 @@ export function ChatInput({ onSend, onAbort, isGenerating, disabled }: Props) {
|
||||
onClick={() => fileInputRef.current?.click()}
|
||||
disabled={disabled}
|
||||
className="shrink-0 h-11 w-11 rounded-2xl border border-white/8 bg-zinc-800/30 flex items-center justify-center text-zinc-400 hover:text-cyan-300 hover:bg-white/5 transition-colors disabled:opacity-30"
|
||||
title="Joindre un fichier"
|
||||
title="Attach file"
|
||||
aria-label="Attach file"
|
||||
>
|
||||
<Paperclip size={18} />
|
||||
</button>
|
||||
@@ -235,7 +238,8 @@ export function ChatInput({ onSend, onAbort, isGenerating, disabled }: Props) {
|
||||
onChange={(e) => setText(e.target.value)}
|
||||
onKeyDown={handleKeyDown}
|
||||
onPaste={handlePaste}
|
||||
placeholder="Écris un message…"
|
||||
placeholder="Type a message…"
|
||||
aria-label="Message"
|
||||
disabled={disabled}
|
||||
rows={1}
|
||||
className="flex-1 bg-transparent resize-none rounded-2xl border border-white/8 bg-zinc-900/35 px-4 py-3 text-sm text-zinc-300 placeholder:text-zinc-500 outline-none focus:ring-2 focus:ring-cyan-400/30 transition-all max-h-[200px]"
|
||||
@@ -252,10 +256,11 @@ export function ChatInput({ onSend, onAbort, isGenerating, disabled }: Props) {
|
||||
<button
|
||||
onClick={handleSubmit}
|
||||
disabled={(!text.trim() && files.length === 0) || disabled}
|
||||
aria-label="Send message"
|
||||
className="shrink-0 h-11 px-5 rounded-2xl bg-gradient-to-r from-cyan-500/80 via-indigo-500/70 to-violet-500/80 text-zinc-900 font-semibold text-sm hover:opacity-90 shadow-[0_8px_24px_rgba(34,211,238,0.1)] disabled:opacity-30 disabled:shadow-none transition-all flex items-center gap-2"
|
||||
>
|
||||
<Send size={16} />
|
||||
<span className="hidden sm:inline">Envoyer</span>
|
||||
<span className="hidden sm:inline">Send</span>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -13,8 +13,8 @@ export function Header({ status, sessionKey, onToggleSidebar, activeSessionData
|
||||
|
||||
return (
|
||||
<>
|
||||
<header className="h-14 border-b border-white/8 bg-[#232329]/90 backdrop-blur-xl flex items-center px-4 gap-3 shrink-0">
|
||||
<button onClick={onToggleSidebar} className="lg:hidden p-2 rounded-2xl hover:bg-white/5 text-zinc-400 transition-colors">
|
||||
<header className="h-14 border-b border-white/8 bg-[#232329]/90 backdrop-blur-xl flex items-center px-4 gap-3 shrink-0" role="banner">
|
||||
<button onClick={onToggleSidebar} aria-label="Toggle sidebar" className="lg:hidden p-2 rounded-2xl hover:bg-white/5 text-zinc-400 transition-colors">
|
||||
<Menu size={20} />
|
||||
</button>
|
||||
<div className="flex items-center gap-3 flex-1 min-w-0">
|
||||
@@ -33,17 +33,17 @@ export function Header({ status, sessionKey, onToggleSidebar, activeSessionData
|
||||
{status === 'connected' ? (
|
||||
<div className="flex items-center gap-2 rounded-2xl border border-white/8 bg-zinc-800/30 px-3 py-1.5">
|
||||
<span className="w-2 h-2 rounded-full bg-cyan-300/80 shadow-[0_0_12px_rgba(34,211,238,0.6)]" />
|
||||
<span className="text-xs text-zinc-300 hidden sm:inline">Connecté</span>
|
||||
<span className="text-xs text-zinc-300 hidden sm:inline">Connected</span>
|
||||
</div>
|
||||
) : status === 'connecting' ? (
|
||||
<div className="flex items-center gap-2 rounded-2xl border border-white/8 bg-zinc-800/30 px-3 py-1.5">
|
||||
<span className="w-2 h-2 rounded-full bg-yellow-400/80 pulse-dot" />
|
||||
<span className="text-xs text-zinc-300 hidden sm:inline">Connexion…</span>
|
||||
<span className="text-xs text-zinc-300 hidden sm:inline">Connecting…</span>
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex items-center gap-2 rounded-2xl border border-white/8 bg-zinc-800/30 px-3 py-1.5">
|
||||
<span className="w-2 h-2 rounded-full bg-red-400/80" />
|
||||
<span className="text-xs text-zinc-300 hidden sm:inline">Déconnecté</span>
|
||||
<span className="text-xs text-zinc-300 hidden sm:inline">Disconnected</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -13,7 +13,7 @@ export function Sidebar({ sessions, activeSession, onSwitch, open, onClose }: Pr
|
||||
return (
|
||||
<>
|
||||
{open && <div className="fixed inset-0 bg-black/60 backdrop-blur-sm z-40 lg:hidden" onClick={onClose} />}
|
||||
<aside className={`fixed lg:relative top-0 left-0 h-full w-72 bg-[#1e1e24]/95 border-r border-white/8 z-50 transform transition-transform lg:translate-x-0 ${open ? 'translate-x-0' : '-translate-x-full'} flex flex-col backdrop-blur-xl`}>
|
||||
<aside role="navigation" aria-label="Sessions" className={`fixed lg:relative top-0 left-0 h-full w-72 bg-[#1e1e24]/95 border-r border-white/8 z-50 transform transition-transform lg:translate-x-0 ${open ? 'translate-x-0' : '-translate-x-full'} flex flex-col backdrop-blur-xl`}>
|
||||
<div className="h-14 flex items-center justify-between px-4 border-b border-white/8">
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="relative">
|
||||
@@ -30,7 +30,7 @@ export function Sidebar({ sessions, activeSession, onSwitch, open, onClose }: Pr
|
||||
</div>
|
||||
<div className="flex-1 overflow-y-auto py-2 px-2">
|
||||
{sessions.length === 0 && (
|
||||
<div className="px-3 py-8 text-center text-zinc-500 text-sm">Aucune session</div>
|
||||
<div className="px-3 py-8 text-center text-zinc-500 text-sm">No sessions</div>
|
||||
)}
|
||||
{sessions.map(s => {
|
||||
const isActive = s.key === activeSession;
|
||||
|
||||
@@ -11,7 +11,7 @@ export function ThinkingBlock({ text }: { text: string }) {
|
||||
className="inline-flex items-center gap-1.5 rounded-2xl border border-white/8 bg-zinc-800/35 px-3 py-1.5 text-xs text-violet-300 hover:bg-white/5 transition-colors"
|
||||
>
|
||||
<Brain size={13} />
|
||||
<span className="font-medium">Réflexion</span>
|
||||
<span className="font-medium">Thinking</span>
|
||||
{open ? <ChevronDown size={12} className="ml-1 text-zinc-500" /> : <ChevronRight size={12} className="ml-1 text-zinc-500" />}
|
||||
</button>
|
||||
{open && (
|
||||
|
||||
@@ -188,7 +188,7 @@ export function ToolCall({ name, input, result }: { name: string; input?: any; r
|
||||
)}
|
||||
{result && (
|
||||
<div>
|
||||
<div className={`text-[11px] ${c.text} opacity-70 mb-1 font-medium`}>Résultat</div>
|
||||
<div className={`text-[11px] ${c.text} opacity-70 mb-1 font-medium`}>Result</div>
|
||||
<HighlightedPre
|
||||
text={result}
|
||||
className="text-xs bg-[#1a1a20]/60 border border-white/5 p-2.5 rounded-xl overflow-x-auto text-zinc-300 max-h-64 overflow-y-auto font-mono"
|
||||
|
||||
Reference in New Issue
Block a user