-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Core] Rerender popovers when content resizes #2718
Changes from 5 commits
2b4c3c8
15ae92c
6394932
94078b7
3788f2a
ca0de37
fdfd8a3
6510801
a9838d8
53d42af
294e219
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,7 @@ import classNames from "classnames"; | |
import { ModifierFn } from "popper.js"; | ||
import * as React from "react"; | ||
import { Manager, Popper, PopperChildrenProps, Reference, ReferenceChildrenProps } from "react-popper"; | ||
import ResizeObserver from "resize-observer-polyfill"; | ||
|
||
import { AbstractPureComponent } from "../../common/abstractPureComponent"; | ||
import * as Classes from "../../common/classes"; | ||
|
@@ -127,6 +128,12 @@ export class Popover extends AbstractPureComponent<IPopoverProps, IPopoverState> | |
// element on the same page. | ||
private lostFocusOnSamePage = true; | ||
|
||
// ResizeObserver instance to monitor for content size changes on the popover | ||
private popperObserver: ResizeObserver; | ||
|
||
// Reference to the Poppper.scheduleUpdate() function, this changes every time the popper is mounted | ||
private popperUpdater: () => void; | ||
|
||
private refHandlers = { | ||
popover: (ref: HTMLElement) => { | ||
this.popoverElement = ref; | ||
|
@@ -201,6 +208,7 @@ export class Popover extends AbstractPureComponent<IPopoverProps, IPopoverState> | |
|
||
public componentDidMount() { | ||
this.updateDarkParent(); | ||
this.popperObserver = new ResizeObserver(() => this.popperUpdater && this.popperUpdater()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add |
||
} | ||
|
||
public componentWillReceiveProps(nextProps: IPopoverProps) { | ||
|
@@ -221,6 +229,11 @@ export class Popover extends AbstractPureComponent<IPopoverProps, IPopoverState> | |
|
||
public componentDidUpdate() { | ||
this.updateDarkParent(); | ||
|
||
if (this.popoverElement instanceof HTMLElement) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. our convention for this check on refs is |
||
// Ensure our observer has an up-to-date reference to popoverElement | ||
this.popperObserver.observe(this.popoverElement); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. clear the observer before observing new elements. this will quickly result in a long list of watched elements, many of which may not be in the DOM. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @giladgray I've opted to just recreate the observer completely, does this seem reasonable you? |
||
} | ||
} | ||
|
||
public componentWillUnmount() { | ||
|
@@ -288,6 +301,8 @@ export class Popover extends AbstractPureComponent<IPopoverProps, IPopoverState> | |
this.props.popoverClassName, | ||
); | ||
|
||
this.popperUpdater = popperProps.scheduleUpdate; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do this as the first line in this method rather than breaking up this rendering logic, with a |
||
|
||
return ( | ||
<div className={Classes.TRANSITION_CONTAINER} ref={popperProps.ref} style={popperProps.style}> | ||
<div className={popoverClasses} style={{ transformOrigin }} {...popoverHandlers}> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
popperScheduleUpdate
?schedulePopperUpdate
? make the name obvious.