import isArray from 'shared/isArray';
import {getCurrentFiberOwnerNameInDevOrNull} from 'react-reconciler/src/ReactCurrentFiber';
import {getToStringValue, toString} from './ToStringValue';
import {disableTextareaChildren} from 'shared/ReactFeatureFlags';
import {track, trackHydrated} from './inputValueTracking';
import {queueChangeEvent} from '../events/ReactDOMEventReplaying';
let didWarnValDefaultVal = false;
export function validateTextareaProps(element: Element, props: Object) {
if (__DEV__) {
if (
props.value !== undefined &&
props.defaultValue !== undefined &&
!didWarnValDefaultVal
) {
console.error(
'%s contains a textarea with both value and defaultValue props. ' +
'Textarea elements must be either controlled or uncontrolled ' +
'(specify either the value prop, or the defaultValue prop, but not ' +
'both). Decide between using a controlled or uncontrolled textarea ' +
'and remove one of these props. More info: ' +
'https://react.dev/link/controlled-components',
getCurrentFiberOwnerNameInDevOrNull() || 'A component',
);
didWarnValDefaultVal = true;
}
if (props.children != null && props.value == null) {
console.error(
'Use the `defaultValue` or `value` props instead of setting ' +
'children on <textarea>.',
);
}
}
}
export function updateTextarea(
element: Element,
value: ?string,
defaultValue: ?string,
) {
const node: HTMLTextAreaElement = (element: any);
if (value != null) {
const newValue = toString(getToStringValue(value));
if (newValue !== node.value) {
node.value = newValue;
}
if (defaultValue == null) {
if (node.defaultValue !== newValue) {
node.defaultValue = newValue;
}
return;
}
}
if (defaultValue != null) {
node.defaultValue = toString(getToStringValue(defaultValue));
} else {
node.defaultValue = '';
}
}
export function initTextarea(
element: Element,
value: ?string,
defaultValue: ?string,
children: ?string,
) {
const node: HTMLTextAreaElement = (element: any);
let initialValue = value;
if (initialValue == null) {
if (children != null) {
if (!disableTextareaChildren) {
if (defaultValue != null) {
throw new Error(
'If you supply `defaultValue` on a <textarea>, do not pass children.',
);
}
if (isArray(children)) {
if (children.length > 1) {
throw new Error('<textarea> can only have at most one child.');
}
children = children[0];
}
defaultValue = children;
}
}
if (defaultValue == null) {
defaultValue = '';
}
initialValue = defaultValue;
}
const stringValue = getToStringValue(initialValue);
node.defaultValue = (stringValue: any);
const textContent = node.textContent;
if (textContent === stringValue) {
if (textContent !== '' && textContent !== null) {
node.value = textContent;
}
}
track((element: any));
}
export function hydrateTextarea(
element: Element,
value: ?string,
defaultValue: ?string,
): void {
const node: HTMLTextAreaElement = (element: any);
let initialValue = value;
if (initialValue == null) {
if (defaultValue == null) {
defaultValue = '';
}
initialValue = defaultValue;
}
const stringValue = toString(getToStringValue(initialValue));
const changed = trackHydrated((node: any), stringValue, false);
if (changed) {
queueChangeEvent(node);
}
}
export function restoreControlledTextareaState(
element: Element,
props: Object,
) {
updateTextarea(element, props.value, props.defaultValue);
}