From da0689cb01e600f2a491e4590dc89f4df564fcaa Mon Sep 17 00:00:00 2001 From: 0xMosas Date: Mon, 18 May 2026 16:17:41 +0100 Subject: [PATCH 01/14] convert CategoryOption and SortOptionItem divs to buttons --- frontend/src/components/MarketFilter.tsx | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/frontend/src/components/MarketFilter.tsx b/frontend/src/components/MarketFilter.tsx index 9d303523..3a537c34 100644 --- a/frontend/src/components/MarketFilter.tsx +++ b/frontend/src/components/MarketFilter.tsx @@ -43,17 +43,18 @@ interface CategoryOptionProps { } const CategoryOption = memo(({ category, isSelected, onSelect }: CategoryOptionProps) => ( -
onSelect(category.value)} - className={`px-4 py-2 cursor-pointer hover:bg-neutral-100 dark:hover:bg-neutral-800 ${ + className={`w-full text-left px-4 py-2 cursor-pointer hover:bg-neutral-100 dark:hover:bg-neutral-800 ${ isSelected ? 'bg-blue-50 dark:bg-blue-900/20 text-blue-600 dark:text-blue-400' : '' }`} > {category.icon} {category.label} -
+ )); interface SortOptionItemProps { @@ -63,16 +64,17 @@ interface SortOptionItemProps { } const SortOptionItem = memo(({ option, isSelected, onSelect }: SortOptionItemProps) => ( -
onSelect(option.value)} - className={`px-4 py-2 cursor-pointer hover:bg-neutral-100 dark:hover:bg-neutral-800 ${ + className={`w-full text-left px-4 py-2 cursor-pointer hover:bg-neutral-100 dark:hover:bg-neutral-800 ${ isSelected ? 'bg-blue-50 dark:bg-blue-900/20 text-blue-600 dark:text-blue-400' : '' }`} > {option.label} -
+ )); export function MarketFilter({ From 20054c589fe87bc1e59d7f4cc20cb4b9716269fb Mon Sep 17 00:00:00 2001 From: 0xMosas Date: Mon, 18 May 2026 16:18:03 +0100 Subject: [PATCH 02/14] add onKeyDown handler and aria attributes to wizard step buttons --- frontend/src/components/WizardProgress.tsx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/WizardProgress.tsx b/frontend/src/components/WizardProgress.tsx index eaf54a68..07c4b9f3 100644 --- a/frontend/src/components/WizardProgress.tsx +++ b/frontend/src/components/WizardProgress.tsx @@ -108,8 +108,16 @@ export function WizardProgress({ key={index} style={stepStyle(index)} onClick={() => onStepClick?.(index)} + onKeyDown={(e) => { + if (e.key === 'Enter' || e.key === ' ') { + e.preventDefault(); + onStepClick?.(index); + } + }} role="button" - tabIndex={0} + tabIndex={onStepClick ? 0 : -1} + aria-label={`Step ${index + 1}: ${label}`} + aria-current={index === currentStep ? 'step' : undefined} >
{index < currentStep ? '✓' : index + 1} From 841738b03313ed0d6ed6c7b87a5b12587ee73cd7 Mon Sep 17 00:00:00 2001 From: 0xMosas Date: Mon, 18 May 2026 16:22:48 +0100 Subject: [PATCH 03/14] convert AMMPoolCard interactive div to button element --- frontend/src/components/AMMComponents.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/AMMComponents.tsx b/frontend/src/components/AMMComponents.tsx index ab6156cb..08199dd7 100644 --- a/frontend/src/components/AMMComponents.tsx +++ b/frontend/src/components/AMMComponents.tsx @@ -15,7 +15,11 @@ export function AMMPoolCard({ poolId, onSelect }: PoolCardProps) { if (!pool) return
Pool not found
; return ( -
onSelect(poolId)}> +
-
+ ); } From 7feae5a924b8f2b40221065c3302992973edfe0c Mon Sep 17 00:00:00 2001 From: 0xMosas Date: Mon, 18 May 2026 16:23:12 +0100 Subject: [PATCH 04/14] convert indicator badge div to button in CompactIndicatorPanel --- frontend/src/components/ResponsiveChart.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/ResponsiveChart.tsx b/frontend/src/components/ResponsiveChart.tsx index 5e897931..d4358c1f 100644 --- a/frontend/src/components/ResponsiveChart.tsx +++ b/frontend/src/components/ResponsiveChart.tsx @@ -191,14 +191,15 @@ export function CompactIndicatorPanel({
{indicators.slice(0, 3).map(indicator => ( -
onShowDetails?.(indicator.name)} > {indicator.name} {indicator.value.toFixed(2)} -
+ ))} {indicators.length > 3 && (
From 2170973030e6f2cd78b3d31ac5aba789a6387db7 Mon Sep 17 00:00:00 2001 From: 0xMosas Date: Tue, 19 May 2026 12:43:54 +0100 Subject: [PATCH 05/14] replace interactive divs with buttons in RBAC examples --- frontend/src/examples/RBACExamples.tsx | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/frontend/src/examples/RBACExamples.tsx b/frontend/src/examples/RBACExamples.tsx index 4b2e0935..520b51a0 100644 --- a/frontend/src/examples/RBACExamples.tsx +++ b/frontend/src/examples/RBACExamples.tsx @@ -118,7 +118,15 @@ export function APIServiceExample() { } } - return
performOperation()}>Perform Operation
; + return ( + + ); } export function ResourceAccessExample() { @@ -183,5 +191,13 @@ export function ValidationExample() { }; } - return
validateSetup()}>Validate System
; + return ( + + ); } From e226c3244f8b29beb8784c3819a88a122f03b499 Mon Sep 17 00:00:00 2001 From: 0xMosas Date: Tue, 19 May 2026 12:45:03 +0100 Subject: [PATCH 06/14] add keyboard support and aria-sort to sortable table headers --- frontend/src/components/AuditLogViewer.tsx | 27 +++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/AuditLogViewer.tsx b/frontend/src/components/AuditLogViewer.tsx index 9cfb8d1e..c08576b4 100644 --- a/frontend/src/components/AuditLogViewer.tsx +++ b/frontend/src/components/AuditLogViewer.tsx @@ -173,16 +173,37 @@ export function AuditLogViewer({ auditLogger, pageSize = 20 }: AuditLogViewerPro - - - From dacd0d51984a42bf53801b5f5d5566486c83ffe3 Mon Sep 17 00:00:00 2001 From: 0xMosas Date: Tue, 19 May 2026 14:40:23 +0100 Subject: [PATCH 07/14] add Escape key handler and dialog role to governance modal overlays --- frontend/src/pages/GovernancePage.tsx | 30 +++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/frontend/src/pages/GovernancePage.tsx b/frontend/src/pages/GovernancePage.tsx index 9a64c581..8c179416 100644 --- a/frontend/src/pages/GovernancePage.tsx +++ b/frontend/src/pages/GovernancePage.tsx @@ -721,8 +721,19 @@ export function GovernancePage() { {/* Proposal Detail Modal */} {selectedProposal && ( -
setSelectedProposal(null)}> -
e.stopPropagation()}> +
setSelectedProposal(null)} + onKeyDown={(e) => { if (e.key === 'Escape') setSelectedProposal(null); }} + role="presentation" + > +
e.stopPropagation()} + role="dialog" + aria-modal="true" + aria-label={selectedProposal.title} + > @@ -906,8 +917,19 @@ export function GovernancePage() { {/* Delegate Modal */} {showDelegateModal && ( -
setShowDelegateModal(false)}> -
e.stopPropagation()}> +
setShowDelegateModal(false)} + onKeyDown={(e) => { if (e.key === 'Escape') setShowDelegateModal(false); }} + role="presentation" + > +
e.stopPropagation()} + role="dialog" + aria-modal="true" + aria-label="Delegate Voting Power" + > From dc9ba5107b7304c88764af3c662d3bdd53689172 Mon Sep 17 00:00:00 2001 From: 0xMosas Date: Tue, 19 May 2026 17:01:10 +0100 Subject: [PATCH 08/14] add keyboard support to dispute card expand toggle --- frontend/src/components/DisputeCard.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frontend/src/components/DisputeCard.tsx b/frontend/src/components/DisputeCard.tsx index be52dda9..5449f6cf 100644 --- a/frontend/src/components/DisputeCard.tsx +++ b/frontend/src/components/DisputeCard.tsx @@ -46,6 +46,10 @@ export function DisputeCard({
setExpanded(!expanded)} + onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); setExpanded(!expanded); } }} + role="button" + tabIndex={0} + aria-expanded={expanded} >
From 14111edeaf64ada987962b8d629cb86723ee02f0 Mon Sep 17 00:00:00 2001 From: 0xMosas Date: Tue, 19 May 2026 17:02:26 +0100 Subject: [PATCH 09/14] add Escape key handler to mobile bottom sheet backdrop --- frontend/src/components/MobileBottomSheet.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/frontend/src/components/MobileBottomSheet.tsx b/frontend/src/components/MobileBottomSheet.tsx index 5fa68ef4..b4dc1a55 100644 --- a/frontend/src/components/MobileBottomSheet.tsx +++ b/frontend/src/components/MobileBottomSheet.tsx @@ -39,6 +39,9 @@ export function MobileBottomSheet({
{ if (e.key === 'Escape') onClose(); }} + role="presentation" + tabIndex={-1} />
Date: Tue, 19 May 2026 23:20:31 +0100 Subject: [PATCH 10/14] add keyboard navigation to oracle card compact and full variants --- frontend/src/components/OracleCard.tsx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/frontend/src/components/OracleCard.tsx b/frontend/src/components/OracleCard.tsx index 08024066..4fd6adcf 100644 --- a/frontend/src/components/OracleCard.tsx +++ b/frontend/src/components/OracleCard.tsx @@ -30,6 +30,10 @@ const OracleCardBase = ({ oracle, onSelect, compact = false }: OracleCardProps)
onSelect?.(oracle.address)} + onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); onSelect?.(oracle.address); } }} + role="button" + tabIndex={onSelect ? 0 : undefined} + aria-label={`Select oracle ${oracle.address}`} >
@@ -50,6 +54,10 @@ const OracleCardBase = ({ oracle, onSelect, compact = false }: OracleCardProps)
onSelect?.(oracle.address)} + onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); onSelect?.(oracle.address); } }} + role="button" + tabIndex={onSelect ? 0 : undefined} + aria-label={`Select oracle ${oracle.address}`} > {/* Header */}
From 4206605e7886ba06eebe288a14ca1a921dce6138 Mon Sep 17 00:00:00 2001 From: 0xMosas Date: Tue, 19 May 2026 23:21:15 +0100 Subject: [PATCH 11/14] add keyboard navigation to proposal card --- frontend/src/components/ProposalCard.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frontend/src/components/ProposalCard.tsx b/frontend/src/components/ProposalCard.tsx index 3c864cfe..9f4681a6 100644 --- a/frontend/src/components/ProposalCard.tsx +++ b/frontend/src/components/ProposalCard.tsx @@ -53,6 +53,10 @@ export function ProposalCard({ return (
onSelect(proposal)} + onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); onSelect(proposal); } }} + role="button" + tabIndex={0} + aria-label={`View proposal: ${proposal.title}`} style={{ backgroundColor: '#0A0A0A', border: '1px solid #1F1F1F', From 746398d2649b1712c391544762b80357538ca285 Mon Sep 17 00:00:00 2001 From: 0xMosas Date: Tue, 19 May 2026 23:38:24 +0100 Subject: [PATCH 12/14] add keyboard navigation to oracle health dashboard provider cards --- frontend/src/components/OracleHealthDashboard.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frontend/src/components/OracleHealthDashboard.tsx b/frontend/src/components/OracleHealthDashboard.tsx index c3ea161b..0df47aeb 100644 --- a/frontend/src/components/OracleHealthDashboard.tsx +++ b/frontend/src/components/OracleHealthDashboard.tsx @@ -140,6 +140,10 @@ export const OracleHealthDashboard: React.FC = ({ key={stat.provider} className={`border p-4 rounded-lg cursor-pointer transition ${getStatusColor(stat)}`} onClick={() => setSelectedProvider(stat.provider)} + onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); setSelectedProvider(stat.provider); } }} + role="button" + tabIndex={0} + aria-label={`View details for oracle provider ${stat.provider}`} >

{stat.provider}

From 092babe4ca005a66ac024b259635510514d31d6e Mon Sep 17 00:00:00 2001 From: 0xMosas Date: Tue, 19 May 2026 23:40:25 +0100 Subject: [PATCH 13/14] add keyboard navigation to indicator panel, drawing tools, role cards, and chart legend --- frontend/src/components/ChartLegend.tsx | 4 ++++ frontend/src/components/DrawingToolsPanel.tsx | 4 ++++ frontend/src/components/IndicatorPanel.tsx | 4 ++++ frontend/src/components/RoleManagementDashboard.tsx | 4 ++++ 4 files changed, 16 insertions(+) diff --git a/frontend/src/components/ChartLegend.tsx b/frontend/src/components/ChartLegend.tsx index a896ae99..45255e55 100644 --- a/frontend/src/components/ChartLegend.tsx +++ b/frontend/src/components/ChartLegend.tsx @@ -61,6 +61,10 @@ export function TechnicalIndicatorLegend({ key={indicator.name} className="indicator-item" onClick={() => onToggleIndicator?.(indicator.name)} + onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); onToggleIndicator?.(indicator.name); } }} + role="button" + tabIndex={onToggleIndicator ? 0 : undefined} + aria-label={`Toggle indicator ${indicator.name}`} >
{indicator.color && ( diff --git a/frontend/src/components/DrawingToolsPanel.tsx b/frontend/src/components/DrawingToolsPanel.tsx index 91dd6de9..f86111bc 100644 --- a/frontend/src/components/DrawingToolsPanel.tsx +++ b/frontend/src/components/DrawingToolsPanel.tsx @@ -72,6 +72,10 @@ export function DrawingToolsPanel({ onClick={() => setExpandedToolId(expandedToolId === tool.id ? null : tool.id) } + onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); setExpandedToolId(expandedToolId === tool.id ? null : tool.id); } }} + role="button" + tabIndex={0} + aria-expanded={expandedToolId === tool.id} >
{ if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); setExpandedIndicator(expandedIndicator === indicator.name ? null : indicator.name); } }} + role="button" + tabIndex={0} + aria-expanded={expandedIndicator === indicator.name} >
handleRoleSelect(role.id)} + onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); handleRoleSelect(role.id); } }} + role="button" + tabIndex={0} + aria-pressed={selectedRoleId === role.id} >

{role.name}

From b2bfb76721da8962b3cd235e7fe57aba397a22d7 Mon Sep 17 00:00:00 2001 From: 0xMosas Date: Tue, 19 May 2026 23:40:35 +0100 Subject: [PATCH 14/14] add Escape key handler to mobile modal and network switch dialog backdrops --- frontend/src/components/MobileModal.tsx | 3 +++ frontend/src/components/NetworkSwitchDialog.tsx | 3 +++ 2 files changed, 6 insertions(+) diff --git a/frontend/src/components/MobileModal.tsx b/frontend/src/components/MobileModal.tsx index 1d62fb62..e7dfe0dc 100644 --- a/frontend/src/components/MobileModal.tsx +++ b/frontend/src/components/MobileModal.tsx @@ -46,6 +46,9 @@ export function MobileModal({
{ if (e.key === 'Escape') onClose(); }} + role="presentation" + tabIndex={-1} />
{ if (e.key === 'Escape') onCancel(); }} + role="presentation" + tabIndex={-1} /> {/* Dialog */}
handleSort('timestamp')} className="sortable"> + handleSort('timestamp')} + onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); handleSort('timestamp'); } }} + className="sortable" + tabIndex={0} + role="columnheader" + aria-sort={sortBy === 'timestamp' ? (sortOrder === 'asc' ? 'ascending' : 'descending') : 'none'} + > Timestamp {sortBy === 'timestamp' && (sortOrder === 'asc' ? '↑' : '↓')} User ID handleSort('action')} className="sortable"> + handleSort('action')} + onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); handleSort('action'); } }} + className="sortable" + tabIndex={0} + role="columnheader" + aria-sort={sortBy === 'action' ? (sortOrder === 'asc' ? 'ascending' : 'descending') : 'none'} + > Action {sortBy === 'action' && (sortOrder === 'asc' ? '↑' : '↓')} Resource Resource ID handleSort('status')} className="sortable"> + handleSort('status')} + onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); handleSort('status'); } }} + className="sortable" + tabIndex={0} + role="columnheader" + aria-sort={sortBy === 'status' ? (sortOrder === 'asc' ? 'ascending' : 'descending') : 'none'} + > Status {sortBy === 'status' && (sortOrder === 'asc' ? '↑' : '↓')} Details