UNPKG

@modular-forms/solid

Version:

The modular and type-safe form library for SolidJS

73 lines (72 loc) 2.8 kB
import { createEffect, createMemo, untrack, mergeProps, } from 'solid-js'; import { createLifecycle } from '../primitives'; import { getElementInput, handleFieldEvent, initializeFieldStore, } from '../utils'; /** * Headless form field that provides reactive properties and state. */ export function Field(props) { // Get store of specified field const getField = createMemo(() => initializeFieldStore(props.of, props.name)); // Create lifecycle of field // eslint-disable-next-line solid/reactivity createLifecycle(mergeProps({ getStore: getField }, props)); return (<> {props.children({ get name() { return props.name; }, get value() { return getField().value.get(); }, get error() { return getField().error.get(); }, get active() { return getField().active.get(); }, get touched() { return getField().touched.get(); }, get dirty() { return getField().dirty.get(); }, }, { get name() { return props.name; }, get autofocus() { return !!getField().error.get(); }, ref(element) { // Add element to elements getField().elements.set((elements) => [...elements, element]); // Create effect that replaces initial input and input of field with // initial input of element if both is "undefined", so that dirty // state also resets to "false" when user removes input createEffect(() => { if (element.type !== 'radio' && getField().startValue.get() === undefined && untrack(getField().value.get) === undefined) { const input = getElementInput(element, getField(), props.type); getField().startValue.set(() => input); getField().value.set(() => input); } }); }, onInput(event) { handleFieldEvent(props.of, getField(), props.name, event, ['touched', 'input'], getElementInput(event.currentTarget, getField(), props.type)); }, onChange(event) { handleFieldEvent(props.of, getField(), props.name, event, [ 'change', ]); }, onBlur(event) { handleFieldEvent(props.of, getField(), props.name, event, [ 'touched', 'blur', ]); }, })} </>); }