Message Input
wa-ui/message-inputFreeComponent
WhatsApp-style message composer with emoji, attachment, auto-resize textarea, and send/voice toggle.
Live preview
live · rendered by the registry
Rendered by wa-ui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://ui.meta-cloud-api.site/r/message-input.jsonSource
1"use client";23import * as React from "react";4import { cn } from "@/lib/utils";5import "@/components/ui/whatsapp/styles/whatsapp.css";67interface MessageInputProps8 extends Omit<React.HTMLAttributes<HTMLDivElement>, "onSubmit"> {9 onSubmit?: (message: string) => void;10 placeholder?: string;11 disabled?: boolean;12 /** Custom elements rendered to the left of the text input, inside the rounded input area */13 leftActions?: React.ReactNode;14 /** Custom element rendered to the right of the input area (outside the rounded box).15 * Can be a render function that receives `{ hasMessage, submit }` to toggle icons based on input state. */16 rightAction?: React.ReactNode | ((ctx: { hasMessage: boolean; submit: () => void }) => React.ReactNode);17}1819const MessageInput = React.forwardRef<HTMLDivElement, MessageInputProps>(20 ({ className, onSubmit, placeholder = "Type a message", disabled = false, leftActions, rightAction, ...props }, ref) => {21 const [message, setMessage] = React.useState("");22 const [multiline, setMultiline] = React.useState(false);23 const textareaRef = React.useRef<HTMLTextAreaElement>(null);2425 const handleSubmit = () => {26 if (message.trim() && onSubmit) {27 onSubmit(message.trim());28 setMessage("");29 setMultiline(false);30 if (textareaRef.current) {31 textareaRef.current.style.height = "24px";32 }33 }34 };3536 const handleKeyDown = (e: React.KeyboardEvent) => {37 if (e.key === "Enter" && !e.shiftKey) {38 e.preventDefault();39 handleSubmit();40 }41 };4243 const handleInput = () => {44 const textarea = textareaRef.current;45 if (textarea) {46 textarea.style.height = "24px";47 const h = Math.min(textarea.scrollHeight, 120);48 textarea.style.height = `${h}px`;49 setMultiline(h > 24);50 }51 };5253 return (54 <div55 ref={ref}56 className={cn(57 "font-wa flex gap-2 bg-wa-compose-bg px-[10px] py-[5px]",58 multiline ? "items-end" : "items-center",59 className60 )}61 {...props}62 >63 {/* Rounded input area */}64 <div className={cn("flex flex-1 gap-1 rounded-[21px] bg-wa-input-bg px-2 py-[5px]", multiline ? "items-end" : "items-center")}>65 {leftActions}66 <textarea67 ref={textareaRef}68 rows={1}69 value={message}70 onChange={(e) => setMessage(e.target.value)}71 onInput={handleInput}72// … truncated
Files it writes
More from wa-ui
All 29 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Action Buttonaction-button | wa-ui | Components | Free | 1 dep · 2 files | |
| Call Permissioncall-permission | wa-ui | Components | Free | 1 dep · 2 files | |
| Carousel Templatecarousel-template | wa-ui | Components | Free | 1 dep · 3 files | |
| Chat Bubblechat-bubble | wa-ui | Components | Free | no deps · 2 files | |
| Chat Headerchat-header | wa-ui | Components | Free | no deps · 2 files | |
| Chat List Itemchat-list-item | wa-ui | Components | Free | no deps · 2 files | |
| Chat Menuchat-menu | wa-ui | Components | Free | 1 dep · 2 files | |
| Contact Bubblecontact-bubble | wa-ui | Components | Free | 1 dep · 3 files |
