-
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 2 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 |
---|---|---|
|
@@ -132,7 +132,7 @@ export class Popover extends AbstractPureComponent<IPopoverProps, IPopoverState> | |
private popperObserver: ResizeObserver; | ||
|
||
// Reference to the Poppper.scheduleUpdate() function, this changes every time the popper is mounted | ||
private popperUpdater: () => void; | ||
private popperScheduleUpdate: () => void; | ||
|
||
private refHandlers = { | ||
popover: (ref: HTMLElement) => { | ||
|
@@ -208,7 +208,7 @@ export class Popover extends AbstractPureComponent<IPopoverProps, IPopoverState> | |
|
||
public componentDidMount() { | ||
this.updateDarkParent(); | ||
this.popperObserver = new ResizeObserver(() => this.popperUpdater && this.popperUpdater()); | ||
this.updatePopperObserver(); | ||
} | ||
|
||
public componentWillReceiveProps(nextProps: IPopoverProps) { | ||
|
@@ -231,13 +231,16 @@ export class Popover extends AbstractPureComponent<IPopoverProps, IPopoverState> | |
this.updateDarkParent(); | ||
|
||
if (this.popoverElement instanceof HTMLElement) { | ||
// Reset the the observer to avoid the list of observed elements growing | ||
this.updatePopperObserver(); | ||
// 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() { | ||
super.componentWillUnmount(); | ||
this.popperObserver.disconnect(); | ||
} | ||
|
||
protected validateProps(props: IPopoverProps & { children?: React.ReactNode }) { | ||
|
@@ -276,10 +279,21 @@ export class Popover extends AbstractPureComponent<IPopoverProps, IPopoverState> | |
} | ||
} | ||
|
||
private updatePopperObserver() { | ||
if (this.popperObserver instanceof ResizeObserver) { | ||
this.popperObserver.disconnect(); | ||
} | ||
|
||
this.popperObserver = new ResizeObserver(() => this.popperScheduleUpdate && this.popperScheduleUpdate()); | ||
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. seems to me that calling
please revert this so it's only created once and simply invoke |
||
} | ||
|
||
private renderPopover = (popperProps: PopperChildrenProps) => { | ||
const { usePortal, interactionKind } = this.props; | ||
const { transformOrigin } = this.state; | ||
|
||
// Need to update our reference to this on every render as the target node may have changed. | ||
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. not the target node but the function instance itself! |
||
this.popperScheduleUpdate = popperProps.scheduleUpdate; | ||
|
||
const popoverHandlers: HTMLDivProps = { | ||
// always check popover clicks for dismiss class | ||
onClick: this.handlePopoverClick, | ||
|
@@ -301,8 +315,6 @@ export class Popover extends AbstractPureComponent<IPopoverProps, IPopoverState> | |
this.props.popoverClassName, | ||
); | ||
|
||
this.popperUpdater = popperProps.scheduleUpdate; | ||
|
||
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.
our convention for this check on refs is
!= null
, no need to repeat the type.