shadcn.io is not affiliated with official shadcn/ui
Footer User Menu Sidebar Block for Radix UI
A billing app in a fixed-height window whose sidebar footer holds the signed-in person as an account menu with page jumps, a Theme radio that really switches the page, and a Sign out that swaps in Sign in.
Installation
Overview
Keep the account where people expect it with this footer user menu sidebar for React with Radix UI. A window framed by a hairline with a plus mark on each corner holds a slim Sidebar for a billing app: four account pages (Account, Billing, Notifications and Team) and, at the foot, the signed-in person as an initials Avatar with a name and an email. The footer is one button that opens a Dropdown Menu: Account, Billing and Notifications jump to their pages, a Theme sub-menu offers a Light, Dark and System radio, and Sign out ends the session. The theme change is real: it puts or removes the dark class on the page, and System keeps following the device. Signing out swaps the footer for a Sign in button and the page for an Empty state; Sign in brings both back and returns focus to the footer. The page is the open account page in plain text, a list of lines under a short sentence. Folded to icons the footer is the avatar with a tooltip, and on a phone the sidebar is a sheet. It's built from Sidebar, Dropdown Menu, Avatar, Empty, Badge, Button and Guides, with a CSS entrance only. For billing, admin and any app whose account lives in the rail.
FAQ
What is in the account menu?
A label with the person's avatar, name and email, then Account, Billing and Notifications, which show those pages in the window, then a Theme sub-menu with a Light, Dark and System radio, then Sign out. Arrow keys move through it, the right arrow (the left in a right-to-left layout) opens the Theme sub-menu, and Escape closes it and returns focus to the footer button.
Does the Theme radio really change the theme?
Yes. Choosing Dark adds the dark class to the html element and Light removes it, which is how this site and the shadcn themes switch. System reads the device's setting and keeps following it while it stays chosen. The radio starts from whatever the page is showing. In your app, call your theme provider's setter (next-themes' setTheme, for example) in the apply function instead.
What does Sign out do?
In this demo, only this: the footer shows a Sign in button, the page shows an empty state saying you're signed out, the rail's links stop opening pages and say why in the status line, and focus moves to the new Sign in button. Sign in restores the footer and the last page and puts focus back on the account button. Nothing is sent and no session exists. Replace signOut and signIn with your auth calls and keep the focus moves.
What stays in the page, and how do I connect it?
Everything. The person, the four pages and their lines are typed at the top of the file, and the signed-in state is the block's own. The pages are links to # whose handler shows the page instead of navigating. They're SidebarMenuButtons with asChild around an a element. Point them at your routes and read the name and email from your session.
What happens when the sidebar collapses or on a phone?
Folded to icons, the footer is the avatar alone with a tooltip that reads "Odette Brakspear, account menu", and the menu opens from it as before. Below the medium breakpoint the sidebar is a sheet opened by the menu button in the top bar, and choosing a page closes it. The provider is set with persist={false} and shortcut={false}, so the block writes no cookie and leaves Ctrl and Command with B to the page it sits on.
Is it accessible?
The footer button announces that it opens a menu and says whose account it is, the pages are links in a navigation landmark named after the product with the open one marked as the current page, and the Theme radio reports which choice is selected. One polite status line says what changed: the page opened, the theme chosen, signed out or in. The page is a scrollable region you can reach with Tab, and the names and emails are isolated so they read right in a right-to-left layout.