handsontable
Version:
Handsontable is a JavaScript Data Grid available for React, Angular and Vue.
281 lines (271 loc) • 11.9 kB
JavaScript
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 _classPrivateFieldGet(s, a) { return s.get(_assertClassBrand(s, a)); }
function _classPrivateFieldSet(s, a, r) { return s.set(_assertClassBrand(s, a), r), r; }
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"); }
import "core-js/modules/es.error.cause.js";
import "core-js/modules/esnext.iterator.constructor.js";
import "core-js/modules/esnext.iterator.for-each.js";
import "core-js/modules/esnext.iterator.map.js";
import { html } from "../../helpers/templateLiteralTag.mjs";
import { addClass, removeClass, getScrollbarWidth, setAttribute } from "../../helpers/dom/element.mjs";
import { A11Y_TABINDEX } from "../../helpers/a11y.mjs";
import { stripTags } from "../../helpers/string.mjs";
const EMPTY_DATA_STATE_CLASS_NAME = 'ht-empty-data-state';
const MIN_HEIGHT = 150;
const TEMPLATE = `<div data-ref="emptyDataStateElement" class="${EMPTY_DATA_STATE_CLASS_NAME} handsontable">
<div class="${EMPTY_DATA_STATE_CLASS_NAME}__content-wrapper">
<div data-ref="emptyDataStateInner" class="${EMPTY_DATA_STATE_CLASS_NAME}__content-wrapper-inner"></div>
</div>
</div>`;
const templateContent = _ref => {
let {
title,
description,
buttons
} = _ref;
return `
<div class="${EMPTY_DATA_STATE_CLASS_NAME}__content">
${title ? `<h2 class="${EMPTY_DATA_STATE_CLASS_NAME}__title">${stripTags(title)}</h2>` : ''}
${description ? `<p class="${EMPTY_DATA_STATE_CLASS_NAME}__description">${stripTags(description)}</p>` : ''}
</div>
<div
data-ref="emptyDataStateButtons"
class="${EMPTY_DATA_STATE_CLASS_NAME}__buttons${(buttons === null || buttons === void 0 ? void 0 : buttons.length) > 0 ? ` ${EMPTY_DATA_STATE_CLASS_NAME}__buttons--has-buttons` : ''}"
>${(buttons === null || buttons === void 0 ? void 0 : buttons.length) > 0 ? buttons.map(button => `<button class="ht-button ht-button--${button.type}">${stripTags(button.text)}</button>`).join('') : ''}</div>`;
};
/**
* EmptyDataStateUI is a UI component that renders and manages empty data state elements.
*
* @private
* @class EmptyDataStateUI
*/
var _rootElement = /*#__PURE__*/new WeakMap();
var _rootDocument = /*#__PURE__*/new WeakMap();
var _refs = /*#__PURE__*/new WeakMap();
var _placeholderElement = /*#__PURE__*/new WeakMap();
export class EmptyDataStateUI {
constructor(_ref2) {
let {
rootElement,
rootDocument
} = _ref2;
/**
* The root element where the emptyDataState UI will be installed.
*
* @type {HTMLElement}
*/
_classPrivateFieldInitSpec(this, _rootElement, void 0);
/**
* The root document where the emptyDataState UI will be installed.
*
* @type {Document}
*/
_classPrivateFieldInitSpec(this, _rootDocument, void 0);
/**
* The references to the UI elements.
*
* @type {object}
*/
_classPrivateFieldInitSpec(this, _refs, void 0);
/**
* The placeholder element.
*
* @type {HTMLElement}
*/
_classPrivateFieldInitSpec(this, _placeholderElement, void 0);
_classPrivateFieldSet(_rootElement, this, rootElement);
_classPrivateFieldSet(_rootDocument, this, rootDocument);
this.install();
}
/**
* Creates the emptyDataState UI elements and sets up the structure.
*/
install() {
var _classPrivateFieldGet2;
if ((_classPrivateFieldGet2 = _classPrivateFieldGet(_refs, this)) !== null && _classPrivateFieldGet2 !== void 0 && _classPrivateFieldGet2.emptyDataStateElement) {
return;
}
const elements = html`${TEMPLATE}`;
_classPrivateFieldSet(_refs, this, elements.refs);
const {
emptyDataStateInner,
emptyDataStateElement
} = _classPrivateFieldGet(_refs, this);
setAttribute(emptyDataStateInner, [A11Y_TABINDEX(-1)]);
setAttribute(emptyDataStateElement, [A11Y_TABINDEX(-1)]);
_classPrivateFieldGet(_rootElement, this).after(elements.fragment);
}
/**
* Gets the emptyDataState element.
*
* @returns {HTMLElement} The empty data state element.
*/
getElement() {
var _classPrivateFieldGet3;
return (_classPrivateFieldGet3 = _classPrivateFieldGet(_refs, this)) === null || _classPrivateFieldGet3 === void 0 ? void 0 : _classPrivateFieldGet3.emptyDataStateElement;
}
/**
* Gets the focusable elements of the emptyDataState element.
*
* @returns {HTMLElement[]} The focusable elements.
*/
getFocusableElements() {
const {
emptyDataStateButtons,
emptyDataStateInner
} = _classPrivateFieldGet(_refs, this);
const emptyDataStateButtonsElements = Array.from(emptyDataStateButtons === null || emptyDataStateButtons === void 0 ? void 0 : emptyDataStateButtons.children);
if (emptyDataStateButtonsElements.length === 0) {
return [emptyDataStateInner];
}
return emptyDataStateButtonsElements;
}
/**
* Shows the emptyDataState element.
*/
show() {
var _classPrivateFieldGet4;
if (!((_classPrivateFieldGet4 = _classPrivateFieldGet(_refs, this)) !== null && _classPrivateFieldGet4 !== void 0 && _classPrivateFieldGet4.emptyDataStateElement)) {
return;
}
_classPrivateFieldGet(_refs, this).emptyDataStateElement.style.display = 'block';
}
/**
* Hides the emptyDataState element.
*/
hide() {
var _classPrivateFieldGet5, _classPrivateFieldGet6;
if (!((_classPrivateFieldGet5 = _classPrivateFieldGet(_refs, this)) !== null && _classPrivateFieldGet5 !== void 0 && _classPrivateFieldGet5.emptyDataStateElement)) {
return;
}
(_classPrivateFieldGet6 = _classPrivateFieldGet(_placeholderElement, this)) === null || _classPrivateFieldGet6 === void 0 || _classPrivateFieldGet6.remove();
_classPrivateFieldSet(_placeholderElement, this, null);
_classPrivateFieldGet(_refs, this).emptyDataStateElement.style.display = 'none';
}
/**
* Updates the content of the emptyDataState element.
*
* @param {string | object} message - The message to update.
*/
updateContent(message) {
var _content$buttons;
const {
emptyDataStateInner
} = _classPrivateFieldGet(_refs, this);
let content = '';
if (typeof message === 'string') {
content = {
title: message
};
} else {
content = {
title: message === null || message === void 0 ? void 0 : message.title,
description: message === null || message === void 0 ? void 0 : message.description,
buttons: message === null || message === void 0 ? void 0 : message.buttons
};
}
const template = html`${templateContent(content)}`;
_classPrivateFieldSet(_refs, this, {
..._classPrivateFieldGet(_refs, this),
...template.refs
});
emptyDataStateInner.innerHTML = '';
emptyDataStateInner.appendChild(template.fragment);
if (((_content$buttons = content.buttons) === null || _content$buttons === void 0 ? void 0 : _content$buttons.length) > 0) {
Array.from(_classPrivateFieldGet(_refs, this).emptyDataStateButtons.children).forEach((button, index) => {
button.addEventListener('click', content.buttons[index].callback);
});
}
}
/**
* Updates the class names of the emptyDataState element.
*
* @param {View} view - The view instance.
*/
updateClassNames(view) {
const {
emptyDataStateElement
} = _classPrivateFieldGet(_refs, this);
if (view.countRenderableColumns() > 0 && view.getColumnHeadersCount() > 0) {
addClass(emptyDataStateElement, `${EMPTY_DATA_STATE_CLASS_NAME}--disable-top-border`);
} else {
removeClass(emptyDataStateElement, `${EMPTY_DATA_STATE_CLASS_NAME}--disable-top-border`);
}
if (view.countRenderableRows() > 0 && view.getRowHeadersCount() > 0) {
addClass(emptyDataStateElement, `${EMPTY_DATA_STATE_CLASS_NAME}--disable-inline-border`);
} else {
removeClass(emptyDataStateElement, `${EMPTY_DATA_STATE_CLASS_NAME}--disable-inline-border`);
}
if (view.hasHorizontalScroll() && !view.isHorizontallyScrollableByWindow()) {
addClass(emptyDataStateElement, `${EMPTY_DATA_STATE_CLASS_NAME}--disable-bottom-border`);
} else {
removeClass(emptyDataStateElement, `${EMPTY_DATA_STATE_CLASS_NAME}--disable-bottom-border`);
}
}
/**
* Updates the size of the emptyDataState element.
*
* @param {View} view - The view instance.
*/
updateSize(view) {
const {
emptyDataStateElement
} = _classPrivateFieldGet(_refs, this);
const scrollbarSize = view.hasHorizontalScroll() ? getScrollbarWidth(view.hot.rootDocument) : 0;
const rows = view.countRenderableRows();
const cols = view.countRenderableColumns();
const headerCols = view.getColumnHeadersCount();
emptyDataStateElement.style.top = cols > 0 ? `${view.getColumnHeaderHeight()}px` : '0px';
emptyDataStateElement.style.insetInlineStart = rows > 0 ? `${view.getRowHeaderWidth()}px` : '0px';
if (rows === 0) {
if (!_classPrivateFieldGet(_placeholderElement, this)) {
_classPrivateFieldSet(_placeholderElement, this, _classPrivateFieldGet(_rootDocument, this).createElement('div'));
_classPrivateFieldGet(_placeholderElement, this).classList.add(`${EMPTY_DATA_STATE_CLASS_NAME}-placeholder`);
view._wt.wtTable.holder.appendChild(_classPrivateFieldGet(_placeholderElement, this));
}
_classPrivateFieldGet(_placeholderElement, this).style.width = '100%';
_classPrivateFieldGet(_placeholderElement, this).style.height = `${MIN_HEIGHT}px`;
} else {
var _classPrivateFieldGet7;
(_classPrivateFieldGet7 = _classPrivateFieldGet(_placeholderElement, this)) === null || _classPrivateFieldGet7 === void 0 || _classPrivateFieldGet7.remove();
_classPrivateFieldSet(_placeholderElement, this, null);
}
let width = view.getWorkspaceWidth();
let height = view.getTableHeight();
if (view.isHorizontallyScrollableByWindow()) {
if (cols > 0) {
width = view.getTotalTableWidth();
} else if (rows > 0) {
width = view.getViewportWidth();
}
} else if (rows > 0) {
width = view.getViewportWidth();
} else if (view.getTableWidth() - view.getRowHeaderWidth() < view.getViewportWidth() && cols > 0) {
width = view.getTableWidth();
}
if (view.isVerticallyScrollableByWindow() || view.hasVerticalScroll()) {
if (cols > 0) {
height = view.hot.getTableHeight() - view.getColumnHeaderHeight();
} else {
height = view.hot.getTableHeight();
}
} else if (headerCols > 0 && cols > 0) {
height = view.getViewportHeight() - scrollbarSize;
} else if (headerCols > 0 && cols === 0) {
height = view.getWorkspaceHeight() - scrollbarSize;
}
emptyDataStateElement.style.width = `${width}px`;
emptyDataStateElement.style.height = `${height}px`;
}
/**
* Removes the emptyDataState UI elements from the DOM and clears the refs.
*/
destroy() {
var _classPrivateFieldGet8, _classPrivateFieldGet9;
(_classPrivateFieldGet8 = _classPrivateFieldGet(_refs, this)) === null || _classPrivateFieldGet8 === void 0 || (_classPrivateFieldGet8 = _classPrivateFieldGet8.emptyDataStateElement) === null || _classPrivateFieldGet8 === void 0 || _classPrivateFieldGet8.remove();
(_classPrivateFieldGet9 = _classPrivateFieldGet(_placeholderElement, this)) === null || _classPrivateFieldGet9 === void 0 || _classPrivateFieldGet9.remove();
_classPrivateFieldSet(_placeholderElement, this, null);
_classPrivateFieldSet(_refs, this, null);
}
}