{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "settings-preferences",
  "title": "Settings Preferences",
  "description": "Customize app experience, appearance, and accessibility.",
  "registryDependencies": [
    "button",
    "card",
    "field",
    "select",
    "separator",
    "switch"
  ],
  "files": [
    {
      "path": "registry/new-york/blocks/settings/settings-preferences.tsx",
      "content": "\"use client\";\n\nimport {\n  Calendar,\n  Clock,\n  Eye,\n  Globe,\n  Hash,\n  Keyboard,\n  Languages,\n  Layout,\n  Loader2,\n  Moon,\n  Palette,\n  Save,\n  Sun,\n  Type,\n  Volume2,\n} from \"lucide-react\";\nimport { useState } from \"react\";\nimport { cn } from \"@/lib/utils\";\nimport { Button } from \"@/registry/new-york/ui/button\";\nimport {\n  Card,\n  CardContent,\n  CardDescription,\n  CardHeader,\n  CardTitle,\n} from \"@/registry/new-york/ui/card\";\nimport {\n  Field,\n  FieldDescription,\n  FieldLabel,\n} from \"@/registry/new-york/ui/field\";\nimport {\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n} from \"@/registry/new-york/ui/select\";\nimport { Separator } from \"@/registry/new-york/ui/separator\";\nimport { Switch } from \"@/registry/new-york/ui/switch\";\n\nexport interface PreferencesData {\n  theme: \"light\" | \"dark\" | \"system\";\n  accentColor?: string;\n  fontSize: \"small\" | \"medium\" | \"large\";\n  language: string;\n  timezone: string;\n  dateFormat: string;\n  timeFormat: \"12h\" | \"24h\";\n  numberFormat: string;\n  density: \"compact\" | \"comfortable\" | \"spacious\";\n  animations: boolean;\n  reducedMotion: boolean;\n  highContrast: boolean;\n  screenReaderAnnouncements: boolean;\n  keyboardShortcuts: boolean;\n}\n\nexport interface SettingsPreferencesProps {\n  preferences?: PreferencesData;\n  onSave?: (data: PreferencesData) => Promise<void>;\n  className?: string;\n}\n\nconst accentColors = [\n  { value: \"blue\", label: \"Blue\", color: \"bg-blue-500\" },\n  { value: \"green\", label: \"Green\", color: \"bg-green-500\" },\n  { value: \"purple\", label: \"Purple\", color: \"bg-purple-500\" },\n  { value: \"orange\", label: \"Orange\", color: \"bg-orange-500\" },\n  { value: \"red\", label: \"Red\", color: \"bg-red-500\" },\n  { value: \"pink\", label: \"Pink\", color: \"bg-pink-500\" },\n];\n\nconst languages = [\n  { value: \"en\", label: \"English\" },\n  { value: \"es\", label: \"Spanish\" },\n  { value: \"fr\", label: \"French\" },\n  { value: \"de\", label: \"German\" },\n  { value: \"ja\", label: \"Japanese\" },\n  { value: \"zh\", label: \"Chinese\" },\n];\n\nconst timezones = [\n  { value: \"UTC\", label: \"UTC\" },\n  { value: \"America/New_York\", label: \"Eastern Time (ET)\" },\n  { value: \"America/Chicago\", label: \"Central Time (CT)\" },\n  { value: \"America/Denver\", label: \"Mountain Time (MT)\" },\n  { value: \"America/Los_Angeles\", label: \"Pacific Time (PT)\" },\n  { value: \"Europe/London\", label: \"London (GMT)\" },\n  { value: \"Europe/Paris\", label: \"Paris (CET)\" },\n  { value: \"Asia/Tokyo\", label: \"Tokyo (JST)\" },\n];\n\nconst dateFormats = [\n  { value: \"MM/DD/YYYY\", label: \"MM/DD/YYYY\" },\n  { value: \"DD/MM/YYYY\", label: \"DD/MM/YYYY\" },\n  { value: \"YYYY-MM-DD\", label: \"YYYY-MM-DD\" },\n  { value: \"DD MMM YYYY\", label: \"DD MMM YYYY\" },\n];\n\nconst numberFormats = [\n  { value: \"1,234.56\", label: \"1,234.56 (US)\" },\n  { value: \"1.234,56\", label: \"1.234,56 (EU)\" },\n  { value: \"1 234,56\", label: \"1 234,56 (FR)\" },\n];\n\nconst defaultPreferences: PreferencesData = {\n  theme: \"system\",\n  accentColor: \"blue\",\n  fontSize: \"medium\",\n  language: \"en\",\n  timezone: \"UTC\",\n  dateFormat: \"MM/DD/YYYY\",\n  timeFormat: \"12h\",\n  numberFormat: \"1,234.56\",\n  density: \"comfortable\",\n  animations: true,\n  reducedMotion: false,\n  highContrast: false,\n  screenReaderAnnouncements: true,\n  keyboardShortcuts: true,\n};\n\nexport default function SettingsPreferences({\n  preferences = defaultPreferences,\n  onSave,\n  className,\n}: SettingsPreferencesProps) {\n  const [isSaving, setIsSaving] = useState(false);\n  const [localPreferences, setLocalPreferences] =\n    useState<PreferencesData>(preferences);\n\n  const handleSave = async () => {\n    setIsSaving(true);\n    try {\n      await onSave?.(localPreferences);\n    } finally {\n      setIsSaving(false);\n    }\n  };\n\n  const updatePreference = <K extends keyof PreferencesData>(\n    key: K,\n    value: PreferencesData[K]\n  ) => {\n    setLocalPreferences((prev) => ({ ...prev, [key]: value }));\n  };\n\n  return (\n    <Card className={cn(\"w-full shadow-xs\", className)}>\n      <CardHeader>\n        <div className=\"flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between\">\n          <div className=\"flex min-w-0 flex-1 flex-col gap-2\">\n            <CardTitle className=\"wrap-break-word\">Preferences</CardTitle>\n            <CardDescription className=\"wrap-break-word\">\n              Customize your app experience and appearance\n            </CardDescription>\n          </div>\n          <div className=\"flex shrink-0 gap-2\">\n            <Button\n              className=\"w-full sm:w-auto\"\n              disabled={isSaving}\n              onClick={handleSave}\n              type=\"button\"\n            >\n              {isSaving ? (\n                <>\n                  <Loader2 className=\"size-4 animate-spin\" />\n                  <span className=\"whitespace-nowrap\">Saving…</span>\n                </>\n              ) : (\n                <>\n                  <Save className=\"size-4\" />\n                  <span className=\"whitespace-nowrap\">Save Changes</span>\n                </>\n              )}\n            </Button>\n          </div>\n        </div>\n      </CardHeader>\n      <CardContent>\n        <div className=\"grid gap-6 md:grid-cols-2\">\n          {/* Appearance Section */}\n          <div className=\"flex flex-col gap-4\">\n            <div className=\"flex items-center gap-2\">\n              <Palette className=\"size-5 text-muted-foreground\" />\n              <h3 className=\"font-semibold text-base\">Appearance</h3>\n            </div>\n\n            <div className=\"grid gap-4 md:grid-cols-2\">\n              {/* Theme Selection */}\n              <div className=\"flex flex-col gap-4 rounded-lg border p-4 md:col-span-2\">\n                <div className=\"flex items-center gap-2\">\n                  <div className=\"flex size-8 items-center justify-center rounded-lg bg-muted\">\n                    <Sun className=\"size-4\" />\n                  </div>\n                  <FieldLabel className=\"mb-0\">Theme</FieldLabel>\n                </div>\n                <div className=\"grid grid-cols-3 gap-2\">\n                  {[\n                    { value: \"light\", label: \"Light\", icon: Sun },\n                    { value: \"dark\", label: \"Dark\", icon: Moon },\n                    { value: \"system\", label: \"System\", icon: Layout },\n                  ].map((theme) => {\n                    const Icon = theme.icon;\n                    return (\n                      <button\n                        aria-label={`Select ${theme.label} theme`}\n                        className={cn(\n                          \"flex flex-col items-center gap-2 rounded-lg border-2 p-3 transition-all\",\n                          localPreferences.theme === theme.value\n                            ? \"border-primary bg-primary/5\"\n                            : \"border-muted hover:border-primary/50\"\n                        )}\n                        key={theme.value}\n                        onClick={() =>\n                          updatePreference(\n                            \"theme\",\n                            theme.value as \"light\" | \"dark\" | \"system\"\n                          )\n                        }\n                        type=\"button\"\n                      >\n                        <Icon className=\"size-5\" />\n                        <span className=\"font-medium text-xs\">\n                          {theme.label}\n                        </span>\n                      </button>\n                    );\n                  })}\n                </div>\n              </div>\n\n              {/* Accent Color */}\n              <div className=\"flex flex-col gap-4 rounded-lg border p-4\">\n                <div className=\"flex items-center gap-2\">\n                  <div className=\"flex size-8 items-center justify-center rounded-lg bg-muted\">\n                    <Palette className=\"size-4\" />\n                  </div>\n                  <FieldLabel className=\"mb-0\">Accent Color</FieldLabel>\n                </div>\n                <div className=\"flex flex-wrap gap-2\">\n                  {accentColors.map((color) => (\n                    <button\n                      aria-label={`Select ${color.label} accent color`}\n                      className={cn(\n                        \"flex size-9 items-center justify-center rounded-full border-2 transition-all\",\n                        localPreferences.accentColor === color.value\n                          ? \"scale-110 border-primary ring-2 ring-primary/20\"\n                          : \"border-muted hover:border-primary/50\"\n                      )}\n                      key={color.value}\n                      onClick={() =>\n                        updatePreference(\"accentColor\", color.value)\n                      }\n                      type=\"button\"\n                    >\n                      <div className={cn(\"size-5 rounded-full\", color.color)} />\n                    </button>\n                  ))}\n                </div>\n              </div>\n\n              {/* Font Size */}\n              <div className=\"flex flex-col gap-4 rounded-lg border p-4\">\n                <div className=\"flex items-center gap-2\">\n                  <div className=\"flex size-8 items-center justify-center rounded-lg bg-muted\">\n                    <Type className=\"size-4\" />\n                  </div>\n                  <FieldLabel className=\"mb-0\" htmlFor=\"font-size\">\n                    Font Size\n                  </FieldLabel>\n                </div>\n                <Select\n                  onValueChange={(value: \"small\" | \"medium\" | \"large\") =>\n                    updatePreference(\"fontSize\", value)\n                  }\n                  value={localPreferences.fontSize}\n                >\n                  <SelectTrigger className=\"w-full\" id=\"font-size\">\n                    <SelectValue />\n                  </SelectTrigger>\n                  <SelectContent>\n                    <SelectItem value=\"small\">Small</SelectItem>\n                    <SelectItem value=\"medium\">Medium</SelectItem>\n                    <SelectItem value=\"large\">Large</SelectItem>\n                  </SelectContent>\n                </Select>\n              </div>\n\n              {/* Density */}\n              <div className=\"flex flex-col gap-4 rounded-lg border p-4\">\n                <div className=\"flex items-center gap-2\">\n                  <div className=\"flex size-8 items-center justify-center rounded-lg bg-muted\">\n                    <Layout className=\"size-4\" />\n                  </div>\n                  <FieldLabel className=\"mb-0\" htmlFor=\"density\">\n                    Display Density\n                  </FieldLabel>\n                </div>\n                <Select\n                  onValueChange={(\n                    value: \"compact\" | \"comfortable\" | \"spacious\"\n                  ) => updatePreference(\"density\", value)}\n                  value={localPreferences.density}\n                >\n                  <SelectTrigger className=\"w-full\" id=\"density\">\n                    <SelectValue />\n                  </SelectTrigger>\n                  <SelectContent>\n                    <SelectItem value=\"compact\">Compact</SelectItem>\n                    <SelectItem value=\"comfortable\">Comfortable</SelectItem>\n                    <SelectItem value=\"spacious\">Spacious</SelectItem>\n                  </SelectContent>\n                </Select>\n              </div>\n            </div>\n          </div>\n\n          {/* Language & Region Section */}\n          <div className=\"flex flex-col gap-4\">\n            <div className=\"flex items-center gap-2\">\n              <Globe className=\"size-5 text-muted-foreground\" />\n              <h3 className=\"font-semibold text-base\">Language & Region</h3>\n            </div>\n\n            <div className=\"grid gap-4 md:grid-cols-2\">\n              {/* Language */}\n              <div className=\"flex flex-col gap-4 rounded-lg border p-4\">\n                <div className=\"flex items-center gap-2\">\n                  <div className=\"flex size-8 items-center justify-center rounded-lg bg-muted\">\n                    <Languages className=\"size-4\" />\n                  </div>\n                  <FieldLabel className=\"mb-0\" htmlFor=\"language\">\n                    Language\n                  </FieldLabel>\n                </div>\n                <Select\n                  onValueChange={(value) => updatePreference(\"language\", value)}\n                  value={localPreferences.language}\n                >\n                  <SelectTrigger className=\"w-full\" id=\"language\">\n                    <SelectValue />\n                  </SelectTrigger>\n                  <SelectContent>\n                    {languages.map((lang) => (\n                      <SelectItem key={lang.value} value={lang.value}>\n                        {lang.label}\n                      </SelectItem>\n                    ))}\n                  </SelectContent>\n                </Select>\n              </div>\n\n              {/* Timezone */}\n              <div className=\"flex flex-col gap-4 rounded-lg border p-4\">\n                <div className=\"flex items-center gap-2\">\n                  <div className=\"flex size-8 items-center justify-center rounded-lg bg-muted\">\n                    <Clock className=\"size-4\" />\n                  </div>\n                  <FieldLabel className=\"mb-0\" htmlFor=\"timezone\">\n                    Timezone\n                  </FieldLabel>\n                </div>\n                <Select\n                  onValueChange={(value) => updatePreference(\"timezone\", value)}\n                  value={localPreferences.timezone}\n                >\n                  <SelectTrigger className=\"w-full\" id=\"timezone\">\n                    <SelectValue />\n                  </SelectTrigger>\n                  <SelectContent>\n                    {timezones.map((tz) => (\n                      <SelectItem key={tz.value} value={tz.value}>\n                        {tz.label}\n                      </SelectItem>\n                    ))}\n                  </SelectContent>\n                </Select>\n              </div>\n\n              {/* Date Format */}\n              <div className=\"flex flex-col gap-4 rounded-lg border p-4\">\n                <div className=\"flex items-center gap-2\">\n                  <div className=\"flex size-8 items-center justify-center rounded-lg bg-muted\">\n                    <Calendar className=\"size-4\" />\n                  </div>\n                  <FieldLabel className=\"mb-0\" htmlFor=\"date-format\">\n                    Date Format\n                  </FieldLabel>\n                </div>\n                <Select\n                  onValueChange={(value) =>\n                    updatePreference(\"dateFormat\", value)\n                  }\n                  value={localPreferences.dateFormat}\n                >\n                  <SelectTrigger className=\"w-full\" id=\"date-format\">\n                    <SelectValue />\n                  </SelectTrigger>\n                  <SelectContent>\n                    {dateFormats.map((format) => (\n                      <SelectItem key={format.value} value={format.value}>\n                        {format.label}\n                      </SelectItem>\n                    ))}\n                  </SelectContent>\n                </Select>\n              </div>\n\n              {/* Time Format */}\n              <div className=\"flex flex-col gap-4 rounded-lg border p-4\">\n                <div className=\"flex items-center gap-2\">\n                  <div className=\"flex size-8 items-center justify-center rounded-lg bg-muted\">\n                    <Clock className=\"size-4\" />\n                  </div>\n                  <FieldLabel className=\"mb-0\" htmlFor=\"time-format\">\n                    Time Format\n                  </FieldLabel>\n                </div>\n                <Select\n                  onValueChange={(value: \"12h\" | \"24h\") =>\n                    updatePreference(\"timeFormat\", value)\n                  }\n                  value={localPreferences.timeFormat}\n                >\n                  <SelectTrigger className=\"w-full\" id=\"time-format\">\n                    <SelectValue />\n                  </SelectTrigger>\n                  <SelectContent>\n                    <SelectItem value=\"12h\">12-hour (AM/PM)</SelectItem>\n                    <SelectItem value=\"24h\">24-hour</SelectItem>\n                  </SelectContent>\n                </Select>\n              </div>\n\n              {/* Number Format */}\n              <div className=\"flex flex-col gap-4 rounded-lg border p-4 md:col-span-2\">\n                <div className=\"flex items-center gap-2\">\n                  <div className=\"flex size-8 items-center justify-center rounded-lg bg-muted\">\n                    <Hash className=\"size-4\" />\n                  </div>\n                  <FieldLabel className=\"mb-0\" htmlFor=\"number-format\">\n                    Number Format\n                  </FieldLabel>\n                </div>\n                <Select\n                  onValueChange={(value) =>\n                    updatePreference(\"numberFormat\", value)\n                  }\n                  value={localPreferences.numberFormat}\n                >\n                  <SelectTrigger className=\"w-full\" id=\"number-format\">\n                    <SelectValue />\n                  </SelectTrigger>\n                  <SelectContent>\n                    {numberFormats.map((format) => (\n                      <SelectItem key={format.value} value={format.value}>\n                        {format.label}\n                      </SelectItem>\n                    ))}\n                  </SelectContent>\n                </Select>\n              </div>\n            </div>\n          </div>\n        </div>\n\n        <Separator className=\"my-6\" />\n\n        {/* Accessibility Section */}\n        <div className=\"flex flex-col gap-4\">\n          <div className=\"flex items-center gap-2\">\n            <Eye className=\"size-5 text-muted-foreground\" />\n            <h3 className=\"font-semibold text-base\">Accessibility</h3>\n          </div>\n\n          <div className=\"grid gap-3 md:grid-cols-2\">\n            <Field>\n              <div className=\"flex items-center justify-between rounded-lg border p-3\">\n                <div className=\"flex items-center gap-3\">\n                  <div className=\"flex size-8 items-center justify-center rounded-lg bg-muted\">\n                    <Volume2 className=\"size-4\" />\n                  </div>\n                  <div className=\"flex flex-col gap-0.5\">\n                    <FieldLabel className=\"mb-0\" htmlFor=\"animations\">\n                      Animations\n                    </FieldLabel>\n                    <FieldDescription className=\"text-xs\">\n                      Smooth transitions\n                    </FieldDescription>\n                  </div>\n                </div>\n                <Switch\n                  checked={localPreferences.animations}\n                  id=\"animations\"\n                  onCheckedChange={(checked) =>\n                    updatePreference(\"animations\", checked)\n                  }\n                />\n              </div>\n            </Field>\n\n            <Field>\n              <div className=\"flex items-center justify-between rounded-lg border p-3\">\n                <div className=\"flex items-center gap-3\">\n                  <div className=\"flex size-8 items-center justify-center rounded-lg bg-muted\">\n                    <Eye className=\"size-4\" />\n                  </div>\n                  <div className=\"flex flex-col gap-0.5\">\n                    <FieldLabel className=\"mb-0\" htmlFor=\"reduced-motion\">\n                      Reduced Motion\n                    </FieldLabel>\n                    <FieldDescription className=\"text-xs\">\n                      Respect system preference\n                    </FieldDescription>\n                  </div>\n                </div>\n                <Switch\n                  checked={localPreferences.reducedMotion}\n                  id=\"reduced-motion\"\n                  onCheckedChange={(checked) =>\n                    updatePreference(\"reducedMotion\", checked)\n                  }\n                />\n              </div>\n            </Field>\n\n            <Field>\n              <div className=\"flex items-center justify-between rounded-lg border p-3\">\n                <div className=\"flex items-center gap-3\">\n                  <div className=\"flex size-8 items-center justify-center rounded-lg bg-muted\">\n                    <Eye className=\"size-4\" />\n                  </div>\n                  <div className=\"flex flex-col gap-0.5\">\n                    <FieldLabel className=\"mb-0\" htmlFor=\"high-contrast\">\n                      High Contrast\n                    </FieldLabel>\n                    <FieldDescription className=\"text-xs\">\n                      Better visibility\n                    </FieldDescription>\n                  </div>\n                </div>\n                <Switch\n                  checked={localPreferences.highContrast}\n                  id=\"high-contrast\"\n                  onCheckedChange={(checked) =>\n                    updatePreference(\"highContrast\", checked)\n                  }\n                />\n              </div>\n            </Field>\n\n            <Field>\n              <div className=\"flex items-center justify-between rounded-lg border p-3\">\n                <div className=\"flex items-center gap-3\">\n                  <div className=\"flex size-8 items-center justify-center rounded-lg bg-muted\">\n                    <Volume2 className=\"size-4\" />\n                  </div>\n                  <div className=\"flex flex-col gap-0.5\">\n                    <FieldLabel className=\"mb-0\" htmlFor=\"screen-reader\">\n                      Screen Reader\n                    </FieldLabel>\n                    <FieldDescription className=\"text-xs\">\n                      Enable announcements\n                    </FieldDescription>\n                  </div>\n                </div>\n                <Switch\n                  checked={localPreferences.screenReaderAnnouncements}\n                  id=\"screen-reader\"\n                  onCheckedChange={(checked) =>\n                    updatePreference(\"screenReaderAnnouncements\", checked)\n                  }\n                />\n              </div>\n            </Field>\n\n            <Field>\n              <div className=\"flex items-center justify-between rounded-lg border p-3\">\n                <div className=\"flex items-center gap-3\">\n                  <div className=\"flex size-8 items-center justify-center rounded-lg bg-muted\">\n                    <Keyboard className=\"size-4\" />\n                  </div>\n                  <div className=\"flex flex-col gap-0.5\">\n                    <FieldLabel className=\"mb-0\" htmlFor=\"keyboard-shortcuts\">\n                      Keyboard Shortcuts\n                    </FieldLabel>\n                    <FieldDescription className=\"text-xs\">\n                      Faster navigation\n                    </FieldDescription>\n                  </div>\n                </div>\n                <Switch\n                  checked={localPreferences.keyboardShortcuts}\n                  id=\"keyboard-shortcuts\"\n                  onCheckedChange={(checked) =>\n                    updatePreference(\"keyboardShortcuts\", checked)\n                  }\n                />\n              </div>\n            </Field>\n          </div>\n        </div>\n      </CardContent>\n    </Card>\n  );\n}\n",
      "type": "registry:ui"
    }
  ],
  "categories": [
    "block",
    "settings"
  ],
  "type": "registry:ui"
}