Skip to content

Commit 4a7f458

Browse files
asudohjoshblack
authored andcommitted
fix(DatePicker): fix calendar dropdown position (#4846)
This change inroduces a Flatpickr plugin that ensures that the calendar dropdown is put in the correct floating position even if the floating menu container is changed via `appendTo` and the floating menu container has significant offset from `<body>`. Fixes #4818.
1 parent e851a89 commit 4a7f458

File tree

2 files changed

+70
-1
lines changed

2 files changed

+70
-1
lines changed

packages/react/src/components/DatePicker/DatePicker.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import flatpickr from 'flatpickr';
1212
import l10n from 'flatpickr/dist/l10n/index';
1313
import { settings } from 'carbon-components';
1414
import DatePickerInput from '../DatePickerInput';
15+
import carbonFlatpickrAppendToPlugin from './plugins/appendToPlugin';
1516
import carbonFlatpickrFixEventsPlugin from './plugins/fixEventsPlugin';
1617
import carbonFlatpickrRangePlugin from './plugins/rangePlugin';
1718
import { match, keys } from '../../internal/keyboard';
@@ -340,7 +341,6 @@ export default class DatePicker extends Component {
340341
this.cal = new flatpickr(this.inputField, {
341342
disableMobile: true,
342343
defaultDate: value,
343-
appendTo,
344344
mode: datePickerType,
345345
allowInput: true,
346346
dateFormat: dateFormat,
@@ -351,6 +351,11 @@ export default class DatePicker extends Component {
351351
datePickerType === 'range'
352352
? new carbonFlatpickrRangePlugin({ input: this.toInputField })
353353
: () => {},
354+
appendTo
355+
? carbonFlatpickrAppendToPlugin({
356+
appendTo,
357+
})
358+
: () => {},
354359
carbonFlatpickrMonthSelectPlugin({
355360
selectorFlatpickrMonthYearContainer: '.flatpickr-current-month',
356361
selectorFlatpickrYearContainer: '.numInputWrapper',
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/**
2+
* @license
3+
*
4+
* Copyright IBM Corp. 2019
5+
*
6+
* This source code is licensed under the Apache-2.0 license found in the
7+
* LICENSE file in the root directory of this source tree.
8+
*/
9+
10+
/**
11+
* @param {object} config Plugin configuration.
12+
* @returns {Plugin} A Flatpickr plugin to put adjust the position of calendar dropdown.
13+
*/
14+
export default config => fp => {
15+
/**
16+
* Adjusts the floating meun position after Flatpicker sets it.
17+
*/
18+
const handlePreCalendarPosition = () => {
19+
Promise.resolve().then(() => {
20+
const {
21+
calendarContainer,
22+
config: fpConfig,
23+
_positionElement: positionElement,
24+
} = fp;
25+
const { appendTo } = fpConfig;
26+
const {
27+
left: containerLeft,
28+
top: containerTop,
29+
} = appendTo.getBoundingClientRect();
30+
const {
31+
left: refLeft,
32+
bottom: refBottom,
33+
} = positionElement.getBoundingClientRect();
34+
if (
35+
(appendTo !== appendTo.ownerDocument.body ||
36+
containerLeft !== 0 ||
37+
containerTop !== 0) &&
38+
appendTo.ownerDocument.defaultView
39+
.getComputedStyle(appendTo)
40+
.getPropertyValue('position') === 'static'
41+
) {
42+
throw new Error(
43+
'Floating menu container must not have `position:static`.'
44+
);
45+
}
46+
// `2` for negative mergin on calendar dropdown
47+
calendarContainer.style.top = `${refBottom - containerTop + 2}px`;
48+
calendarContainer.style.left = `${refLeft - containerLeft}px`;
49+
});
50+
};
51+
52+
/**
53+
* Registers this Flatpickr plugin.
54+
*/
55+
const register = () => {
56+
fp.loadedPlugins.push('carbonFlatpickrAppendToPlugin');
57+
};
58+
59+
return {
60+
appendTo: config.appendTo,
61+
onReady: register,
62+
onPreCalendarPosition: handlePreCalendarPosition,
63+
};
64+
};

0 commit comments

Comments
 (0)