import { cloneElement } from '../../_util/vnode'; import type { ExtractPropTypes, PropType, VNode } from 'vue'; import { defineComponent, getCurrentInstance, inject, onMounted, withDirectives } from 'vue'; import PropTypes from '../../_util/vue-types'; import antInput from '../../_util/antInputDirective'; import classNames from '../../_util/classNames'; import type { FocusEventHandler, KeyboardEventHandler, MouseEventHandler, ChangeEventHandler, CompositionEventHandler, ClipboardEventHandler, } from '../../_util/EventInterface'; export const inputProps = { inputRef: PropTypes.any, prefixCls: String, id: String, inputElement: PropTypes.VueNode, disabled: { type: Boolean, default: undefined }, autofocus: { type: Boolean, default: undefined }, autocomplete: String, editable: { type: Boolean, default: undefined }, activeDescendantId: String, value: String, open: { type: Boolean, default: undefined }, tabindex: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), /** Pass accessibility props to input */ attrs: PropTypes.object, onKeydown: { type: Function as PropType }, onMousedown: { type: Function as PropType }, onChange: { type: Function as PropType }, onPaste: { type: Function as PropType }, onCompositionstart: { type: Function as PropType }, onCompositionend: { type: Function as PropType }, onFocus: { type: Function as PropType }, onBlur: { type: Function as PropType }, }; export type InputProps = Partial>; const Input = defineComponent({ name: 'Input', inheritAttrs: false, props: inputProps, setup(props) { let blurTimeout = null; const VCSelectContainerEvent = inject('VCSelectContainerEvent') as any; if (process.env.NODE_ENV === 'test') { onMounted(() => { const ins = getCurrentInstance(); if (props.autofocus) { if (ins.vnode && ins.vnode.el) { ins.vnode.el.focus(); } } }); } return () => { const { prefixCls, id, inputElement, disabled, tabindex, autofocus, autocomplete, editable, activeDescendantId, value, onKeydown, onMousedown, onChange, onPaste, onCompositionstart, onCompositionend, onFocus, onBlur, open, inputRef, attrs, } = props; let inputNode: any = inputElement || withDirectives(() as VNode, [[antInput]]); const inputProps = inputNode.props || {}; const { onKeydown: onOriginKeyDown, onInput: onOriginInput, onFocus: onOriginFocus, onBlur: onOriginBlur, onMousedown: onOriginMouseDown, onCompositionstart: onOriginCompositionStart, onCompositionend: onOriginCompositionEnd, style, } = inputProps; inputNode = cloneElement( inputNode, Object.assign( { type: 'search', ...inputProps, id, ref: inputRef, disabled, tabindex, autocomplete: autocomplete || 'off', autofocus, class: classNames(`${prefixCls}-selection-search-input`, inputNode?.props?.class), role: 'combobox', 'aria-expanded': open, 'aria-haspopup': 'listbox', 'aria-owns': `${id}_list`, 'aria-autocomplete': 'list', 'aria-controls': `${id}_list`, 'aria-activedescendant': activeDescendantId, ...attrs, value: editable ? value : '', readonly: !editable, unselectable: !editable ? 'on' : null, style: { ...style, opacity: editable ? null : 0 }, onKeydown: (event: KeyboardEvent) => { onKeydown(event); if (onOriginKeyDown) { onOriginKeyDown(event); } }, onMousedown: (event: MouseEvent) => { onMousedown(event); if (onOriginMouseDown) { onOriginMouseDown(event); } }, onInput: (event: Event) => { onChange(event); if (onOriginInput) { onOriginInput(event); } }, onCompositionstart(event: CompositionEvent) { onCompositionstart(event); if (onOriginCompositionStart) { onOriginCompositionStart(event); } }, onCompositionend(event: CompositionEvent) { onCompositionend(event); if (onOriginCompositionEnd) { onOriginCompositionEnd(event); } }, onPaste, onFocus: (...args: any[]) => { clearTimeout(blurTimeout); onOriginFocus && onOriginFocus(args[0]); onFocus && onFocus(args[0]); VCSelectContainerEvent?.focus(args[0]); }, onBlur: (...args: any[]) => { blurTimeout = setTimeout(() => { onOriginBlur && onOriginBlur(args[0]); onBlur && onBlur(args[0]); VCSelectContainerEvent?.blur(args[0]); }, 100); }, }, inputNode.type === 'textarea' ? {} : { type: 'search' }, ), true, true, ) as VNode; return inputNode; }; }, }); export default Input;