• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

SAP / ui5-webcomponents-react / 9203673320

23 May 2024 07:04AM CUT coverage: 88.576% (+0.07%) from 88.506%
9203673320

Pull #5758

github

web-flow
Merge 68bafe876 into 1d3decd9e
Pull Request #5758: Feat(AnalyticalTable): introduce autoResize column feature (#3196)

3056 of 4017 branches covered (76.08%)

62 of 65 new or added lines in 5 files covered. (95.38%)

1 existing line in 1 file now uncovered.

5474 of 6180 relevant lines covered (88.58%)

30429.2 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.12
/packages/main/src/components/AnalyticalTable/hooks/useAutoResize.tsx
1
import { enrichEventWithDetails } from '@ui5/webcomponents-react-base';
2
import { DEFAULT_COLUMN_WIDTH } from '../defaults/Column/index.js';
3
import type { ReactTableHooks } from '../types/index.js';
4
import { CELL_PADDING_PX } from './useDynamicColumnWidths.js';
5

6
function setResizerProps(props, { instance, header }) {
7
  const { dispatch, virtualRowsRange, rows, webComponentsReactProperties } = instance;
139,532✔
8
  const { onAutoResize, tableRef, isTreeTable } = webComponentsReactProperties;
139,532✔
9
  const { autoResizable, id: accessor } = header;
139,532✔
10

11
  if (!document || !tableRef.current || !autoResizable || !rows.length || !virtualRowsRange) {
139,532✔
12
    return props;
130,884✔
13
  }
14

15
  return {
8,648✔
16
    ...props,
17
    onDoubleClick: (e) => {
18
      let largest = getMeasureMax(accessor, virtualRowsRange, tableRef.current, isTreeTable);
423✔
19
      if (largest === -1) {
423!
NEW
20
        return;
×
21
      }
22
      largest = largest > DEFAULT_COLUMN_WIDTH ? largest : DEFAULT_COLUMN_WIDTH;
423✔
23
      if (typeof onAutoResize === 'function') {
423✔
24
        onAutoResize(
423✔
25
          enrichEventWithDetails(e, {
26
            columnId: accessor,
27
            width: largest
28
          })
29
        );
30
      }
31
      if (e.defaultPrevented) {
423✔
32
        return;
94✔
33
      }
34
      dispatch({
329✔
35
        type: 'AUTO_RESIZE',
36
        payload: { [accessor]: largest }
37
      });
38
    }
39
  };
40
}
41

42
function calculateContentWidth(cell) {
43
  let contentWidth = 0;
658✔
44
  Array.from<HTMLElement>(cell.children).forEach((child) => {
658✔
45
    contentWidth += child.scrollWidth;
1,034✔
46
  });
47
  return contentWidth;
658✔
48
}
49

50
function getMeasureMax(accessor, virtualRowsRange, tableNode, isTreeTable): number {
51
  let maxWidth = 0;
423✔
52
  let cellWithMaxWidthContent: HTMLElement | null | false = null;
423✔
53

54
  /**
55
   * recursively find the largest visible cell of the current column
56
   */
57
  function recursiveFindMaxWidth(row, accessor, remainingRows) {
58
    if (!row || remainingRows === 0) {
2,632✔
59
      return;
423✔
60
    }
61
    const cellNode = row.querySelector(`[data-column-id-cell="${accessor}"]`);
2,209✔
62
    const cellTextElement = cellNode?.querySelector(`[data-column-id-cell-text="${accessor}"]`);
2,209✔
63

64
    if (cellTextElement) {
2,209✔
65
      // for tree tables the indent (margin) has to be taken into account
66
      if (isTreeTable && cellNode?.dataset.isFirstColumn) {
2,115✔
67
        const cellWidth = calculateContentWidth(cellNode);
329✔
68
        if (maxWidth < cellWidth) {
329✔
69
          maxWidth = cellWidth;
141✔
70
          cellWithMaxWidthContent = false;
141✔
71
        }
72
      } else {
73
        const currWidth = cellTextElement.scrollWidth;
1,786✔
74
        if (maxWidth < currWidth) {
1,786✔
75
          maxWidth = currWidth;
470✔
76
          // only use the cell with the largest content for measuring
77
          cellWithMaxWidthContent = cellNode;
470✔
78
        }
79
      }
80
    }
81
    // if custom content (`Cell`) is rendered, the `cellTextElement` is not available.
82
    // In this case only the content of the first visible cell is used for measuring
83
    if (cellWithMaxWidthContent === null) {
2,209!
NEW
84
      cellWithMaxWidthContent = cellNode;
×
85
    }
86

87
    recursiveFindMaxWidth(row.nextElementSibling, accessor, remainingRows - 1);
2,209✔
88
  }
89

90
  const firstRow = tableNode.querySelector(`[data-virtual-row-index="${virtualRowsRange.startIndex}"]`);
423✔
91
  recursiveFindMaxWidth(firstRow, accessor, virtualRowsRange.endIndex - virtualRowsRange.startIndex);
423✔
92

93
  if (cellWithMaxWidthContent === false) {
423✔
94
    return Math.ceil(maxWidth + CELL_PADDING_PX + 2 /* account for rounding error and border */);
94✔
95
  }
96

97
  if (!cellWithMaxWidthContent) {
329!
NEW
98
    return -1;
×
99
  }
100

101
  return Math.ceil(
329✔
102
    calculateContentWidth(cellWithMaxWidthContent) + CELL_PADDING_PX + 2 /* account for rounding error and border */
103
  );
104
}
105

106
const setCellProps = (
446✔
107
  props,
108
  {
109
    cell: {
110
      column: { id }
111
    }
112
  }
113
) => {
114
  return [props, { ['data-column-id-cell']: id }];
1,275,096✔
115
};
116

117
export const useAutoResize = (hooks: ReactTableHooks) => {
446✔
118
  hooks.getResizerProps.push(setResizerProps);
50,474✔
119
  hooks.getCellProps.push(setCellProps);
50,474✔
120
};
121

122
useAutoResize.pluginName = 'useAutoResize';
446✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc