You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

254 lines
7.3 KiB

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) {