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 (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        if (typeof b !== "function" && b !== null)
            throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
import { isValidElement } from 'react';
import { isBrowser } from '../lib/globalObject.js';
import { isForwardRef, isMemo } from './react-is.js';
export { delay } from './delay.js';
export var emptyHandler = function () {
    /* noop */
};
var CancelationError = /** @class */ (function (_super) {
    __extends(CancelationError, _super);
    function CancelationError() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this.code = 'CancelationError';
        return _this;
    }
    return CancelationError;
}(Error));
export { CancelationError };
export function taskWithDelay(task, ms) {
    var cancelationToken = function () { return null; };
    new Promise(function (resolve, reject) {
        cancelationToken = reject;
        setTimeout(resolve, ms);
    })
        .then(task)
        .catch(function () { return null; });
    return cancelationToken;
}
export function isFunction(x) {
    return typeof x === 'function';
}
export function isFunctionalComponent(Component) {
    return Boolean(typeof Component === 'function' && !(Component.prototype && Component.prototype.isReactComponent));
}
export function isClassComponent(Component) {
    return Boolean(typeof Component === 'function' && Component.prototype && Component.prototype.isReactComponent);
}
export function isIntrinsicElement(element) {
    return typeof element.type === 'string';
}
export function isRefableElement(element) {
    return (Boolean(isIntrinsicElement(element) || isClassComponent(element.type) || isForwardRef(element)) || isMemo(element));
}
export function escapeRegExpSpecChars(s) {
    return s.replace(/[\\^$*+?.()|[\]{}]/g, '\\$&');
}
export var getRandomID = function () { return Math.random().toString(16).slice(2); };
export var isExternalLink = function (link, globalObject) {
    return isBrowser(globalObject) && new RegExp("^(https?:)?//(?!".concat(globalObject.location.host, ")\\S+"), 'gi').test(link);
};
/**
 * Check if the given ReactNode is an element of the specified ReactUI component
 */
export var isReactUINode = function (componentName, node) {
    if (isValidElement(node)) {
        return (Object.prototype.hasOwnProperty.call(node.type, '__KONTUR_REACT_UI__') &&
            // @ts-expect-error: React doesn't know about existence of __KONTUR_REACT_UI__.
            node.type.__KONTUR_REACT_UI__ === componentName);
    }
    return false;
};
var KB = 1024;
var UNITS = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
var calculateDecimals = function (decimals) {
    if (decimals < 0) {
        return 0;
    }
    return 0;
};
export var formatBytes = function (bytes, decimals) {
    if (decimals === void 0) { decimals = 2; }
    if (bytes === 0) {
        return '0 Bytes';
    }
    if (!bytes) {
        return null;
    }
    var calculatedDecimals = calculateDecimals(decimals);
    var i = Math.floor(Math.log2(bytes) / Math.log2(KB));
    var formattedBytes = parseFloat((bytes / Math.pow(KB, i)).toFixed(calculatedDecimals));
    return "".concat(formattedBytes, " ").concat(UNITS[i]);
};
/**
 * Проверяет, не является ли переданный аргумент null или undefined и исключает типы null и undefined из типа аргумента
 *
 * @param value Значение, которое нужно проверить и исключить из него типы
 * @returns Возвращает true, если переданный аргумент не является null или undefined иначе false
 */
export var isNonNullable = function (value) {
    return value !== null && value !== undefined;
};
/**
 * Checks if the value `null` or `undefined`.
 *
 * @param value Value to check for `null` and `undefined`.
 * @returns Returns `true` if `value` is `null` or `undefined`, else `false`.
 */
export var isNullable = function (value) {
    return value === null || value === undefined;
};
/**
 * Creates a function that checks if the given `child`
 * is an instance of some component specified by `name`.
 *
 * @param name Component name for which function will be created.
 * @returns A function that checks if the given `child` is an instance of the component specified by `name`.
 */
export var isReactUIComponent = function (name) {
    return function (child) {
        var _a;
        // @ts-expect-error: Property `type` doesn't exist on type `React.ReactNode`, but exists on type `React.ReactElement` meanwhile `React.ReactElement` is not compatible with `React` `children` type.
        return ((_a = child === null || child === void 0 ? void 0 : child.type) === null || _a === void 0 ? void 0 : _a.__KONTUR_REACT_UI__) === name;
    };
};
/**
 * Checks if a component instance is a ReactUI component with the given name.
 *
 * @typeParam T Expected ReactUI component type.
 * @param instance Component instance.
 * @param componentName ReactUI component name.
 * @returns `true` if it matches, otherwise `false`.
 */
export var isReactUIInstance = function (instance, componentName) {
    var constructor = instance === null || instance === void 0 ? void 0 : instance.constructor;
    return '__KONTUR_REACT_UI__' in constructor && constructor.__KONTUR_REACT_UI__ === componentName;
};
/**
 * Extracts all data attributes from props and returns them as well as props.
 *
 * @param props Props object to extract data attributes from.
 * @returns Separated data attributes and all other props.
 */
export var extractDataProps = function (props) {
    var dataProps = {};
    var restWithoutDataProps = {};
    Object.entries(props).map(function (_a) {
        var name = _a[0], value = _a[1];
        if (name.startsWith('data-')) {
            return (dataProps[name] = value);
        }
        return (restWithoutDataProps[name] = value);
    });
    return { dataProps: dataProps, restWithoutDataProps: restWithoutDataProps };
};
/**
 * Basically `.startsWith` for arrays.
 *
 * @param searchKeys Array of strings to test against `inputString`.
 * @param inputString String on which search will be performed.
 * @returns `true` if `inputString` starts with one of keys, else `false`.
 */
export var startsWithOneOf = function (searchKeys, inputString) {
    var keyIndex = searchKeys.findIndex(function (key) {
        return inputString.startsWith(key);
    });
    return keyIndex >= 0;
};
export var isButton = isReactUIComponent('Button');
export var isInput = isReactUIComponent('Input');
export var isFxInput = isReactUIComponent('FxInput');
export var isAutocomplete = isReactUIComponent('Autocomplete');
export var isPasswordInput = isReactUIComponent('PasswordInput');
export var isCurrencyInput = isReactUIComponent('CurrencyInput');
export var isSelect = isReactUIComponent('Select');
export var isDropdown = isReactUIComponent('Dropdown');
export var isDropdownMenu = isReactUIComponent('DropdownMenu');
export var isHint = isReactUIComponent('Hint');
export var isTooltip = isReactUIComponent('Tooltip');
export var isKonturIcon = function (icon) {
    return Object.prototype.hasOwnProperty.call(icon === null || icon === void 0 ? void 0 : icon.type, '__KONTUR_ICON__');
};
export function clickOutside(eventType) {
    if (eventType === void 0) { eventType = 'mousedown'; }
    var event = document.createEvent('HTMLEvents');
    event.initEvent(eventType, true, true);
    document.body.dispatchEvent(event);
}
export function isElement(el) {
    return !!el && typeof el === 'object' && 'nodeType' in el && el.nodeType === Node.ELEMENT_NODE;
}
//# sourceMappingURL=utils.js.map