Skip to content

Commit

Permalink
feat(next): support checkStrictly props in SelectTable (#2824)
Browse files Browse the repository at this point in the history
  • Loading branch information
ifblooms authored Feb 15, 2022
1 parent 16a376d commit feba637
Show file tree
Hide file tree
Showing 7 changed files with 229 additions and 7 deletions.
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

0 comments on commit feba637

Please sign in to comment.