"use client"; import * as React from "react"; import { usePrevious } from "../../../hooks/state/usePrevious"; import { useSize } from "../../../hooks/dom/useSize"; import { useFormReset } from "../../../hooks/dom/useFormReset"; import { visuallyHidden } from "../../../lib/styles"; type InputValue = string[] | string; interface VisuallyHiddenInputProps extends Omit< React.InputHTMLAttributes, "value" | "checked" | "onReset" > { value?: T; checked?: boolean; control: HTMLElement | null; bubbles?: boolean; onReset?: (value: T) => void; } function VisuallyHiddenInput( props: VisuallyHiddenInputProps, ) { const { control, value, checked, bubbles = true, type = "hidden", onReset, style, ...inputProps } = props; const isCheckInput = type === "checkbox" || type === "radio" || type === "switch"; const inputRef = React.useRef(null); const prevValue = usePrevious(type === "hidden" ? value : checked); const controlSize = useSize(control); // Bubble value/checked change to parents React.useEffect(() => { const input = inputRef.current; if (!input) return; const inputProto = window.HTMLInputElement.prototype; const propertyKey = isCheckInput ? "checked" : "value"; const eventType = isCheckInput ? "click" : "input"; const currentValue = isCheckInput ? checked : JSON.stringify(value); const descriptor = Object.getOwnPropertyDescriptor( inputProto, propertyKey, ) as PropertyDescriptor; const setter = descriptor.set; if (prevValue !== currentValue && setter) { const event = new Event(eventType, { bubbles }); setter.call(input, currentValue); input.dispatchEvent(event); } }, [prevValue, value, checked, bubbles, isCheckInput]); // Trigger on onReset callback when form is reset useFormReset({ form: inputRef.current?.form ?? null, defaultValue: isCheckInput ? (checked as T) : value, onReset: (resetValue: T) => { onReset?.(resetValue); }, }); const composedStyle = React.useMemo(() => { return { ...style, ...(controlSize?.width !== undefined && controlSize?.height !== undefined ? controlSize : {}), ...visuallyHidden, }; }, [style, controlSize]); return ( ); } export type { VisuallyHiddenInputProps, InputValue }; export { VisuallyHiddenInput };