fix: select2 bug
parent
b786f6bba6
commit
bd138a8711
|
@ -1 +1 @@
|
||||||
Subproject commit 79d49c0ff31a4f505ccd5bc3ad238c08f9925212
|
Subproject commit ac51177e860801a773d0e4241931d03be0efce65
|
|
@ -49,14 +49,14 @@ const OptionListProps = {
|
||||||
height: PropTypes.number,
|
height: PropTypes.number,
|
||||||
itemHeight: PropTypes.number,
|
itemHeight: PropTypes.number,
|
||||||
values: PropTypes.any,
|
values: PropTypes.any,
|
||||||
multiple: PropTypes.bool,
|
multiple: { type: Boolean, default: undefined },
|
||||||
open: PropTypes.bool,
|
open: { type: Boolean, default: undefined },
|
||||||
defaultActiveFirstOption: PropTypes.bool,
|
defaultActiveFirstOption: { type: Boolean, default: undefined },
|
||||||
notFoundContent: PropTypes.any,
|
notFoundContent: PropTypes.any,
|
||||||
menuItemSelectedIcon: PropTypes.any,
|
menuItemSelectedIcon: PropTypes.any,
|
||||||
childrenAsData: PropTypes.bool,
|
childrenAsData: { type: Boolean, default: undefined },
|
||||||
searchValue: PropTypes.string,
|
searchValue: PropTypes.string,
|
||||||
virtual: PropTypes.bool,
|
virtual: { type: Boolean, default: undefined },
|
||||||
|
|
||||||
onSelect: PropTypes.func,
|
onSelect: PropTypes.func,
|
||||||
onToggleOpen: PropTypes.func,
|
onToggleOpen: PropTypes.func,
|
||||||
|
@ -131,6 +131,7 @@ const OptionList = defineComponent<OptionListProps>({
|
||||||
() => {
|
() => {
|
||||||
setActive(props.defaultActiveFirstOption !== false ? getEnabledActiveIndex(0) : -1);
|
setActive(props.defaultActiveFirstOption !== false ? getEnabledActiveIndex(0) : -1);
|
||||||
},
|
},
|
||||||
|
{ immediate: true },
|
||||||
);
|
);
|
||||||
// Auto scroll to item position in single mode
|
// Auto scroll to item position in single mode
|
||||||
|
|
||||||
|
|
|
@ -71,14 +71,6 @@ const SelectTrigger = defineComponent<SelectTriggerProps>({
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
getDropdownTransitionName() {
|
|
||||||
const props = this.$props;
|
|
||||||
let transitionName = props.transitionName;
|
|
||||||
if (!transitionName && props.animation) {
|
|
||||||
transitionName = `${this.getDropdownPrefixCls()}-${props.animation}`;
|
|
||||||
}
|
|
||||||
return transitionName;
|
|
||||||
},
|
|
||||||
getPopupElement() {
|
getPopupElement() {
|
||||||
return this.popupRef.current;
|
return this.popupRef.current;
|
||||||
},
|
},
|
||||||
|
@ -96,6 +88,8 @@ const SelectTrigger = defineComponent<SelectTriggerProps>({
|
||||||
dropdownMatchSelectWidth,
|
dropdownMatchSelectWidth,
|
||||||
containerWidth,
|
containerWidth,
|
||||||
dropdownRender,
|
dropdownRender,
|
||||||
|
animation,
|
||||||
|
transitionName,
|
||||||
} = props;
|
} = props;
|
||||||
const dropdownPrefixCls = `${prefixCls}-dropdown`;
|
const dropdownPrefixCls = `${prefixCls}-dropdown`;
|
||||||
|
|
||||||
|
@ -105,6 +99,9 @@ const SelectTrigger = defineComponent<SelectTriggerProps>({
|
||||||
}
|
}
|
||||||
|
|
||||||
const builtInPlacements = getBuiltInPlacements(dropdownMatchSelectWidth);
|
const builtInPlacements = getBuiltInPlacements(dropdownMatchSelectWidth);
|
||||||
|
|
||||||
|
const mergedTransitionName = animation ? `${dropdownPrefixCls}-${animation}` : transitionName;
|
||||||
|
|
||||||
const popupStyle = { minWidth: containerWidth, ...dropdownStyle };
|
const popupStyle = { minWidth: containerWidth, ...dropdownStyle };
|
||||||
|
|
||||||
if (typeof dropdownMatchSelectWidth === 'number') {
|
if (typeof dropdownMatchSelectWidth === 'number') {
|
||||||
|
@ -120,7 +117,7 @@ const SelectTrigger = defineComponent<SelectTriggerProps>({
|
||||||
popupPlacement={this.direction === 'rtl' ? 'bottomRight' : 'bottomLeft'}
|
popupPlacement={this.direction === 'rtl' ? 'bottomRight' : 'bottomLeft'}
|
||||||
builtinPlacements={builtInPlacements}
|
builtinPlacements={builtInPlacements}
|
||||||
prefixCls={dropdownPrefixCls}
|
prefixCls={dropdownPrefixCls}
|
||||||
popupTransitionName={this.getDropdownTransitionName()}
|
popupTransitionName={mergedTransitionName}
|
||||||
onPopupVisibleChange={props.onDropdownVisibleChange}
|
onPopupVisibleChange={props.onDropdownVisibleChange}
|
||||||
popup={<div ref={this.popupRef}>{popupNode}</div>}
|
popup={<div ref={this.popupRef}>{popupNode}</div>}
|
||||||
popupAlign={dropdownAlign}
|
popupAlign={dropdownAlign}
|
||||||
|
@ -139,11 +136,11 @@ const SelectTrigger = defineComponent<SelectTriggerProps>({
|
||||||
});
|
});
|
||||||
SelectTrigger.props = {
|
SelectTrigger.props = {
|
||||||
dropdownAlign: PropTypes.object,
|
dropdownAlign: PropTypes.object,
|
||||||
visible: PropTypes.bool,
|
visible: { type: Boolean, default: undefined },
|
||||||
disabled: PropTypes.bool,
|
disabled: { type: Boolean, default: undefined },
|
||||||
dropdownClassName: PropTypes.string,
|
dropdownClassName: PropTypes.string,
|
||||||
dropdownStyle: PropTypes.object,
|
dropdownStyle: PropTypes.object,
|
||||||
empty: PropTypes.bool,
|
empty: { type: Boolean, default: undefined },
|
||||||
prefixCls: PropTypes.string,
|
prefixCls: PropTypes.string,
|
||||||
popupClassName: PropTypes.string,
|
popupClassName: PropTypes.string,
|
||||||
animation: PropTypes.string,
|
animation: PropTypes.string,
|
||||||
|
|
|
@ -68,14 +68,15 @@ const Input = defineComponent<InputProps>({
|
||||||
onCompositionend: onOriginCompositionEnd,
|
onCompositionend: onOriginCompositionEnd,
|
||||||
style,
|
style,
|
||||||
} = inputProps;
|
} = inputProps;
|
||||||
|
inputNode = cloneElement(
|
||||||
inputNode = cloneElement(inputNode, {
|
inputNode,
|
||||||
|
Object.assign(
|
||||||
|
{
|
||||||
id,
|
id,
|
||||||
ref: inputRef,
|
ref: inputRef,
|
||||||
disabled,
|
disabled,
|
||||||
tabindex,
|
tabindex,
|
||||||
autocomplete: autocomplete || 'off',
|
autocomplete: autocomplete || 'off',
|
||||||
type: 'search',
|
|
||||||
autofocus,
|
autofocus,
|
||||||
class: `${prefixCls}-selection-search-input`,
|
class: `${prefixCls}-selection-search-input`,
|
||||||
style: { ...style, opacity: editable ? null : 0 },
|
style: { ...style, opacity: editable ? null : 0 },
|
||||||
|
@ -127,7 +128,12 @@ const Input = defineComponent<InputProps>({
|
||||||
onBlur: (...args: any[]) => {
|
onBlur: (...args: any[]) => {
|
||||||
this.VCSelectContainerEvent?.blur(args[0]);
|
this.VCSelectContainerEvent?.blur(args[0]);
|
||||||
},
|
},
|
||||||
}) as VNode;
|
},
|
||||||
|
inputNode.type === 'textarea' ? {} : { type: 'search' },
|
||||||
|
),
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
) as VNode;
|
||||||
return inputNode;
|
return inputNode;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -137,13 +143,13 @@ Input.props = {
|
||||||
prefixCls: PropTypes.string,
|
prefixCls: PropTypes.string,
|
||||||
id: PropTypes.string,
|
id: PropTypes.string,
|
||||||
inputElement: PropTypes.any,
|
inputElement: PropTypes.any,
|
||||||
disabled: PropTypes.bool,
|
disabled: { type: Boolean, default: undefined },
|
||||||
autofocus: PropTypes.bool,
|
autofocus: { type: Boolean, default: undefined },
|
||||||
autocomplete: PropTypes.string,
|
autocomplete: PropTypes.string,
|
||||||
editable: PropTypes.bool,
|
editable: { type: Boolean, default: undefined },
|
||||||
accessibilityIndex: PropTypes.number,
|
accessibilityIndex: PropTypes.number,
|
||||||
value: PropTypes.string,
|
value: PropTypes.string,
|
||||||
open: PropTypes.bool,
|
open: { type: Boolean, default: undefined },
|
||||||
tabindex: PropTypes.number,
|
tabindex: PropTypes.number,
|
||||||
/** Pass accessibility props to input */
|
/** Pass accessibility props to input */
|
||||||
attrs: PropTypes.object,
|
attrs: PropTypes.object,
|
||||||
|
|
|
@ -43,19 +43,19 @@ const props = {
|
||||||
id: PropTypes.string,
|
id: PropTypes.string,
|
||||||
prefixCls: PropTypes.string,
|
prefixCls: PropTypes.string,
|
||||||
values: PropTypes.array,
|
values: PropTypes.array,
|
||||||
open: PropTypes.bool,
|
open: { type: Boolean, default: undefined },
|
||||||
searchValue: PropTypes.string,
|
searchValue: PropTypes.string,
|
||||||
inputRef: PropTypes.any,
|
inputRef: PropTypes.any,
|
||||||
placeholder: PropTypes.any,
|
placeholder: PropTypes.any,
|
||||||
disabled: PropTypes.bool,
|
disabled: { type: Boolean, default: undefined },
|
||||||
mode: PropTypes.string,
|
mode: PropTypes.string,
|
||||||
showSearch: PropTypes.bool,
|
showSearch: { type: Boolean, default: undefined },
|
||||||
autofocus: PropTypes.bool,
|
autofocus: { type: Boolean, default: undefined },
|
||||||
autocomplete: PropTypes.string,
|
autocomplete: PropTypes.string,
|
||||||
accessibilityIndex: PropTypes.number,
|
accessibilityIndex: PropTypes.number,
|
||||||
tabindex: PropTypes.number,
|
tabindex: PropTypes.number,
|
||||||
|
|
||||||
removeIcon: PropTypes.bool,
|
removeIcon: { type: Boolean, default: undefined },
|
||||||
choiceTransitionName: PropTypes.string,
|
choiceTransitionName: PropTypes.string,
|
||||||
|
|
||||||
maxTagCount: PropTypes.number,
|
maxTagCount: PropTypes.number,
|
||||||
|
@ -95,13 +95,16 @@ const SelectSelector = defineComponent<SelectorProps>({
|
||||||
);
|
);
|
||||||
|
|
||||||
// We measure width and set to the input immediately
|
// We measure width and set to the input immediately
|
||||||
|
onMounted(() => {
|
||||||
watch(
|
watch(
|
||||||
inputValue,
|
inputValue,
|
||||||
() => {
|
() => {
|
||||||
inputWidth.value = measureRef.value.scrollWidth;
|
inputWidth.value = measureRef.value.scrollWidth;
|
||||||
},
|
},
|
||||||
{ flush: 'pre' },
|
{ flush: 'post' },
|
||||||
);
|
);
|
||||||
|
});
|
||||||
|
|
||||||
const selectionNode = ref();
|
const selectionNode = ref();
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
const {
|
const {
|
||||||
|
|
|
@ -14,19 +14,19 @@ const props = {
|
||||||
id: PropTypes.string,
|
id: PropTypes.string,
|
||||||
prefixCls: PropTypes.string,
|
prefixCls: PropTypes.string,
|
||||||
values: PropTypes.array,
|
values: PropTypes.array,
|
||||||
open: PropTypes.bool,
|
open: { type: Boolean, default: undefined },
|
||||||
searchValue: PropTypes.string,
|
searchValue: PropTypes.string,
|
||||||
inputRef: PropTypes.any,
|
inputRef: PropTypes.any,
|
||||||
placeholder: PropTypes.any,
|
placeholder: PropTypes.any,
|
||||||
disabled: PropTypes.bool,
|
disabled: { type: Boolean, default: undefined },
|
||||||
mode: PropTypes.string,
|
mode: PropTypes.string,
|
||||||
showSearch: PropTypes.bool,
|
showSearch: { type: Boolean, default: undefined },
|
||||||
autofocus: PropTypes.bool,
|
autofocus: { type: Boolean, default: undefined },
|
||||||
autocomplete: PropTypes.string,
|
autocomplete: PropTypes.string,
|
||||||
accessibilityIndex: PropTypes.number,
|
accessibilityIndex: PropTypes.number,
|
||||||
tabindex: PropTypes.number,
|
tabindex: PropTypes.number,
|
||||||
activeValue: PropTypes.string,
|
activeValue: PropTypes.string,
|
||||||
backfill: PropTypes.bool,
|
backfill: { type: Boolean, default: undefined },
|
||||||
onInputChange: PropTypes.func,
|
onInputChange: PropTypes.func,
|
||||||
onInputPaste: PropTypes.func,
|
onInputPaste: PropTypes.func,
|
||||||
onInputKeyDown: PropTypes.func,
|
onInputKeyDown: PropTypes.func,
|
||||||
|
@ -56,6 +56,7 @@ const SingleSelector = defineComponent<SelectorProps>({
|
||||||
inputChanged.value = false;
|
inputChanged.value = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{ immediate: true },
|
||||||
);
|
);
|
||||||
|
|
||||||
// Not show text when closed expect combobox mode
|
// Not show text when closed expect combobox mode
|
||||||
|
|
|
@ -252,20 +252,20 @@ Selector.inheritAttrs = false;
|
||||||
Selector.props = {
|
Selector.props = {
|
||||||
id: PropTypes.string,
|
id: PropTypes.string,
|
||||||
prefixCls: PropTypes.string,
|
prefixCls: PropTypes.string,
|
||||||
showSearch: PropTypes.bool,
|
showSearch: { type: Boolean, default: undefined },
|
||||||
open: PropTypes.bool,
|
open: { type: Boolean, default: undefined },
|
||||||
/** Display in the Selector value, it's not same as `value` prop */
|
/** Display in the Selector value, it's not same as `value` prop */
|
||||||
values: PropTypes.array,
|
values: PropTypes.array,
|
||||||
multiple: PropTypes.bool,
|
multiple: { type: Boolean, default: undefined },
|
||||||
mode: PropTypes.string,
|
mode: PropTypes.string,
|
||||||
searchValue: PropTypes.string,
|
searchValue: PropTypes.string,
|
||||||
activeValue: PropTypes.string,
|
activeValue: PropTypes.string,
|
||||||
inputElement: PropTypes.any,
|
inputElement: PropTypes.any,
|
||||||
|
|
||||||
autofocus: PropTypes.bool,
|
autofocus: { type: Boolean, default: undefined },
|
||||||
accessibilityIndex: PropTypes.number,
|
accessibilityIndex: PropTypes.number,
|
||||||
tabindex: PropTypes.number,
|
tabindex: PropTypes.number,
|
||||||
disabled: PropTypes.bool,
|
disabled: { type: Boolean, default: undefined },
|
||||||
placeholder: PropTypes.any,
|
placeholder: PropTypes.any,
|
||||||
removeIcon: PropTypes.any,
|
removeIcon: PropTypes.any,
|
||||||
|
|
||||||
|
@ -276,7 +276,7 @@ Selector.props = {
|
||||||
tagRender: PropTypes.func,
|
tagRender: PropTypes.func,
|
||||||
|
|
||||||
/** Check if `tokenSeparators` contains `\n` or `\r\n` */
|
/** Check if `tokenSeparators` contains `\n` or `\r\n` */
|
||||||
tokenWithEnter: PropTypes.bool,
|
tokenWithEnter: { type: Boolean, default: undefined },
|
||||||
|
|
||||||
// Motion
|
// Motion
|
||||||
choiceTransitionName: PropTypes.string,
|
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;
|
notFoundContent?: VNodeChild;
|
||||||
placeholder?: VNodeChild;
|
placeholder?: VNodeChild;
|
||||||
backfill?: boolean;
|
backfill?: boolean;
|
||||||
getInputElement?: () => VNodeChild;
|
getInputElement?: () => VNodeChild | JSX.Element;
|
||||||
optionLabelProp?: string;
|
optionLabelProp?: string;
|
||||||
maxTagTextLength?: number;
|
maxTagTextLength?: number;
|
||||||
maxTagCount?: number;
|
maxTagCount?: number;
|
||||||
|
@ -379,7 +379,7 @@ export default function generateSelector<
|
||||||
});
|
});
|
||||||
|
|
||||||
const displayFlattenOptions = computed(() => flattenOptions(displayOptions.value, props));
|
const displayFlattenOptions = computed(() => flattenOptions(displayOptions.value, props));
|
||||||
|
onMounted(() => {
|
||||||
watch(
|
watch(
|
||||||
mergedSearchValue,
|
mergedSearchValue,
|
||||||
() => {
|
() => {
|
||||||
|
@ -387,8 +387,9 @@ export default function generateSelector<
|
||||||
listRef.value.scrollTo(0);
|
listRef.value.scrollTo(0);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ flush: 'post' },
|
{ flush: 'post', immediate: true },
|
||||||
);
|
);
|
||||||
|
});
|
||||||
|
|
||||||
// ============================ Selector ============================
|
// ============================ Selector ============================
|
||||||
let displayValues = computed<DisplayLabelValueType[]>(() => {
|
let displayValues = computed<DisplayLabelValueType[]>(() => {
|
||||||
|
@ -556,13 +557,14 @@ export default function generateSelector<
|
||||||
let mergedOpen = ref(undefined);
|
let mergedOpen = ref(undefined);
|
||||||
const setInnerOpen = (val: boolean) => {
|
const setInnerOpen = (val: boolean) => {
|
||||||
innerOpen.value = val;
|
innerOpen.value = val;
|
||||||
mergedOpen.value = val;
|
mergedOpen.value = innerOpen.value;
|
||||||
};
|
};
|
||||||
watch(
|
watch(
|
||||||
computed(() => [props.defaultOpen, props.open]),
|
computed(() => [props.defaultOpen, props.open]),
|
||||||
() => {
|
() => {
|
||||||
setInnerOpen(props.open !== undefined ? props.open : props.defaultOpen);
|
setInnerOpen(props.open !== undefined ? props.open : props.defaultOpen);
|
||||||
},
|
},
|
||||||
|
{ immediate: true },
|
||||||
);
|
);
|
||||||
|
|
||||||
// Not trigger `open` in `combobox` when `notFoundContent` is empty
|
// Not trigger `open` in `combobox` when `notFoundContent` is empty
|
||||||
|
@ -573,14 +575,16 @@ export default function generateSelector<
|
||||||
computed(
|
computed(
|
||||||
() =>
|
() =>
|
||||||
props.disabled ||
|
props.disabled ||
|
||||||
(emptyListContent.value && mergedOpen.value && props.mode === 'combobox'),
|
(emptyListContent.value && innerOpen.value && props.mode === 'combobox'),
|
||||||
),
|
),
|
||||||
val => {
|
val => {
|
||||||
debugger;
|
|
||||||
if (val) {
|
if (val) {
|
||||||
mergedOpen.value = false;
|
mergedOpen.value = false;
|
||||||
|
} else {
|
||||||
|
mergedOpen.value = innerOpen.value;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{ immediate: true },
|
||||||
);
|
);
|
||||||
|
|
||||||
const triggerOpen = computed(() => (emptyListContent.value ? false : mergedOpen.value));
|
const triggerOpen = computed(() => (emptyListContent.value ? false : mergedOpen.value));
|
||||||
|
@ -590,7 +594,6 @@ export default function generateSelector<
|
||||||
|
|
||||||
if (innerOpen.value !== nextOpen && !props.disabled) {
|
if (innerOpen.value !== nextOpen && !props.disabled) {
|
||||||
setInnerOpen(nextOpen);
|
setInnerOpen(nextOpen);
|
||||||
|
|
||||||
if (props.onDropdownVisibleChange) {
|
if (props.onDropdownVisibleChange) {
|
||||||
props.onDropdownVisibleChange(nextOpen);
|
props.onDropdownVisibleChange(nextOpen);
|
||||||
}
|
}
|
||||||
|
@ -681,14 +684,19 @@ export default function generateSelector<
|
||||||
setInnerOpen(false);
|
setInnerOpen(false);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{ immediate: true },
|
||||||
);
|
);
|
||||||
|
|
||||||
// Close will clean up single mode search text
|
// Close will clean up single mode search text
|
||||||
watch(mergedOpen, () => {
|
watch(
|
||||||
if (innerOpen.value && !!props.disabled) {
|
mergedOpen,
|
||||||
setInnerOpen(false);
|
() => {
|
||||||
|
if (!mergedOpen.value && !isMultiple.value && props.mode !== 'combobox') {
|
||||||
|
triggerSearch('', false, false);
|
||||||
}
|
}
|
||||||
});
|
},
|
||||||
|
{ immediate: true },
|
||||||
|
);
|
||||||
// ============================ Keyboard ============================
|
// ============================ Keyboard ============================
|
||||||
/**
|
/**
|
||||||
* We record input value here to check if can press to clean up by backspace
|
* We record input value here to check if can press to clean up by backspace
|
||||||
|
@ -857,15 +865,21 @@ export default function generateSelector<
|
||||||
|
|
||||||
// ============================= Popup ==============================
|
// ============================= Popup ==============================
|
||||||
const containerWidth = ref(null);
|
const containerWidth = ref(null);
|
||||||
|
onMounted(() => {
|
||||||
watch(triggerOpen, () => {
|
watch(
|
||||||
|
triggerOpen,
|
||||||
|
() => {
|
||||||
if (triggerOpen.value) {
|
if (triggerOpen.value) {
|
||||||
const newWidth = Math.ceil(containerRef.value.offsetWidth);
|
const newWidth = Math.ceil(containerRef.value.offsetWidth);
|
||||||
if (containerWidth !== newWidth) {
|
if (containerWidth !== newWidth) {
|
||||||
containerWidth.value = newWidth;
|
containerWidth.value = newWidth;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true },
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
const focus = () => {
|
const focus = () => {
|
||||||
selectorRef.value.focus();
|
selectorRef.value.focus();
|
||||||
};
|
};
|
||||||
|
@ -954,10 +968,27 @@ export default function generateSelector<
|
||||||
const {
|
const {
|
||||||
prefixCls = defaultPrefixCls,
|
prefixCls = defaultPrefixCls,
|
||||||
class: className,
|
class: className,
|
||||||
children,
|
id,
|
||||||
|
|
||||||
|
open,
|
||||||
|
defaultOpen,
|
||||||
options,
|
options,
|
||||||
|
children,
|
||||||
|
|
||||||
mode,
|
mode,
|
||||||
|
value,
|
||||||
|
defaultValue,
|
||||||
|
labelInValue,
|
||||||
|
|
||||||
|
// Search related
|
||||||
|
showSearch,
|
||||||
|
inputValue,
|
||||||
|
searchValue,
|
||||||
|
filterOption,
|
||||||
|
optionFilterProp = 'value',
|
||||||
|
autoClearSearchValue = true,
|
||||||
|
onSearch,
|
||||||
|
|
||||||
// Icons
|
// Icons
|
||||||
allowClear,
|
allowClear,
|
||||||
clearIcon,
|
clearIcon,
|
||||||
|
@ -968,7 +999,10 @@ export default function generateSelector<
|
||||||
// Others
|
// Others
|
||||||
disabled,
|
disabled,
|
||||||
loading,
|
loading,
|
||||||
|
defaultActiveFirstOption,
|
||||||
notFoundContent = 'Not Found',
|
notFoundContent = 'Not Found',
|
||||||
|
optionLabelProp,
|
||||||
|
backfill,
|
||||||
getInputElement,
|
getInputElement,
|
||||||
getPopupContainer,
|
getPopupContainer,
|
||||||
|
|
||||||
|
@ -983,13 +1017,25 @@ export default function generateSelector<
|
||||||
dropdownMatchSelectWidth,
|
dropdownMatchSelectWidth,
|
||||||
dropdownRender,
|
dropdownRender,
|
||||||
dropdownAlign,
|
dropdownAlign,
|
||||||
|
showAction = [],
|
||||||
direction,
|
direction,
|
||||||
|
|
||||||
|
// Tags
|
||||||
|
tokenSeparators,
|
||||||
tagRender,
|
tagRender,
|
||||||
|
|
||||||
// Events
|
// Events
|
||||||
onPopupScroll,
|
onPopupScroll,
|
||||||
|
onDropdownVisibleChange,
|
||||||
|
onFocus,
|
||||||
|
onBlur,
|
||||||
|
onKeyup,
|
||||||
|
onKeydown,
|
||||||
|
onMousedown,
|
||||||
|
|
||||||
|
onChange,
|
||||||
|
onSelect,
|
||||||
|
onDeselect,
|
||||||
onClear,
|
onClear,
|
||||||
|
|
||||||
internalProps = {},
|
internalProps = {},
|
||||||
|
@ -999,7 +1045,7 @@ export default function generateSelector<
|
||||||
|
|
||||||
// ============================= Input ==============================
|
// ============================= Input ==============================
|
||||||
// Only works in `combobox`
|
// Only works in `combobox`
|
||||||
const customizeInputElement: VNodeChild =
|
const customizeInputElement: VNodeChild | JSX.Element =
|
||||||
(mode === 'combobox' && getInputElement && getInputElement()) || null;
|
(mode === 'combobox' && getInputElement && getInputElement()) || null;
|
||||||
|
|
||||||
const domProps = omitDOMProps ? omitDOMProps(restProps) : restProps;
|
const domProps = omitDOMProps ? omitDOMProps(restProps) : restProps;
|
||||||
|
@ -1192,7 +1238,7 @@ export default function generateSelector<
|
||||||
// Value
|
// Value
|
||||||
value: PropTypes.any,
|
value: PropTypes.any,
|
||||||
defaultValue: PropTypes.any,
|
defaultValue: PropTypes.any,
|
||||||
labelInValue: PropTypes.bool,
|
labelInValue: { type: Boolean, default: undefined },
|
||||||
|
|
||||||
// Search
|
// Search
|
||||||
inputValue: PropTypes.string,
|
inputValue: PropTypes.string,
|
||||||
|
@ -1204,13 +1250,13 @@ export default function generateSelector<
|
||||||
* It's by design.
|
* It's by design.
|
||||||
*/
|
*/
|
||||||
filterOption: PropTypes.any,
|
filterOption: PropTypes.any,
|
||||||
showSearch: PropTypes.bool,
|
showSearch: { type: Boolean, default: undefined },
|
||||||
autoClearSearchValue: PropTypes.bool,
|
autoClearSearchValue: { type: Boolean, default: undefined },
|
||||||
onSearch: PropTypes.func,
|
onSearch: PropTypes.func,
|
||||||
onClear: PropTypes.func,
|
onClear: PropTypes.func,
|
||||||
|
|
||||||
// Icons
|
// Icons
|
||||||
allowClear: PropTypes.bool,
|
allowClear: { type: Boolean, default: undefined },
|
||||||
clearIcon: PropTypes.any,
|
clearIcon: PropTypes.any,
|
||||||
showArrow: {
|
showArrow: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
|
@ -1221,14 +1267,14 @@ export default function generateSelector<
|
||||||
menuItemSelectedIcon: PropTypes.func,
|
menuItemSelectedIcon: PropTypes.func,
|
||||||
|
|
||||||
// Dropdown
|
// Dropdown
|
||||||
open: PropTypes.bool,
|
open: { type: Boolean, default: undefined },
|
||||||
defaultOpen: PropTypes.bool,
|
defaultOpen: { type: Boolean, default: undefined },
|
||||||
listHeight: PropTypes.number.def(200),
|
listHeight: PropTypes.number.def(200),
|
||||||
listItemHeight: PropTypes.number.def(20),
|
listItemHeight: PropTypes.number.def(20),
|
||||||
dropdownStyle: PropTypes.object,
|
dropdownStyle: PropTypes.object,
|
||||||
dropdownClassName: PropTypes.string,
|
dropdownClassName: PropTypes.string,
|
||||||
dropdownMatchSelectWidth: PropTypes.oneOfType([Boolean, Number]).def(true),
|
dropdownMatchSelectWidth: PropTypes.oneOfType([Boolean, Number]).def(true),
|
||||||
virtual: PropTypes.bool,
|
virtual: { type: Boolean, default: undefined },
|
||||||
dropdownRender: PropTypes.func,
|
dropdownRender: PropTypes.func,
|
||||||
dropdownAlign: PropTypes.any,
|
dropdownAlign: PropTypes.any,
|
||||||
animation: PropTypes.string,
|
animation: PropTypes.string,
|
||||||
|
@ -1237,13 +1283,13 @@ export default function generateSelector<
|
||||||
direction: PropTypes.string,
|
direction: PropTypes.string,
|
||||||
|
|
||||||
// Others
|
// Others
|
||||||
disabled: PropTypes.bool,
|
disabled: { type: Boolean, default: undefined },
|
||||||
loading: PropTypes.bool,
|
loading: { type: Boolean, default: undefined },
|
||||||
autofocus: PropTypes.bool,
|
autofocus: { type: Boolean, default: undefined },
|
||||||
defaultActiveFirstOption: PropTypes.bool,
|
defaultActiveFirstOption: { type: Boolean, default: undefined },
|
||||||
notFoundContent: PropTypes.any.def('Not Found'),
|
notFoundContent: PropTypes.any.def('Not Found'),
|
||||||
placeholder: PropTypes.any,
|
placeholder: PropTypes.any,
|
||||||
backfill: PropTypes.bool,
|
backfill: { type: Boolean, default: undefined },
|
||||||
getInputElement: PropTypes.func,
|
getInputElement: PropTypes.func,
|
||||||
optionLabelProp: PropTypes.string,
|
optionLabelProp: PropTypes.string,
|
||||||
maxTagTextLength: PropTypes.number,
|
maxTagTextLength: PropTypes.number,
|
||||||
|
|
|
@ -18,7 +18,7 @@ export type OnActiveValue = (
|
||||||
export interface OptionCoreData {
|
export interface OptionCoreData {
|
||||||
key?: Key;
|
key?: Key;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
value: Key;
|
value?: Key;
|
||||||
title?: string;
|
title?: string;
|
||||||
class?: string;
|
class?: string;
|
||||||
style?: Vue.CSSProperties;
|
style?: Vue.CSSProperties;
|
||||||
|
|
Loading…
Reference in New Issue