// ReSharper disable InconsistentNaming
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
function isConnected(node) {
    if (node == null)
        return false;
    try {
        return document.contains(node);
    }
    catch (e) {
        return false;
    }
}
function delay(millis) {
    return new Promise(resolve => setTimeout(resolve, millis));
}
export function collapse(element, state) {
    if (!isConnected(element))
        return;
    $(element).collapse(state ? 'hide' : 'show');
}
export function customCollapse(element_1, state_1) {
    return __awaiter(this, arguments, void 0, function* (element, state, millis = 350) {
        if (!isConnected(element))
            return;
        const elementState = element.classList.contains('hide') || element.classList.contains('hiding');
        if (state === elementState)
            return;
        element.style.setProperty('--duration', `${millis}ms`);
        if (!state) {
            element.classList.remove('hide', 'hiding');
            element.classList.add('showing');
            yield delay(millis);
            if (!element.classList.contains('showing'))
                return; // interrupted
            element.classList.remove('showing');
            element.classList.add('show');
        }
        else {
            element.classList.remove('showing', 'show');
            element.classList.add('hiding');
            yield delay(millis);
            if (!element.classList.contains('hiding'))
                return; // interrupted
            element.classList.remove('hiding');
            element.classList.add('hide');
        }
        element.style.removeProperty('--duration');
    });
}
export function scrollTo(selector, top, duration = 0) {
    $(selector).animate({ scrollTop: top }, duration);
}
export function checkVisible(selector, threshold = 0, mode = 'visible') {
    const elem = $(selector)[0];
    if (elem == undefined)
        return false;
    const rect = elem.getBoundingClientRect();
    const viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight);
    const above = rect.bottom - threshold < 0;
    const below = rect.top - viewHeight + threshold >= 0;
    return mode === 'above' ? above : (mode === 'below' ? below : !above && !below);
}
export function getBoundingBox(element) {
    if (!isConnected(element))
        return { x: 0, y: 0, width: 0, height: 0 };
    const rect = element.getBoundingClientRect();
    return { x: rect.left, y: rect.top, width: rect.width, height: rect.height };
}
export function getBoundingBoxes(element) {
    if (!isConnected(element))
        return [];
    const results = [];
    for (const child of element.children) {
        results.push(getBoundingBox(child));
    }
    return results;
}
export function enableTooltips(elements) {
    $(elements.filter(x => isConnected(x))).tooltip();
}
export function dropdown(element, action, placement, autoClose) {
    if (!isConnected(element))
        return;
    autoClose = autoClose || 'always';
    // Configure dropdown and execute action
    $(element)
        .dropdown({ popperConfig: { placement: placement !== null && placement !== void 0 ? placement : 'bottom-start' } })
        .dropdown(action);
    // Down below is autoclose behavior
    if (autoClose === 'never')
        return;
    if (action !== 'toggle' && action !== 'show')
        return;
    // Autoclose only works if we can find the menu
    const menu = $(element).parent().find('.dropdown-menu');
    if (menu.length === 0)
        return;
    const callback = (e) => {
        // Don't auto-close if the event came from the trigger element
        if (isOrHas($(element), e.target))
            return;
        // Check if its inside or outside the menu
        const insideMenu = isOrHas(menu, e.target);
        if (autoClose === 'inside' && !insideMenu)
            return;
        if (autoClose === 'outside' && insideMenu)
            return;
        $(element).dropdown('hide');
    };
    // Register global click handler
    $('body').on('click', callback);
    // Cleanup click handler on dropdown hide
    $(element).one('hidden.bs.dropdown', () => $('body').off('click', callback));
}
function isOrHas(a, b) {
    return a.is(b) || a.has(b).length !== 0;
}
export function createToast(id, html) {
    $('.toast-container').append(html)
        .find(`#${id}`)
        .toast('show')
        .on('hidden.bs.toast', function () { this.remove(); });
}
export function updateToast(id, html) {
    $(`#${id}`).replaceWith(html).toast();
}
export function setAttribute(selector, attribute, value) {
    $(selector).attr(attribute, value);
}
export function trigger(element, selector, events) {
    if (!isConnected(element))
        return;
    let jquery = $(element);
    if (selector != null)
        jquery = jquery.find(selector);
    for (const event of events)
        jquery.trigger(event);
}
//# sourceMappingURL=helpers.js.map