Skip to content

Commit 932cb56

Browse files
fix(): add guard to ensure that elements are not null to prevent null… (#4386)
* fix(): add guard to ensure that elements are not null to prevent null reference in boundingRect call * fix(): add unit tests for getFloatingProps --------- Co-authored-by: Maximilian Franzke <787658+mfranzke@users.noreply.github.com>
1 parent 131a7ad commit 932cb56

File tree

2 files changed

+91
-1
lines changed

2 files changed

+91
-1
lines changed
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
Object.defineProperty(globalThis, 'window', {
2+
value: {
3+
innerHeight: 0,
4+
innerWidth: 0
5+
} as Partial<Window>,
6+
writable: true
7+
});
8+
9+
import { describe, it, expect } from 'vitest';
10+
import { getFloatingProps } from './floating-components';
11+
12+
describe('getFloatingProps', () => {
13+
it('calculates the dimensions correctly', () => {
14+
const element = {
15+
getBoundingClientRect: () => ({ height: 50, width: 80 })
16+
} as HTMLElement;
17+
const parent = {
18+
getBoundingClientRect: () => ({
19+
top: 10,
20+
left: 20,
21+
width: 200,
22+
height: 100,
23+
bottom: 110,
24+
right: 220
25+
})
26+
} as HTMLElement;
27+
28+
const props = getFloatingProps(element, parent, 'center');
29+
expect(props.childWidth).toBe(80);
30+
expect(props.childHeight).toBe(50);
31+
expect(props.top).toBe(10);
32+
expect(props.left).toBe(20);
33+
expect(props.width).toBe(200);
34+
expect(props.height).toBe(100);
35+
expect(props.bottom).toBe(110);
36+
expect(props.right).toBe(220);
37+
});
38+
39+
it('does not throw when element or parent is missing', () => {
40+
expect(() =>
41+
getFloatingProps(
42+
null as unknown as HTMLElement,
43+
{} as HTMLElement,
44+
'top'
45+
)
46+
).not.toThrow();
47+
expect(() =>
48+
getFloatingProps(
49+
{} as HTMLElement,
50+
null as unknown as HTMLElement,
51+
'left'
52+
)
53+
).not.toThrow();
54+
expect(
55+
getFloatingProps(
56+
null as unknown as HTMLElement,
57+
null as unknown as HTMLElement,
58+
'bottom'
59+
)
60+
).toEqual({
61+
bottom: 0,
62+
childHeight: 0,
63+
childWidth: 0,
64+
correctedPlacement: 'bottom',
65+
height: 0,
66+
innerHeight: 0,
67+
innerWidth: 0,
68+
left: 0,
69+
right: 0,
70+
top: 0,
71+
width: 0
72+
});
73+
});
74+
});

packages/components/src/utils/floating-components.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,11 +118,27 @@ export const handleFixedDropdown = (
118118
element.style.position = 'fixed';
119119
};
120120

121-
const getFloatingProps = (
121+
export const getFloatingProps = (
122122
element: HTMLElement,
123123
parent: HTMLElement,
124124
placement: string
125125
) => {
126+
if (!element || !parent) {
127+
return {
128+
top: 0,
129+
bottom: 0,
130+
right: 0,
131+
height: 0,
132+
width: 0,
133+
left: 0,
134+
childHeight: 0,
135+
childWidth: 0,
136+
correctedPlacement: placement,
137+
innerWidth: window.innerWidth,
138+
innerHeight: window.innerHeight
139+
};
140+
}
141+
126142
const childRect = element.getBoundingClientRect();
127143
const { top, height, bottom, right, left, width } =
128144
parent.getBoundingClientRect();

0 commit comments

Comments
 (0)