chore: Svelte 5 syntax updates, a11y fixes, and dead CSS removal

Replace deprecated svelte:component with direct component invocation,
use span instead of label for non-input controls with role="group",
remove unused imports and dead CSS rules.
This commit is contained in:
2026-04-03 08:44:32 +02:00
parent 54a345224e
commit b7905b94fe
7 changed files with 20 additions and 35 deletions
@@ -3,7 +3,7 @@
import { getStickerById } from '$lib/utils/stickers'; import { getStickerById } from '$lib/utils/stickers';
import { import {
startOfMonth, endOfMonth, startOfWeek, endOfWeek, startOfMonth, endOfMonth, startOfWeek, endOfWeek,
eachDayOfInterval, isSameMonth, isSameDay, isToday, format, addMonths, subMonths eachDayOfInterval, isSameMonth, isToday, format, addMonths, subMonths
} from 'date-fns'; } from 'date-fns';
import { de } from 'date-fns/locale'; import { de } from 'date-fns/locale';
@@ -16,6 +16,7 @@
<!-- svelte-ignore a11y_no_static_element_interactions --> <!-- svelte-ignore a11y_no_static_element_interactions -->
<div class="popup-backdrop" transition:fade={{ duration: 200 }} onclick={onclose} onkeydown={e => e.key === 'Escape' && onclose?.()}> <div class="popup-backdrop" transition:fade={{ duration: 200 }} onclick={onclose} onkeydown={e => e.key === 'Escape' && onclose?.()}>
<!-- svelte-ignore a11y_no_static_element_interactions --> <!-- svelte-ignore a11y_no_static_element_interactions -->
<!-- svelte-ignore a11y_click_events_have_key_events -->
<div class="popup-card" transition:scale={{ start: 0.5, duration: 500, easing: elasticOut }} onclick={e => e.stopPropagation()}> <div class="popup-card" transition:scale={{ start: 0.5, duration: 500, easing: elasticOut }} onclick={e => e.stopPropagation()}>
<div class="sticker-display" style="--rarity-color: {getRarityColor(sticker.rarity)}"> <div class="sticker-display" style="--rarity-color: {getRarityColor(sticker.rarity)}">
<img class="sticker-img" src="/stickers/{sticker.image}" alt={sticker.name} /> <img class="sticker-img" src="/stickers/{sticker.image}" alt={sticker.name} />
+11 -11
View File
@@ -171,8 +171,8 @@
</div> </div>
<div class="field"> <div class="field">
<label>Zugewiesen an</label> <span class="label">Zugewiesen an</span>
<div class="assignee-buttons"> <div class="assignee-buttons" role="group" aria-label="Zugewiesen an">
{#each USERS as user} {#each USERS as user}
<button <button
type="button" type="button"
@@ -195,7 +195,7 @@
<!-- Tags: desktop = input + dropdown, mobile = pill buttons --> <!-- Tags: desktop = input + dropdown, mobile = pill buttons -->
<div class="field"> <div class="field">
<label>Tags</label> <span class="label">Tags</span>
<span class="hint">Bestimmen Sticker-Belohnungen</span> <span class="hint">Bestimmen Sticker-Belohnungen</span>
<!-- Desktop: input with dropdown --> <!-- Desktop: input with dropdown -->
@@ -212,9 +212,9 @@
/> />
{#if tagDropdownOpen && filteredDropdownTags.length > 0} {#if tagDropdownOpen && filteredDropdownTags.length > 0}
<div class="tag-dropdown"> <div class="tag-dropdown">
{#each filteredDropdownTags as { tag, icon }} {#each filteredDropdownTags as { tag, icon: Icon }}
<button type="button" class="tag-dropdown-item" onclick={() => selectDropdownTag(tag)}> <button type="button" class="tag-dropdown-item" onclick={() => selectDropdownTag(tag)}>
<svelte:component this={icon} size={14} /> <Icon size={14} />
{tag} {tag}
</button> </button>
{/each} {/each}
@@ -225,14 +225,14 @@
<!-- Mobile: pill buttons --> <!-- Mobile: pill buttons -->
<div class="tag-pills-mobile"> <div class="tag-pills-mobile">
{#each AVAILABLE_TAGS as { tag, icon }} {#each AVAILABLE_TAGS as { tag, icon: Icon }}
<button <button
type="button" type="button"
class="tag-pill" class="tag-pill"
class:selected={selectedTags.includes(tag)} class:selected={selectedTags.includes(tag)}
onclick={() => toggleTag(tag)} onclick={() => toggleTag(tag)}
> >
<svelte:component this={icon} size={14} /> <Icon size={14} />
{tag} {tag}
</button> </button>
{/each} {/each}
@@ -245,7 +245,7 @@
{@const Icon = getTagIcon(tag)} {@const Icon = getTagIcon(tag)}
<button type="button" class="tag-chip selected" onclick={() => toggleTag(tag)}> <button type="button" class="tag-chip selected" onclick={() => toggleTag(tag)}>
{#if Icon} {#if Icon}
<svelte:component this={Icon} size={13} /> <Icon size={13} />
{/if} {/if}
{tag} {tag}
<span class="remove-x">&times;</span> <span class="remove-x">&times;</span>
@@ -256,7 +256,7 @@
</div> </div>
<div class="field"> <div class="field">
<label>Schwierigkeit</label> <span class="label">Schwierigkeit</span>
<span class="hint">Schwerere Aufgaben geben seltenere Sticker</span> <span class="hint">Schwerere Aufgaben geben seltenere Sticker</span>
<div class="difficulty-buttons"> <div class="difficulty-buttons">
<button <button
@@ -323,7 +323,7 @@
{/if} {/if}
<div class="field"> <div class="field">
<label>Nächstes Fälligkeitsdatum berechnen ab</label> <span class="label">Nächstes Fälligkeitsdatum berechnen ab</span>
<div class="refresh-mode-buttons"> <div class="refresh-mode-buttons">
<button <button
type="button" type="button"
@@ -404,7 +404,7 @@
.field { .field {
margin-bottom: 0.75rem; margin-bottom: 0.75rem;
} }
.field label { .field label, .field .label {
display: block; display: block;
font-size: 0.78rem; font-size: 0.78rem;
font-weight: 600; font-weight: 600;
@@ -1,6 +1,6 @@
<script lang="ts"> <script lang="ts">
import { enhance } from '$app/forms'; import { enhance } from '$app/forms';
import { tick } from 'svelte'; import { tick, untrack } from 'svelte';
import type { ActionData, PageData } from './$types'; import type { ActionData, PageData } from './$types';
import SaveFab from '$lib/components/SaveFab.svelte'; import SaveFab from '$lib/components/SaveFab.svelte';
import Cross from '$lib/assets/icons/Cross.svelte'; import Cross from '$lib/assets/icons/Cross.svelte';
@@ -282,7 +282,7 @@
// Pre-init all toggles to false (prevents bind:checked={undefined}), then load real state // Pre-init all toggles to false (prevents bind:checked={undefined}), then load real state
initGlobalToggles(); initGlobalToggles();
if (nutritionMappings.length > 0) { if (untrack(() => nutritionMappings).length > 0) {
loadGlobalOverwrites().then(() => { loadGlobalOverwrites().then(() => {
// Re-init with real overwrite data (overwrite the false defaults) // Re-init with real overwrite data (overwrite the false defaults)
for (const m of nutritionMappings) { for (const m of nutritionMappings) {
@@ -474,20 +474,6 @@
h3 { h3 {
text-align: center; text-align: center;
} }
button.action_button {
animation: unset !important;
font-size: 1.3rem;
color: white;
}
.submit_buttons {
display: flex;
margin-inline: auto;
max-width: 1000px;
margin-block: 1rem;
justify-content: center;
align-items: center;
gap: 2rem;
}
@media (prefers-color-scheme: dark) { @media (prefers-color-scheme: dark) {
:global(:root:not([data-theme="light"])) .title { :global(:root:not([data-theme="light"])) .title {
background-color: var(--nord6-dark); background-color: var(--nord6-dark);
@@ -932,9 +932,6 @@
align-items: stretch; align-items: stretch;
} }
.main-actions {
flex-direction: column;
}
.amount-currency { .amount-currency {
flex-direction: column; flex-direction: column;
@@ -535,8 +535,8 @@
</div> </div>
{/if} {/if}
<div class="editor-gps-options"> <div class="editor-gps-options">
<label class="editor-label">Activity</label> <span class="editor-label">Activity</span>
<div class="activity-chips"> <div class="activity-chips" role="group" aria-label="Activity">
{#each /** @type {const} */ (['running', 'walking', 'cycling', 'hiking']) as act} {#each /** @type {const} */ (['running', 'walking', 'cycling', 'hiking']) as act}
<button <button
class="activity-chip" class="activity-chip"
@@ -547,7 +547,7 @@
{/each} {/each}
</div> </div>
<label class="editor-label">Interval Training</label> <span class="editor-label">Interval Training</span>
<div class="interval-select"> <div class="interval-select">
<button <button
class="interval-option" class="interval-option"
+2 -1
View File
@@ -270,7 +270,8 @@
{#each task.tags as tag} {#each task.tags as tag}
<span class="tag"> <span class="tag">
{#if TAG_ICONS[tag]} {#if TAG_ICONS[tag]}
<svelte:component this={TAG_ICONS[tag]} size={14} /> {@const Icon = TAG_ICONS[tag]}
<Icon size={14} />
{/if} {/if}
{tag} {tag}
</span> </span>