shadcn.io is not affiliated with official shadcn/ui
Contact Import Onboarding Block for Ark UI
A step for choosing which contacts to bring over: a table of 22 people with a checkbox each, four filter chips, a select-all that acts on the rows shown, and an Import button that counts what is ticked.
Installation
Overview
Let a new user decide who comes along instead of importing everything, with this contact step for React with Ark UI. It is a whole screen of Folkwick, a relationship manager: the page's rails and one band across it. Twenty-two contacts from "your address book" sit in a native table with a Checkbox on each row (name, email and phone; three are marked "Already here", and the phone column goes on a phone). Four Toggle Group chips narrow the rows, and the select-all box above the table acts on the rows shown only: it is mixed while some are ticked, and its label counts them ("Select 9 shown"). Import is the one Shine Button and counts what is ticked in all 22 ("Import 14 of 22"). It runs a three-tick Progress and says it imported in this demo.
FAQ
What does select-all do when a filter is on?
It acts on the rows shown and no others. With "Has phone" on, the label reads "Select 15 shown"; ticking the box ticks those 15 and leaves everything else as it was, and a ticked row that a filter hides stays ticked and still counts in "Import 14 of 22". The box is mixed while only some of the shown rows are ticked.
How do the filter chips combine?
They all have to be true: "Has email" and "New only" shows people who have an email and are not already in the product. "New only" and "Already here" together match nobody, so the table shows its empty state ("Nobody matches those filters") in the same box, with the same height, and turning a chip off brings the rows back.
What happens to people marked Already here?
They start unticked. If you tick one the status says it will be updated, not duplicated: the block treats the email as the match. Nothing is merged in the demo; in your app match on your own key and update the existing record.
What does the progress bar do?
Pressing Import starts three ticks, 600 ms apart, filling the bar a third at a time; then the status says "Imported 14 contacts in this demo. Nothing was sent." The timer stops when the run ends and when the page goes, ticking or filtering during the run is held off, and with reduced motion the run is over at once.
How does it work with the keyboard?
The select-all box, the four chips, the table (a labelled scroll region you can focus to scroll) and Import are all in the tab order. Space ticks a row's box, which is named "Import" and the person's name, and Space on a chip turns it on or off. The status is one polite region.
What stays local in the demo, and how do I wire it?
Everything: the 22 contacts are typed in the file and the import only moves a bar. In your app read the address book with your provider's consent flow, send the ids of the ticked rows to your server where submit says so, and show its real progress in place of the three ticks.