UNPKG

@i-novus/ui-core

Version:

Базовые UI компоненты

58 lines (57 loc) 3.54 kB
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';