Skip to content

Commit

Permalink
feat(comp:table): selectable supports showIndex (#1360)
Browse files Browse the repository at this point in the history
  • Loading branch information
danranVm committed Dec 16, 2022
1 parent e44673f commit 19e6f68
Show file tree
Hide file tree
Showing 11 changed files with 153 additions and 84 deletions.
3 changes: 3 additions & 0 deletions packages/components/config/src/defaultConfig.ts
Expand Up @@ -312,6 +312,9 @@ export const defaultConfig: GlobalConfig = {
columnExpandable: {
icon: 'right',
},
columnSelectable: {
showIndex: false,
},
},
tag: {},
tagGroup: {
Expand Down
5 changes: 5 additions & 0 deletions packages/components/config/src/types.ts
Expand Up @@ -464,6 +464,7 @@ export interface TableConfig {

columnBase: TableColumnBaseConfig
columnExpandable: TableColumnExpandableConfig
columnSelectable: TableColumnSelectableConfig
}

export interface TableColumnBaseConfig {
Expand All @@ -476,6 +477,10 @@ export interface TableColumnExpandableConfig {
icon: string | VNodeChild | ((options: { expanded: boolean; record: any }) => string | VNodeChild)
}

export interface TableColumnSelectableConfig {
showIndex: boolean
}

export interface TagConfig {
shape?: TagShape
}
Expand Down
Expand Up @@ -63,9 +63,9 @@ exports[`Table > basic work > render work 1`] = `
</td>
</tr>
<tr class=\\"ix-table-row\\">
<td class=\\"ix-table-cell\\"><button class=\\"ix-table-expandable-trigger\\" type=\\"button\\">
<!---->
</button><a>expandable</a></td>
<td class=\\"ix-table-cell\\">
<!----><a>expandable</a>
</td>
<td class=\\"ix-table-cell\\">
<!----><label class=\\"ix-checkbox\\" role=\\"checkbox\\" aria-checked=\\"false\\" aria-disabled=\\"false\\"><span class=\\"ix-checkbox-input\\"><input type=\\"checkbox\\" class=\\"ix-checkbox-input-inner\\" aria-hidden=\\"true\\"><span class=\\"ix-checkbox-input-box\\"><div aria-hidden=\\"true\\" class=\\"ix-wave\\"></div></span></span>
<!---->
Expand All @@ -92,9 +92,9 @@ exports[`Table > basic work > render work 1`] = `
</td>
</tr>
<tr class=\\"ix-table-row\\">
<td class=\\"ix-table-cell\\"><button class=\\"ix-table-expandable-trigger\\" type=\\"button\\">
<!---->
</button><a>expandable</a></td>
<td class=\\"ix-table-cell\\">
<!----><a>expandable</a>
</td>
<td class=\\"ix-table-cell\\">
<!----><label class=\\"ix-checkbox\\" role=\\"checkbox\\" aria-checked=\\"false\\" aria-disabled=\\"false\\"><span class=\\"ix-checkbox-input\\"><input type=\\"checkbox\\" class=\\"ix-checkbox-input-inner\\" aria-hidden=\\"true\\"><span class=\\"ix-checkbox-input-box\\"><div aria-hidden=\\"true\\" class=\\"ix-wave\\"></div></span></span>
<!---->
Expand Down Expand Up @@ -148,9 +148,9 @@ exports[`Table > basic work > render work 1`] = `
</td>
</tr>
<tr class=\\"ix-table-row\\">
<td class=\\"ix-table-cell\\"><button class=\\"ix-table-expandable-trigger\\" type=\\"button\\">
<!---->
</button><a>expandable</a></td>
<td class=\\"ix-table-cell\\">
<!----><a>expandable</a>
</td>
<td class=\\"ix-table-cell\\">
<!----><label class=\\"ix-checkbox\\" role=\\"checkbox\\" aria-checked=\\"false\\" aria-disabled=\\"false\\"><span class=\\"ix-checkbox-input\\"><input type=\\"checkbox\\" class=\\"ix-checkbox-input-inner\\" aria-hidden=\\"true\\"><span class=\\"ix-checkbox-input-box\\"><div aria-hidden=\\"true\\" class=\\"ix-wave\\"></div></span></span>
<!---->
Expand All @@ -177,9 +177,9 @@ exports[`Table > basic work > render work 1`] = `
</td>
</tr>
<tr class=\\"ix-table-row\\">
<td class=\\"ix-table-cell\\"><button class=\\"ix-table-expandable-trigger\\" type=\\"button\\">
<!---->
</button><a>expandable</a></td>
<td class=\\"ix-table-cell\\">
<!----><a>expandable</a>
</td>
<td class=\\"ix-table-cell\\">
<!----><label class=\\"ix-checkbox\\" role=\\"checkbox\\" aria-checked=\\"false\\" aria-disabled=\\"false\\"><span class=\\"ix-checkbox-input\\"><input type=\\"checkbox\\" class=\\"ix-checkbox-input-inner\\" aria-hidden=\\"true\\"><span class=\\"ix-checkbox-input-box\\"><div aria-hidden=\\"true\\" class=\\"ix-wave\\"></div></span></span>
<!---->
Expand Down Expand Up @@ -233,9 +233,9 @@ exports[`Table > basic work > render work 1`] = `
</td>
</tr>
<tr class=\\"ix-table-row\\">
<td class=\\"ix-table-cell\\"><button class=\\"ix-table-expandable-trigger\\" type=\\"button\\">
<!---->
</button><a>expandable</a></td>
<td class=\\"ix-table-cell\\">
<!----><a>expandable</a>
</td>
<td class=\\"ix-table-cell\\">
<!----><label class=\\"ix-checkbox\\" role=\\"checkbox\\" aria-checked=\\"false\\" aria-disabled=\\"false\\"><span class=\\"ix-checkbox-input\\"><input type=\\"checkbox\\" class=\\"ix-checkbox-input-inner\\" aria-hidden=\\"true\\"><span class=\\"ix-checkbox-input-box\\"><div aria-hidden=\\"true\\" class=\\"ix-wave\\"></div></span></span>
<!---->
Expand All @@ -262,9 +262,9 @@ exports[`Table > basic work > render work 1`] = `
</td>
</tr>
<tr class=\\"ix-table-row\\">
<td class=\\"ix-table-cell\\"><button class=\\"ix-table-expandable-trigger\\" type=\\"button\\">
<!---->
</button><a>expandable</a></td>
<td class=\\"ix-table-cell\\">
<!----><a>expandable</a>
</td>
<td class=\\"ix-table-cell\\">
<!----><label class=\\"ix-checkbox\\" role=\\"checkbox\\" aria-checked=\\"false\\" aria-disabled=\\"false\\"><span class=\\"ix-checkbox-input\\"><input type=\\"checkbox\\" class=\\"ix-checkbox-input-inner\\" aria-hidden=\\"true\\"><span class=\\"ix-checkbox-input-box\\"><div aria-hidden=\\"true\\" class=\\"ix-wave\\"></div></span></span>
<!---->
Expand Down
2 changes: 2 additions & 0 deletions packages/components/table/demo/Selectable.md
Expand Up @@ -11,6 +11,7 @@ order: 30

- 支持多选和单选
- 支持通过行的点击或者双击事件来进行选中
- 支持默认显示序号, 悬浮时显示勾选框
- 通常情况下,你不需要用到 `reactive`, 除非你需要切换某个配置

## en
Expand All @@ -19,4 +20,5 @@ Configure `TableColumnSelectable` in `columns` to support row selection.

- Multiple or single options are supported
- Supports row `click` or `dblclick` events to select
- Support default display serial number, and display checkbox in hover
- Normally you don't need to use Reactive unless you need to switch a configuration
29 changes: 16 additions & 13 deletions packages/components/table/demo/Selectable.vue
@@ -1,18 +1,19 @@
<template>
<IxSpace>
<IxSwitch v-model:checked="selectableColumn.multiple" :labels="['Checkbox', 'Radio']"></IxSwitch>
<IxRadioGroup v-model:value="selectableColumn.trigger">
<IxRadio value="click">Click</IxRadio>
<IxRadio value="dblclick">DblClick</IxRadio>
</IxRadioGroup>
<IxSpace vertical block>
<IxSpace align="center">
<IxRadioGroup v-model:value="selectableColumn.trigger">
<IxRadio value="click">Click</IxRadio>
<IxRadio value="dblclick">DblClick</IxRadio>
</IxRadioGroup>
<IxSwitch v-model:checked="selectableColumn.multiple" :labels="['Multiple', 'Multiple']"></IxSwitch>
<IxSwitch v-model:checked="selectableColumn.showIndex" :labels="['Index', 'Index']"></IxSwitch>
</IxSpace>
<IxTable v-model:selectedRowKeys="selectedRowKeys" :columns="columns" :dataSource="data" :pagination="false">
<template #name="{ value }">
<IxButton mode="link">{{ value }}</IxButton>
</template>
</IxTable>
</IxSpace>
<br />
<br />
<IxTable v-model:selectedRowKeys="selectedRowKeys" :columns="columns" :dataSource="data" :pagination="false">
<template #name="{ value }">
<IxButton mode="link">{{ value }}</IxButton>
</template>
</IxTable>
</template>

<script lang="ts" setup>
Expand All @@ -33,8 +34,10 @@ const selectedRowKeys = ref([1])
const selectableColumn = reactive<TableColumnSelectable<Data>>({
type: 'selectable',
align: 'center',
disabled: record => record.key === 4,
multiple: true,
showIndex: false,
onChange: (selectedKeys, selectedRows) => console.log(selectedKeys, selectedRows),
})
Expand Down
1 change: 1 addition & 0 deletions packages/components/table/docs/Api.zh.md
Expand Up @@ -100,6 +100,7 @@ export type TableColumn<T = any, V = any> =
| `disabled` | 设置是否允许行选择 | `(record: T, rowIndex: number) => boolean` | - | - | - |
| `multiple` | 是否支持多选 | `boolean` | `true` | - | - |
| `menus` | 自定义列头下拉菜单 | `('all' \| 'invert' \| 'none' \| 'pageInvert' \| MenuData)[]` | - | - | - |
| `showIndex` | 是否显示序号 | `boolean` | `false` | ✅ | - |
| `trigger` | 不通过点击选择框,触发行选择的方式 | `'click' \| 'doubleClick'` | - | - | - |
| `onChange` | 选中状态发生变化时触发 | `(selectedRowKeys: (string \| number)[], selectedRecords: T[]) => void` | - | - | - |
| `onMenuClick` | 点击下拉菜单时触发 | `(options: MenuClickOptions, currentPageRowKeys: VKey[]) => void` | - | - | 如果点击时预设的值, 则不会触发该回调(例如:`all`, 那么触发的是 `onSelectAll`) |
Expand Down
36 changes: 24 additions & 12 deletions packages/components/table/src/composables/useColumns.ts
Expand Up @@ -21,7 +21,12 @@ import {
import { debounce, isNil } from 'lodash-es'

import { type VKey, flattenNode } from '@idux/cdk/utils'
import { type TableColumnBaseConfig, type TableColumnExpandableConfig, type TableConfig } from '@idux/components/config'
import {
type TableColumnBaseConfig,
type TableColumnExpandableConfig,
TableColumnSelectableConfig,
type TableConfig,
} from '@idux/components/config'

import { tableColumnKey } from '../column'
import {
Expand All @@ -43,11 +48,12 @@ export function useColumns(
): ColumnsContext {
const mergedColumns = computed(() => {
const { columns } = props
if (columns && columns.length > 0) {
return mergeColumns(props.columns, config.columnBase, config.columnExpandable)
} else {
return mergeColumns(convertColumns(slots.default?.()), config.columnBase, config.columnExpandable)
}
return mergeColumns(
columns && columns.length > 0 ? columns : convertColumns(slots.default?.()),
config.columnBase,
config.columnExpandable,
config.columnSelectable,
)
})
const { flattedColumns, scrollBarColumn, flattedColumnsWithScrollBar } = useFlattedColumns(
mergedColumns,
Expand Down Expand Up @@ -101,7 +107,9 @@ export interface ColumnsContext {
mergedRows: ComputedRef<TableColumnMergedExtra[][]>
}

export type TableColumnMerged = TableColumnMergedBase | TableColumnMergedExpandable | TableColumnMergedSelectable
export type TableColumnMerged = (TableColumnMergedBase | TableColumnMergedExpandable | TableColumnMergedSelectable) & {
type?: 'selectable' | 'expandable' | 'scroll-bar'
}
export type TableColumnMergedExtra =
| TableColumnMergedBaseExtra
| TableColumnMergedExpandable
Expand All @@ -122,14 +130,16 @@ export interface TableColumnMergedBaseExtra extends TableColumnMergedBase {
export interface TableColumnMergedExpandable extends TableColumnMergedBaseExtra, TableColumnExpandable {
align: TableColumnAlign
key: VKey
icon: string | VNodeChild | ((options: { expanded?: boolean; record: unknown }) => string | VNodeChild)
icon: string | VNodeChild | ((options: { expanded: boolean; record: unknown }) => string | VNodeChild)
titleColSpan: number
}
export interface TableColumnMergedSelectable extends TableColumnMergedBaseExtra, TableColumnSelectable {
align: TableColumnAlign
key: VKey
multiple: boolean
titleColSpan: number

customCell?: (data: unknown) => VNodeChild
}

export interface TableColumnScrollBar {
Expand All @@ -145,8 +155,9 @@ function mergeColumns(
columns: TableColumn[],
baseConfig: TableColumnBaseConfig,
expandableConfig: TableColumnExpandableConfig,
selectableConfig: TableColumnSelectableConfig,
): TableColumnMerged[] {
return columns.map(column => convertColumn(column, baseConfig, expandableConfig))
return columns.map(column => convertColumn(column, baseConfig, expandableConfig, selectableConfig))
}

export function convertColumns(nodes: VNode[] | undefined): TableColumn[] {
Expand Down Expand Up @@ -185,6 +196,7 @@ function convertColumn(
column: TableColumn,
baseConfig: TableColumnBaseConfig,
expandableConfig: TableColumnExpandableConfig,
selectableConfig: TableColumnSelectableConfig,
): TableColumnMerged {
const { align = baseConfig.align } = column
const key = getColumnKey(column)
Expand All @@ -197,8 +209,8 @@ function convertColumn(
}
if (type === 'selectable') {
// The default value for `multiple` is true
const multiple = column.multiple ?? true
return { ...column, key, align, multiple }
const { multiple = true, showIndex = selectableConfig.showIndex } = column
return { ...column, key, align, multiple, showIndex } as TableColumnMerged
}
// for ProTable to support more type
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
Expand All @@ -214,7 +226,7 @@ function convertColumn(
newColumn.filterable = { ...baseConfig.filterable, ...filterable }
}
if (children?.length) {
newColumn.children = mergeColumns(children, baseConfig, expandableConfig)
newColumn.children = mergeColumns(children, baseConfig, expandableConfig, selectableConfig)
}
return newColumn
}
Expand Down
33 changes: 16 additions & 17 deletions packages/components/table/src/main/body/BodyCell.tsx
Expand Up @@ -173,26 +173,21 @@ function renderExpandableChildren(
expandable: ComputedRef<TableColumnMergedExpandable | undefined>,
prefixCls: string,
) {
const { icon, customIcon, indent } = expandable.value!
const { record, expanded, level = 0, disabled } = props
const style = {
marginLeft: indent ? convertCssPixel(level * indent) : undefined,
if (props.disabled) {
return undefined
}

const { icon, customIcon, indent } = expandable.value!
const { record, expanded, level = 0 } = props
const style = indent ? `margin-left: ${convertCssPixel(level * indent)}` : undefined

let iconNode: VNodeChild | null
if (disabled) {
iconNode = null
} else if (isFunction(customIcon)) {
iconNode = customIcon({ expanded: !!expanded, record })
} else if (isString(customIcon) && slots[customIcon]) {
iconNode = slots[customIcon]!({ expanded, record })
const iconRender = (isString(customIcon) ? slots[customIcon] : customIcon) ?? icon
if (isFunction(iconRender)) {
iconNode = iconRender({ expanded: !!expanded, record })
} else {
iconNode = isFunction(icon) ? icon({ expanded, record }) : icon
if (isString(iconNode)) {
iconNode = <IxIcon name={iconNode} rotate={expanded ? 90 : 0} />
}
iconNode = isString(iconRender) ? <IxIcon name={iconRender} rotate={expanded ? 90 : 0} /> : iconRender
}

return (
<button class={`${prefixCls}-expandable-trigger`} style={style} type="button" onClick={props.handleExpend}>
{iconNode}
Expand All @@ -206,9 +201,13 @@ function renderSelectableChildren(
selectable: ComputedRef<TableColumnMergedSelectable | undefined>,
onClick: (evt: Event) => void,
) {
const { selected: checked, indeterminate, disabled, handleSelect: onChange } = props
const { multiple, customCell } = selectable.value!
const { selected: checked, indeterminate, disabled, isHover, rowIndex, handleSelect: onChange } = props
const { showIndex, multiple, customCell } = selectable.value!
const customRender = isString(customCell) ? slots[customCell] : customCell
if (!customRender && !checked && !isHover && showIndex) {
const style = disabled ? 'cursor: not-allowed' : 'cursor: pointer'
return <span style={style}>{rowIndex}</span>
}
if (multiple) {
const checkboxProps = { checked, disabled, indeterminate, onChange, onClick }
return customRender ? customRender(checkboxProps) : <IxCheckbox {...checkboxProps}></IxCheckbox>
Expand Down

0 comments on commit 19e6f68

Please sign in to comment.