{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "settings-page",
  "title": "Settings Page",
  "type": "registry:page",
  "files": [
    {
      "path": "packages/registry-svelte/blocks/settings-page/SettingsPage.svelte",
      "content": "<script lang=\"ts\" module>\n  import type { Component } from 'svelte'\n\n  export type SectionId = 'profile' | 'notifications' | 'appearance' | 'workspace' | 'billing' | 'danger'\n\n  export interface SettingsSection {\n    id: SectionId\n    label: string\n    icon: Component\n  }\n\n  export interface SettingsPageProps {\n    /** Override the nav. Ids must still match the built-in panels. */\n    sections?: SettingsSection[]\n    /** Initially active section id. */\n    initialSection?: SectionId\n    class?: string\n  }\n</script>\n\n<script lang=\"ts\">\n  import { Bell, Building2, CreditCard, Palette, TriangleAlert, User } from '@lucide/svelte'\n  import { cn } from '$lib/utils'\n  import { Button } from '$lib/components/ui/button'\n  import { Input } from '$lib/components/ui/input'\n  import { Label } from '$lib/components/ui/label'\n  import { SectionCard } from '$lib/components/ui/section-card'\n  import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '$lib/components/ui/select'\n  import { Separator } from '$lib/components/ui/separator'\n  import { Switch } from '$lib/components/ui/switch'\n  import { Textarea } from '$lib/components/ui/textarea'\n  import {\n    Dialog,\n    DialogContent,\n    DialogDescription,\n    DialogFooter,\n    DialogHeader,\n    DialogTitle,\n  } from '$lib/components/ui/dialog'\n\n  let { sections: sectionsProp, initialSection = 'profile', class: className }: SettingsPageProps = $props()\n\n  const defaultSections: SettingsSection[] = [\n    { id: 'profile', label: 'Profile', icon: User },\n    { id: 'notifications', label: 'Notifications', icon: Bell },\n    { id: 'appearance', label: 'Appearance', icon: Palette },\n    { id: 'workspace', label: 'Workspace', icon: Building2 },\n    { id: 'billing', label: 'Billing', icon: CreditCard },\n    { id: 'danger', label: 'Danger zone', icon: TriangleAlert },\n  ]\n\n  const sections = $derived(sectionsProp ?? defaultSections)\n  // svelte-ignore state_referenced_locally: initialSection seeds state once by design.\n  let active = $state<SectionId>(initialSection)\n\n  let notifyEmail = $state(true)\n  let notifyPush = $state(false)\n  let notifyDigest = $state(true)\n  let themeChoice = $state<'light' | 'dark' | 'system'>('system')\n  let deleteOpen = $state(false)\n  let deleteConfirm = $state('')\n\n  function switchPanel(id: SectionId) {\n    active = id\n  }\n</script>\n\n<div\n  data-slot=\"settings-page\"\n  class={cn('bg-background border-border flex min-h-svh flex-col rounded-xl border lg:flex-row', className)}\n>\n  <!-- Nav rail -->\n  <nav class=\"border-border shrink-0 border-b p-3 lg:w-56 lg:border-r lg:border-b-0\" aria-label=\"Settings sections\">\n    <div\n      class=\"flex [scrollbar-width:none] gap-1 overflow-x-auto lg:flex-col lg:overflow-visible [&::-webkit-scrollbar]:hidden\"\n    >\n      {#each sections as section (section.id)}\n        {@const SectionIcon = section.icon}\n        <button\n          type=\"button\"\n          class=\"focus-visible:ring-ring flex shrink-0 items-center gap-2 rounded-md px-3 py-2 text-sm font-medium transition-colors focus-visible:ring-2 focus-visible:outline-none {active ===\n          section.id\n            ? section.id === 'danger'\n              ? 'text-destructive bg-destructive/10'\n              : 'bg-accent text-accent-foreground'\n            : 'text-muted-foreground hover:bg-accent/50 hover:text-foreground'}\"\n          aria-current={active === section.id ? 'page' : undefined}\n          onclick={() => switchPanel(section.id)}\n        >\n          <SectionIcon class=\"size-4\" aria-hidden=\"true\" />\n          {section.label}\n        </button>\n      {/each}\n    </div>\n  </nav>\n\n  <!-- Content pane -->\n  <div class=\"flex min-w-0 flex-1 flex-col\">\n    <!-- Profile -->\n    {#if active === 'profile'}\n      <section class=\"flex flex-1 flex-col\">\n        <div class=\"flex-1 space-y-6 p-6\">\n          <SectionCard title=\"Public profile\" description=\"How teammates see you across the workspace.\">\n            <div class=\"space-y-4\">\n              <div class=\"space-y-2\">\n                <Label for=\"sp-name\">Display name</Label>\n                <Input id=\"sp-name\" value=\"Amara Osei\" />\n              </div>\n              <div class=\"space-y-2\">\n                <Label for=\"sp-email\">Email</Label>\n                <Input id=\"sp-email\" value=\"amara@acme.com\" type=\"email\" />\n              </div>\n              <div class=\"space-y-2\">\n                <Label for=\"sp-bio\">Bio</Label>\n                <Textarea id=\"sp-bio\" value=\"Design engineer. Builds systems, breaks assumptions.\" rows={3} />\n              </div>\n              <div class=\"space-y-2\">\n                <Label for=\"sp-role\">Role</Label>\n                <Select value=\"editor\">\n                  <SelectTrigger id=\"sp-role\" class=\"w-full sm:w-56\">\n                    <SelectValue />\n                  </SelectTrigger>\n                  <SelectContent>\n                    <SelectItem value=\"admin\">Admin</SelectItem>\n                    <SelectItem value=\"editor\">Editor</SelectItem>\n                    <SelectItem value=\"viewer\">Viewer</SelectItem>\n                  </SelectContent>\n                </Select>\n              </div>\n            </div>\n          </SectionCard>\n        </div>\n        <div class=\"border-border flex items-center justify-end gap-2 border-t p-4\">\n          <Button variant=\"ghost\" size=\"sm\">Discard</Button>\n          <Button size=\"sm\">Save changes</Button>\n        </div>\n      </section>\n\n      <!-- Notifications -->\n    {:else if active === 'notifications'}\n      <section class=\"flex-1 p-6\">\n        <SectionCard title=\"Notifications\" description=\"Choose what reaches you and where.\">\n          <ul class=\"-my-4 divide-y\">\n            <li class=\"flex items-center justify-between gap-4 py-4\">\n              <div>\n                <p class=\"text-sm font-medium\">Email notifications</p>\n                <p class=\"text-muted-foreground text-xs\">Mentions, assignments and approvals.</p>\n              </div>\n              <Switch bind:checked={notifyEmail} aria-label=\"Toggle email notifications\" />\n            </li>\n            <li class=\"flex items-center justify-between gap-4 py-4\">\n              <div>\n                <p class=\"text-sm font-medium\">Push notifications</p>\n                <p class=\"text-muted-foreground text-xs\">Real-time browser alerts while you work.</p>\n              </div>\n              <Switch bind:checked={notifyPush} aria-label=\"Toggle push notifications\" />\n            </li>\n            <li class=\"flex items-center justify-between gap-4 py-4\">\n              <div>\n                <p class=\"text-sm font-medium\">Weekly digest</p>\n                <p class=\"text-muted-foreground text-xs\">A summary of everything, every Monday.</p>\n              </div>\n              <Switch bind:checked={notifyDigest} aria-label=\"Toggle weekly digest\" />\n            </li>\n          </ul>\n        </SectionCard>\n      </section>\n\n      <!-- Appearance -->\n    {:else if active === 'appearance'}\n      <section class=\"flex-1 p-6\">\n        <SectionCard title=\"Appearance\" description=\"Theme follows your system by default.\">\n          <div class=\"space-y-5\">\n            <div class=\"grid grid-cols-3 gap-3\">\n              {#each ['light', 'dark', 'system'] as theme (theme)}\n                <button\n                  type=\"button\"\n                  class=\"focus-visible:ring-ring rounded-lg border p-3 text-left transition-colors focus-visible:ring-2 focus-visible:outline-none {themeChoice ===\n                  theme\n                    ? 'border-primary ring-primary/20 ring-2'\n                    : 'hover:bg-accent/50'}\"\n                  onclick={() => (themeChoice = theme as 'light' | 'dark' | 'system')}\n                >\n                  <span class=\"block text-sm font-medium capitalize\">{theme}</span>\n                  <span class=\"text-muted-foreground block text-xs\">\n                    {theme === 'light' ? 'Bright surfaces' : theme === 'dark' ? 'Low-light friendly' : 'Match device'}\n                  </span>\n                </button>\n              {/each}\n            </div>\n            <Separator />\n            <div class=\"flex items-center justify-between\">\n              <div>\n                <p class=\"text-sm font-medium\">Reduced motion</p>\n                <p class=\"text-muted-foreground text-xs\">Collapse animations to instant transitions.</p>\n              </div>\n              <Switch checked={false} aria-label=\"Toggle reduced motion\" />\n            </div>\n          </div>\n        </SectionCard>\n      </section>\n\n      <!-- Workspace -->\n    {:else if active === 'workspace'}\n      <section class=\"flex-1 p-6\">\n        <SectionCard title=\"Workspace\" description=\"Identity and defaults for everyone here.\">\n          <div class=\"space-y-4\">\n            <div class=\"space-y-2\">\n              <Label for=\"sp-ws-name\">Workspace name</Label>\n              <Input id=\"sp-ws-name\" value=\"Acme Inc\" />\n            </div>\n            <div class=\"space-y-2\">\n              <Label for=\"sp-ws-url\">URL slug</Label>\n              <div class=\"flex\">\n                <span\n                  class=\"border-border bg-muted text-muted-foreground flex items-center rounded-l-md border px-3 font-mono text-xs\"\n                >\n                  acme.uipkge.app\n                </span>\n                <Input id=\"sp-ws-url\" value=\"acme\" class=\"rounded-l-none font-mono text-xs\" />\n              </div>\n            </div>\n            <p class=\"text-muted-foreground text-xs\">16 members · 4 pending invites</p>\n          </div>\n        </SectionCard>\n      </section>\n\n      <!-- Billing -->\n    {:else if active === 'billing'}\n      <section class=\"flex-1 p-6\">\n        <SectionCard title=\"Billing\" description=\"Plan, seats and invoices.\">\n          <div class=\"flex items-center justify-between gap-4\">\n            <div>\n              <p class=\"text-sm font-medium\">Team plan · $12 / seat / month</p>\n              <p class=\"text-muted-foreground mt-1 text-xs\">Next invoice Sep 1, 2026 · 18 seats</p>\n            </div>\n            <Button variant=\"outline\" size=\"sm\">Manage billing</Button>\n          </div>\n        </SectionCard>\n      </section>\n\n      <!-- Danger zone -->\n    {:else}\n      <section class=\"flex-1 p-6\">\n        <div class=\"border-destructive/40 rounded-xl border p-6\">\n          <div class=\"flex items-center justify-between gap-4\">\n            <div>\n              <p class=\"text-destructive text-sm font-medium\">Delete this workspace</p>\n              <p class=\"text-muted-foreground mt-1 text-xs\">\n                All projects, members and data will be permanently removed.\n              </p>\n            </div>\n            <Button variant=\"destructive\" size=\"sm\" onclick={() => (deleteOpen = true)}>Delete…</Button>\n          </div>\n        </div>\n      </section>\n    {/if}\n  </div>\n\n  <Dialog bind:open={deleteOpen}>\n    <DialogContent class=\"max-w-sm\">\n      <DialogHeader>\n        <DialogTitle>Delete workspace?</DialogTitle>\n        <DialogDescription>\n          This removes Acme Inc and all of its data for every member. This cannot be undone.\n        </DialogDescription>\n      </DialogHeader>\n      <Input bind:value={deleteConfirm} placeholder='Type \"DELETE\" to confirm' />\n      <DialogFooter>\n        <Button variant=\"outline\" size=\"sm\" onclick={() => (deleteOpen = false)}>Cancel</Button>\n        <Button variant=\"destructive\" size=\"sm\" disabled={deleteConfirm !== 'DELETE'} onclick={() => (deleteOpen = false)}>\n          Delete forever\n        </Button>\n      </DialogFooter>\n    </DialogContent>\n  </Dialog>\n</div>\n",
      "type": "registry:page",
      "target": "~/src/lib/components/blocks/settings-page/SettingsPage.svelte"
    }
  ],
  "dependencies": [
    "@lucide/svelte"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/svelte/button.json",
    "https://uipkge.dev/r/svelte/dialog.json",
    "https://uipkge.dev/r/svelte/input.json",
    "https://uipkge.dev/r/svelte/label.json",
    "https://uipkge.dev/r/svelte/section-card.json",
    "https://uipkge.dev/r/svelte/select.json",
    "https://uipkge.dev/r/svelte/separator.json",
    "https://uipkge.dev/r/svelte/switch.json",
    "https://uipkge.dev/r/svelte/textarea.json"
  ],
  "description": "Linear-style settings shell: a nav rail of icon sections (collapses to a horizontal tab strip on narrow screens) switching between fully composed panels — profile form with sticky save bar, notification switches, theme picker, workspace identity, billing summary, and a type-to-confirm danger zone. Swap the panel internals for your own forms.",
  "categories": [
    "layout",
    "dashboard"
  ]
}