feat(tree, tree-select): indeterminate-keys & on-update:indeterminate-keys prop

This commit is contained in:
07akioni 2021-09-19 16:41:34 +08:00
parent 78f5db7620
commit d0ba4ff456
8 changed files with 65 additions and 6 deletions

View File

@ -14,6 +14,10 @@
- `n-spin` add `description` prop and slot.
- `n-anchor` add `variant` prop.
- `n-upload` add `abstract` prop, add `n-upload-trigger``n-upload-file-list` component, closes [#1102](https://github.com/TuSimple/naive-ui/issues/1102).
- `n-tree` add `indeterminate-keys` prop.
- `n-tree-select` add `indeterminate-keys` prop.
- `n-tree` add `on-update:indeterminate-keys` prop.
- `n-tree-select` add `on-update:indeterminate-keys` prop.
### Fixes

View File

@ -14,6 +14,10 @@
- `n-spin` 新增 `description` prop 和 slot
- `n-anchor` 新增 `variant` 属性
- `n-upload` 新增 `abstract` 属性,新增 `n-upload-trigger``n-upload-file-list` 组件,关闭 [#1102](https://github.com/TuSimple/naive-ui/issues/1102)
- `n-tree` 新增 `indeterminate-keys` 属性
- `n-tree-select` 新增 `indeterminate-keys` 属性
- `n-tree` 新增 `on-update:indeterminate-keys` 属性
- `n-tree-select` 新增 `on-update:indeterminate-keys` 属性
### Fixes

View File

@ -31,6 +31,7 @@ debug
| default-expanded-keys | `Array<string \| number>` | `[]` | Expanded keys by default. |
| disabled | `boolean` | `false` | Whether to disable the tree select. |
| expanded-keys | `Array<string \| number>` | `undefined` | Expanded keys. |
| indeterminate-keys | `Array<string \| number>` | `undefined` | Indeterminate keys of the tree. |
| filterable | `boolean` | `false` | Whether the tree select is disabled. |
| filter | `(pattern: string, option: TreeSelectOption) => boolean` | - | Filter function. |
| key-field | `string` | `'key'` | The key field in `TreeSelectOption`. |
@ -45,8 +46,9 @@ debug
| value | `string \| number \| Array<string \| number> \| null>` | `undefined` | Selected key (or keys when multiple). |
| virtual-scroll | `boolean` | `true` | Whether to enable virtual scroll. |
| on-blur | `(e: FocusEvent) => void` | `undefined` | Callback on blur. |
| on-update:expanded-keys | `(value: Array<string \| number>) => void` | `undefined` | Callback on expanded keys updated. |
| on-focus | `(e: FocusEvent) => void` | `undefined` | Callback on focus. |
| on-update:expanded-keys | `(value: Array<string \| number>) => void` | `undefined` | Callback on expanded keys updated. |
| on-update:indeterminate-keys | `(keys: Array<string \| number>) => void` | `undefined` | Callback function when node indeterminate options change. |
| on-update:value | `(value: string \| number \| Array<string \| number> \| null, option: TreeSelectOption \| null \| Array<TreeSelectOption \| null>) => void` | `undefined` | Callback on value updated. |
### TreeSelectOption Properties

View File

@ -31,6 +31,7 @@ debug
| default-expanded-keys | `Array<string \| number>` | `[]` | 默认展开节点的 key |
| disabled | `boolean` | `false` | 是否禁用 |
| expanded-keys | `Array<string \| number>` | `undefined` | 展开节点的 key |
| indeterminate-keys | `string \| number` | `undefined` | 部分选中选项的 key |
| filterable | `boolean` | `false` | 是否可过滤 |
| filter | `(pattern: string, option: TreeSelectOption) => boolean` | - | 过滤器函数 |
| key-field | `string` | `'key'` | 替代 `TreeSelectOption` 中的 key 字段名 |
@ -46,8 +47,9 @@ debug
| value | `string \| number \| Array<string \| number> \| null>` | `undefined` | 选中的 key |
| virtual-scroll | `boolean` | `true` | 是否开启虚拟滚动 |
| on-blur | `(e: FocusEvent) => void` | `undefined` | Blur 时的回调 |
| on-update:expanded-keys | `(value: Array<string \| number>) => void` | `undefined` | 展开节点更新的回调 |
| on-focus | `(e: FocusEvent) => void` | `undefined` | Focus 时的回调 |
| on-update:expanded-keys | `(value: Array<string \| number>) => void` | `undefined` | 展开节点更新的回调 |
| on-update:indeterminate-keys | `(keys: Array<string \| number>) => void` | `undefined` | 节点部分勾选项发生变化时的回调函数 |
| on-update:value | `(value: string \| number \| Array<string \| number> \| null, option: TreeSelectOption \| null \| Array<TreeSelectOption \| null>) => void` | `undefined` | 更新值的回调 |
### TreeSelectOption Properties

View File

@ -362,6 +362,21 @@ export default defineComponent({
nTriggerFormInput()
nTriggerFormChange()
}
function doUpdateIndeterminateKeys (
value: string | number | Array<string | number> | null,
option: TreeSelectOption | null | Array<TreeSelectOption | null>
): void {
const {
onUpdateIndeterminateKeys,
'onUpdate:indeterminateKeys': _onUpdateIndeterminateKeys
} = props
if (onUpdateIndeterminateKeys) {
call(onUpdateIndeterminateKeys as OnUpdateValueImpl, value, option)
}
if (_onUpdateIndeterminateKeys) {
call(_onUpdateIndeterminateKeys as OnUpdateValueImpl, value, option)
}
}
function doUpdateExpandedKeys (keys: Key[]): void {
const {
onUpdateExpandedKeys,
@ -455,6 +470,11 @@ export default defineComponent({
}
}
}
function handleUpdateIndeterminateKeys (keys: Key[]): void {
if (props.checkable && props.multiple) {
doUpdateIndeterminateKeys(keys, getOptionsByKeys(keys))
}
}
function handleTriggerFocus (e: FocusEvent): void {
if (menuElRef.value?.contains(e.relatedTarget as Element)) return
focusedRef.value = true
@ -635,6 +655,7 @@ export default defineComponent({
handleMenuClickoutside,
handleUpdateSelectedKeys,
handleUpdateCheckedKeys,
handleUpdateIndeterminateKeys,
handleTriggerFocus,
handleTriggerBlur,
handleMenuFocusin,
@ -782,6 +803,9 @@ export default defineComponent({
onUpdateCheckedKeys={
this.handleUpdateCheckedKeys
}
onUpdateIndeterminateKeys={
this.handleUpdateIndeterminateKeys
}
onUpdateExpandedKeys={
this.doUpdateExpandedKeys
}

View File

@ -34,7 +34,7 @@ batch-render
| check-strategy | `string` | `'all'` | The strategy of setting checked callback's keys argument. `all` means setting all checked node. `parent` means setting all checked parent node of whom all child node are checked. `child` means setting all child node. |
| checkable | `boolean` | `false` | Whether to display the selection box, you need to set `cascade` to `true`. |
| children-field | `string` | `'children'` | The children field in `TreeOption`. |
| checked-keys | `Array<string \| number>` | `undefined` | If set, checked status will work in controlled manner. |
| checked-keys | `Array<string \| number>` | `undefined` | Checked keys of the tree. |
| data | `Array<TreeOption>` | `[]` | The node data of the tree. Reset `data` will cause clearing of some uncontrolled status. If you need to modify data, you'd better make tree work in a controlled manner. |
| default-checked-keys | `Array<string \| number>` | `[]` | Multiple options selected by default. |
| default-expand-all | `boolean` | `false` | Expand all options. |
@ -44,6 +44,7 @@ batch-render
| expand-on-dragenter | `boolean` | `true` | Whether to expand nodes after dragenter. |
| expanded-keys | `Array<string \| number>` | `undefined` | If set, expanded status will work in controlled manner. |
| filter | `(node: TreeOption) => boolean` | `undefined` | A simple string based filter. |
| indeterminate-keys | `Array<string \| number>` | `undefined` | Indeterminate keys of the tree. |
| key-field | `string` | `'key'` | The key field in `TreeOption`. |
| label-field | `string` | `'label'` | The label field in `TreeOption`. |
| leaf-only | `boolean` | `false` | Whether to open or not, only the bottom tree node is optional. |
@ -62,7 +63,8 @@ batch-render
| on-dragleave | `(data: { node: TreeOption, event: DragEvent }) => void` | `undefined` | Drag a node, the callback function after the node leaves other nodes. |
| on-dragstart | `(data: { node: TreeOption, event: DragEvent }) => void` | `undefined` | Callback function to start dragging a certain node. |
| on-drop | `(data: { node: TreeOption, dragNode: TreeOption, dropPosition: 'before' \| 'inside' \| 'after', event: DragEvent }) => void` | `undefined` | The callback function after the node completes the dragging action. |
| on-update:checked-keys | `(keys: Array<string \| number>) => void` | `undefined` | Callback function when node multiple options change. |
| on-update:checked-keys | `(keys: Array<string \| number>) => void` | `undefined` | Callback function when node checked options change. |
| on-update:indeterminate-keys | `(keys: Array<string \| number>) => void` | `undefined` | Callback function when node indeterminate options change. |
| on-update:expanded-keys | `(keys: Array<string \| number>) => void` | `undefined` | The callback function when the node expansion item changes. |
| on-update:selected-keys | `(keys: Array<string \| number>) => void` | `undefined` | The callback function when the selected item of the node changes. |

View File

@ -44,6 +44,7 @@ batch-render
| expand-on-dragenter | `boolean` | `true` | 是否在拖入后展开节点 |
| expanded-keys | `Array<string \| number>` | `undefined` | 如果设定则展开受控 |
| filter | `(node: TreeOption) => boolean` | `undefined` | 一个简单的字符串过滤算法 |
| indeterminate-keys | `string \| number` | `undefined` | 部分选中选项的 key |
| key-field | `string` | `'key'` | 替代 `TreeOption` 中的 key 字段名 |
| label-field | `string` | `'label'` | 替代 `TreeOption` 中的 label 字段名 |
| leaf-only | `boolean` | `false` | 是否开启仅末层树节点可选 |
@ -62,7 +63,8 @@ batch-render
| on-dragleave | `(data: { node: TreeOption, event: DragEvent }) => void` | `undefined` | 拖拽一个节点,该节点离开其它节点后的回调函数 |
| on-dragstart | `(data: { node: TreeOption, event: DragEvent }) => void` | `undefined` | 开始拖拽某一个节点的回调函数 |
| on-drop | `(data: { node: TreeOption, dragNode: TreeOption, dropPosition: 'before' \| 'inside' \| 'after', event: DragEvent }) => void` | `undefined` | 节点完成拖拽动作后的回调函数 |
| on-update:checked-keys | `(keys: Array<string \| number>) => void` | `undefined` | 节点多选项发生变化时的回调函数 |
| on-update:checked-keys | `(keys: Array<string \| number>) => void` | `undefined` | 节点勾选项发生变化时的回调函数 |
| on-update:indeterminate-keys | `(keys: Array<string \| number>) => void` | `undefined` | 节点部分勾选项发生变化时的回调函数 |
| on-update:expanded-keys | `(keys: Array<string \| number>) => void` | `undefined` | 节点展开项发生变化时的回调函数 |
| on-update:selected-keys | `(keys: Array<string \| number>) => void` | `undefined` | 节点选中项发生变化时的回调函数 |

View File

@ -99,6 +99,13 @@ export const treeSharedProps = {
type: Array as PropType<Key[]>,
default: () => []
},
indeterminateKeys: Array as PropType<Key[]>,
onUpdateIndeterminateKeys: [Function, Array] as PropType<
MaybeArray<(value: Key[]) => void>
>,
'onUpdate:indeterminateKeys': [Function, Array] as PropType<
MaybeArray<(value: Key[]) => void>
>,
onUpdateExpandedKeys: [Function, Array] as PropType<
MaybeArray<(value: Key[]) => void>
>,
@ -275,6 +282,8 @@ export default defineComponent({
return checkedStatusRef.value.checkedKeys
})
const displayedIndeterminateKeysRef = computed(() => {
const { indeterminateKeys } = props
if (indeterminateKeys !== undefined) return indeterminateKeys
return checkedStatusRef.value.indeterminateKeys
})
const uncontrolledSelectedKeysRef = ref(
@ -511,6 +520,15 @@ export default defineComponent({
if (onUpdateCheckedKeys) call(onUpdateCheckedKeys, value)
if (_onUpdateCheckedKeys) call(_onUpdateCheckedKeys, value)
}
function doUpdateIndeterminateKeys (value: Key[]): void {
const {
'onUpdate:indeterminateKeys': _onUpdateIndeterminateKeys,
onUpdateIndeterminateKeys
} = props
uncontrolledCheckedKeysRef.value = value
if (_onUpdateIndeterminateKeys) call(_onUpdateIndeterminateKeys, value)
if (onUpdateIndeterminateKeys) call(onUpdateIndeterminateKeys, value)
}
function doUpdateSelectedKeys (value: Key[]): void {
const {
'onUpdate:selectedKeys': _onUpdateSelectedKeys,
@ -571,7 +589,7 @@ export default defineComponent({
if (props.disabled || node.disabled) {
return
}
const { checkedKeys } = dataTreeMateRef.value![
const { checkedKeys, indeterminateKeys } = dataTreeMateRef.value![
checked ? 'check' : 'uncheck'
](node.key, displayedCheckedKeysRef.value, {
cascade: props.cascade,
@ -579,6 +597,7 @@ export default defineComponent({
checkStrategy: mergedCheckStrategyRef.value
})
doUpdateCheckedKeys(checkedKeys)
doUpdateIndeterminateKeys(indeterminateKeys)
}
function toggleExpand (key: Key): void {
if (props.disabled) return