|
|
|
import React, { forwardRef, useContext, useEffect, useRef } from 'react';
|
|
|
|
import RcInput, { InputProps as RcInputProps, InputRef } from 'rc-input';
|
|
|
|
import CloseCircleFilled from '@ant-design/icons/CloseCircleFilled';
|
|
|
|
import classNames from 'classnames';
|
|
|
|
import { composeRef } from 'rc-util/lib/ref';
|
|
|
|
import SizeContext, { SizeType } from '../config-provider/SizeContext';
|
|
|
|
import {
|
|
|
|
getFeedbackIcon,
|
|
|
|
getMergedStatus,
|
|
|
|
getStatusClassNames,
|
|
|
|
InputStatus,
|
|
|
|
} from '../_util/statusUtils';
|
|
|
|
import { ConfigContext } from '../config-provider';
|
|
|
|
import { FormItemStatusContext } from '../form/context';
|
|
|
|
import { hasPrefixSuffix } from './utils';
|
|
|
|
import devWarning from '../_util/devWarning';
|
|
|
|
|
|
|
|
export interface InputFocusOptions extends FocusOptions {
|
|
|
|
cursor?: 'start' | 'end' | 'all';
|
|
|
|
}
|
|
|
|
|
|
|
|
export type { InputRef };
|
|
|
|
|
|
|
|
export function fixControlledValue<T>(value: T) {
|
|
|
|
if (typeof value === 'undefined' || value === null) {
|
|
|
|
return '';
|
|
|
|
}
|
|
|
|
return String(value);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function resolveOnChange<E extends HTMLInputElement | HTMLTextAreaElement>(
|
|
|
|
target: E,
|
|
|
|
e:
|
|
|
|
| React.ChangeEvent<E>
|
|
|
|
| React.MouseEvent<HTMLElement, MouseEvent>
|
|
|
|
| React.CompositionEvent<HTMLElement>,
|
|
|
|
onChange: undefined | ((event: React.ChangeEvent<E>) => void),
|
|
|
|
targetValue?: string,
|
|
|
|
) {
|
|
|
|
if (!onChange) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
let event = e;
|
|
|
|
|
|
|
|
if (e.type === 'click') {
|
|
|
|
// Clone a new target for event.
|
|
|
|
// Avoid the following usage, the setQuery method gets the original value.
|
|
|
|
//
|
|
|
|
// const [query, setQuery] = React.useState('');
|
|
|
|
// <Input
|
|
|
|
// allowClear
|
|
|
|
// value={query}
|
|
|
|
// onChange={(e)=> {
|
|
|
|
// setQuery((prevStatus) => e.target.value);
|
|
|
|
// }}
|
|
|
|
// />
|
|
|
|
|
|
|
|
const currentTarget = target.cloneNode(true) as E;
|
|
|
|
|
|
|
|
// click clear icon
|
|
|
|
event = Object.create(e, {
|
|
|
|
target: { value: currentTarget },
|
|
|
|
currentTarget: { value: currentTarget },
|
|
|
|
});
|
|
|
|
|
|
|
|
currentTarget.value = '';
|
|
|
|
onChange(event as React.ChangeEvent<E>);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Trigger by composition event, this means we need force change the input value
|
|
|
|
if (targetValue !== undefined) {
|
|
|
|
event = Object.create(e, {
|
|
|
|
target: { value: target },
|
|
|
|
currentTarget: { value: target },
|
|
|
|
});
|
|
|
|
|
|
|
|
target.value = targetValue;
|
|
|
|
onChange(event as React.ChangeEvent<E>);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
onChange(event as React.ChangeEvent<E>);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function triggerFocus(
|
|
|
|
element?: HTMLInputElement | HTMLTextAreaElement,
|
|
|
|
option?: InputFocusOptions,
|
|
|
|
) {
|
|
|
|
if (!element) return;
|
|
|
|
|
|
|
|
element.focus(option);
|
|
|
|
|
|
|
|
// Selection content
|
|
|
|
const { cursor } = option || {};
|
|
|
|
if (cursor) {
|
|
|
|
const len = element.value.length;
|
|
|
|
|
|
|
|
switch (cursor) {
|