Components
Loading preview...
The Music Equalizer Upload component is a dynamic and visually engaging file upload interface designed specifically for audio files. Each uploaded file is represented with its name and an animated equalizer, where bars bounce rhythmically to indicate ongoing upload progress—perfect for music or media applications. Users can select multiple audio files either by clicking the upload button or dragging files into the input area. Only audio files are accepted, ensuring file-type integrity, while non-audio files are automatically ignored. Each file can be individually removed using a dedicated trash icon without affecting other uploads. Built with Shadcn UI, Lucide icons, and Framer Motion, this component supports both light and dark themes and offers smooth entry and removal animations, making audio uploads visually appealing and highly interactive.
npx shadcn@latest add https://21st.dev/r/ruixen.ui/music-equalizer-upload"use client"
import * as React from "react"
import { MusicEqualizerUpload, UploadFile } from "@/components/ui/music-equalizer-upload"
import { Button } from "@/components/ui/button"
import { v4 as uuidv4 } from "uuid"
export default function DemoMusicEqualizerUpload() {
const [files, setFiles] = React.useState<UploadFile[]>([])
const inputRef = React.useRef<HTMLInputElement | null>(null)
// Simulate upload completion after 3 seconds
React.useEffect(() => {
const interval = setInterval(() => {
setFiles((prev) =>
prev.map((f) =>
f.status === "uploading"
? { ...f, status: "done" }
: f
)
)
}, 3000)
return () => clearInterval(interval)
}, [])
const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {
if (!e.target.files) return
// Filter only audio files
const audioFiles = Array.from(e.target.files).filter(file => file.type.startsWith("audio/"))
const newFiles: UploadFile[] = audioFiles.map((file) => ({
id: uuidv4(),
file,
status: "uploading"
}))
setFiles((prev) => [...prev, ...newFiles])
e.target.value = "" // reset input to allow re-upload
}
const handleRemove = (id: string) => {
setFiles((prev) => prev.filter((f) => f.id !== id))
}
return (
<div className="p-6 space-y-6">
<h1 className="text-2xl font-semibold">Music Equalizer Upload Demo (Audio Only)</h1>
<input
type="file"
multiple
accept="audio/*" // Accept only audio files
className="hidden"
ref={inputRef}
onChange={handleFileSelect}
/>
<Button onClick={() => inputRef.current?.click()}>Upload Audio Files</Button>
<MusicEqualizerUpload files={files} onRemove={handleRemove} />
</div>
)
}