Files
homepage/src/lib/components/LazyCategory.svelte
Alexander Bocken cc978e73b4
All checks were successful
CI / update (push) Successful in 1m13s
feat: improve accessibility and update color scheme based on PageSpeed insights
- Add aria-labels to icon-only links (add button, edit button, logo, nav toggle)
- Add main landmark element for better page structure
- Fix heading hierarchy on recipe pages (h1 → h2 → h3 progression)
- Add role="status" to loading placeholders to allow aria-label usage
- Update link colors from red to blue for better contrast in both light and dark modes
- Change hover colors from orange/red to light blue across all interactive elements
- Reduce font size of section labels (Season, Keywords) while maintaining semantic structure

These changes address PageSpeed accessibility recommendations including low-contrast text,
missing accessible names, prohibited ARIA attributes, missing landmarks, and improper
heading order.
2026-01-05 16:14:37 +01:00

67 lines
1.5 KiB
Svelte

<script>
import { onMount } from 'svelte';
import { browser } from '$app/environment';
let {
title = '',
eager = false,
estimatedHeight = 400,
rootMargin = '400px',
children
} = $props();
let isVisible = $state(eager); // If eager=true, render immediately
let containerRef = $state(null);
let observer = $state(null);
onMount(() => {
if (!browser || eager) return;
// Create Intersection Observer to detect when category approaches viewport
observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting && !isVisible) {
isVisible = true;
// Once visible, stop observing (keep it rendered)
if (observer && containerRef) {
observer.unobserve(containerRef);
}
}
});
},
{
rootMargin, // Start loading 400px before entering viewport
threshold: 0
}
);
if (containerRef) {
observer.observe(containerRef);
}
return () => {
if (observer) {
observer.disconnect();
}
};
});
</script>
{#if isVisible}
<!-- Render actual content when visible -->
<div bind:this={containerRef}>
{@render children()}
</div>
{:else}
<!-- Placeholder with estimated height to maintain scroll position -->
<div
bind:this={containerRef}
style="height: {estimatedHeight}px; min-height: {estimatedHeight}px;"
role="status"
aria-label="Loading {title}"
>
<!-- Empty placeholder - IntersectionObserver will trigger when this enters viewport -->
</div>
{/if}