UNPKG

react-table-sticky

Version:
111 lines (110 loc) 4.77 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.checkErrors = (columns) => { const hasGroups = !!columns.find((column) => column.parent); const stickyColumnsWithoutGroup = columns.filter((column) => column.sticky && !column.parent).map(({ Header }) => `'${Header}'`); if (hasGroups && stickyColumnsWithoutGroup.length) { throw new Error(`WARNING react-table-sticky: \nYour ReactTable has group and sticky columns outside groups, and that will break UI. \nYou must place ${stickyColumnsWithoutGroup.join(' and ')} columns into a group (even a group with an empty Header label)\n`); } const bugWithUnderColumnsSticky = columns.find((parentCol) => !parentCol.sticky && parentCol.columns && parentCol.columns.find((col) => col.sticky)); if (!bugWithUnderColumnsSticky) return; // @ts-ignore const childBugs = bugWithUnderColumnsSticky.columns.find(({ sticky }) => sticky); if (!childBugs) return; throw new Error(`WARNING react-table-sticky: \nYour ReactTable contain columns group with at least one child columns sticky. \nWhen ReactTable has columns groups, only columns groups can be sticky \nYou must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Header}' column, or remove the sticky property of '${childBugs.Header}' column.`); }; function getStickyValue(column) { if (column.sticky === 'left' || column.sticky === 'right') { return column.sticky; } if (column.parent) { return getStickyValue(column.parent); } return null; } exports.getStickyValue = getStickyValue; function columnIsLastLeftSticky(columnId, columns) { const index = columns.findIndex(({ id }) => id === columnId); const column = columns[index]; const nextColumn = columns[index + 1]; const columnIsLeftSticky = getStickyValue(column) === 'left'; const nextColumnIsLeftSticky = nextColumn && getStickyValue(nextColumn) === 'left'; return columnIsLeftSticky && !nextColumnIsLeftSticky; } exports.columnIsLastLeftSticky = columnIsLastLeftSticky; function columnIsFirstRightSticky(columnId, columns) { const index = columns.findIndex(({ id }) => id === columnId); const column = columns[index]; const prevColumn = columns[index - 1]; const columnIsRightSticky = getStickyValue(column) === 'right'; const prevColumnIsRightSticky = prevColumn && getStickyValue(prevColumn) === 'right'; return columnIsRightSticky && !prevColumnIsRightSticky; } exports.columnIsFirstRightSticky = columnIsFirstRightSticky; function getMarginRight(columnId, columns) { const currentIndex = columns.findIndex(({ id }) => id === columnId); let rightMargin = 0; for (let i = currentIndex + 1; i < columns.length; i += 1) { if (columns[i].isVisible !== false) { rightMargin += columns[i].width; } } return rightMargin; } exports.getMarginRight = getMarginRight; const cellStylesSticky = { // hard coded inline style will be remove in the next major release position: 'sticky', zIndex: 3, }; function findHeadersSameLevel(header, headers) { return headers.filter((flatHeaderItem) => { return flatHeaderItem.depth === header.depth; }); } function getStickyProps(header, instance) { let style = {}; const dataAttrs = {}; exports.checkErrors(instance.columns); const sticky = getStickyValue(header); if (sticky) { style = Object.assign({}, cellStylesSticky); // @ts-ignore dataAttrs['data-sticky-td'] = true; const headers = findHeadersSameLevel(header, instance.flatHeaders); const margin = sticky === 'left' ? header.totalLeft : getMarginRight(header.id, headers); style = Object.assign(Object.assign({}, style), { [sticky]: `${margin}px` }); const isLastLeftSticky = columnIsLastLeftSticky(header.id, headers); if (isLastLeftSticky) { // @ts-ignore dataAttrs['data-sticky-last-left-td'] = true; } const isFirstRightSticky = columnIsFirstRightSticky(header.id, headers); if (isFirstRightSticky) { // @ts-ignore dataAttrs['data-sticky-first-right-td'] = true; } } return Object.assign({ style }, dataAttrs); } exports.useSticky = (hooks) => { hooks.getHeaderProps.push((props, { instance, column }) => { const nextProps = getStickyProps(column, instance); return [props, nextProps]; }); hooks.getCellProps.push((props, { instance, cell }) => { const nextProps = getStickyProps(cell.column, instance); return [props, nextProps]; }); }; exports.useSticky.pluginName = 'useSticky';