Skip to content

Commit 70179e9

Browse files
committed
🎨🔨 Re-adjust the height of TimePicker on Calendar resize due to number of days
Closes #5466
1 parent 386fce0 commit 70179e9

File tree

3 files changed

+93
-5
lines changed

3 files changed

+93
-5
lines changed

‎src/test/test_utils.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,26 @@ export const safeQuerySelectorAll = <T extends HTMLElement = HTMLElement>(
123123
return elements;
124124
};
125125

126+
export const setupMockResizeObserver = () => {
127+
const mockObserve = jest.fn();
128+
const mockDisconnect = jest.fn();
129+
const mockUnobserve = jest.fn();
130+
131+
const ResizeObserverMock = jest.fn(() => ({
132+
observe: mockObserve,
133+
disconnect: mockDisconnect,
134+
unobserve: jest.fn(),
135+
}));
136+
137+
global.ResizeObserver = ResizeObserverMock;
138+
139+
return {
140+
observe: mockObserve,
141+
disconnect: mockDisconnect,
142+
unobserve: mockUnobserve,
143+
};
144+
};
145+
126146
export class SafeElementWrapper<T extends HTMLElement> {
127147
constructor(private element: T) {}
128148

‎src/test/timepicker_test.test.tsx

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
SafeElementWrapper,
1010
safeQuerySelector,
1111
safeQuerySelectorAll,
12+
setupMockResizeObserver,
1213
} from "./test_utils";
1314

1415
const MIN_TIME_LI_LEN = 2;
@@ -19,10 +20,55 @@ describe("TimePicker", () => {
1920
let onChangeMoment: Date | undefined;
2021
let instance: DatePicker | null = null;
2122

23+
let mockObserve: jest.Mock, mockDisconnect: jest.Mock;
24+
25+
beforeAll(() => {
26+
const { observe, disconnect } = setupMockResizeObserver();
27+
mockObserve = observe;
28+
mockDisconnect = disconnect;
29+
});
30+
2231
beforeEach(() => {
2332
div = document.createElement("div");
2433
});
2534

35+
describe("Re-adjust height on Calendar Height Change", () => {
36+
beforeEach(() => {
37+
mockObserve.mockReset();
38+
mockDisconnect.mockReset();
39+
});
40+
41+
it("calls observe on mount", async () => {
42+
render(
43+
<DatePicker
44+
inline
45+
selected={new Date()}
46+
showTimeSelect
47+
timeIntervals={15}
48+
/>,
49+
);
50+
await waitFor(() => {
51+
expect(mockObserve).toHaveBeenCalledTimes(1);
52+
});
53+
});
54+
55+
it("calls disconnect on unmount", async () => {
56+
const component = render(
57+
<DatePicker
58+
inline
59+
selected={new Date()}
60+
showTimeSelect
61+
timeIntervals={15}
62+
/>,
63+
);
64+
65+
component.unmount();
66+
await waitFor(() => {
67+
expect(mockDisconnect).toHaveBeenCalledTimes(1);
68+
});
69+
});
70+
});
71+
2672
it("should update on input time change", () => {
2773
renderDatePicker("February 28, 2018 4:43 PM");
2874
expect(getInputString()).toBe("February 28, 2018 4:43 PM");

‎src/time.tsx

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,18 +62,19 @@ export default class Time extends Component<TimeProps, TimeState> {
6262
);
6363
};
6464

65+
private resizeObserver?: ResizeObserver;
6566
state: TimeState = {
6667
height: null,
6768
};
6869

6970
componentDidMount(): void {
7071
// code to ensure selected time will always be in focus within time window when it first appears
7172
this.scrollToTheSelectedTime();
72-
if (this.props.monthRef && this.header) {
73-
this.setState({
74-
height: this.props.monthRef.clientHeight - this.header.clientHeight,
75-
});
76-
}
73+
this.observeDatePickerHeightChanges();
74+
}
75+
76+
componentWillUnmount(): void {
77+
this.resizeObserver?.disconnect();
7778
}
7879

7980
private header?: HTMLDivElement;
@@ -82,6 +83,27 @@ export default class Time extends Component<TimeProps, TimeState> {
8283

8384
private centerLi?: HTMLLIElement;
8485

86+
private observeDatePickerHeightChanges(): void {
87+
const { monthRef } = this.props;
88+
this.updateContainerHeight();
89+
90+
if (monthRef) {
91+
this.resizeObserver = new ResizeObserver(() => {
92+
this.updateContainerHeight();
93+
});
94+
95+
this.resizeObserver.observe(monthRef);
96+
}
97+
}
98+
99+
private updateContainerHeight(): void {
100+
if (this.props.monthRef && this.header) {
101+
this.setState({
102+
height: this.props.monthRef.clientHeight - this.header.clientHeight,
103+
});
104+
}
105+
}
106+
85107
scrollToTheSelectedTime = (): void => {
86108
requestAnimationFrame((): void => {
87109
if (!this.list) return;

0 commit comments

Comments
 (0)