{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "adjustments-horizontal",
  "type": "registry:component",
  "title": "adjustments-horizontal",
  "description": "Animated adjustments-horizontal icon for Angular",
  "author": "Aniket Pawar <pawaraniket508@gmail.com>",
  "registryDependencies": [],
  "dependencies": [],
  "files": [
    {
      "path": "packages/angular/src/icons/adjustments-horizontal.ts",
      "type": "registry:component",
      "target": "~/src/app/components/heroicons-animated/adjustments-horizontal.ts",
      "content": "import {\n  ChangeDetectionStrategy,\n  Component,\n  computed,\n  DestroyRef,\n  effect,\n  inject,\n  input,\n  signal,\n} from \"@angular/core\";\n\ntype HorizontalStateKey =\n  | \"row1RightX1\"\n  | \"row1LeftX2\"\n  | \"row1KnobCX\"\n  | \"row2RightX1\"\n  | \"row2LeftX2\"\n  | \"row2KnobCX\"\n  | \"row3RightX1\"\n  | \"row3LeftX2\"\n  | \"row3KnobCX\";\n\ntype HorizontalState = Record<HorizontalStateKey, number>;\n\n@Component({\n  selector: \"hi-adjustments-horizontal\",\n  standalone: true,\n  changeDetection: ChangeDetectionStrategy.OnPush,\n  host: {\n    \"[attr.aria-label]\": \"'adjustments-horizontal'\",\n    role: \"img\",\n    \"(mouseenter)\": \"onMouseEnter()\",\n    \"(mouseleave)\": \"onMouseLeave()\",\n  },\n  template: `<svg\n    xmlns=\"http://www.w3.org/2000/svg\"\n    [attr.width]=\"size()\"\n    [attr.height]=\"size()\"\n    viewBox=\"0 0 24 24\"\n    fill=\"none\"\n    [attr.stroke]=\"color()\"\n    [attr.stroke-width]=\"strokeWidth()\"\n    stroke-linecap=\"round\"\n    stroke-linejoin=\"round\"\n    class=\"icon-svg\"\n  >\n    <line [attr.x1]=\"row1RightX1()\" x2=\"20.25\" y1=\"6\" y2=\"6\" />\n    <line x1=\"3.75\" [attr.x2]=\"row1LeftX2()\" y1=\"6\" y2=\"6\" />\n    <circle [attr.cx]=\"row1KnobCX()\" cy=\"6\" fill=\"none\" r=\"1.5\" />\n\n    <line [attr.x1]=\"row2RightX1()\" x2=\"20.25\" y1=\"12\" y2=\"12\" />\n    <line x1=\"3.75\" [attr.x2]=\"row2LeftX2()\" y1=\"12\" y2=\"12\" />\n    <circle [attr.cx]=\"row2KnobCX()\" cy=\"12\" fill=\"none\" r=\"1.5\" />\n\n    <line [attr.x1]=\"row3RightX1()\" x2=\"20.25\" y1=\"18\" y2=\"18\" />\n    <line x1=\"3.75\" [attr.x2]=\"row3LeftX2()\" y1=\"18\" y2=\"18\" />\n    <circle [attr.cx]=\"row3KnobCX()\" cy=\"18\" fill=\"none\" r=\"1.5\" />\n  </svg>`,\n  styles: [\n    `\n      :host {\n        display: inline-block;\n      }\n      .icon-svg {\n        transform-box: fill-box;\n        transform-origin: center;\n      }\n    `,\n  ],\n})\nexport class AdjustmentsHorizontalIcon {\n  readonly color = input(\"currentColor\");\n  readonly size = input(28);\n  readonly strokeWidth = input(1.5);\n  readonly animate = input(false);\n\n  protected isHovered = signal(false);\n  protected shouldAnimate = computed(() => this.animate() || this.isHovered());\n\n  protected row1RightX1 = signal(10.5);\n  protected row1LeftX2 = signal(7.5);\n  protected row1KnobCX = signal(9);\n  protected row2RightX1 = signal(16.5);\n  protected row2LeftX2 = signal(13.5);\n  protected row2KnobCX = signal(15);\n  protected row3RightX1 = signal(10.5);\n  protected row3LeftX2 = signal(7.5);\n  protected row3KnobCX = signal(9);\n\n  private readonly DURATION_MS = 450;\n  private readonly NORMAL_STATE: HorizontalState = {\n    row1RightX1: 10.5,\n    row1LeftX2: 7.5,\n    row1KnobCX: 9,\n    row2RightX1: 16.5,\n    row2LeftX2: 13.5,\n    row2KnobCX: 15,\n    row3RightX1: 10.5,\n    row3LeftX2: 7.5,\n    row3KnobCX: 9,\n  };\n  private readonly ANIMATE_STATE: HorizontalState = {\n    row1RightX1: 13.5,\n    row1LeftX2: 10.5,\n    row1KnobCX: 12,\n    row2RightX1: 13.5,\n    row2LeftX2: 10.5,\n    row2KnobCX: 12,\n    row3RightX1: 13.5,\n    row3LeftX2: 10.5,\n    row3KnobCX: 12,\n  };\n\n  private rafId = 0;\n  private animationToken = 0;\n  private readonly destroyRef = inject(DestroyRef);\n\n  private readonly signalMap: Record<\n    HorizontalStateKey,\n    ReturnType<typeof signal<number>>\n  > = {} as Record<HorizontalStateKey, ReturnType<typeof signal<number>>>;\n\n  constructor() {\n    this.signalMap.row1RightX1 = this.row1RightX1;\n    this.signalMap.row1LeftX2 = this.row1LeftX2;\n    this.signalMap.row1KnobCX = this.row1KnobCX;\n    this.signalMap.row2RightX1 = this.row2RightX1;\n    this.signalMap.row2LeftX2 = this.row2LeftX2;\n    this.signalMap.row2KnobCX = this.row2KnobCX;\n    this.signalMap.row3RightX1 = this.row3RightX1;\n    this.signalMap.row3LeftX2 = this.row3LeftX2;\n    this.signalMap.row3KnobCX = this.row3KnobCX;\n\n    effect(() => {\n      this.runStateAnimation(this.shouldAnimate());\n    });\n    this.destroyRef.onDestroy(() => {\n      this.animationToken++;\n      if (this.rafId) {\n        cancelAnimationFrame(this.rafId);\n        this.rafId = 0;\n      }\n    });\n  }\n\n  private easeOutBack(progress: number): number {\n    const c1 = 1.701_58;\n    const c3 = c1 + 1;\n    const p = progress - 1;\n    return 1 + c3 * p * p * p + c1 * p * p;\n  }\n\n  private lerp(from: number, to: number, progress: number): number {\n    return from + (to - from) * progress;\n  }\n\n  private runStateAnimation(active: boolean) {\n    const target = active ? this.ANIMATE_STATE : this.NORMAL_STATE;\n    const stateKeys = Object.keys(this.NORMAL_STATE) as HorizontalStateKey[];\n    const startValues = {} as HorizontalState;\n    for (const key of stateKeys) {\n      startValues[key] = this.signalMap[key]();\n    }\n\n    const currentToken = ++this.animationToken;\n    if (this.rafId) {\n      cancelAnimationFrame(this.rafId);\n      this.rafId = 0;\n    }\n\n    const start = performance.now();\n    const tick = (now: number) => {\n      if (currentToken !== this.animationToken) {\n        return;\n      }\n      const rawProgress = Math.min((now - start) / this.DURATION_MS, 1);\n      const easedProgress = this.easeOutBack(rawProgress);\n\n      for (const key of stateKeys) {\n        this.signalMap[key].set(\n          this.lerp(startValues[key], target[key], easedProgress)\n        );\n      }\n\n      if (rawProgress < 1) {\n        this.rafId = requestAnimationFrame(tick);\n      } else {\n        this.rafId = 0;\n      }\n    };\n\n    this.rafId = requestAnimationFrame(tick);\n  }\n\n  onMouseEnter() {\n    this.isHovered.set(true);\n  }\n  onMouseLeave() {\n    this.isHovered.set(false);\n  }\n}\n"
    }
  ]
}
