diff --git a/example/src/components/TableDemo.tsx b/example/src/components/TableDemo.tsx
index e4296d50..c4ef6177 100644
--- a/example/src/components/TableDemo.tsx
+++ b/example/src/components/TableDemo.tsx
@@ -392,6 +392,66 @@ export const TableDemo = () => {
columnsWidth={['100px']}
trProps={trProps}
/>
+
+
custom header with order
+
+ }
+ sortDescIcon={
+
+ }
+ columnsWidth={['100px']}
+ />
+
+ custom 'shortened' header with order
+
+ }
+ sortDescIcon={
+
+ }
+ columnsWidth={['100px']}
+ />
);
};
diff --git a/jest.config.ts b/jest.config.ts
index 1fa0b29e..72fcbb41 100644
--- a/jest.config.ts
+++ b/jest.config.ts
@@ -1,38 +1,46 @@
module.exports = {
- preset: "ts-jest",
- testEnvironment: "jsdom",
- collectCoverage: true,
- "moduleNameMapper": {
- "^.+\\.(css|less|scss)$": "identity-obj-proxy"
- },
- "modulePathIgnorePatterns": [
- "/example",
- "/dist",
- "/coverage",
- "/static",
- "/stories"
- ],
- "collectCoverageFrom": [
- "src/**/*.{ts,tsx}",
- "!src/**/index.{ts,tsx}",
- "!src/typings.d.ts",
- "!/node_modules/",
- "!/path/to/dir/",
- "!src/generatePresentationalComponent/createPresentationalComponent.ts"
- ],
- globals: {
- "ts-jest": {
- tsconfig: {
- outDir: "./dist/",
- sourceMap: true,
- noImplicitAny: true,
- module: "commonjs",
- target: "es6",
- jsx: "react",
- allowSyntheticDefaultImports: true,
- esModuleInterop: true,
- },
+ preset: 'ts-jest',
+ testEnvironment: 'jsdom',
+ collectCoverage: true,
+ 'coverageReporters': ['json', 'lcov', 'text', 'html'],
+ 'coverageThreshold': {
+ 'global': {
+ 'branches': 100,
+ 'functions': 100,
+ 'lines': 100,
+ 'statements': 100
+ }
+ },
+ 'moduleNameMapper': {
+ '^.+\\.(css|less|scss)$': 'identity-obj-proxy'
+ },
+ 'modulePathIgnorePatterns': [
+ '/example',
+ '/dist',
+ '/coverage',
+ '/static',
+ '/stories'
+ ],
+ 'collectCoverageFrom': [
+ 'src/**/*.{ts,tsx}',
+ '!src/**/index.{ts,tsx}',
+ '!src/typings.d.ts',
+ '!/node_modules/',
+ '!/path/to/dir/',
+ '!src/generatePresentationalComponent/createPresentationalComponent.ts'
+ ],
+ globals: {
+ 'ts-jest': {
+ tsconfig: {
+ outDir: './dist/',
+ sourceMap: true,
+ noImplicitAny: true,
+ module: 'commonjs',
+ target: 'es6',
+ jsx: 'react',
+ allowSyntheticDefaultImports: true,
+ esModuleInterop: true,
},
},
- };
-
\ No newline at end of file
+ },
+};
diff --git a/src/table/Table.tsx b/src/table/Table.tsx
index da19a5dd..eb9411bd 100644
--- a/src/table/Table.tsx
+++ b/src/table/Table.tsx
@@ -4,6 +4,11 @@ import { Body } from './Body';
import { Header } from './Header';
import { useSortableData } from './useSortable';
import { useTableSearch } from './useTableSearch';
+type CustomHeaderLabel = {
+ label: string;
+ data: string;
+ omit?: boolean;
+};
type TableProps = {
/**
* the data source used to populate the table
@@ -76,7 +81,7 @@ type TableProps = {
/**
* allow to specify a custom header labels
*/
- customHeaderLabels?: { label: string; data: string }[];
+ customHeaderLabels?: CustomHeaderLabel[] | string[];
/**
* allow to pass extra properties to each row
*/
@@ -117,13 +122,28 @@ export const Table = ({
data: withOrderBy ? items : dataSource,
});
+ const isListOfStrings = (
+ headers: CustomHeaderLabel[] | string[]
+ ): headers is string[] =>
+ headers.some(
+ (header: CustomHeaderLabel | string) => typeof header === 'string'
+ );
+
const handleClick = (value: string) => {
if (customHeaderLabels) {
- const customHeaderEl = customHeaderLabels.find(c => c.label === value);
+ const customHeaderEl = isListOfStrings(customHeaderLabels)
+ ? customHeaderLabels.findIndex((c: string) => c === value)
+ : customHeaderLabels.find((c: CustomHeaderLabel) => c.label === value);
+
+ const key =
+ typeof customHeaderEl === 'number'
+ ? Object.keys(dataSource[0])[customHeaderEl]
+ : (customHeaderEl as CustomHeaderLabel).data;
+
//@ts-ignore
- requestSort(customHeaderEl.data);
+ requestSort(key);
//@ts-ignore
- setSelectedHeader(customHeaderEl.data);
+ setSelectedHeader(key);
} else {
requestSort(value);
setSelectedHeader(value);
@@ -142,6 +162,26 @@ export const Table = ({
);
};
+ const getHeaderValues = () => {
+ if (customHeaderLabels && isListOfStrings(customHeaderLabels)) {
+ return customHeaderLabels.filter(
+ (label: string) => !columnsToOmit?.includes(label)
+ );
+ }
+
+ if (customHeaderLabels) {
+ return Array.from(
+ customHeaderLabels.filter(
+ (c: CustomHeaderLabel) =>
+ !columnsToOmit?.includes(c.data) && c.omit !== true
+ ),
+ (c: CustomHeaderLabel) => c.label
+ );
+ }
+
+ return keys(items, columnsToOmit);
+ };
+
return (
<>
{withSearch && (
@@ -156,11 +196,7 @@ export const Table = ({
theadClassName={theadClassName}
trClassName={trClassName}
thClassName={thClassName}
- values={
- customHeaderLabels
- ? Array.from(customHeaderLabels, c => c.label)
- : keys(items, columnsToOmit)
- }
+ values={getHeaderValues()}
keySorted={getClassNamesFor(selectedHeader)}
sortAscIcon={sortAscIcon}
sortDescIcon={sortDescIcon}
diff --git a/src/table/__tests__/Table.test.tsx b/src/table/__tests__/Table.test.tsx
index 7c37224c..ad465af4 100644
--- a/src/table/__tests__/Table.test.tsx
+++ b/src/table/__tests__/Table.test.tsx
@@ -52,6 +52,50 @@ describe('Table', () => {
expect(row.innerHTML).toContain('1');
});
+ it('should perform the order with short custom headers', () => {
+ render(
+
+ );
+ //body
+ const { id } = values[0];
+ const row: any = screen.getByText(id).closest('tr');
+ expect(row.innerHTML).toContain('2');
+ //header
+ const rows: any = screen.getAllByRole('row');
+ const idHeader = rows[0].children[0];
+ fireEvent.click(idHeader);
+ expect(row.innerHTML).toContain('1');
+ });
+
+ it('should not perform the order when data can not be found', () => {
+ render(
+
+ );
+ //body
+ const { id } = values[0];
+ const row: any = screen.getByText(id).closest('tr');
+ expect(row.innerHTML).toContain('2');
+ //header
+ const rows: any = screen.getAllByRole('row');
+ const idHeader = rows[0].children[0];
+ fireEvent.click(idHeader);
+ expect(row.innerHTML).toContain('2');
+ });
+
it('should allow to search and return 0 elements', () => {
render(
{
expect(tbody[1].children).toHaveLength(0);
});
+ it('should not display omitted table headers', () => {
+ render();
+ const row: any = screen.getAllByRole('row');
+ expect(row[1].innerHTML).toContain('id');
+ expect(row[2].innerHTML).toContain('actions');
+ });
+
+ it('should not display omitted table headers with given custom headers', () => {
+ render(
+
+ );
+ const row: any = screen.getAllByRole('row');
+ expect(row[1].innerHTML).toContain('Test');
+ expect(row[2].innerHTML).toContain('actions');
+ });
+
+ it('should not display omitted table headers with given custom headers with omit flag', () => {
+ render(
+
+ );
+ const row: any = screen.getAllByRole('row');
+ expect(row[1].innerHTML).toContain('Test');
+ expect(row[2].innerHTML).toContain('actions');
+ });
+
+ it('should not display omitted table headers with given shorted custom headers', () => {
+ render(
+
+ );
+ const row: any = screen.getAllByRole('row');
+ expect(row[1].innerHTML).toContain('Test');
+ expect(row[2].innerHTML).toContain('actions');
+ });
+
+ it('should display only the table header', () => {
+ render(
+
+ );
+ const row: any = screen.getAllByRole('row');
+ expect(row[1].innerHTML).toContain('Test');
+ expect(row[2].innerHTML).toContain('position');
+ expect(row[3].innerHTML).toContain('actions');
+ const tbody = screen.getAllByRole('rowgroup');
+ expect(tbody[1].children).toHaveLength(0);
+ });
+
it('should allow to reorder the data if the customHeader is specified', () => {
render(
{
expect(row.innerHTML).toContain('1');
});
- it('should not reorder the data if the customHeader specified doesn\'t have a match data', () => {
+ it("should not reorder the data if the customHeader specified doesn't have a match data", () => {
render(
{
Delete
},
];
- return ;
+ return ;
}}