-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Conversation
Codecov Report
@@ Coverage Diff @@
## master #3546 +/- ##
==========================================
+ Coverage 98.35% 98.35% +<.01%
==========================================
Files 120 120
Lines 5168 5175 +7
Branches 640 642 +2
==========================================
+ Hits 5083 5090 +7
Misses 85 85
Continue to review full report at Codecov.
|
All 389 screenshot tests passed for commit 73afd56 vs. |
All 389 screenshot tests passed for commit 2ec343b vs. |
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.
Discussed offline: Radio buttons have different behavior than checkboxes with regard to emitting change events (the change event only emits on the radio that becomes checked), and it might not make sense to specifically apply toggle logic to radios the same way we're handling checkboxes.
packages/mdc-list/index.js
Outdated
const event = document.createEvent('Event'); | ||
event.initEvent('change', false, true); | ||
|
||
if (!element.checked) { |
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 this can be simplified to if (!element.checked || element.type !== 'radio')
and avoid needing the else and repeating the 2 lines inside? (Move the comment up)
packages/mdc-list/index.js
Outdated
const listItem = this.listElements[index]; | ||
const elementsToToggle = | ||
[].slice.call(listItem.querySelectorAll('input[type="radio"], input[type="checkbox"]')); | ||
elementsToToggle.forEach((element) => { |
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.
If we let
a boolean outside of this loop and set it to true when this function is run, we can return it as an indicator of whether an input was found to toggle, and preventDefault
on the event within the foundation if this returns true.
packages/mdc-menu/adapter.js
Outdated
*/ | ||
toggleCheckbox(target) {} | ||
toggleCheckbox(index) {} |
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 is still in menu's adapter... it belongs in List's now, right?
test/unit/mdc-list/mdc-list.test.js
Outdated
test('adapter#toggleCheckbox toggles a radio button', () => { | ||
const {root, component} = setupTest(); | ||
document.body.appendChild(root); | ||
const checkbox = root.querySelector('input[type="radio"]'); |
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: checkbox -> radio
packages/mdc-list/index.js
Outdated
[].slice.call(listItem.querySelectorAll('input[type="radio"], input[type="checkbox"]')); | ||
elementsToToggle.forEach((element) => { | ||
const event = document.createEvent('Event'); | ||
event.initEvent('change', false, true); |
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 there are some potential issues here...
- Why is
bubbles
set tofalse
? Change events bubble by default. i.e. if I set up a document-level change listener, I will only get change events if I actually interact directly with the input right now. - However, right now, if I click directly on a checkbox, I get 2 change events emitted directly on the checkbox. This doesn't happen for radios, possibly because of the
if
below.
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, initEvent
is apparently deprecated in favor of directly using Event constructors; see https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events
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.
Event constructors are not supported in IE11.
https://developer.mozilla.org/en-US/docs/Web/API/Event/Event
td.verify(mockFoundation.handleClick(td.matchers.anything()), {times: 1}); | ||
}); | ||
|
||
test('singleSelection false removes the click handler from the root element', () => { |
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.
FYI there is no equivalent test to this in the new code (i.e. no test that tests MDCListFoundation#handleClick when isSingleSelectionList_
is false)
@@ -374,3 +358,23 @@ test('keydown handler is removed from the root element on destroy', () => { | |||
listElementItem.dispatchEvent(event); | |||
td.verify(mockFoundation.handleKeydown(event, true, 0), {times: 0}); | |||
}); | |||
|
|||
test('adapter#toggleCheckbox toggles a checkbox', () => { |
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 third test with no checkbox/radio to verify it returns false
td.verify(mockAdapter.setAttributeForElementIndex(0, 'tabindex', 0), {times: 0}); | ||
}); | ||
|
||
test('#handleClick proxies to the adapter#toggleCheckbox is toggleCheckbox is true', () => { |
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.
is toggleCheckbox -> if toggleCheckbox
@@ -481,62 +481,66 @@ test('#handleKeydown space key is triggered and focused is moved to a different | |||
td.verify(mockAdapter.setAttributeForElementIndex(2, 'tabindex', 0), {times: 1}); | |||
}); | |||
|
|||
test('#handleClick when singleSelection=true on a list item should not cause the list item to be selected', () => { |
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.
true -> false
component.getDefaultFoundation().adapter_.setTabIndexForListItemChildren(index, 0); | ||
assert.equal(1, listItems[index].querySelectorAll('[tabindex="0"]').length); | ||
} | ||
component.getDefaultFoundation().adapter_.setTabIndexForListItemChildren(0, 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.
The descriptions of this test and in the README need updating for the new behavior.
FYI there's currently no test exercising the preventDefault branch in handleKeydown. |
packages/mdc-list/README.md
Outdated
and then tab to the first element after the list. The `Arrow`, `Home`, and `End` keys should be used for navigating | ||
internal list elements. If `singleSelection=true`, the list will allow the user to use the `Space` or `Enter` keys to | ||
select or deselect a list item. The MDCList will perform the following actions for each key press | ||
As the user navigates through the list, any `button`, and `a` elements within the list will receive `tabindex="-1"` when |
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: remove comma between "button
and a
"
packages/mdc-list/foundation.js
Outdated
@@ -203,17 +204,31 @@ class MDCListFoundation extends MDCFoundation { | |||
this.adapter_.followHref(currentIndex); | |||
} | |||
} | |||
|
|||
if (isEnter || isSpace) { |
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 it be more straightforward to put this within the else if
above, make that else if
check only for isEnter || isSpace
, then nest if (this.isSingleSelectionList_)
within that? IMO it's a little hard to follow right now since there's two separate blocks with logic for enter/space, and potentially both of them can be executed.
Tangentially, I also can't remember why the preventDefault for single-selection is outside the isRootListItem check?
@@ -110,19 +110,6 @@ class MDCMenuAdapter { | |||
* }} evtData | |||
*/ | |||
notifySelected(evtData) {} | |||
|
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.
These also need to be removed from the menu README
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 with one nit and one test comment
packages/mdc-list/foundation.js
Outdated
if (isRootListItem) { | ||
this.setSelectedIndex(currentIndex); | ||
} else if (isEnter || isSpace) { | ||
if (this.isSingleSelectionList_) { |
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 we can collapse these two nested if's (single-selection + root list item) into one if && now?
packages/mdc-list/foundation.js
Outdated
} else if (isEnter || isSpace) { | ||
if (this.isSingleSelectionList_) { | ||
// Check if the space key was pressed on the list item or a child element. | ||
if (isRootListItem) { |
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 don't seem to have a test for single-selection + non-root-list-item
fixes: #3510
BREAKING CHANGE: Moves the toggling of radio buttons and checkboxes to the list from the menu. Adds toggleCheckbox List adapter API.