UNPKG

@public-ui/components

Version:

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

1,004 lines 52.9 kB
/*! * KoliBri - The accessible HTML-Standard */ import { __rest } from "tslib"; import { Fragment, h } from "@stencil/core"; import { isEqual } from "lodash-es"; import { KolButtonWcTag, KolLinkWcTag, KolTableSettingsWcTag } from "../../core/component-names"; import { translate } from "../../i18n"; import { IconFC } from "../../internal/functional-components/icon/component"; import { TooltipFC } from "../../internal/functional-components/tooltip/component"; import { Log, setState, validateFixedCols, validateHasSettingsMenu, validateLabel, validateTableCallbacks, validateTableData, validateTableDataFoot, validateTableHeaderCells, validateTableSelection, validateVariantClassName, } from "../../schema"; import { Callback } from "../../schema/enums"; import clsx from "../../utils/clsx"; import { nonce } from "../../utils/dev.utils"; import { dispatchDomEvent, KolEvent } from "../../utils/events"; const RESIZE_DEBOUNCE_DELAY = 150; export class KolTableStatelessWc { constructor() { 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-tooltip" }, h(TooltipFC, { label: label, badgeText: "", id: `${translationKey}-label`, refFloating: () => { } }))))); } renderHeaderTdCell() { const horizontalHeaders = this.state._headerCells.horizontal; const verticalHeaders = this.state._headerCells.vertical; if (!Array.isArray(horizontalHeaders) || horizontalHeaders.length === 0 || !Array.isArray(verticalHeaders) || verticalHeaders.length === 0) { return h(Fragment, null); } const totalWidth = verticalHeaders.reduce((sum, column) => { var _a; const firstCell = column === null || column === void 0 ? void 0 : column[0]; return sum + ((_a = firstCell === null || firstCell === void 0 ? void 0 : firstCell.width) !== null && _a !== void 0 ? _a : 0); }, 0); return (h("td", { "aria-hidden": "true", colSpan: verticalHeaders.length, rowSpan: horizontalHeaders.length, style: totalWidth > 0 ? { width: `${totalWidth}px` } : undefined })); } formatSortOrderDescription(order) { return this.translateSortOrder.replace('{{order}}', `${order}`); } getSortAriaDescription(order) { if (typeof order === 'number' && order > 0) { return `${this.translateSort} – ${this.formatSortOrderDescription(order)}`; } return this.translateSort; } renderHeadingCell(cell, rowIndex, colIndex, isVertical) { if (cell.visible === false) { return ''; } const sortableSetting = (cell === null || cell === void 0 ? void 0 : cell.sortable) !== false; const hasSortDirection = typeof cell.sortDirection === 'string'; const canSort = sortableSetting && hasSortDirection; let ariaSort = 'none'; let sortButtonIcon = 'kolicon-sort-neutral'; if (canSort && cell.sortDirection) { switch (cell.sortDirection) { case 'ASC': sortButtonIcon = 'kolicon-sort-asc'; ariaSort = 'ascending'; break; case 'DESC': sortButtonIcon = 'kolicon-sort-desc'; ariaSort = 'descending'; break; default: ariaSort = 'none'; } } const scope = isVertical ? 'row' : typeof cell.colSpan === 'number' && cell.colSpan > 1 ? 'colgroup' : 'col'; const sortOrder = typeof cell.sortOrder === 'number' && cell.sortOrder > 0 ? cell.sortOrder : undefined; const sortDescription = this.getSortAriaDescription(sortOrder); const width = cell.width !== undefined ? `${cell.width}px` : undefined; const fixed = this.isFixedCol(colIndex); const offsetLeft = fixed === 'left' ? this.getOffsetString(colIndex, true) : undefined; const offsetRight = fixed === 'right' ? this.getOffsetString(colIndex) : undefined; return (h("th", { key: `${rowIndex}-${colIndex}-${cell.label}`, class: clsx('kol-table__cell kol-table__cell--header', `kol-table__cell--${ariaSort}`, cell.textAlign && `kol-table__cell--align-${cell.textAlign}`, fixed && `kol-table__cell--sticky-${fixed}`), scope: scope, colSpan: cell.colSpan, rowSpan: cell.rowSpan, style: { width: width, left: offsetLeft, right: offsetRight }, "aria-sort": ariaSort, "data-sort": canSort && cell.sortDirection ? `sort-${cell.sortDirection}` : undefined }, canSort && cell.sortDirection ? (h("span", { class: "kol-table__sort" }, h(KolButtonWcTag, { class: "kol-table__sort-button", _icons: { right: sortButtonIcon }, _label: cell.label, _ariaDescription: sortDescription, _on: { onClick: (event) => { var _a; if (typeof ((_a = this.state._on) === null || _a === void 0 ? void 0 : _a.onSort) === 'function' && cell.key && cell.sortDirection) { this.state._on.onSort(event, { key: cell.key, currentSortDirection: cell.sortDirection, }); } if (this.host) { dispatchDomEvent(this.host, KolEvent.sort, { key: cell.key, currentSortDirection: cell.sortDirection, }); } }, } }), sortOrder && (h("span", { "aria-hidden": "true", class: "kol-table__sort-order" }, sortOrder)))) : (cell.label))); } renderSpacer(variant, cellDefs) { var _a; const verticalHeaderColpan = ((_a = this.state._headerCells.vertical) === null || _a === void 0 ? void 0 : _a.length) || 0; const colspan = this.getVisibleColSpan(cellDefs === null || cellDefs === void 0 ? void 0 : cellDefs[0]); const selectionCell = this.state._selection ? 1 : 0; return (h("tr", { "aria-hidden": "true", class: clsx('kol-table__spacer', `kol-table__spacer--${variant}`) }, h("td", { class: clsx(`kol-table__spacer-line kol-table__spacer-line--${variant}`), colSpan: verticalHeaderColpan + colspan + selectionCell }))); } renderFoot() { if (!this.state._dataFoot || this.state._dataFoot.length === 0) { return null; } const rows = this.createDataField(this.state._dataFoot, this.state._headerCells, true); return (h("tfoot", { class: "kol-table__footer" }, [ this.renderSpacer('foot', rows), rows.map((row, rowIndex) => this.renderTableRow(row, rowIndex, true, true)), ])); } render() { var _a; const dataField = this.createDataField(this.state._data, this.state._headerCells); this.checkboxRefs = []; const horizontalHeaders = this.state._headerCells.horizontal; const showInternalCaption = !((_a = this.externalLabelElements) === null || _a === void 0 ? void 0 : _a.length); return (h("div", { key: 'b3078fc5b1fddaf8b1a125452e5a0ba65f64cce1', class: clsx('kol-table', { [`kol-table--${this.state._variant}`]: this.state._variant !== undefined, }) }, this.state._hasSettingsMenu && h(KolTableSettingsWcTag, { key: 'cba65b7abb0aa685c0115c74238414e1acf65d20', _horizontalHeaderCells: horizontalHeaders !== null && horizontalHeaders !== void 0 ? horizontalHeaders : [] }), h("div", { key: 'd8390e0d8ef806a913c5b433c1e528c3729c63a2', ref: (element) => (this.tableDivElement = element), class: "kol-table__scroll-container", tabindex: this.tableDivElementHasScrollbar ? (showInternalCaption ? '-1' : '0') : undefined }, h("table", { key: '24880450759191739622f8dc03f25ec52c188248', ref: (el) => { this.tableRef = el; this.syncTableLabel(this.externalLabelElements); }, "aria-labelledby": showInternalCaption ? 'caption' : undefined, class: "kol-table__table", style: { minWidth: this.getTableMinWidth(), } }, showInternalCaption && (h("caption", { key: '9a80f320bcb382b953176564e1209e24a14ebe91', class: "kol-table__focus-element kol-table__caption", id: "caption", tabindex: this.tableDivElementHasScrollbar ? '0' : undefined }, this.state._label)), Array.isArray(horizontalHeaders) && (h("thead", { key: '9125286ae3e47630e42fd04d970f687ca8c4c056', class: "kol-table__head" }, [ horizontalHeaders.map((cols, rowIndex) => (h("tr", { class: "kol-table__head-row", key: `thead-${rowIndex}` }, this.state._selection && this.renderHeadingSelectionCell(), rowIndex === 0 && this.renderHeaderTdCell(), Array.isArray(cols) && cols.map((cell, colIndex) => this.renderHeadingCell(cell, rowIndex, colIndex, false))))), this.renderSpacer('head', horizontalHeaders), ])), h("tbody", { key: '18458ad8f7712d2acffbec2ae79da9b5991174b7', class: "kol-table__body" }, dataField.map((row, rowIndex) => this.renderTableRow(row, rowIndex, true))), this.renderFoot())))); } static get is() { return "kol-table-stateless-wc"; } static get properties() { return { "externalLabelElements": { "type": "unknown", "mutable": false, "complexType": { "original": "HTMLElement[]", "resolved": "HTMLElement[] | undefined", "references": { "HTMLElement": { "location": "global", "id": "global::HTMLElement" } } }, "required": false, "optional": true, "docs": { "tags": [{ "name": "internal", "text": "Use `_ariaLabelledby` on the public `kol-table-stateless` component instead." }], "text": "External label elements forwarded from the public wrapper." }, "getter": false, "setter": false }, "_ariaLabelledby": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string | undefined", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "internal", "text": "Required by TableStatelessAPI. Actual resolution happens in the shadow wrapper\n(kol-table-stateless), which resolves IDs in the correct tree scope and passes the\nresulting HTMLElement[] via externalLabelElements." }], "text": "" }, "getter": false, "setter": false, "reflect": false, "attribute": "_aria-labelledby" }, "_data": { "type": "string", "mutable": false, "complexType": { "original": "TableDataPropType", "resolved": "KoliBriTableDataType[] | string", "references": { "TableDataPropType": { "location": "import", "path": "../../schema", "id": "src/schema/index.ts::TableDataPropType" } } }, "required": true, "optional": false, "docs": { "tags": [], "text": "Defines the primary table data." }, "getter": false, "setter": false, "reflect": false, "attribute": "_data" }, "_dataFoot": { "type": "string", "mutable": false, "complexType": { "original": "TableDataFootPropType", "resolved": "KoliBriTableDataType[] | string | undefined", "references": { "TableDataFootPropType": { "location": "import", "path": "../../schema", "id": "src/schema/index.ts::TableDataFootPropType" } } }, "required": false, "optional": true, "docs": { "tags": [], "text": "Defines the data for the table footer." }, "getter": false, "setter": false, "reflect": false, "attribute": "_data-foot" }, "_fixedCols": { "type": "unknown", "mutable": false, "complexType": { "original": "FixedColsPropType", "resolved": "[number, number] | undefined", "references": { "FixedColsPropType": { "location": "import", "path": "../../schema", "id": "src/schema/index.ts::FixedColsPropType" } } }, "required": false, "optional": true, "docs": { "tags": [], "text": "Defines the fixed number of columns from start and end of the table" }, "getter": false, "setter": false }, "_headerCells": { "type": "string", "mutable": false, "complexType": { "original": "TableHeaderCellsPropType", "resolved": "string | { horizontal?: KoliBriTableHeaderCell[][] | undefined; vertical?: KoliBriTableHeaderCell[][] | undefined; }", "references": { "TableHeaderCellsPropType": { "location": "import", "path": "../../schema", "id": "src/schema/index.ts::TableHeaderCellsPropType" } } }, "required": true, "optional": false, "docs": { "tags": [], "text": "Defines the horizontal and vertical table headers." }, "getter": false, "setter": false, "reflect": false, "attribute": "_header-cells" }, "_label": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": true, "optional": false, "docs": { "tags": [], "text": "Defines the visible or semantic label of the component (e.g. aria-label, label, headline, caption, summary, etc.)." }, "getter": false, "setter": false, "reflect": false, "attribute": "_label" }, "_on": { "type": "unknown", "mutable": false, "complexType": { "original": "TableCallbacksPropType", "resolved": "undefined | { onSort?: EventValueOrEventCallback<MouseEvent, SortEventPayload> | undefined; onSelectionChange?: EventValueOrEventCallback<Event, KoliBriTableSelectionKeys> | undefined; onChangeHeaderCells?: EventValueOrEventCallback<Event, TableHeaderCells> | undefined; }", "references": { "TableCallbacksPropType": { "location": "import", "path": "../../schema", "id": "src/schema/index.ts::TableCallbacksPropType" } } }, "required": false, "optional": true, "docs": { "tags": [], "text": "Defines the callback functions for table events." }, "getter": false, "setter": false }, "_selection": { "type": "string", "mutable": false, "complexType": { "original": "TableSelectionPropType", "resolved": "string | undefined | ({ disabledKeys?: KoliBriTableSelectionKeys | undefined; keyPropertyName?: string | undefined; label: (row: KoliBriTableDataType) => string; multiple?: boolean | undefined; selectedKeys?: KoliBriTableSelectionKeys | undefined; })", "references": { "TableSelectionPropType": { "location": "import", "path": "../../schema", "id": "src/schema/index.ts::TableSelectionPropType" } } }, "required": false, "optional": true, "docs": { "tags": [], "text": "Defines how rows can be selected and the current selection." }, "getter": false, "setter": false, "reflect": false, "attribute": "_selection" }, "_variant": { "type": "string", "mutable": false, "complexType": { "original": "VariantClassNamePropType", "resolved": "string | undefined", "references": { "VariantClassNamePropType": { "location": "import", "path": "../../schema", "id": "src/schema/index.ts::VariantClassNamePropType" } } }, "required": false, "optional": true, "docs": { "tags": [{ "name": "internal", "text": undefined }], "text": "Defines which variant should be used for presentation." }, "getter": false, "setter": false, "reflect": false, "attribute": "_variant" }, "_hasSettingsMenu": { "type": "boolean", "mutabl