mirror of
https://github.com/hanzoai/sentinel.git
synced 2026-09-29 22:34:33 +00:00
92 lines
2.3 KiB
TypeScript
92 lines
2.3 KiB
TypeScript
import {browserHistory} from 'react-router';
|
|
import styled from '@emotion/styled';
|
|
import type {LocationDescriptorObject} from 'history';
|
|
|
|
import Link from 'sentry/components/links/link';
|
|
import {IconArrow} from 'sentry/icons';
|
|
|
|
export type Alignments = 'left' | 'right' | undefined;
|
|
export type Directions = 'desc' | 'asc' | undefined;
|
|
|
|
type Props = {
|
|
align: Alignments;
|
|
canSort: boolean;
|
|
direction: Directions;
|
|
generateSortLink: () => LocationDescriptorObject | undefined;
|
|
title: React.ReactNode;
|
|
onClick?: (e: React.MouseEvent<HTMLAnchorElement>) => void;
|
|
replace?: boolean;
|
|
};
|
|
|
|
function SortLink({
|
|
align,
|
|
title,
|
|
canSort,
|
|
generateSortLink,
|
|
onClick,
|
|
direction,
|
|
replace,
|
|
}: Props) {
|
|
const target = generateSortLink();
|
|
|
|
if (!target || !canSort) {
|
|
return <StyledNonLink align={align}>{title}</StyledNonLink>;
|
|
}
|
|
|
|
const arrow = !direction ? null : (
|
|
<StyledIconArrow size="xs" direction={direction === 'desc' ? 'down' : 'up'} />
|
|
);
|
|
|
|
const handleOnClick: React.MouseEventHandler<HTMLAnchorElement> = e => {
|
|
if (replace) {
|
|
e.preventDefault();
|
|
browserHistory.replace(target);
|
|
}
|
|
onClick?.(e);
|
|
};
|
|
|
|
return (
|
|
<StyledLink align={align} to={target} onClick={handleOnClick}>
|
|
{title} {arrow}
|
|
</StyledLink>
|
|
);
|
|
}
|
|
|
|
type LinkProps = React.ComponentPropsWithoutRef<typeof Link>;
|
|
type StyledLinkProps = LinkProps & {align: Alignments};
|
|
|
|
const StyledLink = styled((props: StyledLinkProps) => {
|
|
// @ts-expect-error It doesn't look like the `css` property is a part of the props,
|
|
// but prior to this style of destructure-omitting it, it was being omitted
|
|
// with lodash.omit. I mean keeping it omitted here just in case.
|
|
const {align: _align, css: _css, ...forwardProps} = props;
|
|
return <Link {...forwardProps} />;
|
|
})`
|
|
display: block;
|
|
width: 100%;
|
|
white-space: nowrap;
|
|
color: inherit;
|
|
|
|
&:hover,
|
|
&:active,
|
|
&:focus,
|
|
&:visited {
|
|
color: inherit;
|
|
}
|
|
|
|
${(p: StyledLinkProps) => (p.align ? `text-align: ${p.align};` : '')}
|
|
`;
|
|
|
|
const StyledNonLink = styled('div')<{align: Alignments}>`
|
|
display: block;
|
|
width: 100%;
|
|
white-space: nowrap;
|
|
${(p: {align: Alignments}) => (p.align ? `text-align: ${p.align};` : '')}
|
|
`;
|
|
|
|
const StyledIconArrow = styled(IconArrow)`
|
|
vertical-align: top;
|
|
`;
|
|
|
|
export default SortLink;
|