/* @refresh reload */ import { type Component, createSignal, JSX, Setter } from "solid-js"; import type { InputProps } from "../types/interfaces"; import Row from "./row"; function setupEventListener(id: string, setIsHover: Setter): () => void { let isMounted = true; function hover(hover: boolean): void { if (isMounted) { setIsHover(hover); } } const el = document.getElementById(id); el?.addEventListener("pointerenter", () => hover(true)); el?.addEventListener("pointerleave", () => hover(false)); return () => { el?.removeEventListener("pointerenter", () => hover(true)); el?.removeEventListener("pointerleave", () => hover(false)); isMounted = false; } } /** * Sets isText to 'true' or 'false' using the setIsText function. * if the value of the input element is not empty and it's different from the current value */ function setSetIsText(id: string | undefined, isText: boolean, setIsText: Setter): void { if (id) { const el = document.getElementById(id) as HTMLInputElement | HTMLTextAreaElement | null; if (el && el.value !== "" !== isText) { setIsText(el.value !== ""); } } } interface Input extends InputProps { leading?: JSX.Element, trailing?: JSX.Element, } export const Input: Component> = ( { className, id, name, type = "text", title, placeholder, required = false, onChange, leading, trailing }): JSX.Element => { /** * Is 'true' if the input element is in focus */ const [isFocused, setIsFocused] = createSignal(false); /** * Is 'true' if the user is hovering over the input element */ const [isHover, setIsHover] = createSignal(false); /** * Is 'true' if the input element contains any characters */ const [isText, setIsText] = createSignal(false); document.addEventListener("DOMContentLoaded", () => { if (id && title) { setupEventListener(id, setIsHover); } }); return ( { leading } setIsFocused(true) } onBlur={ () => setIsFocused(false) } name={ name ?? undefined } type={ type } placeholder={ placeholder ?? undefined } required={ required } onInput={ () => setSetIsText(id, isText(), setIsText) } onChange={ onChange /*TODO only called after ENTER*/ }/> { trailing } ); } function HoverTitle( { title, isActive = false, htmlFor }: { title?: string | null, isActive?: boolean, htmlFor?: string }): JSX.Element { return (