shadcn.io is not affiliated with official shadcn/ui
Wifi Connect Dialog Block for Radix UI
A smart plug's setup screen with a Wi-Fi dialog shown open: five networks with signal bars and words, a lock or Open, a Saved badge, a password row that unfolds for the chosen secured network and a bounded pretend connect.
Installation
Overview
Pick a network and join it in one list, with this dialog for React with Radix UI. It opens from the Set up your plug screen of Plugbud, a smart plug: the page's header holds an outline Connect to Wi-Fi Button, and the screen itself, a plug drawn from circles and lines, Step 2 of 3 and an Offline status, is drawn under a soft scrim inside a hairline frame with a plus mark on each corner. The Dialog lists five typed networks as radio rows: the name, four signal bars drawn in CSS with a word, Strong, Good, Fair or Weak, a lock with Secured or Open, and a Badge saying Saved on one. Choosing a secured network unfolds its own row under it with a Password Input; the demo password, sunflower, is written in the dialog, a wrong one says Incorrect password, and an open or saved network needs none. The only Shine Button, Connect, spins for a moment, then the dialog says it connected in this demo and the drawn plug reads Online with the network's name. For preview the dialog is drawn open in place when the page loads; the header button opens the real Dialog.
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 screen: a native dialog element that isn't modal, so nothing is trapped, hidden or focused, and the page around the preview keeps working. The Connect to Wi-Fi 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 WifiFields component and share the block's state, so the network you chose in the copy is chosen 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.
Does it really scan or join a network?
No. Browsers cannot list Wi-Fi networks and this page never tries to: the five networks and their signal are typed constants, and the password is a typed demo one, written in the dialog. Connect runs a pretend connect of a little over a second, bounded by a timer, and closing the dialog is refused meanwhile with a polite message. In your app the plug would do the scanning, and this dialog would be a screen on a phone that talks to it.
How does the password row work?
Choosing a secured network opens a row of its own under it, and the field takes focus. Connect with the field empty says Enter the password and focuses it, a wrong password says Incorrect password and marks the field invalid, and the right one, sunflower, runs the connect. The saved network needs no password, so its row says so, and open networks have no row. The list keeps its height whichever row is open, so the dialog never moves.
How is the signal shown without colour?
Two ways at once. Four small bars are drawn, the filled ones solid and the rest faint, and the word beside them, Strong, Good, Fair or Weak, says the same in text. Whether a network is secured is a lock plus the word Secured or Open. Nothing relies on colour, so it reads the same in every theme and to assistive technology, which gets the words.
What stays local in the demo, and how do I wire it up?
All of it. The networks, the password and the connect are the block's state, and the drawn plug follows it. In your app send the chosen network and the password to the device over a local connection, show its own result, and never keep a password longer than the setup needs.
Is it accessible from the keyboard?
Yes. The real dialog is named Connect to Wi-Fi, focus starts inside and stays there until it closes, and Escape and the close button return focus to the header button. The networks are native radios, so the arrow keys move the choice and the password field takes focus when a secured one is chosen. The trigger is the button wrapped in DialogTrigger with asChild, and the dialog is controlled with open and onOpenChange. The copy shown on load moves no focus; Escape inside it and its close button close it and put focus on the button.