import type { CSSProperties } from 'vue'; import { defineComponent, ref } from 'vue'; import classNames from '../_util/classNames'; import type { MouseEventHandler } from '../_util/EventInterface'; import { cloneElement } from '../_util/vnode'; import { baseInputProps } from './inputProps'; import { hasAddon, hasPrefixSuffix } from './utils/commonUtils'; export default defineComponent({ name: 'BaseInput', inheritAttrs: false, props: baseInputProps(), setup(props, { slots, attrs }) { const containerRef = ref(); const onInputMouseDown: MouseEventHandler = e => { if (containerRef.value?.contains(e.target as Element)) { const { triggerFocus } = props; triggerFocus?.(); } }; const getClearIcon = () => { const { allowClear, value, disabled, readonly, handleReset, suffix = slots.suffix, prefixCls, } = props; if (!allowClear) { return null; } const needClear = !disabled && !readonly && value; const className = `${prefixCls}-clear-icon`; const iconNode = slots.clearIcon?.() || '*'; return ( e.preventDefault()} class={classNames( { [`${className}-hidden`]: !needClear, [`${className}-has-suffix`]: !!suffix, }, className, )} role="button" tabindex={-1} > {iconNode} ); }; return () => { const { focused, value, disabled, allowClear, readonly, hidden, prefixCls, prefix = slots.prefix?.(), suffix = slots.suffix?.(), addonAfter = slots.addonAfter, addonBefore = slots.addonBefore, inputElement, affixWrapperClassName, wrapperClassName, groupClassName, } = props; let element = cloneElement(inputElement, { value, hidden, }); // ================== Prefix & Suffix ================== // if (hasPrefixSuffix({ prefix, suffix, allowClear })) { const affixWrapperPrefixCls = `${prefixCls}-affix-wrapper`; const affixWrapperCls = classNames( affixWrapperPrefixCls, { [`${affixWrapperPrefixCls}-disabled`]: disabled, [`${affixWrapperPrefixCls}-focused`]: focused, [`${affixWrapperPrefixCls}-readonly`]: readonly, [`${affixWrapperPrefixCls}-input-with-clear-btn`]: suffix && allowClear && value, }, !hasAddon({ addonAfter, addonBefore }) && attrs.class, affixWrapperClassName, ); const suffixNode = (suffix || allowClear) && ( {getClearIcon()} {suffix} ); element = ( ); } // ================== Addon ================== // if (hasAddon({ addonAfter, addonBefore })) { const wrapperCls = `${prefixCls}-group`; const addonCls = `${wrapperCls}-addon`; const mergedWrapperClassName = classNames( `${prefixCls}-wrapper`, wrapperCls, wrapperClassName, ); const mergedGroupClassName = classNames( `${prefixCls}-group-wrapper`, attrs.class, groupClassName, ); // Need another wrapper for changing display:table to display:inline-block // and put style prop in wrapper return ( ); } return element; }; }, });