Settings Dialog
A dialog laid out as a nav beside a page, for settings with several pages.
<SettingsDialog onOpenChange={setOpen} open={open}> <SettingsDialogNav label="Settings" title="Acme"> <SidebarMenuItem> <SidebarMenuButton isActive> <SidebarMenuLabel>General</SidebarMenuLabel> </SidebarMenuButton> </SidebarMenuItem> </SettingsDialogNav> <SettingsDialogPage title="General">…</SettingsDialogPage></SettingsDialog>Installation
$ npx shadcn@latest add @constella/settings-dialogUsage
import { SettingsDialog, SettingsDialogNav, SettingsDialogPage,} from "@/components/primitives/settings-dialog";import { SidebarMenuButton, SidebarMenuItem, SidebarMenuLabel,} from "@/components/primitives/sidebar";const [open, setOpen] = useState(false);const [page, setPage] = useState("general");
<SettingsDialog onOpenChange={setOpen} open={open}> <SettingsDialogNav label="Settings"> <SidebarMenuItem> <SidebarMenuButton isActive={page === "general"} onClick={() => setPage("general")} > <SidebarMenuLabel>General</SidebarMenuLabel> </SidebarMenuButton> </SidebarMenuItem> </SettingsDialogNav> <SettingsDialogPage description="How Acme shows up for everyone in it." title="General" > … </SettingsDialogPage></SettingsDialog>;SettingsDialog takes Dialog's root props and draws its own close button. Open it with open and onOpenChange, or keep the page in the URL so a reload keeps it.
Composition
SettingsDialog├── SettingsDialogNav│ └── SidebarMenuItem│ └── SidebarMenuButton└── SettingsDialogPageSettings Dialog Nav
Give SettingsDialogNav a label for screen readers and an optional title above its pages. It's a Sidebar that doesn't collapse, so its rows are SidebarMenuItems; mark the open page with isActive.
<SettingsDialogNav label="Workspace settings" title="Acme"> …</SettingsDialogNav>Settings Dialog Page
SettingsDialogPage names the page with title and an optional description, then scrolls its children on its own. Give it a key per page, so switching pages starts at the top.
<SettingsDialogPage description="Choose what reaches you, and where." key="notifications" title="Notifications"> …</SettingsDialogPage>Keep the last page while the dialog closes. If the page comes from state that clears on close (a URL param), the page empties mid-fade; hold on to the last one shown until the dialog is closed.
Field
Build each setting from Field: a choice card with a Switch, in a FieldGroup inside a flush Card, lists them as rows of one card.
<Card size="flush"> <FieldGroup> <Field> <FieldLabel> <FieldContent> <FieldTitle>Mentions</FieldTitle> <FieldDescription>When someone @mentions you.</FieldDescription> </FieldContent> <Switch defaultChecked /> </FieldLabel> </Field> </FieldGroup></Card>API Reference
| Part | Adds |
|---|---|
SettingsDialog | Renders Dialog and a DialogContent with the nav beside the page, stacked on narrow screens, and a DialogCloseButton; sx goes to the popup |
SettingsDialogNav | label (required) names the nav; title labels its group; sx goes to the Sidebar |
SettingsDialogPage | title (required) and description render as DialogTitle and DialogDescription |
Every part takes sx, applied last. For the rest, see Dialog and Sidebar.