2022-01-04 12:16:09 +00:00
|
|
|
import clsx from 'clsx';
|
|
|
|
import { PropsWithChildren, ReactNode } from 'react';
|
|
|
|
import { TableHeaderProps } from 'react-table';
|
|
|
|
|
2022-07-07 13:20:33 +00:00
|
|
|
import { TableHeaderSortIcons } from './TableHeaderSortIcons';
|
2022-01-04 12:16:09 +00:00
|
|
|
import styles from './TableHeaderCell.module.css';
|
|
|
|
|
|
|
|
interface Props {
|
|
|
|
canFilter: boolean;
|
|
|
|
canSort: boolean;
|
|
|
|
headerProps: TableHeaderProps;
|
|
|
|
isSorted: boolean;
|
|
|
|
isSortedDesc?: boolean;
|
|
|
|
onSortClick: (desc: boolean) => void;
|
|
|
|
render: () => ReactNode;
|
|
|
|
renderFilter: () => ReactNode;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function TableHeaderCell({
|
|
|
|
headerProps: { className, role, style },
|
|
|
|
canSort,
|
|
|
|
render,
|
|
|
|
onSortClick,
|
|
|
|
isSorted,
|
2022-09-26 19:43:24 +00:00
|
|
|
isSortedDesc = true,
|
2022-01-04 12:16:09 +00:00
|
|
|
canFilter,
|
|
|
|
renderFilter,
|
|
|
|
}: Props) {
|
|
|
|
return (
|
|
|
|
<th role={role} style={style} className={className}>
|
2022-07-07 13:20:33 +00:00
|
|
|
<div className="flex flex-row flex-nowrap h-full items-center gap-1">
|
|
|
|
<SortWrapper
|
|
|
|
canSort={canSort}
|
|
|
|
onClick={onSortClick}
|
|
|
|
isSorted={isSorted}
|
|
|
|
isSortedDesc={isSortedDesc}
|
|
|
|
>
|
|
|
|
{render()}
|
|
|
|
</SortWrapper>
|
|
|
|
{canFilter ? renderFilter() : null}
|
|
|
|
</div>
|
2022-01-04 12:16:09 +00:00
|
|
|
</th>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
interface SortWrapperProps {
|
|
|
|
canSort: boolean;
|
|
|
|
isSorted: boolean;
|
|
|
|
isSortedDesc?: boolean;
|
2022-07-07 13:20:33 +00:00
|
|
|
onClick?: (desc: boolean) => void;
|
2022-01-04 12:16:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function SortWrapper({
|
|
|
|
canSort,
|
|
|
|
children,
|
2022-07-07 13:20:33 +00:00
|
|
|
onClick = () => {},
|
2022-01-04 12:16:09 +00:00
|
|
|
isSorted,
|
2022-09-26 19:43:24 +00:00
|
|
|
isSortedDesc = true,
|
2022-01-04 12:16:09 +00:00
|
|
|
}: PropsWithChildren<SortWrapperProps>) {
|
|
|
|
if (!canSort) {
|
|
|
|
return <>{children}</>;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
2022-07-07 13:20:33 +00:00
|
|
|
<button
|
2022-01-04 12:16:09 +00:00
|
|
|
type="button"
|
|
|
|
onClick={() => onClick(!isSortedDesc)}
|
2022-07-07 13:20:33 +00:00
|
|
|
className={clsx(
|
2022-07-27 02:11:54 +00:00
|
|
|
'!bg-transparent w-full h-full !ml-0 !px-0 border-none focus:border-none',
|
|
|
|
styles.sortable,
|
2022-07-07 13:20:33 +00:00
|
|
|
isSorted && styles.sortingActive
|
|
|
|
)}
|
2022-01-04 12:16:09 +00:00
|
|
|
>
|
2022-07-07 13:20:33 +00:00
|
|
|
<div className="flex flex-row justify-start items-center w-full h-full">
|
|
|
|
{children}
|
|
|
|
<TableHeaderSortIcons
|
|
|
|
sorted={isSorted}
|
|
|
|
descending={isSorted && !!isSortedDesc}
|
2022-01-04 12:16:09 +00:00
|
|
|
/>
|
2022-07-07 13:20:33 +00:00
|
|
|
</div>
|
|
|
|
</button>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
interface TableColumnHeaderAngularProps {
|
|
|
|
colTitle: string;
|
|
|
|
canSort: boolean;
|
|
|
|
isSorted?: boolean;
|
|
|
|
isSortedDesc?: boolean;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function TableColumnHeaderAngular({
|
|
|
|
canSort,
|
|
|
|
isSorted,
|
|
|
|
colTitle,
|
2022-09-26 19:43:24 +00:00
|
|
|
isSortedDesc = true,
|
2022-07-07 13:20:33 +00:00
|
|
|
}: TableColumnHeaderAngularProps) {
|
|
|
|
return (
|
|
|
|
<div className="flex flex-row flex-nowrap h-full">
|
|
|
|
<SortWrapper
|
|
|
|
canSort={canSort}
|
|
|
|
isSorted={!!isSorted}
|
|
|
|
isSortedDesc={isSortedDesc}
|
|
|
|
>
|
|
|
|
{colTitle}
|
|
|
|
</SortWrapper>
|
|
|
|
</div>
|
2022-01-04 12:16:09 +00:00
|
|
|
);
|
|
|
|
}
|