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