import { r as registerInstance, c as createEvent, g as getElement, h, H as Host } from './index-442cf464.js';
import { f as findRelevantOptions } from './mutation-oberserver-ac258d15.js';

const radioGroupCss = "lu-radio-group{display:flex;flex-flow:column}lu-radio-group.direction-across{margin-left:0;margin-right:5px;flex-flow:row}";

const RadioGroup = class {
  constructor(hostRef) {
    registerInstance(this, hostRef);
    this.luBlur = createEvent(this, "luBlur", 7);
    this.luChange = createEvent(this, "luChange", 7);
    this.inputId = `lu-rg-${radioGroupIds++}`;
    /**
     * This is used when the parent form group receives the update event to tell the parent if it should validate or not.
     */
    this.isResetting = false;
    /**
     * Provides a way for users to specify the labeling elements. Pass the id's, separated by a space, to this prop.
     */
    this.ariaLabeledByAddition = '';
    /**
     * If `true`, the radios can be deselected.
     */
    this.allowEmptySelection = false;
    /**
     * Direction of elements
     */
    this.direction = 'down';
    /**
     * @internal - used by the form group element to declare it's presence
     */
    this.hasFormGroup = false;
    /**
     * id set dynamically
     */
    this.useId = this.inputId + '-wrapper';
    /**
     * The name of the control, which is submitted with the form data.
     */
    this.name = this.inputId;
    /**
     * Tells if a value is required from the radio group
     */
    this.required = false;
    /**
     * Used to add is-valid attribute signifying validity
     */
    this.valid = false;
    /**
     * Used to add is-invalid attribute signifying invalidity
     */
    this.invalid = false;
    this.mutationCallback = (mutationList, _observer) => {
      mutationList.forEach((record) => {
        if (record.type === 'childList') {
          for (let i = 0; i < record.addedNodes.length; i++) {
            const relevantOptions = findRelevantOptions(record.addedNodes[i], 'lu-radio');
            if (relevantOptions)
              relevantOptions.forEach(this.handleNewRadio);
          }
          for (let i = 0; i < record.removedNodes.length; i++) {
            const relevantOptions = findRelevantOptions(record.removedNodes[i], 'lu-radio');
            if (relevantOptions)
              relevantOptions.forEach(this.radioDisconnected);
          }
        }
        if (record.type === 'attributes') {
          if (record.attributeName.toLowerCase() === 'data-is-radio-checked') {
            this.updateRadios(record.target);
          }
          if (record.attributeName.toLowerCase() === 'has-focus') {
            let allBlurred = true;
            this.getRadios().forEach(radio => {
              const focused = radio.getAttribute('has-focus');
              if (focused || focused === '') {
                allBlurred = false;
              }
            });
            if (allBlurred) {
              this.luBlur.emit();
            }
          }
        }
      });
    };
    this.handleNewRadio = (radio) => {
      radio.name = this.name;
      radio.labeledById = this.inputId;
      this.updateRadios();
    };
    this.radioDisconnected = (_radio) => {
      this.updateRadios();
    };
    this.getRadios = () => {
      return Array.from(this.el.querySelectorAll('lu-radio'));
    };
  }
  valueChanged(value) {
    this.luChange.emit({ value, isResetting: this.isResetting });
    this.isResetting = false;
  }
  connectedCallback() {
    this.updateRadios();
    const el = this.el;
    this.mutationO = new MutationObserver(this.mutationCallback);
    this.mutationO.observe(el, {
      childList: true,
      subtree: true,
      attributes: true,
      attributeFilter: ['data-is-radio-checked', 'has-focus']
    });
  }
  disconnectedCallback() {
    this.mutationO.disconnect();
    this.mutationO = undefined;
  }
  updateRadios(checkedRadio) {
    const radios = this.getRadios();
    let hasChecked = false;
    for (const radio of radios) {
      radio.canDeselect = this.allowEmptySelection;
      if (checkedRadio) {
        if (radio === checkedRadio && checkedRadio.checked) {
          this.value = checkedRadio.value;
          hasChecked = true;
        }
        else if (checkedRadio.checked) {
          radio.checked = false;
        }
        else if (radio.checked) {
          hasChecked = true;
        }
      }
      else {
        if (radio.checked && !hasChecked) {
          hasChecked = true;
          this.value = radio.value;
        }
        else {
          radio.checked = false;
        }
      }
    }
    if (!hasChecked) {
      this.value = null;
    }
  }
  /**
   * this gives us a handle to set focus on the element
   */
  async setFocus() {
    if (this.el) {
      const radioList = this.el.querySelectorAll('lu-radio');
      if (radioList && radioList[0]) {
        radioList[0].focus();
      }
    }
  }
  /**
   * this is used by the form validation/ form group to reset Value without initiating a validity check
   * @param update
   */
  async updateValue(update) {
    this.isResetting = true;
    this.getRadios().forEach(radio => {
      if (JSON.stringify(radio.value) === JSON.stringify(update)) {
        radio.checked = true;
      }
    });
  }
  hostData() {
    return Object.assign(Object.assign({ class: {
        'is-radio-group': true,
        'direction-across': this.direction === 'across'
      }, 'role': 'radiogroup' }, (this.hasFormGroup || (this.ariaLabeledByAddition && this.ariaLabeledByAddition.length > 0)) &&
      { 'aria-labelledby': `${this.ariaLabeledByAddition} ` + (this.hasFormGroup ? this.inputId + '-label' : '') }), { 'id': this.useId, 'is-valid': this.valid, 'is-invalid': this.invalid });
  }
  get el() { return getElement(this); }
  static get watchers() { return {
    "value": ["valueChanged"]
  }; }
  render() { return h(Host, this.hostData()); }
};
let radioGroupIds = 0;
RadioGroup.style = radioGroupCss;

export { RadioGroup as lu_radio_group };

//# sourceMappingURL=lu-radio-group.entry.js.map