️ fix: resolve all svelte-check a11y warnings across web apps

- Fix 121 accessibility warnings across 9 web apps (manacore, clock, chat,
  manadeck, calendar, zitare, contacts, picture, todo)
- Add proper ARIA attributes (role, tabindex, aria-label) to interactive elements
- Add onkeydown handlers alongside onclick for keyboard accessibility
- Add svelte-ignore comments for intentional patterns (modals, dropdowns)
- Update svelte-check threshold from error to warning in pre-commit hook
- Fix script compatibility for bash 3.x (remove associative arrays)
- Add comprehensive documentation for svelte-check patterns and fixes

All web apps now pass svelte-check with 0 errors and 0 warnings.
Pre-commit hooks will block any future commits with warnings.
This commit is contained in:
Wuesteon 2025-12-15 19:09:01 +01:00
parent b949037fa5
commit 42e5e97390
101 changed files with 1048 additions and 558 deletions

View file

@ -107,6 +107,7 @@
{#if editingId === conv.id}
<!-- Edit Mode -->
<div class="flex items-center gap-1 px-3 py-2 mx-2">
<!-- svelte-ignore a11y_autofocus - Intentional for edit mode UX -->
<input
type="text"
bind:value={editTitle}

View file

@ -66,11 +66,11 @@
onSubmit({
id: template?.id,
name,
description: description.trim() || null,
description: description.trim() || undefined,
systemPrompt: systemPrompt,
initialQuestion: initialQuestion.trim() || null,
initialQuestion: initialQuestion.trim() || undefined,
color: selectedColor,
modelId: selectedModelId || null,
modelId: selectedModelId || undefined,
documentMode: documentMode,
});
}
@ -169,8 +169,8 @@
<!-- Color -->
<div>
<label class="block text-sm font-medium text-foreground mb-2"> Farbe </label>
<div class="flex flex-wrap gap-2">
<span class="block text-sm font-medium text-foreground mb-2" id="color-label">Farbe</span>
<div class="flex flex-wrap gap-2" role="group" aria-labelledby="color-label">
{#each TEMPLATE_COLORS as color}
<button
type="button"

View file

@ -123,7 +123,7 @@ export const authStore = {
const userData = await authService.getUserFromToken();
user = userData;
return { success: true, error: null };
return { success: true };
} catch (error) {
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
return { success: false, error: errorMessage };
@ -148,7 +148,7 @@ export const authStore = {
// Mana Core Auth requires separate login after signup
if (result.needsVerification) {
return { success: true, error: null, needsVerification: true };
return { success: true, needsVerification: true };
}
// Auto sign in after successful signup
@ -196,7 +196,7 @@ export const authStore = {
return { success: false, error: result.error || 'Password reset failed' };
}
return { success: true, error: null };
return { success: true };
} catch (error) {
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
return { success: false, error: errorMessage };

View file

@ -166,9 +166,24 @@
</SettingsCard>
<div class="flex flex-wrap gap-4 text-sm mt-2">
<a href="#" class="text-[hsl(var(--primary))] hover:underline">Datenschutz</a>
<a href="#" class="text-[hsl(var(--primary))] hover:underline">Nutzungsbedingungen</a>
<a href="#" class="text-[hsl(var(--primary))] hover:underline">Hilfe & Support</a>
<button
onclick={() => alert('Datenschutz-Seite wird bald verfügbar sein.')}
class="text-[hsl(var(--primary))] hover:underline"
>
Datenschutz
</button>
<button
onclick={() => alert('Nutzungsbedingungen werden bald verfügbar sein.')}
class="text-[hsl(var(--primary))] hover:underline"
>
Nutzungsbedingungen
</button>
<button
onclick={() => alert('Hilfe & Support wird bald verfügbar sein.')}
class="text-[hsl(var(--primary))] hover:underline"
>
Hilfe & Support
</button>
</div>
</SettingsSection>
</SettingsPage>

View file

@ -81,11 +81,11 @@
await templatesStore.createTemplate({
userId: authStore.user.id,
name: data.name!,
description: data.description ?? null,
description: data.description,
systemPrompt: data.systemPrompt!,
initialQuestion: data.initialQuestion ?? null,
initialQuestion: data.initialQuestion,
color: data.color!,
modelId: data.modelId ?? null,
modelId: data.modelId,
isDefault: false,
documentMode: data.documentMode ?? false,
});