Files
SCM-Manager/scm-ui/ui-components/src/table/Table.tsx

94 lines
2.6 KiB
TypeScript
Raw Normal View History

2019-11-29 15:57:36 +01:00
import React, { FC, useState } from "react";
2019-11-29 17:13:39 +01:00
import styled from "styled-components";
import { SortTypes } from "./types";
import Icon from "../Icon";
const StyledTable = styled.table.attrs(() => ({
className: "table content is-hoverable"
}))``;
const IconWithMarginLeft = styled(Icon)`
margin-left: 0.25em;
`;
2019-11-29 15:57:36 +01:00
type SortableTableProps = {
data: any[];
};
// @ts-ignore
const Table: FC<SortableTableProps> = ({ data, children }) => {
const [tableData, setTableData] = useState(data);
2019-11-29 17:13:39 +01:00
const [ascending, setAscending] = useState(false);
2019-11-29 15:57:36 +01:00
const [lastSortBy, setlastSortBy] = useState(0);
// @ts-ignore
2019-11-29 17:13:39 +01:00
const sortFunctions = React.Children.map(children, child =>
// @ts-ignore
child.props.createComparator ? child.props.createComparator(child.props) : undefined
);
2019-11-29 15:57:36 +01:00
const mapDataToColumns = (row: any) => {
return (
<tr>
{React.Children.map(children, child => {
// @ts-ignore
return <td>{React.cloneElement(child, { ...child.props, row })}</td>;
})}
</tr>
);
};
const sortDescending = (sortAscending: (a: any, b: any) => number) => {
return (a: any, b: any) => {
return sortAscending(a, b) * -1;
};
};
const tableSort = (index: number) => {
const sortableData = [...tableData];
let sortOrder = ascending;
if (lastSortBy !== index) {
setAscending(true);
sortOrder = true;
}
const sortFunction = sortOrder ? sortFunctions[index] : sortDescending(sortFunctions[index]);
sortableData.sort(sortFunction);
setTableData(sortableData);
setAscending(!sortOrder);
setlastSortBy(index);
};
return (
tableData.length > 0 && (
2019-11-29 17:13:39 +01:00
<StyledTable>
2019-11-29 15:57:36 +01:00
<thead>
<tr>
{React.Children.map(children, (child, index) => (
// @ts-ignore
2019-11-29 17:13:39 +01:00
<th
className={child.props.createComparator && "has-cursor-pointer"}
onClick={child.props.createComparator ? () => tableSort(index) : undefined}
>
{child.props.header}
{child.props.createComparator && renderSortIcon(child.props.sortType, ascending)}
</th>
2019-11-29 15:57:36 +01:00
))}
</tr>
</thead>
<tbody>{tableData.map(mapDataToColumns)}</tbody>
2019-11-29 17:13:39 +01:00
</StyledTable>
2019-11-29 15:57:36 +01:00
)
);
};
2019-11-29 17:13:39 +01:00
const renderSortIcon = (contentType: string, ascending: boolean) => {
if (contentType === SortTypes.Text) {
return <IconWithMarginLeft name={ascending ? "sort-alpha-down-alt" : "sort-alpha-down"} />;
} else {
return <IconWithMarginLeft name={ascending ? "sort-amount-down-alt" : "sort-amount-down"} />;
}
};
2019-11-29 15:57:36 +01:00
export default Table;