Skip to content

Commit

Permalink
Merge pull request #1198 from bindoon/fix-select
Browse files Browse the repository at this point in the history
  • Loading branch information
youluna authored Oct 9, 2019
2 parents b68cbf9 + 2814be4 commit a93fc2d
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 14 deletions.
3 changes: 0 additions & 3 deletions src/select/auto-complete.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,6 @@ class AutoComplete extends Base {

handleMenuSelect(keys) {
const key = keys[0];
if (this.state.value === keys[0]) {
return this.setVisible(false, 'itemClick');
}

const mapDS = this.dataStore.getMapDS();

Expand Down
14 changes: 10 additions & 4 deletions src/select/base.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ export default class Base extends React.Component {
* 自定义弹层的内容
*/
popupContent: PropTypes.node,
/**
* 添加到菜单上的属性
*/
menuProps: PropTypes.object,
/**
* 是否使用本地过滤,在数据源为远程的时候需要关闭此项
*/
Expand Down Expand Up @@ -396,12 +400,13 @@ export default class Base extends React.Component {
locale,
notFoundContent,
useVirtual,
menuProps,
} = this.props;
const { dataSource, highlightKey } = this.state;
const value = this.state.value;
let selectedKeys;

if (isNull(value) || value.length === 0) {
if (isNull(value) || value.length === 0 || this.isAutoComplete) {
selectedKeys = [];
} else if (isSingle(mode)) {
selectedKeys = [valueToSelectKey(value)];
Expand All @@ -424,7 +429,8 @@ export default class Base extends React.Component {
);
}

const menuProps = {
const customProps = {
...menuProps,
children,
role: 'listbox',
selectedKeys,
Expand Down Expand Up @@ -455,7 +461,7 @@ export default class Base extends React.Component {
ref(c);
this.menuRef = c;
}}
{...menuProps}
{...customProps}
>
{items}
</Menu>
Expand All @@ -466,7 +472,7 @@ export default class Base extends React.Component {
</VirtualList>
</div>
) : (
<Menu {...menuProps} style={menuStyle} />
<Menu {...customProps} style={menuStyle} />
);
}

Expand Down
35 changes: 29 additions & 6 deletions src/select/select.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ class Select extends Base {
/**
* 多选模式 multiple/tag
*/
handleMultipleSelect(keys, triggerType, key) {
handleMultipleSelect(keys, triggerType, key, keepSearchValue) {
const itemObj = getValueDataSource(
keys,
this.valueDataSource.mapValueDS,
Expand All @@ -432,6 +432,8 @@ class Select extends Base {
this.setVisible(false, triggerType);
}

// 因为搜索后会设置 hightLight 为第一个item,menu渲染会自动滚动到 hightLight 的元素上面。
// 所以设置 hightLight 为当前选中项避免滚动
key &&
this.state.visible &&
this.setState({
Expand All @@ -447,7 +449,11 @@ class Select extends Base {
this.updateSelectAllYet(itemObj.value);

// 清空搜索
if (!('searchValue' in this.props) && this.state.searchValue) {
if (
!('searchValue' in this.props) &&
this.state.searchValue &&
!keepSearchValue
) {
// 因为 SearchValue 被 clear 后会重新渲染 Menu,所以在 Overlay 检测 safeNode 的时候 e.target 可能会找不到导致弹窗关闭
setTimeout(() => {
this.handleSearchClear(triggerType);
Expand Down Expand Up @@ -528,6 +534,8 @@ class Select extends Base {
mode,
hasClear,
onToggleHighlightItem,
readOnly,
disabled,
} = this.props;

if (popupContent) {
Expand All @@ -548,6 +556,9 @@ class Select extends Base {
break;
case KEYCODE.ENTER:
e.preventDefault();
if (readOnly || disabled) {
break;
}
this.chooseHighlightItem(proxy, e);
break;
case KEYCODE.ESC:
Expand All @@ -559,9 +570,19 @@ class Select extends Base {
!hasSearch && e.preventDefault();
break;
case KEYCODE.BACKSPACE:
if (readOnly || disabled) {
break;
}
if ((mode === 'multiple' && showSearch) || mode === 'tag') {
// 在多选并且有搜索的情况下,删除最后一个 tag
this.handleDeleteTag(e);
const valueDS = this.valueDataSource.valueDS;
if (
valueDS &&
valueDS.length &&
!valueDS[valueDS.length - 1].disabled
) {
this.handleDeleteTag(e);
}
} else if (
mode === 'single' &&
hasClear &&
Expand All @@ -584,25 +605,27 @@ class Select extends Base {
return valueToSelectKey(v);
});

let keepSearchValue = false;

const index = keys.map(v => `${v}`).indexOf(key);

if (index > -1) {
// unselect
keys.splice(index, 1);
keepSearchValue = true; // 回车反选保留搜索值
} else {
// select
keys.push(key);
}

this.handleMultipleSelect(keys, 'enter');
this.handleMultipleSelect(keys, 'enter', null, keepSearchValue);
}

// 回车 选择高亮的 item
chooseHighlightItem(proxy, e) {
const prevVisible = this.state.visible;
const { mode } = this.props;

if (!prevVisible) {
if (!this.state.visible) {
// input tag by itself
if (mode === 'tag' && this.state.searchValue) {
this.chooseMultipleItem(this.state.searchValue);
Expand Down
2 changes: 1 addition & 1 deletion src/select/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { Children } from 'react';
* @return {boolean} is single mode
*/
export function isSingle(mode) {
return !mode || mode === 'single' || mode === 'combobox';
return !mode || mode === 'single';
}

/**
Expand Down
19 changes: 19 additions & 0 deletions test/select/index-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,25 @@ describe('Select', () => {
wrapper.find('div.next-tag .next-tag-close-btn').simulate('click');
});

it('should not delete disabled item with BACKSPACE', done => {
wrapper.setProps({
mode: 'tag',
dataSource: [{value: '10001', label: 'Lucy King'}, {value: '10003', label: 'Tom Cat', disabled: true}],
value: ['10001', '10003'],
onChange: function(value) {
assert(value.length === 1);
done();
},
});

wrapper.find('input').simulate('keydown', {
key: 'backSpace',
keyCode: 8,
});

wrapper.find('div.next-tag .next-tag-close-btn').first().simulate('click');
});

it('should support mode=tag with visible=false', done => {
wrapper.setProps({
mode: 'tag',
Expand Down

0 comments on commit a93fc2d

Please sign in to comment.