@sap-ux/ui-components
Version:
SAP UI Components Library
267 lines • 9.34 kB
JavaScript
;
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