All files / src/utils input.ts

82.97% Statements 39/47
64.1% Branches 25/39
53.33% Functions 8/15
84.78% Lines 39/46

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 1034x                     4x             60x     60x 60x   60x 60x 498x 498x         159x       60x 60x       60x   60x 60x       60x 60x       60x 60x 60x 36x 36x     60x 60x             60x 60x 73x   60x     60x 60x 88x   60x     60x 60x 375x     60x 60x         60x     60x            
import { findAll } from "./dom"
 
type Callbacks = {
    onSubmit?: (value: string) => void
    onInput?: (value: string) => void
    onFocus?: (value: string) => void
    onBlur?: (value: string) => void
    onKeyDown?: (value: string, key: string) => void
    onClick?: (value: string) => void
}
 
export function bindInput(
    selector: string | HTMLInputElement,
    callbacks: Callbacks
): {
    destroy: () => void
} {
    const target =
        selector instanceof HTMLInputElement
            ? [selector]
            : findAll(selector, HTMLInputElement)
    const unbindCallbacks = target.flatMap(el => {
        const cbs: Array<() => void> = []
 
        if (callbacks.onSubmit) {
            const onKeyDown = (event: KeyboardEvent) => {
                callbacks.onKeyDown?.(el.value, event.key)
                if (
                    event.key === "ArrowDown" ||
                    event.key === "ArrowUp" ||
                    event.key === "Enter"
                ) {
                    event.preventDefault()
                }
            }
 
            el.addEventListener("keydown", onKeyDown)
            cbs.push(() => {
                el.removeEventListener("keydown", onKeyDown)
            })
 
            const form = el.form
 
            if (form) {
                const onSubmit = (event: SubmitEvent) => {
                    event.preventDefault()
                    callbacks.onSubmit?.(el.value)
                }
                form.addEventListener("submit", onSubmit)
                cbs.push(() => {
                    form?.removeEventListener("submit", onSubmit)
                })
 
                const buttons = Array.from(form.querySelectorAll("[type=submit]"))
                buttons.forEach(button => {
                    const onClick = (event: Event) => {
                        event.preventDefault()
                        callbacks.onSubmit?.(el.value)
                    }
 
                    button.addEventListener("click", onClick)
                    cbs.push(() => {
                        button.removeEventListener("click", onClick)
                    })
                })
            }
        }
 
        if (callbacks.onClick) {
            const onClick = () => {
                callbacks.onClick?.(el.value)
            }
            el.addEventListener("click", onClick)
        }
 
        if (callbacks.onFocus) {
            const onFocus = () => {
                callbacks.onFocus?.(el.value)
            }
            el.addEventListener("focus", onFocus)
        }
 
        if (callbacks.onInput) {
            const onInput = () => {
                callbacks.onInput?.(el.value)
            }
 
            el.addEventListener("input", onInput)
            cbs.push(() => {
                el.removeEventListener("input", onInput)
            })
        }
 
        return cbs
    })
 
    return {
        destroy() {
            unbindCallbacks.forEach(v => v())
        },
    }
}