feat: update tree-select
parent
10b91894f5
commit
747d5496e7
|
@ -1,5 +1,5 @@
|
|||
module.exports = {
|
||||
dev: {
|
||||
componentName: 'upload', // dev components
|
||||
componentName: 'tree-select', // dev components
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,19 +1,21 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders ./components/tree-select/demo/basic.md correctly 1`] = `<span role="combobox" aria-haspopup="listbox" tabindex="0" class="ant-select ant-select-enabled ant-select-allow-clear" style="width: 300px;"><span class="ant-select-selection ant-select-selection--single"><span class="ant-select-selection__rendered"><span class="ant-select-selection__placeholder">Please select</span></span><span class="ant-select-arrow" style="outline: none;"><i aria-label="icon: down" class="ant-select-arrow-icon anticon anticon-down"><svg viewBox="64 64 896 896" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></i></span></span></span>`;
|
||||
exports[`renders ./components/tree-select/demo/async.md correctly 1`] = `<span role="combobox" aria-haspopup="listbox" tabindex="0" class="ant-select ant-select-enabled" style="width: 100%;"><span class="ant-select-selection ant-select-selection--single"><span class="ant-select-selection__rendered"><span class="ant-select-selection__placeholder">Please select</span></span><span class="ant-select-arrow" style="outline: none;"><i aria-label="icon: down" class="ant-select-arrow-icon anticon anticon-down"><svg viewBox="64 64 896 896" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></i></span></span></span>`;
|
||||
|
||||
exports[`renders ./components/tree-select/demo/basic.md correctly 1`] = `<span role="combobox" aria-haspopup="listbox" tabindex="0" class="ant-select ant-select-enabled ant-select-allow-clear" style="width: 100%;"><span class="ant-select-selection ant-select-selection--single"><span class="ant-select-selection__rendered"><span class="ant-select-selection__placeholder">Please select</span></span><span class="ant-select-arrow" style="outline: none;"><i aria-label="icon: down" class="ant-select-arrow-icon anticon anticon-down"><svg viewBox="64 64 896 896" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></i></span></span></span>`;
|
||||
|
||||
exports[`renders ./components/tree-select/demo/checkable.md correctly 1`] = `
|
||||
<span role="combobox" aria-haspopup="listbox" tabindex="-1" class="ant-select ant-select-enabled" style="width: 300px;"><span class="ant-select-selection ant-select-selection--multiple"><div class="ant-select-selection__rendered"><li unselectable="unselectable" role="menuitem" title="Node1" class="ant-select-selection__choice" style="user-select: none;"><span class="ant-select-selection__choice__remove"><i aria-label="icon: close" class="ant-select-remove-icon anticon anticon-close"><svg viewBox="64 64 896 896" data-icon="close" width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><path d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 0 0 203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"></path></svg></i></span><span class="ant-select-selection__choice__content">Node1</span></li>
|
||||
<span role="combobox" aria-haspopup="listbox" tabindex="-1" class="ant-select ant-select-enabled" style="width: 100%;"><span class="ant-select-selection ant-select-selection--multiple"><div class="ant-select-selection__rendered"><li unselectable="unselectable" role="menuitem" title="Node1" class="ant-select-selection__choice" style="user-select: none;"><span class="ant-select-selection__choice__remove"><i aria-label="icon: close" class="ant-select-remove-icon anticon anticon-close"><svg viewBox="64 64 896 896" data-icon="close" width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><path d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 0 0 203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"></path></svg></i></span><span class="ant-select-selection__choice__content">Node1</span></li>
|
||||
<li class="ant-select-search ant-select-search--inline"><span class="ant-select-search__field__wrap"><input type="text" aria-label="filter select" aria-autocomplete="list" aria-multiline="false" class="ant-select-search__field" style="width: 0px;"><span class="ant-select-search__field__mirror"> </span></span></li>
|
||||
</div>
|
||||
</span></span>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/tree-select/demo/multiple.md correctly 1`] = `
|
||||
<span role="combobox" aria-haspopup="listbox" tabindex="-1" class="ant-select ant-select-enabled ant-select-allow-clear" style="width: 300px;"><span class="ant-select-selection ant-select-selection--multiple"><div class="ant-select-selection__rendered"><li class="ant-select-search ant-select-search--inline"><span class="ant-select-search__field__wrap"><input type="text" aria-label="filter select" aria-autocomplete="list" aria-multiline="false" class="ant-select-search__field" style="width: 0px;"><span class="ant-select-search__field__mirror"> </span></span></li>
|
||||
<span role="combobox" aria-haspopup="listbox" tabindex="-1" class="ant-select ant-select-enabled ant-select-allow-clear" style="width: 100%;"><span class="ant-select-selection ant-select-selection--multiple"><div class="ant-select-selection__rendered"><li class="ant-select-search ant-select-search--inline"><span class="ant-select-search__field__wrap"><input type="text" aria-label="filter select" aria-autocomplete="list" aria-multiline="false" class="ant-select-search__field" style="width: 0px;"><span class="ant-select-search__field__mirror"> </span></span></li>
|
||||
</div><span class="ant-select-search__field__placeholder" style="display: block;">Please select</span></span></span>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/tree-select/demo/suffix.md correctly 1`] = `<span role="combobox" aria-haspopup="listbox" tabindex="0" class="ant-select ant-select-enabled ant-select-allow-clear" style="width: 300px;"><span class="ant-select-selection ant-select-selection--single"><span class="ant-select-selection__rendered"><span class="ant-select-selection__placeholder">Please select</span></span><span class="ant-select-arrow" style="outline: none;"><i slot="suffixIcon" aria-label="icon: smile" class="anticon anticon-smile"><svg viewBox="64 64 896 896" data-icon="smile" width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><path d="M288 421a48 48 0 1 0 96 0 48 48 0 1 0-96 0zm352 0a48 48 0 1 0 96 0 48 48 0 1 0-96 0zM512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm263 711c-34.2 34.2-74 61-118.3 79.8C611 874.2 562.3 884 512 884c-50.3 0-99-9.8-144.8-29.2A370.4 370.4 0 0 1 248.9 775c-34.2-34.2-61-74-79.8-118.3C149.8 611 140 562.3 140 512s9.8-99 29.2-144.8A370.4 370.4 0 0 1 249 248.9c34.2-34.2 74-61 118.3-79.8C413 149.8 461.7 140 512 140c50.3 0 99 9.8 144.8 29.2A370.4 370.4 0 0 1 775.1 249c34.2 34.2 61 74 79.8 118.3C874.2 413 884 461.7 884 512s-9.8 99-29.2 144.8A368.89 368.89 0 0 1 775 775zM664 533h-48.1c-4.2 0-7.8 3.2-8.1 7.4C604 589.9 562.5 629 512 629s-92.1-39.1-95.8-88.6c-.3-4.2-3.9-7.4-8.1-7.4H360a8 8 0 0 0-8 8.4c4.4 84.3 74.5 151.6 160 151.6s155.6-67.3 160-151.6a8 8 0 0 0-8-8.4z"></path></svg></i></span></span></span>`;
|
||||
exports[`renders ./components/tree-select/demo/suffix.md correctly 1`] = `<span role="combobox" aria-haspopup="listbox" tabindex="0" class="ant-select ant-select-enabled ant-select-allow-clear" style="width: 100%;"><span class="ant-select-selection ant-select-selection--single"><span class="ant-select-selection__rendered"><span class="ant-select-selection__placeholder">Please select</span></span><span class="ant-select-arrow" style="outline: none;"><i slot="suffixIcon" aria-label="icon: smile" class="anticon anticon-smile"><svg viewBox="64 64 896 896" data-icon="smile" width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><path d="M288 421a48 48 0 1 0 96 0 48 48 0 1 0-96 0zm352 0a48 48 0 1 0 96 0 48 48 0 1 0-96 0zM512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm263 711c-34.2 34.2-74 61-118.3 79.8C611 874.2 562.3 884 512 884c-50.3 0-99-9.8-144.8-29.2A370.4 370.4 0 0 1 248.9 775c-34.2-34.2-61-74-79.8-118.3C149.8 611 140 562.3 140 512s9.8-99 29.2-144.8A370.4 370.4 0 0 1 249 248.9c34.2-34.2 74-61 118.3-79.8C413 149.8 461.7 140 512 140c50.3 0 99 9.8 144.8 29.2A370.4 370.4 0 0 1 775.1 249c34.2 34.2 61 74 79.8 118.3C874.2 413 884 461.7 884 512s-9.8 99-29.2 144.8A368.89 368.89 0 0 1 775 775zM664 533h-48.1c-4.2 0-7.8 3.2-8.1 7.4C604 589.9 562.5 629 512 629s-92.1-39.1-95.8-88.6c-.3-4.2-3.9-7.4-8.1-7.4H360a8 8 0 0 0-8 8.4c4.4 84.3 74.5 151.6 160 151.6s155.6-67.3 160-151.6a8 8 0 0 0-8-8.4z"></path></svg></i></span></span></span>`;
|
||||
|
||||
exports[`renders ./components/tree-select/demo/treeData.md correctly 1`] = `<span role="combobox" aria-haspopup="listbox" tabindex="0" class="ant-select ant-select-enabled" style="width: 300px;"><span class="ant-select-selection ant-select-selection--single"><span class="ant-select-selection__rendered"><span class="ant-select-selection__placeholder">Please select</span></span><span class="ant-select-arrow" style="outline: none;"><i aria-label="icon: down" class="ant-select-arrow-icon anticon anticon-down"><svg viewBox="64 64 896 896" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></i></span></span></span>`;
|
||||
exports[`renders ./components/tree-select/demo/treeData.md correctly 1`] = `<span role="combobox" aria-haspopup="listbox" tabindex="0" class="ant-select ant-select-enabled" style="width: 100%;"><span class="ant-select-selection ant-select-selection--single"><span class="ant-select-selection__rendered"><span class="ant-select-selection__placeholder">Please select</span></span><span class="ant-select-arrow" style="outline: none;"><i aria-label="icon: down" class="ant-select-arrow-icon anticon anticon-down"><svg viewBox="64 64 896 896" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></i></span></span></span>`;
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import TreeSelect from '..';
|
||||
import focusTest from '../../../tests/shared/focusTest';
|
||||
import mountTest from '../../../tests/shared/mountTest';
|
||||
|
||||
describe('TreeSelect', () => {
|
||||
focusTest(TreeSelect);
|
||||
mountTest(TreeSelect);
|
||||
});
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
<cn>
|
||||
#### 异步加载
|
||||
异步加载树节点。
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### Asynchronous loading
|
||||
Asynchronous loading tree node.
|
||||
</us>
|
||||
|
||||
```tpl
|
||||
<template>
|
||||
<a-tree-select
|
||||
treeDataSimpleMode
|
||||
style="width: 100%"
|
||||
:dropdownStyle="{ maxHeight: '400px', overflow: 'auto' }"
|
||||
:treeData="treeData"
|
||||
placeholder="Please select"
|
||||
:loadData="onLoadData"
|
||||
v-model="value"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
value: undefined,
|
||||
treeData: [
|
||||
{ id: 1, pId: 0, value: '1', title: 'Expand to load' },
|
||||
{ id: 2, pId: 0, value: '2', title: 'Expand to load' },
|
||||
{ id: 3, pId: 0, value: '3', title: 'Tree Node', isLeaf: true },
|
||||
],
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
genTreeNode(parentId, isLeaf = false) {
|
||||
const random = Math.random()
|
||||
.toString(36)
|
||||
.substring(2, 6);
|
||||
return {
|
||||
id: random,
|
||||
pId: parentId,
|
||||
value: random,
|
||||
title: isLeaf ? 'Tree Node' : 'Expand to load',
|
||||
isLeaf,
|
||||
};
|
||||
},
|
||||
onLoadData(treeNode) {
|
||||
return new Promise(resolve => {
|
||||
const { id } = treeNode.dataRef;
|
||||
setTimeout(() => {
|
||||
this.treeData = this.treeData.concat([
|
||||
this.genTreeNode(id, false),
|
||||
this.genTreeNode(id, true),
|
||||
]);
|
||||
resolve();
|
||||
}, 300);
|
||||
});
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
value(value) {
|
||||
console.log(value);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
```
|
|
@ -12,13 +12,12 @@ The most basic usage.
|
|||
<template>
|
||||
<a-tree-select
|
||||
showSearch
|
||||
style="width: 300px"
|
||||
:value="value"
|
||||
style="width: 100%"
|
||||
v-model="value"
|
||||
:dropdownStyle="{ maxHeight: '400px', overflow: 'auto' }"
|
||||
placeholder="Please select"
|
||||
allowClear
|
||||
treeDefaultExpandAll
|
||||
@change="onChange"
|
||||
>
|
||||
<a-tree-select-node value="parent 1" title="parent 1" key="0-1">
|
||||
<a-tree-select-node value="parent 1-0" title="parent 1-0" key="0-1-1">
|
||||
|
@ -42,12 +41,6 @@ The most basic usage.
|
|||
value: undefined,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
onChange(value) {
|
||||
console.log(value);
|
||||
this.value = value;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
```
|
||||
|
|
|
@ -11,10 +11,9 @@ Multiple and checkable.
|
|||
```tpl
|
||||
<template>
|
||||
<a-tree-select
|
||||
style="width: 300px"
|
||||
style="width: 100%"
|
||||
:treeData="treeData"
|
||||
:value="value"
|
||||
@change="onChange"
|
||||
v-model="value"
|
||||
treeCheckable
|
||||
:showCheckedStrategy="SHOW_PARENT"
|
||||
searchPlaceholder="Please select"
|
||||
|
@ -70,12 +69,6 @@ Multiple and checkable.
|
|||
SHOW_PARENT,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
onChange(value) {
|
||||
console.log('onChange ', value);
|
||||
this.value = value;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
```
|
||||
|
|
|
@ -4,6 +4,7 @@ import Checkable from './checkable';
|
|||
import Multiple from './multiple';
|
||||
import TreeData from './treeData';
|
||||
import Suffix from './suffix';
|
||||
import Async from './async';
|
||||
|
||||
import CN from '../index.zh-CN.md';
|
||||
import US from '../index.en-US.md';
|
||||
|
@ -28,15 +29,32 @@ export default {
|
|||
subtitle: '树选择',
|
||||
type: 'Data Entry',
|
||||
title: 'TreeSelect',
|
||||
data() {
|
||||
return {
|
||||
show: true,
|
||||
};
|
||||
},
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<button
|
||||
onClick={() => {
|
||||
this.show = !this.show;
|
||||
}}
|
||||
>
|
||||
show
|
||||
</button>
|
||||
<md cn={md.cn} us={md.us} />
|
||||
<Basic />
|
||||
<Checkable />
|
||||
<Multiple />
|
||||
<TreeData />
|
||||
<Suffix />
|
||||
{this.show ? (
|
||||
<div>
|
||||
<Basic />
|
||||
<Checkable />
|
||||
<Multiple />
|
||||
<TreeData />
|
||||
<Suffix />
|
||||
<Async />
|
||||
</div>
|
||||
) : null}
|
||||
<api>
|
||||
<template slot="cn">
|
||||
<CN />
|
||||
|
|
|
@ -12,7 +12,7 @@ Multiple selection usage.
|
|||
<template>
|
||||
<a-tree-select
|
||||
showSearch
|
||||
style="width: 300px"
|
||||
style="width: 100%"
|
||||
:value="value"
|
||||
:dropdownStyle="{ maxHeight: '400px', overflow: 'auto' }"
|
||||
placeholder="Please select"
|
||||
|
|
|
@ -12,13 +12,12 @@ The most basic usage.
|
|||
<template>
|
||||
<a-tree-select
|
||||
showSearch
|
||||
style="width: 300px"
|
||||
:value="value"
|
||||
style="width: 100%"
|
||||
v-model="value"
|
||||
:dropdownStyle="{ maxHeight: '400px', overflow: 'auto' }"
|
||||
placeholder="Please select"
|
||||
allowClear
|
||||
treeDefaultExpandAll
|
||||
@change="onChange"
|
||||
>
|
||||
<a-icon slot="suffixIcon" type="smile" />
|
||||
<a-tree-select-node value="parent 1" title="parent 1" key="0-1">
|
||||
|
@ -42,12 +41,6 @@ The most basic usage.
|
|||
value: undefined,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
onChange(value) {
|
||||
console.log(value);
|
||||
this.value = value;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
```
|
||||
|
|
|
@ -11,7 +11,7 @@ The tree structure can be populated using `treeData` property. This is a quick a
|
|||
```tpl
|
||||
<template>
|
||||
<a-tree-select
|
||||
style="width: 300px"
|
||||
style="width: 100%"
|
||||
:dropdownStyle="{ maxHeight: '400px', overflow: 'auto' }"
|
||||
:treeData="treeData"
|
||||
placeholder="Please select"
|
||||
|
|
|
@ -56,13 +56,20 @@
|
|||
|
||||
> We recommend you to use `treeData` rather than `TreeNode`, to avoid the trouble of manual construction.
|
||||
|
||||
| Property | Description | Type | Default |
|
||||
| --- | --- | --- | --- |
|
||||
| selectable | can be selected | boolean | true |
|
||||
| disableCheckbox | Disables the checkbox of the treeNode | boolean | false |
|
||||
| disabled | Disabled or not | boolean | false |
|
||||
| isLeaf | Leaf node or not | boolean | false |
|
||||
| key | Required property, should be unique in the tree | string \| number | - |
|
||||
| title | Content showed on the treeNodes | string\|slot | '---' |
|
||||
| value | Will be treated as `treeNodeFilterProp` by default, should be unique in the tree | string | - |
|
||||
| scopedSlots | When using treeNodes, you can use this property to configure the properties that support the slot, such as `scopedSlots: { title: 'XXX'}` | object | - |
|
||||
| Property | Description | Type | Default | Version |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| selectable | can be selected | boolean | true | |
|
||||
| checkable | When Tree is checkable, set TreeNode display Checkbox or not | boolean | - | 1.5.0 |
|
||||
| disableCheckbox | Disables the checkbox of the treeNode | boolean | false | |
|
||||
| disabled | Disabled or not | boolean | false | |
|
||||
| isLeaf | Leaf node or not | boolean | false | |
|
||||
| key | Required property, should be unique in the tree | string \| number | - | |
|
||||
| title | Content showed on the treeNodes | string\|slot | '---' | |
|
||||
| value | Will be treated as `treeNodeFilterProp` by default, should be unique in the tree | string | - | |
|
||||
| scopedSlots | When using treeNodes, you can use this property to configure the properties that support the slot, such as `scopedSlots: { title: 'XXX'}` | object | - | |
|
||||
|
||||
## FAQ
|
||||
|
||||
### How to get parent node in onChange?
|
||||
|
||||
We don't provide this since performance consideration.
|
||||
|
|
|
@ -7,7 +7,6 @@ import {
|
|||
getOptionProps,
|
||||
getComponentFromProp,
|
||||
filterEmpty,
|
||||
isValidElement,
|
||||
getListeners,
|
||||
} from '../_util/props-util';
|
||||
import { ConfigConsumerProps } from '../config-provider';
|
||||
|
@ -16,7 +15,6 @@ import Base from '../base';
|
|||
export { TreeData, TreeSelectProps } from './interface';
|
||||
import Icon from '../icon';
|
||||
import omit from 'omit.js';
|
||||
import { cloneElement } from '../_util/vnode';
|
||||
|
||||
const TreeSelect = {
|
||||
TreeNode: { ...TreeNode, name: 'ATreeSelectNode' },
|
||||
|
@ -39,6 +37,7 @@ const TreeSelect = {
|
|||
created() {
|
||||
warning(
|
||||
this.multiple !== false || !this.treeCheckable,
|
||||
'TreeSelect',
|
||||
'`multiple` will alway be `true` when `treeCheckable` is true',
|
||||
);
|
||||
},
|
||||
|
@ -102,6 +101,8 @@ const TreeSelect = {
|
|||
|
||||
const renderEmpty = this.configProvider.renderEmpty;
|
||||
const notFoundContent = getComponentFromProp(this, 'notFoundContent');
|
||||
const removeIcon = getComponentFromProp(this, 'removeIcon');
|
||||
const clearIcon = getComponentFromProp(this, 'clearIcon');
|
||||
const { getPopupContainer: getContextPopupContainer } = this.configProvider;
|
||||
const rest = omit(restProps, [
|
||||
'inputIcon',
|
||||
|
@ -121,27 +122,33 @@ const TreeSelect = {
|
|||
[`${prefixCls}-sm`]: size === 'small',
|
||||
};
|
||||
|
||||
// showSearch: single - false, multiple - true
|
||||
let { showSearch } = restProps;
|
||||
if (!('showSearch' in restProps)) {
|
||||
showSearch = !!(restProps.multiple || restProps.treeCheckable);
|
||||
}
|
||||
|
||||
let checkable = getComponentFromProp(this, 'treeCheckable');
|
||||
if (checkable) {
|
||||
checkable = <span class={`${prefixCls}-tree-checkbox-inner`} />;
|
||||
}
|
||||
|
||||
const inputIcon = (suffixIcon &&
|
||||
(isValidElement(suffixIcon) ? cloneElement(suffixIcon) : suffixIcon)) || (
|
||||
<Icon type="down" class={`${prefixCls}-arrow-icon`} />
|
||||
const inputIcon = suffixIcon || <Icon type="down" class={`${prefixCls}-arrow-icon`} />;
|
||||
|
||||
const finalRemoveIcon = removeIcon || <Icon type="close" class={`${prefixCls}-remove-icon`} />;
|
||||
|
||||
const finalClearIcon = clearIcon || (
|
||||
<Icon type="close-circle" class={`${prefixCls}-clear-icon`} theme="filled" />
|
||||
);
|
||||
|
||||
const removeIcon = <Icon type="close" class={`${prefixCls}-remove-icon`} />;
|
||||
|
||||
const clearIcon = <Icon type="close-circle" class={`${prefixCls}-clear-icon`} theme="filled" />;
|
||||
const VcTreeSelectProps = {
|
||||
props: Object.assign(
|
||||
{
|
||||
switcherIcon: nodeProps => this.renderSwitcherIcon(prefixCls, nodeProps),
|
||||
inputIcon,
|
||||
removeIcon,
|
||||
clearIcon,
|
||||
removeIcon: finalRemoveIcon,
|
||||
clearIcon: finalClearIcon,
|
||||
...rest,
|
||||
showSearch,
|
||||
getPopupContainer: getPopupContainer || getContextPopupContainer,
|
||||
dropdownClassName: classNames(dropdownClassName, `${prefixCls}-tree-dropdown`),
|
||||
prefixCls,
|
||||
|
|
|
@ -56,13 +56,14 @@
|
|||
|
||||
> 建议使用 treeData 来代替 TreeNode,免去手工构造麻烦
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
| --- | --- | --- | --- |
|
||||
| selectable | 是否可选 | boolean | true |
|
||||
| disableCheckbox | 禁掉 checkbox | boolean | false |
|
||||
| disabled | 是否禁用 | boolean | false |
|
||||
| isLeaf | 是否是叶子节点 | boolean | false |
|
||||
| key | 此项必须设置(其值在整个树范围内唯一) | string \| number | - |
|
||||
| title | 树节点显示的内容 | string\|slot | '---' |
|
||||
| value | 默认根据此属性值进行筛选(其值在整个树范围内唯一) | string | - |
|
||||
| scopedSlots | 使用 treeData 时,可以通过该属性配置支持 slot 的属性,如 `scopedSlots: { title: 'XXX'}` | object | - |
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| selectable | 是否可选 | boolean | true | |
|
||||
| checkable | 当树为 checkable 时,设置独立节点是否展示 Checkbox | boolean | - | 1.5.0 |
|
||||
| disableCheckbox | 禁掉 checkbox | boolean | false | |
|
||||
| disabled | 是否禁用 | boolean | false | |
|
||||
| isLeaf | 是否是叶子节点 | boolean | false | |
|
||||
| key | 此项必须设置(其值在整个树范围内唯一) | string \| number | - | |
|
||||
| title | 树节点显示的内容 | string\|slot | '---' | |
|
||||
| value | 默认根据此属性值进行筛选(其值在整个树范围内唯一) | string | - | |
|
||||
| scopedSlots | 使用 treeData 时,可以通过该属性配置支持 slot 的属性,如 `scopedSlots: { title: 'XXX'}` | object | - | |
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// export this package's api
|
||||
// base 2.5.4
|
||||
// base 2.9.3
|
||||
import Vue from 'vue';
|
||||
import TreeSelect from './src';
|
||||
import ref from 'vue-ref';
|
||||
|
|
|
@ -2,6 +2,7 @@ import warning from 'warning';
|
|||
import PropTypes from '../../../_util/vue-types';
|
||||
import { Tree } from '../../../vc-tree';
|
||||
import BaseMixin from '../../../_util/BaseMixin';
|
||||
import { createRef } from '../util';
|
||||
|
||||
// export const popupContextTypes = {
|
||||
// onPopupKeyDown: PropTypes.func.isRequired,
|
||||
|
@ -110,6 +111,7 @@ const BasePopup = {
|
|||
},
|
||||
},
|
||||
data() {
|
||||
this.treeRef = createRef();
|
||||
warning(this.$props.__propsSymbol__, 'must pass __propsSymbol__');
|
||||
const { treeDefaultExpandAll, treeDefaultExpandedKeys, keyEntities } = this.$props;
|
||||
|
||||
|
@ -150,6 +152,10 @@ const BasePopup = {
|
|||
this.setState({ _loadedKeys: loadedKeys });
|
||||
},
|
||||
|
||||
getTree() {
|
||||
return this.treeRef.current;
|
||||
},
|
||||
|
||||
/**
|
||||
* Not pass `loadData` when searching. To avoid loop ajax call makes browser crash.
|
||||
*/
|
||||
|
@ -231,7 +237,7 @@ const BasePopup = {
|
|||
} else {
|
||||
$notFound = this.renderNotFound();
|
||||
}
|
||||
} else if (!treeNodes.length) {
|
||||
} else if (!treeNodes || !treeNodes.length) {
|
||||
$notFound = this.renderNotFound();
|
||||
} else {
|
||||
$treeNodes = treeNodes;
|
||||
|
@ -265,6 +271,12 @@ const BasePopup = {
|
|||
expand: this.onTreeExpand,
|
||||
load: this.onLoad,
|
||||
},
|
||||
directives: [
|
||||
{
|
||||
name: 'ant-ref',
|
||||
value: this.treeRef,
|
||||
},
|
||||
],
|
||||
};
|
||||
$tree = <Tree {...treeAllProps} />;
|
||||
}
|
||||
|
|
|
@ -17,12 +17,16 @@ const SinglePopup = {
|
|||
},
|
||||
created() {
|
||||
this.inputRef = createRef();
|
||||
this.searchRef = createRef();
|
||||
this.popupRef = createRef();
|
||||
},
|
||||
methods: {
|
||||
onPlaceholderClick() {
|
||||
this.inputRef.current.focus();
|
||||
},
|
||||
|
||||
getTree() {
|
||||
return this.popupRef.current && this.popupRef.current.getTree();
|
||||
},
|
||||
_renderPlaceholder() {
|
||||
const { searchPlaceholder, searchValue, prefixCls } = this.$props;
|
||||
|
||||
|
@ -51,7 +55,17 @@ const SinglePopup = {
|
|||
}
|
||||
|
||||
return (
|
||||
<span class={`${dropdownPrefixCls}-search`}>
|
||||
<span
|
||||
class={`${dropdownPrefixCls}-search`}
|
||||
{...{
|
||||
directives: [
|
||||
{
|
||||
name: 'ant-ref',
|
||||
value: this.searchRef,
|
||||
},
|
||||
],
|
||||
}}
|
||||
>
|
||||
<SearchInput
|
||||
{...{
|
||||
props: { ...this.$props, renderPlaceholder: this._renderPlaceholder },
|
||||
|
@ -74,6 +88,12 @@ const SinglePopup = {
|
|||
{...{
|
||||
props: { ...this.$props, renderSearch: this._renderSearch, __propsSymbol__: Symbol() },
|
||||
on: getListeners(this),
|
||||
directives: [
|
||||
{
|
||||
name: 'ant-ref',
|
||||
value: this.popupRef,
|
||||
},
|
||||
],
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
import shallowEqual from 'shallowequal';
|
||||
import raf from 'raf';
|
||||
import scrollIntoView from 'dom-scroll-into-view';
|
||||
import warning from 'warning';
|
||||
import PropTypes from '../../_util/vue-types';
|
||||
import KeyCode from '../../_util/KeyCode';
|
||||
|
@ -48,6 +49,7 @@ import {
|
|||
isLabelInValue,
|
||||
getFilterTree,
|
||||
cleanEntity,
|
||||
findPopupContainer,
|
||||
} from './util';
|
||||
import SelectNode from './SelectNode';
|
||||
import {
|
||||
|
@ -222,6 +224,37 @@ const Select = {
|
|||
this.forcePopupAlign();
|
||||
});
|
||||
},
|
||||
'$data._open': function() {
|
||||
this.$nextTick(() => {
|
||||
const { prefixCls } = this.$props;
|
||||
const { _selectorValueList: selectorValueList, _valueEntities: valueEntities } = this.$data;
|
||||
const isMultiple = this.isMultiple();
|
||||
|
||||
// Scroll to value position, only need sync on single mode
|
||||
if (!isMultiple && selectorValueList.length && this.popup) {
|
||||
const { value } = selectorValueList[0];
|
||||
const { domTreeNodes } = this.popup.getTree();
|
||||
const { key } = valueEntities[value] || {};
|
||||
const treeNode = domTreeNodes[key];
|
||||
|
||||
if (treeNode) {
|
||||
const domNode = treeNode.$el;
|
||||
raf(() => {
|
||||
const popupNode = this.popup.$el;
|
||||
const triggerContainer = findPopupContainer(popupNode, `${prefixCls}-dropdown`);
|
||||
const searchNode = this.popup.searchRef.current;
|
||||
|
||||
if (domNode && triggerContainer && searchNode) {
|
||||
scrollIntoView(domNode, triggerContainer, {
|
||||
onlyScrollIfNeeded: true,
|
||||
offsetTop: searchNode.offsetHeight,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
|
@ -342,9 +375,11 @@ const Select = {
|
|||
}
|
||||
|
||||
// Get key by value
|
||||
const valueLabels = {};
|
||||
latestValueList.forEach(wrapperValue => {
|
||||
const { value } = wrapperValue;
|
||||
const { value, label } = wrapperValue;
|
||||
const entity = (newState._valueEntities || prevState._valueEntities)[value];
|
||||
valueLabels[value] = label;
|
||||
|
||||
if (entity) {
|
||||
keyList.push(entity.key);
|
||||
|
@ -366,9 +401,19 @@ const Select = {
|
|||
);
|
||||
|
||||
// Format value list again for internal usage
|
||||
newState._valueList = checkedKeys.map(key => ({
|
||||
value: (newState._keyEntities || prevState._keyEntities).get(key).value,
|
||||
}));
|
||||
newState._valueList = checkedKeys.map(key => {
|
||||
const val = (newState._keyEntities || prevState._keyEntities).get(key).value;
|
||||
|
||||
const wrappedValue = {
|
||||
value: val,
|
||||
};
|
||||
|
||||
if (valueLabels[val] !== undefined) {
|
||||
wrappedValue.label = valueLabels[val];
|
||||
}
|
||||
|
||||
return wrappedValue;
|
||||
});
|
||||
} else {
|
||||
newState._valueList = filteredValueList;
|
||||
}
|
||||
|
@ -422,6 +467,7 @@ const Select = {
|
|||
searchValue,
|
||||
filterTreeNodeFn,
|
||||
newState._valueEntities || prevState._valueEntities,
|
||||
SelectNode,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -827,6 +873,7 @@ const Select = {
|
|||
value,
|
||||
filterTreeNodeFn,
|
||||
valueEntities,
|
||||
SelectNode,
|
||||
),
|
||||
});
|
||||
}
|
||||
|
@ -844,7 +891,13 @@ const Select = {
|
|||
},
|
||||
|
||||
onChoiceAnimationLeave() {
|
||||
this.forcePopupAlign();
|
||||
raf(() => {
|
||||
this.forcePopupAlign();
|
||||
});
|
||||
},
|
||||
|
||||
setPopupRef(popup) {
|
||||
this.popup = popup;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1051,6 +1104,12 @@ const Select = {
|
|||
on: {
|
||||
treeExpanded: this.delayForcePopupAlign,
|
||||
},
|
||||
directives: [
|
||||
{
|
||||
name: 'ant-ref',
|
||||
value: this.setPopupRef,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const Popup = isMultiple ? MultiplePopup : SinglePopup;
|
||||
|
|
|
@ -5,12 +5,25 @@ import {
|
|||
convertTreeToEntities as vcConvertTreeToEntities,
|
||||
conductCheck as rcConductCheck,
|
||||
} from '../../vc-tree/src/util';
|
||||
import SelectNode from './SelectNode';
|
||||
import { hasClass } from '../../vc-util/Dom/class';
|
||||
import { SHOW_CHILD, SHOW_PARENT } from './strategies';
|
||||
import { getSlots, getPropsData, isEmptyElement } from '../../_util/props-util';
|
||||
|
||||
let warnDeprecatedLabel = false;
|
||||
|
||||
// =================== DOM =====================
|
||||
export function findPopupContainer(node, prefixClass) {
|
||||
let current = node;
|
||||
while (current) {
|
||||
if (hasClass(current, prefixClass)) {
|
||||
return current;
|
||||
}
|
||||
current = current.parentNode;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// =================== MISC ====================
|
||||
export function toTitle(title) {
|
||||
if (typeof title === 'string') {
|
||||
|
@ -190,7 +203,7 @@ export function cleanEntity({ node, pos, children }) {
|
|||
* we have to convert `treeNodes > data > treeNodes` to keep the key.
|
||||
* Such performance hungry!
|
||||
*/
|
||||
export function getFilterTree(h, treeNodes, searchValue, filterFunc, valueEntities) {
|
||||
export function getFilterTree(h, treeNodes, searchValue, filterFunc, valueEntities, Component) {
|
||||
if (!searchValue) {
|
||||
return null;
|
||||
}
|
||||
|
@ -208,9 +221,9 @@ export function getFilterTree(h, treeNodes, searchValue, filterFunc, valueEntiti
|
|||
.filter(n => n);
|
||||
if (children.length || match) {
|
||||
return (
|
||||
<SelectNode {...node.data} key={valueEntities[getPropsData(node).value].key}>
|
||||
<Component {...node.data} key={valueEntities[getPropsData(node).value].key}>
|
||||
{children}
|
||||
</SelectNode>
|
||||
</Component>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// based on rc-tree 1.14.10
|
||||
// based on rc-tree 2.1.3
|
||||
'use strict';
|
||||
|
||||
module.exports = require('./src/');
|
||||
|
|
|
@ -108,8 +108,9 @@ const Tree = {
|
|||
|
||||
data() {
|
||||
warning(this.$props.__propsSymbol__, 'must pass __propsSymbol__');
|
||||
warning(this.$props.children, 'please children prop replace slots.default');
|
||||
warning(this.$props.children, 'please use children prop replace slots.default');
|
||||
this.needSyncKeys = {};
|
||||
this.domTreeNodes = {};
|
||||
const state = {
|
||||
_posEntities: new Map(),
|
||||
_keyEntities: new Map(),
|
||||
|
@ -180,7 +181,6 @@ const Tree = {
|
|||
|
||||
// Calculate the entities data for quick match
|
||||
const entitiesMap = convertTreeToEntities(treeNode);
|
||||
newState._posEntities = entitiesMap.posEntities;
|
||||
newState._keyEntities = entitiesMap.keyEntities;
|
||||
}
|
||||
|
||||
|
@ -231,8 +231,7 @@ const Tree = {
|
|||
|
||||
if (!props.checkStrictly) {
|
||||
const conductKeys = conductCheck(checkedKeys, true, keyEntities);
|
||||
checkedKeys = conductKeys.checkedKeys;
|
||||
halfCheckedKeys = conductKeys.halfCheckedKeys;
|
||||
({ checkedKeys, halfCheckedKeys } = conductKeys);
|
||||
}
|
||||
|
||||
newState._checkedKeys = checkedKeys;
|
||||
|
@ -366,6 +365,7 @@ const Tree = {
|
|||
dragNode: this.dragNode,
|
||||
dragNodesKeys: _dragNodesKeys.slice(),
|
||||
dropPosition: _dropPosition + Number(posArr[posArr.length - 1]),
|
||||
dropToGap: false,
|
||||
};
|
||||
|
||||
if (_dropPosition !== 0) {
|
||||
|
@ -415,7 +415,7 @@ const Tree = {
|
|||
selected: targetSelected,
|
||||
node: treeNode,
|
||||
selectedNodes,
|
||||
nativeEvent: e,
|
||||
nativeEvent: e.nativeEvent,
|
||||
};
|
||||
this.__emit('update:selectedKeys', selectedKeys);
|
||||
this.__emit('select', selectedKeys, eventObj);
|
||||
|
@ -499,16 +499,16 @@ const Tree = {
|
|||
// Process load data
|
||||
const promise = loadData(treeNode);
|
||||
promise.then(() => {
|
||||
const newLoadedKeys = arrAdd(this.$data._loadedKeys, eventKey);
|
||||
const newLoadingKeys = arrDel(this.$data._loadingKeys, eventKey);
|
||||
const { _loadedKeys: currentLoadedKeys, _loadingKeys: currentLoadingKeys } = this.$data;
|
||||
const newLoadedKeys = arrAdd(currentLoadedKeys, eventKey);
|
||||
const newLoadingKeys = arrDel(currentLoadingKeys, eventKey);
|
||||
|
||||
// onLoad should trigger before internal setState to avoid `loadData` trigger twice.
|
||||
// https://github.com/ant-design/ant-design/issues/12464
|
||||
const eventObj = {
|
||||
this.__emit('load', newLoadedKeys, {
|
||||
event: 'load',
|
||||
node: treeNode,
|
||||
};
|
||||
this.__emit('load', newLoadedKeys, eventObj);
|
||||
});
|
||||
this.setUncontrolledState({
|
||||
_loadedKeys: newLoadedKeys,
|
||||
});
|
||||
|
@ -598,6 +598,14 @@ const Tree = {
|
|||
}
|
||||
},
|
||||
|
||||
registerTreeNode(key, node) {
|
||||
if (node) {
|
||||
this.domTreeNodes[key] = node;
|
||||
} else {
|
||||
delete this.domTreeNodes[key];
|
||||
}
|
||||
},
|
||||
|
||||
isKeyChecked(key) {
|
||||
const { _checkedKeys: checkedKeys = [] } = this.$data;
|
||||
return checkedKeys.indexOf(key) !== -1;
|
||||
|
@ -652,18 +660,15 @@ const Tree = {
|
|||
render() {
|
||||
const { _treeNode: treeNode } = this.$data;
|
||||
const { prefixCls, focusable, showLine, tabIndex = 0 } = this.$props;
|
||||
const domProps = {};
|
||||
|
||||
return (
|
||||
<ul
|
||||
{...domProps}
|
||||
class={classNames(prefixCls, {
|
||||
[`${prefixCls}-show-line`]: showLine,
|
||||
})}
|
||||
role="tree"
|
||||
unselectable="on"
|
||||
tabIndex={focusable ? tabIndex : null}
|
||||
onKeydown={focusable ? this.onKeydown : () => {}}
|
||||
>
|
||||
{mapChildren(treeNode, (node, index) => this.renderTreeNode(node, index))}
|
||||
</ul>
|
||||
|
|
|
@ -39,6 +39,7 @@ const TreeNode = {
|
|||
|
||||
// By user
|
||||
isLeaf: PropTypes.bool,
|
||||
checkable: PropTypes.bool,
|
||||
selectable: PropTypes.bool,
|
||||
disabled: PropTypes.bool,
|
||||
disableCheckbox: PropTypes.bool,
|
||||
|
@ -69,11 +70,23 @@ const TreeNode = {
|
|||
|
||||
// Isomorphic needn't load data in server side
|
||||
mounted() {
|
||||
const {
|
||||
eventKey,
|
||||
vcTree: { registerTreeNode },
|
||||
} = this;
|
||||
this.syncLoadData(this.$props);
|
||||
registerTreeNode && registerTreeNode(eventKey, this);
|
||||
},
|
||||
updated() {
|
||||
this.syncLoadData(this.$props);
|
||||
},
|
||||
beforeDestroy() {
|
||||
const {
|
||||
eventKey,
|
||||
vcTree: { registerTreeNode },
|
||||
} = this;
|
||||
registerTreeNode && registerTreeNode(eventKey, null);
|
||||
},
|
||||
|
||||
methods: {
|
||||
onSelectorClick(e) {
|
||||
|
@ -111,10 +124,10 @@ const TreeNode = {
|
|||
|
||||
const { disableCheckbox, checked } = this;
|
||||
const {
|
||||
vcTree: { checkable, onNodeCheck },
|
||||
vcTree: { onNodeCheck },
|
||||
} = this;
|
||||
|
||||
if (!checkable || disableCheckbox) return;
|
||||
if (!this.isCheckable() || disableCheckbox) return;
|
||||
|
||||
e.preventDefault();
|
||||
const targetChecked = !checked;
|
||||
|
@ -275,18 +288,15 @@ const TreeNode = {
|
|||
return !!(treeDisabled || disabled);
|
||||
},
|
||||
|
||||
isSelectable() {
|
||||
const { selectable } = this;
|
||||
isCheckable() {
|
||||
const { checkable } = this.$props;
|
||||
const {
|
||||
vcTree: { selectable: treeSelectable },
|
||||
vcTree: { checkable: treeCheckable },
|
||||
} = this;
|
||||
|
||||
// Ignore when selectable is undefined or null
|
||||
if (typeof selectable === 'boolean') {
|
||||
return selectable;
|
||||
}
|
||||
|
||||
return treeSelectable;
|
||||
// Return false if tree or treeNode is not checkable
|
||||
if (!treeCheckable || checkable === false) return false;
|
||||
return treeCheckable;
|
||||
},
|
||||
|
||||
// Load data to avoid default expanded tree without data
|
||||
|
@ -307,6 +317,20 @@ const TreeNode = {
|
|||
}
|
||||
},
|
||||
|
||||
isSelectable() {
|
||||
const { selectable } = this;
|
||||
const {
|
||||
vcTree: { selectable: treeSelectable },
|
||||
} = this;
|
||||
|
||||
// Ignore when selectable is undefined or null
|
||||
if (typeof selectable === 'boolean') {
|
||||
return selectable;
|
||||
}
|
||||
|
||||
return treeSelectable;
|
||||
},
|
||||
|
||||
// Switcher
|
||||
renderSwitcher() {
|
||||
const { expanded } = this;
|
||||
|
@ -323,7 +347,7 @@ const TreeNode = {
|
|||
class={classNames(`${prefixCls}-switcher`, `${prefixCls}-switcher-noop`)}
|
||||
>
|
||||
{typeof switcherIcon === 'function'
|
||||
? cloneElement(switcherIcon({ ...this.$props, isLeaf: true }))
|
||||
? switcherIcon({ ...this.$props, isLeaf: true })
|
||||
: switcherIcon}
|
||||
</span>
|
||||
);
|
||||
|
@ -336,7 +360,7 @@ const TreeNode = {
|
|||
return (
|
||||
<span key="switcher" onClick={this.onExpand} class={switcherCls}>
|
||||
{typeof switcherIcon === 'function'
|
||||
? cloneElement(switcherIcon({ ...this.$props, isLeaf: false }))
|
||||
? switcherIcon({ ...this.$props, isLeaf: false })
|
||||
: switcherIcon}
|
||||
</span>
|
||||
);
|
||||
|
@ -346,9 +370,10 @@ const TreeNode = {
|
|||
renderCheckbox() {
|
||||
const { checked, halfChecked, disableCheckbox } = this;
|
||||
const {
|
||||
vcTree: { prefixCls, checkable },
|
||||
vcTree: { prefixCls },
|
||||
} = this;
|
||||
const disabled = this.isDisabled();
|
||||
const checkable = this.isCheckable();
|
||||
|
||||
if (!checkable) return null;
|
||||
|
||||
|
|
|
@ -49,8 +49,8 @@ export function getNodeChildren(children = []) {
|
|||
}
|
||||
|
||||
export function isCheckDisabled(node) {
|
||||
const { disabled, disableCheckbox } = getOptionProps(node) || {};
|
||||
return !!(disabled || disableCheckbox);
|
||||
const { disabled, disableCheckbox, checkable } = getOptionProps(node) || {};
|
||||
return !!(disabled || disableCheckbox) || checkable === false;
|
||||
}
|
||||
|
||||
export function traverseTreeNodes(treeNodes, callback) {
|
||||
|
@ -116,7 +116,8 @@ export function calcDropPosition(event, treeNode) {
|
|||
|
||||
if (clientY <= top + des) {
|
||||
return -1;
|
||||
} else if (clientY >= bottom - des) {
|
||||
}
|
||||
if (clientY >= bottom - des) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -162,13 +163,13 @@ const internalProcessProps = (props = {}) => {
|
|||
key: props.key,
|
||||
};
|
||||
};
|
||||
export function convertDataToTree(h, treeData, processer) {
|
||||
export function convertDataToTree(h, treeData, processor) {
|
||||
if (!treeData) return [];
|
||||
|
||||
const { processProps = internalProcessProps } = processer || {};
|
||||
const { processProps = internalProcessProps } = processor || {};
|
||||
const list = Array.isArray(treeData) ? treeData : [treeData];
|
||||
return list.map(({ children, ...props }) => {
|
||||
const childrenNodes = convertDataToTree(h, children, processer);
|
||||
const childrenNodes = convertDataToTree(h, children, processor);
|
||||
return <TreeNode {...processProps(props)}>{childrenNodes}</TreeNode>;
|
||||
});
|
||||
}
|
||||
|
@ -398,8 +399,8 @@ export function conductExpandParent(keyList, keyEntities) {
|
|||
expandedKeys.set(key, true);
|
||||
|
||||
const { parent, node } = entity;
|
||||
|
||||
if (isCheckDisabled(node)) return;
|
||||
const props = getOptionProps(node);
|
||||
if (props && props.disabled) return;
|
||||
|
||||
if (parent) {
|
||||
conductUp(parent.key);
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
/* @flow */
|
||||
|
||||
/**
|
||||
* Add class with compatibility for SVG since classList is not supported on
|
||||
* SVG elements in IE
|
||||
*/
|
||||
export function addClass(el, cls) {
|
||||
/* istanbul ignore if */
|
||||
if (!cls || !(cls = cls.trim())) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* istanbul ignore else */
|
||||
if (el.classList) {
|
||||
if (cls.indexOf(' ') > -1) {
|
||||
cls.split(/\s+/).forEach(c => el.classList.add(c));
|
||||
} else {
|
||||
el.classList.add(cls);
|
||||
}
|
||||
} else {
|
||||
const cur = ` ${el.getAttribute('class') || ''} `;
|
||||
if (cur.indexOf(' ' + cls + ' ') < 0) {
|
||||
el.setAttribute('class', (cur + cls).trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove class with compatibility for SVG since classList is not supported on
|
||||
* SVG elements in IE
|
||||
*/
|
||||
export function removeClass(el, cls) {
|
||||
/* istanbul ignore if */
|
||||
if (!cls || !(cls = cls.trim())) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* istanbul ignore else */
|
||||
if (el.classList) {
|
||||
if (cls.indexOf(' ') > -1) {
|
||||
cls.split(/\s+/).forEach(c => el.classList.remove(c));
|
||||
} else {
|
||||
el.classList.remove(cls);
|
||||
}
|
||||
if (!el.classList.length) {
|
||||
el.removeAttribute('class');
|
||||
}
|
||||
} else {
|
||||
let cur = ` ${el.getAttribute('class') || ''} `;
|
||||
const tar = ' ' + cls + ' ';
|
||||
while (cur.indexOf(tar) >= 0) {
|
||||
cur = cur.replace(tar, ' ');
|
||||
}
|
||||
cur = cur.trim();
|
||||
if (cur) {
|
||||
el.setAttribute('class', cur);
|
||||
} else {
|
||||
el.removeAttribute('class');
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
export function hasClass(node, className) {
|
||||
if (node.classList) {
|
||||
return node.classList.contains(className);
|
||||
}
|
||||
const originClass = node.className;
|
||||
return ` ${originClass} `.indexOf(` ${className} `) > -1;
|
||||
}
|
||||
|
||||
export function addClass(node, className) {
|
||||
if (node.classList) {
|
||||
node.classList.add(className);
|
||||
} else {
|
||||
if (!hasClass(node, className)) {
|
||||
node.className = `${node.className} ${className}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function removeClass(node, className) {
|
||||
if (node.classList) {
|
||||
node.classList.remove(className);
|
||||
} else {
|
||||
if (hasClass(node, className)) {
|
||||
const originClass = node.className;
|
||||
node.className = ` ${originClass} `.replace(` ${className} `, ' ');
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,7 +3,7 @@ export default function mountTest(Component) {
|
|||
describe(`mount and unmount`, () => {
|
||||
// https://github.com/ant-design/ant-design/pull/18441
|
||||
it(`component could be updated and unmounted without errors`, () => {
|
||||
const wrapper = mount(Component);
|
||||
const wrapper = mount(Component, { sync: false });
|
||||
expect(() => {
|
||||
wrapper.vm.$forceUpdate();
|
||||
wrapper.destroy();
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Project: https://github.com/vueComponent/ant-design-vue
|
||||
// Definitions by: akki-jat <https://github.com/akki-jat>
|
||||
// Definitions: https://github.com/vueComponent/ant-design-vue/types
|
||||
// Project: https://github.com/vueComponent/ant-design-vue Definitions by:
|
||||
// akki-jat <https://github.com/akki-jat> Definitions:
|
||||
// https://github.com/vueComponent/ant-design-vue/types
|
||||
|
||||
import { AntdComponent } from './component';
|
||||
import { TreeNode } from './tree-node';
|
||||
|
@ -15,6 +15,8 @@ export interface TreeData {
|
|||
selectable?: boolean;
|
||||
}
|
||||
|
||||
export type TreeNodeValue = string | number | string[] | number[];
|
||||
|
||||
export declare class TreeSelect extends AntdComponent {
|
||||
static TreeNode: typeof TreeNode;
|
||||
|
||||
|
@ -29,11 +31,7 @@ export declare class TreeSelect extends AntdComponent {
|
|||
*/
|
||||
allowClear: boolean;
|
||||
|
||||
/**
|
||||
* To set the initial selected treeNode(s).
|
||||
* @type string | string[]
|
||||
*/
|
||||
defaultValue: string | string[];
|
||||
defaultValue: TreeNodeValue;
|
||||
|
||||
/**
|
||||
* Disabled or not
|
||||
|
@ -171,7 +169,13 @@ export declare class TreeSelect extends AntdComponent {
|
|||
* @default false
|
||||
* @type boolean | object[]
|
||||
*/
|
||||
treeDataSimpleMode: boolean | Array<{ id: string; pId: string; rootPId: any }>;
|
||||
treeDataSimpleMode:
|
||||
| boolean
|
||||
| Array<{
|
||||
id: string;
|
||||
pId: string;
|
||||
rootPId: any;
|
||||
}>;
|
||||
|
||||
/**
|
||||
* Whether to expand all treeNodes by default
|
||||
|
@ -206,11 +210,7 @@ export declare class TreeSelect extends AntdComponent {
|
|||
*/
|
||||
treeNodeLabelProp: string;
|
||||
|
||||
/**
|
||||
* To set the current selected treeNode(s).
|
||||
* @type string | string[]
|
||||
*/
|
||||
value: string | string[];
|
||||
value: TreeNodeValue;
|
||||
|
||||
/**
|
||||
* The custom suffix icon
|
||||
|
@ -218,6 +218,10 @@ export declare class TreeSelect extends AntdComponent {
|
|||
*/
|
||||
suffixIcon: any;
|
||||
|
||||
removeIcon?: any;
|
||||
|
||||
clearIcon?: any;
|
||||
|
||||
/**
|
||||
* remove focus
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue