'use client';
'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var tslib = require('tslib');
var lit = require('lit');
var decorators_js = require('lit/decorators.js');
var classMap_js = require('lit/directives/class-map.js');
var live_js = require('lit/directives/live.js');
var formControlElement = require('../../base/form-control-element.cjs.js');
var validatorMixin = require('../../utils/validatorMixin.cjs.js');
var watch = require('../../utils/watch.cjs.js');
var radioGroup = require('./radio-group.cjs.js');

/**
 * @summary RadioGroup group multiple radios so they function as a single form control.
 *
 * @slot default - The default slot where sgds-radio are placed.
 * @slot invalidIcon - The slot for invalid icon
 *
 * @event sgds-change - Emitted when the radio group's selected value changes.
 *
 */
class SgdsRadioGroup extends validatorMixin.SgdsFormValidatorMixin(formControlElement["default"]) {
    constructor() {
        super(...arguments);
        /**@internal */
        this.defaultValue = "";
        /** The selected value of the control. */
        this.value = "";
        /**Feedback text for error state when validated */
        this.invalidFeedback = "";
        /** Allows invalidFeedback, invalid and valid styles to be visible with the input */
        this.hasFeedback = false;
        /** Makes the input as a required field. */
        this.required = false;
        this._isTouched = false;
    }
    _handleValueChange() {
        this.emit("sgds-change", { detail: { value: this.value } });
        this._updateCheckedRadio();
    }
    _handleInvalidChange() {
        this._radios.forEach(r => (r.invalid = this.invalid));
    }
    /**
     * radio requries a custom _mixinResetFormControl as the update of input value
     * requires to fire a reset event manually
     * */
    _mixinResetFormControl() {
        this.value = this.input.value = this.defaultValue;
        this._updateInputValue("reset");
        this._mixinResetValidity(this.input);
    }
    connectedCallback() {
        super.connectedCallback();
        this.defaultValue = this.value;
        this.addEventListener("sgds-blur", () => {
            this._isTouched = true;
        });
    }
    firstUpdated(changedProperties) {
        super.firstUpdated(changedProperties);
        const radios = this._radios;
        radios.forEach((item, index) => {
            if (radios.length > 1) {
                switch (index) {
                    case 0:
                        item.setAttribute("first-of-type", "");
                        break;
                    case radios.length - 1:
                        item.setAttribute("last-of-type", "");
                        break;
                    default:
                        item.setAttribute("nth-of-type", "");
                }
            }
        });
        if (this.value) {
            this._updateInputValue("change");
        }
    }
    _handleRadioClick(event) {
        event.preventDefault();
        const target = event.target;
        if (target.disabled) {
            return;
        }
        this.value = target.value;
        this._updateInputValue();
        const radios = this._radios;
        radios.forEach(radio => {
            return (radio.checked = radio === target);
        });
    }
    /**
     * when input value is set programatically, need to manually dispatch a change event
     * In order to prevent race conditions and ensure sequence of events, set input's value here instead of binding to value prop of input
     */
    _updateInputValue(eventName = "change") {
        this.input.value = this.value;
        this.input.dispatchEvent(new InputEvent(eventName));
    }
    _handleKeyDown(event) {
        var _a;
        if (!["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", " "].includes(event.key)) {
            return;
        }
        const radios = this._radios.filter(radio => !radio.disabled);
        const checkedRadio = (_a = radios.find(radio => radio.checked)) !== null && _a !== void 0 ? _a : radios[0];
        //if eventkey is space, index increment is 0, if eventkey arrowup/arrowleft, index is -1, arrowright/arrowdown, index incr is 1
        const incr = event.key === " " ? 0 : ["ArrowUp", "ArrowLeft"].includes(event.key) ? -1 : 1;
        let index = radios.indexOf(checkedRadio) + incr;
        if (index < 0) {
            index = radios.length - 1;
        }
        if (index > radios.length - 1) {
            index = 0;
        }
        this._radios.forEach(radio => {
            radio.checked = false;
            radio.tabIndex = -1;
        });
        this.value = radios[index].value;
        this._updateInputValue();
        radios[index].checked = true;
        radios[index].tabIndex = 0;
        // preventDefault at the end to allow Tab
        event.preventDefault();
    }
    _handleSlotChange() {
        const radios = this._radios;
        radios.forEach(radio => (radio.checked = radio.value === this.value));
        this._disabledChildRadios();
        if (!radios.some(radio => radio.checked)) {
            if (radios[0])
                radios[0].tabIndex = 0;
        }
    }
    _updateCheckedRadio() {
        const radios = this._radios;
        radios.forEach(radio => (radio.checked = radio.value === this.value));
    }
    _renderHintText() {
        const hintTextTemplate = lit.html ` <div id="${this._controlId}Help" class="form-text">${this.hintText}</div> `;
        return this.hintText && hintTextTemplate;
    }
    /**
     * Checks for validity. Under the hood, HTMLFormElement's reportValidity method calls this method to check for component's validity state
     * Note that the native error popup is prevented for SGDS form components by default. Instead the validation message shows up in the feedback container of SgdsInput
     */
    reportValidity() {
        return this._mixinReportValidity();
    }
    /**
     * Checks for validity without any native error popup message
     */
    checkValidity() {
        return this._mixinCheckValidity();
    }
    /**
     * Returns the ValidityState object
     */
    get validity() {
        return this._mixinGetValidity();
    }
    /**
     * Returns the validation message based on the ValidityState
     */
    get validationMessage() {
        return this._mixinGetValidationMessage();
    }
    _handleIsTouched() {
        if (this._isTouched) {
            this.invalid = !this.input.checkValidity();
        }
    }
    _handleDisabledChange() {
        // Disabled form controls are always valid, so we need to recheck validity when the state changes
        this.setInvalid(false);
        this._disabledChildRadios();
    }
    _disabledChildRadios() {
        if (this.disabled) {
            const radios = this._radios;
            radios.forEach(radio => (radio.disabled = this.disabled));
        }
    }
    render() {
        const defaultSlot = lit.html `
      <slot
        class="radio-container"
        @click=${this._handleRadioClick}
        @keydown=${this._handleKeyDown}
        @slotchange=${this._handleSlotChange}
        role="presentation"
      ></slot>
    `;
        return lit.html `
      <fieldset name=${this.name}>
        <div class="label-hint-container">
          <label
            class=${classMap_js.classMap({
            "form-label": true,
            required: this.required
        })}
          >
            ${this.label}
          </label>
          ${this._renderHintText()}
        </div>
        ${defaultSlot}
        <input
          type="text"
          class="radio-group-validation-input ${classMap_js.classMap({
            "is-invalid": this.hasFeedback && this.invalid
        })}"
          ?required=${this.required}
          tabindex="-1"
          @change=${(e) => super._mixinHandleChange(e)}
          .value=${live_js.live(this.value)}
          aria-describedby=${this.invalid && this.hasFeedback ? "radio-group-feedback" : `${this._controlId}Help`}
        />
        ${this.invalid && this.hasFeedback
            ? lit.html `
              <div class="invalid-feedback-container">
                <slot name="invalidIcon">
                  <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none">
                    <path
                      d="M17.5 10C17.5 14.1421 14.1421 17.5 10 17.5C5.85786 17.5 2.5 14.1421 2.5 10C2.5 5.85786 5.85786 2.5 10 2.5C14.1421 2.5 17.5 5.85786 17.5 10ZM10 6.25C9.49805 6.25 9.10584 6.68339 9.15578 7.18285L9.48461 10.4711C9.51109 10.7359 9.7339 10.9375 10 10.9375C10.2661 10.9375 10.4889 10.7359 10.5154 10.4711L10.8442 7.18285C10.8942 6.68339 10.5019 6.25 10 6.25ZM10.0014 11.875C9.48368 11.875 9.06394 12.2947 9.06394 12.8125C9.06394 13.3303 9.48368 13.75 10.0014 13.75C10.5192 13.75 10.9389 13.3303 10.9389 12.8125C10.9389 12.2947 10.5192 11.875 10.0014 11.875Z"
                      fill="currentColor"
                    />
                  </svg>
                </slot>
                <div id="radio-group-feedback" class="invalid-feedback">
                  ${this.invalidFeedback ? this.invalidFeedback : this.input.validationMessage}
                </div>
              </div>
            `
            : lit.nothing}
      </fieldset>
    `;
    }
}
SgdsRadioGroup.styles = [...formControlElement["default"].styles, radioGroup["default"]];
tslib.__decorate([
    decorators_js.query("slot:not([name])")
], SgdsRadioGroup.prototype, "defaultSlot", void 0);
tslib.__decorate([
    decorators_js.state()
], SgdsRadioGroup.prototype, "defaultValue", void 0);
tslib.__decorate([
    decorators_js.property({ reflect: true })
], SgdsRadioGroup.prototype, "value", void 0);
tslib.__decorate([
    decorators_js.property({ type: String, reflect: true })
], SgdsRadioGroup.prototype, "invalidFeedback", void 0);
tslib.__decorate([
    decorators_js.property({ type: Boolean, reflect: true })
], SgdsRadioGroup.prototype, "hasFeedback", void 0);
tslib.__decorate([
    decorators_js.property({ type: Boolean, reflect: true })
], SgdsRadioGroup.prototype, "required", void 0);
tslib.__decorate([
    watch.watch("value", { waitUntilFirstUpdate: true })
], SgdsRadioGroup.prototype, "_handleValueChange", null);
tslib.__decorate([
    watch.watch("invalid", { waitUntilFirstUpdate: true })
], SgdsRadioGroup.prototype, "_handleInvalidChange", null);
tslib.__decorate([
    decorators_js.state()
], SgdsRadioGroup.prototype, "_isTouched", void 0);
tslib.__decorate([
    decorators_js.queryAssignedElements()
], SgdsRadioGroup.prototype, "_radios", void 0);
tslib.__decorate([
    watch.watch("_isTouched", { waitUntilFirstUpdate: true })
], SgdsRadioGroup.prototype, "_handleIsTouched", null);
tslib.__decorate([
    watch.watch("disabled", { waitUntilFirstUpdate: true })
], SgdsRadioGroup.prototype, "_handleDisabledChange", null);

exports.SgdsRadioGroup = SgdsRadioGroup;
exports["default"] = SgdsRadioGroup;
//# sourceMappingURL=sgds-radio-group.cjs.js.map
