-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathCopilotModalHeader.tsx
More file actions
109 lines (93 loc) · 3.13 KB
/
Copy pathCopilotModalHeader.tsx
File metadata and controls
109 lines (93 loc) · 3.13 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
import React, { useCallback } from "react";
import { cn } from "@/lib/utils";
import { useCopilotChatConfiguration, CopilotChatDefaultLabels } from "@/providers/CopilotChatConfigurationProvider";
import { renderSlot, WithSlots } from "@/lib/slots";
import { X } from "lucide-react";
type HeaderSlots = {
titleContent: typeof CopilotModalHeader.Title;
closeButton: typeof CopilotModalHeader.CloseButton;
};
type HeaderRestProps = {
title?: string;
} & Omit<React.HTMLAttributes<HTMLDivElement>, "children">;
export type CopilotModalHeaderProps = WithSlots<HeaderSlots, HeaderRestProps>;
export function CopilotModalHeader({
title,
titleContent,
closeButton,
children,
className,
...rest
}: CopilotModalHeaderProps) {
const configuration = useCopilotChatConfiguration();
const fallbackTitle = configuration?.labels.modalHeaderTitle ?? CopilotChatDefaultLabels.modalHeaderTitle;
const resolvedTitle = title ?? fallbackTitle;
const handleClose = useCallback(() => {
configuration?.setModalOpen(false);
}, [configuration]);
const BoundTitle = renderSlot(titleContent, CopilotModalHeader.Title, {
children: resolvedTitle,
});
const BoundCloseButton = renderSlot(closeButton, CopilotModalHeader.CloseButton, {
onClick: handleClose,
});
if (children) {
return children({
titleContent: BoundTitle,
closeButton: BoundCloseButton,
title: resolvedTitle,
...rest,
});
}
return (
<header
data-slot="copilot-modal-header"
className={cn(
"flex items-center justify-between border-b border-border px-4 py-4",
"bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/80",
className,
)}
{...rest}
>
<div className="flex w-full items-center gap-2">
<div className="flex-1" aria-hidden="true" />
<div className="flex flex-1 justify-center text-center">{BoundTitle}</div>
<div className="flex flex-1 justify-end">{BoundCloseButton}</div>
</div>
</header>
);
}
CopilotModalHeader.displayName = "CopilotModalHeader";
export namespace CopilotModalHeader {
export const Title: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({ children, className, ...props }) => (
<div
className={cn(
"w-full text-base font-medium leading-none tracking-tight text-foreground",
className,
)}
{...props}
>
{children}
</div>
);
export const CloseButton: React.FC<React.ButtonHTMLAttributes<HTMLButtonElement>> = ({
className,
...props
}) => (
<button
type="button"
className={cn(
"inline-flex size-8 items-center justify-center rounded-full text-muted-foreground transition cursor-pointer",
"hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
className,
)}
aria-label="Close"
{...props}
>
<X className="h-4 w-4" aria-hidden="true" />
</button>
);
}
CopilotModalHeader.Title.displayName = "CopilotModalHeader.Title";
CopilotModalHeader.CloseButton.displayName = "CopilotModalHeader.CloseButton";
export default CopilotModalHeader;