<!--
    Component: FontApplicator
    Applies a font to its children once the font file is loaded.
    Shows the skeleton snippet while loading; falls back to system font if no skeleton is provided.
-->
<script lang="ts">
import { cn } from '$shared/lib';
import type { Snippet } from 'svelte';
import type {
    FontLoadStatus,
    UnifiedFont,
} from '../../model/types';

interface Props {
    /**
     * Font to apply
     */
    font: UnifiedFont;
    /**
     * Current load status for this font, supplied by the composing layer.
     * Kept out of the component so it does not depend on (and import) the
     * lifecycle store — the owning widget reads the manager and passes the
     * resolved status down. `undefined` means the font is not tracked yet and
     * is treated as not-yet-revealed (skeleton / system-font fallback).
     */
    status: FontLoadStatus | undefined;
    /**
     * CSS classes
     */
    className?: string;
    /**
     * Content snippet
     */
    children?: Snippet;
    /**
     * Shown while the font file is loading.
     * When omitted, children render in system font until ready.
     */
    skeleton?: Snippet;
}

let {
    font,
    status,
    className,
    children,
    skeleton,
}: Props = $props();

const shouldReveal = $derived(status === 'loaded' || status === 'error');
</script>

{#if !shouldReveal && skeleton}
    {@render skeleton()}
{:else}
    <div
        style:font-family={shouldReveal ? `'${font.name}'` : 'system-ui, -apple-system, sans-serif'}
        class={cn(className)}
    >
        {@render children?.()}
    </div>
{/if}
