"use strict";
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
var _ = require("lodash");
var classnames = require("classnames");
var React = require("react");
var FormError_1 = require("../FormError");
var Radio_1 = require("./Radio");
var WithKeyboardNav_1 = require("../WithKeyboardNav");
require("./RadioGroup.less");
var cssClass = {
    CONTAINER: "RadioGroup",
    LABEL: "RadioGroup--label",
    RADIO: "RadioGroup--radio",
    RADIO_SELECTED_WITH_ADDITIONAL_TEXT: "RadioGroup--radio--selectedWithAdditionalText",
    ADDITIONAL_TEXT: "RadioGroup--additionalText",
};
var LABEL_ID_PREFIX = "RadioGroup--label";
var nextLabelIDSuffix = 0;
var getNextLabelID = function () { return LABEL_ID_PREFIX + "--" + nextLabelIDSuffix++; };
/**
 * Form element that allows for a single, required selection from a small set of 2 or more options.
 */
var RadioGroup = /** @class */ (function (_super) {
    __extends(RadioGroup, _super);
    function RadioGroup() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this._labelID = getNextLabelID();
        _this._optionRefsByID = {};
        _this._handleRadioRef = function (ref) {
            if (ref) {
                _this._optionRefsByID[ref.props.id] = ref;
            }
        };
        _this._handleNavChange = function (selectedID) {
            var selectedRadioRef = _this._optionRefsByID[selectedID];
            if (!selectedRadioRef) {
                return;
            }
            selectedRadioRef.focus();
        };
        return _this;
    }
    RadioGroup.prototype.render = function () {
        var _this = this;
        var _a = this.props, ariaLabelledBy = _a.ariaLabelledBy, className = _a.className, disabled = _a.disabled, error = _a.error, label = _a.label, onChange = _a.onChange, options = _a.options, selectedID = _a.selectedID;
        if (ariaLabelledBy && label) {
            console.warn("You should not pass both `ariaLabelledBy` and `label` props. The `ariaLabelledBy` prop is ignored.");
        }
        var labelID = label || !ariaLabelledBy ? this._labelID : ariaLabelledBy;
        var focusableOptionID = this._getFocusableOptionID(options);
        return (React.createElement(WithKeyboardNav_1.default, { currentID: focusableOptionID, itemIDs: options.map(function (o) { return (o.disabled ? undefined : o.id); }), onChange: this._handleNavChange },
            React.createElement("div", { "aria-labelledby": labelID, className: classnames(cssClass.CONTAINER, className), role: "radiogroup" },
                !ariaLabelledBy && (React.createElement("div", { className: cssClass.LABEL, id: labelID }, label)),
                error && React.createElement(FormError_1.default, null, error),
                _.map(options, function (o) {
                    var isSelectedAndHasAdditionalText = o.id === selectedID && o.additionalText;
                    return (React.createElement(React.Fragment, { key: o.id },
                        React.createElement(Radio_1.default, { checked: o.id === selectedID, className: classnames(cssClass.RADIO, isSelectedAndHasAdditionalText && cssClass.RADIO_SELECTED_WITH_ADDITIONAL_TEXT), disabled: !!disabled || !!o.disabled, id: o.id, onSelect: onChange, ref: function (ref) { return _this._handleRadioRef(ref); }, tabIndex: o.id === focusableOptionID ? 0 : -1, value: o.value, lang: o.lang }, o.label),
                        isSelectedAndHasAdditionalText && (React.createElement("div", { className: cssClass.ADDITIONAL_TEXT }, o.additionalText))));
                }))));
    };
    /**
     * This implements the roving tabindex pattern as described in the w3.org spec for radio groups:
     * https://www.w3.org/TR/wai-aria-practices-1.1/examples/radio/radio-1/radio-1.html
     *
     * We essentially set the tabindex for all options to -1 except the one that's currently selected
     * or the first non-disabled one in the list.
     */
    RadioGroup.prototype._getFocusableOptionID = function (options) {
        var selectedID = this.props.selectedID;
        var focusableOptionID = null;
        _.forEach(options, function (option) {
            if (!option) {
                return;
            }
            // If we haven't found the selected option, pick the first non-disabled one.
            if (!option.disabled && focusableOptionID === null) {
                focusableOptionID = option.id;
                return;
            }
            // If there's a selected, non-disabled option, pick that as the focusable option.
            if (!option.disabled && option.id === selectedID) {
                focusableOptionID = option.id;
                return;
            }
        });
        return focusableOptionID;
    };
    return RadioGroup;
}(React.PureComponent));
exports.default = RadioGroup;
