diff --git a/src/components/Table/__test__/table.spec.js b/src/components/Table/__test__/table.spec.js index c2e89abb2..b4051d065 100644 --- a/src/components/Table/__test__/table.spec.js +++ b/src/components/Table/__test__/table.spec.js @@ -3,6 +3,8 @@ import { mount } from 'enzyme'; import Table from '../index'; import Column from '../../Column'; +jest.mock('../helpers/columns/getEnumerableWidth', () => jest.fn(() => 50)); + const data = [ { name: 'a', @@ -13,14 +15,17 @@ const data = [ const tableData = [ { name: 'Pepe', + email: 'pepe@gmail.com', id: '1234qwerty', }, { name: 'John', + email: 'john@gmail.com', id: '5678asdfgh', }, { name: 'Josep', + email: 'josep@gmail.com', id: '9012zxcvbn', }, ]; @@ -56,7 +61,7 @@ describe('', () => { expect(header.text()).toBe('Name'); expect(cell.text()).toBe('a'); }); - it('should not add a column when showCheckboxColumn is not passed', () => { + it('should not add a column when showCheckboxColumn and showRowNumberColumn are not passed', () => { const component = mount(
@@ -89,7 +94,7 @@ describe('
', () => { expect(component.find('th[scope="row"]').length).toBe(1); expect(component.find('td[role="gridcell"]').length).toBe(2); }); - it('should update the columns state when add a column and showCheckboxColumn is not passed', () => { + it('should update the columns state when add a column and (showCheckboxColumn and showRowNumberColumn) are not passed', () => { const component = mount(
@@ -102,6 +107,7 @@ describe('
', () => { sortable: false, computedWidth: 50, type: 'text', + isFirstDataColumn: true, }, ]); component.setProps({ @@ -115,12 +121,14 @@ describe('
', () => { sortable: false, computedWidth: 50, type: 'text', + isFirstDataColumn: true, }, { field: 'number', sortable: true, computedWidth: 50, type: 'text', + isFirstDataColumn: false, }, ]); }); @@ -142,6 +150,7 @@ describe('
', () => { sortable: false, computedWidth: 50, type: 'text', + isFirstDataColumn: true, }, ]); component.setProps({ @@ -160,12 +169,14 @@ describe('
', () => { sortable: false, computedWidth: 50, type: 'text', + isFirstDataColumn: true, }, { field: 'number', sortable: true, computedWidth: 50, type: 'text', + isFirstDataColumn: false, }, ]); }); @@ -177,6 +188,7 @@ describe('
', () => { sortable: false, computedWidth: 50, type: 'text', + isFirstDataColumn: true, }, ]; const component = mount( @@ -223,6 +235,7 @@ describe('
', () => { computedWidth: 50, sortable: false, type: 'text', + isFirstDataColumn: true, }, { field: 'number', @@ -230,6 +243,7 @@ describe('
', () => { computedWidth: 50, sortable: false, type: 'text', + isFirstDataColumn: false, }, ]); resizeBar.at(0).simulate('mousedown', { clientX: 100 }); @@ -244,6 +258,7 @@ describe('
', () => { isResized: true, sortable: false, type: 'text', + isFirstDataColumn: true, }, { field: 'number', @@ -251,6 +266,7 @@ describe('
', () => { computedWidth: 50, sortable: false, type: 'text', + isFirstDataColumn: false, }, ]); }); @@ -574,8 +590,8 @@ describe('
', () => { '9012zxcvbn': true, }); expect(onRowSelectionMockFn).toHaveBeenCalledWith([ - { id: '1234qwerty', name: 'Pepe' }, - { id: '9012zxcvbn', name: 'Josep' }, + { id: '1234qwerty', name: 'Pepe', email: 'pepe@gmail.com' }, + { id: '9012zxcvbn', name: 'Josep', email: 'josep@gmail.com' }, ]); }); it('should call onRowSelection with the right data when select all rows and there are selected rows', () => { @@ -696,14 +712,17 @@ describe('
', () => { expect(onRowSelectionMockFn).toHaveBeenCalledWith([ { name: 'Pepe', + email: 'pepe@gmail.com', id: '1234qwerty', }, { name: 'John', + email: 'john@gmail.com', id: '5678asdfgh', }, { name: 'Josep', + email: 'josep@gmail.com', id: '9012zxcvbn', }, ]); @@ -749,10 +768,12 @@ describe('
', () => { expect(onRowSelectionMockFn).toHaveBeenCalledWith([ { name: 'Pepe', + email: 'pepe@gmail.com', id: '1234qwerty', }, { name: 'Josep', + email: 'josep@gmail.com', id: '9012zxcvbn', }, ]); @@ -805,14 +826,17 @@ describe('
', () => { expect(onRowSelectionMockFn).toHaveBeenCalledWith([ { name: 'Pepe', + email: 'pepe@gmail.com', id: '1234qwerty', }, { name: 'John', + email: 'john@gmail.com', id: '5678asdfgh', }, { name: 'Josep', + email: 'josep@gmail.com', id: '9012zxcvbn', }, ]); @@ -858,6 +882,7 @@ describe('
', () => { expect(onRowSelectionMockFn).toHaveBeenCalledWith([ { name: 'John', + email: 'john@gmail.com', id: '5678asdfgh', }, ]); @@ -903,6 +928,7 @@ describe('
', () => { expect(onRowSelectionMockFn).toHaveBeenCalledWith([ { id: '5678asdfgh', + email: 'john@gmail.com', name: 'John', }, ]); @@ -1072,6 +1098,7 @@ describe('
', () => { expect(onRowSelectionMockFn.mock.calls[0][0]).toEqual([ { id: '5678asdfgh', + email: 'john@gmail.com', name: 'John', }, ]); @@ -1155,4 +1182,268 @@ describe('
', () => { const input = component.find('Input[label="select row"]').find('input'); expect(input.prop('type')).toBe('checkbox'); }); + it('should render the right amount of columns headers with the right props', () => { + const component = mount( +
+ + + +
, + ); + const thElements = component.find('thead').find('th'); + expect(thElements.length).toBe(3); + thElements.forEach(th => + expect(th.props()).toEqual( + expect.objectContaining({ + 'aria-label': th.text(), + scope: 'col', + tabIndex: -1, + }), + ), + ); + }); + it('should render the right amount of columns headers with the right props when showCheckboxColumn is passed', () => { + const component = mount( + + + + +
, + ); + const thElements = component.find('thead').find('th'); + expect(thElements.length).toBe(4); + thElements.forEach((th, index) => { + if (index === 0) { + expect(th.props()).toEqual( + expect.objectContaining({ + scope: 'col', + tabIndex: -1, + }), + ); + } else { + expect(th.props()).toEqual( + expect.objectContaining({ + 'aria-label': th.text(), + scope: 'col', + tabIndex: -1, + }), + ); + } + }); + }); + it('should render the right amount of columns headers with the right props when showRowNumberColumn is passed', () => { + const component = mount( + + + + +
, + ); + const thElements = component.find('thead').find('th'); + expect(thElements.length).toBe(4); + thElements.forEach((th, index) => { + if (index === 0) { + expect(th.props()).toEqual( + expect.objectContaining({ + scope: 'col', + tabIndex: -1, + }), + ); + } else { + expect(th.props()).toEqual( + expect.objectContaining({ + 'aria-label': th.text(), + scope: 'col', + tabIndex: -1, + }), + ); + } + }); + }); + it('should render the right amount of columns headers with the right props when showCheckboxColumn and showRowNumberColumn are passed', () => { + const component = mount( + + + + +
, + ); + const thElements = component.find('thead').find('th'); + expect(thElements.length).toBe(5); + thElements.forEach((th, index) => { + if (index === 0 || index === 1) { + expect(th.props()).toEqual( + expect.objectContaining({ + scope: 'col', + tabIndex: -1, + }), + ); + } else { + expect(th.props()).toEqual( + expect.objectContaining({ + 'aria-label': th.text(), + scope: 'col', + tabIndex: -1, + }), + ); + } + }); + }); + it('should render the right amount of body cells with the right props', () => { + const component = mount( + + + + +
, + ); + const firstRowChildren = component + .find('tbody') + .find('tr') + .at(0) + .children(); + expect(firstRowChildren.length).toBe(3); + firstRowChildren.forEach((element, index) => { + if (index === 0) { + expect(element.find('th').props()).toEqual( + expect.objectContaining({ + scope: 'row', + tabIndex: -1, + 'data-label': expect.any(String), + }), + ); + } else { + expect(element.find('td').props()).toEqual( + expect.objectContaining({ + role: 'gridcell', + tabIndex: -1, + 'data-label': expect.any(String), + }), + ); + } + }); + }); + it('should render the right amount of body cells with the right props when showCheckboxColumn is passed', () => { + const component = mount( + + + + +
, + ); + const firstRowChildren = component + .find('tbody') + .find('tr') + .at(0) + .children(); + expect(firstRowChildren.length).toBe(4); + firstRowChildren.forEach((element, index) => { + if (index === 0) { + expect(element.find('td').props()).toEqual( + expect.objectContaining({ + role: 'gridcell', + tabIndex: -1, + }), + ); + } else if (index === 1) { + expect(element.find('th').props()).toEqual( + expect.objectContaining({ + scope: 'row', + tabIndex: -1, + 'data-label': expect.any(String), + }), + ); + } else { + expect(element.find('td').props()).toEqual( + expect.objectContaining({ + role: 'gridcell', + tabIndex: -1, + 'data-label': expect.any(String), + }), + ); + } + }); + }); + it('should render the right amount of body cells with the right props when showRowNumberColumn is passed', () => { + const component = mount( + + + + +
, + ); + const firstRowChildren = component + .find('tbody') + .find('tr') + .at(0) + .children(); + expect(firstRowChildren.length).toBe(4); + firstRowChildren.forEach((element, index) => { + if (index === 0) { + expect(element.find('td').props()).toEqual( + expect.objectContaining({ + role: 'gridcell', + tabIndex: -1, + }), + ); + } else if (index === 1) { + expect(element.find('th').props()).toEqual( + expect.objectContaining({ + scope: 'row', + tabIndex: -1, + 'data-label': expect.any(String), + }), + ); + } else { + expect(element.find('td').props()).toEqual( + expect.objectContaining({ + role: 'gridcell', + tabIndex: -1, + 'data-label': expect.any(String), + }), + ); + } + }); + }); + it('should render the right amount of body cells with the right props when showCheckboxColumn and showRowNumberColumn are passed', () => { + const component = mount( + + + + +
, + ); + const firstRowChildren = component + .find('tbody') + .find('tr') + .at(0) + .children(); + expect(firstRowChildren.length).toBe(5); + firstRowChildren.forEach((element, index) => { + if (index === 0 || index === 1) { + expect(element.find('td').props()).toEqual( + expect.objectContaining({ + role: 'gridcell', + tabIndex: -1, + }), + ); + } else if (index === 2) { + expect(element.find('th').props()).toEqual( + expect.objectContaining({ + scope: 'row', + tabIndex: -1, + 'data-label': expect.any(String), + }), + ); + } else { + expect(element.find('td').props()).toEqual( + expect.objectContaining({ + role: 'gridcell', + tabIndex: -1, + 'data-label': expect.any(String), + }), + ); + } + }); + }); }); diff --git a/src/components/Table/body/__test__/cell.spec.js b/src/components/Table/body/__test__/cell.spec.js index 3751a8dbc..32d2f09e8 100644 --- a/src/components/Table/body/__test__/cell.spec.js +++ b/src/components/Table/body/__test__/cell.spec.js @@ -40,6 +40,10 @@ describe(' when isFirst is not passed', () => { const component = mount(); expect(component.find('SelectableCell').exists()).toBe(true); }); + it('should render the EnumerableCell component when columnType is "WITH_ENUMERABLE"', () => { + const component = mount(); + expect(component.find('EnumerableCell').exists()).toBe(true); + }); it('should render the ActionsCell component when columnType is "action"', () => { const component = mount(); expect(component.find('ActionsCell').exists()).toBe(true); @@ -106,4 +110,8 @@ describe(' when isFirst is passed', () => { const component = mount(); expect(component.find('SelectableCell').exists()).toBe(true); }); + it('should render the EnumerableCell component when columnType is "WITH_ENUMERABLE"', () => { + const component = mount(); + expect(component.find('EnumerableCell').exists()).toBe(true); + }); }); diff --git a/src/components/Table/body/__test__/row.spec.js b/src/components/Table/body/__test__/row.spec.js index 0fd0fdd6f..2569db398 100644 --- a/src/components/Table/body/__test__/row.spec.js +++ b/src/components/Table/body/__test__/row.spec.js @@ -9,10 +9,12 @@ const columns = [ { component: undefined, field: 'name', + isFirstDataColumn: true, }, { component: undefined, field: 'number', + isFirstDataColumn: false, }, ]; @@ -122,9 +124,11 @@ describe('', () => { { component: undefined, field: 'number', + isFirstDataColumn: true, }, { field: 'name', + isFirstDataColumn: false, }, ]; const component = mount(); diff --git a/src/components/Table/body/cell.js b/src/components/Table/body/cell.js index fe60607ed..011e64282 100644 --- a/src/components/Table/body/cell.js +++ b/src/components/Table/body/cell.js @@ -1,6 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { SELECTABLE_CHECKBOX } from '../helpers/columns'; +import { SELECTABLE_CHECKBOX, WITH_ENUMERABLE } from '../helpers/columns'; +import EnumerableCell from './enumerableCell'; import SelectableCell from './selectableCell'; import ActionsCell from './actionsCell'; import StyledCell from './styled/cell'; @@ -55,6 +56,10 @@ export default function Cell(props) { return undefined; }; + if (columnType === WITH_ENUMERABLE) { + return ; + } + if (columnType === 'action') { return ( + + + + + ); +} diff --git a/src/components/Table/body/row.js b/src/components/Table/body/row.js index e45e8e179..b7ef8bd5c 100644 --- a/src/components/Table/body/row.js +++ b/src/components/Table/body/row.js @@ -1,22 +1,13 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { SELECTABLE_CHECKBOX } from '../helpers/columns'; import { getFieldValue } from '../helpers/rows'; import Cell from './cell'; import LoadingCells from './loadingCells'; import StyledRow from './styled/row'; -function isFirstAndNoSelectable(index, type) { - if (index === 0 && type !== SELECTABLE_CHECKBOX) { - return true; - } - return false; -} - export default function Row(props) { const { rowData, columns, isSelected, ...rest } = props; - let isFirstColumn; const cells = columns.map((column, index) => { const { header, @@ -28,13 +19,12 @@ export default function Row(props) { computedWidth, isResized, type: columnType, + isFirstDataColumn, children, ...restColumnProps } = column; const key = `cell-${index}`; const value = getFieldValue(rowData, field); - isFirstColumn = - !isFirstColumn && (isFirstAndNoSelectable(index, columnType) || index === 1); return ( diff --git a/src/components/Table/body/styled/enumerable.js b/src/components/Table/body/styled/enumerable.js new file mode 100644 index 000000000..03584ba55 --- /dev/null +++ b/src/components/Table/body/styled/enumerable.js @@ -0,0 +1,14 @@ +import styled from 'styled-components'; +import attachThemeAttrs from '../../../../styles/helpers/attachThemeAttrs'; + +const StyledEnumerable = attachThemeAttrs(styled.span)` + display: block; + text-align: center; + color: ${props => props.palette.text.header}; + + &::after { + content: counter(rowCounter); + } +`; + +export default StyledEnumerable; diff --git a/src/components/Table/body/styled/row.js b/src/components/Table/body/styled/row.js index fbc6e2699..b2ca5d218 100644 --- a/src/components/Table/body/styled/row.js +++ b/src/components/Table/body/styled/row.js @@ -6,6 +6,7 @@ const StyledRow = attachThemeAttrs(styled.tr)` box-shadow: ${props => props.shadows.shadow_8}; transition: all 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; box-sizing: border-box; + counter-increment: rowCounter; &:hover { background-color: ${props => replaceAlpha(props.palette.action.hover, 0.4)}; diff --git a/src/components/Table/helpers/columns/__test__/getColumns.spec.js b/src/components/Table/helpers/columns/__test__/getColumns.spec.js index f5c17038c..222e2ab00 100644 --- a/src/components/Table/helpers/columns/__test__/getColumns.spec.js +++ b/src/components/Table/helpers/columns/__test__/getColumns.spec.js @@ -2,37 +2,44 @@ import React from 'react'; import Column from '../../../../Column'; import getColumns from '../getColumns'; +jest.mock('../../../helpers/columns/getEnumerableWidth', () => jest.fn(() => 50)); + describe('getColumns', () => { - it('should return null when children is null and showCheckboxColumn is false', () => { + it('should return null when children is null, showCheckboxColumn is false and showRowNumberColumn is false', () => { const children = null; const showCheckboxColumn = false; - expect(getColumns({ children, showCheckboxColumn })).toBeNull(); + const showRowNumberColumn = false; + expect(getColumns({ children, showCheckboxColumn, showRowNumberColumn })).toBeNull(); }); - it('should return an empty array when children is not passed', () => { + it('should return an empty array when children is not passed, showCheckboxColumn is false and showRowNumberColumn is false', () => { const children = undefined; const showCheckboxColumn = false; - expect(getColumns({ children, showCheckboxColumn })).toEqual([]); + const showRowNumberColumn = false; + expect(getColumns({ children, showCheckboxColumn, showRowNumberColumn })).toEqual([]); }); - it('should return an empty array when children is an array with falsy values and showCheckboxColumn is false', () => { + it('should return an empty array when children is an array with falsy values, showCheckboxColumn is false and showRowNumberColumn is false', () => { const children = [null, undefined]; const showCheckboxColumn = false; - expect(getColumns({ children, showCheckboxColumn })).toEqual([]); + const showRowNumberColumn = false; + expect(getColumns({ children, showCheckboxColumn, showRowNumberColumn })).toEqual([]); }); - it('should return an array with the columns props when showCheckboxColumn is false', () => { + it('should return an array with the columns props when showCheckboxColumn is false and showRowNumberColumn is false', () => { const children = [} />]; const showCheckboxColumn = false; - expect(getColumns({ children, showCheckboxColumn })).toEqual([ + const showRowNumberColumn = false; + expect(getColumns({ children, showCheckboxColumn, showRowNumberColumn })).toEqual([ { field: 'a', header: 'header', component: , sortable: false, type: 'text', + isFirstDataColumn: true, width: undefined, }, ]); }); - it('should return an array with the columns props plus the selectable column when showCheckboxColumn is true', () => { + it('should return an array with the columns props, plus the selectable column when showCheckboxColumn is true', () => { const children = [} />]; const showCheckboxColumn = true; expect(getColumns({ children, showCheckboxColumn })).toEqual([ @@ -46,6 +53,56 @@ describe('getColumns', () => { component: , sortable: false, type: 'text', + isFirstDataColumn: true, + width: undefined, + }, + ]); + }); + it('should return an array with the columns props, plus the enumerable column data including enumerable offset value when showRowNumberColumn is true and rowNumberOffset is set', () => { + const children = [} />]; + const showRowNumberColumn = true; + const rowNumberOffset = 333; + expect(getColumns({ children, showRowNumberColumn, rowNumberOffset })).toEqual([ + { + type: 'WITH_ENUMERABLE', + rowNumberOffset: 333, + width: 50, + }, + { + field: 'a', + header: 'header', + component: , + sortable: false, + type: 'text', + isFirstDataColumn: true, + width: undefined, + }, + ]); + }); + it('should return an array with the columns props, plus the enumerable and the selectable columns when showCheckboxColumn and showRowNumberColumn are true', () => { + const children = [} />]; + const showCheckboxColumn = true; + const showRowNumberColumn = true; + const rowNumberOffset = 0; + expect( + getColumns({ children, showCheckboxColumn, showRowNumberColumn, rowNumberOffset }), + ).toEqual([ + { + type: 'WITH_ENUMERABLE', + rowNumberOffset: 0, + width: 50, + }, + { + type: 'SELECTABLE_CHECKBOX', + width: 52, + }, + { + field: 'a', + header: 'header', + component: , + sortable: false, + type: 'text', + isFirstDataColumn: true, width: undefined, }, ]); @@ -63,6 +120,7 @@ describe('getColumns', () => { component: , sortable: false, type: 'text', + isFirstDataColumn: true, width: undefined, }, { @@ -92,6 +150,7 @@ describe('getColumns', () => { component: , sortable: false, type: 'text', + isFirstDataColumn: true, defaultWidth: 160, width: 30, }, @@ -100,6 +159,7 @@ describe('getColumns', () => { header: 'header b', sortable: false, type: 'text', + isFirstDataColumn: false, defaultWidth: 150, }, ]); @@ -126,6 +186,7 @@ describe('getColumns', () => { component: , sortable: false, type: 'text', + isFirstDataColumn: true, defaultWidth: 150, }, { @@ -133,6 +194,7 @@ describe('getColumns', () => { header: 'header b', sortable: false, type: 'text', + isFirstDataColumn: false, defaultWidth: 50, }, ]); diff --git a/src/components/Table/helpers/columns/__test__/getEnumerableWidth.spec.js b/src/components/Table/helpers/columns/__test__/getEnumerableWidth.spec.js new file mode 100644 index 000000000..ef63d7cd1 --- /dev/null +++ b/src/components/Table/helpers/columns/__test__/getEnumerableWidth.spec.js @@ -0,0 +1,13 @@ +import getEnumerableWidth from '../getEnumerableWidth'; + +describe('getEnumerableWidth', () => { + it('should return the default width when value is not sent', () => { + expect(getEnumerableWidth()).toBe(48); + }); + it('should return the default calculated width when value is default', () => { + expect(getEnumerableWidth(0)).toBe(48); + }); + it('should return the right width when value length is 3 (999)', () => { + expect(getEnumerableWidth(999)).toBe(72); + }); +}); diff --git a/src/components/Table/helpers/columns/getColumns.js b/src/components/Table/helpers/columns/getColumns.js index 383a3aa8d..acf021073 100644 --- a/src/components/Table/helpers/columns/getColumns.js +++ b/src/components/Table/helpers/columns/getColumns.js @@ -1,5 +1,5 @@ import React from 'react'; -import { SELECTABLE_CHECKBOX } from './'; +import { getEnumerableWidth, SELECTABLE_CHECKBOX, WITH_ENUMERABLE } from './'; function getDefaultWidth(defaultWidth, minColumnWidth, maxColumnWidth) { const minColWidth = Number(minColumnWidth); @@ -16,11 +16,35 @@ function getDefaultWidth(defaultWidth, minColumnWidth, maxColumnWidth) { } export default function getColumns(params) { - const { children = [], showCheckboxColumn, minColumnWidth, maxColumnWidth } = params; + const { + children = [], + showCheckboxColumn, + showRowNumberColumn, + rowNumberOffset, + minColumnWidth, + maxColumnWidth, + } = params; + + const configColumns = []; + + if (showRowNumberColumn) { + configColumns.push({ + type: WITH_ENUMERABLE, + rowNumberOffset, + width: getEnumerableWidth(rowNumberOffset), + }); + } + + if (showCheckboxColumn) { + configColumns.push({ + type: SELECTABLE_CHECKBOX, + width: 52, + }); + } const columnsData = React.Children.map( children, - column => { + (column, index) => { if (column && column.props) { const { type, width, defaultWidth } = column.props; const widthNumber = Number(width); @@ -34,6 +58,7 @@ export default function getColumns(params) { ...column.props, width: widthNumber || undefined, defaultWidth: getDefaultWidth(defaultWidth, minColumnWidth, maxColumnWidth), + isFirstDataColumn: index === 0, }; } return null; @@ -41,14 +66,9 @@ export default function getColumns(params) { null, ); - if (showCheckboxColumn) { - return [ - { - type: SELECTABLE_CHECKBOX, - width: 52, - }, - ...columnsData, - ]; + if (configColumns.length) { + return configColumns.concat(columnsData); } + return columnsData; } diff --git a/src/components/Table/helpers/columns/getEnumerableWidth.js b/src/components/Table/helpers/columns/getEnumerableWidth.js new file mode 100644 index 000000000..ec5610a4f --- /dev/null +++ b/src/components/Table/helpers/columns/getEnumerableWidth.js @@ -0,0 +1,11 @@ +const enumerableColumnOffset = 40; +const singleNumberWidth = 8; + +export default function getEnumerableWidth(numberValue) { + if (numberValue) { + const valuePlusOne = Number(numberValue) + 1; + const enumerableStringWidth = singleNumberWidth * valuePlusOne.toString().length; + return enumerableStringWidth + enumerableColumnOffset; + } + return 48; +} diff --git a/src/components/Table/helpers/columns/index.js b/src/components/Table/helpers/columns/index.js index 6e9fd92bf..5ab8f480c 100644 --- a/src/components/Table/helpers/columns/index.js +++ b/src/components/Table/helpers/columns/index.js @@ -1,6 +1,8 @@ import getColumns from './getColumns'; +import getEnumerableWidth from './getEnumerableWidth'; import isNotSameColumns from './isNotSameColumns'; const SELECTABLE_CHECKBOX = 'SELECTABLE_CHECKBOX'; +const WITH_ENUMERABLE = 'WITH_ENUMERABLE'; -export { getColumns, isNotSameColumns, SELECTABLE_CHECKBOX }; +export { getColumns, getEnumerableWidth, isNotSameColumns, SELECTABLE_CHECKBOX, WITH_ENUMERABLE }; diff --git a/src/components/Table/index.d.ts b/src/components/Table/index.d.ts index ae57a6b65..da0ad94a6 100644 --- a/src/components/Table/index.d.ts +++ b/src/components/Table/index.d.ts @@ -11,6 +11,8 @@ export interface TableProps extends BaseProps { minColumnWidth?: string | number; maxColumnWidth?: string | number; showCheckboxColumn?: boolean; + showRowNumberColumn?: boolean; + rowNumberOffset?: number; onRowSelection?: (rows: object[]) => void; maxRowSelection?: string | number; selectedRows?: []; diff --git a/src/components/Table/index.js b/src/components/Table/index.js index b16133b24..868e62238 100644 --- a/src/components/Table/index.js +++ b/src/components/Table/index.js @@ -42,6 +42,8 @@ export default class Table extends Component { showCheckboxColumn, keyField, data, + showRowNumberColumn, + rowNumberOffset, maxRowSelection, minColumnWidth, maxColumnWidth, @@ -52,6 +54,8 @@ export default class Table extends Component { columns: getColumns({ children, showCheckboxColumn, + showRowNumberColumn, + rowNumberOffset, minColumnWidth, maxColumnWidth, }), @@ -103,6 +107,8 @@ export default class Table extends Component { const { children, showCheckboxColumn, + showRowNumberColumn, + rowNumberOffset, maxRowSelection, selectedRows, data, @@ -114,12 +120,16 @@ export default class Table extends Component { const prevColumns = getColumns({ children: prevChildren, showCheckboxColumn: prevShowCheckboxColumn, + showRowNumberColumn, + rowNumberOffset, minColumnWidth: prevMinColumnWidth, maxColumnWidth: prevMaxColumnWidth, }); const currentColumns = getColumns({ children, showCheckboxColumn, + showRowNumberColumn, + rowNumberOffset, minColumnWidth, maxColumnWidth, }); @@ -389,6 +399,7 @@ export default class Table extends Component { sortDirection, defaultSortDirection, resizeColumnDisabled, + rowNumberOffset, minColumnWidth, maxColumnWidth, style, @@ -443,7 +454,7 @@ export default class Table extends Component { /> - + {}, maxRowSelection: undefined, selectedRows: [], diff --git a/src/components/Table/readme.md b/src/components/Table/readme.md index 4e33c21d4..d0d6584b3 100644 --- a/src/components/Table/readme.md +++ b/src/components/Table/readme.md @@ -619,6 +619,83 @@ const StatusBadge = ({ value }) => ``` +##### Table with enumerates row + +```js +import React from 'react'; +import { Table, Column, ButtonGroup, ButtonIcon, Badge } from 'react-rainbow-components'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { + faCog, + faPencilAlt, + faStore, + faPlus, + faBell, + faEllipsisV, +} from '@fortawesome/free-solid-svg-icons'; + +const data = [ + { + name: 'Leandro Torres', + company: 'Nexxtway', + email: 'leandro@gmail.com', + status: 'verified', + id: '1234qwerty', + }, + { + name: 'Jose Torres', + company: 'Google', + email: 'jose@gmail.com', + status: 'verified', + id: '1234asdfgh', + }, + { + name: 'Reinier', + company: 'Nexxtway', + email: 'reinier@gmail.com', + status: 'verified', + id: '1234zxcvbn', + }, + { + name: 'Sara', + company: 'Nexxtway', + email: 'sara@gmail.com', + status: 'verified', + id: '5678qwerty', + }, + { + name: 'Tahimi', + company: 'Nexxtway', + email: 'tahimi@gmail.com', + status: 'verified', + id: '5678asdfgh', + }, +]; + +const badgeStyles = { color: '#1de9b6' }; + +const StatusBadge = ({ value }) => ; + +
+ + + } /> + } + /> + + + + + + + +
+
+``` + ##### Table Loading ```js diff --git a/src/components/Table/styled/tableBody.js b/src/components/Table/styled/tableBody.js index 326c0138f..ef3a6b629 100644 --- a/src/components/Table/styled/tableBody.js +++ b/src/components/Table/styled/tableBody.js @@ -3,6 +3,7 @@ import attachThemeAttrs from '../../../styles/helpers/attachThemeAttrs'; const StyledTableBody = attachThemeAttrs(styled.tbody)` background-color: ${props => props.palette.background.main}; + counter-reset: rowCounter ${props => props.rowNumberOffset}; `; export default StyledTableBody;