Skip to content

Commit

Permalink
feat(pro: table): add IxProTable and IxProTableLayoutTool (#936)
Browse files Browse the repository at this point in the history
  • Loading branch information
danranVm authored May 30, 2022
1 parent 3e91b33 commit 688627f
Show file tree
Hide file tree
Showing 45 changed files with 1,517 additions and 85 deletions.
Original file line number Diff line number Diff line change
@@ -1 +1 @@
@overlay-arrow-size: 6px;
@overlay-arrow-size: 8px;
2 changes: 1 addition & 1 deletion packages/components/header/style/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
font-size: @header-suffix-font-size;
padding: @header-suffix-padding;

&:hover {
.@{icon-prefix}:hover {
color: @header-suffix-active-color;
}
}
Expand Down
5 changes: 4 additions & 1 deletion packages/components/space/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ export type SpaceSize = 'sm' | 'md' | 'lg'
export const spaceProps = {
align: IxPropTypes.oneOf<SpaceAlign>(['start', 'center', 'end', 'baseline', 'stretch']),
block: IxPropTypes.bool,
/**
* @deprecated please use `vertical` instead'
*/
direction: IxPropTypes.oneOf<SpaceDirection>(['vertical', 'horizontal']),
justify: IxPropTypes.oneOf<SpaceJustify>(['start', 'center', 'end', 'space-around', 'space-between']),
size: IxPropTypes.oneOfType([Number, String, IxPropTypes.array<string | number>()]),
Expand All @@ -28,6 +31,6 @@ export const spaceProps = {
}

export type SpaceProps = ExtractInnerPropTypes<typeof spaceProps>
export type SpacePublicProps = ExtractPublicPropTypes<typeof spaceProps>
export type SpacePublicProps = Omit<ExtractPublicPropTypes<typeof spaceProps>, 'direction'>
export type SpaceComponent = DefineComponent<Omit<HTMLAttributes, keyof SpacePublicProps> & SpacePublicProps>
export type SpaceInstance = InstanceType<DefineComponent<SpaceProps>>
24 changes: 8 additions & 16 deletions packages/components/table/docs/Index.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ order: 0
| `borderless` | 是否无边框 | `boolean` | `true` || - |
| `childrenKey` | 指定树形结构的 `key` | `string` | `children` || - |
| `columns` | 表格列的配置描述 | `TableColumn[]` | - | - | 参见[TableColumn](#TableColumn) |
| `customAdditional` | 自定义表格行和单元格的额外属性 | `TableCustomAdditional[]` | - | - | 参见[TableCustomAdditional](#TableCustomAdditional) |
| `customAdditional` | 自定义表格行和单元格的额外属性 | `TableCustomAdditional` | - | - | 参见[TableCustomAdditional](#TableCustomAdditional) |
| `dataSource` | 表格数据数组 | `object[]` | - | - | - |
| `ellipsis` | 超过宽度将自动省略 | `boolean` | `false` | - | - |
| `empty` | 空数据时的内容 | `string \| EmptyProps \| #empty` | - | - | - |
Expand All @@ -47,60 +47,52 @@ export type TableColumn<T = any, V = any> =
| TableColumnSelectable<T>
```
##### TableColumnCommon
列配置的公用属性。
#### 通用配置。
| 名称 | 说明 | 类型 | 默认值 | 全局配置 | 备注 |
| --- | --- | --- | --- | --- | --- |
| `align` | 文本对齐方式 | `'start' \| 'center' \| 'end'` | `'start'` | ✅ | - |
| `colSpan` | 计算列的 `colSpan` | `(record: T, rowIndex: number) => number` | - | - | 返回为 `0` 时,不渲染, 通常用于列合并 |
| `fixed` | 是否固定 | `'start' \| 'end'` | - | - | - |
| `responsive` | 响应式 breakpoint 配置列表 | `BreakpointKey[]` | - | - | - |
| `rowSpan` | 计算列的 `rowSpan` | `(record: T, rowIndex: number) => number` | - | - | 返回为 `0` 时,不渲染, 通常用于行合并 |
| `titleColSpan` | 设置表头的 `colSpan` | - | - | - | 为 `0` 时,不渲染 |
| `width` | 列宽度 | `string \| number` | - | - | - |
##### TableColumnBase
普通列配置的属性,继承 `TableColumnCommon`
普通列配置的属性。
| 名称 | 说明 | 类型 | 默认值 | 全局配置 | 备注 |
| --- | --- | --- | --- | --- | --- |
| `key` | 表格列 `key` 的取值 | `string \| number` | - | - | 默认为 `dataKey` 或者 `type` |
| `children` | 子列的配置项 | `TableColumnBase[]` | - | - | 用于设置分组表头 |
| `dataKey` | 数据在数据项中对应的路径 | `string \| string[]` | - | - | 支持通过数组查询嵌套路径 |
| `ellipsis` | 超过宽度将自动省略 | `boolean` | - | - | 优先级高于 `props` 中的 `ellipsis` |
| `key` | 表格列 `key` 的取值 | `string \| number` | - | - | 默认为 `dataKey` |
| `sortable` | 是否可排序, 参见[TableColumnSortable](#TableColumnSortable) | `TableColumnSortable` | - | - | - |
| `title` | 列头的文本 | `string` | - | - | - |
| `customCell` | 自定义单元格内容 | `string \| ((data: { value: V; record: T; rowIndex: number }) => VNodeChild)` | - | - | 类型为 `string` 时,对应插槽名 |
| `customTitle` | 自定义表头标题 | `string \| ((data: { title?: string }) => VNodeChild)` | - | - | 类型为 `string` 时,对应插槽名 |
##### TableColumnExpandable
可展开列配置的属性继承 `TableColumnBase`
可展开列配置的属性, 继承 `TableColumnBase`
| 名称 | 说明 | 类型 | 默认值 | 全局配置 | 备注 |
| --- | --- | --- | --- | --- | --- |
| `type` | 列类型 | `'expandable'` | - | - | 必填 |
| `dataKey` | 数据在数据项中对应的路径 | `string \| string[]` | - | - | 通常在树形表格时设置 |
| `disabled` | 设置是否允许行展开 | `(record:T) => boolean` | - | - | - |
| `ellipsis` | 超过宽度将自动省略 | `boolean` | `false` | - | 通常在树形表格时设置 |
| `key` | 表格列 `key` 的取值 | `string \| number` | - | - | 默认为 `dataKey`,通常在树形表格时设置 |
| `icon` | 展开按钮图标 | `string` | `'right'` | ✅ | - |
| `indent` | 展示树形数据时,每层缩进的宽度 | `number` | `12` | - | - |
| `title` | 列头的文本 | `string` | - | - | 通常在树形表格时设置 |
| `trigger` | 不通过图标,触发行展开的方式 | `'click' \| 'doubleClick'` | - | - | - |
| `onChange` | 展开状态发生变化时触发 | `(expendedRowKeys: (string \| number)[], expendedRecords: T[]) => void` | - | - | - |
| `onExpand` | 点击展开图标,或通过 `trigger` 触发 | `(expanded: boolean, record: T) => void` | - | - | - |
| `customCell` | 自定义单元格内容 | `string \| ((data: { value: V; record: T; rowIndex: number }) => VNodeChild)` | - | - | 类型为 `string` 时,对应插槽名 |
| `customTitle` | 自定义表头标题 | `string \| ((data: { title?: string }) => VNodeChild)` | - | - | 类型为 `string` 时,对应插槽名 |
| `customExpand` | 自定义展开内容 | `string \| ((data: { record: T; rowIndex: number }) => VNodeChild)` | - | - | 类型为 `string` 时,对应插槽名 |
| `customIcon` | 自定义表头标题 | `string \| ((data: { expanded: boolean; record: T }) => VNodeChild)` | - | - | 类型为 `string` 时,对应插槽名 |
| `customIcon` | 自定义展开图标 | `string \| ((data: { expanded: boolean; record: T }) => VNodeChild)` | - | - | 类型为 `string` 时,对应插槽名 |
##### TableColumnSelectable
可选择列配置的属性,继承 `TableColumnCommon`
可选择列配置的属性
| 名称 | 说明 | 类型 | 默认值 | 全局配置 | 备注 |
| --- | --- | --- | --- | --- | --- |
Expand Down
10 changes: 8 additions & 2 deletions packages/components/table/src/composables/useColumns.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,14 +185,20 @@ function convertColumn(
const key = getColumnKey(column)

if ('type' in column) {
if (column.type === 'expandable') {
const { type } = column
if (type === 'expandable') {
const { icon = expandableConfig.icon } = column
return { ...column, key, align, icon }
} else {
}
if (type === 'selectable') {
// The default value for `multiple` is true
const multiple = column.multiple ?? true
return { ...column, key, align, multiple }
}
// for ProTable to support more type
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
return { ...column, key, align }
} else {
const { sortable, filterable, children } = column
const newColumn = { ...column, key, align }
Expand Down
3 changes: 3 additions & 0 deletions packages/components/table/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ export interface TableColumnCommon<T = any> {
colSpan?: (record: T, rowIndex: number) => number
rowSpan?: (record: T, rowIndex: number) => number
fixed?: TableColumnFixed
/**
* @deprecated
*/
responsive?: BreakpointKey[]
titleColSpan?: number
width?: string | number
Expand Down
4 changes: 2 additions & 2 deletions packages/components/tree/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ export const treeNodeProps = {
isLeaf: IxPropTypes.bool.isRequired,
isFirst: IxPropTypes.bool.isRequired,
isLast: IxPropTypes.bool.isRequired,
label: IxPropTypes.string.isRequired,
label: IxPropTypes.string,
level: IxPropTypes.number.isRequired,
rawNode: IxPropTypes.object<TreeNode>().isRequired,
expanded: IxPropTypes.bool.isRequired,
Expand Down Expand Up @@ -187,7 +187,7 @@ export const treeNodeExpandProps = {
export const treeNodeContentProps = {
disabled: IxPropTypes.bool,
nodeKey: IxPropTypes.oneOfType([String, Number, Symbol]).isRequired,
label: IxPropTypes.string.isRequired,
label: IxPropTypes.string,
rawNode: IxPropTypes.object<TreeNode>().isRequired,
selected: IxPropTypes.bool,
}
26 changes: 15 additions & 11 deletions packages/pro/config/src/defaultConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,24 @@
* found in the LICENSE file at https://github.com/IDuxFE/idux/blob/main/LICENSE
*/

import type { CommonConfig, GlobalConfig, ProTree } from './types'

import { zhCN } from '@idux/pro/locales'

const common: CommonConfig = { prefixCls: 'ix-pro' }

const proTree: ProTree = {
clearIcon: 'close-circle',
collapseIcon: ['collapse', 'uncollapse'],
}
import { type ProGlobalConfig } from './types'

export const defaultConfig: GlobalConfig = {
common,
export const defaultConfig: ProGlobalConfig = {
common: { prefixCls: 'ix-pro' },
locale: zhCN,

proTree,
table: {
columnIndexable: {
width: 40,
align: 'center',
customCell: ({ rowIndex }) => rowIndex,
},
toolbar: ['layout'],
},
tree: {
clearIcon: 'close-circle',
collapseIcon: ['collapse', 'uncollapse'],
},
}
39 changes: 20 additions & 19 deletions packages/pro/config/src/globalConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,21 @@
* found in the LICENSE file at https://github.com/IDuxFE/idux/blob/main/LICENSE
*/

import type { GlobalConfig, GlobalConfigKey } from './types'
import type { App, Plugin } from 'vue'

import { inject, provide, reactive } from 'vue'
import { type App, type Plugin, inject, provide, reactive } from 'vue'

import { cloneDeep, merge } from 'lodash-es'

import { defaultConfig } from './defaultConfig'
import { type ProGlobalConfig, type ProGlobalConfigKey } from './types'

const tokens: [GlobalConfigKey, symbol][] = Object.keys(defaultConfig).map(key => [key as GlobalConfigKey, Symbol(key)])
const tokenMap = new Map<GlobalConfigKey, symbol>(tokens)
const tokens: [ProGlobalConfigKey, symbol][] = Object.keys(defaultConfig).map(key => [
key as ProGlobalConfigKey,
Symbol(key),
])
const tokenMap = new Map<ProGlobalConfigKey, symbol>(tokens)

export type DeepPartialGlobalConfig = {
[K in GlobalConfigKey]?: Partial<GlobalConfig[K]>
[K in ProGlobalConfigKey]?: Partial<ProGlobalConfig[K]>
}

/**
Expand All @@ -28,7 +29,7 @@ export type DeepPartialGlobalConfig = {
*/
export const createGlobalConfig = (config: DeepPartialGlobalConfig): Plugin => {
const install = (app: App): void => {
const compNames = Object.keys(config) as GlobalConfigKey[]
const compNames = Object.keys(config) as ProGlobalConfigKey[]
compNames.forEach(compName => {
const token = tokenMap.get(compName)!
const currConfig = defaultConfig[compName]
Expand All @@ -40,25 +41,25 @@ export const createGlobalConfig = (config: DeepPartialGlobalConfig): Plugin => {
return { install }
}

export function useGlobalConfig<T extends GlobalConfigKey>(compName: T): Readonly<GlobalConfig[T]>
export function useGlobalConfig<T extends GlobalConfigKey>(
export function useGlobalConfig<T extends ProGlobalConfigKey>(compName: T): Readonly<ProGlobalConfig[T]>
export function useGlobalConfig<T extends ProGlobalConfigKey>(
compName: T,
config: Partial<GlobalConfig[T]>,
): [Readonly<GlobalConfig[T]>, (config: Partial<GlobalConfig[T]>) => void]
export function useGlobalConfig<T extends GlobalConfigKey>(
config: Partial<ProGlobalConfig[T]>,
): [Readonly<ProGlobalConfig[T]>, (config: Partial<ProGlobalConfig[T]>) => void]
export function useGlobalConfig<T extends ProGlobalConfigKey>(
compName: T,
config?: Partial<GlobalConfig[T]>,
): Readonly<GlobalConfig[T]> | [Readonly<GlobalConfig[T]>, (config: Partial<GlobalConfig[T]>) => void] {
config?: Partial<ProGlobalConfig[T]>,
): Readonly<ProGlobalConfig[T]> | [Readonly<ProGlobalConfig[T]>, (config: Partial<ProGlobalConfig[T]>) => void] {
const token = tokenMap.get(compName)!
const currConfig = inject<GlobalConfig[T]>(token, defaultConfig[compName])
const currConfig = inject<ProGlobalConfig[T]>(token, defaultConfig[compName])

if (!config) {
return currConfig as Readonly<GlobalConfig[T]>
return currConfig as Readonly<ProGlobalConfig[T]>
}

const cloneConfig = reactive(merge(cloneDeep(currConfig), config)) as GlobalConfig[T]
const cloneConfig = reactive(merge(cloneDeep(currConfig), config)) as ProGlobalConfig[T]

provide(token, cloneConfig)

return [cloneConfig, (config: Partial<GlobalConfig[T]>) => merge(cloneConfig, config)]
return [cloneConfig, (config: Partial<ProGlobalConfig[T]>) => merge(cloneConfig, config)]
}
33 changes: 19 additions & 14 deletions packages/pro/config/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,29 @@
* found in the LICENSE file at https://github.com/IDuxFE/idux/blob/main/LICENSE
*/

import type { Locale } from '@idux/pro/locales'
import type { ProLocale } from '@idux/pro/locales'
import type { ProTableColumnIndexable, ProTableToolbar } from '@idux/pro/table'

// Common
export interface CommonConfig {
prefixCls: string
}
export interface ProGlobalConfig {
common: ProCommonConfig
locale: ProLocale

export interface ProTree {
clearIcon: string
collapseIcon: [string, string]
table: ProTableConfig
tree: ProTreeConfig
}

export interface GlobalConfig {
// Common
common: CommonConfig
locale: Locale
export type ProGlobalConfigKey = keyof ProGlobalConfig

export interface ProCommonConfig {
prefixCls: string
}

proTree: ProTree
export interface ProTableConfig {
columnIndexable: Omit<ProTableColumnIndexable, 'type'>
toolbar: ProTableToolbar[]
}

export type GlobalConfigKey = keyof GlobalConfig
export interface ProTreeConfig {
clearIcon: string
collapseIcon: [string, string]
}
2 changes: 1 addition & 1 deletion packages/pro/default.less
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
@import './style/core/default.less';

@import './layout/style/themes/default.less';

@import './table/style/themes/default.less';
@import './transfer/style/themes/default.less';
@import './tree/style/themes/default.less';
4 changes: 3 additions & 1 deletion packages/pro/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@
import type { App, Directive } from 'vue'

import { IxProLayout, IxProLayoutSiderTrigger } from '@idux/pro/layout'
import { IxProTable, IxProTableLayoutTool } from '@idux/pro/table'
import { IxProTransfer } from '@idux/pro/transfer'
import { IxProTree } from '@idux/pro/tree'
import { version } from '@idux/pro/version'

const directives: Record<string, Directive> = {}

const components = [IxProLayout, IxProLayoutSiderTrigger, IxProTransfer, IxProTree]
const components = [IxProLayout, IxProLayoutSiderTrigger, IxProTable, IxProTableLayoutTool, IxProTransfer, IxProTree]

const install = (app: App): void => {
components.forEach(component => {
Expand All @@ -32,6 +33,7 @@ export default installer
export { install }

export * from '@idux/pro/layout'
export * from '@idux/pro/table'
export * from '@idux/pro/transfer'
export * from '@idux/pro/tree'
export * from '@idux/pro/version'
26 changes: 23 additions & 3 deletions packages/pro/locales/src/langs/en-US.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,32 @@
* found in the LICENSE file at https://github.com/IDuxFE/idux/blob/main/LICENSE
*/

import type { Locale } from '../types'
import { type ProLocale } from '../types'

/* eslint-disable camelcase */
const enUS: Locale = {
const enUS: ProLocale = {
type: 'en-US',
proTree: {

table: {
layout: {
title: 'Layout settings',
sm: 'Compact',
md: 'Medium',
lg: 'Relaxed',
all: 'All field',
reset: 'Reset',
indexable: 'Index column',
expandable: 'Expand column',
selectable: 'Select column',
startPin: 'Pin to start',
endPin: 'Pin to end',
noPin: 'Unpinned',
startPinTitle: 'Fixed the start',
endPinTitle: 'Fixed the end',
noPinTitle: 'Not Fixed',
},
},
tree: {
expandAll: 'Expand all',
collapseAll: 'Collapse all',
},
Expand Down
Loading

0 comments on commit 688627f

Please sign in to comment.