Skip to content

Commit

Permalink
Upgrade react-popper/popperjs to v2 (#549)
Browse files Browse the repository at this point in the history
  • Loading branch information
ericgio committed Oct 30, 2021
1 parent 5ff2cf8 commit 9449e5b
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 117 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,15 @@
},
"dependencies": {
"@babel/runtime": "^7.14.6",
"@popperjs/core": "^2.10.2",
"@restart/hooks": "^0.4.0",
"classnames": "^2.2.0",
"fast-deep-equal": "^3.1.1",
"invariant": "^2.2.1",
"lodash.debounce": "^4.0.8",
"prop-types": "^15.5.8",
"react-overlays": "^5.1.0",
"react-popper": "^1.0.0",
"react-popper": "^2.2.5",
"scroll-into-view-if-needed": "^2.2.20",
"warning": "^4.0.1"
},
Expand Down
34 changes: 33 additions & 1 deletion src/__tests__/components/Overlay.test.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import React from 'react';

import Menu from '../../components/Menu';
import Overlay, { getPlacement } from '../../components/Overlay';
import Overlay, {
Align,
getModifiers,
getPlacement,
} from '../../components/Overlay';

import { getMenu, render, screen, waitFor } from '../helpers';

Expand Down Expand Up @@ -60,3 +64,31 @@ describe('Overlay placement', () => {
});
});
});

describe('Overlay modifiers', () => {
it('sets the `flip` modifier', () => {
const props = { align: Align.JUSTIFY, flip: false };
const selector = ({ name }) => name === 'flip';

expect(getModifiers(props).find(selector).enabled).toBe(false);

props.flip = true;
expect(getModifiers(props).find(selector).enabled).toBe(true);
});

it('conditionally adds the `setWidth` modifier', () => {
const props = { align: Align.JUSTIFY, flip: false };

const modifiers = getModifiers(props);
expect(modifiers).toHaveLength(2);
expect(
modifiers.find(({ name }) => name === 'setPopperWidth')
).toBeTruthy();

props.align = Align.LEFT;
expect(getModifiers(props)).toHaveLength(1);

props.align = Align.RIGHT;
expect(getModifiers(props)).toHaveLength(1);
});
});
2 changes: 1 addition & 1 deletion src/components/Menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export interface MenuProps extends HTMLProps<HTMLDivElement> {
emptyLabel?: ReactNode;
innerRef: Ref<HTMLDivElement>;
inputHeight: number;
scheduleUpdate: () => void;
scheduleUpdate: (() => void) | null;
maxHeight?: string;
text: string;
}
Expand Down
92 changes: 45 additions & 47 deletions src/components/Overlay.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Data, Placement } from 'popper.js';
import type { ModifierArguments, Placement, Options } from '@popperjs/core';
import PropTypes from 'prop-types';
import React, { CSSProperties, ReactNode, Ref } from 'react';
import { Popper, PopperProps } from 'react-popper';
import { CSSProperties, ReactElement, Ref, useState } from 'react';
import { usePopper } from 'react-popper';

import { noop } from '../utils';

Expand Down Expand Up @@ -51,48 +51,43 @@ export interface OverlayRenderProps {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
innerRef: Ref<any>;
inputHeight: number;
scheduleUpdate: () => void;
scheduleUpdate: (() => void) | null;
style: CSSProperties;
}

export interface OverlayProps {
align: Align;
children: (props: OverlayRenderProps) => ReactNode;
children: (props: OverlayRenderProps) => ReactElement | null;
dropup: boolean;
flip: boolean;
isMenuShown: boolean;
positionFixed: boolean;
referenceElement?: HTMLElement;
}

function getModifiers(props: OverlayProps): PopperProps['modifiers'] {
return {
computeStyles: {
enabled: true,
fn: (data: Data) => {
return {
...data,
styles: {
...data.styles,
// Use the following condition instead of `align === 'justify'`
// since it allows the component to fall back to justifying the
// menu width if `align` is undefined.
width:
props.align !== Align.RIGHT && props.align !== Align.LEFT
? // Set the popper width to match the target width.
`${data.offsets.reference.width}px`
: data.styles.width,
},
};
},
},
flip: {
enabled: props.flip,
},
preventOverflow: {
escapeWithReference: true,
const setPopperWidth = {
enabled: true,
fn: (data: ModifierArguments<Options>) => {
// eslint-disable-next-line no-param-reassign
data.state.styles.popper.width = `${data.state.rects.reference.width}px`;
},
name: 'setPopperWidth',
phase: 'write',
};

export function getModifiers(props: Pick<OverlayProps, 'align' | 'flip'>) {
const modifiers = [
{
enabled: !!props.flip,
name: 'flip',
},
};
];

if (props.align !== Align.RIGHT && props.align !== Align.LEFT) {
modifiers.push(setPopperWidth);
}

return modifiers;
}

export function getPlacement(
Expand All @@ -105,25 +100,28 @@ export function getPlacement(
}

const Overlay = ({ referenceElement, ...props }: OverlayProps) => {
const [popperElement, attachRef] = useState<HTMLElement>();
const { attributes, styles, forceUpdate } = usePopper(
referenceElement,
popperElement,
{
modifiers: getModifiers(props),
placement: getPlacement(props),
strategy: props.positionFixed ? 'fixed' : 'absolute',
}
);

if (!props.isMenuShown) {
return null;
}

return (
<Popper
modifiers={getModifiers(props)}
placement={getPlacement(props)}
positionFixed={props.positionFixed}
referenceElement={referenceElement}>
{({ arrowProps, ref, outOfBoundaries, ...popperProps }) =>
props.children({
...popperProps,
innerRef: ref,
inputHeight: referenceElement ? referenceElement.offsetHeight : 0,
})
}
</Popper>
);
return props.children({
...attributes.popper,
innerRef: attachRef,
inputHeight: referenceElement?.offsetHeight || 0,
scheduleUpdate: forceUpdate,
style: styles.popper,
});
};

Overlay.propTypes = propTypes;
Expand Down
83 changes: 16 additions & 67 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -978,7 +978,7 @@
core-js-pure "^3.16.0"
regenerator-runtime "^0.13.4"

"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.8", "@babel/runtime@^7.14.0", "@babel/runtime@^7.14.6", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2":
"@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.8", "@babel/runtime@^7.14.0", "@babel/runtime@^7.14.6", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2":
version "7.15.4"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.15.4.tgz#fd17d16bfdf878e6dd02d19753a39fa8a8d9c84a"
integrity sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==
Expand Down Expand Up @@ -1076,14 +1076,6 @@
resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz#87de7af9c231826fdd68ac7258f77c429e0e5fcf"
integrity sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==

"@hypnosphi/create-react-context@^0.3.1":
version "0.3.1"
resolved "https://registry.yarnpkg.com/@hypnosphi/create-react-context/-/create-react-context-0.3.1.tgz#f8bfebdc7665f5d426cba3753e0e9c7d3154d7c6"
integrity sha512-V1klUed202XahrWJLLOT3EXNeCpFHCcJntdFGI15ntCwau+jfT386w7OFTMaCqOgXUH1fa0w/I1oZs+i/Rfr0A==
dependencies:
gud "^1.0.0"
warning "^4.0.3"

"@istanbuljs/load-nyc-config@^1.0.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced"
Expand Down Expand Up @@ -1306,7 +1298,7 @@
"@nodelib/fs.scandir" "2.1.5"
fastq "^1.6.0"

"@popperjs/core@^2.8.6":
"@popperjs/core@^2.10.2", "@popperjs/core@^2.8.6":
version "2.10.2"
resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.10.2.tgz#0798c03351f0dea1a5a4cabddf26a55a7cbee590"
integrity sha512-IXf3XA7+XyN7CP9gGh/XB0UxVMlvARGEgGXLubFICsUMGz6Q+DU+i4gGlpOxTjKvXjkJDJC8YdqdKkDj9qZHEQ==
Expand Down Expand Up @@ -3287,18 +3279,6 @@ dedent@^0.7.0:
resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c"
integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=

deep-equal@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a"
integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==
dependencies:
is-arguments "^1.0.4"
is-date-object "^1.0.1"
is-regex "^1.0.4"
object-is "^1.0.1"
object-keys "^1.1.1"
regexp.prototype.flags "^1.2.0"

deep-is@^0.1.3, deep-is@~0.1.3:
version "0.1.4"
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
Expand Down Expand Up @@ -4344,11 +4324,6 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a"
integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==

gud@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/gud/-/gud-1.0.0.tgz#a489581b17e6a70beca9abe3ae57de7a499852c0"
integrity sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw==

gzip-size@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-5.1.1.tgz#cb9bee692f87c0612b232840a873904e4c135274"
Expand Down Expand Up @@ -4635,14 +4610,6 @@ is-accessor-descriptor@^1.0.0:
dependencies:
kind-of "^6.0.0"

is-arguments@^1.0.4:
version "1.1.1"
resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b"
integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==
dependencies:
call-bind "^1.0.2"
has-tostringtag "^1.0.0"

is-arrayish@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
Expand Down Expand Up @@ -4853,7 +4820,7 @@ is-reference@^1.2.1:
dependencies:
"@types/estree" "*"

is-regex@^1.0.4, is-regex@^1.1.4:
is-regex@^1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958"
integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==
Expand Down Expand Up @@ -6146,14 +6113,6 @@ object-inspect@^1.11.0, object-inspect@^1.9.0:
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.11.0.tgz#9dceb146cedd4148a0d9e51ab88d34cf509922b1"
integrity sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==

object-is@^1.0.1:
version "1.1.5"
resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac"
integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==
dependencies:
call-bind "^1.0.2"
define-properties "^1.1.3"

object-keys@^1.0.12, object-keys@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
Expand Down Expand Up @@ -6500,11 +6459,6 @@ please-upgrade-node@^3.2.0:
dependencies:
semver-compare "^1.0.0"

popper.js@^1.14.4:
version "1.16.1"
resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b"
integrity sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==

posix-character-classes@^0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab"
Expand Down Expand Up @@ -6631,7 +6585,7 @@ prop-types-extra@^1.1.0:
react-is "^16.3.2"
warning "^4.0.0"

prop-types@^15.0.0, prop-types@^15.5.8, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2:
prop-types@^15.0.0, prop-types@^15.5.8, prop-types@^15.6.2, prop-types@^15.7.2:
version "15.7.2"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
Expand Down Expand Up @@ -6777,6 +6731,11 @@ react-dom@^17.0.2:
object-assign "^4.1.1"
scheduler "^0.20.2"

react-fast-compare@^3.0.1:
version "3.2.0"
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.0.tgz#641a9da81b6a6320f270e89724fb45a0b39e43bb"
integrity sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==

"react-is@^16.12.0 || ^17.0.0", react-is@^17.0.1, react-is@^17.0.2:
version "17.0.2"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
Expand Down Expand Up @@ -6806,17 +6765,12 @@ react-overlays@^5.1.0, react-overlays@^5.1.1:
uncontrollable "^7.2.1"
warning "^4.0.3"

react-popper@^1.0.0:
version "1.3.11"
resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-1.3.11.tgz#a2cc3f0a67b75b66cfa62d2c409f9dd1fcc71ffd"
integrity sha512-VSA/bS+pSndSF2fiasHK/PTEEAyOpX60+H5EPAjoArr8JGm+oihu4UbrqcEBpQibJxBVCpYyjAX7abJ+7DoYVg==
dependencies:
"@babel/runtime" "^7.1.2"
"@hypnosphi/create-react-context" "^0.3.1"
deep-equal "^1.1.1"
popper.js "^1.14.4"
prop-types "^15.6.1"
typed-styles "^0.0.7"
react-popper@^2.2.5:
version "2.2.5"
resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-2.2.5.tgz#1214ef3cec86330a171671a4fbcbeeb65ee58e96"
integrity sha512-kxGkS80eQGtLl18+uig1UIf9MKixFSyPxglsgLBxlYnyDf65BiY9B3nZSc6C9XUNDgStROB0fMQlTEz1KxGddw==
dependencies:
react-fast-compare "^3.0.1"
warning "^4.0.2"

react-shallow-renderer@^16.13.1:
Expand Down Expand Up @@ -6950,7 +6904,7 @@ regex-not@^1.0.0, regex-not@^1.0.2:
extend-shallow "^3.0.2"
safe-regex "^1.1.0"

regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.3.1:
regexp.prototype.flags@^1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26"
integrity sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA==
Expand Down Expand Up @@ -7988,11 +7942,6 @@ type-fest@^0.21.3:
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37"
integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==

typed-styles@^0.0.7:
version "0.0.7"
resolved "https://registry.yarnpkg.com/typed-styles/-/typed-styles-0.0.7.tgz#93392a008794c4595119ff62dde6809dbc40a3d9"
integrity sha512-pzP0PWoZUhsECYjABgCGQlRGL1n7tOHsgwYv3oIiEpJwGhFTuty/YNeduxQYzXXa3Ge5BdT6sHYIQYpl4uJ+5Q==

typedarray-to-buffer@^3.1.5:
version "3.1.5"
resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080"
Expand Down

0 comments on commit 9449e5b

Please sign in to comment.