Getting Started
Components
Loading...
Installation
pnpm dlx shadcn@latest add button-group-input-group
Usage
import { ButtonGroupInputGroup } from "@/components/ui/button-group-input-group"<ButtonGroupInputGroup
onSendMessage={(message) => {
console.log("Sending message:", message)
}}
onFileSelect={(file) => {
console.log("File selected:", file.name)
}}
onAudioRecord={(audioBlob) => {
console.log("Audio recorded:", audioBlob)
}}
/>Features
- Text Input: Standard text input with Enter key support
- File Upload: Click to attach files of any type
- Voice Recording: Record audio messages with start/stop controls
- Voice Mode Toggle: Switch between text and voice input modes
- Keyboard Shortcuts: Enter to send, Shift+Enter for new lines
- Accessibility: Full ARIA support and keyboard navigation
Props
| Prop | Type | Default | Description |
|---|---|---|---|
onSendMessage | (message: string) => void | undefined | Callback fired when a text message is sent |
onFileSelect | (file: File) => void | undefined | Callback fired when a file is selected |
onAudioRecord | (audioBlob: Blob) => void | undefined | Callback fired when audio recording is completed |
Behavior
Text Mode (Default)
- Users can type messages in the input field
- Press Enter to send the message
- Press Shift+Enter to create a new line
- Send button is disabled when input is empty
- File attachment button is available
Voice Mode
- Click the voice mode button to enable voice recording
- Input field becomes disabled and shows recording instructions
- Microphone button appears for start/stop recording
- File attachment button is disabled during voice mode
- Send button is hidden in voice mode
File Upload
- Click the plus (+) button to open file picker
- Accepts any file type (
accept="*/*") - File input is reset after selection
- Disabled during voice mode
Audio Recording
- Requires microphone permissions
- Records in WebM format
- Visual feedback with recording state
- Automatic cleanup of media streams
- Error handling for permission issues
Examples
Basic Usage
<ButtonGroupInputGroup />With API Integration
<ButtonGroupInputGroup
onSendMessage={async (message) => {
await fetch("/api/messages", {
method: "POST",
body: JSON.stringify({ message }),
})
}}
onFileSelect={async (file) => {
const formData = new FormData()
formData.append("file", file)
await fetch("/api/upload", {
method: "POST",
body: formData,
})
}}
onAudioRecord={async (audioBlob) => {
const formData = new FormData()
formData.append("audio", audioBlob, "recording.webm")
await fetch("/api/audio", {
method: "POST",
body: formData,
})
}}
/>With State Management
function ChatInput() {
const [messages, setMessages] = useState([])
const [isUploading, setIsUploading] = useState(false)
const handleSendMessage = async (message) => {
setMessages((prev) => [...prev, { type: "text", content: message }])
// Send to backend...
}
const handleFileSelect = async (file) => {
setIsUploading(true)
try {
// Upload logic...
setMessages((prev) => [...prev, { type: "file", content: file.name }])
} finally {
setIsUploading(false)
}
}
return (
<div className="space-y-2">
<ButtonGroupInputGroup
onSendMessage={handleSendMessage}
onFileSelect={handleFileSelect}
/>
{isUploading && <div>Uploading...</div>}
</div>
)
}Accessibility
- ARIA Labels: Proper labeling for all interactive elements
- Keyboard Navigation: Full keyboard support
- Screen Readers: Descriptive tooltips and state announcements
- Focus Management: Logical tab order
- Color Contrast: Meets WCAG guidelines
Browser Support
- Modern Browsers: Chrome, Firefox, Safari, Edge (latest versions)
- MediaRecorder API: Required for voice recording functionality
- File API: Required for file upload functionality
- HTTPS: Required for microphone access in production
Join The Beta
Copy and Paste 86+
ai sdk patterns.
ai sdk patterns.
Get early access pricing and shape the future of the product.
Go to pricing