mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-22 16:46:42 +02:00
♿️ 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:
parent
b949037fa5
commit
42e5e97390
101 changed files with 1048 additions and 558 deletions
|
|
@ -1,34 +0,0 @@
|
|||
<script lang="ts">
|
||||
/**
|
||||
* Icon Component - Uses @manacore/shared-icons
|
||||
* Phosphor Icons (Bold weight)
|
||||
*/
|
||||
import { iconPaths } from '@manacore/shared-icons';
|
||||
|
||||
interface Props {
|
||||
name: keyof typeof iconPaths;
|
||||
size?: number;
|
||||
class?: string;
|
||||
color?: string;
|
||||
}
|
||||
|
||||
let { name, size = 24, class: className = '', color }: Props = $props();
|
||||
|
||||
const path = $derived(iconPaths[name]);
|
||||
</script>
|
||||
|
||||
{#if path}
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={size}
|
||||
height={size}
|
||||
fill={color || 'currentColor'}
|
||||
viewBox="0 0 256 256"
|
||||
class={className}
|
||||
aria-hidden="true"
|
||||
>
|
||||
{@html path}
|
||||
</svg>
|
||||
{:else}
|
||||
<span class="text-red-500" title="Icon '{name}' not found">⚠</span>
|
||||
{/if}
|
||||
|
|
@ -3,11 +3,11 @@
|
|||
import { deckStore } from '$lib/stores/deckStore.svelte';
|
||||
|
||||
interface Props {
|
||||
open?: boolean;
|
||||
onClose?: () => void;
|
||||
visible: boolean;
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
let { open = $bindable(false), onClose }: Props = $props();
|
||||
let { visible, onClose }: Props = $props();
|
||||
|
||||
let title = $state('');
|
||||
let description = $state('');
|
||||
|
|
@ -42,13 +42,12 @@
|
|||
tags = '';
|
||||
|
||||
// Close modal
|
||||
open = false;
|
||||
onClose?.();
|
||||
onClose();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<Modal bind:open title="Create New Deck" {onClose}>
|
||||
<Modal {visible} title="Create New Deck" {onClose}>
|
||||
<form
|
||||
onsubmit={(e) => {
|
||||
e.preventDefault();
|
||||
|
|
@ -59,8 +58,9 @@
|
|||
<Input label="Deck Title" bind:value={title} placeholder="e.g., Spanish Vocabulary" required />
|
||||
|
||||
<div class="space-y-2">
|
||||
<label class="text-sm font-medium">Description</label>
|
||||
<label for="deck-description" class="text-sm font-medium">Description</label>
|
||||
<textarea
|
||||
id="deck-description"
|
||||
bind:value={description}
|
||||
placeholder="What is this deck about?"
|
||||
class="flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
|
||||
|
|
@ -96,8 +96,7 @@
|
|||
type="button"
|
||||
variant="ghost"
|
||||
onclick={() => {
|
||||
open = false;
|
||||
onClose?.();
|
||||
onClose();
|
||||
}}
|
||||
>
|
||||
Cancel
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@
|
|||
let userEmail = $derived(authStore.user?.email);
|
||||
|
||||
// Navigation shortcuts (Ctrl+1-5)
|
||||
const navRoutes = navItems.map((item) => item.href);
|
||||
const navRoutes = $derived(navItems.map((item) => item.href));
|
||||
|
||||
function handleKeydown(event: KeyboardEvent) {
|
||||
const target = event.target as HTMLElement;
|
||||
|
|
|
|||
|
|
@ -74,4 +74,4 @@
|
|||
</div>
|
||||
|
||||
<!-- Create Deck Modal -->
|
||||
<CreateDeckModal bind:open={showCreateModal} />
|
||||
<CreateDeckModal visible={showCreateModal} onClose={() => (showCreateModal = false)} />
|
||||
|
|
|
|||
|
|
@ -151,13 +151,19 @@
|
|||
|
||||
<!-- Delete Confirmation Modal -->
|
||||
{#if showDeleteConfirm}
|
||||
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
||||
<div
|
||||
class="fixed inset-0 z-50 flex items-center justify-center bg-black/50"
|
||||
onclick={() => (showDeleteConfirm = false)}
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
tabindex="-1"
|
||||
>
|
||||
<!-- svelte-ignore a11y_no_noninteractive_element_interactions a11y_click_events_have_key_events -->
|
||||
<div
|
||||
class="bg-surface-elevated rounded-lg shadow-xl max-w-md w-full mx-4 p-6"
|
||||
onclick={(e) => e.stopPropagation()}
|
||||
role="document"
|
||||
>
|
||||
<h3 class="text-xl font-semibold mb-2">Delete Deck?</h3>
|
||||
<p class="text-muted-foreground mb-6">
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue