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

SAP / ui5-webcomponents-react / 6021926795

30 Aug 2023 07:33AM CUT coverage: 87.671% (-0.2%) from 87.867%
6021926795

Pull #4986

github

web-flow
Merge 5f777c296 into 59639a77c
Pull Request #4986: feat(AnalyticalTable): add `subComponentsBehavior` prop

2761 of 3704 branches covered (0.0%)

20 of 33 new or added lines in 2 files covered. (60.61%)

2 existing lines in 2 files now uncovered.

5049 of 5759 relevant lines covered (87.67%)

18708.89 hits per line

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

94.12
/packages/main/src/components/AnalyticalTable/TableBody/RowSubComponent.tsx
1
import type { VirtualItem } from '@tanstack/react-virtual';
2
import { ThemingParameters } from '@ui5/webcomponents-react-base';
3
import type { ReactNode } from 'react';
4
import React, { useEffect, useRef } from 'react';
5
import { createUseStyles } from 'react-jss';
6

7
const styles = {
387✔
8
  subcomponent: {
9
    position: 'absolute',
10
    width: '100%',
11
    '&:focus': {
12
      outlineOffset: `calc(-1 * ${ThemingParameters.sapContent_FocusWidth})`,
13
      outline: `${ThemingParameters.sapContent_FocusWidth} ${ThemingParameters.sapContent_FocusStyle} ${ThemingParameters.sapContent_FocusColor}`
14
    }
15
  }
16
};
17
const useStyles = createUseStyles(styles, { name: 'RowSubComponent' });
387✔
18

19
interface RowSubComponent {
20
  subComponentsHeight: Record<string, { rowId: string; subComponentHeight?: number }>;
21
  virtualRow: VirtualItem<Record<string, unknown>>;
22
  dispatch: (e: { type: string; payload?: Record<string, unknown> }) => void;
23
  row: Record<string, unknown>;
24
  rowHeight: number;
25
  children: ReactNode | ReactNode[];
26
  rows: Record<string, unknown>[];
27
  alwaysShowSubComponent: boolean;
28
  rowIndex: number;
29
}
30

31
// eslint-disable-next-line @typescript-eslint/no-unused-vars
32
export const RowSubComponent = (props: RowSubComponent) => {
387✔
33
  const {
34
    subComponentsHeight,
35
    virtualRow,
36
    dispatch,
37
    row,
38
    rowHeight,
39
    children,
40
    rows,
41
    alwaysShowSubComponent,
42
    rowIndex
43
  } = props;
5,509✔
44
  const subComponentRef = useRef(null);
5,509✔
45
  const classes = useStyles();
5,509✔
46

47
  useEffect(() => {
5,509✔
48
    const subComponentHeightObserver = new ResizeObserver((entries) => {
2,676✔
49
      entries.forEach((entry) => {
2,485✔
50
        const target = entry.target.getBoundingClientRect();
2,485✔
51
        if (target) {
2,485✔
52
          // Firefox implements `borderBoxSize` as a single content rect, rather than an array
53
          const borderBoxSize = Array.isArray(entry.borderBoxSize) ? entry.borderBoxSize[0] : entry.borderBoxSize;
2,485!
54
          // Safari doesn't implement `borderBoxSize`
55
          const subCompHeight = borderBoxSize?.blockSize ?? target.height;
2,485!
56
          if (subComponentsHeight?.[virtualRow.index]?.subComponentHeight !== subCompHeight && subCompHeight !== 0) {
2,485✔
57
            // use most common sub-component height of first 10 sub-components as default height
58
            if (alwaysShowSubComponent && subComponentsHeight && Object.keys(subComponentsHeight).length === 10) {
1,500✔
59
              const objGroupedByHeight = Object.values(subComponentsHeight).reduce((acc, cur) => {
72✔
60
                const count = acc?.[cur.subComponentHeight];
720✔
61
                if (typeof count === 'number') {
720✔
62
                  return { ...acc, [cur.subComponentHeight]: count + 1 };
648✔
63
                }
64
                return { ...acc, [cur.subComponentHeight]: 1 };
72✔
65
              }, {});
66

67
              const mostUsedHeight = Object.keys(objGroupedByHeight).reduce((a, b) =>
72✔
68
                objGroupedByHeight[a] > objGroupedByHeight[b] ? a : b
×
69
              );
70
              const estimatedHeights = rows.reduce((acc, cur, index) => {
72✔
71
                acc[index] = { subComponentHeight: parseInt(mostUsedHeight), rowId: cur.id };
3,600✔
72
                return acc;
3,600✔
73
              }, {});
74
              dispatch({
72✔
75
                type: 'SUB_COMPONENTS_HEIGHT',
76
                payload: { ...estimatedHeights, ...subComponentsHeight }
77
              });
78
            } else {
79
              dispatch({
1,428✔
80
                type: 'SUB_COMPONENTS_HEIGHT',
81
                payload: {
82
                  ...subComponentsHeight,
83
                  [virtualRow.index]: { subComponentHeight: subCompHeight, rowId: row.id }
84
                }
85
              });
86
            }
87
          }
88
          // recalc if row id of row index has changed
89
          if (
2,485!
90
            subComponentsHeight?.[virtualRow.index]?.rowId != null &&
3,467✔
91
            subComponentsHeight?.[virtualRow.index]?.rowId !== row.id
92
          ) {
UNCOV
93
            dispatch({
×
94
              type: 'SUB_COMPONENTS_HEIGHT',
95
              payload: {
96
                ...subComponentsHeight,
97
                [virtualRow.index]: { subComponentHeight: subCompHeight, rowId: row.id }
98
              }
99
            });
100
          }
101
        }
102
      });
103
    });
104
    if (subComponentRef.current?.firstChild) {
2,676✔
105
      subComponentHeightObserver.observe(subComponentRef.current?.firstChild);
2,676✔
106
    }
107
    return () => {
2,676✔
108
      subComponentHeightObserver.disconnect();
2,656✔
109
    };
110
  }, [
111
    subComponentRef.current?.firstChild,
112
    subComponentsHeight,
113
    row.id,
114
    subComponentsHeight?.[virtualRow.index]?.subComponentHeight,
115
    virtualRow.index
116
  ]);
117

118
  return (
5,509✔
119
    <div
120
      ref={subComponentRef}
121
      data-subcomponent
122
      data-subcomponent-row-index={rowIndex}
123
      tabIndex={-1}
124
      style={{
125
        boxSizing: 'border-box',
126
        transform: `translateY(${rowHeight}px)`
127
      }}
128
      className={classes.subcomponent}
129
    >
130
      {children}
131
    </div>
132
  );
133
};
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