UNPKG

claritykit-svelte

Version:

A comprehensive Svelte component library focused on accessibility, ADHD-optimized design, developer experience, and full SSR compatibility

317 lines (316 loc) 11.7 kB
/** * Therapeutic Component Accessibility Utilities * * Specialized accessibility functions for therapeutic and ADHD-focused components * that go beyond standard accessibility to support neurodivergent users. */ import { announceForADHD, getADHDRecommendations } from './adhd-focus-management.js'; // Default configuration const defaultConfig = { enableContextualHelp: true, enableProgressAnnouncements: true, enableEmotionalSupport: true, enableCrisisDetection: true, announceEveryNthAction: 3, emotionalSupportMessages: true }; let config = { ...defaultConfig }; /** * Initialize therapeutic accessibility system */ export function initTherapeuticAccessibility(userConfig) { if (userConfig) { config = { ...defaultConfig, ...userConfig }; } } /** * Create comprehensive ARIA descriptions for therapeutic components */ export function createTherapeuticAriaDescription(component) { const parts = []; // Component identification parts.push(`${component.type} therapeutic component.`); // Purpose and benefits parts.push(`Purpose: ${component.purpose}.`); if (component.benefits.length > 0) { parts.push(`Benefits: ${component.benefits.join(', ')}.`); } // Current state if (component.currentState) { parts.push(`Current state: ${component.currentState}.`); } // Usage guidance parts.push(`Usage: ${component.usage}.`); // Interaction guidance if (component.interactions && component.interactions.length > 0) { parts.push(`Available interactions: ${component.interactions.join(', ')}.`); } // Help availability if (component.helpAvailable !== false) { parts.push('Press h anytime for contextual help.'); } return parts.join(' '); } /** * Generate contextual help for therapeutic components */ export function generateContextualHelp(component) { const helpParts = []; helpParts.push(`Help for ${component.type}:`); // Current mode context if (component.currentMode) { helpParts.push(`Currently in ${component.currentMode} mode.`); } // Available actions if (component.availableActions && component.availableActions.length > 0) { helpParts.push(`Available actions: ${component.availableActions.join(', ')}.`); } // Keyboard shortcuts if (component.keyboardShortcuts) { const shortcuts = Object.entries(component.keyboardShortcuts) .map(([key, action]) => `${key} for ${action}`) .join(', '); helpParts.push(`Keyboard shortcuts: ${shortcuts}.`); } // Tips if (component.tips && component.tips.length > 0) { helpParts.push(`Tips: ${component.tips.join('. ')}.`); } // General help helpParts.push('Press Escape to cancel or exit. Take breaks when needed.'); return helpParts.join(' '); } /** * Announce mood or energy state changes with emotional support */ export function announceMoodChange(change) { let message = ''; // Determine change direction const isImprovement = typeof change.newValue === 'number' && typeof change.previousValue === 'number' ? change.newValue > change.previousValue : false; // Base announcement if (isImprovement) { message = `Mood improved to ${change.label}. ${change.description}.`; if (config.enableEmotionalSupport) { message += ' Well done for tracking your mood.'; } } else { message = `Mood changed to ${change.label}. ${change.description}.`; if (config.enableEmotionalSupport) { message += ' Remember, all feelings are valid.'; } } // Add context if provided if (change.context) { message += ` ${change.context}`; } announceForADHD(change.component, message, 'medium'); } /** * Announce energy level changes with adaptive guidance */ export function announceEnergyChange(change) { let message = `Energy level changed to ${change.newLevel}. ${change.description}.`; // Add adaptive suggestions if (change.suggestions && change.suggestions.length > 0) { message += ` Suggestions: ${change.suggestions.join(', ')}.`; } // Add supportive context if (config.enableEmotionalSupport) { if (change.newLevel === 'low') { message += ' It\'s okay to rest when you need to.'; } else if (change.newLevel === 'high' || change.newLevel === 'very-high') { message += ' Great energy! Consider channeling it into meaningful activities.'; } } announceForADHD(change.component, message, 'medium'); } /** * Announce breathing exercise progress with calming guidance */ export function announceBreathingProgress(progress) { let message = ''; if (progress.paused) { message = 'Breathing exercise paused. Take your time. Resume when ready.'; } else { // Phase-specific guidance const phaseGuidance = { inhale: 'Breathe in slowly and deeply', hold: 'Hold gently, stay present', exhale: 'Release slowly, let go of tension' }; message = phaseGuidance[progress.phase]; // Progress context if (progress.cycleCount > 0 && progress.cycleCount % 3 === 0) { message += `. Completed ${progress.cycleCount} cycles. You're doing well.`; } } announceForADHD(progress.component, message, 'low'); } /** * Announce crisis mode changes with clear guidance */ export function announceCrisisModeChange(change) { let message = ''; if (change.activated && change.severity) { message = `Crisis mode activated at ${change.severity} level. Interface simplified to reduce cognitive load.`; // Add guidance based on severity switch (change.severity) { case 'severe': message += ' Only essential functions are shown. Press Escape anytime to deactivate.'; break; case 'moderate': message += ' Interface is simplified. You have access to main functions.'; break; case 'mild': message += ' Minor simplifications applied. Most functions remain available.'; break; } if (config.enableEmotionalSupport) { message += ' You are safe. Take things one step at a time.'; } } else { message = 'Crisis mode deactivated. Full interface restored. You did well managing the situation.'; } announceForADHD(change.component, message, 'high', true); } /** * Provide progress announcements for multi-step therapeutic processes */ export function announceTherapeuticProgress(progress) { let message = ''; if (progress.completed) { message = `Process completed! You finished all ${progress.totalSteps} steps.`; if (config.enableEmotionalSupport) { message += ' Well done for taking care of your mental health.'; } } else { message = `Step ${progress.currentStep} of ${progress.totalSteps}`; if (progress.stepName) { message += `: ${progress.stepName}`; } // Add encouragement at certain milestones if (progress.encouragement && progress.currentStep > 1) { const percentage = Math.round((progress.currentStep / progress.totalSteps) * 100); if (percentage >= 50) { message += `. You're ${percentage}% through - keep going!`; } } } announceForADHD(progress.component, message, 'medium'); } /** * Handle therapeutic component errors with supportive messaging */ export function announceTherapeuticError(error) { let message = `${error.message}`; // Add suggestion if available if (error.suggestion) { message += ` ${error.suggestion}`; } // Add reassurance for therapeutic contexts if (error.reassurance !== false && config.enableEmotionalSupport) { switch (error.type) { case 'validation': message += ' Take your time, there\'s no rush.'; break; case 'connection': message += ' Technical issues happen. Your progress is still valuable.'; break; case 'timeout': message += ' This might be a good time for a brief break.'; break; default: message += ' It\'s okay to pause and try again when ready.'; } } announceForADHD(error.component, message, 'high', true); } /** * Generate ADHD-friendly keyboard shortcut descriptions */ export function createKeyboardShortcutDescription(shortcuts) { const descriptions = Object.entries(shortcuts).map(([key, action]) => { // Make key combinations more readable const readableKey = key .replace('Ctrl+', 'Control ') .replace('Shift+', 'Shift ') .replace('Alt+', 'Alt ') .replace('Cmd+', 'Command ') .replace('Meta+', 'Command '); return `${readableKey} for ${action}`; }); return `Keyboard shortcuts: ${descriptions.join(', ')}. Press h anytime for help.`; } /** * Create accessible state announcements for complex therapeutic components */ export function announceComplexState(state) { const parts = []; // Main state parts.push(state.mainState); // Key details (limit to avoid overwhelming) const importantDetails = Object.entries(state.details) .slice(0, 3) // Limit to 3 most important details .map(([key, value]) => `${key}: ${value}`) .join(', '); if (importantDetails) { parts.push(importantDetails); } // User actions if (state.userActions && state.userActions.length > 0) { const actions = state.userActions.slice(0, 2).join(' or '); // Limit to 2 actions parts.push(`You can ${actions}`); } // Context if (state.context) { parts.push(state.context); } const message = parts.join('. ') + '.'; announceForADHD(state.component, message, 'medium'); } /** * Smart help system that adapts to user behavior patterns */ export function provideAdaptiveHelp(component, context) { const recommendations = getADHDRecommendations(component); const helpParts = []; // Start with contextual help helpParts.push('Help available:'); // Address specific struggles if (context.userStruggles && context.userStruggles.length > 0) { helpParts.push(`Common challenges: ${context.userStruggles.join(', ')}`); } // Time-based suggestions if (context.timeSpent && context.timeSpent > 30000) { // 30 seconds helpParts.push('Taking longer than expected? Consider breaking this into smaller steps.'); } // Repeat attempt guidance if (context.repeatAttempts && context.repeatAttempts > 3) { helpParts.push('Multiple attempts detected. Try using keyboard navigation or taking a short break.'); } // ADHD-specific recommendations if (recommendations.length > 0) { helpParts.push(`ADHD support: ${recommendations.slice(0, 2).join('. ')}`); } // Always end with encouragement if (config.enableEmotionalSupport) { helpParts.push('Remember: progress over perfection. You\'re doing great.'); } return helpParts.join(' '); } /** * Export configuration getter/setter */ export function getTherapeuticAccessibilityConfig() { return { ...config }; } export function updateTherapeuticAccessibilityConfig(updates) { config = { ...config, ...updates }; }