{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "settings-dialog", "title": "Settings Dialog", "description": "A drill-in settings dialog — a worked example composing NavigatorDialog with a Cell-based menu that navigates into editable sub-views.", "dependencies": [ "lucide-react" ], "registryDependencies": [ "navigator-dialog", "cell", "button", "input", "label" ], "files": [ { "path": "registry/custom-ui/settings-dialog.tsx", "content": "\"use client\";\n\nimport * as React from \"react\";\nimport {\n BellIcon,\n ChevronRightIcon,\n PaletteIcon,\n ShieldIcon,\n UserIcon,\n} from \"lucide-react\";\n\nimport {\n Cell,\n CellContent,\n CellDescription,\n CellEnd,\n CellStart,\n CellTitle,\n} from \"@/components/custom-ui/cell\";\nimport {\n NavigatorDialog,\n useNavigator,\n} from \"@/components/custom-ui/navigator-dialog\";\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\nimport { Label } from \"@/components/ui/label\";\n\n// A worked example of NavigatorDialog + Cell: a drill-in settings dialog.\n// Copy it in and adapt the views to your own settings — the data below is\n// placeholder content.\n\ninterface SettingsRow {\n /** Matches a NavigatorView id below — `navigate()` drills into it. */\n id: string;\n icon: React.ReactNode;\n title: string;\n description: string;\n}\n\nconst SETTINGS_ROWS: SettingsRow[] = [\n {\n id: \"edit-name\",\n icon: ,\n title: \"Edit name\",\n description: \"Change your display name\",\n },\n {\n id: \"notifications\",\n icon: ,\n title: \"Notifications\",\n description: \"Manage notification preferences\",\n },\n {\n id: \"appearance\",\n icon: ,\n title: \"Appearance\",\n description: \"Customize your experience\",\n },\n {\n id: \"advanced\",\n icon: ,\n title: \"Advanced\",\n description: \"Developer options and more\",\n },\n];\n\n// Menu view — a Cell-based list. Each row is a button that drills in.\nfunction MenuView() {\n const { navigate } = useNavigator();\n return (\n
\n {SETTINGS_ROWS.map((row) => (\n \n \n \n ))}\n
\n );\n}\n\n// A drilled-in editing view — no redundant heading; the screen title\n// already names it in the header bar.\nfunction EditNameView() {\n const { back } = useNavigator();\n return (\n {\n event.preventDefault();\n back();\n }}\n >\n
\n \n \n
\n \n );\n}\n\nfunction PlaceholderView({ text }: { text: string }) {\n return

{text}

;\n}\n\nexport interface SettingsDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n}\n\nexport function SettingsDialog({ open, onOpenChange }: SettingsDialogProps) {\n return (\n ,\n },\n {\n id: \"edit-name\",\n name: \"Profile\",\n title: \"Edit name\",\n render: () => ,\n footer: () => (\n \n ),\n },\n {\n id: \"notifications\",\n name: \"Notifications\",\n title: \"Notifications\",\n render: () => (\n \n ),\n },\n {\n id: \"appearance\",\n name: \"Appearance\",\n title: \"Appearance\",\n render: () => (\n \n ),\n },\n {\n id: \"advanced\",\n name: \"Advanced\",\n title: \"Advanced\",\n render: () => (\n \n ),\n },\n ]}\n />\n );\n}\n", "type": "registry:component", "target": "components/custom-ui/settings-dialog.tsx" } ], "type": "registry:block" }