UNPKG

@sap-ux/ui-components

Version:
267 lines 9.34 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports._onHeaderRender = void 0; exports._copyAndSort = _copyAndSort; exports.focusEditedCell = focusEditedCell; exports.getCellFromCoords = getCellFromCoords; exports.scrollToColumn = scrollToColumn; exports.scrollToRow = scrollToRow; exports.waitFor = waitFor; exports.sleep = sleep; exports.addRowNumbers = addRowNumbers; exports.getStylesForSelectedCell = getStylesForSelectedCell; exports.showFocus = showFocus; exports.hideFocus = hideFocus; exports.getComboBoxInput = getComboBoxInput; const react_1 = __importDefault(require("react")); const react_2 = require("@fluentui/react"); const __1 = require(".."); /** * Method to copy and sort. * * @param {T[]} items * @param {string }columnKey * @param {boolean} isSortedDescending * @returns {T[]} */ function _copyAndSort(items, columnKey, isSortedDescending) { const key = columnKey; return items.slice(0).sort((a, b) => ((isSortedDescending ? a[key] > b[key] : a[key] < b[key]) ? 1 : -1)); } /** * Focus edited cell. * * @param {EditedCell | undefined} editedCell * @param {UITableProps} props * @param {string} direction * @returns {Promise<void>} */ function focusEditedCell(editedCell, props, direction = '') { const rowIndex = editedCell?.rowIndex || 0; const colKey = editedCell?.column?.key || ''; let newRowIndex = rowIndex; let newColKey = colKey; if (!colKey) { return Promise.resolve(); } // go up/down/left/right if (direction) { const editableColumnKeys = props.columns.filter((c) => c.editable).map((c) => c.key); const rowsLen = props.items.length; const colIdx = editableColumnKeys.indexOf(colKey); if (direction === 'right') { if (colIdx < editableColumnKeys.length - 1) { newColKey = editableColumnKeys[colIdx + 1]; } } else if (direction === 'left') { if (colIdx > 0) { newColKey = editableColumnKeys[colIdx - 1]; } } else if (direction === 'down') { if (rowIndex < rowsLen - 1) { newRowIndex = rowIndex + 1; } } else if (direction === 'up') { if (rowIndex > 0) { newRowIndex = rowIndex - 1; } } } return new Promise((resolve) => { requestAnimationFrame(() => { const cell = getCellFromCoords(newRowIndex, newColKey, props.columns, props.showRowNumbers); if (cell && direction) { cell.click(); } cell?.focus(); requestAnimationFrame(() => resolve()); }); }); } /** * Get cell from coordinates. * * @param {number} rowIdx * @param {string} columnKey * @param {UIColumn} columns * @param {boolean} addOneToColIndex * @returns {NodeListOf<Element>} */ function getCellFromCoords(rowIdx, columnKey, columns, addOneToColIndex = false) { const selectedIdx = (columns.findIndex((col) => col.key === columnKey) || 0) + +addOneToColIndex; const row = document.querySelector(`.ms-DetailsList .ms-DetailsList-contentWrapper .ms-List-page .ms-DetailsRow[data-item-index="${rowIdx || 0}"]`); const cols = row?.querySelectorAll('.ms-DetailsRow-cell'); return cols?.length && cols[selectedIdx]; } // manual workaround due to the lack of API for selecting columns /** * Scrolls to column. * * @param {string} columnKey * @param {UIColumn[]} columns * @param {number} selectedRow * @param {boolean} addOneToColIndex */ function scrollToColumn(columnKey, columns, selectedRow, addOneToColIndex = false) { const sidebar = document.querySelector('.data-editor__sidebar'); const sidebarWidth = (sidebar?.getBoundingClientRect().width ?? 0) + (addOneToColIndex ? 20 : 0); const scrollContainer = document.querySelector('.ms-ScrollablePane--contentContainer'); const cell = getCellFromCoords(selectedRow, columnKey, columns, addOneToColIndex); const box = cell && cell.getBoundingClientRect(); if (scrollContainer && box) { const left = scrollContainer.scrollLeft + Math.ceil(box.x) - sidebarWidth; requestAnimationFrame(() => scrollContainer.scrollTo({ left, behavior: 'smooth' })); } } /** * Scrolls to row. * * @param {number} idx * @param {IDetailsList | null} table */ function scrollToRow(idx = 0, table = null) { if (!table) { return; } table.focusIndex(idx, false); const slctr = `.ms-DetailsList-contentWrapper .ms-DetailsRow[data-selection-index="${idx}"]`; waitFor(slctr) .then((rowEl) => { rowEl.setAttribute('tabIndex', '0'); rowEl.click(); rowEl.focus(); showFocus(); }) .catch((e) => { throw e; }); } /** * Wait for selector. * * @param {string} selector * @param {number} count - number of tries, after which the element is considered not found * (so that the function doesn't run forever) * @returns {Promise<Element>} */ async function waitFor(selector, count = 10) { if (count === 0) { return Promise.reject(new Error('Element for selector not found: ' + selector)); } await sleep(); const el = document.querySelector(selector); return el ? Promise.resolve(el) : waitFor(selector, count - 1); } /** * Promisified setTimeout. * * @param ms * @returns Promise */ function sleep(ms = 200) { return new Promise((resolve) => setTimeout(resolve, ms)); } /** * Adds row numbers. * * @param {any} columns * @param {boolean} showRowNumbers * @returns {any} */ function addRowNumbers(columns, showRowNumbers = false) { if (showRowNumbers && columns[0].key !== '__row_number__') { columns.unshift({ key: '__row_number__', name: '#', fieldName: '__row_number__', minWidth: 24, maxWidth: 24, isResizable: false }); } return columns; } const _onHeaderRender = (props, defaultRender) => { if (!props || !defaultRender) { return null; } const customProps = { ...props, onRenderColumnHeaderTooltip: (item, tooltipDefaultRender) => { if (item?.column) { const column = item.column; const editable = (column.editable ? '' : 'not-') + 'editable-container'; const isRowNumber = column.key === '__row_number__'; const containerDiv = isRowNumber ? react_1.default.createElement("div", { className: editable }) : null; // row number column header is focusable on the parent of this cell const isFocusable = !isRowNumber; return (react_1.default.createElement("div", { className: "data-editor__header-cell", "data-is-focusable": isFocusable }, column.iconName && (react_1.default.createElement(__1.UIIcon, { className: "type-icon", iconName: column.iconName, title: column.iconTooltip || '' })), react_1.default.createElement("span", { title: column?.headerTooltip || column.name }, column.name), containerDiv)); } const isCheckTooltip = item?.hostClassName === 'ms-DetailsHeader-checkTooltip'; if (props.selection && isCheckTooltip && tooltipDefaultRender) { return tooltipDefaultRender(item); } return null; } }; return react_1.default.createElement(react_2.Sticky, null, defaultRender(customProps)); }; exports._onHeaderRender = _onHeaderRender; /** * Gets styles for selected cell. * * @param state * @returns {Partial<IDetailsListStyles>} */ function getStylesForSelectedCell(state) { let styles = {}; const editedRow = state.editedCell ? state.editedCell.rowIndex : undefined; const editedColumn = state.editedCell ? state.editedCell.column : undefined; if (editedRow !== undefined && editedColumn !== undefined) { styles = { root: { ['div.ms-List-cell']: { position: 'relative', zIndex: 0 }, [`div.ms-List-cell[data-list-index="${editedRow}"]`]: { zIndex: 1 }, [`.ms-DetailsRow-cell`]: { overflow: 'hidden' }, [`div.ms-List-cell[data-list-index="${editedRow}"] .ms-DetailsRow-cell[data-automation-key="${editedColumn.key}"]`]: { overflow: 'visible' } } }; } return styles; } function showFocus() { document.body.classList.remove('ms-Fabric--isFocusHidden'); document.body.classList.add('ms-Fabric--isFocusVisible'); } function hideFocus() { document.body.classList.add('ms-Fabric--isFocusHidden'); document.body.classList.remove('ms-Fabric--isFocusVisible'); } /** * Gets ComboBox input. * * @param ref * @returns {HTMLInputElement | undefined } */ function getComboBoxInput(ref) { return ref?.current?.querySelector('input'); } //# sourceMappingURL=UITable-helper.js.map