fix: clear build warnings across svelte components

Resolves 16 vite-plugin-svelte warnings: state_referenced_locally
(wrap prop reads in untrack), two a11y issues (ConfirmDialog tabindex
+ key handler, meal entry role/list), and nine unused CSS selectors.
Bump to 1.40.2.
This commit is contained in:
2026-04-21 11:22:04 +02:00
parent 38824cc054
commit 2087970f46
13 changed files with 25 additions and 60 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "homepage", "name": "homepage",
"version": "1.40.1", "version": "1.40.2",
"private": true, "private": true,
"type": "module", "type": "module",
"scripts": { "scripts": {
+8 -1
View File
@@ -14,7 +14,14 @@
{#if dialog.open} {#if dialog.open}
<div class="confirm-backdrop" onclick={() => dialog.respond(false)} role="presentation"> <div class="confirm-backdrop" onclick={() => dialog.respond(false)} role="presentation">
<div class="confirm-dialog" onclick={(e) => e.stopPropagation()} role="alertdialog" aria-modal="true"> <div
class="confirm-dialog"
onclick={(e) => e.stopPropagation()}
onkeydown={(e) => e.stopPropagation()}
role="alertdialog"
aria-modal="true"
tabindex="-1"
>
{#if dialog.title} {#if dialog.title}
<h3 class="confirm-title">{dialog.title}</h3> <h3 class="confirm-title">{dialog.title}</h3>
{/if} {/if}
+1 -1
View File
@@ -337,7 +337,7 @@
} }
// Recreate chart when lang changes // Recreate chart when lang changes
let prevLang = lang; let prevLang = untrack(() => lang);
$effect(() => { $effect(() => {
const currentLang = lang; const currentLang = lang;
if (currentLang !== prevLang) { if (currentLang !== prevLang) {
+2 -1
View File
@@ -1,6 +1,7 @@
<script> <script>
import { page } from '$app/stores'; import { page } from '$app/stores';
import { browser } from '$app/environment'; import { browser } from '$app/environment';
import { untrack } from 'svelte';
import { Heart, ExternalLink, ScanBarcode, X } from '@lucide/svelte'; import { Heart, ExternalLink, ScanBarcode, X } from '@lucide/svelte';
import { detectFitnessLang, fitnessSlugs, t } from '$lib/js/fitnessI18n'; import { detectFitnessLang, fitnessSlugs, t } from '$lib/js/fitnessI18n';
import MacroBreakdown from './MacroBreakdown.svelte'; import MacroBreakdown from './MacroBreakdown.svelte';
@@ -35,7 +36,7 @@
// --- Search state --- // --- Search state ---
let query = $state(''); let query = $state('');
let results = $state(initialResults ?? []); let results = $state(untrack(() => initialResults ?? []));
let loading = $state(false); let loading = $state(false);
let timeout = $state(null); let timeout = $state(null);
const isPrefilledMode = $derived(initialResults != null); const isPrefilledMode = $derived(initialResults != null);
@@ -1372,14 +1372,6 @@
font-weight: 600; font-weight: 600;
color: var(--color-text-secondary); color: var(--color-text-secondary);
} }
.add-row input {
padding: 0.4rem 0.5rem;
border: 1px solid var(--color-border);
border-radius: 6px;
background: var(--color-bg-tertiary);
color: var(--color-text-primary);
font-size: 0.8rem;
}
.add-actions { .add-actions {
display: flex; display: flex;
gap: 0.5rem; gap: 0.5rem;
@@ -441,6 +441,7 @@
text-overflow: ellipsis; text-overflow: ellipsis;
display: -webkit-box; display: -webkit-box;
-webkit-line-clamp: 2; -webkit-line-clamp: 2;
line-clamp: 2;
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
} }
.hero-ing-grams { .hero-ing-grams {
@@ -12,6 +12,7 @@ import { confirm } from '$lib/js/confirmDialog.svelte'
import { do_on_key } from '$lib/components/recipes/do_on_key.js' import { do_on_key } from '$lib/components/recipes/do_on_key.js'
import { portions } from '$lib/js/portions_store.js' import { portions } from '$lib/js/portions_store.js'
import BaseRecipeSelector from '$lib/components/recipes/BaseRecipeSelector.svelte' import BaseRecipeSelector from '$lib/components/recipes/BaseRecipeSelector.svelte'
import { untrack } from 'svelte'
let { let {
lang = 'de' as 'de' | 'en', lang = 'de' as 'de' | 'en',
@@ -25,9 +26,9 @@ let {
useStore?: boolean, useStore?: boolean,
}>(); }>();
let portions_local = $state<string | undefined>(portionsProp) let portions_local = $state<string | undefined>(untrack(() => portionsProp))
if (useStore) { if (untrack(() => useStore)) {
portions.subscribe((p: any) => { portions.subscribe((p: any) => {
portions_local = p portions_local = p
}); });
@@ -672,8 +672,7 @@ ol li::marker{
.info-value:focus{ .info-value:focus{
border-bottom-color: var(--color-border); border-bottom-color: var(--color-border);
} }
.info-value:empty::before, .info-value:empty::before{
.info-value span:empty::before{
content: attr(data-placeholder); content: attr(data-placeholder);
color: var(--color-text-tertiary); color: var(--color-text-tertiary);
font-style: italic; font-style: italic;
-1
View File
@@ -423,7 +423,6 @@
color: var(--color-text-secondary, #666); color: var(--color-text-secondary, #666);
} }
.field input[type="text"], .field input[type="text"],
.field input[type="date"],
.field input[type="number"], .field input[type="number"],
.field textarea, .field textarea,
.field select { .field select {
@@ -1,5 +1,5 @@
<script> <script>
import { onMount, onDestroy } from 'svelte'; import { onMount, onDestroy, untrack } from 'svelte';
import { getShoppingSync } from '$lib/js/shoppingSync.svelte'; import { getShoppingSync } from '$lib/js/shoppingSync.svelte';
import { SHOPPING_CATEGORIES } from '$lib/data/shoppingCategoryItems'; import { SHOPPING_CATEGORIES } from '$lib/data/shoppingCategoryItems';
import { Plus, ListX, Apple, Beef, Milk, Croissant, Wheat, FlameKindling, GlassWater, Candy, Snowflake, SprayCan, Sparkles, Package, Search, Store } from '@lucide/svelte'; import { Plus, ListX, Apple, Beef, Milk, Croissant, Wheat, FlameKindling, GlassWater, Candy, Snowflake, SprayCan, Sparkles, Package, Search, Store } from '@lucide/svelte';
@@ -21,9 +21,11 @@
const sync = getShoppingSync(); const sync = getShoppingSync();
// Seed sync state immediately so SSR can render the list // Seed sync state immediately so SSR can render the list
if (data.initialList) { untrack(() => {
sync.seed(data.initialList, data.shareToken); if (data.initialList) {
} sync.seed(data.initialList, data.shareToken);
}
});
const lang = $derived(detectCospendLang($page.url.pathname)); const lang = $derived(detectCospendLang($page.url.pathname));
const loc = $derived(locale(lang)); const loc = $derived(locale(lang));
@@ -789,9 +789,6 @@
.section-toggle:hover { .section-toggle:hover {
background: var(--color-surface-hover, var(--color-bg-elevated)); background: var(--color-surface-hover, var(--color-bg-elevated));
} }
.section-toggle + .section-toggle {
margin-top: 0.5rem;
}
.section-toggle-left { .section-toggle-left {
display: flex; display: flex;
align-items: center; align-items: center;
@@ -1156,9 +1153,4 @@
opacity: 1; opacity: 1;
} }
@media (max-width: 480px) {
.stat-grid {
grid-template-columns: 1fr;
}
}
</style> </style>
@@ -350,10 +350,6 @@
.stat-delta.down { color: var(--green); } .stat-delta.down { color: var(--green); }
.stat-delta.flat { color: var(--color-text-tertiary); } .stat-delta.flat { color: var(--color-text-tertiary); }
.chart-wrap {
/* FitnessChart has its own card styling */
}
.empty { .empty {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -1771,7 +1771,7 @@
{/if} {/if}
</div> </div>
<div class="meal-entries"> <div class="meal-entries" role="list">
{#each mealEntries as entry} {#each mealEntries as entry}
{@const imgUrl = entry.source === 'recipe' && entry.sourceId ? recipeImages[entry.sourceId] : null} {@const imgUrl = entry.source === 'recipe' && entry.sourceId ? recipeImages[entry.sourceId] : null}
<div <div
@@ -1779,6 +1779,7 @@
class:has-image={!!imgUrl} class:has-image={!!imgUrl}
class:dragging={draggingEntryId === entry._id} class:dragging={draggingEntryId === entry._id}
draggable={editingEntryId !== entry._id} draggable={editingEntryId !== entry._id}
role="listitem"
ondragstart={(ev) => onEntryDragStart(ev, entry._id)} ondragstart={(ev) => onEntryDragStart(ev, entry._id)}
ondragend={onEntryDragEnd} ondragend={onEntryDragEnd}
> >
@@ -2308,11 +2309,6 @@
text-transform: uppercase; text-transform: uppercase;
color: var(--color-text-secondary); color: var(--color-text-secondary);
} }
.macro-bar-goal {
font-weight: 400;
opacity: 0.7;
text-transform: none;
}
.macro-bar-track { .macro-bar-track {
width: 100%; width: 100%;
height: 6px; height: 6px;
@@ -2409,15 +2405,6 @@
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.04em; letter-spacing: 0.04em;
} }
/* Macro rings (custom meal detail + food detail) */
.ring-text {
font-size: 14px;
font-weight: 700;
fill: currentColor;
text-anchor: middle;
dominant-baseline: central;
}
/* ── Micro Details ── */ /* ── Micro Details ── */
.micro-inline { .micro-inline {
margin-top: 0.75rem; margin-top: 0.75rem;
@@ -3669,14 +3656,6 @@
font-size: 0.72rem; font-size: 0.72rem;
color: var(--color-text-tertiary); color: var(--color-text-tertiary);
} }
.custom-meal-info[role="button"] {
cursor: pointer;
border-radius: 6px;
transition: background 0.12s;
}
.custom-meal-info[role="button"]:hover {
background: var(--color-bg-elevated);
}
/* Custom meal detail screen */ /* Custom meal detail screen */
.cm-detail { .cm-detail {
padding: 0.75rem; padding: 0.75rem;
@@ -3780,10 +3759,6 @@
.cm-detail-btn-confirm:hover { .cm-detail-btn-confirm:hover {
opacity: 0.9; opacity: 0.9;
} }
.btn-sm {
padding: 0.3rem 0.65rem;
font-size: 0.72rem;
}
.manage-meals-link { .manage-meals-link {
display: flex; display: flex;
align-items: center; align-items: center;