{
  "name": "checkbox",
  "type": "registry:component",
  "files": [
    {
      "name": "checkbox.component.ts",
      "content": "import {\n  booleanAttribute,\n  ChangeDetectionStrategy,\n  Component,\n  computed,\n  forwardRef,\n  input,\n  output,\n  signal,\n  ViewEncapsulation,\n} from '@angular/core';\nimport { type ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\n\nimport { NgIcon, provideIcons } from '@ng-icons/core';\nimport { lucideCheck } from '@ng-icons/lucide';\nimport type { ClassValue } from 'clsx';\n\nimport { ZardIdDirective } from '@/shared/core';\nimport { mergeClasses, noopFn } from '@/shared/utils/merge-classes';\n\nimport { checkboxLabelVariants, checkboxVariants } from './checkbox.variants';\n\ntype OnTouchedType = () => void;\ntype OnChangeType = (value: boolean) => void;\n\n@Component({\n  selector: 'z-checkbox, [z-checkbox]',\n  imports: [NgIcon, ZardIdDirective],\n  template: `\n    <span class=\"relative flex\" zardId=\"checkbox\" #z=\"zardId\">\n      <input\n        #input\n        type=\"checkbox\"\n        name=\"checkbox\"\n        [id]=\"zId() || z.id()\"\n        [class]=\"classes()\"\n        [checked]=\"checked()\"\n        [disabled]=\"disabled()\"\n        [attr.data-state]=\"checked() ? 'checked' : 'unchecked'\"\n        [attr.data-checked]=\"checked() ? '' : null\"\n        [attr.aria-invalid]=\"zInvalid() ? 'true' : null\"\n        (blur)=\"onCheckboxBlur()\"\n        (click)=\"onCheckboxChange()\"\n      />\n      <ng-icon\n        name=\"lucideCheck\"\n        class=\"text-primary-foreground pointer-events-none absolute top-1/2 left-1/2 flex -translate-1/2 items-center justify-center transition-opacity\"\n        [class]=\"checked() ? 'opacity-100' : 'opacity-0'\"\n      />\n    </span>\n    <label [class]=\"labelClasses()\" [for]=\"zId() || z.id()\">\n      <ng-content />\n    </label>\n  `,\n  providers: [\n    {\n      provide: NG_VALUE_ACCESSOR,\n      useExisting: forwardRef(() => ZardCheckboxComponent),\n      multi: true,\n    },\n  ],\n  changeDetection: ChangeDetectionStrategy.OnPush,\n  encapsulation: ViewEncapsulation.None,\n  viewProviders: [provideIcons({ lucideCheck })],\n  host: {\n    'data-slot': 'checkbox',\n    '[class]': \"(disabled() ? 'cursor-not-allowed' : 'cursor-pointer') + ' flex items-center gap-2'\",\n    '[attr.aria-disabled]': 'disabled() ? \"true\" : null',\n    '[attr.aria-invalid]': 'zInvalid() ? \"true\" : null',\n    '[attr.data-checked]': \"checked() ? '' : null\",\n    '[attr.data-state]': \"checked() ? 'checked' : 'unchecked'\",\n  },\n  exportAs: 'zCheckbox',\n})\nexport class ZardCheckboxComponent implements ControlValueAccessor {\n  readonly checkChange = output<boolean>();\n\n  readonly class = input<ClassValue>('');\n  readonly zDisabled = input(false, { transform: booleanAttribute });\n  readonly zInvalid = input(false, { transform: booleanAttribute });\n  readonly zId = input<string>('');\n\n  private onChange: OnChangeType = noopFn;\n  private onTouched: OnTouchedType = noopFn;\n\n  protected readonly classes = computed(() => mergeClasses(checkboxVariants(), this.class()));\n\n  readonly disabledByForm = signal(false);\n  protected readonly labelClasses = computed(() => mergeClasses(checkboxLabelVariants()));\n  protected readonly disabled = computed(() => this.zDisabled() || this.disabledByForm());\n  readonly checked = signal(false);\n\n  writeValue(val: boolean): void {\n    this.checked.set(val);\n  }\n\n  setDisabledState(isDisabled: boolean): void {\n    this.disabledByForm.set(isDisabled);\n  }\n\n  registerOnChange(fn: OnChangeType): void {\n    this.onChange = fn;\n  }\n\n  registerOnTouched(fn: OnTouchedType): void {\n    this.onTouched = fn;\n  }\n\n  onCheckboxBlur(): void {\n    this.onTouched();\n  }\n\n  onCheckboxChange(): void {\n    if (this.disabled()) {\n      return;\n    }\n\n    this.checked.update(v => !v);\n    this.onChange(this.checked());\n    this.checkChange.emit(this.checked());\n  }\n}\n"
    },
    {
      "name": "checkbox.variants.ts",
      "content": "import { cva } from 'class-variance-authority';\n\nexport const checkboxVariants = cva(\n  'cursor-[unset] peer size-4 shrink-0 appearance-none rounded-[4px] border border-input shadow-sm transition outline-none hover:shadow-md focus-visible:ring-3 focus-visible:ring-ring/50 focus-visible:border-ring disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 checked:border-primary checked:bg-primary checked:text-primary-foreground dark:checked:bg-primary',\n);\n\nexport const checkboxLabelVariants = cva('cursor-[unset] text-sm text-current empty:hidden select-none');\n"
    },
    {
      "name": "index.ts",
      "content": "export * from './checkbox.component';\nexport * from './checkbox.variants';\n"
    }
  ],
  "demos": [
    {
      "name": "basic.ts",
      "content": "import { Component } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\n\nimport { ZardCheckboxComponent } from '@/shared/components/checkbox/checkbox.component';\nimport { ZardFieldImports } from '@/shared/components/field/field.imports';\n\n@Component({\n  selector: 'z-demo-checkbox-basic',\n  imports: [ZardCheckboxComponent, ...ZardFieldImports, FormsModule],\n  template: `\n    <div z-field-group class=\"mx-auto w-56\">\n      <div z-field zOrientation=\"horizontal\">\n        <z-checkbox zId=\"terms-checkbox-basic\" [(ngModel)]=\"terms\" />\n        <label z-field-label for=\"terms-checkbox-basic\">Accept terms and conditions</label>\n      </div>\n    </div>\n  `,\n})\nexport class ZardDemoCheckboxBasicComponent {\n  terms = false;\n}\n"
    },
    {
      "name": "default.ts",
      "content": "import { Component } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\n\nimport { ZardCheckboxComponent } from '@/shared/components/checkbox/checkbox.component';\nimport { ZardFieldImports } from '@/shared/components/field/field.imports';\n\n@Component({\n  selector: 'z-demo-checkbox-default',\n  imports: [ZardCheckboxComponent, ...ZardFieldImports, FormsModule],\n  template: `\n    <div z-field-group class=\"min-w-sm\">\n      <div z-field zOrientation=\"horizontal\">\n        <z-checkbox zId=\"terms-checkbox\" [(ngModel)]=\"terms\" />\n        <label z-field-label for=\"terms-checkbox\">Accept terms and conditions</label>\n      </div>\n      <div z-field zOrientation=\"horizontal\">\n        <z-checkbox zId=\"terms-checkbox-2\" [(ngModel)]=\"termsWithDesc\" />\n        <div z-field-content>\n          <label z-field-label for=\"terms-checkbox-2\">Accept terms and conditions</label>\n          <p z-field-description>By clicking this checkbox, you agree to the terms.</p>\n        </div>\n      </div>\n      <div z-field zOrientation=\"horizontal\" data-disabled=\"true\">\n        <z-checkbox zId=\"toggle-checkbox\" zDisabled />\n        <label z-field-label for=\"toggle-checkbox\">Enable notifications</label>\n      </div>\n      <label z-field-label>\n        <div z-field zOrientation=\"horizontal\">\n          <z-checkbox zId=\"toggle-checkbox-2\" [(ngModel)]=\"notifications\" />\n          <div z-field-content>\n            <div z-field-title>Enable notifications</div>\n            <p z-field-description>You can enable or disable notifications at any time.</p>\n          </div>\n        </div>\n      </label>\n    </div>\n  `,\n})\nexport class ZardDemoCheckboxDefaultComponent {\n  terms = false;\n  termsWithDesc = true;\n  notifications = false;\n}\n"
    },
    {
      "name": "description.ts",
      "content": "import { Component } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\n\nimport { ZardCheckboxComponent } from '@/shared/components/checkbox/checkbox.component';\nimport { ZardFieldImports } from '@/shared/components/field/field.imports';\n\n@Component({\n  selector: 'z-demo-checkbox-description',\n  imports: [ZardCheckboxComponent, ...ZardFieldImports, FormsModule],\n  template: `\n    <div z-field-group class=\"mx-auto w-72\">\n      <div z-field zOrientation=\"horizontal\">\n        <z-checkbox zId=\"terms-checkbox-desc\" [(ngModel)]=\"terms\" />\n        <div z-field-content>\n          <label z-field-label for=\"terms-checkbox-desc\">Accept terms and conditions</label>\n          <p z-field-description>By clicking this checkbox, you agree to the terms and conditions.</p>\n        </div>\n      </div>\n    </div>\n  `,\n})\nexport class ZardDemoCheckboxDescriptionComponent {\n  terms = true;\n}\n"
    },
    {
      "name": "disabled.ts",
      "content": "import { Component } from '@angular/core';\n\nimport { ZardCheckboxComponent } from '@/shared/components/checkbox/checkbox.component';\nimport { ZardFieldImports } from '@/shared/components/field/field.imports';\n\n@Component({\n  selector: 'z-demo-checkbox-disabled',\n  imports: [ZardCheckboxComponent, ...ZardFieldImports],\n  template: `\n    <div z-field-group class=\"mx-auto w-56\">\n      <div z-field zOrientation=\"horizontal\" data-disabled=\"true\">\n        <z-checkbox zId=\"toggle-checkbox-disabled\" zDisabled />\n        <label z-field-label for=\"toggle-checkbox-disabled\">Enable notifications</label>\n      </div>\n    </div>\n  `,\n})\nexport class ZardDemoCheckboxDisabledComponent {}\n"
    },
    {
      "name": "group.ts",
      "content": "import { Component } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\n\nimport { ZardCheckboxComponent } from '@/shared/components/checkbox/checkbox.component';\nimport { ZardFieldImports } from '@/shared/components/field/field.imports';\n\n@Component({\n  selector: 'z-demo-checkbox-group',\n  imports: [ZardCheckboxComponent, ...ZardFieldImports, FormsModule],\n  template: `\n    <fieldset z-field-set>\n      <legend z-field-legend zVariant=\"label\">Show these items on the desktop:</legend>\n      <p z-field-description>Select the items you want to show on the desktop.</p>\n      <div z-field-group class=\"gap-3\">\n        <div z-field zOrientation=\"horizontal\">\n          <z-checkbox zId=\"finder-pref-9k2-hard-disks-ljj-checkbox\" [(ngModel)]=\"hardDisks\" />\n          <label z-field-label for=\"finder-pref-9k2-hard-disks-ljj-checkbox\" class=\"font-normal\">Hard disks</label>\n        </div>\n        <div z-field zOrientation=\"horizontal\">\n          <z-checkbox zId=\"finder-pref-9k2-external-disks-1yg-checkbox\" [(ngModel)]=\"externalDisks\" />\n          <label z-field-label for=\"finder-pref-9k2-external-disks-1yg-checkbox\" class=\"font-normal\">\n            External disks\n          </label>\n        </div>\n        <div z-field zOrientation=\"horizontal\">\n          <z-checkbox zId=\"finder-pref-9k2-cds-dvds-fzt-checkbox\" [(ngModel)]=\"cds\" />\n          <label z-field-label for=\"finder-pref-9k2-cds-dvds-fzt-checkbox\" class=\"font-normal\">\n            CDs, DVDs, and iPods\n          </label>\n        </div>\n        <div z-field zOrientation=\"horizontal\">\n          <z-checkbox zId=\"finder-pref-9k2-connected-servers-6l2-checkbox\" [(ngModel)]=\"connectedServers\" />\n          <label z-field-label for=\"finder-pref-9k2-connected-servers-6l2-checkbox\" class=\"font-normal\">\n            Connected servers\n          </label>\n        </div>\n      </div>\n    </fieldset>\n  `,\n})\nexport class ZardDemoCheckboxGroupComponent {\n  hardDisks = true;\n  externalDisks = true;\n  cds = false;\n  connectedServers = false;\n}\n"
    },
    {
      "name": "invalid.ts",
      "content": "import { Component } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\n\nimport { ZardCheckboxComponent } from '@/shared/components/checkbox/checkbox.component';\nimport { ZardFieldImports } from '@/shared/components/field/field.imports';\n\n@Component({\n  selector: 'z-demo-checkbox-invalid',\n  imports: [ZardCheckboxComponent, ...ZardFieldImports, FormsModule],\n  template: `\n    <div z-field-group class=\"mx-auto w-56\">\n      <div z-field zOrientation=\"horizontal\" data-invalid=\"true\">\n        <z-checkbox zId=\"terms-checkbox-invalid\" [(ngModel)]=\"terms\" zInvalid />\n        <label z-field-label for=\"terms-checkbox-invalid\">Accept terms and conditions</label>\n      </div>\n    </div>\n  `,\n})\nexport class ZardDemoCheckboxInvalidComponent {\n  terms = false;\n}\n"
    },
    {
      "name": "table.ts",
      "content": "import { Component, computed, signal } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\n\nimport { ZardCheckboxComponent } from '@/shared/components/checkbox/checkbox.component';\nimport { ZardTableImports } from '@/shared/components/table/table.imports';\n\ninterface Row {\n  id: string;\n  name: string;\n  email: string;\n  role: string;\n}\n\nconst TABLE_DATA: readonly Row[] = [\n  { id: '1', name: 'Sarah Chen', email: 'sarah.chen@example.com', role: 'Admin' },\n  { id: '2', name: 'Marcus Rodriguez', email: 'marcus.rodriguez@example.com', role: 'User' },\n  { id: '3', name: 'Priya Patel', email: 'priya.patel@example.com', role: 'User' },\n  { id: '4', name: 'David Kim', email: 'david.kim@example.com', role: 'Editor' },\n];\n\n@Component({\n  selector: 'z-demo-checkbox-table',\n  imports: [ZardCheckboxComponent, ...ZardTableImports, FormsModule],\n  template: `\n    <table z-table>\n      <thead z-table-header>\n        <tr z-table-row>\n          <th z-table-head class=\"w-8\">\n            <z-checkbox zId=\"select-all-checkbox\" [ngModel]=\"allSelected()\" (checkChange)=\"toggleAll($event)\" />\n          </th>\n          <th z-table-head>Name</th>\n          <th z-table-head>Email</th>\n          <th z-table-head>Role</th>\n        </tr>\n      </thead>\n      <tbody z-table-body>\n        @for (row of rows; track row.id) {\n          <tr z-table-row [attr.data-state]=\"isSelected(row.id) ? 'selected' : null\">\n            <td z-table-cell>\n              <z-checkbox\n                [zId]=\"'row-' + row.id + '-checkbox'\"\n                [ngModel]=\"isSelected(row.id)\"\n                (checkChange)=\"toggleRow(row.id, $event)\"\n              />\n            </td>\n            <td z-table-cell class=\"font-medium\">{{ row.name }}</td>\n            <td z-table-cell>{{ row.email }}</td>\n            <td z-table-cell>{{ row.role }}</td>\n          </tr>\n        }\n      </tbody>\n    </table>\n  `,\n})\nexport class ZardDemoCheckboxTableComponent {\n  protected readonly rows = TABLE_DATA;\n  private readonly selectedRows = signal<ReadonlySet<string>>(new Set(['1']));\n\n  protected readonly allSelected = computed(() => this.selectedRows().size === this.rows.length);\n\n  protected isSelected(id: string): boolean {\n    return this.selectedRows().has(id);\n  }\n\n  protected toggleAll(checked: boolean): void {\n    this.selectedRows.set(checked ? new Set(this.rows.map(row => row.id)) : new Set());\n  }\n\n  protected toggleRow(id: string, checked: boolean): void {\n    const next = new Set(this.selectedRows());\n    if (checked) {\n      next.add(id);\n    } else {\n      next.delete(id);\n    }\n    this.selectedRows.set(next);\n  }\n}\n"
    }
  ]
}
