nextui.dev
Home
Docs
Saved
Pricing
Components37
  • Forms & inputs7
  • Cards13
  • Buttons, badges & avatars8
  • Feedback & display6
  • Effects3
Agents23
  • Chat inputNew
  • Task checklistNew
  • ReasoningNew
  • Tool callNew
  • Model pickerNew
  • Tool approvalNew
  • AttachmentsNew
  • SourcesNew
  • Agent timelineNew
  • Context meterNew
  • Artifact panelNew
  • Message actionsNew
  • Streaming messageNew
  • Sub-agentsNew
  • Conversation shellNew
  • Agent questionNew
  • Voice agentNew
  • Voice orbNew
  • Thinking ring
  • Thinking waveNew
  • Thinking sparkle
  • Thinking bot
  • Prompt deckNew
Blocks20
  • Agent chatNew
  • Pill heroNew
  • Grid hero
  • Moodboard generatorNew
  • Waitlist heroNew
  • Intro bannerNew
  • Creative home heroNew
  • Chat heroNew
  • App shelfNew
  • Usage card
  • Design resultsNew
  • Pricing tiers
  • Dashboard home
  • The shiftNew
  • Launch perksNew
  • Testimonials
  • Quote
  • Team
  • Leads tableNew
  • Sign in
Pages13
  • ASCII workspace$49
  • Research agent$49
  • Support agent$49
  • Coding agent$49
  • CRM overviewNew
  • Marketing dashboardNew
  • Developer portfolio$49
  • Particle landing$49
  • Particle story$49
  • Statement converter$49
  • AI photo studio$49
  • Group card launch$49
  • Month-end storyNew
Themes9
  • Default
  • Ember
  • Ocean
  • Forest
  • Grape
  • Rose
  • Amber
  • Clay
  • Brutal
Upgrade
nextui.dev

nextui components, blocks and themes you install with one command.

Product

  • Components
  • Blocks
  • Themes
  • Pricing

Resources

  • Docs
  • Roadmap
  • GitHub

Legal

  • License
  • Privacy
  • Terms
  • Refunds

nextUI

[ 200 OK ] · nextUI

© 2026 NEXTUI • All rights reserved.

Upgrade
ComponentsAI & agentsAttachments
Copy promptCopy prompt

Customize

Allowed types, same format as the input accept attribute ("image/*,.pdf")

Files past this count are ignored

10

Loop a scripted drop with uploads and an error, for demos. Stops when the viewer interacts

JSX · copied with Copy prompt

<Attachments autoPlay />

AttachmentsNew

File chips for a chat composer: drop, paste or pick files, with image thumbnails, upload progress, error chips and remove.

Installation

Set your access key from API keys as NEXTUI_TOKEN in .env.local and add the @nextui namespace below to components.json once. Then every item installs by name. Each install counts as a copy on a free account.

$pnpm dlx shadcn@latest add @nextui/attachments
1{
2 "registries": {
3 "@nextui": {
4 "url": "https://nextui.dev/r/{name}.json",
5 "headers": { "Authorization": "Bearer ${NEXTUI_TOKEN}" }
6 }
7 }
8}

Usage

1"use client";
2
3import { useState } from "react";
4import { useChat } from "@ai-sdk/react";
5import { Attachments } from "@/components/nextui/attachments";
6
7export function Composer() {
8 const { sendMessage } = useChat();
9 const [text, setText] = useState("");
10 const [files, setFiles] = useState<File[]>([]);
11 // Remount the chips after sending to clear them.
12 const [round, setRound] = useState(0);
13
14 return (
15 <form
16 onSubmit={(e) => {
17 e.preventDefault();
18 // AI SDK 7 turns File objects into file parts (data URLs) for you.
19 const dt = new DataTransfer();
20 files.forEach((f) => dt.items.add(f));
21 sendMessage({ text, files: dt.files });
22 setText("");
23 setFiles([]);
24 setRound((r) => r + 1);
25 }}
26 >
27 <Attachments
28 key={round}
29 accept="image/*,.pdf,.csv,.txt"
30 maxSize={10 * 1024 * 1024}
31 onAdd={(added) => setFiles((prev) => [...prev, ...added])}
32 onRemove={(_, file) => setFiles((prev) => prev.filter((f) => f !== file))}
33 >
34 <textarea value={text} onChange={(e) => setText(e.target.value)} />
35 </Attachments>
36 </form>
37 );
38}
39
40// Uploading to your own storage? Pass attachments yourself, with status "uploading" and progress 0–1.

API reference

Edit props live in the preview above, or see all 9 props
PropTypeDefaultDescription
attachmentsAttachment[]–Controlled list: id, name, size, type, url, status, progress, error. Leave out and the component keeps picked files itself
onAdd(files: File[]) => void–Called with files that pass the accept and size checks
onRemove(id: string, file?: File) => void–Called when a chip's remove button is clicked, with the File it came from
acceptstring–Allowed types, same format as the input accept attribute ("image/*,.pdf")
maxSizenumber20971520Largest file in bytes; bigger files show an error chip
maxFilesnumber10Files past this count are ignored
childrenReactNode–Your composer. Dropping or pasting files anywhere on it attaches them; a paperclip button sits beside it
autoPlaybooleanfalseLoop a scripted drop with uploads and an error, for demos. Stops when the viewer interacts
classNamestring–Extra classes on the wrapper

Related

All components

Chat inputNew

Task checklistNew

Free

ReasoningNew

Sign in to see the code

Preview it freely. A free account copies code and prompts a few times a day.

Sign in