{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "color-picker",
  "title": "Color Picker",
  "type": "registry:ui",
  "files": [
    {
      "path": "packages/registry-angular/components/color-picker/color-picker.component.ts",
      "content": "import {\n  ChangeDetectorRef,\n  Component,\n  EventEmitter,\n  Input,\n  Output,\n  booleanAttribute,\n  forwardRef,\n  inject,\n  signal,\n  ChangeDetectionStrategy,\n} from '@angular/core'\nimport { NG_VALUE_ACCESSOR, type ControlValueAccessor } from '@angular/forms'\nimport { cn } from '@/lib/utils'\n\nconst 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/**\n * Angular port of the React ColorPicker: a native colour input hidden over a swatch\n * (the swatch shows the current value), an optional hex text field, and a row of\n * preset swatches. Controlled like React: `value` / `valueChange` (`[(value)]`), plus\n * NG_VALUE_ACCESSOR for forms.\n */\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-color-picker, [ui-color-picker]',\n  standalone: true,\n  providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => UiColorPickerComponent), multi: true }],\n  host: {\n    'data-uipkge': '',\n    'data-slot': 'color-picker',\n    '[class]': 'hostClass',\n  },\n  template: `\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]=\"disabled\"\n          aria-label=\"Pick color\"\n          class=\"absolute inset-0 h-full w-full cursor-pointer opacity-0 disabled:cursor-not-allowed\"\n          (input)=\"emit($any($event.target).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]=\"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          (input)=\"emit($any($event.target).value)\"\n          (blur)=\"onTouched()\"\n        />\n      }\n    </div>\n    @if (swatches.length > 0) {\n      <div class=\"flex flex-wrap gap-1.5\">\n        @for (color of swatches; track color) {\n          <button\n            type=\"button\"\n            [disabled]=\"disabled\"\n            [attr.aria-label]=\"'Select ' + color\"\n            [style.background-color]=\"color\"\n            [class]=\"swatchClass(color)\"\n            (click)=\"emit(color)\"\n          ></button>\n        }\n      </div>\n    }\n  `,\n})\nexport class UiColorPickerComponent implements ControlValueAccessor {\n  // Zoneless-safe: form writes happen outside template events, so schedule a repaint.\n  private readonly cdr = inject(ChangeDetectorRef)\n  private readonly _value = signal<string | undefined>(undefined)\n  private formBound = false\n\n  /** Current hex value (React `value`). */\n  @Input()\n  set value(v: string | null | undefined) {\n    this._value.set(v ?? undefined)\n  }\n  get value(): string | undefined {\n    return this._value()\n  }\n  @Output() valueChange = new EventEmitter<string>()\n  @Input({ transform: booleanAttribute }) disabled = false\n  /** Override the swatches shown below the color input. Pass [] to hide entirely. */\n  @Input() presets: string[] = DEFAULT_PRESETS\n  /** Hide the hex text field next to the color trigger. */\n  @Input({ transform: booleanAttribute }) hideHexInput = false\n  @Input('class') className?: string\n\n  onTouched: () => void = () => {}\n  private onChange: (v: string) => void = () => {}\n\n  get hostClass(): string {\n    return cn('block space-y-3', this.className)\n  }\n\n  get swatches(): string[] {\n    return this.presets ?? []\n  }\n\n  /** Native <input type=\"color\"> only accepts #rrggbb — keep a safe value while typing free-form hex. */\n  get safeColorValue(): string {\n    return /^#[0-9a-fA-F]{6}$/.test(this.value || '') ? (this.value as string) : '#ffffff'\n  }\n\n  swatchClass(color: string): string {\n    return 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      this.value?.toLowerCase() === color.toLowerCase()\n        ? 'ring-foreground ring-2 ring-offset-2'\n        : 'ring-border/50 ring-1',\n      color.toLowerCase() === '#ffffff' && 'ring-border',\n    )\n  }\n\n  emit(next: string): void {\n    if (this.disabled) return\n    // Controlled like React; a bound form control owns the value, so reflect it locally.\n    if (this.formBound) this._value.set(next)\n    this.valueChange.emit(next)\n    this.onChange(next)\n  }\n\n  writeValue(v: string | null): void {\n    this._value.set(v ?? undefined)\n    this.cdr.markForCheck()\n  }\n  registerOnChange(fn: (v: string) => void): void {\n    this.formBound = true\n    this.onChange = fn\n  }\n  registerOnTouched(fn: () => void): void {\n    this.onTouched = fn\n  }\n  setDisabledState(isDisabled: boolean): void {\n    this.disabled = isDisabled\n    this.cdr.markForCheck()\n  }\n}\n",
      "type": "registry:ui",
      "target": "~/src/app/components/ui/color-picker/color-picker.component.ts"
    },
    {
      "path": "packages/registry-angular/components/color-picker/index.ts",
      "content": "export { UiColorPickerComponent } from './color-picker.component'\n",
      "type": "registry:ui",
      "target": "~/src/app/components/ui/color-picker/index.ts"
    }
  ],
  "dependencies": [
    "@angular/forms"
  ],
  "devDependencies": [],
  "registryDependencies": [],
  "description": "Hex color input: a native color swatch, an optional hex text field and a preset swatch row. Controlled via value / valueChange and usable as a form control.",
  "categories": [
    "form"
  ]
}