@i-novus/ui-core
Version:
Базовые UI компоненты
58 lines (57 loc) • 3.54 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { forwardRef, useCallback, useRef, useMemo, useState, useEffect, } from 'react';
import classNames from 'classnames';
import { v4 as generateId } from 'uuid';
import { useConfigProvider } from '../core';
import { useComposeRef } from '../core/hooks/useComposeRef';
import { Icon } from '../data-display/Icon';
// eslint-disable-next-line sonarjs/cognitive-complexity
export const Input = forwardRef((props, ref) => {
const { className, disabled = false, error, prefix, prefixIcon, suffixIcon, required, readOnly = false, clearIcon, onChange, onReset, style, id, visible = true, type, autoComplete, length, onFocus, onBlur, ...restProps } = props;
const { getPrefix } = useConfigProvider();
const prefixCls = getPrefix(prefix);
const inputContainerRef = useRef(null);
const inputRef = useRef(null);
const composedRef = useComposeRef(inputRef, ref);
const isControlled = useRef(Object.hasOwn(props, 'value'));
const [clearIconVisible, setClearIconVisible] = useState(false);
const handleChange = useCallback((event) => {
onChange?.(event.target.value, event);
if (inputRef.current && !isControlled.current) {
setClearIconVisible(Boolean(event.target.value));
}
}, [onChange]);
const onInputReset = useCallback((event) => {
event.stopPropagation();
event.preventDefault();
onReset?.(event);
if (inputRef.current && !isControlled.current) {
inputRef.current.value = '';
setClearIconVisible(false);
}
}, [onReset]);
const targetId = useMemo(() => generateId(), []);
useEffect(() => {
if (isControlled.current) {
setClearIconVisible(Boolean(props.value));
}
else {
setClearIconVisible(Boolean(inputRef.current?.value));
}
}, [props.value]);
const ClearIcon = useMemo(() => {
const hasReset = isControlled.current ? Boolean(onReset) : true;
if (disabled || readOnly || !clearIconVisible || !clearIcon || !hasReset) {
return null;
}
const icon = typeof clearIcon === 'boolean' ? _jsx(Icon, { icon: "common-close" }) : clearIcon?.icon;
return icon ? (_jsx("button", { type: "button", onClick: onInputReset, onMouseDown: e => e.preventDefault(), className: `${prefixCls}-input-clear-icon`, tabIndex: 0, children: icon })) : null;
}, [clearIcon, clearIconVisible, disabled, onInputReset, prefixCls, readOnly, onReset]);
return (visible ? (_jsxs("label", { htmlFor: `${targetId}`, ref: inputContainerRef, className: classNames(`${prefixCls}-input-container`, {
[`${prefixCls}-input-container_disabled`]: disabled,
[`${prefixCls}-input-container_error`]: error,
[`${prefixCls}-input-container_required`]: required,
[`${prefixCls}-input-container_readonly`]: readOnly,
}, className), style: style, children: [prefixIcon && (_jsx("span", { className: `${prefixCls}-input-prefix`, children: prefixIcon })), _jsx("input", { ...restProps, id: `${targetId}`, autoComplete: autoComplete || 'off', ref: composedRef, className: `${prefixCls}-input`, readOnly: readOnly, disabled: disabled || readOnly, onBlur: onBlur, onFocus: onFocus, onChange: handleChange, maxLength: length, type: type }), ClearIcon, suffixIcon && (_jsx("span", { className: classNames(`${prefixCls}-input-suffix`), children: suffixIcon }))] })) : null);
});
Input.displayName = 'Input';