-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCollaboratorAnchor.tsx
More file actions
125 lines (119 loc) · 3.96 KB
/
Copy pathCollaboratorAnchor.tsx
File metadata and controls
125 lines (119 loc) · 3.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import { MouseEvent, ReactNode } from "react";
import {
Anchor,
AnchorProps,
Group,
GroupProps,
HoverCard,
HoverCardDropdownProps,
HoverCardProps,
HoverCardTargetProps,
Stack,
Text,
TextProps,
} from "@mantine/core";
import { CollaboratorAvatar } from "@/components/CollaboratorAvatar/CollaboratorAvatar.tsx";
import { InlineFlex } from "@/components/InlineFlex/InlineFlex.tsx";
import { USER_ANONYMOUS } from "@/lib/constants/generic.ts";
import { TCollaborator } from "@/types/schema.ts";
interface CollaboratorAnchorProps extends HoverCardProps {
collaborator?: TCollaborator;
secondaryInfo?: string | ReactNode;
targetProps?: Partial<HoverCardTargetProps>;
dropdownProps?: Partial<HoverCardDropdownProps>;
anchorProps?: Partial<AnchorProps>;
secondaryInfoProps?: Partial<TextProps>;
hoverCardGroupProps?: Partial<GroupProps>;
withHoverCard?: boolean;
withInlineAvatar?: boolean;
onClick?: (event: MouseEvent<HTMLAnchorElement>) => void;
}
/**
* Displays a collaborator's name as an anchor.
* It can optionally show an inline avatar and a hover card with more details about the collaborator.
*
* @param {TCollaborator} [collaborator] - The collaborator data to display. If not provided, defaults to an anonymous user.
* @param {Partial<AnchorProps>} [anchorProps] - Props for the anchor element.
*
* @param {boolean} [withInlineAvatar=false] - Whether to show the avatar inline with the name.
* @param {boolean} [withHoverCard=false] - Whether to show the hover card.
*
* @param {HoverCardProps} [hoverCardProps] - Additional props for the hover card.
* @param {Partial<GroupProps>} [hoverCardGroupProps] - Props for the group inside the hover card.
* @param {Partial<HoverCardTargetProps>} [targetProps] - Props for the hover card target.
* @param {Partial<HoverCardDropdownProps>} [dropdownProps] - Props for the hover card dropdown.
*
* @param {string | ReactNode} [secondaryInfo] - Optional secondary information to show.
* @param {Partial<TextProps>} [secondaryInfoProps] - Props for the secondary info text.
*
* @returns {JSX.Element} The rendered collaborator anchor component.
*/
export const CollaboratorAnchor = ({
anchorProps = {},
collaborator,
dropdownProps = {},
hoverCardGroupProps = {},
secondaryInfo,
secondaryInfoProps = {},
targetProps = {},
withHoverCard = false,
withInlineAvatar = false,
onClick,
...hoverCardProps
}: CollaboratorAnchorProps) => {
let secondaryInfoElement = null;
if (secondaryInfo) {
if (typeof secondaryInfo === "string") {
secondaryInfoElement = (
<Text span inline c="dimmed" size="sm" {...secondaryInfoProps}>
{secondaryInfo}
</Text>
);
} else {
secondaryInfoElement = secondaryInfo;
}
}
const clickHandler = (event: MouseEvent<HTMLAnchorElement>) => {
if (onClick) {
onClick(event);
}
};
return (
<HoverCard
middlewares={{ inline: true }}
withArrow
position="top"
radius="md"
openDelay={200}
closeDelay={400}
disabled={withHoverCard === false}
{...hoverCardProps}
>
<HoverCard.Target {...targetProps}>
<Anchor onClick={clickHandler} {...anchorProps}>
<InlineFlex>
{withInlineAvatar ? (
<CollaboratorAvatar
collaborator={collaborator}
size={25}
withTooltip={false}
/>
) : null}
{collaborator?.name ?? USER_ANONYMOUS.name}
</InlineFlex>
</Anchor>
</HoverCard.Target>
<HoverCard.Dropdown {...dropdownProps}>
<Group gap="md" align="center" wrap="nowrap" {...hoverCardGroupProps}>
<CollaboratorAvatar collaborator={collaborator} />
<Stack gap={4}>
<Text span inline fw="bold">
{collaborator?.name ?? USER_ANONYMOUS.name}
</Text>
{secondaryInfoElement}
</Stack>
</Group>
</HoverCard.Dropdown>
</HoverCard>
);
};