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
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/list/ListGroup.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ const ListGroup = (props) => {

ListGroup.propTypes = {
className: PropTypes.string,
children: PropTypes.element,
children: PropTypes.node,
tag: PropTypes.string,
};

Expand Down
63 changes: 46 additions & 17 deletions packages/list/ListItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,26 @@ import classnames from 'classnames';
export default class ListItem extends Component {
listItemElement_ = React.createRef();

componentDidMount() {
const {init} = this.props;
init && init();
}

get listItemElement() {
return this.listItemElement_.current;
componentDidUpdate(prevProps) {
const {
shouldFocus,
shouldFollowHref,
shouldToggleCheckbox,
} = this.props;
if (shouldFocus !== prevProps.shouldFocus && shouldFocus) {
this.focus();
}
if (shouldFollowHref !== prevProps.shouldFollowHref && shouldFollowHref) {
this.followHref();
}
if (shouldToggleCheckbox !== prevProps.shouldToggleCheckbox && shouldToggleCheckbox) {
this.toggleCheckbox();
}
}

get classes() {
const {className} = this.props;
return classnames('mdc-list-item', className);
const {className, classNamesFromList} = this.props;
return classnames('mdc-list-item', className, classNamesFromList);
}

focus() {
Expand All @@ -64,19 +72,23 @@ export default class ListItem extends Component {
const {
/* eslint-disable */
className,
classNamesFromList,
childrenTabIndex,
init,
id,
shouldFocus,
shouldFollowHref,
shouldToggleCheckbox,
/* eslint-enable */
attributesFromList,
children,
...otherProps
} = this.props;

return (
<li
className={this.classes}
ref={this.listItemElement_}
{...otherProps}
{...attributesFromList} // overrides attributes in otherProps
ref={this.listItemElement_}
>
{React.Children.map(children, this.renderChild)}
</li>
Expand All @@ -93,15 +105,32 @@ export default class ListItem extends Component {
}

ListItem.propTypes = {
id: PropTypes.string,
childrenTabIndex: PropTypes.number,
children: PropTypes.node,
className: PropTypes.string,
init: PropTypes.func,
classNamesFromList: PropTypes.array,
attributesFromList: PropTypes.object,
childrenTabIndex: PropTypes.number,
tabIndex: PropTypes.number,
shouldFocus: PropTypes.bool,
shouldFollowHref: PropTypes.bool,
shouldToggleCheckbox: PropTypes.bool,
onKeyDown: PropTypes.func,
onClick: PropTypes.func,
onFocus: PropTypes.func,
onBlur: PropTypes.func,
};

ListItem.defaultProps = {
id: '',
childrenTabIndex: -1,
className: '',
classNamesFromList: [],
attributesFromList: {},
childrenTabIndex: -1,
tabIndex: -1,
shouldFocus: false,
shouldFollowHref: false,
shouldToggleCheckbox: false,
onKeyDown: () => {},
onClick: () => {},
onFocus: () => {},
onBlur: () => {},
};
25 changes: 17 additions & 8 deletions packages/list/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ class MyApp extends Component {
}
```

> _NOTE_: Please use the `ListItem` component to specify list items. `List` will not recognize custom list item components.

## Variants

### Two-Line List
Expand Down Expand Up @@ -140,7 +142,9 @@ class MyApp extends Component {

### Single Selection

You can use the `singleSelection` Boolean prop for `List` to allow for selection of list items. You can also set the `selectedIndex` of the list programmatically.
You can use the `singleSelection` Boolean prop for `List` to allow for selection of list items. You can also set the `selectedIndex` of the list programmatically and include a `handleSelect` callback.

> _NOTE_: If you are inserting or removing list items, you must update the `selectedIndex` accordingly.

```js
class MyApp extends React.Component {
Expand All @@ -153,6 +157,7 @@ class MyApp extends React.Component {
<List
singleSelection
selectedIndex={this.state.selectedIndex}
handleSelect={(selectedIndex) => this.setState({selectedIndex})}
>
<ListItem>
<ListItemText primaryText='Photos'/>
Expand All @@ -176,27 +181,31 @@ class MyApp extends React.Component {
Prop Name | Type | Description
--- | --- | ---
className | String | Classes to be applied to the list element
nonInterative | Boolean | Disables interactivity affordances
nonInteractive | Boolean | Disables interactivity affordances
dense | Boolean | Styles the density of the list, making it appear more compact
avatarList | Boolean | Configures the leading tiles of each row to display images instead of icons. This will make the graphics of the list items larger
twoLine | Boolean | Styles the list with two lines
singleSelection | Boolean | Allows for single selection of list items
wrapFocus | Boolean | Sets the list to allow the up arrow on the first element to focus the last element of the list and vice versa
selectedIndex | Number | Toggles the selected state of the list item at the given index
handleSelect | Function(selectedIndex: Number) => void | Callback for handling a list item selection event
aria-orientation | String | Indicates the list orientation
onClick | Function(evt: Event) => void | Callback for handling a click event
onKeyDown | Function(evt: Event) => void | Callback for handling a keydown event
onFocus | Function(evt: Event) => void | Callback for handling a focus event
onBlur | Function(evt: Event) => void | Callback for handling a blur event

### ListItem

Prop Name | Type | Description
--- | --- | ---
id | String | Unique identifier for the list item. Defaults to the index
className | String | Classes to be applied to the list item element
classNamesFromList | Array<String> | Additional classes to be applied to the list item element, passed down from list
attributesFromList | Additional attributes to be applied to the list item element, passed down from list
childrenTabIndex | Number | Tab index to be applied to all children of the list item
init | Function() => void | Callback executed when list item mounts
shouldFocus | Whether to focus the list item
shouldFollowHref | Whether to follow the link indicated by the list item
shouldToggleCheckbox | Whether to toggle the checkbox on the list item
onClick | Function(evt: Event) => void | Callback for handling a click event
onKeyDown | Function(evt: Event) => void | Callback for handling a keydown event
onFocus | Function(evt: Event) => void | Callback for handling a focus event
onBlur | Function(evt: Event) => void | Callback for handling a blur event

### ListItemText

Expand Down
Loading