{"version":3,"file":"di-controls-controls.mjs","sources":["../../../../libs/di-controls/controls/control-value-accessor.ts","../../../../libs/di-controls/controls/control.ts","../../../../libs/di-controls/controls/state-control.ts","../../../../libs/di-controls/controls/collection-control.ts","../../../../libs/di-controls/controls/proxy-control.ts","../../../../libs/di-controls/controls/di-controls-controls.ts"],"sourcesContent":["import {\n\tChangeDetectorRef,\n\tDirective, effect, ElementRef,\n\tinject,\n\tmodel, ModelSignal, Renderer2,\n\tSignal,\n\tsignal,\n\tWritableSignal,\n} from '@angular/core';\nimport {ControlValueAccessor, DefaultValueAccessor, NgControl} from '@angular/forms';\nimport {EMPTY_FUNCTION} from 'di-controls/constants';\nimport {hasValue} from 'di-controls/helpers';\nimport {toObservable} from '@angular/core/rxjs-interop';\n\nexport interface DIControlValueAccessorConfig<T> {\n\t/**\n\t * Function that will be called when the current control receives an update from the host control or from the\n\t * Forms API.\n\t *\n\t * @param value - new value.\n\t */\n\tonIncomingUpdate?: (value: T | null) => void;\n\n\t/**\n\t * Add support for native element. Which means that the control will\n\t * update the native element attributes like `disabled`.\n\t */\n\twithNativeElementSupport?: boolean;\n}\n\n/**\n * Base implementation of ControlValueAccessor\n */\n@Directive()\nexport abstract class DIControlValueAccessor<T> implements ControlValueAccessor {\n\tprotected readonly model: Signal<T | null> = signal(null);\n\tprotected readonly ngControl: NgControl | null;\n\tprotected readonly changeDetectorRef: ChangeDetectorRef;\n\treadonly disabled: ModelSignal<boolean> = model(false);\n\n\tprotected touch: () => void = EMPTY_FUNCTION;\n\tprotected change: (value: T | null) => void = EMPTY_FUNCTION;\n\n\t#element = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n\t#renderer = inject(Renderer2);\n\n\tprotected constructor(protected readonly config?: DIControlValueAccessorConfig<T>) {\n\t\tthis.ngControl = inject(NgControl, {optional: true, self: true});\n\t\tthis.changeDetectorRef = inject(ChangeDetectorRef);\n\n\t\tif (this.ngControl && (!this.ngControl.valueAccessor || this.ngControl.valueAccessor instanceof DefaultValueAccessor)) {\n\t\t\tthis.ngControl.valueAccessor = this;\n\t\t}\n\n\t\tif (this.config?.withNativeElementSupport) {\n\t\t\ttoObservable(this.disabled)\n\t\t\t\t.subscribe((isDisabled) => this.addDisabledAttribute(isDisabled))\n\t\t}\n\t}\n\n\t/**\n\t * Returns true if the control is not empty.\n\t */\n\tget hasValue(): boolean {\n\t\treturn hasValue(this.model());\n\t}\n\n\t/**\n\t * Method is called by the forms API.\n\t *\n\t * @param fn - callback function to register on value change\n\t * @internal\n\t */\n\tregisterOnChange(fn: (value: T | null) => void): void {\n\t\tthis.change = fn;\n\t}\n\n\t/**\n\t * Method is called by the forms API.\n\t *\n\t * @param fn - callback function to register on touch\n\t * @internal\n\t */\n\tregisterOnTouched(fn: () => void): void {\n\t\tthis.touch = fn;\n\t}\n\n\t/**\n\t * Method is called by the forms API to write to the view when programmatic changes from model to view are requested.\n\t *\n\t * @param obj - new value\n\t * @internal\n\t */\n\twriteValue(obj: T | null): void {\n\t\tif (this.model() !== obj) {\n\t\t\tthis.update(obj);\n\t\t}\n\t}\n\n\t/**\n\t * Updates the model.\n\t *\n\t * @param value - new value\n\t */\n\tinternalUpdateModel(value: T | null): void {\n\t\t(this.model as WritableSignal<T | null>).set(value);\n\t\tthis.change(this.model());\n\t\tthis.changeDetectorRef.markForCheck();\n\t}\n\n\t/**\n\t * Method is called by the forms API to write to the view when programmatic changes from model to view are requested.\n\t *\n\t * @param isDisabled - new value\n\t * @internal\n\t */\n\tsetDisabledState(isDisabled: boolean): void {\n\t\tthis.disabled.set(isDisabled);\n\t\tthis.addDisabledAttribute(isDisabled);\n\t}\n\n\tprivate update(value: T | null): void {\n\t\t(this.model as WritableSignal<T | null>).set(value);\n\t\tthis.config?.onIncomingUpdate && this.config.onIncomingUpdate(value);\n\t\tthis.changeDetectorRef.markForCheck();\n\t}\n\n\tprivate addDisabledAttribute(isDisabled: boolean): void {\n\t\tif (this.config?.withNativeElementSupport) {\n\t\t\t\tisDisabled\n\t\t\t\t\t? this.#renderer.setAttribute(this.#element, 'disabled', 'true')\n\t\t\t\t\t: this.#renderer.removeAttribute(this.#element, 'disabled');\n\t\t}\n\t}\n}\n","import {DestroyRef, Directive, ElementRef, inject, OnInit} from '@angular/core';\nimport {DIControlValueAccessor, DIControlValueAccessorConfig} from './control-value-accessor';\nimport { EMPTY_FUNCTION } from 'di-controls/constants';\n\n/**\n * Configuration for the `DIControl`.\n */\nexport interface DIControlConfig<TModel, TChildModel> extends DIControlValueAccessorConfig<TModel> {\n  /**\n   * Host control for the current control. It can be injected using `DI_HOST_CONTROL` token.\n   */\n  host?: DIControl<any, TModel> | null;\n  /**\n   * Function that will be called when the current control receives an update from the child control.\n   *\n   * @param control - child control that was updated.\n   * @param value - new value.\n   */\n  onChildControlChange?: (control: DIControl<TChildModel>, value: TModel | null) => void;\n}\n\n/**\n * `DIControl` can be used to implement any control that you want. It can work with any model type.\n * All updates from children will be accepted as is. And updates from outside (`FormControl`, `NgModel`, another Control)\n * will be accepted as is too.\n *\n * ## Creating a control\n * To create a control you need to extend your `@Component` or `@Directive` from `DIControl` class.\n * After that your control will be able to work with `NgModel`, `FormControl`.\n *\n * ```ts fileName=\"custom-control.component.ts\"\n * @Component({})\n * export class CustomControlComponent extends DIControl<string> {\n *   constructor() {\n *    super();\n *  }\n * }\n *  ```\n *\n * ## Registering as a host\n * By default your control can work only with `NgModel` and `FormControl`. But you can register your control as a host\n * for another controls, then your control will be able to update them and accept updates from them. To do that you need to\n * use `provideHostControl` function.\n *\n * ```ts {2} fileName=\"custom-control.component.ts\"\n * @Component({\n *   providers: [provideHostControl(CustomControlComponent)],\n * })\n * export class CustomControlComponent extends DIControl<string> {\n *   constructor() {\n *     super();\n *   }\n * }\n * ```\n *\n * ## Injecting host control\n * By default your control doesn't communicate with host controls. But you can inject host control and put it\n * into `super` call. This will register your control in the host control and start communication between them.\n *\n * > **Note**\n * > If you register your control as a host for another controls, then you can inject it\n * > only with `skipSelf` option.\n *\n * ```ts {5} fileName=\"custom-control.component.ts\"\n * @Component({})\n * export class CustomControlComponent extends DIControl<string> {\n *   constructor() {\n *     // we add `optional` option to make it possible to use this control without host\n *     super({host: injectHostControl({optional: true})});\n *   }\n * }\n * ```\n *\n * ## Getting model\n * To get model you need to use `model` property. It will return model for the current control.\n *\n * ```ts {9} fileName=\"custom-control.component.ts\"\n * @Component({})\n * export class CustomControlComponent extends DIControl<string> {\n *   constructor() {\n *     super();\n *   }\n *\n *   @HostListener('click')\n *   onClick() {\n *     console.log(this.model());\n *   }\n * }\n * ```\n *\n * ## Updating model\n * To update model you need to call `updateModel` method. It will update model for the current control and all\n * children controls, as well as for the `NgModel` or `FormControl`.\n *\n * ```ts {9} fileName=\"custom-control.component.ts\"\n * @Component({})\n * export class CustomControlComponent extends DIControl<string> {\n *   constructor() {\n *     super();\n *   }\n *\n *   @HostListener('click')\n *   onClick() {\n *     this.updateModel('new value');\n *   }\n * }\n * ```\n * ## Catching updates\n * Sometimes you may need to catch updates from different sources. For example, to update the value of the native\n * input element. To do this, you can provide the `onIncomingUpdate` hook.\n *\n * ```ts {6} fileName=\"custom-control.component.ts\"\n * @Component({})\n * export class CustomControlComponent extends DIControl<string> {\n *   constructor() {\n *     super({\n *       onIncomingUpdate: (value: string | null) => {\n *         this.elementRef.nativeElement.value = value;\n *       },\n *     });\n *   }\n * }\n * ```\n */\n@Directive()\nexport abstract class DIControl<TModel, TChildModel = TModel>\n  extends DIControlValueAccessor<TModel>\n  implements OnInit\n{\n  /**\n   * List of children controls.\n   *\n   * @protected\n   * @internal\n   */\n  protected children: Set<DIControl<TChildModel>> = new Set<DIControl<TChildModel>>();\n  /**\n   * Control from which we have to update our model.\n   *\n   * @protected\n   * @internal\n   */\n  protected updateFrom: DIControl<TChildModel> | null = null;\n\n  /**\n   * Request host for update the current control.\n   * Host will update the current control based on its current state and host control logic.\n   *\n   * @protected\n   * @internal\n   */\n  protected requestForUpdate: () => void = EMPTY_FUNCTION;\n  /**\n   * Function that should be used to make control touched.\n   */\n  protected override touch: () => void = () => this.config?.host?.touch();\n\n  private onControlChangeFn: (value: TModel | null) => void = EMPTY_FUNCTION;\n  private destroyRef: DestroyRef = inject(DestroyRef);\n\n  protected constructor(protected override readonly config?: DIControlConfig<TModel, TChildModel>) {\n    super(config);\n\n    this.destroyRef.onDestroy(() => this.config?.host?.unregisterControl(this));\n  }\n\n  ngOnInit(): void {\n    /*\n     * We have to register control with Promise.resolve because NgModel uses it too to set first\n     * value (https://github.com/angular/angular/blob/7df9127088bda3c9d29937a04287b87dc2045ea7/packages/forms/src/directives/ng_model.ts#L314)\n     */\n    Promise.resolve().then(() => this.config?.host?.registerControl(this));\n  }\n\n  /**\n   * Registers provided control as a child of the current control.\n   *\n   * @param control - control that will be registered.\n   * @internal\n   */\n  registerControl(control: DIControl<TChildModel>): void {\n    this.children.add(control);\n\n    /*\n     * We have to update control because its can be created dynamically.\n     * We use Promise.resolve because NgModel uses it too to set first value (https://github.com/angular/angular/blob/7df9127088bda3c9d29937a04287b87dc2045ea7/packages/forms/src/directives/ng_model.ts#L314)\n     * so there's no need to use angular life cycle hooks\n     */\n    Promise.resolve().then(() => {\n      this.updateControl(control, this.model());\n    });\n\n    control.registerOnControlChange((value: unknown | null) => {\n      this.childControlChange(control, value as TModel | null);\n      this.config?.onChildControlChange?.(control, value as TModel | null);\n    });\n\n    control.registerRequestForUpdate(() => {\n      this.updateControl(control, this.model());\n    });\n  }\n\n  /**\n   * Unregisters provided control from the current control.\n   *\n   * @param control - control that will be unregistered.\n   * @internal\n   */\n  unregisterControl(control: DIControl<TChildModel>): void {\n    this.children.delete(control);\n  }\n\n  override registerOnTouched(fn: () => void): void {\n    this.touch = () => {\n      fn();\n\n      // Touch host control to update its state\n      this.config?.host?.touch();\n    };\n  }\n\n  /**\n   * Registers provided function as a callback that will be called when the current control changes.\n   * This function will be provided by the host control to update its model.\n   *\n   * @param fn - callback function.\n   * @internal\n   */\n  registerOnControlChange(fn: (value: TModel | null) => void): void {\n    this.onControlChangeFn = fn;\n  }\n\n  /**\n   * Registers provided function as a callback that can be called to request an update from the host control.\n   * After calling this function the host control will update the model of the current control based on the current\n   * state of the control and host control logic.\n   *\n   * @param fn - callback function.\n   * @internal\n   */\n  registerRequestForUpdate(fn: () => void): void {\n    this.requestForUpdate = fn;\n  }\n\n  /**\n   * Updates the model of the current control.\n   * This is the main method that should be used to update the model.\n   *\n   * @param value - new value.\n   */\n\tupdateModel(value: TModel | null): void {\n\t\tthis.updateFrom = null;\n    this.internalUpdateModel(value);\n  }\n\n\t/**\n\t * Updates the model of the current control.\n\t * Don't use this method directly, use `updateModel` instead.\n\t *\n\t * @param value - new value.\n\t * @internal\n\t */\n\toverride internalUpdateModel(value: TModel | null): void {\n\t\tsuper.internalUpdateModel(value);\n\t\tthis.onControlChangeFn(value);\n\t\tthis.updateControls(this.model());\n\t}\n\n  override writeValue(value: TModel | null): void {\n    if (this.model() !== value) {\n      super.writeValue(value);\n      this.updateControls(value);\n      this.onControlChangeFn(value);\n    }\n  }\n\n  /**\n   * Method is called by the host to update the value of the control.\n   *\n   * @param value - new value\n   * @internal\n   */\n  writeValueFromHost(value: TModel | null): void {\n    if (this.model() !== value) {\n      super.writeValue(value);\n      this.change(value);\n      this.updateControls(value);\n    }\n  }\n\n  /**\n   * Updates all child controls with the provided value.\n   *\n   * @param value - new value.\n   * @protected\n   * @internal\n   */\n  protected updateControls(value: TModel | null): void {\n    this.children.forEach((control: DIControl<TChildModel>) => {\n      if (control !== this.updateFrom) {\n        this.updateControl(control, value);\n      }\n    });\n    this.updateFrom = null;\n  }\n\n  /**\n   * Updates provided control with the provided value.\n   *\n   * @param control - control that will be updated.\n   * @param value - new value.\n   * @protected\n   * @internal\n   */\n  protected updateControl(control: DIControl<TChildModel>, value: TModel | null): void {\n    control.writeValueFromHost(value as TChildModel);\n  }\n\n  /**\n   * Function catches updates from child controls and updates the current control model.\n   *\n   * @param control - control that was updated.\n   * @param value - new value.\n   * @protected\n   * @internal\n   */\n  protected childControlChange(control: DIControl<TChildModel>, value: TModel | null): void {\n    if (this.model() !== value) {\n      this.updateFrom = control;\n      this.internalUpdateModel(value);\n      this.config?.onIncomingUpdate && this.config.onIncomingUpdate(value);\n    }\n  }\n}\n","import {computed, Directive, InputSignal, OnChanges, Signal, SimpleChanges} from '@angular/core';\nimport {DICompareHost} from 'di-controls/classes';\nimport {DI_DEFAULT_COMPARE} from 'di-controls/constants';\nimport {DIControl, DIControlConfig} from './control';\nimport {DICompareFunction} from 'di-controls/types';\nimport {resolveValue} from 'di-controls/helpers';\n\n/**\n * Configuration for the `DIStateControl`.\n */\nexport interface DIStateControlConfig<TModel, TValue extends TModel = TModel> extends DIControlConfig<TModel, TModel> {\n\t/**\n\t * Value that will be used for the unchecked state.\n\t */\n\tuncheckValue?: TModel;\n\t/**\n\t * Function that will be used to compare model value with the `value` property.\n\t */\n\tcompare?: DICompareHost<TModel | null, TValue> | DICompareFunction<TModel | null, TValue> | null;\n\t/**\n\t * Indicates whether the current control can have intermediate state.\n\t */\n\thasIntermediate?: boolean;\n}\n\n/**\n * `DIStateControl` can be used to implement state controls (checkbox, radio, chip, switch, etc.).\n * It extends `DIControl` and adds `checked` signal that can be used to get checked state.\n * By default it works with `boolean` type, it adds `value` input that can be used to set custom\n * \"true\" value.\n *\n * ## Creating a control\n * To create a control you need to extend your `@Component` or `@Directive` from `DIStateControl` class.\n * After that your control will be able to work with `NgModel`, `FormControl`.\n *\n * ```ts fileName=\"custom-control.component.ts\"\n * @Component({})\n * export class CustomControlComponent<T = boolean> extends DIStateControl<T> {\n *   @Input({required: true})\n *   value!: T;\n *\n *   constructor() {\n *    super();\n *  }\n * }\n *  ```\n *\n * ## Injecting host control\n * By default your control doesn't communicate with host controls. But you can inject host control and put it\n * into `super` call. This will register your control in the host control and start communication between them.\n *\n * > **Note**\n * > If you register your control as a host for another controls, then you can inject it\n * > only with `skipSelf` option.\n *\n * ```ts {5} fileName=\"custom-control.component.ts\"\n * @Component({})\n * export class CustomControlComponent<T = boolean> extends DIStateControl<T> {\n *   constructor() {\n *     // we add `optional` option to make it possible to use this control without host\n *     super({host: injectHostControl({optional: true})});\n *   }\n * }\n * ```\n *\n * ## Getting checked state\n * To get checked state you need to use `checked` signal. It will return `true` if the current control is checked,\n * `false` if it is unchecked and `null` if it is in intermediate state.\n *\n * ```ts {9} fileName=\"custom-control.component.ts\"\n * @Component({})\n * export class CustomControlComponent<T> extends DIControl<T> {\n *  @Input({required: true})\n *   value!: T;\n *\n *   constructor() {\n *     super();\n *\n *     console.log(this.checked());\n *   }\n * }\n * ```\n *\n * ## Getting model\n * To get model you need to use `model` property. It will return model for the current control.\n *\n * ```ts {9} fileName=\"custom-control.component.ts\"\n * @Component({})\n * export class CustomControlComponent<T = boolean> extends DIStateControl<T> {\n *   constructor() {\n *     super();\n *   }\n *\n *   @HostListener('click')\n *   onClick() {\n *     console.log(this.checked());\n *   }\n * }\n * ```\n *\n * ## Updating model\n * To update model you should use `check`, `uncheck`, `intermediate` or `toggle` methods.\n * They will update model based on the current state and configuration.\n *\n * ```ts {9} fileName=\"custom-control.component.ts\"\n * @Component({})\n * export class CustomControlComponent<T = boolean> extends DIStateControl<T> {\n *   constructor() {\n *     super();\n *   }\n *\n *   @HostListener('click')\n *   onClick() {\n *     this.toggle();\n *   }\n * }\n * ```\n *\n * ## Catching updates\n * Sometimes you may need to catch updates from different sources. For example, to update the value of the native\n * input element. To do this, you can provide the `onIncomingUpdate` hook.\n *\n * ```ts {6} fileName=\"custom-control.component.ts\"\n * @Component({})\n * export class CustomControlComponent<T = boolean> extends DIStateControl<T>  {\n *   constructor() {\n *     super({\n *       onIncomingUpdate: (value: string | null) => {\n *         this.elementRef.nativeElement.value = value;\n *       },\n *     });\n *   }\n * }\n * ```\n *\n *\n *  ## Using with DICollectionControl\n *  Using `DIStateControl` together with `DICollectionControl` will result in\n *  `DICollectionControl` containing a list of values from `DIStateControl` that have\n *  a checked state. If your `DIStateControl` has objects as values, you may\n *  likely need a comparison function because they can sometimes be immutable.\n *\n * To achieve this, provide your `DICollectionControl` as a `DICompareHost` and\n * inject it into your `DIStateControl` to give `DIStateControl` access to\n * the `compareFn` function.\n *\n * > **Warning**\n * > `DICollectionControl` requires an explicit specification of the `uncheckedValue` in the `DIStateControl`\n *\n * ```ts {3-4} fileName=\"checkbox-group.component.ts\"\n * @Component({\n *   providers: [\n *     provideHostControl(CheckboxGroupComponent),\n *     provideCompareHost(CheckboxGroupComponent),\n *   ],\n * })\n * export class CheckboxGroupComponent<T> extends DICollectionControl<T> {\n *   constructor() {\n *     super();\n *   }\n * }\n * ```\n *\n * ```ts {5-7} fileName=\"checkbox.component.ts\"\n * @Component()\n * export class CheckboxComponent<T> extends DIStateControl<T> {\n *   constructor() {\n *     super({\n *       host: injectHostControl({ optional: true }),\n *       compare: inject(DICompareHost, { optional: true }),\n *       hasIntermediate: true,\n *     });\n *\n *   @HostListener('click')\n *   onClick() {\n *     this.toggle();\n *   }\n * }\n * ```\n */\n@Directive({\n    standalone: false\n})\nexport abstract class DIStateControl<TModel, TValue extends TModel = TModel>\n\textends DIControl<TModel>\n\timplements OnChanges\n{\n\t/**\n\t * Value that will be used for the checked state.\n\t * You can override it to transform it to `@Input` or to set value by default.\n\t */\n\tabstract value: TValue | InputSignal<TValue>;\n\n\tchecked: Signal<boolean | null> = computed(() => {\n\t\tconst compareFn: DICompareFunction<TModel | null, TValue> =\n\t\t\ttypeof this.config?.compare === 'function'\n\t\t\t\t? this.config.compare\n\t\t\t\t: resolveValue<DICompareFunction<TModel | null, TValue>>(this.config?.compare?.compareFn ?? DI_DEFAULT_COMPARE);\n\n\t\treturn compareFn(this.model(), resolveValue(this.value)) ? true : this.isIntermediate ? null : false;\n\t});\n\n\tprotected constructor(\n\t\tprotected override readonly config?: DIStateControlConfig<TModel, TValue>,\n\t) {\n\t\tsuper(config);\n\t}\n\n\tngOnChanges({ value }: SimpleChanges): void {\n\t\t/*\n\t\t * We have to request host for updates, because when we use ngFor directive\n\t\t * with trackBy function, Angular doesn't re-create components, it just changes their inputs,\n\t\t * so we have to request for updates our host, to determine right checked state\n\t\t */\n\t\tif (value) {\n\t\t\tthis.requestForUpdate();\n\t\t}\n\t}\n\n\t/** Sets checked state */\n\tcheck(): void {\n\t\tthis.updateModel(resolveValue(this.value));\n\t}\n\n\t/** Sets unchecked state */\n\tuncheck(): void {\n\t\tif (!('uncheckValue'  in (this.config ?? {}))) {\n\t\t\tthrow new Error('To use uncheck method you need to provide uncheckValue in DIStateControl config');\n\t\t}\n\n\t\tthis.updateModel(this.config!.uncheckValue as TModel);\n\t}\n\n\t/** Sets intermediate state */\n\tintermediate(): void {\n\t\tthis.updateModel(null);\n\t}\n\n\t/** Toggles checked state */\n\ttoggle(): void {\n\t\tthis.checked() ? this.uncheck() : this.check();\n\t}\n\n\tget isIntermediate(): boolean {\n\t\treturn this.model() === null && !!this.config?.hasIntermediate;\n\t}\n}\n","import {Directive} from '@angular/core';\nimport {DICompareHost, SetCompare} from 'di-controls/classes';\nimport {DICompareFunction} from 'di-controls/types';\nimport {DIControl, DIControlConfig} from './control';\nimport {DIStateControl} from './state-control';\nimport {resolveValue} from 'di-controls/helpers';\nimport {DI_DEFAULT_COMPARE} from 'di-controls/constants';\n\n/**\n * Configuration for the `DICollectionControl`.\n */\nexport interface DICollectionControlConfig<TModel, TChildModel> extends DIControlConfig<TModel[], TChildModel> {\n\t/**\n\t * Function that will be used to compare values in the array.\n\t * Useful when you want to compare objects by some property.\n\t */\n\tcompare?: DICompareHost<TModel | null> | DICompareFunction<TModel | null> | null;\n}\n\n/**\n * `DICollectionControl` can be used to implement array controls (checkbox group, radio group, chips, etc.).\n * It has an additional integration with `DIStateControl` that allows you to use it as a host for\n * `DIStateControl` controls. If you use `DIStateControl` as a child control, then `DICollectionControl`\n * will update its model when the child control is checked or unchecked, so `DICollectionControl` will\n * contain only checked values.\n *\n * It also works with other controls, but their model should be an array.\n *\n * > **Warning**\n * > If child control model is updated with non-array value, then `DICollectionControl` will be updated with `null`.\n *\n * ## Creating a control\n * To create a control you need to extend your `@Component` or `@Directive` from `DICollectionControl` class.\n * After that your control will be able to work with `NgModel`, `FormControl`.\n *\n * ```ts fileName=\"custom-control.component.ts\"\n * @Component({})\n * export class CustomControlComponent extends DICollectionControl<string> {\n *   constructor() {\n *    super();\n *  }\n * }\n *  ```\n *\n * ## Registering as a host\n * By default your control can work only with `NgModel` and `FormControl`. But you can register your control as a host\n * for another controls, then your control will be able to update them and accept updates from them. To do that you need to\n * use `provideHostControl` function.\n *\n * ```ts {2} fileName=\"custom-control.component.ts\"\n * @Component({\n *   providers: [provideHostControl(CustomControlComponent)],\n * })\n * export class CustomControlComponent extends DICollectionControl<string> {\n *   constructor() {\n *     super();\n *   }\n * }\n * ```\n *\n * ## Injecting host control\n * By default your control doesn't communicate with host controls. But you can inject host control and put it\n * into `super` call. This will register your control in the host control and start communication between them.\n *\n * > **Note**\n * > If you register your control as a host for another controls, then you can inject it\n * > only with `skipSelf` option.\n *\n * ```ts {5} fileName=\"custom-control.component.ts\"\n * @Component({})\n * export class CustomControlComponent extends DICollectionControl<string> {\n *   constructor() {\n *     // we add `optional` option to make it possible to use this control without host\n *     super({host: injectHostControl({optional: true})});\n *   }\n * }\n * ```\n *\n * ## Getting model\n * To get model you need to use `model` property. It will return model for the current control.\n *\n * ```ts {9} fileName=\"custom-control.component.ts\"\n * @Component({})\n * export class CustomControlComponent extends DICollectionControl<string> {\n *   constructor() {\n *     super();\n *   }\n *\n *   @HostListener('click')\n *   onClick() {\n *     console.log(this.model());\n *   }\n * }\n * ```\n *\n * ## Updating model\n * To update model you need to call `updateModel` method. It will update model for the current control and all\n * children controls, as well as for the `NgModel` or `FormControl`.\n *\n * ```ts {9} fileName=\"custom-control.component.ts\"\n * @Component({})\n * export class CustomControlComponent extends DICollectionControl<string> {\n *   constructor() {\n *     super();\n *   }\n *\n *   @HostListener('click')\n *   onClick() {\n *     this.updateModel(['new value']);\n *   }\n * }\n * ```\n * ## Catching updates\n * Sometimes you may need to catch updates from different sources. For example, to update the value of the native\n * input element. To do this, you can provide the `onIncomingUpdate` hook.\n *\n * ```ts {6} fileName=\"custom-control.component.ts\"\n * @Component({})\n * export class CustomControlComponent extends DICollectionControl<string> {\n *   constructor() {\n *     super({\n *       onIncomingUpdate: (value: string[] | null) => {\n *         this.elementRef.nativeElement.value = value;\n *       },\n *     });\n *   }\n * }\n * ```\n * ```\n */\n@Directive()\nexport abstract class DICollectionControl<TModel> extends DIControl<TModel[], TModel | TModel[]> {\n\tprivate proxyModel: SetCompare<TModel> = new SetCompare<TModel>();\n\n\tprotected constructor(protected override config?: DICollectionControlConfig<TModel, TModel | TModel[]>) {\n\t\tsuper(config);\n\t}\n\n\tprivate getCompareFn(): DICompareFunction<TModel> {\n\t\treturn typeof this.config?.compare === 'function'\n\t\t\t? this.config.compare\n\t\t\t: resolveValue<DICompareFunction<TModel | null>>(this.config?.compare?.compareFn ?? DI_DEFAULT_COMPARE);\n\t}\n\n\toverride internalUpdateModel(obj: TModel[] | null): void {\n\t\tthis.proxyModel = new SetCompare(this.getCompareFn(), obj);\n\n\t\tsuper.internalUpdateModel(obj);\n\t}\n\n\toverride writeValue(value: TModel[] | null) {\n\t\tthis.proxyModel = new SetCompare(this.getCompareFn(), value);\n\n\t\tsuper.writeValue(value);\n\t}\n\n\toverride writeValueFromHost(obj: TModel[] | null) {\n\t\tthis.proxyModel = new SetCompare(this.getCompareFn(), obj);\n\n\t\tsuper.writeValueFromHost(obj);\n\t}\n\n\tprotected override childControlChange(\n\t\tcontrol: DIControl<TModel | TModel[]>,\n\t\tvalue: TModel[] | null,\n\t) {\n\t\tthis.updateFrom = control;\n\t\tthis.updateModel(this.getNewModel(control, value));\n\t\tthis.config?.onIncomingUpdate && this.config.onIncomingUpdate(this.model());\n\t}\n\n\tprivate getNewModel(\n\t\tcontrol: DIControl<TModel | TModel[]>,\n\t\tupdates: TModel | TModel[] | null,\n\t): TModel[] | null {\n\t\tif (control instanceof DIStateControl) {\n\t\t\tcontrol.checked()\n\t\t\t\t? this.proxyModel.add(resolveValue(control.value))\n\t\t\t\t: this.proxyModel.delete(resolveValue(control.value));\n\t\t} else if (Array.isArray(updates)) {\n\t\t\tthis.proxyModel = new SetCompare<TModel>(this.getCompareFn(), updates);\n\t\t} else {\n\t\t\tthis.proxyModel = new SetCompare<TModel>(this.getCompareFn());\n\n\t\t\treturn null;\n\t\t}\n\n\t\treturn this.proxyModel.toArray();\n\t}\n\n\tprotected override updateControl(control: DIControl<TModel | TModel[]>): void {\n\t\tif (control instanceof DIStateControl) {\n\t\t\t// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n\t\t\t// @ts-expect-error\n\t\t\tcontrol.writeValueFromHost(this.proxyModel.has(resolveValue(control.value)) ? resolveValue(control.value) : control.config.uncheckValue);\n\t\t} else {\n\t\t\tcontrol.writeValueFromHost(this.model());\n\t\t}\n\t}\n}\n","import {Directive} from '@angular/core';\nimport {DIProxyControlGetValue, DIProxyControlSetValue} from 'di-controls/types';\nimport {DIControl, DIControlConfig} from './control';\n\n/**\n * Configuration for the `DIProxyControl`.\n */\nexport interface DIProxyControlConfig<TModel, TChildModel> extends DIControlConfig<TModel, TChildModel> {\n\t/**\n\t * Function that will be used to get value from the current object model and set it to the child control\n\t * when update is requested.\n\t */\n\tgetValue: DIProxyControlGetValue<TModel, TChildModel>;\n\t/**\n\t * Function that will be used to set value to the object model when child control value is changed.\n\t */\n\tsetValue: DIProxyControlSetValue<TModel, TChildModel>;\n}\n\n/**\n * `DIProxyControl` is very suitable.\n * It is typically used as a host and works exclusively with objects. It is\n * necessary to bind child controls to a specific property of the object,\n * thereby ensuring that they update only that specific property and not the\n * entire object as a whole. Please see `*DateRangePage`.\n *\n * ## Creating a control\n * To create a control you need to extend your `@Component` or `@Directive` from `DIProxyControl` class\n * and provide `getValue` and `setValue` functions that will be used to get and set value from the object\n * to the child control.\n *\n * ```ts fileName=\"custom-control.component.ts\"\n * @Component({})\n * export class CustomControlComponent extends DIProxyControl<MyObject> {\n *   constructor() {\n *    super({\n *      getValue: (model) => model.objectProperty,\n *      setValue: (model, value) => ({...model, objectProperty: value}),\n *    });\n *  }\n * }\n *  ```\n *\n * ## Registering as a host\n * By default your control can work only with `NgModel` and `FormControl`. But you can register your control as a host\n * for another controls, then your control will be able to update them and accept updates from them. To do that you need to\n * use `provideHostControl` function.\n *\n * ```ts {2} fileName=\"custom-control.component.ts\"\n * @Component({\n *   providers: [provideHostControl(CustomControlComponent)],\n * })\n * export class CustomControlComponent extends DIProxyControl<MyObject> {\n *   constructor() {\n *     super({\n *      getValue: (model) => model.objectProperty,\n *      setValue: (model, value) => ({...model, objectProperty: value}),\n *    });\n *   }\n * }\n * ```\n *\n * ## Injecting host control\n * By default your control doesn't communicate with host controls. But you can inject host control and put it\n * into `super` call. This will register your control in the host control and start communication between them.\n *\n * > **Note**\n * > If you register your control as a host for another controls, then you can inject it\n * > only with `skipSelf` option.\n *\n * ```ts {5} fileName=\"custom-control.component.ts\"\n * @Component({})\n * export class CustomControlComponent extends DIProxyControl<MyObject> {\n *   constructor() {\n *     // we add `optional` option to make it possible to use this control without host\n *     super({\n *       host: injectHostControl({optional: true}),\n *       getValue: (model) => model.objectProperty,\n *       setValue: (model, value) => ({...model, objectProperty: value}),\n *     });\n *   }\n * }\n * ```\n *\n * ## Getting model\n * To get model you need to use `model` property. It will return model for the current control.\n *\n * ```ts {9} fileName=\"custom-control.component.ts\"\n * @Component({})\n * export class CustomControlComponent extends DIProxyControl<MyObject> {\n *   constructor() {\n *     super(\n *       getValue: (model) => model.objectProperty,\n *       setValue: (model, value) => ({...model, objectProperty: value}),\n *     );\n *   }\n *\n *   @HostListener('click')\n *   onClick() {\n *     console.log(this.model());\n *   }\n * }\n * ```\n *\n * ## Updating model\n * To update model you need to call `updateModel` method. It will update model for the current control and all\n * children controls, as well as for the `NgModel` or `FormControl`.\n *\n * ```ts {9} fileName=\"custom-control.component.ts\"\n * @Component({})\n * export class CustomControlComponent extends DIProxyControl<MyObject> {\n *   constructor() {\n *     super(\n *       getValue: (model) => model.objectProperty,\n *       setValue: (model, value) => ({...model, objectProperty: value}),\n *     );\n *   }\n *\n *   @HostListener('click')\n *   onClick() {\n *     this.updateModel({objectProperty: 'new value'});\n *   }\n * }\n * ```\n * ## Catching updates\n * Sometimes you may need to catch updates from different sources. For example, to update the value of the native\n * input element. To do this, you can provide the `onIncomingUpdate` hook.\n *\n * ```ts {6} fileName=\"custom-control.component.ts\"\n * @Component({})\n * export class CustomControlComponent extends DIProxyControl<MyObject> {\n *   constructor() {\n *     super({\n *       onIncomingUpdate: (value: MyObject | null) => {\n *         this.elementRef.nativeElement.value = value;\n *       },\n *     });\n *   }\n * }\n * ```\n */\n@Directive()\nexport abstract class DIProxyControl<TModel, TChildModel> extends DIControl<TModel, TChildModel> {\n\tprotected constructor(\n\t\tprotected override config: DIProxyControlConfig<TModel, TChildModel>,\n\t) {\n\t\tsuper(config);\n\t}\n\n\toverride registerControl(control: DIControl<TChildModel>): void {\n\t\tthis.children.add(control);\n\n\t\t/*\n\t\t * We have to update control because its can be created dynamically.\n\t\t * We use Promise.resolve because NgModel uses it too to set first value (https://github.com/angular/angular/blob/7df9127088bda3c9d29937a04287b87dc2045ea7/packages/forms/src/directives/ng_model.ts#L314)\n\t\t * so there's no need to use angular life cycle hooks\n\t\t */\n\t\tPromise.resolve().then(() => control.writeValueFromHost(this.config.getValue(this.model())));\n\n\t\tcontrol.registerOnControlChange((value: unknown | null) => {\n\t\t\tvalue = this.config.setValue(this.model(), value as TChildModel | null);\n\n\t\t\tthis.childControlChange(control, value as TModel | null);\n\t\t\tthis.config?.onChildControlChange?.(control, value as TModel | null);\n\t\t});\n\n\t\tcontrol.registerRequestForUpdate(() => {\n\t\t\tthis.updateControl(control, this.config.getValue(this.model()) as TModel | null);\n\t\t});\n\t}\n\n\tprotected override updateControl(control: DIControl<TChildModel>, value: TModel | null): void {\n\t\tcontrol.writeValueFromHost(this.config.getValue(value));\n\t}\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}