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

fix(modal): adjust modal background to avoid shifting #2508

Closed

Conversation

ymeine
Copy link
Contributor

@ymeine ymeine commented Jul 9, 2018

Shifting potentially occurs when a scrollbar present on the container disappears once the modal opens.

The solution is taken from Bootstrap itself.

Tests are missing but require an e2e testing application.

fixes #641

Copy link
Member

@maxokorokov maxokorokov left a comment

Choose a reason for hiding this comment

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

LGTM, a couple of minor comments.

It's a shame to do a couple of style recalcs and a layout, but it's what bootstrap does indeed. Can't find a better solution either.

@@ -0,0 +1,46 @@
import {Injectable, Inject} from '@angular/core';
import {DOCUMENT} from '@angular/platform-browser';
Copy link
Member

Choose a reason for hiding this comment

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

@angular/common, this one should be deprecated

import {Injectable, Inject} from '@angular/core';
import {DOCUMENT} from '@angular/platform-browser';

import {isDefined} from './util';
Copy link
Member

Choose a reason for hiding this comment

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

unused

return this.adjustBody(width);
}

adjustBody(width: number) {
Copy link
Member

Choose a reason for hiding this comment

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

adjustBody, isPresent, getWidthprivate _adjustBody, private _isPresent, private _getWidth

private _adjustBody(width: number) {
const {body} = this._document;
const userSetPadding = body.style.paddingRight;
const paddingAmount = parseFloat(window.getComputedStyle(body)['padding-right']);
Copy link
Member

Choose a reason for hiding this comment

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

Hmm, I was just fixing SSR for the carousel and realised that window might break it too...

Copy link
Member

Choose a reason for hiding this comment

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

Regardless, I don't think the fix for this should be a part of this PR

@maxokorokov maxokorokov added this to the 3.0.0 milestone Jul 19, 2018
@@ -45,6 +46,7 @@ export class NgbModalStack {
let windowCmptRef: ComponentRef<NgbModalWindow> = this._attachWindowComponent(containerEl, contentRef);
let ngbModalRef: NgbModalRef = new NgbModalRef(windowCmptRef, contentRef, backdropCmptRef, options.beforeDismiss);

ngbModalRef.result.then(revertPaddingForScrollBar, revertPaddingForScrollBar);

Choose a reason for hiding this comment

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

Maybe write as ngbModalRef.result.finally(revertPaddingForScrollBar) ?

Choose a reason for hiding this comment

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

export class ScrollBar {
constructor(@Inject(DOCUMENT) private _document) {}

compensate() {

Choose a reason for hiding this comment

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

Could you please add explicit return type so it is easier to read? We've got a return statement in this function but it is not immediately clear what is returned.

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, I'll add it along with documentation about it



@Injectable()
export class ScrollBar {

Choose a reason for hiding this comment

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

Could you add a bit of JS doc to this class with a brief description on how it works, what it can be used for etc.?

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, since I finally made it as a separate utility it makes sense

}

private _adjustBody(width: number) {
const {body} = this._document;

Choose a reason for hiding this comment

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

Wouldn't explicit const body = this._document.body; be more readable here?

Copy link
Member

Choose a reason for hiding this comment

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

Same on line 33, if you want to do something with it. But it's just a question of style to me...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well, destructuring is standard feature, used elsewhere in this project, and avoids repetition. Then I could say it makes more sense when destructuring pure data objects (like parameters). I don't know 😛

return rect.left + rect.right < window.innerWidth;
}

private _getWidth(): number {

Choose a reason for hiding this comment

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

This could be called only once, if I'm not mistaken? (I mean, we don't have to call it in each and every compensate() call.

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 don't know... could there be any situation where the width of the scrollbar would change (with custom styling then) throughout the application lifetime? (and would we support that?)

If not, I can cache the result.

Choose a reason for hiding this comment

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

Let's leave it as-is for now.


compensate() {
if (!this._isPresent()) {
return () => {};

Choose a reason for hiding this comment

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

nit: this is always the same, you could extract it as const noop = () => {};

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure I will do

@pkozlowski-opensource
Copy link
Member

@ymeine thnx for this PR, it fixes a long-lasting bug!

I've added few comments in the code - I would mostly like to see more docs (or at least types!).

const document = this._document;
const {body} = document;

const measurer = document.createElement('div');
Copy link
Member

Choose a reason for hiding this comment

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

By the way just realised that this is a lot more confusing to me. Unclear if it's a global document (wrong) or a local one.

(nitpicking, feel free to ignore)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah... again that's a matter of style. And here the context is not far to check. I made like that to avoid repetition, but also to write in a more familiar style - which is exactly what is making you confused ^^

Choose a reason for hiding this comment

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

If you ask me I would:

  • drop the document const (and use this._document everywhere)
  • have const documentBody = this._document.createElement('div');

Copy link
Member

Choose a reason for hiding this comment

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

I see the word 'document' 4 times in the snippet above, so I won't agree with the repetition argument :)

vs

const body = this._document.body; // or const {body} = this._document;
const measurer = this._document.createElement('div')

I can read your version fine too though

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 was referring to repetition of property access mainly. But anyways this case is too small to have real benefit. I'll make the change.

Shifting potentially occurs when a scrollbar present on the container disappears once the modal opens.

The solution is taken from Bootstrap itself.

Remaining:

- tests
@ymeine ymeine force-pushed the fix/641-modal-bgcontent-shifting branch from e5f0da1 to 4cbea01 Compare July 20, 2018 13:52
pkozlowski-opensource pushed a commit that referenced this pull request Jul 27, 2018
Shifting potentially occurs when a scrollbar present on the container disappears once the modal opens.
The solution is taken from Bootstrap itself.

Fixes #641
Closes #2508
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Modal: content shifts to the right
3 participants