-
Notifications
You must be signed in to change notification settings - Fork 3.4k
fix(button): properly show focus effect #9826
Conversation
.on('blur', function(ev) { | ||
}); | ||
|
||
element.on('blur', 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.
Note: This is intentionally another on
statement, because otherwise the indention is ugly and this is just more clear..
b3d2f2d
to
984d61b
Compare
|
||
element.on('focus', function() { | ||
// Only show the focus effect when being focused through keyboard interaction. | ||
if ($mdInteraction.getLastInteractionType() === 'keyboard') { |
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.
Wouldn't this change the existing interaction if a developer focuses an element over Javascript (such as when opening a dialog or a custom component)?
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 think if you want to target operations related to the mouse, you should target those events specifically. Tracking the element
's last interaction seems to better than tracking to body
, since a click event somewhere else on a page would prevent a button from getting a md-focused
class (again like a custom popup).
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 does not change anything to the existing behavior, just that we now check the global interaction to detect the last interaction.
Focusing manually per .focus
does not work right now as well, because the mousedown
event didn't get fired.
This is the approach we wanted to go with the $mdInteraction
service, as proposed by Marcy. Similar to #9827
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 does not change anything to the existing behavior, just that we now check the global interaction to detect the last interaction.
You can see the behavior change with this codepen: http://codepen.io/shortfuse/pen/LRAarO
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 just some testing and mousedown
gets fired after focus
on Chrome. Instead of tracking mouseactive as a boolean
, I would suggest a timestamp on last mousedown event. Then attach a timeout to the adding of md-focused
. If mousedown was triggered within a certain time (say 100ms), don't add the class.
Edit: You also have to cancel said timeout from 'blur'
984d61b
to
c77660e
Compare
c0629cd
to
6774229
Compare
@@ -54,7 +54,7 @@ angular | |||
* </hljs> | |||
* | |||
*/ | |||
function MdCheckboxDirective(inputDirective, $mdAria, $mdConstant, $mdTheming, $mdUtil, $timeout) { | |||
function MdCheckboxDirective(inputDirective, $mdAria, $mdConstant, $mdTheming, $mdUtil, $timeout, $mdInteraction) { |
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 like the $mdInteraction
import is unused.
*/ | ||
MdInteractionService.prototype.isProgrammatic = function(checkDelay) { | ||
var delay = angular.isDefined(checkDelay) ? checkDelay : 15; |
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.
angular.isNumber
might be more appropriate here.
* @returns {boolean} Whether there was any interaction or not. | ||
*/ | ||
MdInteractionService.prototype.isProgrammatic = function(checkDelay) { |
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 know that we decided on the naming for this together, but I'm still not sure that isProgrammatic
is very obvious. It seems like it implies that the service is programmatic. That being said, I don't have any better suggestions at the moment, perhaps other team member can pitch in?
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.
Yeah, Carlos had a great idea here. - isUserInvoked
.
4463449
to
7bcc991
Compare
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.
|
||
button.triggerHandler('focus'); | ||
|
||
expect(button[0]).toHaveClass('md-focused'); |
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.
AFAIK you don't have to fetch the DOM node here. expect(button).toHaveClass('md-focused')
should work as well.
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.
Valid and changed it. But FYI: a lot of other tests are doing the same and I don't want to diff the whole test 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.
That's why I didn't make it a blocking request. It's basically the same, it just looks nicer.
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.
Yeah, changed it for the tests I've added.
* Only apply the focus effect for programmatic focus or by keyboard interaction (as same as it does currently, but not with a random timeout). References angular#7963 Fixes angular#8749
7bcc991
to
1630d42
Compare
Similar to #9827
Fixes #8749. References #7963