fix: autocomplete custom children class not work

* refactor(v3/vc-selector/input): use composition api

* fix: change input props className to class

* revert with cloneElement

* fix: auto-complete demo custom test
cssinjs
bqy_fe 2022-03-20 10:50:57 +08:00 committed by GitHub
parent c86338542d
commit 414e7a1c56
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 155 additions and 166 deletions

View File

@ -1,6 +1,10 @@
export type FocusEventHandler = (e: FocusEvent) => void; export type FocusEventHandler = (e: FocusEvent) => void;
export type MouseEventHandler = (e: MouseEvent) => void; export type MouseEventHandler = (e: MouseEvent) => void;
export type KeyboardEventHandler = (e: KeyboardEvent) => void; export type KeyboardEventHandler = (e: KeyboardEvent) => void;
export type CompositionEventHandler = (e: CompositionEvent) => void;
export type ClipboardEventHandler = (e: ClipboardEvent) => void;
export type ChangeEventHandler = (e: ChangeEvent) => void;
export type ChangeEvent = Event & { export type ChangeEvent = Event & {
target: { target: {
value?: string | undefined; value?: string | undefined;

View File

@ -30,7 +30,7 @@ exports[`renders ./components/auto-complete/demo/custom.vue correctly 1`] = `
<div style="width: 200px;" class="ant-select ant-select-show-search ant-select-auto-complete ant-select-single ant-select-customize-input ant-select-show-search"> <div style="width: 200px;" class="ant-select ant-select-show-search ant-select-auto-complete ant-select-single ant-select-customize-input ant-select-show-search">
<!----> <!---->
<!----> <!---->
<div class="ant-select-selector"><span class="ant-select-selection-search"><textarea placeholder="input here" id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-input ant-select-selection-search-input" style="height: 50px;" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" aria-activedescendant="rc_select_TEST_OR_SSR_list_0"></textarea></span> <div class="ant-select-selector"><span class="ant-select-selection-search"><textarea placeholder="input here" id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-input ant-select-selection-search-input custom" style="height: 50px;" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" aria-activedescendant="rc_select_TEST_OR_SSR_list_0"></textarea></span>
<!----><span class="ant-select-selection-placeholder"><!----></span> <!----><span class="ant-select-selection-placeholder"><!----></span>
</div> </div>
<!----> <!---->

View File

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