import React, { useLayoutEffect, useRef } from 'react'; import { twMerge } from 'tailwind-merge'; import { InputContainer } from './InputContainer'; import { InputControl } from './InputControl'; import { InputStartDecorator, InputEndDecorator } from './InputDecorator'; import { InputError } from './InputError'; import { InputGroup } from './InputGroup'; import { Label } from './Label'; type InputProps = { label?: string; hiddenLabel?: boolean; className?: string; inputClassName?: string; error?: string; initialValue?: string; name: string; onChange?: (event: React.ChangeEvent) => void; startDecorator?: React.ReactNode; endDecorator?: React.ReactNode; } & React.InputHTMLAttributes; const makeObserverFunction = (ref: React.RefObject, varPrefix: string) => { return (entries: ResizeObserverEntry[]) => { const { contentRect: { width }, } = entries[0]; if (ref.current) { ref.current.style.setProperty(`--${varPrefix}-width`, width + 'px'); } }; }; export function TextInput({ label, className, hiddenLabel, error, initialValue, inputClassName, id, startDecorator, endDecorator, ...inputProps }: InputProps) { const isError = Boolean(error); const errorLabel = isError && id ? `${id}-error` : undefined; const inputControlRef = useRef(null); const startDecoratorRef = useRef(null); const endDecoratorRef = useRef(null); useLayoutEffect(() => { const startResizeObserver = new ResizeObserver(makeObserverFunction(inputControlRef, 'start-decorator')); const endResizeObserver = new ResizeObserver(makeObserverFunction(inputControlRef, 'end-decorator')); if (startDecoratorRef.current) { startResizeObserver.observe(startDecoratorRef.current); } if (endDecoratorRef.current) { endResizeObserver.observe(endDecoratorRef.current); } return () => { startResizeObserver.disconnect(); endResizeObserver.disconnect(); }; }, [inputControlRef, startDecoratorRef, endDecoratorRef]); const input = ( ); return ( {!hiddenLabel && label && ); }