Skip to content
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

refactor(list): Refactor list item management #413

Merged
merged 28 commits into from
Nov 6, 2018

Conversation

bonniezhou
Copy link
Contributor

Move the logic having to do with list item classes, attributes, etc inside ListItem instead of in List. Move event handlers to ListItem. Remove the needs for IDs on list items, instead recalibrate the list item index on every re-render.

Fixes #367, #366, #365.

@codecov-io
Copy link

codecov-io commented Nov 5, 2018

Codecov Report

Merging #413 into master will decrease coverage by 0.87%.
The diff coverage is 80.48%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #413      +/-   ##
==========================================
- Coverage   96.94%   96.07%   -0.88%     
==========================================
  Files          53       53              
  Lines        1836     1811      -25     
  Branches      212      212              
==========================================
- Hits         1780     1740      -40     
- Misses         56       71      +15
Impacted Files Coverage Δ
packages/list/ListGroup.js 100% <ø> (ø) ⬆️
packages/list/ListItem.js 87.5% <71.42%> (-8.5%) ⬇️
packages/list/index.js 89.09% <82.35%> (-10.91%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 003221a...fbc15f1. Read the comment docs.

getFocusedElementIndex: () => {
let count = -1;
let index = -1;
React.Children.forEach(this.props.children, (child) => {
Copy link

Choose a reason for hiding this comment

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

this is cool - didn't know you could inspect child.type.name. Aren't you give the index here? Is it because you're accounting for dividers and other elements that aren't ListItems?

Copy link

Choose a reason for hiding this comment

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

Also is there a way to break early from this? If you've found the element

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yep, the index thing is to get around dividers and non-ListItems. and you can't break early in React.Children.forEach so I changed it to use React.Children.toArray instead. https://stackoverflow.com/questions/51334473/react-how-to-break-out-of-react-children-foreach-loop

getFocusedElementIndex: () => this.getListItemIndexOfTarget_(document.activeElement),
getListItemCount: () => this.listItemCount,
getFocusedElementIndex: () => {
let count = -1;
Copy link

Choose a reason for hiding this comment

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

I think count should start at 0

}
const i = listItemClassNames[index].indexOf(className);
listItemClassNames[index].splice(i, 1);
Copy link

Choose a reason for hiding this comment

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

I think you need to check if i<= -1. If you do listItemClassNames[index].splice(-1, 1), its going to delete something, which I believe is unintended.

}
target = target.parentElement;
renderChild = (child) => {
if (child.type.name === 'ListItem') {
Copy link

Choose a reason for hiding this comment

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

I think in the Readme, we should say that the children need to be type ListItem's (if we don't already). One of the issues this past week gave an example of this:

<Link>
  <ListItem ... />
</Link>

},
this.state.listItemAttributes[idOrIndex]);
onKeyDown: (e) => {
onKeyDown();
Copy link

Choose a reason for hiding this comment

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

pass the events in onKeyDown, onClick, onFocus, and onBlur. The user's may want that

shouldFocus: focusListItemAtIndex === index,
shouldFollowHref: followHrefAtIndex === index,
shouldToggleCheckbox: toggleCheckboxAtIndex === index,
attributesToSet: listItemAttributes[index],
Copy link

Choose a reason for hiding this comment

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

How about renaming attributesToSet and classNamesToAdd to attributesFromList and classNamesFromList? I think it is inferred that we want to add them.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

omg yes, I struggled hard with this naming 😅

if (index >= 0) {
this.foundation_.handleKeydown(e, true /* isRootListItem is true if index >= 0 */, index);
// Work around until MDC Web issue is resolved:
Copy link

Choose a reason for hiding this comment

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

the if(index >= 0) can be inlined with if (e.key === 'Enter' || e.keyCode === 13 || e.key === 'Space' || e.keyCode === 32). The foundation.handleKeyDown method already does that check.

// Toggle the checkbox only if it's not the target of the event, or the checkbox will have 2 change events.
const toggleCheckbox = e.target.type === 'checkbox';
this.foundation_.handleClick(index, toggleCheckbox);
// Work around until MDC Web issue is resolved:
// https://github.com/material-components/material-components-web/issues/4053
this.props.handleSelect(index);
Copy link

Choose a reason for hiding this comment

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

this should have an if (index >= 0) check. foundation.handleClick does that check, so we should also do it here.

},
this.state.listItemAttributes[idOrIndex]);
onKeyDown: (e) => {
onKeyDown(e);
Copy link

Choose a reason for hiding this comment

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

Sorry - should have thought of this earlier...do you think the index is useful information to pass to the onKeyDown event handler?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If we include index in onKeyDown then we should probably include it in the rest of the handlers too. I think we can leave it as is for now, and add it if someone has a specific use case for index.

@moog16 moog16 added this to the 0.6.x milestone Nov 6, 2018
@moog16 moog16 self-assigned this Nov 6, 2018
@bonniezhou
Copy link
Contributor Author

Filed #415

@bonniezhou bonniezhou merged commit 1f563d3 into master Nov 6, 2018
@bonniezhou bonniezhou deleted the refactor/list-item-logic branch November 6, 2018 22:11
4cm4k1 added a commit to 4cm4k1/material-components-web-react that referenced this pull request Nov 13, 2018
…md note

* master:
  chore: Publish
  fix(text-field): added reference to input element (material-components#414)
  fix(drawer): update readme and screenshots to support below top app bar (material-components#397)
  refactor(list): Refactor list item management (material-components#413)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants