From bd02b83da43a3b32270c158fcc9c5a9abedb02b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=AA=97=E4=BD=A0=E6=98=AF=E5=B0=8F=E7=8C=AB=E5=92=AA?= Date: Fri, 7 Aug 2020 17:53:23 +0800 Subject: [PATCH] feat: Table new sticky prop (#25939) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: Table new sticky prop * add example * update snapshots * fix typo * fix example and improve less * rename to @zindex-table-fixed-column * fix compile error * fix header z-index * upgrade rc-table and add active style * improve less var * upgrade rc-table and remove hover style Co-authored-by: 二货机器人 --- components/style/themes/default.less | 5 +- .../__tests__/__snapshots__/demo.test.js.snap | 1071 +++++++++++++++++ components/table/demo/sticky.md | 100 ++ components/table/index.en-US.md | 53 +- components/table/index.zh-CN.md | 53 +- components/table/style/index.less | 34 +- package.json | 2 +- 7 files changed, 1263 insertions(+), 55 deletions(-) create mode 100644 components/table/demo/sticky.md diff --git a/components/style/themes/default.less b/components/style/themes/default.less index b175ddda6c..e519266b59 100644 --- a/components/style/themes/default.less +++ b/components/style/themes/default.less @@ -329,7 +329,7 @@ // z-index list, order by `z-index` @zindex-badge: auto; -@zindex-table-fixed: auto; +@zindex-table-fixed: 2; @zindex-affix: 10; @zindex-back-top: 10; @zindex-picker-panel: 10; @@ -610,6 +610,9 @@ @table-expand-icon-bg: @component-background; @table-selection-column-width: 60px; @table-selection-extra-right: 0; +// Sticky +@table-sticky-scroll-bar-bg: fade(#000, 35%); +@table-sticky-scroll-bar-radius: 4px; // Tag // -- diff --git a/components/table/__tests__/__snapshots__/demo.test.js.snap b/components/table/__tests__/__snapshots__/demo.test.js.snap index 3256f13669..7d320bdebe 100644 --- a/components/table/__tests__/__snapshots__/demo.test.js.snap +++ b/components/table/__tests__/__snapshots__/demo.test.js.snap @@ -15221,6 +15221,1077 @@ exports[`renders ./components/table/demo/size.md correctly 1`] = ` `; +exports[`renders ./components/table/demo/sticky.md correctly 1`] = ` +
+
+
+
+
+
+ + + + + + + + + + + + + + + + + +
+ Full Name + + Age + + Column 1 + + Column 2 + + Column 3 + + Column 4 + + Column 5 + + Column 6 + + Column 7 + + Column 8 + + Action +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Edrward 0 + + 32 + + London Park no. 0 + + London Park no. 0 + + London Park no. 0 + + London Park no. 0 + + London Park no. 0 + + London Park no. 0 + + London Park no. 0 + + London Park no. 0 + + + action + +
+ Edrward 1 + + 32 + + London Park no. 1 + + London Park no. 1 + + London Park no. 1 + + London Park no. 1 + + London Park no. 1 + + London Park no. 1 + + London Park no. 1 + + London Park no. 1 + + + action + +
+ Edrward 2 + + 32 + + London Park no. 2 + + London Park no. 2 + + London Park no. 2 + + London Park no. 2 + + London Park no. 2 + + London Park no. 2 + + London Park no. 2 + + London Park no. 2 + + + action + +
+ Edrward 3 + + 32 + + London Park no. 3 + + London Park no. 3 + + London Park no. 3 + + London Park no. 3 + + London Park no. 3 + + London Park no. 3 + + London Park no. 3 + + London Park no. 3 + + + action + +
+ Edrward 4 + + 32 + + London Park no. 4 + + London Park no. 4 + + London Park no. 4 + + London Park no. 4 + + London Park no. 4 + + London Park no. 4 + + London Park no. 4 + + London Park no. 4 + + + action + +
+ Edrward 5 + + 32 + + London Park no. 5 + + London Park no. 5 + + London Park no. 5 + + London Park no. 5 + + London Park no. 5 + + London Park no. 5 + + London Park no. 5 + + London Park no. 5 + + + action + +
+ Edrward 6 + + 32 + + London Park no. 6 + + London Park no. 6 + + London Park no. 6 + + London Park no. 6 + + London Park no. 6 + + London Park no. 6 + + London Park no. 6 + + London Park no. 6 + + + action + +
+ Edrward 7 + + 32 + + London Park no. 7 + + London Park no. 7 + + London Park no. 7 + + London Park no. 7 + + London Park no. 7 + + London Park no. 7 + + London Park no. 7 + + London Park no. 7 + + + action + +
+ Edrward 8 + + 32 + + London Park no. 8 + + London Park no. 8 + + London Park no. 8 + + London Park no. 8 + + London Park no. 8 + + London Park no. 8 + + London Park no. 8 + + London Park no. 8 + + + action + +
+ Edrward 9 + + 32 + + London Park no. 9 + + London Park no. 9 + + London Park no. 9 + + London Park no. 9 + + London Park no. 9 + + London Park no. 9 + + London Park no. 9 + + London Park no. 9 + + + action + +
+
+
+
+ +
+
+
+`; + exports[`renders ./components/table/demo/summary.md correctly 1`] = ` Array [
action, + }, +]; + +const data = []; +for (let i = 0; i < 100; i++) { + data.push({ + key: i, + name: `Edrward ${i}`, + age: 32, + address: `London Park no. ${i}`, + }); +} + +ReactDOM.render( + , + mountNode, +); +``` diff --git a/components/table/index.en-US.md b/components/table/index.en-US.md index 6187607cf8..bd88e63f38 100644 --- a/components/table/index.en-US.md +++ b/components/table/index.en-US.md @@ -58,32 +58,33 @@ const columns = [ ### Table -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| tableLayout | The [table-layout](https://developer.mozilla.org/en-US/docs/Web/CSS/table-layout) attribute of table element | - \| `auto` \| `fixed` | -
`fixed` when header/columns are fixed, or using `column.ellipsis` | -| bordered | Whether to show all table borders | boolean | false | -| columns | Columns of table | [ColumnsType](#Column)\[] | - | -| components | Override default table elements | [TableComponents](https://git.io/fANxz) | - | -| dataSource | Data record array to be displayed | object\[] | - | -| expandable | Config expandable content | [expandable](#expandable) | - | -| footer | Table footer renderer | function(currentPageData) | - | -| loading | Loading status of table | boolean \| [object](/components/spin/#API) ([more](https://github.com/ant-design/ant-design/issues/4544#issuecomment-271533135)) | false | -| locale | The i18n text including filter, sort, empty text, etc | object | filterConfirm: `Ok`
filterReset: `Reset`
emptyText: `No Data`
[Default](https://github.com/ant-design/ant-design/blob/4ad1ccac277782d7ed14f7e5d02d6346aae0db67/components/locale/default.tsx#L19) | -| pagination | Config of pagination. You can ref table pagination [config](#pagination) or full [`pagination`](/components/pagination/) document, hide it by setting it to `false` | object | - | -| rowClassName | Row's className | function(record, index): string | - | -| rowKey | Row's unique key, could be a string or function that returns a string | string \| function(record): string | `key` | -| rowSelection | Row selection [config](#rowSelection) | object | - | -| scroll | Whether the table can be scrollable, [config](#scroll) | object | - | -| showHeader | Whether to show table header | boolean | true | -| size | Size of table | `default` \| `middle` \| `small` | `default` | -| summary | Summary content | (currentData) => ReactNode | - | -| title | Table title renderer | function(currentPageData) | - | -| onChange | Callback executed when pagination, filters or sorter is changed | function(pagination, filters, sorter, extra: { currentDataSource: [], action: `paginate` \| `sort` \| `filter` }) | - | -| onHeaderRow | Set props on per header row | function(column, index) | - | -| onRow | Set props on per row | function(record, index) | - | -| getPopupContainer | The render container of dropdowns in table | (triggerNode) => HTMLElement | () => TableHtmlElement | -| sortDirections | Supported sort way, could be `ascend`, `descend` | Array | \[`ascend`, `descend`] | -| showSorterTooltip | The header show next sorter direction tooltip | boolean | true | +| Property | Description | Type | Default | Version | +| --- | --- | --- | --- | --- | +| tableLayout | The [table-layout](https://developer.mozilla.org/en-US/docs/Web/CSS/table-layout) attribute of table element | - \| `auto` \| `fixed` | -
`fixed` when header/columns are fixed, or using `column.ellipsis` | | +| bordered | Whether to show all table borders | boolean | false | | +| columns | Columns of table | [ColumnsType](#Column)\[] | - | | +| components | Override default table elements | [TableComponents](https://git.io/fANxz) | - | | +| dataSource | Data record array to be displayed | object\[] | - | | +| expandable | Config expandable content | [expandable](#expandable) | - | | +| footer | Table footer renderer | function(currentPageData) | - | | +| loading | Loading status of table | boolean \| [object](/components/spin/#API) ([more](https://github.com/ant-design/ant-design/issues/4544#issuecomment-271533135)) | false | | +| locale | The i18n text including filter, sort, empty text, etc | object | filterConfirm: `Ok`
filterReset: `Reset`
emptyText: `No Data`
[Default](https://github.com/ant-design/ant-design/blob/4ad1ccac277782d7ed14f7e5d02d6346aae0db67/components/locale/default.tsx#L19) | | +| pagination | Config of pagination. You can ref table pagination [config](#pagination) or full [`pagination`](/components/pagination/) document, hide it by setting it to `false` | object | - | | +| rowClassName | Row's className | function(record, index): string | - | | +| rowKey | Row's unique key, could be a string or function that returns a string | string \| function(record): string | `key` | | +| rowSelection | Row selection [config](#rowSelection) | object | - | | +| scroll | Whether the table can be scrollable, [config](#scroll) | object | - | | +| showHeader | Whether to show table header | boolean | true | | +| size | Size of table | `default` \| `middle` \| `small` | `default` | | +| summary | Summary content | (currentData) => ReactNode | - | | +| title | Table title renderer | function(currentPageData) | - | | +| onChange | Callback executed when pagination, filters or sorter is changed | function(pagination, filters, sorter, extra: { currentDataSource: [], action: `paginate` \| `sort` \| `filter` }) | - | | +| onHeaderRow | Set props on per header row | function(column, index) | - | | +| onRow | Set props on per row | function(record, index) | - | | +| getPopupContainer | The render container of dropdowns in table | (triggerNode) => HTMLElement | () => TableHtmlElement | | +| sortDirections | Supported sort way, could be `ascend`, `descend` | Array | \[`ascend`, `descend`] | | +| showSorterTooltip | The header show next sorter direction tooltip | boolean | true | | +| sticky | Set sticky header and scroll bar | boolean \| `{offsetHeader?: number, offsetScroll?: number}` | - | 4.6.0 | #### onRow usage diff --git a/components/table/index.zh-CN.md b/components/table/index.zh-CN.md index 358e81a53a..5fa7dd0658 100644 --- a/components/table/index.zh-CN.md +++ b/components/table/index.zh-CN.md @@ -65,32 +65,33 @@ const columns = [ ### Table -| 参数 | 说明 | 类型 | 默认值 | -| --- | --- | --- | --- | -| tableLayout | 表格元素的 [table-layout](https://developer.mozilla.org/zh-CN/docs/Web/CSS/table-layout) 属性,设为 `fixed` 表示内容不会影响列的布局 | - \| `auto` \| `fixed` | 无
固定表头/列或使用了 `column.ellipsis` 时,默认值为 `fixed` | -| bordered | 是否展示外边框和列边框 | boolean | false | -| columns | 表格列的配置描述,具体项见下表 | [ColumnsType](#Column)\[] | - | -| components | 覆盖默认的 table 元素 | [TableComponents](https://git.io/fANxz) | - | -| dataSource | 数据数组 | object\[] | - | -| expandable | 配置展开属性 | [expandable](#expandable) | - | -| footer | 表格尾部 | function(currentPageData) | - | -| loading | 页面是否加载中 | boolean \| [object](/components/spin/#API) ([更多](https://github.com/ant-design/ant-design/issues/4544#issuecomment-271533135)) | false | -| locale | 默认文案设置,目前包括排序、过滤、空数据文案 | object | filterConfirm: `确定`
filterReset: `重置`
emptyText: `暂无数据`
[默认值](https://github.com/ant-design/ant-design/blob/4ad1ccac277782d7ed14f7e5d02d6346aae0db67/components/locale/default.tsx#L19) | -| pagination | 分页器,参考[配置项](#pagination)或 [pagination](/components/pagination/) 文档,设为 false 时不展示和进行分页 | object | - | -| rowClassName | 表格行的类名 | function(record, index): string | - | -| rowKey | 表格行 key 的取值,可以是字符串或一个函数 | string \| function(record): string | `key` | -| rowSelection | 表格行是否可选择,[配置项](#rowSelection) | object | - | -| scroll | 表格是否可滚动,也可以指定滚动区域的宽、高,[配置项](#scroll) | object | - | -| showHeader | 是否显示表头 | boolean | true | -| size | 表格大小 | `default` \| `middle` \| `small` | default | -| summary | 总结栏 | (currentData) => ReactNode | - | -| title | 表格标题 | function(currentPageData) | - | -| onChange | 分页、排序、筛选变化时触发 | function(pagination, filters, sorter, extra: { currentDataSource: [], action: `paginate` \| `sort` \| `filter` }) | - | -| onHeaderRow | 设置头部行属性 | function(column, index) | - | -| onRow | 设置行属性 | function(record, index) | - | -| getPopupContainer | 设置表格内各类浮层的渲染节点,如筛选菜单 | (triggerNode) => HTMLElement | () => TableHtmlElement | -| sortDirections | 支持的排序方式,取值为 `ascend` `descend` | Array | \[`ascend`, `descend`] | -| showSorterTooltip | 表头是否显示下一次排序的 tooltip 提示 | boolean | true | +| 参数 | 说明 | 类型 | 默认值 | 版本 | +| --- | --- | --- | --- | --- | +| tableLayout | 表格元素的 [table-layout](https://developer.mozilla.org/zh-CN/docs/Web/CSS/table-layout) 属性,设为 `fixed` 表示内容不会影响列的布局 | - \| `auto` \| `fixed` | 无
固定表头/列或使用了 `column.ellipsis` 时,默认值为 `fixed` | | +| bordered | 是否展示外边框和列边框 | boolean | false | | +| columns | 表格列的配置描述,具体项见下表 | [ColumnsType](#Column)\[] | - | | +| components | 覆盖默认的 table 元素 | [TableComponents](https://git.io/fANxz) | - | | +| dataSource | 数据数组 | object\[] | - | | +| expandable | 配置展开属性 | [expandable](#expandable) | - | | +| footer | 表格尾部 | function(currentPageData) | - | | +| loading | 页面是否加载中 | boolean \| [object](/components/spin/#API) ([更多](https://github.com/ant-design/ant-design/issues/4544#issuecomment-271533135)) | false | | +| locale | 默认文案设置,目前包括排序、过滤、空数据文案 | object | filterConfirm: `确定`
filterReset: `重置`
emptyText: `暂无数据`
[默认值](https://github.com/ant-design/ant-design/blob/4ad1ccac277782d7ed14f7e5d02d6346aae0db67/components/locale/default.tsx#L19) | | +| pagination | 分页器,参考[配置项](#pagination)或 [pagination](/components/pagination/) 文档,设为 false 时不展示和进行分页 | object | - | | +| rowClassName | 表格行的类名 | function(record, index): string | - | | +| rowKey | 表格行 key 的取值,可以是字符串或一个函数 | string \| function(record): string | `key` | | +| rowSelection | 表格行是否可选择,[配置项](#rowSelection) | object | - | | +| scroll | 表格是否可滚动,也可以指定滚动区域的宽、高,[配置项](#scroll) | object | - | | +| showHeader | 是否显示表头 | boolean | true | | +| size | 表格大小 | `default` \| `middle` \| `small` | default | | +| summary | 总结栏 | (currentData) => ReactNode | - | | +| title | 表格标题 | function(currentPageData) | - | | +| onChange | 分页、排序、筛选变化时触发 | function(pagination, filters, sorter, extra: { currentDataSource: [], action: `paginate` \| `sort` \| `filter` }) | - | | +| onHeaderRow | 设置头部行属性 | function(column, index) | - | | +| onRow | 设置行属性 | function(record, index) | - | | +| getPopupContainer | 设置表格内各类浮层的渲染节点,如筛选菜单 | (triggerNode) => HTMLElement | () => TableHtmlElement | | +| sortDirections | 支持的排序方式,取值为 `ascend` `descend` | Array | \[`ascend`, `descend`] | | +| showSorterTooltip | 表头是否显示下一次排序的 tooltip 提示 | boolean | true | | +| sticky | 设置粘性头部和滚动条 | boolean \| `{offsetHeader?: number, offsetScroll?: number}` | - | 4.6.0 | #### onRow 用法 diff --git a/components/table/style/index.less b/components/table/style/index.less index b002e9ef92..b12e70af67 100644 --- a/components/table/style/index.less +++ b/components/table/style/index.less @@ -9,6 +9,8 @@ @table-header-icon-color: #bfbfbf; @table-header-icon-color-hover: darken(@table-header-icon-color, 10%); @table-header-sort-active-filter-bg: lighten(@table-header-sort-active-bg, 2%); +@table-sticky-zindex: @zindex-table-fixed + 1; +@table-sticky-scroll-bar-active-bg: fade(@table-sticky-scroll-bar-bg, 80%); .@{table-prefix-cls}-wrapper { max-width: 100%; @@ -516,7 +518,7 @@ &-cell-fix-right { position: -webkit-sticky !important; position: sticky !important; - z-index: 2; + z-index: @zindex-table-fixed; background: @table-bg; } @@ -595,6 +597,36 @@ box-shadow: inset -10px 0 8px -8px darken(@shadow-color, 5%); } } + &-sticky { + &-header { + position: sticky; + z-index: @table-sticky-zindex; + } + &-scroll { + position: fixed; + bottom: 0; + z-index: @table-sticky-zindex; + display: flex; + align-items: center; + background: lighten(@border-color-split, 80%); + border-top: 1px solid @border-color-split; + opacity: 0.6; + &:hover { + transform-origin: center bottom; + } + &-bar { + height: 8px; + background-color: @table-sticky-scroll-bar-bg; + border-radius: @table-sticky-scroll-bar-radius; + &:hover { + background-color: @table-sticky-scroll-bar-active-bg; + } + &-active { + background-color: @table-sticky-scroll-bar-active-bg; + } + } + } + } } @media all and (-ms-high-contrast: none) { diff --git a/package.json b/package.json index ddcbfa5954..7dcae97af9 100644 --- a/package.json +++ b/package.json @@ -138,7 +138,7 @@ "rc-slider": "~9.3.0", "rc-steps": "~4.1.0", "rc-switch": "~3.2.0", - "rc-table": "~7.8.0", + "rc-table": "~7.9.2", "rc-tabs": "~11.6.0", "rc-textarea": "~0.3.0", "rc-tooltip": "~4.2.0",