This repository has been archived by the owner on Jan 23, 2024. It is now read-only.
forked from calcom/cal.com
/
Dropdown.tsx
163 lines (141 loc) · 5.73 KB
/
Dropdown.tsx
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
import { CheckCircleIcon } from "@heroicons/react/outline";
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
import Link from "next/link";
import { ComponentProps, forwardRef } from "react";
import { classNames } from "@calcom/lib";
import { SVGComponent } from "@calcom/types/SVGComponent";
import { ButtonColor } from "../../button/Button";
export const Dropdown = DropdownMenuPrimitive.Root;
type DropdownMenuTriggerProps = ComponentProps<typeof DropdownMenuPrimitive["Trigger"]>;
export const DropdownMenuTrigger = forwardRef<HTMLButtonElement, DropdownMenuTriggerProps>(
({ className = "", ...props }, forwardedRef) => (
<DropdownMenuPrimitive.Trigger
{...props}
className={classNames(
!props.asChild &&
`inline-flex items-center rounded-md bg-transparent px-3 py-2 text-sm font-medium text-gray-700 ring-0 hover:bg-gray-50 focus:bg-gray-100 group-hover:text-black ${className}`
)}
ref={forwardedRef}
/>
)
);
DropdownMenuTrigger.displayName = "DropdownMenuTrigger";
export const DropdownMenuTriggerItem = DropdownMenuPrimitive.Trigger;
export const DropdownMenuPortal = DropdownMenuPrimitive.Portal;
type DropdownMenuContentProps = ComponentProps<typeof DropdownMenuPrimitive["Content"]>;
export const DropdownMenuContent = forwardRef<HTMLDivElement, DropdownMenuContentProps>(
({ children, sideOffset = 2, align = "end", ...props }, forwardedRef) => {
return (
<DropdownMenuPrimitive.Content
align={align}
{...props}
sideOffset={sideOffset}
className={classNames(
"shadow-dropdown w-50 relative z-10 ml-1.5 origin-top-right rounded-md border border-gray-200 bg-white text-sm",
"[&>*:first-child]:mt-1 [&>*:last-child]:mb-1"
)}
ref={forwardedRef}>
{children}
</DropdownMenuPrimitive.Content>
);
}
);
DropdownMenuContent.displayName = "DropdownMenuContent";
type DropdownMenuLabelProps = ComponentProps<typeof DropdownMenuPrimitive["Label"]>;
export const DropdownMenuLabel = (props: DropdownMenuLabelProps) => (
<DropdownMenuPrimitive.Label {...props} className="px-3 py-2 text-gray-500" />
);
type DropdownMenuItemProps = ComponentProps<typeof DropdownMenuPrimitive["CheckboxItem"]>;
export const DropdownMenuItem = forwardRef<HTMLDivElement, DropdownMenuItemProps>(
({ className = "", ...props }, forwardedRef) => (
<DropdownMenuPrimitive.Item
className={`focus:ring-brand-800 text-sm text-gray-700 ring-inset first-of-type:rounded-t-[inherit] last-of-type:rounded-b-[inherit] hover:bg-gray-100 hover:text-gray-900 focus:outline-none focus:ring-1 ${className}`}
{...props}
ref={forwardedRef}
/>
)
);
DropdownMenuItem.displayName = "DropdownMenuItem";
export const DropdownMenuGroup = DropdownMenuPrimitive.Group;
type DropdownMenuCheckboxItemProps = ComponentProps<typeof DropdownMenuPrimitive["CheckboxItem"]>;
export const DropdownMenuCheckboxItem = forwardRef<HTMLDivElement, DropdownMenuCheckboxItemProps>(
({ children, ...props }, forwardedRef) => {
return (
<DropdownMenuPrimitive.CheckboxItem {...props} ref={forwardedRef}>
{children}
<DropdownMenuPrimitive.ItemIndicator>
<CheckCircleIcon />
</DropdownMenuPrimitive.ItemIndicator>
</DropdownMenuPrimitive.CheckboxItem>
);
}
);
DropdownMenuCheckboxItem.displayName = "DropdownMenuCheckboxItem";
export const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
type DropdownMenuRadioItemProps = ComponentProps<typeof DropdownMenuPrimitive["RadioItem"]>;
export const DropdownMenuRadioItem = forwardRef<HTMLDivElement, DropdownMenuRadioItemProps>(
({ children, ...props }, forwardedRef) => {
return (
<DropdownMenuPrimitive.RadioItem {...props} ref={forwardedRef}>
{children}
<DropdownMenuPrimitive.ItemIndicator>
<CheckCircleIcon />
</DropdownMenuPrimitive.ItemIndicator>
</DropdownMenuPrimitive.RadioItem>
);
}
);
DropdownMenuRadioItem.displayName = "DropdownMenuRadioItem";
type DropdownItemProps = {
children: React.ReactNode;
color?: ButtonColor;
StartIcon?: SVGComponent;
EndIcon?: SVGComponent;
href?: string;
disabled?: boolean;
} & ButtonOrLinkProps;
type ButtonOrLinkProps = ComponentProps<"button"> & ComponentProps<"a">;
export function ButtonOrLink({ href, ...props }: ButtonOrLinkProps) {
const isLink = typeof href !== "undefined";
const ButtonOrLink = isLink ? "a" : "button";
const content = <ButtonOrLink {...props} />;
if (isLink) {
return (
<Link href={href} legacyBehavior>
{content}
</Link>
);
}
return content;
}
export const DropdownItem = (props: DropdownItemProps) => {
const { StartIcon, EndIcon, children, color, ...rest } = props;
return (
<ButtonOrLink
{...rest}
className={classNames(
"inline-flex w-full items-center px-3 py-2 text-gray-700 hover:text-gray-900 disabled:cursor-not-allowed",
color === "destructive" ? "hover:bg-red-100 hover:text-red-700" : "hover:bg-gray-100"
)}>
<>
{StartIcon && <StartIcon className="h-4 w-4" />}
<div className="mx-3 text-sm font-medium leading-5">{children}</div>
{EndIcon && <EndIcon className="h-4 w-4" />}
</>
</ButtonOrLink>
);
};
type DropdownMenuSeparatorProps = ComponentProps<typeof DropdownMenuPrimitive["Separator"]>;
export const DropdownMenuSeparator = forwardRef<HTMLDivElement, DropdownMenuSeparatorProps>(
({ className = "", ...props }, forwardedRef) => {
return (
<DropdownMenuPrimitive.Separator
className={classNames("my-1 h-px bg-gray-200", className)}
{...props}
ref={forwardedRef}
/>
);
}
);
DropdownMenuSeparator.displayName = "DropdownMenuSeparator";
export default Dropdown;