import React, {FC, ReactNode, useEffect, useRef} from "react"; import AutosizeInput from 'react-input-autosize'; import {lastChanged, NumberFieldType} from "./LastChanged"; import classNames from "classnames"; export type TextProps = { id: string, name?: string, value: string, onChange: (value: string) => void, type?: 'input' | 'textarea', placeholder?: string, fullWidth?: boolean, autoFocusOnUpdate?: boolean, inputLeft?: ReactNode, inputRight?: ReactNode, emptyMinWidth?: number, } export const Text: FC = ({ value, onChange, name, id, type = 'input', placeholder, fullWidth, autoFocusOnUpdate = true, inputLeft, inputRight, emptyMinWidth }) => { const inputRef = useRef(null) value = typeof value !== 'string' ? '' : value; // ensure value is a string /** * Because the re-rendering seems to be too slow (that's my guess) * Everytime the user enters 2 or more digits at once, the input gets blurred and the second number never gets captured * so let's focus this everytime the value changes so that the user may add several numbers at once (eg: type the number "20") */ useEffect(() => { /** * Unfortunately, due to re-renders we have to use this hack. otherwise, the range field would always focus the second input since * for some reason this component is unmounting and mounting on every update. * I know i should probably fox the root, but that could probably take DAYS which I don't have rn. */ if (lastChanged.fieldType !== 'text') { return } if (!autoFocusOnUpdate) { return; } if (lastChanged.id === id && lastChanged.fieldType === 'text') { if (type === 'textarea') { inputRef.current?.focus() // Place cursor at the end for textarea const textLength = inputRef.current?.value?.length || 0 inputRef.current?.setSelectionRange(textLength, textLength) } else { inputRef.current?.focus() } } }, [value]) let text: ReactNode; const ringclass = "focus:!border-gray-400 focus:!ring-[3px] focus:!ring-gray-250 focus:!ring-opacity-40 focus:!ring-offset-2"; const hasInnerComponents = typeof inputLeft !== 'undefined' || typeof inputRight !== 'undefined'; const minWidthWhenEmpty = !fullWidth && value.length === 0 ? emptyMinWidth : undefined; if (type === 'input') { const input = { lastChanged.id = id lastChanged.fieldType = 'text' onChange(event.target.value) }} placeholder={placeholder} /> text = !hasInnerComponents ? input :
{typeof inputLeft !== 'undefined' &&
{inputLeft}
} {input} {typeof inputRight !== 'undefined' &&
{inputRight}
}
} else { text =