function _check_private_redeclaration(obj, privateCollection) {
    if (privateCollection.has(obj)) {
        throw new TypeError("Cannot initialize the same private elements twice on an object");
    }
}
function _class_apply_descriptor_get(receiver, descriptor) {
    if (descriptor.get) {
        return descriptor.get.call(receiver);
    }
    return descriptor.value;
}
function _class_apply_descriptor_set(receiver, descriptor, value) {
    if (descriptor.set) {
        descriptor.set.call(receiver, value);
    } else {
        if (!descriptor.writable) {
            throw new TypeError("attempted to set read only private field");
        }
        descriptor.value = value;
    }
}
function _class_extract_field_descriptor(receiver, privateMap, action) {
    if (!privateMap.has(receiver)) {
        throw new TypeError("attempted to " + action + " private field on non-instance");
    }
    return privateMap.get(receiver);
}
function _class_private_field_get(receiver, privateMap) {
    var descriptor = _class_extract_field_descriptor(receiver, privateMap, "get");
    return _class_apply_descriptor_get(receiver, descriptor);
}
function _class_private_field_init(obj, privateMap, value) {
    _check_private_redeclaration(obj, privateMap);
    privateMap.set(obj, value);
}
function _class_private_field_set(receiver, privateMap, value) {
    var descriptor = _class_extract_field_descriptor(receiver, privateMap, "set");
    _class_apply_descriptor_set(receiver, descriptor, value);
    return value;
}
function _class_private_method_get(receiver, privateSet, fn) {
    if (!privateSet.has(receiver)) {
        throw new TypeError("attempted to get private field on non-instance");
    }
    return fn;
}
function _class_private_method_init(obj, privateSet) {
    _check_private_redeclaration(obj, privateSet);
    privateSet.add(obj);
}
import { BasePlugin } from '../base/index.mjs';
import { loadingContent } from './content.mjs';
import * as C from '../../i18n/constants.mjs';
import { LOADING_CLASS_NAME } from '../../helpers/constants.mjs';
export const PLUGIN_KEY = 'loading';
export const PLUGIN_PRIORITY = 350;
export { LOADING_CLASS_NAME };
var /**
   * Dialog instance reference.
   *
   * @type {Dialog|null}
   */ _dialogPlugin = /*#__PURE__*/ new WeakMap(), /**
   * Handle dialog focus event.
   */ _onAfterDialogFocus = /*#__PURE__*/ new WeakSet();
/**
 * @plugin Loading
 * @class Loading
 *
 * @description
 * The loading plugin provides a loading overlay system for Handsontable using the Dialog plugin.
 * It displays a loading indicator with customizable title, icon, and description.
 *
 * In order to enable the loading mechanism, {@link Options#loading} option must be set to `true`.
 *
 * The plugin provides several configuration options to customize the loading behavior and appearance:
 * - `icon`: Loading icon to display HTML (as string) in svg format (default: `<svg ... />`).
 * - `title`: Loading title to display (default: 'Loading...').
 * - `description`: Loading description to display (default: '').
 *
 * @example
 *
 * ::: only-for javascript
 * ```js
 * // Enable loading plugin with default options
 * loading: true,
 *
 * // Enable loading plugin with custom configuration
 * loading: {
 *   icon: 'A custom loading icon in SVG format',
 *   title: 'Custom loading title',
 *   description: 'Custom loading description',
 * }
 *
 * // Access to loading plugin instance:
 * const loadingPlugin = hot.getPlugin('loading');
 *
 * // Show a loading programmatically:
 * loadingPlugin.show();
 *
 * // Hide the loading programmatically:
 * loadingPlugin.hide();
 *
 * // Check if dialog is visible:
 * const isVisible = loadingPlugin.isVisible();
 * ```
 * :::
 *
 * ::: only-for react
 * ```jsx
 * const MyComponent = () => {
 *   const hotRef = useRef(null);
 *
 *   useEffect(() => {
 *     const hot = hotRef.current.hotInstance;
 *     const loadingPlugin = hot.getPlugin('loading');
 *
 *     loadingPlugin.show();
 *   }, []);
 *
 *   return (
 *     <HotTable
 *       ref={hotRef}
 *       settings={{
 *         data: data,
 *         loading: {
 *           icon: 'A custom loading icon in SVG format',
 *           title: 'Custom loading title',
 *           description: 'Custom loading description',
 *         }
 *       }}
 *     />
 *   );
 * }
 * ```
 * :::
 *
 * ::: only-for angular
 * ```ts
 * hotSettings: Handsontable.GridSettings = {
 *   data: data,
 *   loading: {
 *     icon: 'A custom loading icon in SVG format',
 *     title: 'Custom loading title',
 *     description: 'Custom loading description',
 *   }
 * }
 * ```
 *
 * ```html
 * <hot-table
 *   [settings]="hotSettings">
 * </hot-table>
 * ```
 * :::
 */ export class Loading extends BasePlugin {
    static get PLUGIN_KEY() {
        return PLUGIN_KEY;
    }
    static get PLUGIN_PRIORITY() {
        return PLUGIN_PRIORITY;
    }
    static get DEFAULT_SETTINGS() {
        return {
            // eslint-disable-next-line max-len
            icon: `<svg class="${LOADING_CLASS_NAME}__icon-svg" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 16 16"><path stroke="currentColor" stroke-width="2" d="M15 8a7 7 0 1 1-3.5-6.062"></path></svg>`,
            title: undefined,
            description: ''
        };
    }
    static get SETTINGS_VALIDATORS() {
        return {
            icon: (value)=>typeof value === 'string',
            title: (value)=>typeof value === 'string',
            description: (value)=>typeof value === 'string'
        };
    }
    /**
   * Check if the plugin is enabled in the handsontable settings.
   *
   * @returns {boolean}
   */ isEnabled() {
        return !!this.hot.getSettings()[PLUGIN_KEY];
    }
    /**
   * Enable plugin for this Handsontable instance.
   */ enablePlugin() {
        if (this.enabled) {
            return;
        }
        if (_class_private_field_get(this, _dialogPlugin) === null) {
            _class_private_field_set(this, _dialogPlugin, this.hot.getPlugin('dialog'));
            if (!_class_private_field_get(this, _dialogPlugin)?.isEnabled()) {
                this.hot.getSettings().dialog = true;
            }
            this.hot.addHook('afterDialogFocus', ()=>_class_private_method_get(this, _onAfterDialogFocus, onAfterDialogFocus).call(this));
        }
        super.enablePlugin();
    }
    /**
   * Update plugin state after Handsontable settings update.
   */ updatePlugin() {
        this.disablePlugin();
        this.enablePlugin();
        super.updatePlugin();
    }
    /**
   * Disable plugin for this Handsontable instance.
   */ disablePlugin() {
        this.hide();
        super.disablePlugin();
    }
    /**
   * Check if loading dialog is currently visible.
   *
   * @returns {boolean}
   */ isVisible() {
        return _class_private_field_get(this, _dialogPlugin)?.isVisible() ?? false;
    }
    /**
   * Show loading dialog with optional custom options.
   *
   * @param {object} options Custom loading options.
   * @param {string} options.icon Custom loading icon.
   * @param {string} options.title Custom loading title.
   * @param {string} options.description Custom loading description.
   */ show(options = {}) {
        if (!this.isEnabled() || !_class_private_field_get(this, _dialogPlugin) || !_class_private_field_get(this, _dialogPlugin)?.isEnabled()) {
            return;
        }
        if (this.isVisible()) {
            this.update(options);
            return;
        }
        const shouldProceed = this.hot.runHooks('beforeLoadingShow');
        if (shouldProceed === false) {
            return;
        }
        this.update(options);
        _class_private_field_get(this, _dialogPlugin).show();
        this.hot.runHooks('afterLoadingShow');
    }
    /**
   * Hide loading dialog.
   */ hide() {
        if (!_class_private_field_get(this, _dialogPlugin) || !_class_private_field_get(this, _dialogPlugin)?.isEnabled() || !this.isVisible()) {
            return;
        }
        const shouldProceed = this.hot.runHooks('beforeLoadingHide');
        if (shouldProceed === false) {
            return;
        }
        _class_private_field_get(this, _dialogPlugin).hide();
        this.hot.runHooks('afterLoadingHide');
    }
    /**
   * Update loading description without hiding/showing the dialog.
   *
   * @param {object} options Custom loading options.
   * @param {string} options.icon Custom loading icon.
   * @param {string} options.title Custom loading title.
   * @param {string} options.description Custom loading description.
   */ update(options) {
        if (!this.isEnabled() || !_class_private_field_get(this, _dialogPlugin) || !_class_private_field_get(this, _dialogPlugin)?.isEnabled()) {
            return;
        }
        this.updatePluginSettings(options);
        const id = this.hot.guid;
        const icon = this.getSetting('icon');
        const title = this.getSetting('title') ?? this.hot.getTranslatedPhrase(C.LOADING_TITLE);
        const description = this.getSetting('description');
        const content = loadingContent({
            id,
            icon,
            title,
            description
        });
        _class_private_field_get(this, _dialogPlugin).update({
            content,
            customClassName: LOADING_CLASS_NAME,
            background: this.hot.countSourceRows() === 0 ? 'solid' : 'semi-transparent',
            a11y: {
                role: 'alertdialog',
                ariaLabelledby: `${id}-${PLUGIN_KEY}-title`,
                ariaDescribedby: description ? `${id}-${PLUGIN_KEY}-description` : undefined
            }
        });
    }
    /**
   * Destroy plugin instance.
   */ destroy() {
        _class_private_field_set(this, _dialogPlugin, null);
        super.destroy();
    }
    constructor(...args){
        super(...args), _class_private_method_init(this, _onAfterDialogFocus), _class_private_field_init(this, _dialogPlugin, {
            writable: true,
            value: void 0
        }), _class_private_field_set(this, _dialogPlugin, null);
    }
}
function onAfterDialogFocus() {
    _class_private_field_get(this, _dialogPlugin).focus();
}
