/** * Touch Target Size Utilities * * Ensures all interactive elements meet WCAG 2.5.5 (AAA) and mobile accessibility guidelines * - iOS Human Interface Guidelines: 44x44pt minimum * - Android Material Design: 48x48dp minimum * - WCAG 2.5.5: 44x44px minimum */ export const MINIMUM_TOUCH_TARGET = 44; // pixels export const RECOMMENDED_TOUCH_TARGET = 48; // pixels /** * Standard touch target styles for buttons and interactive elements */ export const touchTargetStyles = { minWidth: MINIMUM_TOUCH_TARGET, minHeight: MINIMUM_TOUCH_TARGET, }; /** * Recommended (larger) touch target styles */ export const recommendedTouchTargetStyles = { minWidth: RECOMMENDED_TOUCH_TARGET, minHeight: RECOMMENDED_TOUCH_TARGET, }; /** * Spacing around touch targets to prevent accidental taps * WCAG 2.5.8 (AAA): 24px spacing between targets */ export const MINIMUM_TOUCH_SPACING = 8; // pixels (relaxed for dense UIs) export const RECOMMENDED_TOUCH_SPACING = 16; // pixels /** * Apply touch target styles to MUI component sx prop */ export function withTouchTarget(existingSx?: object) { return { ...touchTargetStyles, ...existingSx, }; } /** * Apply recommended touch target styles to MUI component sx prop */ export function withRecommendedTouchTarget(existingSx?: object) { return { ...recommendedTouchTargetStyles, ...existingSx, }; } /** * Touch target configuration for different component types */ export const componentTouchTargets = { iconButton: { small: { minWidth: 36, minHeight: 36 }, // Below minimum - avoid using medium: touchTargetStyles, // Default - meets minimum large: recommendedTouchTargetStyles, // Recommended for primary actions }, button: { small: { minWidth: 64, minHeight: 32 }, // Text buttons medium: { minWidth: 88, minHeight: 36 }, // Standard buttons large: { minWidth: 120, minHeight: 48 }, // Primary actions }, chip: { small: { minHeight: 24 }, // Display only - not clickable medium: { minHeight: 32, minWidth: 32 }, // Clickable chips }, fab: { small: { width: 40, height: 40 }, // Below minimum - use with caution medium: { width: 56, height: 56 }, // Default FAB size large: { width: 64, height: 64 }, // Extended FAB }, listItem: { minHeight: 48, // Material Design list item height }, menuItem: { minHeight: 48, // Sufficient vertical space }, tab: { minHeight: 48, // Tab bar height minWidth: 90, // Minimum tab width }, }; /** * Validate if an element meets minimum touch target size */ export function validateTouchTarget(width: number, height: number): { valid: boolean; recommendations: string[]; } { const recommendations: string[] = []; if (width < MINIMUM_TOUCH_TARGET) { recommendations.push(`Width ${width}px is below minimum ${MINIMUM_TOUCH_TARGET}px`); } if (height < MINIMUM_TOUCH_TARGET) { recommendations.push(`Height ${height}px is below minimum ${MINIMUM_TOUCH_TARGET}px`); } if (width < RECOMMENDED_TOUCH_TARGET || height < RECOMMENDED_TOUCH_TARGET) { recommendations.push(`Consider using ${RECOMMENDED_TOUCH_TARGET}px for better accessibility`); } return { valid: width >= MINIMUM_TOUCH_TARGET && height >= MINIMUM_TOUCH_TARGET, recommendations, }; }