UNPKG

@pmndrs/uikit

Version:

Build performant 3D user interfaces with Three.js and yoga.

58 lines (57 loc) 2.32 kB
import { abortableEffect } from '../../utils.js'; import { parseNumberValue } from '../../properties/values.js'; export function createHtmlInputElement(onChange, multiline, onSelectionChange) { const element = document.createElement(multiline ? 'textarea' : 'input'); const style = element.style; style.setProperty('position', 'absolute'); style.setProperty('left', '-1000vw'); style.setProperty('top', '0'); style.setProperty('pointerEvents', 'none'); style.setProperty('opacity', '0'); element.addEventListener('input', () => { onChange?.(element.value); onSelectionChange(); }); element.addEventListener('focus', onSelectionChange); element.addEventListener('keydown', onSelectionChange); element.addEventListener('keyup', onSelectionChange); element.addEventListener('blur', onSelectionChange); return element; } export function setupHtmlInputElement(properties, element, value, abortSignal) { document.body.appendChild(element); abortSignal.addEventListener('abort', () => element.remove()); abortableEffect(() => { element.value = value.value; }, abortSignal); abortableEffect(() => { element.disabled = properties.value.disabled; }, abortSignal); abortableEffect(() => { element.tabIndex = parseNumberValue(properties.value.tabIndex); }, abortSignal); abortableEffect(() => { element.autocomplete = properties.value.autocomplete; }, abortSignal); abortableEffect(() => element.setAttribute('type', properties.value.type), abortSignal); } export function setupUpdateHasFocus(element, hasFocusSignal, onFocusChange, abortSignal) { if (abortSignal.aborted) { return; } hasFocusSignal.value = document.activeElement === element; const listener = () => { const hasFocus = document.activeElement === element; if (hasFocus == hasFocusSignal.value) { return; } hasFocusSignal.value = hasFocus; onFocusChange(hasFocus); }; element.addEventListener('focus', listener); element.addEventListener('blur', listener); abortSignal.addEventListener('abort', () => { element.removeEventListener('focus', listener); element.removeEventListener('blur', listener); }); }