diff --git a/CHANGELOG.en-US.md b/CHANGELOG.en-US.md
index 6eae4c2578c..24dc953e6ba 100644
--- a/CHANGELOG.en-US.md
+++ b/CHANGELOG.en-US.md
@@ -112,6 +112,7 @@
### Feats
- `n-loading-bar` add `loading-bar-style` props, closes [#457](https://github.com/TuSimple/naive-ui/issues/457).
+- `n-tree-select` add `check-strategy` prop.
- `n-button` add `text-color` prop.
- `n-form` export `FormValidationError` type.
- `n-popconfirm` support not show action components, closes [#770](https://github.com/TuSimple/naive-ui/issues/770).
diff --git a/CHANGELOG.zh-CN.md b/CHANGELOG.zh-CN.md
index e789b99cfd1..1904a824c75 100644
--- a/CHANGELOG.zh-CN.md
+++ b/CHANGELOG.zh-CN.md
@@ -112,6 +112,7 @@
### Feats
- `n-loading-bar` 新增 `loading-bar-style` 属性,关闭 [#457](https://github.com/TuSimple/naive-ui/issues/457)
+- `n-tree-select` 增加 `check-strategy` 属性.
- `n-button` 新增 `text-color` 属性
- `n-form` 导出 `FormValidationError` 类型
- `n-popconfirm` 支持不显示操作组件,关闭 [#770](https://github.com/TuSimple/naive-ui/issues/770)
diff --git a/src/tree-select/demos/enUS/check-strategy.demo.md b/src/tree-select/demos/enUS/check-strategy.demo.md
new file mode 100644
index 00000000000..8cf1b18b56a
--- /dev/null
+++ b/src/tree-select/demos/enUS/check-strategy.demo.md
@@ -0,0 +1,121 @@
+# Set Check Strategy
+
+# all: show all checked node; parent: show all checked parent node when all child node are checked; child: show all child node
+
+```html
+
+```
+
+```js
+import { defineComponent } from 'vue'
+
+export default defineComponent({
+ setup () {
+ return {
+ options: [
+ {
+ label: 'Rubber Soul',
+ key: 'Rubber Soul',
+ children: [
+ {
+ label:
+ "Everybody's Got Something to Hide Except Me and My Monkey",
+ key: "Everybody's Got Something to Hide Except Me and My Monkey"
+ },
+ {
+ label: 'Drive My Car',
+ key: 'Drive My Car',
+ disabled: true
+ },
+ {
+ label: 'Norwegian Wood',
+ key: 'Norwegian Wood'
+ },
+ {
+ label: "You Won't See",
+ key: "You Won't See",
+ disabled: true
+ },
+ {
+ label: 'Nowhere Man',
+ key: 'Nowhere Man'
+ },
+ {
+ label: 'Think For Yourself',
+ key: 'Think For Yourself'
+ },
+ {
+ label: 'The Word',
+ key: 'The Word'
+ },
+ {
+ label: 'Michelle',
+ key: 'Michelle',
+ disabled: true
+ },
+ {
+ label: 'What goes on',
+ key: 'What goes on'
+ },
+ {
+ label: 'Girl',
+ key: 'Girl'
+ },
+ {
+ label: "I'm looking through you",
+ key: "I'm looking through you"
+ },
+ {
+ label: 'In My Life',
+ key: 'In My Life'
+ },
+ {
+ label: 'Wait',
+ key: 'Wait'
+ }
+ ]
+ },
+ {
+ label: 'Let It Be',
+ key: 'Let It Be Album',
+ children: [
+ {
+ label: 'Two Of Us',
+ key: 'Two Of Us'
+ },
+ {
+ label: 'Dig A Pony',
+ key: 'Dig A Pony'
+ },
+ {
+ label: 'Across The Universe',
+ key: 'Across The Universe',
+ children: [
+ {
+ label: 'Dig It',
+ key: 'Dig It'
+ },
+ {
+ label: 'go',
+ key: 'go'
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ updateValue: (values) => {
+ console.log(values)
+ }
+ }
+ }
+})
+```
diff --git a/src/tree-select/demos/enUS/index.demo-entry.md b/src/tree-select/demos/enUS/index.demo-entry.md
index 198a9fb6c42..1e1db355b2e 100644
--- a/src/tree-select/demos/enUS/index.demo-entry.md
+++ b/src/tree-select/demos/enUS/index.demo-entry.md
@@ -9,6 +9,7 @@ basic
custom-field
multiple
checkbox
+check-strategy
filterable
debug
```
@@ -21,6 +22,7 @@ debug
| --- | --- | --- | --- |
| cascade | `boolean` | `false` | Whether to do cascade check when use checkboxes. |
| checkable | `boolean` | `false` | Whether to use checkbox to select value. |
+| check-strategy | `string` | `'all'` | The way to show checked options. `all`: Show all checked node. `parent`: Show all checked parent node when all child node are checked. `child`: show all child node. |
| children-field | `string` | `'children'` | The children field in `TreeSelectOption`. |
| clearable | `boolean` | `false` | Whether it's clearable. |
| consistent-menu-width | `boolean` | `true` | Whether to make menu's width consistent with input. Set to `true` will disable virtual scroll. |
diff --git a/src/tree-select/demos/zhCN/check-strategy.demo.md b/src/tree-select/demos/zhCN/check-strategy.demo.md
new file mode 100644
index 00000000000..e93469b69d5
--- /dev/null
+++ b/src/tree-select/demos/zhCN/check-strategy.demo.md
@@ -0,0 +1,119 @@
+# 指定勾选策略
+
+```html
+
+```
+
+```js
+import { defineComponent } from 'vue'
+
+export default defineComponent({
+ setup () {
+ return {
+ options: [
+ {
+ label: 'Rubber Soul',
+ key: 'Rubber Soul',
+ children: [
+ {
+ label:
+ "Everybody's Got Something to Hide Except Me and My Monkey",
+ key: "Everybody's Got Something to Hide Except Me and My Monkey"
+ },
+ {
+ label: 'Drive My Car',
+ key: 'Drive My Car',
+ disabled: true
+ },
+ {
+ label: 'Norwegian Wood',
+ key: 'Norwegian Wood'
+ },
+ {
+ label: "You Won't See",
+ key: "You Won't See",
+ disabled: true
+ },
+ {
+ label: 'Nowhere Man',
+ key: 'Nowhere Man'
+ },
+ {
+ label: 'Think For Yourself',
+ key: 'Think For Yourself'
+ },
+ {
+ label: 'The Word',
+ key: 'The Word'
+ },
+ {
+ label: 'Michelle',
+ key: 'Michelle',
+ disabled: true
+ },
+ {
+ label: 'What goes on',
+ key: 'What goes on'
+ },
+ {
+ label: 'Girl',
+ key: 'Girl'
+ },
+ {
+ label: "I'm looking through you",
+ key: "I'm looking through you"
+ },
+ {
+ label: 'In My Life',
+ key: 'In My Life'
+ },
+ {
+ label: 'Wait',
+ key: 'Wait'
+ }
+ ]
+ },
+ {
+ label: 'Let It Be',
+ key: 'Let It Be Album',
+ children: [
+ {
+ label: 'Two Of Us',
+ key: 'Two Of Us'
+ },
+ {
+ label: 'Dig A Pony',
+ key: 'Dig A Pony'
+ },
+ {
+ label: 'Across The Universe',
+ key: 'Across The Universe',
+ children: [
+ {
+ label: 'Dig It',
+ key: 'Dig It'
+ },
+ {
+ label: 'go',
+ key: 'go'
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ updateValue: (values) => {
+ console.log(values)
+ }
+ }
+ }
+})
+```
diff --git a/src/tree-select/demos/zhCN/index.demo-entry.md b/src/tree-select/demos/zhCN/index.demo-entry.md
index dd2b1e2d0b2..0151c2ac760 100644
--- a/src/tree-select/demos/zhCN/index.demo-entry.md
+++ b/src/tree-select/demos/zhCN/index.demo-entry.md
@@ -9,6 +9,7 @@ basic
custom-field
multiple
checkbox
+check-strategy
filterable
debug
```
@@ -21,6 +22,7 @@ debug
| --- | --- | --- | --- |
| cascade | `boolean` | `false` | 使用 checkbox 进行多选时是否级联 |
| checkable | `boolean` | `false` | 是否使用 checkbox 进行选择 |
+| check-strategy | `string` | `'all'` | 设置勾选策略来指定显示的勾选节点,`all`:显示全部选中节点;`parent`:只显示父节点(当父节点下所有子节点都选中时);`child`:只显示子节点 |
| children-field | `string` | `'children'` | 替代 `TreeSelectOption` 中的 children 字段名 |
| clearable | `boolean` | `false` | 是否可清除 |
| consistent-menu-width | `boolean` | `true` | 是否使菜单宽度和输入框一致,打开会禁用虚拟滚动 |
diff --git a/src/tree-select/src/TreeSelect.tsx b/src/tree-select/src/TreeSelect.tsx
index 1721a572316..d70984c88e4 100644
--- a/src/tree-select/src/TreeSelect.tsx
+++ b/src/tree-select/src/TreeSelect.tsx
@@ -47,7 +47,7 @@ import type {
TreeSelectOption,
Value
} from './interface'
-import { treeSelectInjectionKey } from './interface'
+import { treeSelectInjectionKey, CheckStrategy } from './interface'
import {
treeOption2SelectOption,
filterTree,
@@ -81,6 +81,7 @@ const props = {
},
filterable: Boolean,
leafOnly: Boolean,
+ checkStrategy: String as PropType,
maxTagCount: [String, Number] as PropType,
multiple: Boolean,
showPath: Boolean,
@@ -285,11 +286,17 @@ export default defineComponent({
if (Array.isArray(mergedValue)) {
const res: SelectBaseOption[] = []
const { value: treeMate } = dataTreeMateRef
+ const { checkedKeys } = treeMate.getCheckedKeys(mergedValue)
const { keyField, labelField } = props
- mergedValue.forEach((value) => {
+ checkedKeys.forEach((value) => {
const tmNode = treeMate.getNode(value)
if (tmNode !== null) {
- res.push(
+ if (
+ props.checkStrategy === 'all' ||
+ (props.checkStrategy === 'parent' && !tmNode.isLeaf) ||
+ (props.checkStrategy === 'child' && tmNode.isLeaf)
+ ) {
+ res.push(
showPath
? treeOption2SelectOptionWithPath(
tmNode,
@@ -299,6 +306,7 @@ export default defineComponent({
)
: treeOption2SelectOption(tmNode, labelField)
)
+ }
}
})
return res
@@ -691,6 +699,7 @@ export default defineComponent({
mergedClsPrefix,
filteredTreeInfo,
checkable,
+ checkStrategy,
multiple
} = this
return withDirectives(
@@ -723,6 +732,7 @@ export default defineComponent({
checkedKeys={this.treeCheckedKeys}
selectedKeys={this.treeSelectedKeys}
checkable={checkable}
+ checkStrategy={checkStrategy}
cascade={this.mergedCascade}
leafOnly={this.leafOnly}
multiple={this.multiple}
diff --git a/src/tree-select/src/interface.ts b/src/tree-select/src/interface.ts
index d2f53b85f36..034654ed84d 100644
--- a/src/tree-select/src/interface.ts
+++ b/src/tree-select/src/interface.ts
@@ -41,3 +41,5 @@ export interface TreeSelectInjection {
export const treeSelectInjectionKey: InjectionKey =
Symbol('tree-select')
+
+export type CheckStrategy = 'all' | 'parent' | 'child'
diff --git a/src/tree/src/Tree.tsx b/src/tree/src/Tree.tsx
index ae3be5f904c..dad68349180 100644
--- a/src/tree/src/Tree.tsx
+++ b/src/tree/src/Tree.tsx
@@ -28,6 +28,7 @@ import { call, createDataKey, warn } from '../../_utils'
import type { ExtractPublicPropTypes, MaybeArray } from '../../_utils'
import { NxScrollbar } from '../../scrollbar'
import type { ScrollbarInst } from '../../scrollbar'
+import { CheckStrategy } from '../../tree-select/src/interface'
import { treeLight } from '../styles'
import type { TreeTheme } from '../styles'
import NTreeNode from './TreeNode'
@@ -126,6 +127,7 @@ const treeProps = {
blockLine: Boolean,
disabled: Boolean,
checkedKeys: Array as PropType,
+ checkStrategy: String as PropType,
defaultCheckedKeys: {
type: Array as PropType,
default: () => []
@@ -263,6 +265,9 @@ export default defineComponent({
cascade: props.cascade
})
})
+ const mergedCheckStrategyRef = computed(() =>
+ props.leafOnly ? 'child' : props.checkStrategy
+ )
const displayedCheckedKeysRef = computed(() => {
return checkedStatusRef.value.checkedKeys
})
@@ -567,7 +572,8 @@ export default defineComponent({
checked ? 'check' : 'uncheck'
](node.key, displayedCheckedKeysRef.value, {
cascade: props.cascade,
- leafOnly: props.leafOnly
+ leafOnly: props.leafOnly,
+ checkStrategy: mergedCheckStrategyRef.value
})
doUpdateCheckedKeys(checkedKeys)
}