JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 8
  • Score
    100M100P100Q34436F
  • License MIT

React component for text/audio input with AI API integration. Framework-agnostic, works with Next.js, Vite, PHP, and any React setup.

Package Exports

  • ai-input-react
  • ai-input-react/styles.css

Readme

ai-input-react

npm version license npm downloads

A React input component with AI text/voice support. Unified text and audio input with real-time waveform visualization, designed for AI-powered applications.

Why Use This?

  • 🎤 Unified Input – Text and audio in a single component
  • 🌊 Real-time Waveform – Audio visualization during recording
  • 🎨 Zero Config Styling – Prepacked CSS, no Tailwind needed
  • 🔌 Headless Mode – Full control with render props
  • Framework Agnostic – Next.js, Vite, Laravel, etc.

Installation

# npm
npm install ai-input-react

# yarn
yarn add ai-input-react

# pnpm
pnpm add ai-input-react

Quick Start

import { AiInput } from 'ai-input-react'
import 'ai-input-react/styles.css'

function App() {
  return (
    <AiInput
      send={async (input) => {
        const res = await fetch('/api/chat', {
          method: 'POST',
          body: JSON.stringify({ message: input }),
        })
        return res.json()
      }}
      onSuccess={(result) => console.log('Response:', result)}
    />
  )
}

That's it! The component includes text input with a microphone button for audio recording.


Framework Examples

Next.js (App Router)
// app/page.tsx
'use client'

import { AiInput } from 'ai-input-react'
import 'ai-input-react/styles.css'

export default function Home() {
  return (
    <AiInput
      send={async (input) => {
        const res = await fetch('/api/chat', {
          method: 'POST',
          body: JSON.stringify({ message: input }),
        })
        return res.json()
      }}
    />
  )
}
Laravel + Inertia
// resources/js/Pages/Chat.tsx
import { AiInput } from 'ai-input-react'
import 'ai-input-react/styles.css'

export default function Chat({ csrfToken }: { csrfToken: string }) {
  return (
    <AiInput
      send={async (input) => {
        const res = await fetch('/api/chat', {
          method: 'POST',
          headers: {
            'X-CSRF-TOKEN': csrfToken,
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({ message: input }),
        })
        return res.json()
      }}
    />
  )
}
Vite
// src/App.tsx
import { AiInput } from 'ai-input-react'
import 'ai-input-react/styles.css'

export default function App() {
  return (
    <AiInput
      send={async (input) => {
        const res = await fetch('/api/chat', {
          method: 'POST',
          body: JSON.stringify({ message: input }),
        })
        return res.json()
      }}
    />
  )
}

GPT + Whisper Example

<AiInput
  placeholder="Ask anything..."
  send={async (input) => {
    // Text → GPT
    const response = await fetch('https://api.openai.com/v1/chat/completions', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        model: 'gpt-4',
        messages: [{ role: 'user', content: input as string }],
      }),
    })
    return response.json()
  }}
  sendAudio={async (blob) => {
    // Audio → Whisper
    const formData = new FormData()
    formData.append('file', blob, 'audio.webm')
    formData.append('model', 'whisper-1')

    const response = await fetch('https://api.openai.com/v1/audio/transcriptions', {
      method: 'POST',
      headers: { 'Authorization': `Bearer ${token}` },
      body: formData,
    })
    return response.json()
  }}
  onTranscription={(text) => console.log('Transcribed:', text)}
/>

API Reference

Props

Prop Type Required Description
send (input: string | Blob) => Promise<any> Transport function for sending input
sendAudio (blob: Blob) => Promise<any> Separate transport for audio (uses send if not provided)
placeholder string Input placeholder text
disabled boolean Disable the input
className string Additional CSS classes
rateLimit { cooldownMs, maxRequests, windowMs } Rate limiting configuration
audioConfig { maxDurationMs, mimeTypes } Audio recording settings
onSuccess (result: any) => void Called on successful response
onError (error: Error) => void Called on error
onTranscription (text: string) => void Called when audio is transcribed
children (props: RenderProps) => ReactNode Render prop for headless usage

Render Props (Headless Mode)

<AiInput send={sendFn}>
  {(props) => (
    // Full control over UI
  )}
</AiInput>
Prop Type Description
text string Current text value
setText (value: string) => void Update text
submit () => void Submit current input
canSubmit boolean Whether submit is allowed
state 'idle' | 'loading' | 'success' | 'error' | 'recording' Current state
isRecording boolean Audio recording active
startRecording () => Promise<void> Start recording
stopRecording () => void Stop and send recording
cancelRecording () => void Discard recording
audioLevels number[] Waveform data (0-1)
recordingDuration number Recording time in ms
error Error | null Current error
reset () => void Reset to idle state

Styling

import 'ai-input-react/styles.css'

Includes dark theme with zinc/amber colors, waveform visualization, and smooth animations.

Custom Styling (Tailwind)

If using Tailwind, don't import the CSS file. The component uses Tailwind utility classes that will be processed by your build.


Security

⚠️ Never store API keys in frontend code!

Use short-lived tokens from your backend:

// ❌ Dangerous
const API_KEY = 'sk-...'

// ✅ Safe
const token = await getTokenFromBackend()

Browser Support

Browser Version
Chrome 49+
Firefox 36+
Safari 14.1+
Edge 79+

Audio recording requires HTTPS (or localhost) and microphone permission.


Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Issues & Support


License

MIT © 2024