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;