Skip to content

Commit 4f46927

Browse files
committed
feat(table): allow table column header customization
1 parent 70debcc commit 4f46927

File tree

5 files changed

+104
-19
lines changed

5 files changed

+104
-19
lines changed

demo/TableExamples.jsx

+87-6
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,52 @@
1-
import React from 'react';
1+
import React, { useState } from 'react';
22
import { Table } from '../dist/main';
33

44
export function TableExamples() {
5+
const [sortState, setSortState] = useState({ sortBy: 'a', sortOrder: 'ASC' });
6+
7+
function changeSort(attribute) {
8+
console.log('sorting by', attribute);
9+
10+
setSortState((prevState) => {
11+
const attributeChanged = prevState.sortBy !== attribute;
12+
const order = !attributeChanged && prevState.sortOrder === 'ASC' ? 'DESC' : 'ASC';
13+
14+
return {
15+
sortBy: attribute,
16+
sortOrder: order,
17+
};
18+
});
19+
}
20+
21+
function buildSortingHeader(label, attribute) {
22+
return (
23+
<div className="d-flex justify-content-between">
24+
{label}
25+
<a
26+
href="#"
27+
onClick={(e) => {
28+
e.preventDefault();
29+
e.stopPropagation();
30+
changeSort(attribute);
31+
}}
32+
>
33+
{sortState.sortBy === attribute ? (
34+
sortState.sortOrder === 'ASC' ? (
35+
<img src="https://upload.wikimedia.org/wikipedia/commons/5/53/Sort_up_1.18.gif" alt="V" />
36+
) : (
37+
<img src="https://upload.wikimedia.org/wikipedia/commons/2/25/Sort_down_1.18.gif" alt="A" />
38+
)
39+
) : (
40+
<img src="https://upload.wikimedia.org/wikipedia/commons/7/73/Sort_both.svg" alt="V/A" />
41+
)}
42+
</a>
43+
</div>
44+
);
45+
}
546
return (
647
<div>
748
<div className="row">
8-
<div className="col">
49+
<div className="col mb-3">
950
<h1 className="h4">Simple Table</h1>
1051
<Table
1152
columns={['a', 'b', 'c']}
@@ -17,7 +58,7 @@ export function TableExamples() {
1758
/>
1859
</div>
1960

20-
<div className="col">
61+
<div className="col mb-3">
2162
<h1 className="h4">Table with formated colums</h1>
2263
<Table
2364
columns={[
@@ -33,7 +74,7 @@ export function TableExamples() {
3374
/>
3475
</div>
3576

36-
<div className="col">
77+
<div className="col mb-3">
3778
<h1 className="h4">Table with formatted values </h1>
3879
<Table
3980
columns={[
@@ -76,7 +117,7 @@ export function TableExamples() {
76117
</div>
77118

78119
<div className="row">
79-
<div className="col">
120+
<div className="col mb-3">
80121
<h1 className="h4">Table with custom styles</h1>
81122
<Table
82123
columns={['a', 'b', 'c']}
@@ -94,7 +135,7 @@ export function TableExamples() {
94135
/>
95136
</div>
96137

97-
<div className="col">
138+
<div className="col mb-3">
98139
<h1 className="h4">Table with row actions</h1>
99140
<Table
100141
columns={[
@@ -126,6 +167,46 @@ export function TableExamples() {
126167
/>
127168
</div>
128169
</div>
170+
171+
<div className="row">
172+
<div className="col-6 mb-3">
173+
<h1 className="h4">Table with custom header</h1>
174+
175+
<Table
176+
columns={[
177+
{
178+
attribute: 'a',
179+
label: 'A',
180+
},
181+
{
182+
attribute: 'b',
183+
label: 'B',
184+
},
185+
{
186+
attribute: 'c',
187+
label: 'C',
188+
},
189+
]}
190+
columnHeaderFormat={buildSortingHeader}
191+
docs={sortData(
192+
[
193+
{ a: 1, b: 9, c: 3 },
194+
{ a: 6, b: 5, c: 7 },
195+
{ a: 8, b: 2, c: 4 },
196+
],
197+
sortState
198+
)}
199+
/>
200+
</div>
201+
</div>
129202
</div>
130203
);
131204
}
205+
206+
function sortData(data, { sortBy, sortOrder }) {
207+
return data.sort((a, b) => {
208+
const diff = a[sortBy] - b[sortBy];
209+
210+
return sortOrder === 'ASC' ? diff : -diff;
211+
});
212+
}

demo/demo.jsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ ReactDOM.render(
1515
<ToastsContainer>
1616
<StatefulTabs
1717
vertical={true}
18-
initialTab={6}
18+
initialTab={4}
1919
tabs={[
2020
{
2121
title: 'Dialog',

src/table/Table.jsx

+10-7
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export function Table({
1616
caption,
1717
actions,
1818
actionLabel,
19+
columnHeaderFormat,
1920
}) {
2021
const normalizedColumns = normalizeColumns(columns);
2122

@@ -32,7 +33,7 @@ export function Table({
3233
<div className="table-responsive">
3334
<table className={tableClasses}>
3435
{caption && <caption>{caption}</caption>}
35-
<TableHead {...{ actions, actionLabel }} columns={normalizedColumns} />
36+
<TableHead {...{ actions, actionLabel, columnHeaderFormat }} columns={normalizedColumns} />
3637
<TableBody {...{ docs, rowClass, actions }} columns={normalizedColumns} />
3738
</table>
3839
</div>
@@ -47,18 +48,20 @@ Table.defaultProps = {
4748
dark: false,
4849
actionLabel: 'Actions',
4950
rowClass: () => '',
51+
columnHeaderFormat: (label) => label,
5052
};
5153

5254
Table.propTypes = {
55+
actionLabel: PropTypes.string,
5356
actions: PropTypes.arrayOf(PropTypes.object),
57+
bordered: PropTypes.bool,
58+
caption: PropTypes.oneOfType([PropTypes.string, PropTypes.element]),
59+
columnHeaderFormat: PropTypes.func,
5460
columns: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.object])),
61+
dark: PropTypes.bool,
5562
docs: PropTypes.arrayOf(PropTypes.object),
56-
rowClass: PropTypes.func,
57-
striped: PropTypes.bool,
58-
bordered: PropTypes.bool,
5963
hover: PropTypes.bool,
64+
rowClass: PropTypes.func,
6065
small: PropTypes.bool,
61-
dark: PropTypes.bool,
62-
caption: PropTypes.oneOfType([PropTypes.string, PropTypes.element]),
63-
actionLabel: PropTypes.string,
66+
striped: PropTypes.bool,
6467
};

src/table/TableHead.jsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ import React from 'react';
22
import PropTypes from 'prop-types';
33
import { getColumnClass } from './table-helpers';
44

5-
export function TableHead({ columns, actions, actionLabel }) {
5+
export function TableHead({ columns, actions, actionLabel, columnHeaderFormat }) {
66
return (
77
<thead>
88
<tr>
99
{columns.map((column, columnIndex) => (
1010
<th key={columnIndex} className={getColumnClass(column)}>
11-
{column.label}
11+
{columnHeaderFormat(column.label, column.attribute)}
1212
</th>
1313
))}
1414
{actions && <th className="text-center">{actionLabel}</th>}
@@ -21,4 +21,5 @@ TableHead.propTypes = {
2121
actionLabel: PropTypes.string,
2222
actions: PropTypes.arrayOf(PropTypes.object),
2323
columns: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.object])),
24+
columnHeaderFormat: PropTypes.func.isRequired,
2425
};

src/table/table-helpers.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { formatClasses } from '../utils/attributes';
2+
13
export function normalizeColumns(columns) {
24
return columns.map((column) => {
35
if (typeof column !== 'string') {
@@ -12,7 +14,5 @@ export function normalizeColumns(columns) {
1214
}
1315

1416
export function getColumnClass({ align }) {
15-
const classes = [align === 'center' ? 'text-center' : align === 'right' ? 'text-right' : ''];
16-
17-
return classes.join(' ');
17+
return formatClasses([align === 'center' ? 'text-center' : align === 'right' ? 'text-right' : '']);
1818
}

0 commit comments

Comments
 (0)