{"version":3,"file":"ng-forge-dynamic-forms-bootstrap-lazy-multi-checkbox.mjs","mappings":";;;;;;;AAqEc;;;;AAIH;;IAGA;;;;;AAKP;;;AAGF;AAEI;;AAEF;AAIF;AACE;AACE;AAEA;AACE;;AAEJ;AAEA;AACE;AACA;;;AAIE;;AAEJ;;;AAIA;;;AAGI;AACE;AACA;;;AAEF;;AAEJ;;;AArDiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAlBlB;;;;AA1CS","names":[],"ignoreList":[],"sources":["../../../../packages/dynamic-forms-bootstrap/src/lib/fields/multi-checkbox/bs-multi-checkbox.component.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, computed, input, linkedSignal } from '@angular/core';\nimport { FieldOption, ValueType } from '@ng-forge/dynamic-forms';\nimport { DynamicTextPipe } from '@ng-forge/dynamic-forms/integration';\nimport { injectNgForgeField, NgForgeFieldHost, isEqual, NgForgeControl } from '@ng-forge/dynamic-forms/integration';\nimport { explicitEffect } from 'ngxtension/explicit-effect';\nimport { BsMultiCheckboxProps } from './bs-multi-checkbox.type';\nimport { AsyncPipe } from '@angular/common';\n\n@Component({\n  selector: 'df-bs-multi-checkbox',\n  imports: [DynamicTextPipe, AsyncPipe, NgForgeControl],\n  styleUrl: '../../styles/_form-field.scss',\n  hostDirectives: [NgForgeFieldHost],\n  template: `\n    @let f = ngf.field();\n    @let checked = checkedValuesMap();\n    @if (ngf.label(); as label) {\n      <div class=\"form-label\">{{ label | dynamicText | async }}</div>\n    }\n\n    <div class=\"checkbox-group\">\n      @for (option of options(); track option.value; let i = $index) {\n        <div\n          class=\"form-check\"\n          [class.form-switch]=\"props()?.switch\"\n          [class.form-check-inline]=\"props()?.inline\"\n          [class.form-check-reverse]=\"props()?.reverse\"\n        >\n          <input\n            ngForgeControl\n            type=\"checkbox\"\n            [id]=\"ngf.key() + '_' + i\"\n            [checked]=\"checked['' + option.value]\"\n            [disabled]=\"f().disabled() || option.disabled\"\n            (change)=\"onCheckboxChange(option, $event)\"\n            class=\"form-check-input\"\n            [class.is-invalid]=\"f().invalid() && f().touched()\"\n            [attr.tabindex]=\"ngf.tabIndex()\"\n          />\n          <label [for]=\"ngf.key() + '_' + i\" class=\"form-check-label\">\n            {{ option.label | dynamicText | async }}\n          </label>\n        </div>\n      }\n    </div>\n\n    @if (ngf.errorsToDisplay()[0]; as error) {\n      <div class=\"invalid-feedback d-block\" [id]=\"ngf.errorId()\" role=\"alert\">{{ error.message }}</div>\n    } @else if (props()?.hint; as hint) {\n      <div class=\"form-text\" [id]=\"ngf.hintId()\">{{ hint | dynamicText | async }}</div>\n    }\n  `,\n  styles: [\n    `\n      :host {\n        display: block;\n      }\n\n      .checkbox-group {\n        margin-bottom: 0.5rem;\n      }\n\n      :host([hidden]) {\n        display: none !important;\n      }\n    `,\n  ],\n  changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport default class BsMultiCheckboxFieldComponent {\n  protected readonly ngf = injectNgForgeField<ValueType[]>();\n\n  readonly options = input<FieldOption<ValueType>[]>([]);\n  readonly props = input<BsMultiCheckboxProps>();\n\n  /** Computed map of checked option values for O(1) lookup in template */\n  readonly checkedValuesMap = computed(() => {\n    const map: Record<string, boolean> = {};\n    for (const opt of this.valueViewModel()) {\n      map[String(opt.value)] = true;\n    }\n    return map;\n  });\n\n  valueViewModel = linkedSignal<FieldOption<ValueType>[]>(\n    () => {\n      const currentValues = this.ngf.field()().value();\n      return this.options().filter((option) => currentValues.includes(option.value));\n    },\n    { equal: isEqual },\n  );\n\n  constructor() {\n    explicitEffect([this.valueViewModel], ([selectedOptions]: [FieldOption<ValueType>[]]) => {\n      const selectedValues = selectedOptions.map((option: FieldOption<ValueType>) => option.value);\n\n      if (!isEqual(selectedValues, this.ngf.field()().value())) {\n        this.ngf.field()().value.set(selectedValues);\n      }\n    });\n\n    explicitEffect([this.options], ([options]: [FieldOption<ValueType>[]]) => {\n      const values = options.map((option: FieldOption<ValueType>) => option.value);\n      const uniqueValues = new Set(values);\n\n      if (values.length !== uniqueValues.size) {\n        const duplicates = values.filter((value, index) => values.indexOf(value) !== index);\n        throw new Error(`Duplicate option values detected in bs-multi-checkbox: ${duplicates.join(', ')}`);\n      }\n    });\n  }\n\n  onCheckboxChange(option: FieldOption<ValueType>, event: Event): void {\n    const checked = (event.target as HTMLInputElement).checked;\n    this.valueViewModel.update((currentOptions: FieldOption<ValueType>[]) => {\n      if (checked) {\n        return currentOptions.some((opt: FieldOption<ValueType>) => opt.value === option.value)\n          ? currentOptions\n          : [...currentOptions, option];\n      } else {\n        return currentOptions.filter((opt: FieldOption<ValueType>) => opt.value !== option.value);\n      }\n    });\n  }\n}\n"]}