shadcn.io is not affiliated with official shadcn/ui
Duplicate Detection File Upload Block for React Aria
A pre-upload review of incoming files against a media library: how each one matches, the library file beside it, a Skip, Replace or Keep both select, smart defaults and a summary in the foot.
Installation
Overview
Let people see what is already in the library before they upload, with this duplicate review for React with React Aria. It is the clean-up step of Twinsift, a media-library tool. Each incoming file is a row that says how it matches: same contents (a checksum), same name and size, same name with another size, or new. The library file it matches sits beside it, and a Native Select decides: Skip, Replace or Keep both, where Keep both shows the name it would get ("team-offsite (2).jpg"). "Apply smart defaults" skips exact duplicates and keeps both for a same-name file of another size; the foot sums the result ("Skip 2, replace 0, keep both 2, add 2 new") and the Shine Button says how many files go up. A File Upload strip adds more files, compared with the library by name and size. The frame's bands are ruled by Guides. For media libraries, asset managers, sync tools and any upload that should not create copies by accident.
FAQ
How is a match decided?
In this order: the same checksum as a library file, then the same name and size, then the same name alone, else new. The checksums of the seeded files are typed. A file you add is compared by name and size only, because the block never opens it, so it can never match by contents.
What do smart defaults choose?
Exact duplicates (same contents, or same name and size) are skipped, a same-name file of another size is kept alongside the old one, and new files are added. It fills the rows and leaves you to change any of them; Clear choices undoes it.
How is the name for Keep both made?
The extension is kept and " (2)" goes before it, then " (3)" and so on until the name is free in the library and in the other incoming files. The row's last line spells the result, so nobody has to guess.
Why is Upload disabled at first?
Every duplicate needs an answer: until each has a choice the button is disabled and the status line says how many are left. New files need no choice. Skipped files are left out of the count on the button.
What stays local, and how do I wire it to a library?
The rows, the choices and the queued result are local state. To use it for real, replace LIBRARY with your library's listing, compute checksums in the browser or on the server before the review, and send the rows by choice from upload: skip nothing, replace by id, add with the new name.