diff --git a/assets/index.less b/assets/index.less index 6403c5410..2fde62b95 100644 --- a/assets/index.less +++ b/assets/index.less @@ -17,6 +17,10 @@ .@{tablePrefixCls}-scroll { overflow: auto; + table { + width: auto; + min-width: 100%; + } } .@{tablePrefixCls}-header { @@ -92,12 +96,13 @@ th, td { padding: @vertical-padding @horizontal-padding; + white-space: nowrap; } } .@{tablePrefixCls} { &-expand-icon-col { - width: 10px; + width: 34px; } &-row, &-expanded-row { &-expand-icon { diff --git a/examples/fixedColumnsWhenResize.html b/examples/fixedColumnsWhenResize.html new file mode 100644 index 000000000..e69de29bb diff --git a/examples/fixedColumnsWhenResize.js b/examples/fixedColumnsWhenResize.js new file mode 100644 index 000000000..46b36fe45 --- /dev/null +++ b/examples/fixedColumnsWhenResize.js @@ -0,0 +1,45 @@ +/* eslint-disable no-console,func-names,react/no-multi-comp */ +const React = require('react'); +const ReactDOM = require('react-dom'); +const Table = require('rc-table'); +require('rc-table/assets/index.less'); + +const columns = [ + { title: 'title1', dataIndex: 'a', key: 'a', width: 100, fixed: 'left' }, + { title: 'title2', dataIndex: 'b', key: 'b', width: 100, fixed: 'left' }, + { title: 'title3', dataIndex: 'c', key: 'c' }, + { title: 'title4', dataIndex: 'b', key: 'd' }, + { title: 'title5', dataIndex: 'b', key: 'e' }, + { title: 'title6', dataIndex: 'b', key: 'f' }, + { title:
title7


Hello world!
, dataIndex: 'b', key: 'g' }, + { title: 'title8', dataIndex: 'b', key: 'h' }, + { title: 'title9', dataIndex: 'b', key: 'i' }, + { title: 'title10', dataIndex: 'b', key: 'j' }, + { title: 'title11', dataIndex: 'b', key: 'k' }, + { title: 'title12', dataIndex: 'b', key: 'l', width: 100, fixed: 'right' }, +]; + +const data = [ + { a: '123', b: 'xxxxxxxx', d: 3, key: '1' }, + { a: 'cdd', b: 'edd12221', d: 3, key: '2' }, + { a: '133', c: 'edd12221', d: 2, key: '3' }, + { a: '133', c: 'edd12221', d: 2, key: '4' }, + { a: '133', c: 'edd12221', d: 2, key: '5' }, + { a: '133', c: 'edd12221', d: 2, key: '6' }, + { a: '133', c: 'edd12221', d: 2, key: '7' }, + { a: '133', c: 'edd12221', d: 2, key: '8' }, + { a: '133', c: 'edd12221', d: 2, key: '9' }, +]; + +ReactDOM.render( +
+

See fixed columns when you resize window

+ record.title} + expandIconAsCell + scroll={{ x: 800 }} + data={data} + /> + +, document.getElementById('__react-content')); diff --git a/src/Table.jsx b/src/Table.jsx index b4dfd86de..c48e50feb 100644 --- a/src/Table.jsx +++ b/src/Table.jsx @@ -93,10 +93,10 @@ export default class Table extends React.Component { componentDidMount() { if (this.columnManager.isAnyColumnsFixed()) { - this.syncFixedTableRowHeight(); - this.debouncedSyncFixedTableRowHeight = debounce(this.syncFixedTableRowHeight, 150); + this.handleWindowResize(); + this.debouncedWindowResize = debounce(this.handleWindowResize, 150); this.resizeEvent = addEventListener( - window, 'resize', this.debouncedSyncFixedTableRowHeight + window, 'resize', this.debouncedWindowResize ); } } @@ -116,7 +116,7 @@ export default class Table extends React.Component { componentDidUpdate(prevProps) { if (this.columnManager.isAnyColumnsFixed()) { - this.syncFixedTableRowHeight(); + this.handleWindowResize(); } // when table changes to empty, reset scrollLeft if (prevProps.data.length > 0 && this.props.data.length === 0 && this.hasScrollX()) { @@ -128,8 +128,8 @@ export default class Table extends React.Component { if (this.resizeEvent) { this.resizeEvent.remove(); } - if (this.debouncedSyncFixedTableRowHeight) { - this.debouncedSyncFixedTableRowHeight.cancel(); + if (this.debouncedWindowResize) { + this.debouncedWindowResize.cancel(); } } @@ -576,12 +576,41 @@ export default class Table extends React.Component { this.scrollPosition = position; if (this.tableNode) { const { prefixCls } = this.props; - classes(this.tableNode) - .remove(new RegExp(`^${prefixCls}-scroll-position-.+$`)) - .add(`${prefixCls}-scroll-position-${position}`); + if (position === 'both') { + classes(this.tableNode) + .remove(new RegExp(`^${prefixCls}-scroll-position-.+$`)) + .add(`${prefixCls}-scroll-position-left`) + .add(`${prefixCls}-scroll-position-right`); + } else { + classes(this.tableNode) + .remove(new RegExp(`^${prefixCls}-scroll-position-.+$`)) + .add(`${prefixCls}-scroll-position-${position}`); + } + } + } + + setScrollPositionClassName(target) { + const node = target || this.refs.bodyTable; + const scrollToLeft = node.scrollLeft === 0; + const scrollToRight = node.scrollLeft + 1 >= + node.children[0].getBoundingClientRect().width - + node.getBoundingClientRect().width; + if (scrollToLeft && scrollToRight) { + this.setScrollPosition('both'); + } else if (scrollToLeft) { + this.setScrollPosition('left'); + } else if (scrollToRight) { + this.setScrollPosition('right'); + } else if (this.scrollPosition !== 'middle') { + this.setScrollPosition('middle'); } } + handleWindowResize = () => { + this.syncFixedTableRowHeight(); + this.setScrollPositionClassName(); + } + syncFixedTableRowHeight = () => { const tableRect = this.tableNode.getBoundingClientRect(); // If tableNode's height less than 0, suppose it is hidden and don't recalculate rowHeight. @@ -653,15 +682,7 @@ export default class Table extends React.Component { } else if (e.target === headTable && bodyTable) { bodyTable.scrollLeft = e.target.scrollLeft; } - if (e.target.scrollLeft === 0) { - this.setScrollPosition('left'); - } else if (e.target.scrollLeft + 1 >= - e.target.children[0].getBoundingClientRect().width - - e.target.getBoundingClientRect().width) { - this.setScrollPosition('right'); - } else if (this.scrollPosition !== 'middle') { - this.setScrollPosition('middle'); - } + this.setScrollPositionClassName(e.target); } if (scroll.y) { if (fixedColumnsBodyLeft && e.target !== fixedColumnsBodyLeft) { @@ -695,7 +716,11 @@ export default class Table extends React.Component { if (props.useFixedHeader || (props.scroll && props.scroll.y)) { className += ` ${prefixCls}-fixed-header`; } - className += ` ${prefixCls}-scroll-position-${this.scrollPosition}`; + if (this.scrollPosition === 'both') { + className += ` ${prefixCls}-scroll-position-left ${prefixCls}-scroll-position-right`; + } else { + className += ` ${prefixCls}-scroll-position-${this.scrollPosition}`; + } const isTableScroll = this.columnManager.isAnyColumnsFixed() || props.scroll.x || diff --git a/tests/Table.fixedColumns.spec.js b/tests/Table.fixedColumns.spec.js index 2d62ffd22..7971704f2 100644 --- a/tests/Table.fixedColumns.spec.js +++ b/tests/Table.fixedColumns.spec.js @@ -5,6 +5,14 @@ import { renderToJson } from 'enzyme-to-json'; import Table from '..'; describe('Table.fixedColumns', () => { + // see: + // https://github.com/airbnb/enzyme/issues/49#issuecomment-270250193 + // https://github.com/tmpvar/jsdom/issues/653 + function mockClientRect(node, rect) { + node.getBoundingClientRect = () => ({ + ...rect, + }); + } const columns = [ { title: 'title1', dataIndex: 'a', key: 'a', width: 100, fixed: 'left' }, { title: 'title2', dataIndex: 'b', key: 'b', width: 100, fixed: 'left' }, @@ -76,14 +84,6 @@ describe('Table.fixedColumns', () => { const fixedRightRows = tableNode.querySelectorAll('.rc-table-fixed-right tr'); const rowHeight = '30px'; - // see: - // https://github.com/airbnb/enzyme/issues/49#issuecomment-270250193 - // https://github.com/tmpvar/jsdom/issues/653 - function mockClientRect(node, rect) { - node.getBoundingClientRect = () => ({ - ...rect, - }); - } function simulateTableShow() { mockClientRect(tableNode, { top: 0, @@ -152,4 +152,29 @@ describe('Table.fixedColumns', () => { expect(tr.style.height).toBe(rowHeight); }); }); + + it('has correct scroll classNames when table resize', () => { + const wrapper = mount( +
+ ); + const tableNode = wrapper.instance().tableNode; + const tableBodyContainer = tableNode.querySelectorAll('.rc-table-scroll > .rc-table-body')[0]; + const tableBodyNode = tableBodyContainer.children[0]; + expect(tableNode.className).toContain('rc-table-scroll-position-left'); + expect(tableNode.className).toContain('rc-table-scroll-position-right'); + mockClientRect(tableBodyContainer, { + width: 500, + }); + mockClientRect(tableBodyNode, { + width: 800, + }); + wrapper.setProps({ style: { width: 500 } }); + expect(tableNode.className).toContain('rc-table-scroll-position-left'); + expect(tableNode.className).not.toContain('rc-table-scroll-position-right'); + }); });