import { useMemo, useRef } from 'react' import { View, TextInput } from 'react-native' import { useWrappingScrollable } from '../../modules/scroll' import { Field, IFieldRef, fields, useField } from '@codeleap/form' import { AnyRecord, TypeGuards } from '@codeleap/types' /** * When both `value` and `onValueChange` are provided, the component runs in uncontrolled-by-form * mode: `useField` is never called and the field ref (blur/focus/scrollIntoView) is a no-op stub. * This check is frozen on mount — toggling between controlled and uncontrolled after mount is unsupported. */ export function useInputBase = Field>( field: T, defaultField: (options?: AnyRecord) => T = fields.text as () => T, internalState: { value: V; onValueChange: (value: V) => void }, params: Partial> = {}, deps: any[] = [] ) { const { value, onValueChange } = internalState const hasInternalState = useMemo(() => TypeGuards.isFunction(onValueChange) && !TypeGuards.isNil(value), []) const wrapperRef = useRef(null) const innerInputRef = useRef(null) const scrollable = useWrappingScrollable() const fieldHandle = hasInternalState ? {} as Partial> : useField(field as T, [ { blur() { innerInputRef.current.blur() }, focus() { innerInputRef.current.focus() }, getValue() { return innerInputRef.current.state as V }, scrollIntoView() { /** Requires a wrapping ScrollView registered via `useWrappingScrollable`; silently does nothing if none is found. */ return field.measurePosition(wrapperRef).then((measureResult) => { field.scrollTo(scrollable, measureResult) }) }, ...params, }, deps ] as unknown as Parameters, defaultField) const validation = fieldHandle?.validation return { fieldHandle, validation, wrapperRef, innerInputRef, scrollable, inputValue: (hasInternalState ? value : fieldHandle?.value) as V, onInputValueChange: hasInternalState ? onValueChange : fieldHandle?.setValue, } }