UNPKG

@public-ui/components

Version:

Contains all web components that belong to KoliBri - The accessible HTML-Standard.

1,214 lines (1,159 loc) 60.4 kB
/*! * KoliBri - The accessible HTML-Standard */ import { proxyCustomElement, HTMLElement, h, Fragment } from '@stencil/core/internal/client'; import { a as __rest } from './tslib.es6.js'; import { b as KolButtonWcTag, c as KolLinkWcTag, o as KolTableSettingsWcTag } from './component-names.js'; import { t as translate } from './i18n.js'; import { I as IconFC } from './component3.js'; import { T as TooltipFC } from './component.js'; import './common.js'; import { N as emptyStringByArrayHandler, o as objectObjectHandler, p as parseJson, a as watchValidator, L as Log, s as setState } from './prop.validators.js'; import { c as validateHasSettingsMenu, v as validateTableData, a as validateTableDataFoot, b as validateFixedCols, f as validateTableCallbacks, d as validateTableSelection } from './table-selection.js'; import { v as validateLabel } from './label.js'; import { v as validateVariantClassName } from './variant-class-name.js'; import { C as Callback } from './keyboard.js'; import { c as clsx } from './clsx.js'; import { n as nonce } from './dev.utils.js'; import { d as dispatchDomEvent, K as KolEvent } from './events.js'; import { M as MapCache, e as eq, U as Uint8Array, f as getAllKeys, b as getTag, d as isBuffer, S as Stack, h as isTypedArray } from './_Uint8Array.js'; import { S as Symbol, a as isArray, i as isObjectLike } from './isArray.js'; /** Used to stand-in for `undefined` hash values. */ var HASH_UNDEFINED = '__lodash_hash_undefined__'; /** * Adds `value` to the array cache. * * @private * @name add * @memberOf SetCache * @alias push * @param {*} value The value to cache. * @returns {Object} Returns the cache instance. */ function setCacheAdd(value) { this.__data__.set(value, HASH_UNDEFINED); return this; } /** * Checks if `value` is in the array cache. * * @private * @name has * @memberOf SetCache * @param {*} value The value to search for. * @returns {boolean} Returns `true` if `value` is found, else `false`. */ function setCacheHas(value) { return this.__data__.has(value); } /** * * Creates an array cache object to store unique values. * * @private * @constructor * @param {Array} [values] The values to cache. */ function SetCache(values) { var index = -1, length = values == null ? 0 : values.length; this.__data__ = new MapCache; while (++index < length) { this.add(values[index]); } } // Add methods to `SetCache`. SetCache.prototype.add = SetCache.prototype.push = setCacheAdd; SetCache.prototype.has = setCacheHas; /** * A specialized version of `_.some` for arrays without support for iteratee * shorthands. * * @private * @param {Array} [array] The array to iterate over. * @param {Function} predicate The function invoked per iteration. * @returns {boolean} Returns `true` if any element passes the predicate check, * else `false`. */ function arraySome(array, predicate) { var index = -1, length = array == null ? 0 : array.length; while (++index < length) { if (predicate(array[index], index, array)) { return true; } } return false; } /** * Checks if a `cache` value for `key` exists. * * @private * @param {Object} cache The cache to query. * @param {string} key The key of the entry to check. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. */ function cacheHas(cache, key) { return cache.has(key); } /** Used to compose bitmasks for value comparisons. */ var COMPARE_PARTIAL_FLAG$3 = 1, COMPARE_UNORDERED_FLAG$1 = 2; /** * A specialized version of `baseIsEqualDeep` for arrays with support for * partial deep comparisons. * * @private * @param {Array} array The array to compare. * @param {Array} other The other array to compare. * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. * @param {Function} customizer The function to customize comparisons. * @param {Function} equalFunc The function to determine equivalents of values. * @param {Object} stack Tracks traversed `array` and `other` objects. * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. */ function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { var isPartial = bitmask & COMPARE_PARTIAL_FLAG$3, arrLength = array.length, othLength = other.length; if (arrLength != othLength && !(isPartial && othLength > arrLength)) { return false; } // Check that cyclic values are equal. var arrStacked = stack.get(array); var othStacked = stack.get(other); if (arrStacked && othStacked) { return arrStacked == other && othStacked == array; } var index = -1, result = true, seen = (bitmask & COMPARE_UNORDERED_FLAG$1) ? new SetCache : undefined; stack.set(array, other); stack.set(other, array); // Ignore non-index properties. while (++index < arrLength) { var arrValue = array[index], othValue = other[index]; if (customizer) { var compared = isPartial ? customizer(othValue, arrValue, index, other, array, stack) : customizer(arrValue, othValue, index, array, other, stack); } if (compared !== undefined) { if (compared) { continue; } result = false; break; } // Recursively compare arrays (susceptible to call stack limits). if (seen) { if (!arraySome(other, function(othValue, othIndex) { if (!cacheHas(seen, othIndex) && (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { return seen.push(othIndex); } })) { result = false; break; } } else if (!( arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack) )) { result = false; break; } } stack['delete'](array); stack['delete'](other); return result; } /** * Converts `map` to its key-value pairs. * * @private * @param {Object} map The map to convert. * @returns {Array} Returns the key-value pairs. */ function mapToArray(map) { var index = -1, result = Array(map.size); map.forEach(function(value, key) { result[++index] = [key, value]; }); return result; } /** * Converts `set` to an array of its values. * * @private * @param {Object} set The set to convert. * @returns {Array} Returns the values. */ function setToArray(set) { var index = -1, result = Array(set.size); set.forEach(function(value) { result[++index] = value; }); return result; } /** Used to compose bitmasks for value comparisons. */ var COMPARE_PARTIAL_FLAG$2 = 1, COMPARE_UNORDERED_FLAG = 2; /** `Object#toString` result references. */ var boolTag = '[object Boolean]', dateTag = '[object Date]', errorTag = '[object Error]', mapTag = '[object Map]', numberTag = '[object Number]', regexpTag = '[object RegExp]', setTag = '[object Set]', stringTag = '[object String]', symbolTag = '[object Symbol]'; var arrayBufferTag = '[object ArrayBuffer]', dataViewTag = '[object DataView]'; /** Used to convert symbols to primitives and strings. */ var symbolProto = Symbol ? Symbol.prototype : undefined, symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; /** * A specialized version of `baseIsEqualDeep` for comparing objects of * the same `toStringTag`. * * **Note:** This function only supports comparing values with tags of * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. * * @private * @param {Object} object The object to compare. * @param {Object} other The other object to compare. * @param {string} tag The `toStringTag` of the objects to compare. * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. * @param {Function} customizer The function to customize comparisons. * @param {Function} equalFunc The function to determine equivalents of values. * @param {Object} stack Tracks traversed `object` and `other` objects. * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. */ function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { switch (tag) { case dataViewTag: if ((object.byteLength != other.byteLength) || (object.byteOffset != other.byteOffset)) { return false; } object = object.buffer; other = other.buffer; case arrayBufferTag: if ((object.byteLength != other.byteLength) || !equalFunc(new Uint8Array(object), new Uint8Array(other))) { return false; } return true; case boolTag: case dateTag: case numberTag: // Coerce booleans to `1` or `0` and dates to milliseconds. // Invalid dates are coerced to `NaN`. return eq(+object, +other); case errorTag: return object.name == other.name && object.message == other.message; case regexpTag: case stringTag: // Coerce regexes to strings and treat strings, primitives and objects, // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring // for more details. return object == (other + ''); case mapTag: var convert = mapToArray; case setTag: var isPartial = bitmask & COMPARE_PARTIAL_FLAG$2; convert || (convert = setToArray); if (object.size != other.size && !isPartial) { return false; } // Assume cyclic values are equal. var stacked = stack.get(object); if (stacked) { return stacked == other; } bitmask |= COMPARE_UNORDERED_FLAG; // Recursively compare objects (susceptible to call stack limits). stack.set(object, other); var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); stack['delete'](object); return result; case symbolTag: if (symbolValueOf) { return symbolValueOf.call(object) == symbolValueOf.call(other); } } return false; } /** Used to compose bitmasks for value comparisons. */ var COMPARE_PARTIAL_FLAG$1 = 1; /** Used for built-in method references. */ var objectProto$1 = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty$1 = objectProto$1.hasOwnProperty; /** * A specialized version of `baseIsEqualDeep` for objects with support for * partial deep comparisons. * * @private * @param {Object} object The object to compare. * @param {Object} other The other object to compare. * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. * @param {Function} customizer The function to customize comparisons. * @param {Function} equalFunc The function to determine equivalents of values. * @param {Object} stack Tracks traversed `object` and `other` objects. * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. */ function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { var isPartial = bitmask & COMPARE_PARTIAL_FLAG$1, objProps = getAllKeys(object), objLength = objProps.length, othProps = getAllKeys(other), othLength = othProps.length; if (objLength != othLength && !isPartial) { return false; } var index = objLength; while (index--) { var key = objProps[index]; if (!(isPartial ? key in other : hasOwnProperty$1.call(other, key))) { return false; } } // Check that cyclic values are equal. var objStacked = stack.get(object); var othStacked = stack.get(other); if (objStacked && othStacked) { return objStacked == other && othStacked == object; } var result = true; stack.set(object, other); stack.set(other, object); var skipCtor = isPartial; while (++index < objLength) { key = objProps[index]; var objValue = object[key], othValue = other[key]; if (customizer) { var compared = isPartial ? customizer(othValue, objValue, key, other, object, stack) : customizer(objValue, othValue, key, object, other, stack); } // Recursively compare objects (susceptible to call stack limits). if (!(compared === undefined ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack)) : compared )) { result = false; break; } skipCtor || (skipCtor = key == 'constructor'); } if (result && !skipCtor) { var objCtor = object.constructor, othCtor = other.constructor; // Non `Object` object instances with different constructors are not equal. if (objCtor != othCtor && ('constructor' in object && 'constructor' in other) && !(typeof objCtor == 'function' && objCtor instanceof objCtor && typeof othCtor == 'function' && othCtor instanceof othCtor)) { result = false; } } stack['delete'](object); stack['delete'](other); return result; } /** Used to compose bitmasks for value comparisons. */ var COMPARE_PARTIAL_FLAG = 1; /** `Object#toString` result references. */ var argsTag = '[object Arguments]', arrayTag = '[object Array]', objectTag = '[object Object]'; /** Used for built-in method references. */ var objectProto = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty = objectProto.hasOwnProperty; /** * A specialized version of `baseIsEqual` for arrays and objects which performs * deep comparisons and tracks traversed objects enabling objects with circular * references to be compared. * * @private * @param {Object} object The object to compare. * @param {Object} other The other object to compare. * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. * @param {Function} customizer The function to customize comparisons. * @param {Function} equalFunc The function to determine equivalents of values. * @param {Object} [stack] Tracks traversed `object` and `other` objects. * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. */ function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { var objIsArr = isArray(object), othIsArr = isArray(other), objTag = objIsArr ? arrayTag : getTag(object), othTag = othIsArr ? arrayTag : getTag(other); objTag = objTag == argsTag ? objectTag : objTag; othTag = othTag == argsTag ? objectTag : othTag; var objIsObj = objTag == objectTag, othIsObj = othTag == objectTag, isSameTag = objTag == othTag; if (isSameTag && isBuffer(object)) { if (!isBuffer(other)) { return false; } objIsArr = true; objIsObj = false; } if (isSameTag && !objIsObj) { stack || (stack = new Stack); return (objIsArr || isTypedArray(object)) ? equalArrays(object, other, bitmask, customizer, equalFunc, stack) : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); } if (!(bitmask & COMPARE_PARTIAL_FLAG)) { var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); if (objIsWrapped || othIsWrapped) { var objUnwrapped = objIsWrapped ? object.value() : object, othUnwrapped = othIsWrapped ? other.value() : other; stack || (stack = new Stack); return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); } } if (!isSameTag) { return false; } stack || (stack = new Stack); return equalObjects(object, other, bitmask, customizer, equalFunc, stack); } /** * The base implementation of `_.isEqual` which supports partial comparisons * and tracks traversed objects. * * @private * @param {*} value The value to compare. * @param {*} other The other value to compare. * @param {boolean} bitmask The bitmask flags. * 1 - Unordered comparison * 2 - Partial comparison * @param {Function} [customizer] The function to customize comparisons. * @param {Object} [stack] Tracks traversed `value` and `other` objects. * @returns {boolean} Returns `true` if the values are equivalent, else `false`. */ function baseIsEqual(value, other, bitmask, customizer, stack) { if (value === other) { return true; } if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) { return value !== value && other !== other; } return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); } /** * Performs a deep comparison between two values to determine if they are * equivalent. * * **Note:** This method supports comparing arrays, array buffers, booleans, * date objects, error objects, maps, numbers, `Object` objects, regexes, * sets, strings, symbols, and typed arrays. `Object` objects are compared * by their own, not inherited, enumerable properties. Functions and DOM * nodes are compared by strict equality, i.e. `===`. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to compare. * @param {*} other The other value to compare. * @returns {boolean} Returns `true` if the values are equivalent, else `false`. * @example * * var object = { 'a': 1 }; * var other = { 'a': 1 }; * * _.isEqual(object, other); * // => true * * object === other; * // => false */ function isEqual(value, other) { return baseIsEqual(value, other); } const isHeaderRows = (rows) => { return Array.isArray(rows) && rows.every((headerRow) => Array.isArray(headerRow)); }; const validateTableHeaderCells = (component, value) => { emptyStringByArrayHandler(value, () => { objectObjectHandler(value, () => { try { value = parseJson(value); } catch (e) { } watchValidator(component, '_headerCells', (value) => { if (typeof value !== 'object' || value === null) return false; const horizontal = value.horizontal; const vertical = value.vertical; if ((horizontal !== undefined && !isHeaderRows(horizontal)) || (vertical !== undefined && !isHeaderRows(vertical))) { return false; } const allHeaderCells = []; for (const row of horizontal !== null && horizontal !== void 0 ? horizontal : []) { allHeaderCells.push(...row); } for (const col of vertical !== null && vertical !== void 0 ? vertical : []) { allHeaderCells.push(...col); } return allHeaderCells.every((cell) => cell.width === undefined || typeof cell.width === 'number'); }, new Set(['TableHeaderCellsPropType']), value); }); }); }; const RESIZE_DEBOUNCE_DELAY = 150; const KolTableStatelessWc$1 = proxyCustomElement(class KolTableStatelessWc extends HTMLElement { constructor(registerHost) { super(); if (registerHost !== false) { this.__registerHost(); } this.translateNoEntries = translate('kol-no-entries'); this.state = { _data: [], _headerCells: { horizontal: [], vertical: [], }, _label: '', _hasSettingsMenu: false, }; this.horizontal = true; this.cellsToRenderTimeouts = new Map(); this.dataToKeyMap = new Map(); this.checkboxRefs = []; this.translateSort = translate('kol-sort'); this.translateSortOrder = translate('kol-table-sort-order'); this.maxCols = 0; this.fixedOffsets = []; this.settingsChangedCounter = 0; this.tableDivElementHasScrollbar = false; this.stickyColsDisabled = false; this.renderTableRow = (row, rowIndex, isVertical, isFooter = false) => { var _a, _b; let key = String(rowIndex); if (this.horizontal && ((_a = row[0]) === null || _a === void 0 ? void 0 : _a.data)) { key = (_b = this.getDataKey(row[0].data)) !== null && _b !== void 0 ? _b : key; } return (h("tr", { class: clsx('kol-table__row', { 'kol-table__row--body': !isFooter, 'kol-table__row--footer': isFooter, }), key: `row-${key}` }, this.renderSelectionCell(row, rowIndex), row.map((cell, colIndex) => this.renderTableCell(cell, rowIndex, colIndex, isVertical)))); }; this.renderTableCell = (cell, rowIndex, colIndex, isVertical) => { if (cell.visible === false) { return ''; } let key = `${rowIndex}-${colIndex}-${cell.label}`; if (cell.data) { const dataKey = this.getDataKey(cell.data); key = dataKey ? `${dataKey}-${this.horizontal ? colIndex : rowIndex}` : key; } if (cell.headerCell) { return this.renderHeadingCell(cell, rowIndex, colIndex, isVertical); } else { const isNoEntriesHintCell = typeof cell.render !== 'function' && cell.label === this.translateNoEntries; const actionColumn = this.getActionColumnHeader(colIndex); const isActionColumn = Boolean(actionColumn && cell.data); const fixed = this.isFixedCol(colIndex); const offsetLeft = fixed === 'left' ? this.getOffsetString(cell.colIndex, true) : undefined; const offsetRight = fixed === 'right' ? this.getOffsetString(cell.colIndex) : undefined; const hasCustomRender = typeof cell.render === 'function'; return (h("td", { key: `cell-${key}-${this.settingsChangedCounter}`, class: clsx('kol-table__cell kol-table__cell--body', cell.textAlign && `kol-table__cell--align-${cell.textAlign}`, isActionColumn && 'kol-table__cell--actions', fixed && `kol-table__cell--sticky-${fixed}`), "aria-atomic": isNoEntriesHintCell ? 'false' : undefined, "aria-live": isNoEntriesHintCell ? 'polite' : undefined, "aria-relevant": isNoEntriesHintCell ? 'text' : undefined, colSpan: cell.colSpan, rowSpan: cell.rowSpan, style: { textAlign: cell.textAlign, left: offsetLeft, right: offsetRight, }, ref: hasCustomRender ? (el) => { this.cellRender(cell, el); } : undefined }, isActionColumn && actionColumn && cell.data ? this.renderActionItems(actionColumn, cell.data, key) : !hasCustomRender ? cell.label : '')); } }; this.renderActionItems = (actionColumn, rowData, key) => { const actions = actionColumn.actions(rowData); return (h("div", { class: "kol-table__cell-actions" }, actions.map((action, actionIndex) => { if (action.type === 'button') { const buttonProps = __rest(action, []); return h(KolButtonWcTag, Object.assign({ key: `action-${key}-${actionIndex}` }, buttonProps, { _variant: buttonProps._variant })); } else if (action.type === 'link') { const linkProps = __rest(action, []); return h(KolLinkWcTag, Object.assign({ key: `action-${key}-${actionIndex}` }, linkProps)); } return null; }))); }; } onExternalLabelElementsChange(value) { this.syncTableLabel(value); } validateAriaLabelledby() { } syncTableLabel(elements) { if (!this.tableRef) return; if ('ariaLabelledByElements' in this.tableRef) { if (elements === null || elements === void 0 ? void 0 : elements.length) { this.tableRef.ariaLabelledByElements = elements; } Log.debug([this.tableRef, !!(elements === null || elements === void 0 ? void 0 : elements.length), elements, this.tableRef.ariaLabelledByElements]); } } validateHasSettingsMenu(value) { validateHasSettingsMenu(this, value); } validateData(value) { validateTableData(this, value, { beforePatch: (nextValue) => { this.updateDataToKeyMap(nextValue); }, }); } validateDataFoot(value) { validateTableDataFoot(this, value); } validateFixedCols(value) { validateFixedCols(this, value); this.checkAndUpdateStickyState(); } validateHeaderCells(value) { validateTableHeaderCells(this, value); if (!isEqual(this.previousHeaderCells, this.state._headerCells)) { this.initializeHeaderCellSettings(); } this.previousHeaderCells = this.state._headerCells; } validateLabel(value) { validateLabel(this, value, { required: true, }); } validateOn(value) { validateTableCallbacks(this, value); } validateSelection(value) { validateTableSelection(this, value); this.checkAndUpdateStickyState(); } validateVariantClassName(value) { validateVariantClassName(this, value); } handleKeyDown(event) { var _a; if (event.key === 'ArrowUp' || event.key === 'ArrowDown') { const focusedElement = (_a = this.tableDivElement) === null || _a === void 0 ? void 0 : _a.querySelector(':focus'); let index = this.checkboxRefs.indexOf(focusedElement); if (index > -1) { event.preventDefault(); if (event.key === 'ArrowDown') { index = (index + 1) % this.checkboxRefs.length; this.checkboxRefs[index].focus(); } else if (event.key === 'ArrowUp') { event.preventDefault(); index = (index + this.checkboxRefs.length - 1) % this.checkboxRefs.length; this.checkboxRefs[index].focus(); } } } } componentDidRender() { this.checkDivElementScrollbar(); } componentDidLoad() { if (this.tableDivElement && ResizeObserver) { this.tableDivElementResizeObserver = new ResizeObserver(this.handleResize.bind(this)); this.tableDivElementResizeObserver.observe(this.tableDivElement); } this.checkAndUpdateStickyState(); } handleSettingsChange(event) { var _a; const updatedHeaderCells = Object.assign(Object.assign({}, this.state._headerCells), { horizontal: event.detail }); setState(this, '_headerCells', updatedHeaderCells); this.settingsChangedCounter++; if (typeof ((_a = this.state._on) === null || _a === void 0 ? void 0 : _a[Callback.onChangeHeaderCells]) === 'function') { this.state._on[Callback.onChangeHeaderCells](event, updatedHeaderCells); } } disconnectedCallback() { var _a; (_a = this.tableDivElementResizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect(); clearTimeout(this.resizeDebounceTimeout); } handleResize() { this.checkDivElementScrollbar(); clearTimeout(this.resizeDebounceTimeout); this.resizeDebounceTimeout = setTimeout(() => { this.checkAndUpdateStickyState(); }, RESIZE_DEBOUNCE_DELAY); } checkDivElementScrollbar() { if (this.tableDivElement) { this.tableDivElementHasScrollbar = this.tableDivElement.scrollWidth > this.tableDivElement.clientWidth; } } calculateFixedColsWidth() { var _a, _b, _c, _d, _e, _f; if (!this._fixedCols) return 0; const primaryHeader = this.getPrimaryHeaders(this.state._headerCells); let totalWidth = 0; for (let i = 0; i < this._fixedCols[0] && i < primaryHeader.length; i++) { totalWidth += (_b = (_a = primaryHeader[i]) === null || _a === void 0 ? void 0 : _a.width) !== null && _b !== void 0 ? _b : 0; } const startRight = this.maxCols - this._fixedCols[1]; for (let i = startRight; i < this.maxCols && i < primaryHeader.length; i++) { totalWidth += (_d = (_c = primaryHeader[i]) === null || _c === void 0 ? void 0 : _c.width) !== null && _d !== void 0 ? _d : 0; } if (this.state._selection) { const selectionCell = (_e = this.tableDivElement) === null || _e === void 0 ? void 0 : _e.querySelector('.kol-table__cell--selection'); totalWidth += (_f = selectionCell === null || selectionCell === void 0 ? void 0 : selectionCell.offsetWidth) !== null && _f !== void 0 ? _f : 0; } return totalWidth; } checkAndUpdateStickyState() { if (!this.tableDivElement || !this._fixedCols) { this.stickyColsDisabled = false; return; } const containerWidth = this.tableDivElement.clientWidth; const fixedColsWidth = this.calculateFixedColsWidth(); this.stickyColsDisabled = fixedColsWidth > 0 && fixedColsWidth >= containerWidth; } updateDataToKeyMap(data) { data.forEach((data) => { if (!this.dataToKeyMap.has(data)) { this.dataToKeyMap.set(data, nonce()); } }); this.dataToKeyMap.forEach((_, key) => { if (!data.includes(key)) { this.dataToKeyMap.delete(key); } }); } getDataKey(data) { return this.dataToKeyMap.get(data); } getActionColumnHeader(colIndex) { const headers = this.horizontal ? this.state._headerCells.horizontal : this.state._headerCells.vertical; if (!headers || headers.length === 0) return undefined; const primaryHeader = this.getPrimaryHeaders(this.state._headerCells); const header = primaryHeader[colIndex]; if (header && header.type === 'action') { return header; } return undefined; } cellRender(cell, el) { if (el) { clearTimeout(this.cellsToRenderTimeouts.get(el)); this.cellsToRenderTimeouts.set(el, setTimeout(() => { if (typeof cell.render === 'function') { const renderContent = cell.render(el, cell, cell.data, this.state._data); if (typeof renderContent === 'string') { el.textContent = renderContent; } } })); } } getNumberOfCols(horizontalHeaders, data) { let max = 0; horizontalHeaders.forEach((row) => { let count = 0; if (Array.isArray(row)) { row.forEach((col) => { var _a; count += (_a = col.colSpan) !== null && _a !== void 0 ? _a : 1; }); } if (max < count) { max = count; } }); if (max === 0) { max = data.length; } return max; } getNumberOfRows(verticalHeaders, data) { var _a; let max = 0; verticalHeaders.forEach((col) => { let count = 0; if (Array.isArray(col)) { col.forEach((row) => { var _a; count += (_a = row.rowSpan) !== null && _a !== void 0 ? _a : 1; }); } if (max < count) { max = count; } }); if (max === 0) { max = data.length; } else { max -= ((_a = this.state._dataFoot) === null || _a === void 0 ? void 0 : _a.length) || 0; } return max; } getThePrimaryHeadersWithKeyOrRenderFunction(headers) { const primaryHeaders = []; headers.forEach((cells) => { cells.forEach((cell) => { if (typeof cell.key === 'string' || typeof cell.render === 'function') { primaryHeaders.push(cell); } }); }); return primaryHeaders; } getPrimaryHeaders(headers) { var _a, _b; let primaryHeaders = this.getThePrimaryHeadersWithKeyOrRenderFunction((_a = headers.horizontal) !== null && _a !== void 0 ? _a : []); this.horizontal = true; if (primaryHeaders.length === 0) { primaryHeaders = this.getThePrimaryHeadersWithKeyOrRenderFunction((_b = headers.vertical) !== null && _b !== void 0 ? _b : []); if (primaryHeaders.length > 0) { this.horizontal = false; } } return primaryHeaders; } createDataField(data, headers, isFoot) { var _a, _b, _c, _d, _e, _f, _g, _h; headers.horizontal = Array.isArray(headers === null || headers === void 0 ? void 0 : headers.horizontal) ? headers.horizontal : []; headers.vertical = Array.isArray(headers === null || headers === void 0 ? void 0 : headers.vertical) ? headers.vertical : []; this.maxCols = this.getNumberOfCols(headers.horizontal, data); const primaryHeader = this.getPrimaryHeaders(headers); let maxRows = this.getNumberOfRows(headers.vertical, data); let startRow = 0; if (isFoot) { startRow = maxRows; maxRows += ((_a = this.state._dataFoot) === null || _a === void 0 ? void 0 : _a.length) || 0; } const dataField = []; const rowCount = []; const rowSpans = []; headers.vertical.forEach((_row, index) => { rowCount[index] = 0; rowSpans[index] = []; }); const sortedPrimaryHeader = primaryHeader; for (let i = startRow; i < maxRows; i++) { const dataRow = []; headers.vertical.forEach((headerCells, index) => { let rowsTotal = 0; rowSpans[index].forEach((value) => (rowsTotal += value)); if (rowsTotal <= i) { const rows = headerCells[i - rowsTotal + rowCount[index]]; if (typeof rows === 'object') { dataRow.push(Object.assign(Object.assign({}, rows), { headerCell: true, data: {} })); let rowSpan = 1; if (typeof rows.rowSpan === 'number' && rows.rowSpan > 1) { rowSpan = rows.rowSpan; } rowSpans[index].push(rowSpan); if (typeof rows.colSpan === 'number' && rows.colSpan > 1) { for (let k = 1; k < rows.colSpan; k++) { rowSpans[index + k].push(rowSpan); } } rowCount[index]++; } } }); for (let j = 0; j < this.maxCols; j++) { let fixed = this.isFixedCol(j); if (fixed === 'left') { if (this.getFixedOffset(j) === undefined) { let offset = (_b = this.fixedOffsets[j - 1]) !== null && _b !== void 0 ? _b : 0; offset += (_d = (_c = sortedPrimaryHeader[j - 1]) === null || _c === void 0 ? void 0 : _c.width) !== null && _d !== void 0 ? _d : 0; this.fixedOffsets[j] = offset; } } if (fixed === 'right') { if (this.getFixedOffset(j) === undefined) { let offset = (_e = this.fixedOffsets[j + 1]) !== null && _e !== void 0 ? _e : 0; offset += (_g = (_f = sortedPrimaryHeader[j + 1]) === null || _f === void 0 ? void 0 : _f.width) !== null && _g !== void 0 ? _g : 0; this.fixedOffsets[j] = offset; } } if (this.horizontal === true) { const row = isFoot && this.state._dataFoot ? this.state._dataFoot[i - startRow] : data[i]; if (typeof sortedPrimaryHeader[j] === 'object' && sortedPrimaryHeader[j] !== null && typeof row === 'object' && row !== null && (typeof sortedPrimaryHeader[j].key === 'string' || typeof sortedPrimaryHeader[j].render === 'function')) { const cellKey = sortedPrimaryHeader[j].key; const cellValue = row[cellKey]; dataRow.push(Object.assign(Object.assign({}, sortedPrimaryHeader[j]), { colIndex: j, colSpan: undefined, rowSpan: undefined, data: row, label: cellValue })); } } else { if (typeof sortedPrimaryHeader[i] === 'object' && sortedPrimaryHeader[i] !== null && typeof data[j] === 'object' && data[j] !== null && (typeof sortedPrimaryHeader[i].key === 'string' || typeof sortedPrimaryHeader[i].render === 'function')) { const cellKey = sortedPrimaryHeader[i].key; const cellValue = data[j][cellKey]; dataRow.push(Object.assign(Object.assign({}, sortedPrimaryHeader[i]), { colIndex: j, colSpan: undefined, rowSpan: undefined, data: data[j], label: cellValue })); } } } dataField.push(dataRow); } if (data.length === 0) { let colspan = this.getVisibleColSpan((_h = headers.horizontal) === null || _h === void 0 ? void 0 : _h[0]); let rowspan = 0; if (Array.isArray(headers.vertical) && headers.vertical.length > 0) { colspan -= headers.vertical.length; headers.vertical[0].forEach((row) => { rowspan += row.rowSpan || 1; }); } const emptyCell = { colSpan: colspan, label: this.translateNoEntries, render: undefined, rowSpan: Math.max(rowspan, 1), }; if (dataField.length === 0) { dataField.push([emptyCell]); } else { dataField[0].push(emptyCell); } } return dataField; } getVisibleColSpan(cells) { var _a; return ((_a = cells === null || cells === void 0 ? void 0 : cells.reduce((acc, cell) => { if ('visible' in cell && cell.visible === false) { return acc; } return acc + (cell.colSpan || 1); }, 0)) !== null && _a !== void 0 ? _a : 0); } isFixedCol(index) { if (!this._fixedCols || index === undefined || this.stickyColsDisabled) { return undefined; } if (index < this._fixedCols[0]) { return 'left'; } if (index >= this.maxCols - this._fixedCols[1]) { return 'right'; } } getFixedOffset(index) { if (!this.tableDivElement || index === undefined) { return undefined; } if (this.fixedOffsets[index] !== undefined) { return this.fixedOffsets[index]; } return undefined; } getOffsetString(index, left) { if (left && this._selection) { return 'calc( var(--kol-table-selection-col-width) + ' + this.getFixedOffset(index) + 'px)'; } return this.getFixedOffset(index) + 'px'; } handleSelectionChangeCallbackAndEvent(event, payload) { var _a; if (typeof ((_a = this.state._on) === null || _a === void 0 ? void 0 : _a[Callback.onSelectionChange]) === 'function') { this.state._on[Callback.onSelectionChange](event, payload); } if (this.host) { dispatchDomEvent(this.host, KolEvent.selectionChange, payload); } } initializeHeaderCellSettings() { if (this.state._headerCells && this.state._headerCells.horizontal && this.state._headerCells.horizontal.length > 0) { const updatedHeaderCells = Object.assign(Object.assign({}, this.state._headerCells), { horizontal: this.state._headerCells.horizontal.map((row) => row.map((header) => (Object.assign(Object.assign({}, header), { visible: typeof header.visible === 'boolean' ? header.visible : true, hidable: typeof header.hidable === 'boolean' ? header.hidable : true })))) }); setState(this, '_headerCells', updatedHeaderCells); } } componentWillLoad() { this.validateData(this._data); this.validateDataFoot(this._dataFoot); this.validateHeaderCells(this._headerCells); this.validateLabel(this._label); this.validateOn(this._on); this.validateSelection(this._selection); this.validateHasSettingsMenu(this._hasSettingsMenu); this.validateVariantClassName(this._variant); } renderSelectionCell(row, rowIndex) { var _a; const selection = this.state._selection; if (!selection) return ''; const keyPropertyName = this.getSelectionKeyPropertyName(); const firstCellData = (_a = row[0]) === null || _a === void 0 ? void 0 : _a.data; if (!firstCellData) return ''; const keyProperty = firstCellData[keyPropertyName]; const isMultiple = selection.multiple || selection.multiple === undefined; const selected = (() => { const v = selection === null || selection === void 0 ? void 0 : selection.selectedKeys; const arr = v === undefined ? [] : Array.isArray(v) ? v : [v]; return arr.some((k) => String(k) === String(keyProperty)); })(); const disabled = (() => { const v = selection === null || selection === void 0 ? void 0 : selection.disabledKeys; const arr = v === undefined ? [] : Array.isArray(v) ? v : [v]; return arr.some((k) => String(k) === String(keyProperty)); })(); const label = selection.label(firstCellData); const props = { name: 'selection', checked: selected, disabled, id: String(keyProperty), ['aria-label']: label, }; return (h("td", { key: `tbody-${rowIndex}-selection`, class: "kol-table__cell kol-table__cell--selection" }, h("div", { class: clsx('kol-table__selection', { 'kol-table__selection--checked': selected }) }, isMultiple ? (h("label", { class: clsx('kol-table__selection-label', { 'kol-table__selection-label--disabled': disabled, }) }, h(IconFC, { class: "kol-table__selection-icon", icons: `kolicon ${selected ? 'kolicon-check' : ''}`, label: "" }), h("input", Object.assign({ class: clsx('kol-table__selection-input kol-table__selection-input--checkbox'), ref: (el) => el && this.checkboxRefs.push(el) }, props, { type: "checkbox", onInput: (event) => { const current = (() => { const v = selection === null || selection === void 0 ? void 0 : selection.selectedKeys; return v === undefined ? [] : Array.isArray(v) ? v : [v]; })(); const updatedSelectedKeys = !selected ? [...current, keyProperty] : current.filter((k) => String(k) !== String(keyProperty)); this.handleSelectionChangeCallbackAndEvent(event, updatedSelectedKeys !== null && updatedSelectedKeys !== void 0 ? updatedSelectedKeys : []); } })))) : (h("label", { class: "kol-table__selection-label" }, h("input", Object.assign({ class: clsx('kol-table__selection-input kol-table__selection-input--radio') }, props, { type: "radio", onInput: (event) => { this.handleSelectionChangeCallbackAndEvent(event, [keyProperty]); } })))), h("div", { class: "kol-table__selection-input-tooltip" }, h(TooltipFC, { label: label, badgeText: "", id: `${keyProperty}-label`, refFloating: () => { } }))))); } getSelectionKeyPropertyName() { var _a, _b; return (_b = (_a = this.state._selection) === null || _a === void 0 ? void 0 : _a.keyPropertyName) !== null && _b !== void 0 ? _b : 'id'; } getDataWithSelectionEnabled() { const keyPropertyName = this.getSelectionKeyPropertyName(); return this.state._data.filter((item) => { var _a; const v = (_a = this.state._selection) === null || _a === void 0 ? void 0 : _a.disabledKeys; const arr = v === undefined ? [] : Array.isArray(v) ? v : [v]; return !arr.some((k) => String(k) === String(item[keyPropertyName])); }); } getSelectedKeysWithoutDisabledKeys() { const sel = (() => { var _a; const v = (_a = this.state._selection) === null || _a === void 0 ? void 0 : _a.selectedKeys; return v === undefined ? [] : Array.isArray(v) ? v : [v]; })(); const dis = (() => { var _a; const v = (_a = this.state._selection) === null || _a === void 0 ? void 0 : _a.disabledKeys; return v === undefined ? [] : Array.isArray(v) ? v : [v]; })(); return sel.filter((k) => !dis.some((d) => String(d) === String(k))); } getSelectedKeysWithDisabledKeysOnly() { const sel = (() => { var _a; const v = (_a = this.state._selection) === null || _a === void 0 ? void 0 : _a.selectedKeys; return v === undefined ? [] : Array.isArray(v) ? v : [v]; })(); const dis = (() => { var _a; const v = (_a = this.state._selection) === null || _a === void 0 ? void 0 : _a.disabledKeys; return v === undefined ? [] : Array.isArray(v) ? v : [v]; })(); return sel.filter((k) => dis.some((d) => String(d) === String(k))); } getRevertedSelection(selectAll) { var _a; const keyPropertyName = this.getSelectionKeyPropertyName(); const selection = (_a = this.getSelectedKeysWithDisabledKeysOnly()) !== null && _a !== void 0 ? _a : []; if (selectAll) { selection.push(...this.getDataWithSelectionEnabled().map((el) => el === null || el === void 0 ? void 0 : el[keyPropertyName])); } return selection; } getTableMinWidth() { var _a, _b; const horizontalHeaders = (_a = this.state._headerCells.horizontal) !== null && _a !== void 0 ? _a : []; const horizontalHeaderWidths = []; horizontalHeaders.forEach((row) => { row.forEach((cell) => { if (cell.visible !== false && cell.width !== undefined && cell.width > 0) { horizontalHeaderWidths.push(cell.width); } }); }); const verticalHeaders = (_b = this.state._headerCells.vertical) !== null && _b !== void 0 ? _b : []; const verticalHeaderWidths = []; verticalHeaders.forEach((column) => { column.forEach((cell) => { if (cell.width !== undefined && cell.width > 0) { verticalHeaderWidths.push(cell.width); } }); }); const allWidths = [...verticalHeaderWidths, ...horizontalHeaderWidths]; if (allWidths.length === 0) { return '0px'; } if (allWidths.length === 1) { return `${allWidths[0]}px`; } return `calc(${allWidths.map((w) => `${w}px`).join(' + ')})`; } renderHeadingSelectionCell() { var _a, _b; const selection = this.state._selection; if (!selection) { return h("td", { class: "kol-table__cell kol-table__cell--header", key: `thead-0` }); } if (selection.multiple === false) { return h("td", { key: `thead-0-selection`, class: "kol-table__cell kol-table__cell--header kol-table__cell--selection" }); } const selectedKeyLength = (_b = (_a = this.getSelectedKeysWithoutDisabledKeys()) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0; const dataLength = this.getDataWithSelectionEnabled().length; const isChecked = selectedKeyLength === dataLength; const indeterminate = selectedKeyLength !== 0 && !isChecked; let translationKey = 'kol-table-selection-indeterminate'; if (isChecked && !indeterminate) { translationKey = 'kol-table-selection-none'; } if (selectedKeyLength === 0) { translationKey = 'kol-table-selection-all'; } const label = translate(translationKey); return (h("th", { key: `thead-0-selection`, class: "kol-table__cell kol-table__cell--header kol-table__cell--selection" }, h("div", { class: clsx('kol-table__selection', { 'kol-table__selection--indeterminate': indeterminate, 'kol-table__selection--checked': isChecked, }) }, h("label", { class: "kol-table__selection-label" }, h(IconFC, { class: "kol-table__selection-icon", icons: `kolicon ${indeterminate ? 'kolicon-minus' : isChecked ? 'kolicon-check' : ''}`, label: "" }), h("input", { class: clsx('kol-table__selection-input kol-table__selection-input--checkbox'), "data-testid": "selection-checkbox-all", ref: (el) => el && this.checkboxRefs.push(el), name: "selection", checked: isChecked && !indeterminate, indeterminate: indeterminate, "aria-label": label, type: "checkbox", onInput: (event) => { this.handleSelectionChangeCallbackAndEvent(event, this.getRevertedSelection(!isChecked)); } })), h("div", { class: "kol-table__selection-input-toolti