var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { Component, Host, h, Element, Prop, Event, Watch, Method, State } from '@stencil/core';
import { createEnterKeyHandlerToTriggerClick } from '../../utils/accessibility';
import { sanitizeVegaComponent } from '../../utils/component';
import { CheckBoxRequiredRule } from '../../helpers/validator/rules/check-box-required-rule';
import ChangeManager from '../../helpers/change-manager/change-manager';
import { CHECKBOX_GROUP_DISABLED_CHANGE, CHECKBOX_VALUE_CHANGE, FORM_ELEMENT_VALUE_CHANGE, } from '../../helpers/change-manager/subject/static-subject/static-subject-title';
import { Observer } from '../../helpers/change-manager/observer/observer';
import { arrayToClassString, findParent } from '../../utils/ui';
import { InjectVegaGlobalSlimmer, InjectVegaSlimmer } from 'vega-slimmer/core';
import { FormFieldControllerSlimmer } from '../../helpers/slimmers/form-field-controller-slimmer';
import { createEventEmitSlimmer, } from '../../helpers/event-manager/slimmers/event-emit-slimmer';
import { VegaChange } from '../../helpers/event-manager/event-id/vega-event-id';
import { VegaCheckboxShowErrorController } from './slimmers/controllers/vega-checkbox-show-error-controller';
import { VegaComponentUsageRuntimeMetricsSlimmer } from '../../helpers/slimmers/component-usage-runtime-metrics';
import { ChildNodesEventPreventSlimmer } from '../../helpers/event-manager/slimmers/child-nodes-event-prevent-slimmer';
import { AriaAttributesValueMapper } from '../../helpers/slimmers/mutation-observer/aria-attributes-value-mapper';
/**
 * @vegaVersion 1.0.7
 */
export class VegaCheckbox {
  constructor() {
    this.globalSlimmers = {};
    this.vegaCheckboxShowErrorController = new VegaCheckboxShowErrorController();
    this.ariaAttributesValueMapper = new AriaAttributesValueMapper(() => {
      return this.host.shadowRoot.querySelector('input');
    }, {
      'aria-label': {
        dependency: ['data-aria-label', 'identifier'],
        defaultValue: 'No label defined',
      },
    });
    this.formFieldController = new FormFieldControllerSlimmer({
      propertyRules: [
        {
          propertyName: 'required',
          ruleFactory: (isRequired) => (isRequired ? new CheckBoxRequiredRule() : null),
        },
      ],
      defaultValue: (target) => (target.identifier === '' ? false : ''),
      attributeGetter: (propertyName) => this[propertyName],
      inputContainerGetter: () => this.inputContainerRef,
      touchableAreaGetter: () => [this.inputRef],
    });
    this.changeEventEmitter = createEventEmitSlimmer(VegaCheckbox, VegaChange);
    this.dropdownEventPrevent = new ChildNodesEventPreventSlimmer([VegaChange], () => this.host, {
      customPreventHandle: (e) => {
        e.stopPropagation();
      },
    });
    this.vegaComponentUsageRuntimeMetricsSlimmer = new VegaComponentUsageRuntimeMetricsSlimmer();
    /**
     * Indicates whether the parent checkbox group is disabled.
     */
    this.groupDisabled = false;
    /**
     * Indicates whether the parent checkbox group show error message.
     */
    this.showError = false;
    /**
     * Sets a unique identifier for the checkbox.
     *
     * Refer to the `value` property for detailed information on
     *    how to use this property during form validation.
     *
     * @vegaVersion 1.10.0
     */
    this.identifier = '';
    /**
     * Determines the value that is associated with the checkbox
     *    when it is checked or unchecked.
     *
     * When the `identifier` property is set, the `value` property will
     *    return the value of the `identifier` when the checkbox is checked.
     *    When the checkbox is unchecked, the `value` property will
     *    return an empty string ''.
     *
     * If the `identifier` property is not set, the `value` property behaves
     *    as a boolean and returns `true` when the checkbox is checked,
     *    and `false` when it is unchecked.
     *
     * @vegaVersion 1.0.7
     */
    /* eslint-disable-next-line @stencil/strict-mutable */
    this.value = this.identifier !== '' ? '' : false;
    /**
     * Specifies whether the checkbox should be pre-checked.
     *
     * Use the `value` property to retrieve the current status of the checkbox.
     *
     * @vegaVersion 1.0.7
     */
    this.checked = false;
    /**
     * Specifies whether the checkbox is in an indeterminate state.
     *
     * The indeterminate state is a visual-only state typically used to represent
     *    a checkbox whose value is neither fully checked nor fully unchecked,
     *    such as a "select all" control where only some children are selected.
     *
     * Setting this property does not affect the `checked` or `value` properties.
     *    User interaction (clicking) will clear the indeterminate state and
     *    toggle `checked` as usual.
     *
     * @vegaVersion 2.83.0
     */
    /* eslint-disable-next-line @stencil/strict-mutable */
    this.indeterminate = false;
    /**
     * Specifies whether the checkbox element is disabled.
     *
     * @vegaVersion 1.3.0
     */
    this.disabled = false;
    /**
     * Specifies the size of the checkbox.
     *
     * @vegaVersion 1.3.0
     */
    this.size = 'default';
    /**
     * Specifies whether the checkbox must be checked
     *    to pass form validation.
     *
     * @vegaVersion 1.3.0
     */
    this.required = false;
    /**
     * Specifies the validation status of the checkbox component.
     *
     * @vegaVersion 1.10.0
     */
    /* eslint-disable-next-line @stencil/strict-mutable */
    this.isValid = null;
    /**
     * Indeterminate-clearing behavior is unit-tested.
     * The checked-state side of this method is e2e-test covered in
     * @see{module:vega-checkbox-change}
     */
    this.onCheckBoxChange = (e) => {
      if (this.indeterminate) {
        this.indeterminate = false;
      }
      this.checked = e.currentTarget.checked;
    };
    this.onSelectedIconClick = (e) => {
      e.stopPropagation();
    };
  }
  /* The below method is e2e-test covered in
   * @see{module:vega-checkbox-value-sync}
   */
  watchValueChange(newValue) {
    this.checked = this.identifier !== '' ? newValue === this.identifier : newValue === true;
  }
  watchCheckedChange() {
    this.initValue();
    this.changeEventEmitter.emit(this.value);
    ChangeManager.notify(CHECKBOX_VALUE_CHANGE, { host: this.host, detail: this.value });
    ChangeManager.notify(FORM_ELEMENT_VALUE_CHANGE, {
      host: this.host,
      detail: this.value,
    });
  }
  disconnectedCallback() {
    this.unRegisterGroupDisabledObserver();
  }
  componentWillLoad() {
    // Handle pre-set value (e.g., Angular writeValue before hydration, or HTML attribute)
    const shouldBeChecked = this.identifier !== ''
      ? this.value === this.identifier
      : this.value === true || this.value === 'true';
    if (!this.checked && shouldBeChecked) {
      this.checked = true;
    }
    this.initValue();
    this.initAndRegisterGroupDisabledObserver();
  }
  componentDidRender() {
    if (this.host.innerHTML.trim() === '') {
      this.labelElement.classList.add('vega-hidden');
    }
    this.syncNativeIndeterminate();
  }
  /**
   * Invoke this method to set the value of the checkbox.
   *
   * It is recommended to use this method instead of directly modifying the `value` property.
   *
   * @vegaVersion 1.16.0
   */
  async setValue(value) {
    this.checked = this.identifier ? value === this.identifier : value === true;
  }
  render() {
    var _a;
    /* istanbul ignore next */
    const isInsideCheckboxGroup = ((_a = this.host.parentElement) === null || _a === void 0 ? void 0 : _a.nodeName) == 'VEGA-CHECKBOX-GROUP';
    return sanitizeVegaComponent(h(Host, { class: {
        'vega-flex-shrink-0 v-min-w-min': isInsideCheckboxGroup,
        'checked': this.checked,
        'indeterminate': this.indeterminate,
        'disabled': this.isDisabled(),
      } },
      h("label", { class: arrayToClassString([
          'vega-checkbox-container',
          this.showError && 'error',
          this.size && `size-${this.size}`,
        ]), ref: (e) => (this.inputContainerRef = e) },
        h("input", { ref: (e) => (this.inputRef = e), type: "checkbox", checked: this.checked, value: this.identifier, onChange: this.onCheckBoxChange, "aria-checked": this.indeterminate ? 'mixed' : undefined, disabled: this.isDisabled(), tabIndex: 0, onKeyDown: createEnterKeyHandlerToTriggerClick() }),
        h("span", { class: "vega-checkbox-icon", onClick: this.onSelectedIconClick, tabIndex: -1, "aria-hidden": "true" }, this.renderIconDom()),
        h("div", { class: "vega-checkbox-label-container", ref: (el) => (this.labelElement = el) },
          this.renderLabelDom(),
          this.renderRequireDom()))), this.host);
  }
  renderIconDom() {
    if (this.indeterminate) {
      return h("vega-icon", { icon: "minus-sign", size: this.size === 'small' ? 'size-12' : 'size-16' });
    }
    return this.checked ? (h("vega-icon", { icon: "checkmark", size: this.size === 'small' ? 'size-12' : 'size-16' })) : null;
  }
  renderLabelDom() {
    return (h("span", { class: "vega-checkbox-label" },
      h("slot", null)));
  }
  renderRequireDom() {
    return (h("span", { class: {
        'vega-require': this.required,
      } }, this.required ? '*' : ''));
  }
  initValue() {
    this.value = this.identifier !== '' ? (this.checked ? this.identifier : '') : this.checked;
  }
  /**
   * Syncs the indeterminate property to the native input element.
   * The HTML `indeterminate` attribute can only be set via JavaScript,
   *    so it must be applied imperatively after each render.
   */
  syncNativeIndeterminate() {
    if (this.inputRef) {
      this.inputRef.indeterminate = this.indeterminate;
    }
  }
  /**
   * indicating whether the component is disabled or not, single checkbox will take the self disabled value and the checkbox in group will take the self disabled and group disabled value
   *
   * @returns {boolean} the checkbox disabled or not
   */
  isDisabled() {
    return this.disabled || this.groupDisabled;
  }
  /**
   * The function checks if a checkbox button element can accept a disabled state from a group.
   *
   * @param {GroupDisabledPayload} input - The input parameter is of type GroupDisabledPayload, which is an object containing information about a disabled checkbox button group.
   * @returns {boolean} a boolean value, which indicates whether the input element (this.el) is present in a group  of checkbox buttons (vega-checkbox) or not.
   */
  canAcceptGroupDisabledObserver(input) {
    return findParent(this.host, 'vega-checkbox-group') === input.host;
  }
  /**
   * This function listens for changes in the disabled state of a group and updates the `groupDisabled` variable accordingly.
   *
   * @param {GroupDisabledPayload} input - The input parameter is of type GroupDisabledPayload, which is likely an object containing information about a disabled group.
   */
  groupDisabledObserverListener(input) {
    this.groupDisabled = input.host.disabled;
  }
  /**
   * This function initializes an observer for changes in the disabled state of a checkbox group.
   */
  initAndRegisterGroupDisabledObserver() {
    if (findParent(this.host, 'vega-checkbox-group')) {
      this.groupDisabledObserver = new Observer(this.canAcceptGroupDisabledObserver.bind(this), this.groupDisabledObserverListener.bind(this));
      ChangeManager.register(CHECKBOX_GROUP_DISABLED_CHANGE, this.groupDisabledObserver);
    }
  }
  /**
   * This function unregister a group disabled observer if it exists.
   */
  unRegisterGroupDisabledObserver() {
    if (this.groupDisabledObserver) {
      ChangeManager.unregister(CHECKBOX_GROUP_DISABLED_CHANGE, this.groupDisabledObserver);
    }
  }
  static get is() { return "vega-checkbox"; }
  static get encapsulation() { return "shadow"; }
  static get originalStyleUrls() { return {
    "$": ["vega-checkbox.scss"]
  }; }
  static get styleUrls() { return {
    "$": ["vega-checkbox.css"]
  }; }
  static get properties() { return {
    "identifier": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "string",
        "resolved": "string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [{
            "name": "vegaVersion",
            "text": "1.10.0"
          }],
        "text": "Sets a unique identifier for the checkbox.\n\nRefer to the `value` property for detailed information on\n   how to use this property during form validation."
      },
      "attribute": "identifier",
      "reflect": false,
      "defaultValue": "''"
    },
    "value": {
      "type": "any",
      "mutable": true,
      "complexType": {
        "original": "string | boolean",
        "resolved": "boolean | string",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [{
            "name": "vegaVersion",
            "text": "1.0.7"
          }],
        "text": "Determines the value that is associated with the checkbox\n   when it is checked or unchecked.\n\nWhen the `identifier` property is set, the `value` property will\n   return the value of the `identifier` when the checkbox is checked.\n   When the checkbox is unchecked, the `value` property will\n   return an empty string ''.\n\nIf the `identifier` property is not set, the `value` property behaves\n   as a boolean and returns `true` when the checkbox is checked,\n   and `false` when it is unchecked."
      },
      "attribute": "value",
      "reflect": false,
      "defaultValue": "this.identifier !== '' ? '' : false"
    },
    "checked": {
      "type": "boolean",
      "mutable": true,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [{
            "name": "vegaVersion",
            "text": "1.0.7"
          }],
        "text": "Specifies whether the checkbox should be pre-checked.\n\nUse the `value` property to retrieve the current status of the checkbox."
      },
      "attribute": "checked",
      "reflect": false,
      "defaultValue": "false"
    },
    "indeterminate": {
      "type": "boolean",
      "mutable": true,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [{
            "name": "vegaVersion",
            "text": "2.83.0"
          }],
        "text": "Specifies whether the checkbox is in an indeterminate state.\n\nThe indeterminate state is a visual-only state typically used to represent\n   a checkbox whose value is neither fully checked nor fully unchecked,\n   such as a \"select all\" control where only some children are selected.\n\nSetting this property does not affect the `checked` or `value` properties.\n   User interaction (clicking) will clear the indeterminate state and\n   toggle `checked` as usual."
      },
      "attribute": "indeterminate",
      "reflect": true,
      "defaultValue": "false"
    },
    "disabled": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [{
            "name": "vegaVersion",
            "text": "1.3.0"
          }],
        "text": "Specifies whether the checkbox element is disabled."
      },
      "attribute": "disabled",
      "reflect": true,
      "defaultValue": "false"
    },
    "size": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "'default' | 'small'",
        "resolved": "\"default\" | \"small\"",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [{
            "name": "vegaVersion",
            "text": "1.3.0"
          }],
        "text": "Specifies the size of the checkbox."
      },
      "attribute": "size",
      "reflect": false,
      "defaultValue": "'default'"
    },
    "required": {
      "type": "boolean",
      "mutable": false,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [{
            "name": "vegaVersion",
            "text": "1.3.0"
          }],
        "text": "Specifies whether the checkbox must be checked\n   to pass form validation."
      },
      "attribute": "required",
      "reflect": true,
      "defaultValue": "false"
    },
    "isValid": {
      "type": "boolean",
      "mutable": true,
      "complexType": {
        "original": "boolean",
        "resolved": "boolean",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [{
            "name": "vegaVersion",
            "text": "1.10.0"
          }],
        "text": "Specifies the validation status of the checkbox component."
      },
      "attribute": "is-valid",
      "reflect": true,
      "defaultValue": "null"
    }
  }; }
  static get states() { return {
    "groupDisabled": {},
    "showError": {}
  }; }
  static get events() { return [{
      "method": "vegaChange",
      "name": "vegaChange",
      "bubbles": true,
      "cancelable": true,
      "composed": true,
      "docs": {
        "tags": [{
            "name": "vegaVersion",
            "text": "1.0.10"
          }],
        "text": "An event emitter notifying changes in the value of the checkbox,\n   whether triggered programmatically or through user interaction."
      },
      "complexType": {
        "original": "string | boolean",
        "resolved": "boolean | string",
        "references": {}
      }
    }, {
      "method": "change",
      "name": "change",
      "bubbles": true,
      "cancelable": true,
      "composed": true,
      "docs": {
        "tags": [{
            "name": "eventSemantics",
            "text": "namespace:native"
          }, {
            "name": "vegaVersion",
            "text": "2.0.0"
          }],
        "text": "An event emitter notifying changes in the value of the checkbox,\n   whether triggered programmatically or through user interaction."
      },
      "complexType": {
        "original": "string | boolean",
        "resolved": "boolean | string",
        "references": {}
      }
    }]; }
  static get methods() { return {
    "setValue": {
      "complexType": {
        "signature": "(value: string | boolean) => Promise<void>",
        "parameters": [{
            "tags": [],
            "text": ""
          }],
        "references": {
          "Promise": {
            "location": "global"
          }
        },
        "return": "Promise<void>"
      },
      "docs": {
        "text": "Invoke this method to set the value of the checkbox.\n\nIt is recommended to use this method instead of directly modifying the `value` property.",
        "tags": [{
            "name": "vegaVersion",
            "text": "1.16.0"
          }]
      }
    }
  }; }
  static get elementRef() { return "host"; }
  static get watchers() { return [{
      "propName": "value",
      "methodName": "watchValueChange"
    }, {
      "propName": "checked",
      "methodName": "watchCheckedChange"
    }]; }
}
__decorate([
  InjectVegaGlobalSlimmer()
], VegaCheckbox.prototype, "globalSlimmers", void 0);
__decorate([
  InjectVegaSlimmer()
], VegaCheckbox.prototype, "vegaCheckboxShowErrorController", void 0);
__decorate([
  InjectVegaSlimmer()
], VegaCheckbox.prototype, "ariaAttributesValueMapper", void 0);
__decorate([
  InjectVegaSlimmer()
], VegaCheckbox.prototype, "formFieldController", void 0);
__decorate([
  InjectVegaSlimmer()
], VegaCheckbox.prototype, "changeEventEmitter", void 0);
__decorate([
  InjectVegaSlimmer()
], VegaCheckbox.prototype, "dropdownEventPrevent", void 0);
__decorate([
  InjectVegaSlimmer()
], VegaCheckbox.prototype, "vegaComponentUsageRuntimeMetricsSlimmer", void 0);
