{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "color-picker",
  "title": "Color Picker",
  "type": "registry:ui",
  "files": [
    {
      "path": "packages/registry-svelte/components/color-picker/ColorPicker.svelte",
      "content": "<script lang=\"ts\" module>\n  import type { HTMLAttributes } from 'svelte/elements'\n\n  export interface ColorPickerProps extends HTMLAttributes<HTMLDivElement> {\n    value?: string\n    disabled?: boolean\n    /** Override the swatches shown below the color input. Pass [] to hide entirely. */\n    presets?: string[]\n    /** Hide the hex text field next to the color trigger. */\n    hideHexInput?: boolean\n    /** Fires with the new value on every change (input, hex edit, or swatch click). */\n    onValueChange?: (value: string) => void\n    ref?: HTMLDivElement | null\n  }\n</script>\n\n<script lang=\"ts\">\n  import { cn } from '$lib/utils'\n\n  const DEFAULT_PRESETS = [\n    '#ef4444',\n    '#f97316',\n    '#eab308',\n    '#22c55e',\n    '#14b8a6',\n    '#3b82f6',\n    '#8b5cf6',\n    '#ec4899',\n    '#ffffff',\n    '#d4d4d4',\n    '#737373',\n    '#171717',\n  ]\n\n  let {\n    value = $bindable(''),\n    disabled,\n    presets = DEFAULT_PRESETS,\n    hideHexInput = false,\n    onValueChange,\n    class: className,\n    ref = $bindable(null),\n    ...restProps\n  }: ColorPickerProps = $props()\n\n  const swatches = $derived(presets ?? [])\n\n  /** Native <input type=\"color\"> only accepts #rrggbb — keep a safe value while typing free-form hex. */\n  const safeColorValue = $derived(/^#[0-9a-fA-F]{6}$/.test(value || '') ? value : '#ffffff')\n\n  function update(next: string) {\n    value = next\n    onValueChange?.(next)\n  }\n</script>\n\n<div bind:this={ref} data-uipkge data-slot=\"color-picker\" class={cn('space-y-3', className)} {...restProps}>\n  <!-- Color trigger + hex field -->\n  <div class=\"flex items-center gap-2\">\n    <div\n      class=\"border-input relative h-10 w-10 shrink-0 overflow-hidden rounded-md border shadow-xs\"\n      style:background-color={value || '#ffffff'}\n    >\n      <input\n        type=\"color\"\n        value={safeColorValue}\n        {disabled}\n        aria-label=\"Pick color\"\n        class=\"absolute inset-0 h-full w-full cursor-pointer opacity-0 disabled:cursor-not-allowed\"\n        oninput={(e) => update(e.currentTarget.value)}\n      />\n    </div>\n    {#if !hideHexInput}\n      <input\n        type=\"text\"\n        value={value || ''}\n        placeholder=\"#000000\"\n        spellcheck=\"false\"\n        autocomplete=\"off\"\n        {disabled}\n        aria-label=\"Hex color\"\n        class=\"bg-background border-input text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 h-10 flex-1 rounded-md border px-3 text-sm uppercase shadow-xs outline-none focus-visible:ring-2 disabled:cursor-not-allowed disabled:opacity-50\"\n        oninput={(e) => update(e.currentTarget.value)}\n      />\n    {/if}\n  </div>\n\n  <!-- Preset swatches -->\n  {#if swatches.length}\n    <div class=\"flex flex-wrap gap-1.5\">\n      {#each swatches as color (color)}\n        <button\n          type=\"button\"\n          {disabled}\n          aria-label={`Select ${color}`}\n          style:background-color={color}\n          class={cn(\n            'ring-offset-background focus-visible:ring-ring/40 size-6 shrink-0 rounded-md shadow-sm transition-transform outline-none hover:scale-110 focus-visible:ring-2 disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:scale-100',\n            value?.toLowerCase() === color.toLowerCase() ? 'ring-foreground ring-2 ring-offset-2' : 'ring-border/50 ring-1',\n            color.toLowerCase() === '#ffffff' && 'ring-border',\n          )}\n          onclick={() => update(color)}\n        ></button>\n      {/each}\n    </div>\n  {/if}\n</div>\n",
      "type": "registry:ui",
      "target": "~/src/lib/components/ui/color-picker/ColorPicker.svelte"
    },
    {
      "path": "packages/registry-svelte/components/color-picker/index.ts",
      "content": "export { default as ColorPicker, type ColorPickerProps } from './ColorPicker.svelte'\n",
      "type": "registry:ui",
      "target": "~/src/lib/components/ui/color-picker/index.ts"
    }
  ],
  "dependencies": [],
  "devDependencies": [],
  "registryDependencies": [],
  "description": "Hex color input with a native color trigger, an editable hex field, and a preset swatch grid. Two-way bindable value with an onValueChange callback; presets are overridable or hideable.",
  "categories": [
    "form"
  ]
}