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
JavaScript
/**
* 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 };
}