Skip to content

Commit

Permalink
fix: autocomplete custom children class not work
Browse files Browse the repository at this point in the history
* refactor(v3/vc-selector/input): use composition api

* fix: change input props className to class

* revert with cloneElement

* fix: auto-complete demo custom test
  • Loading branch information
buqiyuan committed Mar 20, 2022
1 parent c863385 commit 414e7a1
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 166 deletions.
4 changes: 4 additions & 0 deletions components/_util/EventInterface.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
export type FocusEventHandler = (e: FocusEvent) => void;
export type MouseEventHandler = (e: MouseEvent) => 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 & {
target: {
value?: string | undefined;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 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>
</div>
<!---->
Expand Down
315 changes: 150 additions & 165 deletions components/vc-select/Selector/Input.tsx
Original file line number Diff line number Diff line change
@@ -1,66 +1,53 @@
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 PropTypes from '../../_util/vue-types';
import type { RefObject } from '../../_util/createRef';
import antInput from '../../_util/antInputDirective';
import classNames from '../../_util/classNames';
import type { EventHandler } from '../../_util/EventInterface';
import type { VueNode } from '../../_util/type';
import type {
FocusEventHandler,
KeyboardEventHandler,
MouseEventHandler,
ChangeEventHandler,
CompositionEventHandler,
ClipboardEventHandler,
} from '../../_util/EventInterface';

interface InputProps {
prefixCls: string;
id: string;
inputElement: VueNode;
disabled: boolean;
autofocus: boolean;
autocomplete: string;
editable: boolean;
activeDescendantId?: string;
value: string;
open: boolean;
tabindex: number | string;
export const inputProps = {
inputRef: PropTypes.any,
prefixCls: PropTypes.string,
id: PropTypes.string,
inputElement: PropTypes.VueNode,
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: object;
inputRef: RefObject;
onKeydown: EventHandler;
onMousedown: EventHandler;
onChange: EventHandler;
onPaste: EventHandler;
onCompositionstart: EventHandler;
onCompositionend: EventHandler;
onFocus: EventHandler;
onBlur: EventHandler;
}
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: {
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,
},
props: inputProps,
setup(props) {
let blurTimeout = null;
const VCSelectContainerEvent = inject('VCSelectContainerEvent') as any;

if (process.env.NODE_ENV === 'test') {
onMounted(() => {
const ins = getCurrentInstance();
Expand All @@ -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 || {};
const {
onKeydown: onOriginKeyDown,
onInput: onOriginInput,
onFocus: onOriginFocus,
onBlur: onOriginBlur,
onMousedown: onOriginMouseDown,
onCompositionstart: onOriginCompositionStart,
onCompositionend: onOriginCompositionEnd,
style,
} = inputProps;
inputNode = cloneElement(
inputNode,
Object.assign(
{
id,
ref: inputRef,
disabled,
tabindex,
autocomplete: autocomplete || 'off',
autofocus,
class: classNames(`${prefixCls}-selection-search-input`, inputNode?.props?.className),
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(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);
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(
{
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);
},
},
},
inputNode.type === 'textarea' ? {} : { type: 'search' },
),
true,
true,
) as VNode;
return inputNode;
inputNode.type === 'textarea' ? {} : { type: 'search' },
),
true,
true,
) as VNode;
return inputNode;
};
},
});

Expand Down

0 comments on commit 414e7a1

Please sign in to comment.