Skip to content

Commit

Permalink
Fix issues in scrollable pane (#4055)
Browse files Browse the repository at this point in the history
* Fix infinite recursion in scrollable pane

* Rush change

* Fix root cause of infinite loop

* Fixed issue with sticky headers not being added to stickyAbove

* Remove ref for stickyContainer

* Fix bad rebase
  • Loading branch information
MaxLustig authored and ThomasMichon committed Mar 1, 2018
1 parent fdab0a0 commit 5c53827
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 48 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"changes": [
{
"packageName": "office-ui-fabric-react",
"comment": "Fix infinite recursion in scrollable pane",
"type": "patch"
}
],
"packageName": "office-ui-fabric-react",
"email": "maxlus@microsoft.com"
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ export class ScrollablePaneBase extends BaseComponent<IScrollablePaneProps, {}>
};

public root: HTMLElement;
public stickyContainer: HTMLElement;
public stickyAbove: HTMLElement;
public stickyBelow: HTMLElement;
private _subscribers: Set<Function>;
Expand Down Expand Up @@ -63,22 +62,11 @@ export class ScrollablePaneBase extends BaseComponent<IScrollablePaneProps, {}>
public componentDidMount() {
this._events.on(this.root, 'scroll', this.notifySubscribers);
this._events.on(window, 'resize', this._onWindowResize);
this._async.setTimeout(() => {
this._resizeContainer();
if (this.stickyContainer.parentElement && this.root.parentElement) {
this.stickyContainer.parentElement.removeChild(this.stickyContainer);
this.root.parentElement.insertBefore(this.stickyContainer, this.root.nextSibling);
this.notifySubscribers();
}
}, 500);
}

public componentWillUnmount() {
this._events.off(this.root);
this._events.off(window);
if (this.stickyContainer.parentElement) {
this.stickyContainer.parentElement.removeChild(this.stickyContainer);
}
}

public render() {
Expand All @@ -95,13 +83,12 @@ export class ScrollablePaneBase extends BaseComponent<IScrollablePaneProps, {}>
{ ...getNativeProps(this.props, divProperties) }
ref={ this._resolveRef('root') }
className={ classNames.root }
data-is-scrollable={ true }
>
<div ref={ this._resolveRef('stickyContainer') } className={ classNames.stickyContainer }>
<div ref={ this._resolveRef('stickyAbove') } className={ classNames.stickyAbove } />
<div ref={ this._resolveRef('stickyBelow') } className={ classNames.stickyBelow } />
<div ref={ this._resolveRef('stickyAbove') } className={ classNames.stickyAbove } />
<div ref={ this._resolveRef('stickyBelow') } className={ classNames.stickyBelow } />
<div data-is-scrollable={ true }>
{ this.props.children }
</div>
{ this.props.children }
</div>
);
}
Expand Down Expand Up @@ -171,7 +158,6 @@ export class ScrollablePaneBase extends BaseComponent<IScrollablePaneProps, {}>
}
}, 1);
}
this.notifySubscribers();
this._setPlaceholderHeights(stickyList);
}
}
Expand All @@ -186,26 +172,12 @@ export class ScrollablePaneBase extends BaseComponent<IScrollablePaneProps, {}>

private _onWindowResize() {
this._async.setTimeout(() => {
this._resizeContainer();
this.notifySubscribers();
this._setPlaceholderHeights(this._stickyAbove);
this._setPlaceholderHeights(this._stickyBelow);
}, 5);
}

private _resizeContainer() {
const { stickyContainer, root } = this;
const { borderTopWidth, borderLeftWidth } = getComputedStyle(root);
stickyContainer.style.height = root.clientHeight + 'px';
stickyContainer.style.width = root.clientWidth + 'px';
if (borderTopWidth) {
stickyContainer.style.top = root.offsetTop + parseInt(borderTopWidth, 10) + 'px';
}
if (borderLeftWidth) {
stickyContainer.style.left = root.offsetLeft + parseInt(borderLeftWidth, 10) + 'px';
}
}

@autobind
private _setPlaceholderHeights(stickies: Set<Sticky>) {
stickies.forEach((sticky, idx) => {
Expand Down Expand Up @@ -249,4 +221,4 @@ export class ScrollablePaneBase extends BaseComponent<IScrollablePaneProps, {}>
}
return offset;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
@import '../../common/common';

.root {
overflow-y: auto;
max-height: inherit;
height: inherit;
-webkit-overflow-scrolling: touch;
}

.stickyAbove,
.stickyBelow {
position: absolute;
pointer-events: auto;
width: 100%;
z-index: 1;
}

.stickyAbove {
top: 0;

@include high-contrast {
border-bottom: 1px solid WindowText;
}
}

.stickyBelow {
bottom: 0;

@include high-contrast {
border-top: 1px solid WindowText;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,6 @@ export const getStyles = (
},
className
],
stickyContainer: [
{
overflow: 'hidden',
position: 'absolute',
pointerEvents: 'none',

}
],
stickyAbove: [
{
top: 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,6 @@ export interface IScrollablePaneStyles {
* Style set for the root element.
*/
root: IStyle;
/**
* Style set for the stickyContainer element.
*/
stickyContainer: IStyle;
/**
* Style set for the stickyAbove element.
*/
Expand All @@ -65,4 +61,4 @@ export interface IScrollablePaneStyles {
* Style set for the stickyAbove element.
*/
stickyBelow: IStyle;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,8 @@ export class Sticky extends BaseComponent<IStickyProps, IStickyState> {
const canStickyFooter = stickyPosition === StickyPositionType.Both || stickyPosition === StickyPositionType.Footer;

this.setState({
isStickyTop: canStickyHeader && ((!isStickyTop && top <= headerBound.bottom) || (isStickyTop && bottom < headerBound.bottom)),
isStickyBottom: canStickyFooter && ((!isStickyBottom && bottom >= footerBound.top) || (isStickyBottom && top > footerBound.top))
isStickyTop: canStickyHeader && ((top <= headerBound.bottom) || (isStickyTop && bottom < headerBound.bottom)),
isStickyBottom: canStickyFooter && ((bottom >= footerBound.top) || (isStickyBottom && top > footerBound.top))
});
}

Expand Down

0 comments on commit 5c53827

Please sign in to comment.