handsontable
Version:
Handsontable is a JavaScript Data Grid available for React, Angular and Vue.
290 lines (281 loc) • 10.1 kB
JavaScript
"use strict";
exports.__esModule = true;
require("core-js/modules/es.error.cause.js");
var _base = require("../base");
var _content = require("./content");
var C = _interopRequireWildcard(require("../../i18n/constants"));
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
function _classPrivateMethodInitSpec(e, a) { _checkPrivateRedeclaration(e, a), a.add(e); }
function _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); }
function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
function _classPrivateFieldSet(s, a, r) { return s.set(_assertClassBrand(s, a), r), r; }
function _classPrivateFieldGet(s, a) { return s.get(_assertClassBrand(s, a)); }
function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); }
const PLUGIN_KEY = exports.PLUGIN_KEY = 'loading';
const PLUGIN_PRIORITY = exports.PLUGIN_PRIORITY = 350;
const LOADING_CLASS_NAME = exports.LOADING_CLASS_NAME = `ht-${PLUGIN_KEY}`;
/**
* @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>
* ```
* :::
*/
var _dialogPlugin = /*#__PURE__*/new WeakMap();
var _Loading_brand = /*#__PURE__*/new WeakSet();
class Loading extends _base.BasePlugin {
constructor() {
super(...arguments);
/**
* Handle dialog focus event.
*/
_classPrivateMethodInitSpec(this, _Loading_brand);
/**
* Dialog instance reference.
*
* @type {Dialog|null}
*/
_classPrivateFieldInitSpec(this, _dialogPlugin, null);
}
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 (_classPrivateFieldGet(_dialogPlugin, this) === null) {
var _classPrivateFieldGet2;
_classPrivateFieldSet(_dialogPlugin, this, this.hot.getPlugin('dialog'));
if (!((_classPrivateFieldGet2 = _classPrivateFieldGet(_dialogPlugin, this)) !== null && _classPrivateFieldGet2 !== void 0 && _classPrivateFieldGet2.isEnabled())) {
this.hot.getSettings().dialog = true;
}
this.hot.addHook('afterDialogFocus', () => _assertClassBrand(_Loading_brand, this, _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() {
var _classPrivateFieldGet3, _classPrivateFieldGet4;
return (_classPrivateFieldGet3 = (_classPrivateFieldGet4 = _classPrivateFieldGet(_dialogPlugin, this)) === null || _classPrivateFieldGet4 === void 0 ? void 0 : _classPrivateFieldGet4.isVisible()) !== null && _classPrivateFieldGet3 !== void 0 ? _classPrivateFieldGet3 : 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() {
var _classPrivateFieldGet5;
let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
if (!this.isEnabled() || !_classPrivateFieldGet(_dialogPlugin, this) || !((_classPrivateFieldGet5 = _classPrivateFieldGet(_dialogPlugin, this)) !== null && _classPrivateFieldGet5 !== void 0 && _classPrivateFieldGet5.isEnabled())) {
return;
}
if (this.isVisible()) {
this.update(options);
return;
}
const shouldProceed = this.hot.runHooks('beforeLoadingShow');
if (shouldProceed === false) {
return;
}
this.update(options);
_classPrivateFieldGet(_dialogPlugin, this).show();
this.hot.runHooks('afterLoadingShow');
}
/**
* Hide loading dialog.
*/
hide() {
var _classPrivateFieldGet6;
if (!_classPrivateFieldGet(_dialogPlugin, this) || !((_classPrivateFieldGet6 = _classPrivateFieldGet(_dialogPlugin, this)) !== null && _classPrivateFieldGet6 !== void 0 && _classPrivateFieldGet6.isEnabled()) || !this.isVisible()) {
return;
}
const shouldProceed = this.hot.runHooks('beforeLoadingHide');
if (shouldProceed === false) {
return;
}
_classPrivateFieldGet(_dialogPlugin, this).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) {
var _classPrivateFieldGet7, _this$getSetting;
if (!this.isEnabled() || !_classPrivateFieldGet(_dialogPlugin, this) || !((_classPrivateFieldGet7 = _classPrivateFieldGet(_dialogPlugin, this)) !== null && _classPrivateFieldGet7 !== void 0 && _classPrivateFieldGet7.isEnabled())) {
return;
}
this.updatePluginSettings(options);
const id = this.hot.guid;
const icon = this.getSetting('icon');
const title = (_this$getSetting = this.getSetting('title')) !== null && _this$getSetting !== void 0 ? _this$getSetting : this.hot.getTranslatedPhrase(C.LOADING_TITLE);
const description = this.getSetting('description');
const content = (0, _content.loadingContent)({
id,
icon,
title,
description
});
_classPrivateFieldGet(_dialogPlugin, this).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() {
_classPrivateFieldSet(_dialogPlugin, this, null);
super.destroy();
}
}
exports.Loading = Loading;
function _onAfterDialogFocus() {
_classPrivateFieldGet(_dialogPlugin, this).focus();
}