182 lines
5.6 KiB
Vue
182 lines
5.6 KiB
Vue
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<KeyboardEventHandler> },
|
|
onMousedown: { type: Function as PropType<MouseEventHandler> },
|
|
onChange: { type: Function as PropType<ChangeEventHandler> },
|
|
onPaste: { type: Function as PropType<ClipboardEventHandler> },
|
|
onCompositionstart: { type: Function as PropType<CompositionEventHandler> },
|
|
onCompositionend: { type: Function as PropType<CompositionEventHandler> },
|
|
onFocus: { type: Function as PropType<FocusEventHandler> },
|
|
onBlur: { type: Function as PropType<FocusEventHandler> },
|
|
};
|
|
|
|
export type InputProps = Partial<ExtractPropTypes<typeof inputProps>>;
|
|
|
|
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((<input />) 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;
|