-
Notifications
You must be signed in to change notification settings - Fork 6.7k
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 animation when switching tabs, include optional dynamic height #1788
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.
Lots of little points, but overall very good 👍
@@ -36,5 +36,5 @@ $md-tab-bar-height: 48px !default; | |||
position: absolute; | |||
bottom: 0; | |||
height: 2px; | |||
transition: 350ms ease-out; | |||
transition: 500ms ease-out; |
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.
Any reason not to use constants here?
display: flex; | ||
transition: height 0.5s $ease-in-out-curve-function; |
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.
0.5s == 500ms; is this supposed to be the same measure as above for the ink-bar? If so, a constant would be even better :)
display: block; | ||
md-tab-body { | ||
display: block; | ||
position: absolute; |
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'm not 100% sure but I think we already have a mixin for "fullscreen" css. If not, we should probably have one somewhere.
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 don't see that we have one already. Want me to make one in this change?
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.
We do have the md-fullscreen mixin, which is I think what Hans means. But it is position: fixed, not absolute.
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.
Right, there should probably be md-fill
mixin or something like that with position: absolute
. That mixin does not work right now.
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.
Agree
@@ -36,5 +36,5 @@ $md-tab-bar-height: 48px !default; | |||
position: absolute; | |||
bottom: 0; | |||
height: 2px; | |||
transition: 350ms ease-out; | |||
transition: 500ms ease-out; | |||
} |
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.
End of file, end of line.
(@position.start)="_onAnimationStarted($event)" | ||
(@position.done)="_onAnimationComplete($event)"> | ||
<template portalHost></template> | ||
</div> |
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.
End of line.
templateUrl: 'tab-body.html', | ||
animations: [ | ||
trigger('position', [ | ||
state('left', style({transform: 'translateX(-100%)'})), |
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.
According to https://jsperf.com/translate3d-vs-xy/28, translate3d
is the fastest in most browsers (because 3d rendering), which is why we use it in most places.
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.
Seems that Chrome has them set at about equal operations but 3D is way faster in Safari (and probably others). Thanks for the heads up
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.
Nits
|
||
it('should update tab positions and attach content when selected', fakeAsync(() => { | ||
fixture.detectChanges(); | ||
let tabComponent = fixture.debugElement.query(By.css('md-tab-group')).componentInstance; |
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.
Out of curiosity, why is this one let
while the other is const
? Seems like they could both be const
.
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.
Thanks, I tend to just default to let
rather than const
. Gotta break that habit.
@@ -0,0 +1,6 @@ | |||
<div class="md-tab-body-content" | |||
[@position]="_position" |
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.
Nit: This animation name doesn't really describe what is happening with the animation.
@@ -30,6 +37,7 @@ import {MdTabNavBar, MdTabLink} from './tab-nav-bar/tab-nav-bar'; | |||
import {MdInkBar} from './ink-bar'; | |||
import {Observable} from 'rxjs/Observable'; | |||
import 'rxjs/add/operator/map'; | |||
import {PortalHostDirective} from '../core/portal/portal-directives'; |
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.
It might make more sense to add this to the existing import list on line 19 from ../core
. I think it's exported there too.
* Sets the height of the body wrapper to the height of the activating tab if dynamic | ||
* height property is true. | ||
*/ | ||
_setTabBodyWrapperHeight(e: 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.
Nit: return 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.
Maybe height
would be more descriptive than e
? It's not clear at first glance what it stands for.
]) | ||
] | ||
}) | ||
export class MdTabBody implements OnInit { |
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'm curious why this has to be its own component. Is it for code org or is there another reason it has to be this way?
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.
Primarily code organization - portal attach/detach + animations would have added quite a bit to tab group and I don't think it would have been as readable about what is happening between all the interactions
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.
Okay, that's fair. Thought that might be the case.
95e81f4
to
3067f8b
Compare
Changes made in response to the comments. Thanks for reviewing |
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
98df4f2
to
54744b7
Compare
Switched md-fullscreen back to using absolute positioning (changed in #893) which is safe for its use in sidenav. Renamed as md-fill and used in the tab body. |
Sorry, added one more small change to support RTL animation direction |
LGTM. |
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.
After this PR, we should make sure that the tabs accessibility has not changed, since there is now a state where the content of more than one tab is on-screen at once. We might need set aria-hidden
on the tab that is being animated out.
/** | ||
* Returns an array of true/false that represents the active states for the provided elements | ||
* @param elements | ||
* @returns {webdriver.promise.Promise<Promise<boolean>[]>|webdriver.promise.Promise<T[]>} |
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.
Since this is TypeScript, you don't need the type in the JsDoc (these were formerly js)
} else if (v > 0) { | ||
this._position = this.getLayoutDirection() == 'ltr' ? 'right' : 'left'; | ||
} | ||
if (v == 0) { this._position = 'center'; } |
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.
Just else
here?
@@ -136,6 +139,53 @@ describe('MdTabGroup', () => { | |||
expect(component.handleSelection).toHaveBeenCalledTimes(1); | |||
expect(component.selectEvent.index).toBe(2); | |||
})); | |||
|
|||
it('should update tab positions and attach content when selected', fakeAsync(() => { |
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 a test for RTL?
Changes made (added test for RTL). Will make a note to check out screen reader support after this PR |
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. |
No description provided.