Skip to content
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

Add options to hide MultiGrid top-right and bottom-left grid scrollbars but still make the scroll events work on those grids #1040

Merged
merged 10 commits into from May 15, 2018
Merged
2 changes: 2 additions & 0 deletions docs/MultiGrid.md
Expand Up @@ -24,6 +24,8 @@ Some properties (eg `columnCount`, `rowCount`) are adjusted slightly to supporte
| styleBottomRightGrid | object | | Optional custom inline style to attach to bottom-right `Grid` element. |
| styleTopLeftGrid | object | | Optional custom inline style to attach to top-left `Grid` element. |
| styleTopRightGrid | object | | Optional custom inline style to attach to top-right `Grid` element. |
| hideTopRightGridScrollbar | boolean | | Optional hides top-right `Grid` scrollbar by adding an additional wrapper. Only useful if `enableFixedRowScroll` is set to `true` |
| hideBottomLeftGridScrollbar | boolean | | Optional hides bottom-left `Grid` scrollbar by adding an additional wrapper. Only useful if `enableFixedColumnScroll` is set to `true` |

### Public Methods

Expand Down
2 changes: 2 additions & 0 deletions source/MultiGrid/MultiGrid.example.js
Expand Up @@ -100,6 +100,8 @@ export default class MultiGridExample extends React.PureComponent {
styleTopLeftGrid={STYLE_TOP_LEFT_GRID}
styleTopRightGrid={STYLE_TOP_RIGHT_GRID}
width={width}
hideTopRightGridScrollbar
hideBottomLeftGridScrollbar
/>
)}
</AutoSizer>
Expand Down
51 changes: 51 additions & 0 deletions source/MultiGrid/MultiGrid.jest.js
Expand Up @@ -171,6 +171,57 @@ describe('MultiGrid', () => {
});
});

describe('hideTopRightGridScrollbar, hideBottomLeftGridScrollbar should hide the scrollbars', () => {
function getScrollbarSize20() {
return 20;
}
it('should add scroll wrappers to hide scroll bar when configured for fixed columns and rows with scroll interaction', () => {
const rendered = findDOMNode(
render(
getMarkup({
enableFixedColumnScroll: true,
enableFixedRowScroll: true,
fixedColumnCount: 1,
fixedRowCount: 1,
hideTopRightGridScrollbar: true,
hideBottomLeftGridScrollbar: true,
getScrollbarSize: getScrollbarSize20,
}),
),
);
let wrappers = rendered.querySelectorAll('.TopRightGrid_ScrollWrapper');
expect(wrappers.length).toEqual(1);
const [topRightWrapper] = wrappers;
wrappers = rendered.querySelectorAll('.BottomLeftGrid_ScrollWrapper');
expect(wrappers.length).toEqual(1);
const [bottomLeftWrapper] = wrappers;

expect(topRightWrapper.style.getPropertyValue('overflow-x')).toEqual('hidden');
expect(topRightWrapper.style.getPropertyValue('overflow-y')).toEqual('hidden');
expect(bottomLeftWrapper.style.getPropertyValue('overflow-x')).toEqual('hidden');
expect(bottomLeftWrapper.style.getPropertyValue('overflow-y')).toEqual('hidden');

expect(topRightWrapper.style.getPropertyValue('height')).toEqual('20px');
expect(bottomLeftWrapper.style.getPropertyValue('height')).toEqual('280px');
expect(topRightWrapper.style.getPropertyValue('width')).toEqual('350px');
expect(bottomLeftWrapper.style.getPropertyValue('width')).toEqual('50px');

const grids = rendered.querySelectorAll('.ReactVirtualized__Grid');
expect(grids.length).toEqual(4);
const [topLeft, topRight, bottomLeft, bottomRight] = grids;
expect(topLeft.style.getPropertyValue('overflow-x')).toEqual('hidden');
expect(topLeft.style.getPropertyValue('overflow-y')).toEqual('hidden');
expect(topRight.style.getPropertyValue('overflow-x')).toEqual('auto');
expect(topRight.style.getPropertyValue('overflow-y')).toEqual('hidden');
expect(topRight.style.getPropertyValue('height')).toEqual('40px');
expect(bottomLeft.style.getPropertyValue('overflow-x')).toEqual('hidden');
expect(bottomLeft.style.getPropertyValue('overflow-y')).toEqual('auto');
expect(bottomLeft.style.getPropertyValue('width')).toEqual('70px');
expect(bottomRight.style.getPropertyValue('overflow-x')).toEqual('auto');
expect(bottomRight.style.getPropertyValue('overflow-y')).toEqual('auto');
});
});

describe('#recomputeGridSize', () => {
it('should clear calculated cached styles in recomputeGridSize', () => {
let fixedRowHeight = 75;
Expand Down
77 changes: 67 additions & 10 deletions source/MultiGrid/MultiGrid.js
Expand Up @@ -30,6 +30,8 @@ class MultiGrid extends React.PureComponent {
styleBottomRightGrid: PropTypes.object.isRequired,
styleTopLeftGrid: PropTypes.object.isRequired,
styleTopRightGrid: PropTypes.object.isRequired,
hideTopRightGridScrollbar: PropTypes.bool,
hideBottomLeftGridScrollbar: PropTypes.bool,
};

static defaultProps = {
Expand All @@ -48,6 +50,8 @@ class MultiGrid extends React.PureComponent {
styleBottomRightGrid: {},
styleTopLeftGrid: {},
styleTopRightGrid: {},
hideTopRightGridScrollbar: false,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I don't think there is a need to specify defaultProps for these. Since it would be undefined if not passed in. Which is a falsey value

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added because there was an existing pattern for enableFixedColumnScroll and enableFixedRowScroll. So followed it.

hideBottomLeftGridScrollbar: false,
};

state = {
Expand Down Expand Up @@ -611,32 +615,54 @@ class MultiGrid extends React.PureComponent {
fixedColumnCount,
fixedRowCount,
rowCount,
scrollTop,
hideBottomLeftGridScrollbar,
} = props;
const {showVerticalScrollbar} = this.state;

if (!fixedColumnCount) {
return null;
}

const additionalRowCount = showVerticalScrollbar ? 1 : 0;
const additionalRowCount = showVerticalScrollbar ? 1 : 0,
height = this._getBottomGridHeight(props),
width = this._getLeftGridWidth(props),
scrollbarSize = this.state.showVerticalScrollbar ? this.state.scrollbarSize : 0,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

scrollbarSize is now in state.instanceProps.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think state structure change in Grid but not in MutliGrid so it is working fine.
Also, I ran yarn lint and it seem to be all good too.

So we are good here?

gridWidth = hideBottomLeftGridScrollbar ? width + scrollbarSize : width;

return (
const bottomLeftGrid = (
<Grid
{...props}
cellRenderer={this._cellRendererBottomLeftGrid}
className={this.props.classNameBottomLeftGrid}
columnCount={fixedColumnCount}
deferredMeasurementCache={this._deferredMeasurementCacheBottomLeftGrid}
height={this._getBottomGridHeight(props)}
height={height}
onScroll={enableFixedColumnScroll ? this._onScrollTop : undefined}
ref={this._bottomLeftGridRef}
rowCount={Math.max(0, rowCount - fixedRowCount) + additionalRowCount}
rowHeight={this._rowHeightBottomGrid}
style={this._bottomLeftGridStyle}
tabIndex={null}
width={this._getLeftGridWidth(props)}
width={gridWidth}
/>
);

if (hideBottomLeftGridScrollbar) {
return (
<div
className="BottomLeftGrid_ScrollWrapper"
style={{
...this._bottomLeftGridStyle,
height,
width,
overflowY: 'hidden',
}}>
{bottomLeftGrid}
</div>
);
}
return bottomLeftGrid;
}

_renderBottomRightGrid(props) {
Expand Down Expand Up @@ -700,16 +726,31 @@ class MultiGrid extends React.PureComponent {
fixedColumnCount,
fixedRowCount,
scrollLeft,
hideTopRightGridScrollbar,
} = props;
const {showHorizontalScrollbar} = this.state;
const {showHorizontalScrollbar, scrollbarSize} = this.state;

if (!fixedRowCount) {
return null;
}

const additionalColumnCount = showHorizontalScrollbar ? 1 : 0;
const additionalColumnCount = showHorizontalScrollbar ? 1 : 0,
height = this._getTopGridHeight(props),
width = this._getRightGridWidth(props),
additionalHeight = showHorizontalScrollbar ? scrollbarSize : 0;

return (
let gridHeight = height,
style = this._topRightGridStyle;

if (hideTopRightGridScrollbar) {
gridHeight = height + additionalHeight;
style = {
...this._topRightGridStyle,
left: 0,
};
}

const topRightGrid = (
<Grid
{...props}
cellRenderer={this._cellRendererTopRightGrid}
Expand All @@ -719,16 +760,32 @@ class MultiGrid extends React.PureComponent {
}
columnWidth={this._columnWidthRightGrid}
deferredMeasurementCache={this._deferredMeasurementCacheTopRightGrid}
height={this._getTopGridHeight(props)}
height={gridHeight}
onScroll={enableFixedRowScroll ? this._onScrollLeft : undefined}
ref={this._topRightGridRef}
rowCount={fixedRowCount}
scrollLeft={scrollLeft}
style={this._topRightGridStyle}
style={style}
tabIndex={null}
width={this._getRightGridWidth(props)}
width={width}
/>
);

if (hideTopRightGridScrollbar) {
return (
<div
className="TopRightGrid_ScrollWrapper"
style={{
...this._topRightGridStyle,
height,
width,
overflowX: 'hidden',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you need to wrap it in another div

If you need to. you can just modify this._topRightGridStyle

this._topRightGridStyle = {
   ...this._topRightGridStyle,
   height,
   width, 
   overflowX: 'hidden'
}

Unless Im misunderstanding something :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. We need this extra wrapper so we can hide the scrollbar with a hack.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wuweiweiwu , are you waiting for some change here?

}}>
{topRightGrid}
</div>
);
}
return topRightGrid;
}

_rowHeightBottomGrid = ({index}) => {
Expand Down