fix: select2 bug
parent
b786f6bba6
commit
bd138a8711
|
@ -1 +1 @@
|
|||
Subproject commit 79d49c0ff31a4f505ccd5bc3ad238c08f9925212
|
||||
Subproject commit ac51177e860801a773d0e4241931d03be0efce65
|
|
@ -49,14 +49,14 @@ const OptionListProps = {
|
|||
height: PropTypes.number,
|
||||
itemHeight: PropTypes.number,
|
||||
values: PropTypes.any,
|
||||
multiple: PropTypes.bool,
|
||||
open: PropTypes.bool,
|
||||
defaultActiveFirstOption: PropTypes.bool,
|
||||
multiple: { type: Boolean, default: undefined },
|
||||
open: { type: Boolean, default: undefined },
|
||||
defaultActiveFirstOption: { type: Boolean, default: undefined },
|
||||
notFoundContent: PropTypes.any,
|
||||
menuItemSelectedIcon: PropTypes.any,
|
||||
childrenAsData: PropTypes.bool,
|
||||
childrenAsData: { type: Boolean, default: undefined },
|
||||
searchValue: PropTypes.string,
|
||||
virtual: PropTypes.bool,
|
||||
virtual: { type: Boolean, default: undefined },
|
||||
|
||||
onSelect: PropTypes.func,
|
||||
onToggleOpen: PropTypes.func,
|
||||
|
@ -131,6 +131,7 @@ const OptionList = defineComponent<OptionListProps>({
|
|||
() => {
|
||||
setActive(props.defaultActiveFirstOption !== false ? getEnabledActiveIndex(0) : -1);
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
// Auto scroll to item position in single mode
|
||||
|
||||
|
|
|
@ -71,14 +71,6 @@ const SelectTrigger = defineComponent<SelectTriggerProps>({
|
|||
},
|
||||
|
||||
methods: {
|
||||
getDropdownTransitionName() {
|
||||
const props = this.$props;
|
||||
let transitionName = props.transitionName;
|
||||
if (!transitionName && props.animation) {
|
||||
transitionName = `${this.getDropdownPrefixCls()}-${props.animation}`;
|
||||
}
|
||||
return transitionName;
|
||||
},
|
||||
getPopupElement() {
|
||||
return this.popupRef.current;
|
||||
},
|
||||
|
@ -96,6 +88,8 @@ const SelectTrigger = defineComponent<SelectTriggerProps>({
|
|||
dropdownMatchSelectWidth,
|
||||
containerWidth,
|
||||
dropdownRender,
|
||||
animation,
|
||||
transitionName,
|
||||
} = props;
|
||||
const dropdownPrefixCls = `${prefixCls}-dropdown`;
|
||||
|
||||
|
@ -105,6 +99,9 @@ const SelectTrigger = defineComponent<SelectTriggerProps>({
|
|||
}
|
||||
|
||||
const builtInPlacements = getBuiltInPlacements(dropdownMatchSelectWidth);
|
||||
|
||||
const mergedTransitionName = animation ? `${dropdownPrefixCls}-${animation}` : transitionName;
|
||||
|
||||
const popupStyle = { minWidth: containerWidth, ...dropdownStyle };
|
||||
|
||||
if (typeof dropdownMatchSelectWidth === 'number') {
|
||||
|
@ -120,7 +117,7 @@ const SelectTrigger = defineComponent<SelectTriggerProps>({
|
|||
popupPlacement={this.direction === 'rtl' ? 'bottomRight' : 'bottomLeft'}
|
||||
builtinPlacements={builtInPlacements}
|
||||
prefixCls={dropdownPrefixCls}
|
||||
popupTransitionName={this.getDropdownTransitionName()}
|
||||
popupTransitionName={mergedTransitionName}
|
||||
onPopupVisibleChange={props.onDropdownVisibleChange}
|
||||
popup={<div ref={this.popupRef}>{popupNode}</div>}
|
||||
popupAlign={dropdownAlign}
|
||||
|
@ -139,11 +136,11 @@ const SelectTrigger = defineComponent<SelectTriggerProps>({
|
|||
});
|
||||
SelectTrigger.props = {
|
||||
dropdownAlign: PropTypes.object,
|
||||
visible: PropTypes.bool,
|
||||
disabled: PropTypes.bool,
|
||||
visible: { type: Boolean, default: undefined },
|
||||
disabled: { type: Boolean, default: undefined },
|
||||
dropdownClassName: PropTypes.string,
|
||||
dropdownStyle: PropTypes.object,
|
||||
empty: PropTypes.bool,
|
||||
empty: { type: Boolean, default: undefined },
|
||||
prefixCls: PropTypes.string,
|
||||
popupClassName: PropTypes.string,
|
||||
animation: PropTypes.string,
|
||||
|
|
|
@ -68,66 +68,72 @@ const Input = defineComponent<InputProps>({
|
|||
onCompositionend: onOriginCompositionEnd,
|
||||
style,
|
||||
} = inputProps;
|
||||
|
||||
inputNode = cloneElement(inputNode, {
|
||||
id,
|
||||
ref: inputRef,
|
||||
disabled,
|
||||
tabindex,
|
||||
autocomplete: autocomplete || 'off',
|
||||
type: 'search',
|
||||
autofocus,
|
||||
class: `${prefixCls}-selection-search-input`,
|
||||
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': `${id}_list_${accessibilityIndex}`,
|
||||
...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[]) => {
|
||||
this.VCSelectContainerEvent?.focus(args[0]);
|
||||
},
|
||||
onBlur: (...args: any[]) => {
|
||||
this.VCSelectContainerEvent?.blur(args[0]);
|
||||
},
|
||||
}) as VNode;
|
||||
inputNode = cloneElement(
|
||||
inputNode,
|
||||
Object.assign(
|
||||
{
|
||||
id,
|
||||
ref: inputRef,
|
||||
disabled,
|
||||
tabindex,
|
||||
autocomplete: autocomplete || 'off',
|
||||
autofocus,
|
||||
class: `${prefixCls}-selection-search-input`,
|
||||
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': `${id}_list_${accessibilityIndex}`,
|
||||
...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[]) => {
|
||||
this.VCSelectContainerEvent?.focus(args[0]);
|
||||
},
|
||||
onBlur: (...args: any[]) => {
|
||||
this.VCSelectContainerEvent?.blur(args[0]);
|
||||
},
|
||||
},
|
||||
inputNode.type === 'textarea' ? {} : { type: 'search' },
|
||||
),
|
||||
true,
|
||||
true,
|
||||
) as VNode;
|
||||
return inputNode;
|
||||
},
|
||||
});
|
||||
|
@ -137,13 +143,13 @@ Input.props = {
|
|||
prefixCls: PropTypes.string,
|
||||
id: PropTypes.string,
|
||||
inputElement: PropTypes.any,
|
||||
disabled: PropTypes.bool,
|
||||
autofocus: PropTypes.bool,
|
||||
disabled: { type: Boolean, default: undefined },
|
||||
autofocus: { type: Boolean, default: undefined },
|
||||
autocomplete: PropTypes.string,
|
||||
editable: PropTypes.bool,
|
||||
editable: { type: Boolean, default: undefined },
|
||||
accessibilityIndex: PropTypes.number,
|
||||
value: PropTypes.string,
|
||||
open: PropTypes.bool,
|
||||
open: { type: Boolean, default: undefined },
|
||||
tabindex: PropTypes.number,
|
||||
/** Pass accessibility props to input */
|
||||
attrs: PropTypes.object,
|
||||
|
|
|
@ -43,19 +43,19 @@ const props = {
|
|||
id: PropTypes.string,
|
||||
prefixCls: PropTypes.string,
|
||||
values: PropTypes.array,
|
||||
open: PropTypes.bool,
|
||||
open: { type: Boolean, default: undefined },
|
||||
searchValue: PropTypes.string,
|
||||
inputRef: PropTypes.any,
|
||||
placeholder: PropTypes.any,
|
||||
disabled: PropTypes.bool,
|
||||
disabled: { type: Boolean, default: undefined },
|
||||
mode: PropTypes.string,
|
||||
showSearch: PropTypes.bool,
|
||||
autofocus: PropTypes.bool,
|
||||
showSearch: { type: Boolean, default: undefined },
|
||||
autofocus: { type: Boolean, default: undefined },
|
||||
autocomplete: PropTypes.string,
|
||||
accessibilityIndex: PropTypes.number,
|
||||
tabindex: PropTypes.number,
|
||||
|
||||
removeIcon: PropTypes.bool,
|
||||
removeIcon: { type: Boolean, default: undefined },
|
||||
choiceTransitionName: PropTypes.string,
|
||||
|
||||
maxTagCount: PropTypes.number,
|
||||
|
@ -95,13 +95,16 @@ const SelectSelector = defineComponent<SelectorProps>({
|
|||
);
|
||||
|
||||
// We measure width and set to the input immediately
|
||||
watch(
|
||||
inputValue,
|
||||
() => {
|
||||
inputWidth.value = measureRef.value.scrollWidth;
|
||||
},
|
||||
{ flush: 'pre' },
|
||||
);
|
||||
onMounted(() => {
|
||||
watch(
|
||||
inputValue,
|
||||
() => {
|
||||
inputWidth.value = measureRef.value.scrollWidth;
|
||||
},
|
||||
{ flush: 'post' },
|
||||
);
|
||||
});
|
||||
|
||||
const selectionNode = ref();
|
||||
watchEffect(() => {
|
||||
const {
|
||||
|
|
|
@ -14,19 +14,19 @@ const props = {
|
|||
id: PropTypes.string,
|
||||
prefixCls: PropTypes.string,
|
||||
values: PropTypes.array,
|
||||
open: PropTypes.bool,
|
||||
open: { type: Boolean, default: undefined },
|
||||
searchValue: PropTypes.string,
|
||||
inputRef: PropTypes.any,
|
||||
placeholder: PropTypes.any,
|
||||
disabled: PropTypes.bool,
|
||||
disabled: { type: Boolean, default: undefined },
|
||||
mode: PropTypes.string,
|
||||
showSearch: PropTypes.bool,
|
||||
autofocus: PropTypes.bool,
|
||||
showSearch: { type: Boolean, default: undefined },
|
||||
autofocus: { type: Boolean, default: undefined },
|
||||
autocomplete: PropTypes.string,
|
||||
accessibilityIndex: PropTypes.number,
|
||||
tabindex: PropTypes.number,
|
||||
activeValue: PropTypes.string,
|
||||
backfill: PropTypes.bool,
|
||||
backfill: { type: Boolean, default: undefined },
|
||||
onInputChange: PropTypes.func,
|
||||
onInputPaste: PropTypes.func,
|
||||
onInputKeyDown: PropTypes.func,
|
||||
|
@ -56,6 +56,7 @@ const SingleSelector = defineComponent<SelectorProps>({
|
|||
inputChanged.value = false;
|
||||
}
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
|
||||
// Not show text when closed expect combobox mode
|
||||
|
|
|
@ -252,20 +252,20 @@ Selector.inheritAttrs = false;
|
|||
Selector.props = {
|
||||
id: PropTypes.string,
|
||||
prefixCls: PropTypes.string,
|
||||
showSearch: PropTypes.bool,
|
||||
open: PropTypes.bool,
|
||||
showSearch: { type: Boolean, default: undefined },
|
||||
open: { type: Boolean, default: undefined },
|
||||
/** Display in the Selector value, it's not same as `value` prop */
|
||||
values: PropTypes.array,
|
||||
multiple: PropTypes.bool,
|
||||
multiple: { type: Boolean, default: undefined },
|
||||
mode: PropTypes.string,
|
||||
searchValue: PropTypes.string,
|
||||
activeValue: PropTypes.string,
|
||||
inputElement: PropTypes.any,
|
||||
|
||||
autofocus: PropTypes.bool,
|
||||
autofocus: { type: Boolean, default: undefined },
|
||||
accessibilityIndex: PropTypes.number,
|
||||
tabindex: PropTypes.number,
|
||||
disabled: PropTypes.bool,
|
||||
disabled: { type: Boolean, default: undefined },
|
||||
placeholder: PropTypes.any,
|
||||
removeIcon: PropTypes.any,
|
||||
|
||||
|
@ -276,7 +276,7 @@ Selector.props = {
|
|||
tagRender: PropTypes.func,
|
||||
|
||||
/** Check if `tokenSeparators` contains `\n` or `\r\n` */
|
||||
tokenWithEnter: PropTypes.bool,
|
||||
tokenWithEnter: { type: Boolean, default: undefined },
|
||||
|
||||
// Motion
|
||||
choiceTransitionName: PropTypes.string,
|
||||
|
|
|
@ -0,0 +1,136 @@
|
|||
import createRef from '../../_util/createRef';
|
||||
/* eslint-disable no-console */
|
||||
import Select, { Option } from '..';
|
||||
import '../assets/index.less';
|
||||
import { nextTick } from 'vue';
|
||||
|
||||
const Combobox = {
|
||||
data() {
|
||||
this.textareaRef = createRef();
|
||||
|
||||
this.timeoutId;
|
||||
return {
|
||||
disabled: false,
|
||||
value: '',
|
||||
options: [],
|
||||
};
|
||||
},
|
||||
|
||||
mounted() {
|
||||
nextTick(() => {
|
||||
console.log('Ref:', this.textareaRef.current);
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
onChange(value, option) {
|
||||
console.log('onChange', value, option);
|
||||
|
||||
this.value = value;
|
||||
},
|
||||
|
||||
onKeyDown(e) {
|
||||
const { value } = this;
|
||||
if (e.keyCode === 13) {
|
||||
console.log('onEnter', value);
|
||||
}
|
||||
},
|
||||
|
||||
onSelect(v, option) {
|
||||
console.log('onSelect', v, option);
|
||||
},
|
||||
|
||||
onSearch(text: string) {
|
||||
console.log('onSearch:', text);
|
||||
},
|
||||
|
||||
onAsyncChange(value) {
|
||||
window.clearTimeout(this.timeoutId);
|
||||
console.log(value);
|
||||
this.options = [];
|
||||
//const value = String(Math.random());
|
||||
this.timeoutId = window.setTimeout(() => {
|
||||
this.options = [{ value }, { value: `${value}-${value}` }];
|
||||
}, 1000);
|
||||
},
|
||||
|
||||
toggleDisabled() {
|
||||
const { disabled } = this;
|
||||
|
||||
this.disabled = !disabled;
|
||||
},
|
||||
},
|
||||
|
||||
render() {
|
||||
const { value, disabled } = this;
|
||||
return (
|
||||
<div>
|
||||
<h2>combobox</h2>
|
||||
<p>
|
||||
<button type="button" onClick={this.toggleDisabled}>
|
||||
toggle disabled
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
this.value = '';
|
||||
}}
|
||||
>
|
||||
reset
|
||||
</button>
|
||||
</p>
|
||||
<div>
|
||||
<Select
|
||||
disabled={disabled}
|
||||
style={{ width: '500px' }}
|
||||
onChange={this.onChange}
|
||||
onSelect={this.onSelect}
|
||||
onSearch={this.onSearch}
|
||||
onInputKeyDown={this.onKeyDown}
|
||||
notFoundContent=""
|
||||
allowClear
|
||||
placeholder="please select"
|
||||
value={value}
|
||||
mode="combobox"
|
||||
backfill
|
||||
onFocus={() => console.log('focus')}
|
||||
onBlur={() => console.log('blur')}
|
||||
>
|
||||
<Option value="jack">
|
||||
<b style={{ color: 'red' }}>jack</b>
|
||||
</Option>
|
||||
<Option value="lucy">lucy</Option>
|
||||
<Option value="disabled" disabled>
|
||||
disabled
|
||||
</Option>
|
||||
<Option value="yiminghe">yiminghe</Option>
|
||||
<Option value="竹林星光">竹林星光</Option>
|
||||
</Select>
|
||||
|
||||
<h3>Customize Input Element</h3>
|
||||
<Select
|
||||
mode="combobox"
|
||||
style={{ width: '200px' }}
|
||||
getInputElement={() => (
|
||||
<textarea style={{ background: 'red' }} rows={3} ref={this.textareaRef} />
|
||||
)}
|
||||
options={[{ value: 'light' }, { value: 'bamboo' }]}
|
||||
allowClear
|
||||
placeholder="2333"
|
||||
/>
|
||||
|
||||
<h3>Async Input Element</h3>
|
||||
<Select
|
||||
mode="combobox"
|
||||
notFoundContent={null}
|
||||
style={{ width: '200px' }}
|
||||
options={this.options}
|
||||
onChange={this.onAsyncChange}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
export default Combobox;
|
||||
/* eslint-enable */
|
|
@ -0,0 +1,105 @@
|
|||
/* eslint-disable no-console */
|
||||
|
||||
import Select, { Option } from '..';
|
||||
import '../assets/index.less';
|
||||
|
||||
interface ControlledState {
|
||||
destroy: boolean;
|
||||
value: string | number;
|
||||
open: boolean;
|
||||
}
|
||||
|
||||
const Controlled = {
|
||||
data: () => ({
|
||||
destroy: false,
|
||||
value: 9,
|
||||
open: true,
|
||||
}),
|
||||
methods: {
|
||||
onChange(e) {
|
||||
let value;
|
||||
if (e && e.target) {
|
||||
({ value } = e.target);
|
||||
} else {
|
||||
value = e;
|
||||
}
|
||||
console.log('onChange', value);
|
||||
this.value = value;
|
||||
},
|
||||
|
||||
onDestroy() {
|
||||
this.destroy = true;
|
||||
},
|
||||
|
||||
onBlur(v) {
|
||||
console.log('onBlur', v);
|
||||
},
|
||||
|
||||
onFocus() {
|
||||
console.log('onFocus');
|
||||
},
|
||||
|
||||
onDropdownVisibleChange(open) {
|
||||
this.open = open;
|
||||
},
|
||||
getPopupContainer(node) {
|
||||
return node.parentNode;
|
||||
},
|
||||
},
|
||||
|
||||
render() {
|
||||
const { open, destroy, value } = this;
|
||||
if (destroy) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<div style={{ margin: '20px' }}>
|
||||
<h2>controlled Select</h2>
|
||||
<div style={{ width: '300px' }}>
|
||||
<Select
|
||||
id="my-select"
|
||||
value={value}
|
||||
placeholder="placeholder"
|
||||
listHeight={200}
|
||||
style={{ width: '500px' }}
|
||||
onBlur={this.onBlur}
|
||||
onFocus={this.onFocus}
|
||||
open={open}
|
||||
optionLabelProp="children"
|
||||
optionFilterProp="text"
|
||||
onChange={this.onChange}
|
||||
onDropdownVisibleChange={this.onDropdownVisibleChange}
|
||||
//getPopupContainer={this.getPopupContainer}
|
||||
>
|
||||
<Option value="01" text="jack" title="jack">
|
||||
<b
|
||||
style={{
|
||||
color: 'red',
|
||||
}}
|
||||
>
|
||||
jack
|
||||
</b>
|
||||
</Option>
|
||||
<Option value="11" text="lucy">
|
||||
lucy
|
||||
</Option>
|
||||
<Option value="21" disabled text="disabled">
|
||||
disabled
|
||||
</Option>
|
||||
<Option value="31" text="yiminghe">
|
||||
yiminghe
|
||||
</Option>
|
||||
{[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map(i => (
|
||||
<Option key={i} value={i} text={String(i)}>
|
||||
{i}-text
|
||||
</Option>
|
||||
))}
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
export default Controlled;
|
||||
/* eslint-enable */
|
|
@ -0,0 +1,119 @@
|
|||
/* eslint-disable no-console */
|
||||
|
||||
import Select, { Option } from '..';
|
||||
import '../assets/index.less';
|
||||
|
||||
const children = [];
|
||||
for (let i = 10; i < 36; i += 1) {
|
||||
children.push(
|
||||
<Option
|
||||
key={i.toString(36) + i}
|
||||
disabled={i === 10}
|
||||
title={`中文${i}`}
|
||||
vSlots={{ default: () => `中文${i}` }}
|
||||
></Option>,
|
||||
);
|
||||
}
|
||||
|
||||
const Test = {
|
||||
data: () => ({
|
||||
state: {
|
||||
useAnim: false,
|
||||
showArrow: false,
|
||||
loading: false,
|
||||
value: ['a10'],
|
||||
},
|
||||
}),
|
||||
methods: {
|
||||
setState(state) {
|
||||
Object.assign(this.state, state);
|
||||
},
|
||||
onChange(value, options) {
|
||||
console.log('onChange', value, options);
|
||||
this.setState({
|
||||
value,
|
||||
});
|
||||
},
|
||||
|
||||
onSelect(...args) {
|
||||
console.log(args);
|
||||
},
|
||||
|
||||
onDeselect(...args) {
|
||||
console.log(args);
|
||||
},
|
||||
|
||||
useAnim(e) {
|
||||
this.setState({
|
||||
useAnim: e.target.checked,
|
||||
});
|
||||
},
|
||||
|
||||
showArrow(e) {
|
||||
this.setState({
|
||||
showArrow: e.target.checked,
|
||||
});
|
||||
},
|
||||
|
||||
loading(e) {
|
||||
this.setState({
|
||||
loading: e.target.checked,
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
render() {
|
||||
const { useAnim, showArrow, loading, value } = this.state;
|
||||
console.log(showArrow);
|
||||
return (
|
||||
<div>
|
||||
<h2>multiple select(scroll the menu)</h2>
|
||||
|
||||
<p>
|
||||
<label html-for="useAnim">
|
||||
anim
|
||||
<input id="useAnim" checked={useAnim} type="checkbox" onChange={this.useAnim} />
|
||||
</label>
|
||||
<p />
|
||||
<label html-for="showArrow">
|
||||
showArrow
|
||||
<input id="showArrow" checked={showArrow} type="checkbox" onChange={this.showArrow} />
|
||||
</label>
|
||||
</p>
|
||||
<p>
|
||||
<label html-for="loading">
|
||||
loading
|
||||
<input id="loading" checked={loading} type="checkbox" onChange={this.loading} />
|
||||
</label>
|
||||
</p>
|
||||
|
||||
<div style={{ width: '300px' }}>
|
||||
<Select
|
||||
value={value}
|
||||
animation={useAnim ? 'slide-up' : null}
|
||||
choiceTransitionName="rc-select-selection__choice-zoom"
|
||||
style={{ width: '500px' }}
|
||||
mode="multiple"
|
||||
loading={loading}
|
||||
showArrow={showArrow}
|
||||
allowClear
|
||||
optionFilterProp="children"
|
||||
optionLabelProp="children"
|
||||
onSelect={this.onSelect}
|
||||
onDeselect={this.onDeselect}
|
||||
placeholder="please select"
|
||||
onChange={this.onChange}
|
||||
onFocus={() => console.log('focus')}
|
||||
onBlur={v => console.log('blur', v)}
|
||||
tokenSeparators={[' ', ',']}
|
||||
>
|
||||
{children}
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
export default Test;
|
||||
/* eslint-enable */
|
|
@ -128,7 +128,7 @@ export interface SelectProps<OptionsType extends object[], ValueType> {
|
|||
notFoundContent?: VNodeChild;
|
||||
placeholder?: VNodeChild;
|
||||
backfill?: boolean;
|
||||
getInputElement?: () => VNodeChild;
|
||||
getInputElement?: () => VNodeChild | JSX.Element;
|
||||
optionLabelProp?: string;
|
||||
maxTagTextLength?: number;
|
||||
maxTagCount?: number;
|
||||
|
@ -379,16 +379,17 @@ export default function generateSelector<
|
|||
});
|
||||
|
||||
const displayFlattenOptions = computed(() => flattenOptions(displayOptions.value, props));
|
||||
|
||||
watch(
|
||||
mergedSearchValue,
|
||||
() => {
|
||||
if (listRef.value && listRef.value.scrollTo) {
|
||||
listRef.value.scrollTo(0);
|
||||
}
|
||||
},
|
||||
{ flush: 'post' },
|
||||
);
|
||||
onMounted(() => {
|
||||
watch(
|
||||
mergedSearchValue,
|
||||
() => {
|
||||
if (listRef.value && listRef.value.scrollTo) {
|
||||
listRef.value.scrollTo(0);
|
||||
}
|
||||
},
|
||||
{ flush: 'post', immediate: true },
|
||||
);
|
||||
});
|
||||
|
||||
// ============================ Selector ============================
|
||||
let displayValues = computed<DisplayLabelValueType[]>(() => {
|
||||
|
@ -556,13 +557,14 @@ export default function generateSelector<
|
|||
let mergedOpen = ref(undefined);
|
||||
const setInnerOpen = (val: boolean) => {
|
||||
innerOpen.value = val;
|
||||
mergedOpen.value = val;
|
||||
mergedOpen.value = innerOpen.value;
|
||||
};
|
||||
watch(
|
||||
computed(() => [props.defaultOpen, props.open]),
|
||||
() => {
|
||||
setInnerOpen(props.open !== undefined ? props.open : props.defaultOpen);
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
|
||||
// Not trigger `open` in `combobox` when `notFoundContent` is empty
|
||||
|
@ -573,14 +575,16 @@ export default function generateSelector<
|
|||
computed(
|
||||
() =>
|
||||
props.disabled ||
|
||||
(emptyListContent.value && mergedOpen.value && props.mode === 'combobox'),
|
||||
(emptyListContent.value && innerOpen.value && props.mode === 'combobox'),
|
||||
),
|
||||
val => {
|
||||
debugger;
|
||||
if (val) {
|
||||
mergedOpen.value = false;
|
||||
} else {
|
||||
mergedOpen.value = innerOpen.value;
|
||||
}
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
|
||||
const triggerOpen = computed(() => (emptyListContent.value ? false : mergedOpen.value));
|
||||
|
@ -590,7 +594,6 @@ export default function generateSelector<
|
|||
|
||||
if (innerOpen.value !== nextOpen && !props.disabled) {
|
||||
setInnerOpen(nextOpen);
|
||||
|
||||
if (props.onDropdownVisibleChange) {
|
||||
props.onDropdownVisibleChange(nextOpen);
|
||||
}
|
||||
|
@ -681,14 +684,19 @@ export default function generateSelector<
|
|||
setInnerOpen(false);
|
||||
}
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
|
||||
// Close will clean up single mode search text
|
||||
watch(mergedOpen, () => {
|
||||
if (innerOpen.value && !!props.disabled) {
|
||||
setInnerOpen(false);
|
||||
}
|
||||
});
|
||||
watch(
|
||||
mergedOpen,
|
||||
() => {
|
||||
if (!mergedOpen.value && !isMultiple.value && props.mode !== 'combobox') {
|
||||
triggerSearch('', false, false);
|
||||
}
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
// ============================ Keyboard ============================
|
||||
/**
|
||||
* We record input value here to check if can press to clean up by backspace
|
||||
|
@ -857,15 +865,21 @@ export default function generateSelector<
|
|||
|
||||
// ============================= Popup ==============================
|
||||
const containerWidth = ref(null);
|
||||
|
||||
watch(triggerOpen, () => {
|
||||
if (triggerOpen.value) {
|
||||
const newWidth = Math.ceil(containerRef.value.offsetWidth);
|
||||
if (containerWidth !== newWidth) {
|
||||
containerWidth.value = newWidth;
|
||||
}
|
||||
}
|
||||
onMounted(() => {
|
||||
watch(
|
||||
triggerOpen,
|
||||
() => {
|
||||
if (triggerOpen.value) {
|
||||
const newWidth = Math.ceil(containerRef.value.offsetWidth);
|
||||
if (containerWidth !== newWidth) {
|
||||
containerWidth.value = newWidth;
|
||||
}
|
||||
}
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
});
|
||||
|
||||
const focus = () => {
|
||||
selectorRef.value.focus();
|
||||
};
|
||||
|
@ -954,10 +968,27 @@ export default function generateSelector<
|
|||
const {
|
||||
prefixCls = defaultPrefixCls,
|
||||
class: className,
|
||||
children,
|
||||
id,
|
||||
|
||||
open,
|
||||
defaultOpen,
|
||||
options,
|
||||
children,
|
||||
|
||||
mode,
|
||||
value,
|
||||
defaultValue,
|
||||
labelInValue,
|
||||
|
||||
// Search related
|
||||
showSearch,
|
||||
inputValue,
|
||||
searchValue,
|
||||
filterOption,
|
||||
optionFilterProp = 'value',
|
||||
autoClearSearchValue = true,
|
||||
onSearch,
|
||||
|
||||
// Icons
|
||||
allowClear,
|
||||
clearIcon,
|
||||
|
@ -968,7 +999,10 @@ export default function generateSelector<
|
|||
// Others
|
||||
disabled,
|
||||
loading,
|
||||
defaultActiveFirstOption,
|
||||
notFoundContent = 'Not Found',
|
||||
optionLabelProp,
|
||||
backfill,
|
||||
getInputElement,
|
||||
getPopupContainer,
|
||||
|
||||
|
@ -983,13 +1017,25 @@ export default function generateSelector<
|
|||
dropdownMatchSelectWidth,
|
||||
dropdownRender,
|
||||
dropdownAlign,
|
||||
showAction = [],
|
||||
direction,
|
||||
|
||||
// Tags
|
||||
tokenSeparators,
|
||||
tagRender,
|
||||
|
||||
// Events
|
||||
onPopupScroll,
|
||||
onDropdownVisibleChange,
|
||||
onFocus,
|
||||
onBlur,
|
||||
onKeyup,
|
||||
onKeydown,
|
||||
onMousedown,
|
||||
|
||||
onChange,
|
||||
onSelect,
|
||||
onDeselect,
|
||||
onClear,
|
||||
|
||||
internalProps = {},
|
||||
|
@ -999,7 +1045,7 @@ export default function generateSelector<
|
|||
|
||||
// ============================= Input ==============================
|
||||
// Only works in `combobox`
|
||||
const customizeInputElement: VNodeChild =
|
||||
const customizeInputElement: VNodeChild | JSX.Element =
|
||||
(mode === 'combobox' && getInputElement && getInputElement()) || null;
|
||||
|
||||
const domProps = omitDOMProps ? omitDOMProps(restProps) : restProps;
|
||||
|
@ -1192,7 +1238,7 @@ export default function generateSelector<
|
|||
// Value
|
||||
value: PropTypes.any,
|
||||
defaultValue: PropTypes.any,
|
||||
labelInValue: PropTypes.bool,
|
||||
labelInValue: { type: Boolean, default: undefined },
|
||||
|
||||
// Search
|
||||
inputValue: PropTypes.string,
|
||||
|
@ -1204,13 +1250,13 @@ export default function generateSelector<
|
|||
* It's by design.
|
||||
*/
|
||||
filterOption: PropTypes.any,
|
||||
showSearch: PropTypes.bool,
|
||||
autoClearSearchValue: PropTypes.bool,
|
||||
showSearch: { type: Boolean, default: undefined },
|
||||
autoClearSearchValue: { type: Boolean, default: undefined },
|
||||
onSearch: PropTypes.func,
|
||||
onClear: PropTypes.func,
|
||||
|
||||
// Icons
|
||||
allowClear: PropTypes.bool,
|
||||
allowClear: { type: Boolean, default: undefined },
|
||||
clearIcon: PropTypes.any,
|
||||
showArrow: {
|
||||
type: Boolean,
|
||||
|
@ -1221,14 +1267,14 @@ export default function generateSelector<
|
|||
menuItemSelectedIcon: PropTypes.func,
|
||||
|
||||
// Dropdown
|
||||
open: PropTypes.bool,
|
||||
defaultOpen: PropTypes.bool,
|
||||
open: { type: Boolean, default: undefined },
|
||||
defaultOpen: { type: Boolean, default: undefined },
|
||||
listHeight: PropTypes.number.def(200),
|
||||
listItemHeight: PropTypes.number.def(20),
|
||||
dropdownStyle: PropTypes.object,
|
||||
dropdownClassName: PropTypes.string,
|
||||
dropdownMatchSelectWidth: PropTypes.oneOfType([Boolean, Number]).def(true),
|
||||
virtual: PropTypes.bool,
|
||||
virtual: { type: Boolean, default: undefined },
|
||||
dropdownRender: PropTypes.func,
|
||||
dropdownAlign: PropTypes.any,
|
||||
animation: PropTypes.string,
|
||||
|
@ -1237,13 +1283,13 @@ export default function generateSelector<
|
|||
direction: PropTypes.string,
|
||||
|
||||
// Others
|
||||
disabled: PropTypes.bool,
|
||||
loading: PropTypes.bool,
|
||||
autofocus: PropTypes.bool,
|
||||
defaultActiveFirstOption: PropTypes.bool,
|
||||
disabled: { type: Boolean, default: undefined },
|
||||
loading: { type: Boolean, default: undefined },
|
||||
autofocus: { type: Boolean, default: undefined },
|
||||
defaultActiveFirstOption: { type: Boolean, default: undefined },
|
||||
notFoundContent: PropTypes.any.def('Not Found'),
|
||||
placeholder: PropTypes.any,
|
||||
backfill: PropTypes.bool,
|
||||
backfill: { type: Boolean, default: undefined },
|
||||
getInputElement: PropTypes.func,
|
||||
optionLabelProp: PropTypes.string,
|
||||
maxTagTextLength: PropTypes.number,
|
||||
|
|
|
@ -18,7 +18,7 @@ export type OnActiveValue = (
|
|||
export interface OptionCoreData {
|
||||
key?: Key;
|
||||
disabled?: boolean;
|
||||
value: Key;
|
||||
value?: Key;
|
||||
title?: string;
|
||||
class?: string;
|
||||
style?: Vue.CSSProperties;
|
||||
|
|
Loading…
Reference in New Issue