-
Notifications
You must be signed in to change notification settings - Fork 6.8k
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
feat(tabs): add swipe events #6294
Conversation
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.
@amcdnl trying this out, it seems like this breaks the ability to scroll the tab content by dragging on mobile
(I just tried on the device emulator in Chrome)
@@ -54,3 +54,12 @@ export interface HammerManager { | |||
off(events: string, handler?: Function): void; | |||
on(events: string, handler: Function): void; | |||
} | |||
|
|||
/** @docs-private */ | |||
export interface HammerEvent { |
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.
Why introduce this instead of using the existing HammerInput
type?
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.
Did not realize those were the same, I'll consolidate.
src/lib/tabs/tab-group.ts
Outdated
_bodyContentSwiped(event: HammerEvent): void { | ||
if(this.selectedIndex === null) this.selectedIndex = 0; | ||
if(this.selectedIndex !== 0 && event.type === 'swiperight') { | ||
this.selectedIndex = this._findNextTabByIndex(this.selectedIndex, 'left'); |
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.
No need to send left
or right
instead of directly sending the delta
src/lib/tabs/tab-body.html
Outdated
@@ -1,4 +1,6 @@ | |||
<div class="mat-tab-body-content" #content | |||
(swipeleft)="onSwipe.emit($event)" | |||
(swiperight)="onSwipe.emit($event)" |
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.
Not just (swipe)
?
src/lib/tabs/tab-group.ts
Outdated
if(this.selectedIndex !== 0 && event.type === 'swiperight') { | ||
this.selectedIndex = this._findNextTabByIndex(this.selectedIndex, 'left'); | ||
} else if(this.selectedIndex < this._tabs.length && event.type === 'swipeleft') { | ||
this.selectedIndex = this._findNextTabByIndex(this.selectedIndex, 'right'); |
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.
Are left
and right
reversed in RTL?
src/lib/tabs/tab-header.html
Outdated
@@ -7,6 +7,8 @@ | |||
</div> | |||
|
|||
<div class="mat-tab-label-container" #tabListContainer | |||
(swipeleft)="_handleSwipe($event)" | |||
(swiperight)="_handleSwipe($event)" |
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.
This captures the swipe
gesture specifically, but it feels like the header would need to capture dragging as well (which I think Hammer captures under panmove
)
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.
Good idea. It has a drag
property I listen to.
src/lib/tabs/tab-group.ts
Outdated
|
||
/** Body content was swiped left/right */ | ||
_bodyContentSwiped(event: HammerEvent): void { | ||
if(this.selectedIndex === null) this.selectedIndex = 0; |
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.
Braces are always required
src/lib/tabs/tab-group.ts
Outdated
const tabsArray = this._tabs.toArray(); | ||
const nextIdx = direction === 'right' ? index + 1 : index - 1; | ||
|
||
if(nextIdx < tabsArray.length && nextIdx >= 0) { |
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.
Space between if
and paren (here and elsewhere)
src/lib/tabs/tab-group.ts
Outdated
@@ -275,4 +275,31 @@ export class MdTabGroup extends _MdTabGroupMixinBase implements AfterContentInit | |||
this._tabBodyWrapperHeight = this._tabBodyWrapper.nativeElement.clientHeight; | |||
this._renderer.setStyle(this._tabBodyWrapper.nativeElement, 'height', ''); | |||
} | |||
|
|||
/** Finds the next tab in the stack for the given direction */ | |||
_findNextTabByIndex(index: number, direction: string): number { |
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.
Similar function elsewhere in library: https://github.com/angular/material2/blob/master/src/cdk/a11y/list-key-manager.ts#L203
@jelbourn - I'm getting a lint error saying:
which is false because its being used in the
|
@jelbourn - ready for review. |
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.
For the lint error: it's a bug in the version of TypeScript we use. Just need to suppress it until we bump the TS version
Seems good overall, just needs unit tests (the slider has examples of faking hammer events)
src/lib/tabs/tab-body.html
Outdated
@@ -1,4 +1,6 @@ | |||
<div class="mat-tab-body-content" #content | |||
(swipe)="onSwipe.emit($event)" | |||
[style.touch-action]="'pan-y'" |
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.
Add a comment for why this needs to be an inline style? Also, since this is static, you don't need a binding; just style="touch-action: pan-y"
is good.
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.
Would you like the comment to be a HTML inline comment?
This actually doesn't work if you do it static like you suggested. I had tried that at first implementation.
Reference: hammerjs/hammer.js#1014
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.
I spent a bit too much time tracking this down. touch-action: none
is coming from our material GestureConfig
; adding the swipe gesture always sets the touch action to pan-y
+ pan-x
(equivalent to none
).
The "correct" fix for this would be to change how our gesture config add recognizers for certain events, but that's more complicated than we want to do right now. I filed #6484 to track this. Can you make your comment something like
<!-- touch-action workaround for https://github.com/angular/material2/issues/6484 -->
Comment can go above the element (I don't think a comment inside of a tag is valid html). HTML comments are stripped when packaging the release
src/lib/tabs/tab-group.ts
Outdated
this.selectedIndex = 0; | ||
} | ||
|
||
if (event.direction === 2 || event.direction === 4) { |
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.
Add an enum or constants instead of using the number literals in the function body
commit 85a6fff Author: mmalerba <mmalerba@google.com> Date: Sat Aug 12 15:05:58 2017 -0700 fix demo app (angular#6437)
@jelbourn - added unit tests and comments, ready for review again. |
@jelbourn I just searched "enum" in repo and found this (PascalCased enum members) and this (UPPERCASED enum members). ... and the enum members here (from HammerDirection) are going to be lowercased. I'm not sure what's the standard for Note that according this style-guide the recommended approach for enum members is to use PascalCase. |
deltaY: number; | ||
center: { x: number; y: number; }; | ||
} | ||
|
||
/** @docs-private */ | ||
export enum HammerDirection { | ||
left = 2, | ||
right = 4 |
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.
Enum fields should be PascalCase
src/lib/tabs/tab-header.spec.ts
Outdated
@@ -214,6 +219,21 @@ describe('MdTabHeader', () => { | |||
.toBe(0, 'Expected no ripple to show up after mousedown'); | |||
}); | |||
|
|||
it('should update scroll to next set on swipe', () => { |
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.
next set?
src/lib/tabs/tab-group.spec.ts
Outdated
const body = fixture.nativeElement. | ||
querySelector('.mat-tab-body-active .mat-tab-body-content'); | ||
|
||
dispatchSwipeEvent(body, 2, gestureConfig); |
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.
Use the enum rather than hard-coded numbers
src/lib/tabs/tab-group.spec.ts
Outdated
|
||
// select the second tab | ||
const body = fixture.nativeElement. | ||
querySelector('.mat-tab-body-active .mat-tab-body-content'); |
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.
Prefer breaking at the higher syntactic level:
const body =
fixture.nativeElement.querySelector('.mat-tab-body-active .mat-tab-body-content');
src/lib/tabs/tab-group.spec.ts
Outdated
@@ -169,6 +176,22 @@ describe('MdTabGroup', () => { | |||
expect(testElement.querySelectorAll('.mat-ripple-element').length) | |||
.toBe(0, 'Expected no ripple to show up on label mousedown.'); | |||
}); | |||
|
|||
it('should switch tabs on body swipe', () => { |
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.
Also need tests for skipping disabled tabs and for swipes at the first/last tab.
src/lib/tabs/tab-group.spec.ts
Outdated
config.emitEventForElement('swipe', bodyElement, { | ||
deltaX: direction === 2 ? -100 : 100, | ||
direction: direction, | ||
srcEvent: { preventDefault: jasmine.createSpy('preventDefault') } |
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.
Omit spaces in braces
src/lib/tabs/tab-group.ts
Outdated
let direction = event.direction; | ||
if (this._dir.value === 'rtl') { | ||
direction = direction === HammerDirection.left ? | ||
HammerDirection.right : HammerDirection.left; |
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.
Overflow indent is +4, but this one can also be broken at a higher syntactic level
direction =
direction === HammerDirection.left ? HammerDirection.right : HammerDirection.left;
@jelbourn - rdy to go. |
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.
LGTM, @andrewseguin should also take a look
Looks good to me as well, thanks for adding this! |
Maybe a flake? Try rebasing and re-pushing? |
I was just wondering how it is going with that weird error? Did a little search and found this. Hope it helps. microsoft/TypeScript#14538 (comment) |
Hi @amcdnl do you think this PR will make the next minor release? |
@CharlBest - That would be a @jelbourn call. |
Looks like there are still failures on CI |
@amcdnl Do you think the CI failures are difficult to fix? |
Any progress on this? |
Any progress on this @amcdnl ? |
Hi @amcdnl! This PR has merge conflicts due to recent upstream merges. |
1 similar comment
Hi @amcdnl! This PR has merge conflicts due to recent upstream merges. |
@amcdnl do you think this will make the v7 release? |
@jelbourn Do you think this PR will be considered or is it out of scope at the moment? |
Austin has been taking some time off, we'll revisit when he gets back |
@jelbourn Thank you for the reply. Good luck with everything you're working on and great job. |
@CharlBest If you would like to take over on this pull request, then I'd be happy to work with you on reviewing and getting it merged in |
Yes sure. I won't mind doing it although I'm not exactly sure what I'm suppose to do. :) |
@andrewseguin @CharlBest did you guys took over this pull request? Or is it still stalled? |
We decided recently that we want to remove HammerJS as a dependency, so we probably won't add this directly to the library any more, and instead document instructions for how to accomplish it with the gesture library of your choice. |
Closing this since we've decided to remove Hammer as a dependency and push gesture recognition to the application layer |
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
Addresses #2209 by adding swipe events to the tab content area.