Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Bulk Actions Dialog Block for Ark UI

A media library with twelve files ticked and the dialog that acts on all of them: a scrolling list of the files, four action cards, the chosen action's own control, a bar that fills, and a destructive button for delete.

Framework
UI library

Preview

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Overview

Let people act on a whole selection at once without losing track of what they picked, with this bulk-actions dialog for React with Ark UI. It opens from the Library page of Trayloft, a media library for small studios: the page's header says how many of the 18 files are selected and holds an outline Actions Button, and the page itself, a grid of tiles with twelve ringed, is drawn under a soft scrim inside a hairline frame with a plus mark on each corner. The dialog lists the selected files in a scrolling region that says what is true of each, then offers four actions as cards: move to a folder with a Select, add up to three tags with a Tags Input, archive, or delete. One slot below them shows the chosen action's own control and never changes height. The button's label follows the action, "Move 12 files", and it fills a bar by CSS before a result line replaces the form. Delete asks for the words "delete 12" and turns the button destructive. Apply is a Shine Button for the safe actions. For preview the dialog is drawn open in place when the page loads; the Actions button opens the real Dialog, with the same list, the same choice and the same state. For media libraries, file managers, inboxes and any list where people select first and decide second.

FAQ

Why is the dialog already open, and what do I keep?

So you can see it without a click. On load the dialog is a copy drawn in place over the page: a native dialog element that isn't modal, so nothing is trapped, hidden or focused, and the page around the preview keeps working. The Actions button opens the real Dialog, modal, with its focus trap, Escape and focus return, and the copy stays closed until a reload. Both show the same ActionFields component and share the block's state, so an action chosen in the copy is there in the real one. In your app keep the Dialog and drop the copy: the "in-place" state, the scrim and the dialog element inside the frame.

What stays local, and how do I wire a real bulk action?

All of it. The twelve files are typed in SELECTED; Apply changes them in local state (a folder name, a tag, an archived flag, or removal) and the page behind the dialog redraws from that state. Nothing is sent. In your app send one request with the file ids and the action, wait for the server's answer, and only then show the result line; for a long job, return a job id, close the dialog with a polite message, and let the page show progress where the files are.

How does delete stay safe?

Delete is the only action that asks you to type something: the words "delete 12", with the number of files in them, so the phrase changes if the selection does. Until it matches, the button stays quiet and focusable, and pressing it says what is missing in the polite status message and moves focus to the field. When it matches, the button is the catalog's destructive Button with a text colour mixed toward foreground to keep its contrast. After deleting, the selection is empty, so Actions opens a dialog that says no files are selected; a reload brings the files back.

What does the bar do, and what if motion is reduced?

It is a plain element whose width transitions from empty to full over a second and a half, with the real result applied when the transition ends. Escape and Cancel are ignored while it runs, so a bulk run can't be half-cancelled. With reduced motion on, the bar doesn't animate and the result comes at once.

How do the tags work?

The tags field is the catalog Tags Input: Enter or a comma adds a tag, Backspace on an empty field removes the last one, a paste of several adds them all, and three is the most, which the field says. Applying with no tags is refused with a message and focus returns to the field. Tags you add are appended to a file's own, without repeats.

Is it accessible from the keyboard?

Yes. The real dialog is named by its title and described by its sentence, focus stays inside until it closes, and Escape, Cancel and the close button return focus to Actions. The trigger is the button wrapped in DialogTrigger with asChild, and the dialog is controlled with open and onOpenChange. The file list is a labelled region you can scroll with the arrow keys, the four actions are one radio group you walk with the arrows, and the copy shown on load moves no focus; Escape inside it, Cancel and its close button close it and put focus on Actions.