"use strict";
/*---------------------------------------------------------------------------------------------
 * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
 * See LICENSE.md in the project root for license terms and full copyright notice.
 *--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
 * @module Picker
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.ListPicker = exports.getListPanel = exports.ExpandableSection = exports.ListPickerItem = exports.ListItemType = void 0;
require("./ListPicker.scss");
const classnames_1 = require("classnames");
const React = require("react");
const components_react_1 = require("@itwin/components-react");
const core_react_1 = require("@itwin/core-react");
const DragInteraction_1 = require("../toolbar/DragInteraction");
const UiFramework_1 = require("../UiFramework");
const itwinui_icons_react_1 = require("@itwin/itwinui-icons-react");
/** Enum for the list picker item type
 * @beta
 */
var ListItemType;
(function (ListItemType) {
    ListItemType[ListItemType["Item"] = 0] = "Item";
    ListItemType[ListItemType["Separator"] = 1] = "Separator";
    ListItemType[ListItemType["Container"] = 2] = "Container";
})(ListItemType || (exports.ListItemType = ListItemType = {}));
/** List Picker Item React component
 * @beta
 */
class ListPickerItem extends React.PureComponent {
    /** Renders ListPickerItem */
    render() {
        const itemClassName = (0, classnames_1.default)("ListPicker-item", this.props.isActive && "is-active", this.props.isFocused && "is-focused", this.props.className);
        // TODO - if cut off, show a title
        const title = this.props.label && this.props.label.length > 25
            ? this.props.label
            : undefined;
        return (
        // eslint-disable-next-line jsx-a11y/click-events-have-key-events
        React.createElement("div", { className: itemClassName, onClick: this.props.onClick, role: "button", tabIndex: -1 },
            React.createElement("div", { className: "label", title: title }, this.props.label)));
    }
}
exports.ListPickerItem = ListPickerItem;
/** Expandable Section React component
 * @beta
 */
class ExpandableSection extends React.PureComponent {
    /** Creates an ExpandableSection */
    constructor(props) {
        super(props);
        this._onClick = () => {
            this.setState((prevState) => ({ expanded: !prevState.expanded }));
        };
        this.state = { expanded: !!this.props.expanded };
    }
    async componentDidUpdate(prevProps) {
        if (this.props.expanded !== prevProps.expanded) {
            this.setState({ expanded: true });
        }
    }
    /** Renders ExpandableSection */
    render() {
        const className = (0, classnames_1.default)("nz-toolbar-item-expandable-group-group", this.props.className);
        const icon = this.state.expanded ? (React.createElement(core_react_1.Icon, { iconSpec: React.createElement(itwinui_icons_react_1.SvgChevronDown, null) })) : (React.createElement(core_react_1.Icon, { iconSpec: React.createElement(itwinui_icons_react_1.SvgChevronRight, null) }));
        return (React.createElement(components_react_1.Panel, { className: className, style: this.props.style, key: this.props.title },
            React.createElement("div", { onClick: this._onClick, className: this.state.expanded
                    ? "ListPickerInnerContainer-header-expanded"
                    : "ListPickerInnerContainer-header", role: "button", tabIndex: -1, "aria-expanded": this.state.expanded },
                React.createElement("div", { className: "ListPickerInnerContainer-header-content" },
                    React.createElement("div", { className: "ListPickerInnerContainer-expander" }, icon),
                    React.createElement("div", { className: "ListPickerInnerContainer-title" }, this.props.title))),
            this.state.expanded ? (React.createElement(components_react_1.GroupColumn, null, this.props.children)) : (React.createElement("div", null))));
    }
}
exports.ExpandableSection = ExpandableSection;
/** @beta */
function getListPanel(props) {
    const expandSingleSection = () => {
        const populatedContainers = props.items.filter((item) => {
            return (item.type === ListItemType.Container && item.children.length !== 0);
        });
        return populatedContainers.length === 1;
    };
    const listItemToElement = (item, itemIndex) => {
        switch (item.type) {
            case ListItemType.Item:
                return (React.createElement(ListPickerItem, { ...props, key: itemIndex.toString(), label: item.name, isActive: item.enabled, onClick: () => {
                        props.setEnabled(item, !item.enabled);
                    } }));
            case ListItemType.Separator:
                return (React.createElement("div", { key: itemIndex.toString(), className: "ListPicker-separator" }));
            case ListItemType.Container:
                if (item.children.length !== 0) {
                    return (React.createElement(ExpandableSection, { key: itemIndex.toString(), title: item.name, className: "ListPickerInnerContainer", expanded: props.expanded === true
                            ? !expandSingleSection()
                            : expandSingleSection() },
                        React.createElement(components_react_1.GroupColumn, null, item.children.map(listItemToElement))));
                }
                else {
                    return React.createElement("div", { key: itemIndex.toString() });
                }
            default:
                return React.createElement("div", { key: itemIndex.toString() });
        }
    };
    return (React.createElement(components_react_1.Panel, { className: "ListPickerContainer" },
        React.createElement(components_react_1.Title, null, props.title),
        props.searchBox && props.onSearchValueChange && (
        // eslint-disable-next-line deprecation/deprecation
        React.createElement(core_react_1.SearchBox, { className: "ListPickerSearchBox", onValueChanged: props.onSearchValueChange })),
        React.createElement(components_react_1.Columns, null,
            React.createElement(components_react_1.GroupColumn, { className: "ListPicker-column" }, props.items.map(listItemToElement)))));
}
exports.getListPanel = getListPanel;
/**
 * List picker toolbar popup item.
 * Used to provide an expandable list of items to enable/disable items.
 * @beta
 */
function ListPickerPopupItem(props) {
    const icon = props.iconSpec ? (typeof props.iconSpec === "string" ? (React.createElement(core_react_1.Icon, { iconSpec: props.iconSpec })) : (React.createElement("i", { className: "icon uifw-item-svg-icon" }, props.iconSpec))) : (React.createElement(core_react_1.Icon, { iconSpec: React.createElement(itwinui_icons_react_1.SvgList, null) }));
    return (React.createElement(DragInteraction_1.ToolbarDragInteractionContext.Consumer, null, (isEnabled) => {
        return props.panelOnly === true ? (getListPanel(props)) : (React.createElement(components_react_1.PopupItem, { hideIndicator: isEnabled, icon: icon, title: props.title, panel: getListPanel(props) }));
    }));
}
/**
 * List Picker that lets the user pick from a list of items to enable/disable
 * It also provides options to enable all, disable all and invert selection
 * @beta
 */
class ListPicker extends React.Component {
    static get Key_All() {
        return -3;
    }
    static get Key_None() {
        return -2;
    }
    static get Key_Invert() {
        return -1;
    }
    static get Key_Separator() {
        return -4;
    }
    /** Creates a ListPicker */
    constructor(props) {
        super(props);
        // Handle enabling/disabling the items
        // This will call the this.props.setEnabled function to provide the parent with a chance to process it
        this._setEnabled = (item, enabled) => {
            if (this.isSpecialItem(item)) {
                switch (item.key) {
                    case ListPicker.Key_All: {
                        if (this.props.enableAllFunc)
                            this.props.enableAllFunc();
                        return;
                    }
                    case ListPicker.Key_None: {
                        if (this.props.disableAllFunc)
                            this.props.disableAllFunc();
                        return;
                    }
                    case ListPicker.Key_Invert: {
                        if (this.props.invertFunc)
                            this.props.invertFunc();
                        return;
                    }
                }
            }
            // Call on parent to do processing of the item
            this.props.setEnabled(item, enabled);
        };
    }
    // Creates an array of items containing the separator and special requests (all, none, invert)
    createItems(items) {
        const newItems = [];
        // Create special buttons (All/None/Invert)
        if (this.props.enableAllFunc) {
            let allEnabled = true;
            items.map((item) => {
                allEnabled = allEnabled && item.enabled;
            });
            newItems.push({
                key: ListPicker.Key_All,
                name: UiFramework_1.UiFramework.translate("pickerButtons.all"),
                enabled: allEnabled,
                type: ListItemType.Item,
            });
        }
        if (this.props.disableAllFunc) {
            let allDisabled = false;
            items.map((item) => {
                allDisabled = allDisabled || item.enabled;
            });
            newItems.push({
                key: ListPicker.Key_None,
                name: UiFramework_1.UiFramework.translate("pickerButtons.none"),
                enabled: !allDisabled,
                type: ListItemType.Item,
            });
        }
        if (this.props.invertFunc) {
            newItems.push({
                key: ListPicker.Key_Invert,
                name: UiFramework_1.UiFramework.translate("pickerButtons.invert"),
                enabled: false,
                type: ListItemType.Item,
            });
        }
        if (this.props.enableAllFunc ||
            this.props.disableAllFunc ||
            this.props.invertFunc) {
            newItems.push({
                key: ListPicker.Key_Separator,
                name: UiFramework_1.UiFramework.translate("pickerButtons.separator"),
                enabled: false,
                type: ListItemType.Separator,
            });
        }
        // Push items
        items.map((item) => {
            newItems.push(item);
        });
        return newItems;
    }
    /**
     * Checks if item is a special item.
     * @param item Item to check
     */
    isSpecialItem(item) {
        return (item.key === ListPicker.Key_All ||
            item.key === ListPicker.Key_Invert ||
            item.key === ListPicker.Key_None ||
            item.type !== ListItemType.Item ||
            item.key === ListPicker.Key_Separator);
    }
    /** Renders ListPicker */
    render() {
        return (React.createElement(ListPickerPopupItem, { ...this.props, title: this.props.title, setEnabled: this._setEnabled, onExpanded: this.props.onExpanded, items: this.createItems(this.props.items), iconSpec: this.props.iconSpec }));
    }
}
exports.ListPicker = ListPicker;
//# sourceMappingURL=ListPicker.js.map