{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "settings-dialog",
  "title": "Settings Dialog",
  "description": "A settings dialog with sidebar navigation and focused controls.",
  "dependencies": [
    "lucide-react",
    "radix-ui"
  ],
  "registryDependencies": [
    "breadcrumb",
    "button",
    "dialog",
    "sidebar",
    "switch"
  ],
  "files": [
    {
      "path": "src/components/examples/settings-dialog.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport {\n  Bell,\n  Check,\n  Globe,\n  Home,\n  Keyboard,\n  Link,\n  Lock,\n  Menu,\n  MessageCircle,\n  Paintbrush,\n  Settings,\n  Video,\n  type LucideIcon,\n} from \"lucide-react\"\n\nimport {\n  Breadcrumb,\n  BreadcrumbItem,\n  BreadcrumbLink,\n  BreadcrumbList,\n  BreadcrumbPage,\n  BreadcrumbSeparator,\n} from \"@/components/ui/breadcrumb\"\nimport { Button } from \"@/components/ui/button\"\nimport {\n  Dialog,\n  DialogContent,\n  DialogDescription,\n  DialogTitle,\n  DialogTrigger,\n} from \"@/components/ui/dialog\"\nimport {\n  Sidebar,\n  SidebarContent,\n  SidebarGroup,\n  SidebarGroupContent,\n  SidebarMenu,\n  SidebarMenuButton,\n  SidebarMenuItem,\n  SidebarProvider,\n} from \"@/components/ui/sidebar\"\nimport { Switch } from \"@/components/ui/switch\"\n\ntype Setting = {\n  key: string\n  title: string\n  description: string\n  defaultValue: boolean\n}\n\ntype SettingsSection = {\n  name: string\n  icon: LucideIcon\n  description: string\n  settings: Setting[]\n}\n\nconst sections: SettingsSection[] = [\n  { name: \"Notifications\", icon: Bell, description: \"Choose how and when you receive updates.\", settings: [{ key: \"push-notifications\", title: \"Push notifications\", description: \"Receive notifications for new activity.\", defaultValue: true }, { key: \"email-summary\", title: \"Email summary\", description: \"Get a daily summary of unread activity.\", defaultValue: false }] },\n  { name: \"Navigation\", icon: Menu, description: \"Tune the way you move through your workspace.\", settings: [{ key: \"compact-navigation\", title: \"Compact navigation\", description: \"Use a denser navigation layout.\", defaultValue: false }, { key: \"remember-last-page\", title: \"Remember last page\", description: \"Return to the page you last visited.\", defaultValue: true }] },\n  { name: \"Home\", icon: Home, description: \"Personalize what you see when you open the app.\", settings: [{ key: \"recent-items\", title: \"Show recent items\", description: \"Show recently opened content on your home screen.\", defaultValue: true }, { key: \"suggestions\", title: \"Show suggestions\", description: \"Show recommendations based on your activity.\", defaultValue: true }] },\n  { name: \"Appearance\", icon: Paintbrush, description: \"Adjust your visual preferences.\", settings: [{ key: \"reduced-motion\", title: \"Reduce motion\", description: \"Limit non-essential animations.\", defaultValue: false }, { key: \"high-contrast\", title: \"High contrast\", description: \"Increase contrast for interface elements.\", defaultValue: false }] },\n  { name: \"Messages & media\", icon: MessageCircle, description: \"Control how conversations and shared content behave.\", settings: [{ key: \"read-receipts\", title: \"Read receipts\", description: \"Let others know when you have read their messages.\", defaultValue: true }, { key: \"link-previews\", title: \"Link previews\", description: \"Show a preview when someone sends a supported link.\", defaultValue: true }] },\n  { name: \"Language & region\", icon: Globe, description: \"Choose language, region, and formatting preferences.\", settings: [{ key: \"auto-translate\", title: \"Auto-translate\", description: \"Offer translations for messages in other languages.\", defaultValue: false }, { key: \"local-time\", title: \"Use local time\", description: \"Display dates and times in your local time zone.\", defaultValue: true }] },\n  { name: \"Accessibility\", icon: Keyboard, description: \"Make the interface easier to use your way.\", settings: [{ key: \"keyboard-hints\", title: \"Keyboard shortcuts\", description: \"Show available shortcuts in menus and tooltips.\", defaultValue: true }, { key: \"focus-indicator\", title: \"Enhanced focus indicator\", description: \"Use a more visible keyboard focus ring.\", defaultValue: false }] },\n  { name: \"Mark as read\", icon: Check, description: \"Choose when activity is considered seen.\", settings: [{ key: \"mark-on-open\", title: \"Mark on open\", description: \"Mark a message as read when it is opened.\", defaultValue: true }, { key: \"mark-all-confirmation\", title: \"Confirm mark all read\", description: \"Ask before marking every message as read.\", defaultValue: true }] },\n  { name: \"Audio & video\", icon: Video, description: \"Control media behavior in calls and messages.\", settings: [{ key: \"join-muted\", title: \"Join calls muted\", description: \"Start calls with your microphone muted.\", defaultValue: false }, { key: \"autoplay-video\", title: \"Autoplay video\", description: \"Play videos automatically when they are visible.\", defaultValue: false }] },\n  { name: \"Connected accounts\", icon: Link, description: \"Manage services connected to your account.\", settings: [{ key: \"sync-calendar\", title: \"Sync calendar\", description: \"Keep connected calendar events up to date.\", defaultValue: true }, { key: \"share-presence\", title: \"Share presence\", description: \"Share your availability with connected services.\", defaultValue: false }] },\n  { name: \"Privacy & visibility\", icon: Lock, description: \"Decide what information other people can see.\", settings: [{ key: \"activity-status\", title: \"Activity status\", description: \"Show others when you are active.\", defaultValue: true }, { key: \"profile-discovery\", title: \"Profile discovery\", description: \"Allow people to find you by your profile details.\", defaultValue: true }] },\n  { name: \"Advanced\", icon: Settings, description: \"Manage advanced behavior and diagnostics.\", settings: [{ key: \"beta-features\", title: \"Beta features\", description: \"Enable early access to experimental features.\", defaultValue: false }, { key: \"diagnostics\", title: \"Usage diagnostics\", description: \"Share anonymous diagnostics to improve the app.\", defaultValue: true }] },\n]\n\nexport type SettingsPreferences = Record<string, boolean>\n\nexport type SettingsDialogProps = {\n  open?: boolean\n  defaultOpen?: boolean\n  onOpenChange?: (open: boolean) => void\n  preferences?: SettingsPreferences\n  onPreferencesChange?: (preferences: SettingsPreferences) => void\n  trigger?: React.ReactElement\n}\n\nconst defaultPreferences = Object.fromEntries(\n  sections.flatMap((section) => section.settings.map((setting) => [setting.key, setting.defaultValue]))\n) as SettingsPreferences\n\nexport function SettingsDialog({\n  open: openProp,\n  defaultOpen = false,\n  onOpenChange,\n  preferences: preferencesProp,\n  onPreferencesChange,\n  trigger,\n}: SettingsDialogProps) {\n  const [uncontrolledOpen, setUncontrolledOpen] = React.useState(defaultOpen)\n  const [activeItem, setActiveItem] = React.useState(\"Messages & media\")\n  const [uncontrolledPreferences, setUncontrolledPreferences] = React.useState<SettingsPreferences>(defaultPreferences)\n  const open = openProp ?? uncontrolledOpen\n  const preferences = preferencesProp ?? uncontrolledPreferences\n  const activeSection = sections.find((section) => section.name === activeItem) ?? sections[0]\n\n  const handleOpenChange = (nextOpen: boolean) => {\n    if (openProp === undefined) setUncontrolledOpen(nextOpen)\n    onOpenChange?.(nextOpen)\n  }\n\n  const handlePreferenceChange = (key: string, value: boolean) => {\n    const nextPreferences = { ...preferences, [key]: value }\n    if (preferencesProp === undefined) setUncontrolledPreferences(nextPreferences)\n    onPreferencesChange?.(nextPreferences)\n  }\n\n  return (\n    <Dialog open={open} onOpenChange={handleOpenChange}>\n      <DialogTrigger asChild>{trigger ?? <Button size=\"sm\">Open settings</Button>}</DialogTrigger>\n      <DialogContent className=\"overflow-hidden p-0 md:max-h-[500px] md:max-w-[700px] lg:max-w-[800px]\">\n        <DialogTitle className=\"sr-only\">Settings</DialogTitle>\n        <DialogDescription className=\"sr-only\">Customize your settings here.</DialogDescription>\n        <SidebarProvider className=\"min-h-0 items-start\">\n          <Sidebar collapsible=\"none\" className=\"hidden w-52 border-r md:flex\">\n            <SidebarContent>\n              <SidebarGroup>\n                <SidebarGroupContent>\n                  <SidebarMenu>\n                    {sections.map((section) => (\n                      <SidebarMenuItem key={section.name}>\n                        <SidebarMenuButton isActive={section.name === activeSection.name} onClick={() => setActiveItem(section.name)}>\n                          <section.icon />\n                          <span>{section.name}</span>\n                        </SidebarMenuButton>\n                      </SidebarMenuItem>\n                    ))}\n                  </SidebarMenu>\n                </SidebarGroupContent>\n              </SidebarGroup>\n            </SidebarContent>\n          </Sidebar>\n          <main className=\"flex h-[440px] min-w-0 flex-1 flex-col overflow-hidden\">\n            <header className=\"flex min-h-14 shrink-0 items-center border-b px-4\">\n              <Breadcrumb className=\"hidden md:block\">\n                <BreadcrumbList>\n                  <BreadcrumbItem><BreadcrumbLink href=\"#\">Settings</BreadcrumbLink></BreadcrumbItem>\n                  <BreadcrumbSeparator />\n                  <BreadcrumbItem><BreadcrumbPage>{activeSection.name}</BreadcrumbPage></BreadcrumbItem>\n                </BreadcrumbList>\n              </Breadcrumb>\n              <label className=\"sr-only\" htmlFor=\"settings-section\">Settings section</label>\n              <select id=\"settings-section\" className=\"h-8 w-full rounded-md border border-input bg-background px-2 text-sm md:hidden\" value={activeSection.name} onChange={(event) => setActiveItem(event.target.value)}>\n                {sections.map((section) => <option key={section.name}>{section.name}</option>)}\n              </select>\n            </header>\n            <div className=\"flex flex-1 flex-col gap-5 overflow-y-auto p-5\">\n              <div>\n                <h3 className=\"text-sm font-medium\">{activeSection.name}</h3>\n                <p className=\"mt-1 text-xs text-muted-foreground\">{activeSection.description}</p>\n              </div>\n              {activeSection.settings.map((setting) => (\n                <SettingRow key={setting.key} title={setting.title} description={setting.description} checked={preferences[setting.key]} onCheckedChange={(value) => handlePreferenceChange(setting.key, value)} />\n              ))}\n            </div>\n          </main>\n        </SidebarProvider>\n      </DialogContent>\n    </Dialog>\n  )\n}\n\nfunction SettingRow({ title, description, checked, onCheckedChange }: Pick<Setting, \"title\" | \"description\"> & { checked: boolean; onCheckedChange: (checked: boolean) => void }) {\n  return (\n    <div className=\"flex items-start justify-between gap-4\">\n      <div>\n        <p className=\"text-sm font-medium\">{title}</p>\n        <p className=\"mt-1 max-w-sm text-xs leading-relaxed text-muted-foreground\">{description}</p>\n      </div>\n      <Switch checked={checked} onCheckedChange={onCheckedChange} aria-label={title} />\n    </div>\n  )\n}\n",
      "type": "registry:block"
    }
  ],
  "type": "registry:block"
}