Skip to content

wip: fix(virtual-scroll): make horizontal scrolling work in RTL #12512

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

Merged
merged 8 commits into from
Aug 23, 2018

Conversation

mmalerba
Copy link
Contributor

@mmalerba mmalerba commented Aug 3, 2018

No description provided.

@mmalerba mmalerba requested review from jelbourn and crisbeto August 3, 2018 17:16
@mmalerba mmalerba requested a review from andrewseguin as a code owner August 3, 2018 17:16
@googlebot googlebot added the cla: yes PR author has agreed to Google's Contributor License Agreement label Aug 3, 2018
@mmalerba mmalerba added the target: major This PR is targeted for the next major release label Aug 3, 2018
@@ -14,8 +15,9 @@ import {CdkVirtualForOf} from './virtual-for-of';
import {CdkVirtualScrollViewport} from './virtual-scroll-viewport';

@NgModule({
imports: [PlatformModule],
imports: [BidiModule, PlatformModule],
Copy link
Member

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 import the BidiModule since the Directionality is provided at the root.

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 it definitely needs to be in exports, so that we detect native dir="rtl" attrs as directives. I'm not sure if it needs to be in imports, I see a lot of other modules doing it though. @jelbourn do you know if having it in imports is still necessary?

Copy link
Member

Choose a reason for hiding this comment

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

It should still be in the imports; I think it only ever worked exclusively in exports unintentionally

@Input() itemSize = 50;
@Input() bufferSize = 0;
@Input() items = Array(10).fill(0).map((_, i) => i);
@Input() trackBy;
Copy link
Member

Choose a reason for hiding this comment

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

This one's missing a type.

* @param offset The offset to scroll to.
* @param behavior The ScrollBehavior to use when scrolling. Default is behavior is `auto`.
*/
scrollToOffset(offset: number, behavior: ScrollBehavior = 'auto') {
const viewportElement = this.elementRef.nativeElement;

// For a horizontal viewport in a right-to-left language we need to calculate what `scrollRight`
// would be.
offset = this.orientation == 'horizontal' && this._dir && this._dir.value == 'rtl' ?
Copy link
Member

Choose a reason for hiding this comment

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

It looks like you're repeating Math.max(0, this._totalContentSize - this._viewportSize - offset) at least in a couple of places. Consider moving it into a helper.

@@ -41,7 +41,7 @@ <h1>Angular Material Demos</h1>
</div>
</mat-toolbar>

<div #root="dir" dir="ltr" class="demo-content">
<div #root="dir" dir="rtl" class="demo-content">
Copy link
Member

Choose a reason for hiding this comment

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

Should this be reverted?

// For a horizontal viewport in a right-to-left language we need to translate along the x-axis
// in the negative direction.
const axisDirection = this.orientation == 'horizontal' && this._dir && this._dir.value == 'rtl'
? -1 : 1;
Copy link
Member

@jelbourn jelbourn Aug 7, 2018

Choose a reason for hiding this comment

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

Since you check them a couple of times, I would add _isHorizontal and _isRtl methods. Then this would just look like

// For a horizontal viewport in a right-to-left language we need to translate along the x-axis
// in the negative direction.
const axisCoefficient = this._isHorizontal && this._isRtl() ? -1 : 1;

@mmalerba mmalerba requested a review from devversion as a code owner August 9, 2018 01:13
@mmalerba mmalerba changed the title fix(virtual-scroll): make horizontal scrolling work in RTL wip: fix(virtual-scroll): make horizontal scrolling work in RTL Aug 9, 2018
@ngbot
Copy link

ngbot bot commented Aug 13, 2018

Hi @mmalerba! This PR has merge conflicts due to recent upstream merges.
Please help to unblock it by resolving these conflicts. Thanks!

@mmalerba mmalerba force-pushed the vs-rtl branch 3 times, most recently from 5fb3b9a to dd7cc5f Compare August 14, 2018 18:52
@mmalerba
Copy link
Contributor Author

@jelbourn @crisbeto PTAL, I refactored this to have the CdkVirtualScrollViewport extend CdkScrollable and take advantage of the RTL logic I already added to CdkScrollable

Copy link
Member

@crisbeto crisbeto left a comment

Choose a reason for hiding this comment

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

LGTM

will-change: transform;

// Note: We can't put `will-change: transform;` here because it causes Safari to not update the
// viewport's `scrollHeight` when the spacer's transform changes.
Copy link
Member

Choose a reason for hiding this comment

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

nit: might sound a little weird, but we could even have a unit test for this if we want to be super sure that it never gets reintroduced. E.g. the test would just be expect(getComputedStyle(element).willChange).toBe('none').

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 actually did add some unit tests that verify the scrollHeight / scrollWidth are correct after updating the spacer transform. They would fail if someone tried to add this back

@Optional() private _dir?: Directionality) {}
constructor(protected elementRef: ElementRef<HTMLElement>,
protected scrollDispatcher: ScrollDispatcher,
protected ngZone: NgZone,
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't all of the protected properties be underscored?

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 we want people to extend their own components from this if they act as a viewport. Therefore the protected properties are kind of a part of the public API and should not be underscored

@crisbeto crisbeto added pr: lgtm action: merge The PR is ready for merge by the caretaker labels Aug 22, 2018
Copy link
Member

@jelbourn jelbourn left a comment

Choose a reason for hiding this comment

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

LGTM aside from Kristiyan's comments

// For a horizontal viewport in a right-to-left language we need to translate along the x-axis
// in the negative direction.
const axisDirection = this.orientation == 'horizontal' && this.dir && this.dir.value == 'rtl'
? -1 : 1;
Copy link
Member

Choose a reason for hiding this comment

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

How about

const isHorizontal = this.orientation == 'horizontal';
const isRtl = this.dir && this.dir.value == 'rtl';
const axisDirection = isHorizontal && isRtl ? -1 : 1;

@jelbourn jelbourn merged commit 22953a9 into angular:master Aug 23, 2018
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 9, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker cla: yes PR author has agreed to Google's Contributor License Agreement target: major This PR is targeted for the next major release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants