"use strict";
/*
 * Copyright 2023 Palantir Technologies, Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.SegmentedControl = void 0;
var tslib_1 = require("tslib");
var classnames_1 = tslib_1.__importDefault(require("classnames"));
var React = tslib_1.__importStar(require("react"));
var common_1 = require("../../common");
var props_1 = require("../../common/props");
var buttons_1 = require("../button/buttons");
/**
 * Segmented control component.
 *
 * @see https://blueprintjs.com/docs/#core/components/segmented-control
 */
exports.SegmentedControl = React.forwardRef(function (props, ref) {
    var _a;
    var className = props.className, defaultValue = props.defaultValue, fill = props.fill, inline = props.inline, _b = props.intent, intent = _b === void 0 ? common_1.Intent.NONE : _b, large = props.large, onValueChange = props.onValueChange, options = props.options, _c = props.role, role = _c === void 0 ? "radiogroup" : _c, small = props.small, controlledValue = props.value, htmlProps = tslib_1.__rest(props, ["className", "defaultValue", "fill", "inline", "intent", "large", "onValueChange", "options", "role", "small", "value"]);
    var _d = React.useState(defaultValue), localValue = _d[0], setLocalValue = _d[1];
    var selectedValue = controlledValue !== null && controlledValue !== void 0 ? controlledValue : localValue;
    var outerRef = React.useRef(null);
    var handleOptionClick = React.useCallback(function (newSelectedValue, targetElement) {
        setLocalValue(newSelectedValue);
        onValueChange === null || onValueChange === void 0 ? void 0 : onValueChange(newSelectedValue, targetElement);
    }, [onValueChange]);
    var handleKeyDown = React.useCallback(function (e) {
        var _a;
        if (role === "radiogroup") {
            // in a `radiogroup`, arrow keys select next item, not tab key.
            var direction = common_1.Utils.getArrowKeyDirection(e, ["ArrowLeft", "ArrowUp"], ["ArrowRight", "ArrowDown"]);
            var outerElement = outerRef.current;
            if (direction === undefined || !outerElement)
                return;
            var focusedElement = (_a = common_1.Utils.getActiveElement(outerElement)) === null || _a === void 0 ? void 0 : _a.closest("button");
            if (!focusedElement)
                return;
            // must rely on DOM state because we have no way of mapping `focusedElement` to a React.JSX.Element
            var enabledOptionElements = Array.from(outerElement.querySelectorAll("button:not(:disabled)"));
            var focusedIndex = enabledOptionElements.indexOf(focusedElement);
            if (focusedIndex < 0)
                return;
            e.preventDefault();
            // auto-wrapping at 0 and `length`
            var newIndex = (focusedIndex + direction + enabledOptionElements.length) % enabledOptionElements.length;
            var newOption = enabledOptionElements[newIndex];
            newOption.click();
            newOption.focus();
        }
    }, [outerRef, role]);
    var classes = (0, classnames_1.default)(common_1.Classes.SEGMENTED_CONTROL, className, (_a = {},
        _a[common_1.Classes.FILL] = fill,
        _a[common_1.Classes.INLINE] = inline,
        _a));
    var isAnySelected = options.some(function (option) { return selectedValue === option.value; });
    return (React.createElement("div", tslib_1.__assign({}, (0, props_1.removeNonHTMLProps)(htmlProps), { role: role, onKeyDown: handleKeyDown, className: classes, ref: (0, common_1.mergeRefs)(ref, outerRef) }), options.map(function (option, index) {
        var isSelected = selectedValue === option.value;
        return (React.createElement(SegmentedControlOption, tslib_1.__assign({}, option, { intent: intent, isSelected: isSelected, key: option.value, large: large, onClick: handleOptionClick, small: small }, (role === "radiogroup"
            ? {
                "aria-checked": isSelected,
                role: "radio",
                // "roving tabIndex" on a radiogroup: https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#kbd_roving_tabindex
                // `!isAnySelected` accounts for case where no value is currently selected
                // (passed value/defaultValue is not one of the values of the passed options.)
                // In this case, set first item to be tabbable even though it's unselected.
                tabIndex: isSelected || (index === 0 && !isAnySelected) ? 0 : -1,
            }
            : {
                "aria-pressed": isSelected,
            }))));
    })));
});
exports.SegmentedControl.displayName = "".concat(props_1.DISPLAYNAME_PREFIX, ".SegmentedControl");
function SegmentedControlOption(_a) {
    var isSelected = _a.isSelected, label = _a.label, onClick = _a.onClick, value = _a.value, buttonProps = tslib_1.__rest(_a, ["isSelected", "label", "onClick", "value"]);
    var handleClick = React.useCallback(function (event) { return onClick === null || onClick === void 0 ? void 0 : onClick(value, event.currentTarget); }, [onClick, value]);
    return React.createElement(buttons_1.Button, tslib_1.__assign({}, buttonProps, { onClick: handleClick, minimal: !isSelected, text: label !== null && label !== void 0 ? label : value }));
}
SegmentedControlOption.displayName = "".concat(props_1.DISPLAYNAME_PREFIX, ".SegmentedControlOption");
//# sourceMappingURL=segmentedControl.js.map