a11y(web-dashboard): add aria labels, roles, and live regions to interactive components
- EmergencyControls: aria-label on all buttons and confirmation input - OrderForm: aria-label and aria-pressed on buy/sell toggle buttons - DashboardLayout: aria-label on navigation - StatusBar: aria-live on connection status, aria-hidden on decorative indicator dot Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -36,7 +36,7 @@ export function DashboardLayout({ children }: Props) {
|
||||
return (
|
||||
<div className="flex flex-col h-screen">
|
||||
{/* Top navigation */}
|
||||
<nav className="flex items-center gap-1 px-4 py-2 bg-[var(--color-bg-secondary)] border-b border-[var(--color-border)]">
|
||||
<nav aria-label="Dashboard navigation" className="flex items-center gap-1 px-4 py-2 bg-[var(--color-bg-secondary)] border-b border-[var(--color-border)]">
|
||||
<span className="text-sm font-bold text-[var(--color-accent)] mr-4">FOXHUNT</span>
|
||||
{NAV_ITEMS.map((item) => (
|
||||
<NavLink
|
||||
|
||||
@@ -12,11 +12,12 @@ export function StatusBar() {
|
||||
return (
|
||||
<footer className="flex items-center justify-between px-4 py-1 text-xs bg-[var(--color-bg-secondary)] border-t border-[var(--color-border)] text-[var(--color-text-secondary)]">
|
||||
<div className="flex items-center gap-4">
|
||||
<span className="flex items-center gap-1">
|
||||
<span className="flex items-center gap-1" aria-live="polite">
|
||||
<span
|
||||
className={`inline-block w-2 h-2 rounded-full ${
|
||||
connected ? 'bg-[var(--color-green)]' : 'bg-[var(--color-red)]'
|
||||
}`}
|
||||
aria-hidden="true"
|
||||
/>
|
||||
WS: {connected ? 'Connected' : 'Disconnected'}
|
||||
</span>
|
||||
@@ -29,6 +30,7 @@ export function StatusBar() {
|
||||
{authenticated && (
|
||||
<button
|
||||
onClick={logout}
|
||||
aria-label="Sign out of the trading system"
|
||||
className="text-[var(--color-text-secondary)] hover:text-[var(--color-red)] transition-colors"
|
||||
>
|
||||
Sign Out
|
||||
|
||||
@@ -26,6 +26,7 @@ export function EmergencyControls() {
|
||||
{!showConfirm ? (
|
||||
<button
|
||||
onClick={() => setShowConfirm(true)}
|
||||
aria-label="Trigger emergency stop — cancels all orders and closes all positions"
|
||||
className="w-full py-3 text-sm font-bold rounded bg-[var(--color-red)] text-white hover:bg-red-600 transition-colors"
|
||||
>
|
||||
EMERGENCY STOP
|
||||
@@ -40,6 +41,7 @@ export function EmergencyControls() {
|
||||
value={confirmText}
|
||||
onChange={(e) => setConfirmText(e.target.value)}
|
||||
placeholder="Type STOP"
|
||||
aria-label="Type STOP to confirm emergency shutdown"
|
||||
className="w-full px-2 py-1.5 text-sm rounded border border-[var(--color-red)] bg-[var(--color-bg-primary)] text-[var(--color-text-primary)] outline-none"
|
||||
autoFocus
|
||||
/>
|
||||
@@ -49,6 +51,7 @@ export function EmergencyControls() {
|
||||
setShowConfirm(false);
|
||||
setConfirmText('');
|
||||
}}
|
||||
aria-label="Cancel emergency stop"
|
||||
className="py-1.5 text-xs rounded border border-[var(--color-border)] text-[var(--color-text-secondary)] hover:text-[var(--color-text-primary)]"
|
||||
>
|
||||
Cancel
|
||||
@@ -56,6 +59,7 @@ export function EmergencyControls() {
|
||||
<button
|
||||
onClick={handleEmergencyStop}
|
||||
disabled={confirmText !== 'STOP' || emergencyStop.isPending}
|
||||
aria-label="Confirm emergency stop"
|
||||
className="py-1.5 text-xs rounded bg-[var(--color-red)] text-white disabled:opacity-50"
|
||||
>
|
||||
{emergencyStop.isPending ? 'Stopping...' : 'Confirm STOP'}
|
||||
|
||||
@@ -64,6 +64,8 @@ export function OrderForm() {
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setSide('buy')}
|
||||
aria-label="Set order side to buy"
|
||||
aria-pressed={side === 'buy'}
|
||||
className={`py-1.5 text-sm rounded font-medium transition-colors ${
|
||||
side === 'buy'
|
||||
? 'bg-[var(--color-green)] text-white'
|
||||
@@ -75,6 +77,8 @@ export function OrderForm() {
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setSide('sell')}
|
||||
aria-label="Set order side to sell"
|
||||
aria-pressed={side === 'sell'}
|
||||
className={`py-1.5 text-sm rounded font-medium transition-colors ${
|
||||
side === 'sell'
|
||||
? 'bg-[var(--color-red)] text-white'
|
||||
|
||||
Reference in New Issue
Block a user