<!--
    Component: ContentEditable
    Provides a contenteditable div with custom font and text properties.
-->
<script lang="ts">
interface Props {
    /**
     * Visible text (bindable)
     */
    text: string;
    /**
     * Font size in pixels
     */
    fontSize?: number;
    /**
     * Line height
     */
    lineHeight?: number;
    /**
     * Letter spacing in pixels
     */
    letterSpacing?: number;
}

let {
    text = $bindable('The quick brown fox jumps over the lazy dog.'),
    fontSize = 48,
    lineHeight = 1.2,
    letterSpacing = 0,
}: Props = $props();

let element: HTMLDivElement | undefined = $state();

// Initial Sync: Set the text ONLY ONCE when the element is created.
// This prevents Svelte from "owning" the innerHTML/innerText.
$effect(() => {
    if (element && element.innerText !== text) {
        element.innerText = text;
    }
});

// Handle changes: Update the outer state without re-rendering the div.
function handleInput(e: Event) {
    const target = e.target as HTMLDivElement;
    // Update the bindable prop directly
    text = target.innerText;
}
</script>

<div
    bind:this={element}
    contenteditable="plaintext-only"
    spellcheck="false"
    role="textbox"
    tabindex="0"
    data-placeholder="Type something to test..."
    oninput={handleInput}
    class="
        w-full min-h-[1.2em] outline-none transition-all duration-200
        empty:before:content-[attr(data-placeholder)] empty:before:text-slate-400
        selection:bg-indigo-100 selection:text-indigo-900
        caret-indigo-500 focus:outline-none
    "
    style:font-size="{fontSize}px"
    style:line-height={lineHeight}
    style:letter-spacing="{letterSpacing}em"
>
</div>
