Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(next): support checkStrictly props in SelectTable #2824

Merged
merged 7 commits into from
Feb 15, 2022
Merged
16 changes: 16 additions & 0 deletions packages/antd/docs/components/SelectTable.md
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,9 @@ const schema = {
.toLowerCase()
.localeCompare(optionB.description.toLowerCase()),
optionAsValue: true,
rowSelection: {
checkStrictly: false,
},
},
enum: [
{ key: '1', name: 'title-1', description: 'A-description' },
Expand All @@ -468,6 +471,11 @@ const schema = {
},
],
},
{
key: '2-2',
name: 'title2-2',
description: 'YY-description',
},
],
},
{ key: '3', name: 'title-3', description: 'C-description' },
Expand Down Expand Up @@ -608,6 +616,14 @@ export default () => (

`TableProps` type definition reference antd https://ant.design/components/table/

### rowSelection

| Property name | Type | Description | Default value |
| ------------- | ------- | -------------------------------------------------------------------------- | ------------- |
| checkStrictly | boolean | Check table row precisely; parent row and children rows are not associated | true |

`rowSelectionProps` type definition reference antd https://ant.design/components/table/#rowSelection

### SelectTable.Column

`ColumnProps` type definition reference antd https://ant.design/components/table/ Table.Column
18 changes: 17 additions & 1 deletion packages/antd/docs/components/SelectTable.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,9 @@ const schema = {
.toLowerCase()
.localeCompare(optionB.description.toLowerCase()),
optionAsValue: true,
rowSelection: {
checkStrictly: false,
},
},
enum: [
{ key: '1', name: '标题1', description: 'A-描述' },
Expand All @@ -464,6 +467,11 @@ const schema = {
{ key: '2-1-1', name: '标题2-1-1', description: 'Z-描述' },
],
},
{
key: '2-2',
name: '标题2-2',
description: 'YY-描述',
},
],
},
{ key: '3', name: '标题3', description: 'C-描述' },
Expand Down Expand Up @@ -602,7 +610,15 @@ export default () => (
| filterSort | (optionA, optionB) => number | 搜索时对筛选结果项的排序函数, 类似 Array.sort 里的 compareFunction | - |
| onSearch | 文本框值变化时回调 | (inputValue) => void | - |

其余参考 https://ant.design/components/table-cn/
参考 https://ant.design/components/table-cn/

### rowSelection

| 属性名 | 类型 | 描述 | 默认值 |
| ------------- | ------- | ------------------------------------------------------------ | ------ |
| checkStrictly | boolean | checkable 状态下节点选择完全受控(父子数据选中状态不再关联) | true |

参考 https://ant.design/components/table/#rowSelection

### SelectTable.Column

Expand Down
16 changes: 16 additions & 0 deletions packages/next/docs/components/SelectTable.md
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,9 @@ const schema = {
.toLowerCase()
.localeCompare(optionB.description.toLowerCase()),
optionAsValue: true,
rowSelection: {
checkStrictly: false,
},
},
enum: [
{ key: '1', name: 'title-1', description: 'A-description' },
Expand All @@ -472,6 +475,11 @@ const schema = {
},
],
},
{
key: '2-2',
name: 'title2-2',
description: 'YY-description',
},
],
},
{ key: '3', name: 'title-3', description: 'C-description' },
Expand Down Expand Up @@ -613,6 +621,14 @@ export default () => (

`TableProps` type definition reference fusion https://fusion.design/pc/component/basic/table

### rowSelection

| Property name | Type | Description | Default value |
| ------------- | ------- | -------------------------------------------------------------------------- | ------------- |
| checkStrictly | boolean | Check table row precisely; parent row and children rows are not associated | true |

`rowSelectionProps` type definition reference fusion https://fusion.design/pc/component/basic/table rowSelection

### SelectTable.Column

`ColumnProps` type definition reference fusion https://fusion.design/pc/component/basic/table Table.Column
18 changes: 17 additions & 1 deletion packages/next/docs/components/SelectTable.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,9 @@ const schema = {
.toLowerCase()
.localeCompare(optionB.description.toLowerCase()),
optionAsValue: true,
rowSelection: {
checkStrictly: false,
},
},
enum: [
{ key: '1', name: '标题1', description: 'A-描述' },
Expand All @@ -468,6 +471,11 @@ const schema = {
{ key: '2-1-1', name: '标题2-1-1', description: 'Z-描述' },
],
},
{
key: '2-2',
name: '标题2-2',
description: 'YY-描述',
},
],
},
{ key: '3', name: '标题3', description: 'C-描述' },
Expand Down Expand Up @@ -607,7 +615,15 @@ export default () => (
| filterSort | (optionA, optionB) => number | 搜索时对筛选结果项的排序函数, 类似 Array.sort 里的 compareFunction | - |
| onSearch | 文本框值变化时回调 | (inputValue) => void | - |

其余参考 https://fusion.design/pc/component/basic/table
参考 https://fusion.design/pc/component/basic/table

### rowSelection

| 属性名 | 类型 | 描述 | 默认值 |
| ------------- | ------- | ------------------------------------------------------------ | ------ |
| checkStrictly | boolean | checkable 状态下节点选择完全受控(父子数据选中状态不再关联) | true |

参考 https://fusion.design/pc/component/basic/table rowSelection

### SelectTable.Column

Expand Down
28 changes: 27 additions & 1 deletion packages/next/src/select-table/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { useFilterOptions } from './useFilterOptions'
import { useFlatOptions } from './useFlatOptions'
import { useTitleAddon } from './useTitleAddon'
import { useSize } from './useSize'
import { useCheckSlackly, getCheckedProps } from './useCheckSlackly'
import { usePrefixCls } from '../__builtins__'

type IFilterOption = boolean | ((option: any, keyword: string) => boolean)
Expand All @@ -32,6 +33,9 @@ export interface ISelectTableProps extends Omit<TableProps, 'primaryKey'> {
onSearch?: (keyword: string) => void
onChange?: (value: any) => void
value?: any
rowSelection?: TableProps['rowSelection'] & {
checkStrictly?: boolean
}
}

type ComposedSelectTable = React.FC<ISelectTableProps> & {
Expand Down Expand Up @@ -180,6 +184,22 @@ export const SelectTable: ComposedSelectTable = observer((props) => {
selectedRowKeys.includes(item?.[primaryKey])
)
}
if (rowSelection?.checkStrictly !== false) {
onInnerChange(selectedRowKeys, records)
} else {
onSlacklyChange(selectedRowKeys)
}
}

// Fusion TreeData SlacklyChange
const onSlacklyChange = (prevSelectedRowKeys: any[]) => {
const { selectedRowKeys, records } = useCheckSlackly(
prevSelectedRowKeys,
selected,
primaryKey,
flatDataSource
)

onInnerChange(selectedRowKeys, records)
}

Expand Down Expand Up @@ -232,10 +252,16 @@ export const SelectTable: ComposedSelectTable = observer((props) => {
...rowSelection,
getProps: (record, index) => ({
...(rowSelection?.getProps?.(record, index) as any),
...(rowSelection?.checkStrictly !== false
? {}
: getCheckedProps(record, primaryKey, selected)), // 父子关联模式indeterminate值
disabled,
}), // fusion
selectedRowKeys: selected,
onChange: onInnerChange,
onChange:
rowSelection?.checkStrictly !== false
? onInnerChange
: onSlacklyChange,
mode,
...titleAddon,
}
Expand Down
131 changes: 131 additions & 0 deletions packages/next/src/select-table/useCheckSlackly.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
/**
* 获取该字段Checkbox的indeterminate属性
* @param record 字段项
* @param primaryKey 键名称
* @param selected 当前选中的字段值集合
* @returns indeterminate属性值
*/
const getCheckedProps = (record: any, primaryKey: string, selected: any[]) => {
if (record.children?.length) {
const childrenDataSource = record.children
const selectedChildren = childrenDataSource.filter((item) =>
selected?.includes(item[primaryKey])
)
return {
// checked受控,此处配置在rowSelection并不会生效,供getFinalTreeKeys使用
checked: selectedChildren.length === childrenDataSource.length,
indeterminate: !!(
selectedChildren.length &&
selectedChildren.length !== childrenDataSource.length
),
}
}
return {}
}

/**
* 获取树列表某个键值的集合
* @param tree 树列表
* @param primaryKey 键名称
* @returns 键值数组集合
*/
const getTreeKeys = (tree: any[] = [], primaryKey: string) =>
tree.reduce(
(prev, current) => [
...prev,
current[primaryKey],
...getTreeKeys(current?.children, primaryKey),
],
[]
)

/**
* 获取最终选中值(添加选中所有子元素的父元素,或移除未选中所有子元素的父元素)
* @param tree 树列表
* @param primaryKey 键名称
* @param selectedRowKeys 当前选中的字段值集合
* @returns 最终选中的字段值集合
*/
const getFinalTreeKeys = (
tree: any[] = [],
primaryKey: string,
selectedRowKeys: any[]
) => {
let finalSelectedRowKeys = [...selectedRowKeys]

tree.forEach((item) => {
if (item.children?.length) {
// 优先递归子元素
finalSelectedRowKeys = getFinalTreeKeys(
item.children,
primaryKey,
finalSelectedRowKeys
)
if (getCheckedProps(item, primaryKey, finalSelectedRowKeys)?.checked) {
// 如果该元素的子元素全部选中,则也选中该项(即包含全选子元素的父元素)
finalSelectedRowKeys = [
...new Set([...finalSelectedRowKeys, item[primaryKey]]),
]
} else {
// 如果该元素的子元素未全部选中,则移除该项
finalSelectedRowKeys = finalSelectedRowKeys.filter(
(key) => key !== item[primaryKey]
)
}
}
})

return finalSelectedRowKeys
}

interface ICheckSlackly {
(
selectedRowKeys: any[],
selected: any[],
primaryKey: string,
flatDataSource: any[]
): {
selectedRowKeys: any[]
records: any[]
}
}

const useCheckSlackly: ICheckSlackly = (
selectedRowKeys,
selected,
primaryKey,
flatDataSource
) => {
const isSelected = selectedRowKeys.length > selected.length
const currentKey = [...selectedRowKeys, ...selected].find(
(key) => !(selectedRowKeys.includes(key) && selected.includes(key))
)
const currentRecords = flatDataSource.find(
(item) => item[primaryKey] === currentKey
)
const currentTreeKeys = getTreeKeys([currentRecords], primaryKey)
let newSelectedRowKeys = []

if (isSelected) {
newSelectedRowKeys = [...new Set([...selected, ...currentTreeKeys])]
} else {
newSelectedRowKeys = selected.filter(
(key) => !currentTreeKeys.includes(key)
)
}
// 添加选中所有子元素的父元素,或移除未选中所有子元素的父元素
newSelectedRowKeys = getFinalTreeKeys(
flatDataSource,
primaryKey,
newSelectedRowKeys
)

return {
selectedRowKeys: newSelectedRowKeys,
records: flatDataSource.filter((item) =>
newSelectedRowKeys.includes(item[primaryKey])
),
}
}

export { useCheckSlackly, getCheckedProps }
9 changes: 5 additions & 4 deletions packages/next/src/select-table/useTitleAddon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,18 @@ const newCheckbox =
(selected, flatDataSource, primaryKey, disabled, readOnly, onChange) =>
() => {
const allDataSourceKeys = flatDataSource.map((item) => item?.[primaryKey])
const indeterminate = !!(
selected?.length && selected.length !== allDataSourceKeys.length
)
return (
<Checkbox
key="titleAddons"
checked={!!selected?.length}
disabled={disabled}
indeterminate={
!!(selected?.length && selected.length !== allDataSourceKeys.length)
}
indeterminate={indeterminate}
onChange={(checked) => {
if (!readOnly) {
if (checked) {
if (checked || indeterminate) {
onChange?.(allDataSourceKeys, flatDataSource)
} else {
onChange?.([], [])
Expand Down