chat
A basic chat component that can be used to display a simple chat conversation.
🙂
What's up? Got any plans?
🙃
Got nothing special going on, you?
Installation
npx shadcn add "https://registry.niels.foo/chat.json"
Source
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
import { SendHorizonal } from "lucide-react";
import { createContext, forwardRef, useContext } from "react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { cn } from "@/lib/utils";
const AlignmentContext = createContext<"start" | "end">("start");
type ChatAvatarProps = React.HTMLAttributes<HTMLDivElement>;
export function ChatAvatar({ className, children, ...props }: ChatAvatarProps) {
const align = useContext(AlignmentContext);
return (
<div
className={cn(
"flex aspect-square h-10 w-10 shrink-0 items-center justify-center overflow-hidden rounded-full p-2",
align === "start"
? "rounded-br-none bg-neutral-100 dark:bg-neutral-800"
: "rounded-bl-none bg-chat",
className
)}
{...props}
>
{children}
</div>
);
}
type ChatBubbleProps = React.HTMLAttributes<HTMLDivElement>;
export function ChatBubble({ className, children, ...props }: ChatBubbleProps) {
const align = useContext(AlignmentContext);
return (
<div
className={cn(
"min-h-10 overflow-hidden rounded-xl px-3 py-2",
align === "start"
? "rounded-bl-none bg-neutral-100 text-neutral-800 dark:bg-neutral-800 dark:text-neutral-100"
: "rounded-br-none bg-chat text-chat-foreground",
className
)}
{...props}
>
{children}
</div>
);
}
type ChatMessageProps = React.HTMLAttributes<HTMLDivElement> & {
align: "start" | "end";
};
export function ChatMessage({
children,
className,
align,
...props
}: ChatMessageProps) {
return (
<AlignmentContext.Provider value={align}>
<div
className={cn(
"flex space-x-2",
align === "end" && "flex-row-reverse space-x-reverse",
className
)}
{...props}
>
{children}
</div>
</AlignmentContext.Provider>
);
}
type ChatProps = React.HTMLAttributes<HTMLDivElement>;
export const Chat = forwardRef<HTMLDivElement, ChatProps>(
({ children, className, ...props }, ref) => {
return (
<div
ref={ref}
className={cn(
"flex w-full flex-1 flex-col space-y-4 overflow-y-auto sm:flex-none",
className
)}
{...props}
>
{children}
</div>
);
}
);
Chat.displayName = "Chat";
type ChatInputProps = React.InputHTMLAttributes<HTMLInputElement>;
export const ChatInput = forwardRef<HTMLInputElement, ChatInputProps>(
({ className, ...props }, ref) => {
return (
<Input
ref={ref}
type="text"
className={cn("h-10 flex-grow rounded-xl", className)}
{...props}
/>
);
}
);
ChatInput.displayName = "ChatInput";
export function ChatSubmit({
className,
children,
...props
}: React.ButtonHTMLAttributes<HTMLButtonElement>) {
return (
<Button
type="submit"
className={cn(
"h-10 rounded-xl bg-chat hover:bg-chat/90 text-chat-foreground",
className
)}
{...props}
>
{children || <SendHorizonal className="h-4 w-4" />}
</Button>
);
}
type ChatPromptProps = React.HTMLAttributes<HTMLFormElement>;
export const ChatForm = forwardRef<HTMLFormElement, ChatPromptProps>(
({ className, children, ...props }, ref) => {
return (
<form
ref={ref}
className={cn("flex items-center space-x-2", className)}
{...props}
>
{children}
</form>
);
}
);
ChatForm.displayName = "ChatForm";