Problem
Regarding to #13597
The implementation of ListItem is complex to understand and does too many things that developers does not expect.
-
render ListItemSecondaryAction inside ListItem cause the markup to change
<ListItem>
Some text
</ListItem>
// result
// <div>Some text</div>
<ListItem>
Some text
<ListItemSecondaryAction>
action
</ListItemSecondaryAction>
</ListItem>
// result
// <div>
// <div>Some text</div>
// <button>action</div>
// </div>
This cause a lot of confusion to developer. Moreover, the ContainerProps is added for customization which add more API for the developer to know.
-
when button prop is true, ButtonBase is used which change the default tag of ListItem, again cause confusion and developer needs to know the implementation detail
<ListItem>
Some text
</ListItem>
// result => <li>Some text</li>
<ListItem button>
Some text
</ListItem>
// result => <div>Some text<div>
-
Frequently, the ListItem is override by a or Link from router library. Developer needs to know to wrap with li
<li>
<ListItem button component={Link}>
Some text
</ListItem>
</li>
Goal
List components tends to be used to create new component like nested menu, link item, and many more. So, material-ui should provide the list components that are styled with material design spec and simple to compose together without needing to know much about the implementation.
- no children checking
- no DOM changing between prop
- no
container props
Solution I : One element, One DOM #26446
From comments and issues, one way to improved is to extract button out of ListItem so each component render only single markup
// v4
<ListItem button>...</ListItem>
// v5
<ListItem>
<ListItemButton>...</ListItemButton>
</ListItem>
Pros
- least API (no nested component API)
- types is straight forward
- replacing with routing library is similar to
Button
Cons
- Developer needs to know the markup before picking the component
- using
ListItem and ListItemButton together require nested CSS & negative margin. (customise padding will require negative margin adjustment)
Solution II : Flat ListItemButton #26480
ListItemButton always render 2 DOM, by default <li> <div>
// v4
<ListItem button>...</ListItem>
// v5
<ListItemButton>...</ListItemButton>
Pros
- no nested css specificity, custom styles is straight forward
Cons
- hard to manage types
- overriding via
componentsProps
Secondary Action
Both solutions will use the same API for handling secondary action. Regardless of the approach, ListItem and ListItemButton accept secondaryAction prop.
<ListItem secondaryAction={...}>
<ListItemButton secondaryAction={...}>
This will remove the hidden logic to check if children has ListItemSecondaryAction or not.
Breaking change?
Instead of making this as breaking change , I prefer to adjust ListItem and mark some prop like button as deprecated and then remove them in next major version because I assume that most of the project use ListItem in some way.
Further
from @eps1lon suggestion, it is nice to expose UnorderedList and OrderedList as a wrapper of ListItem like Chakra-UI does.
cc @mui-org/core
Problem
Regarding to #13597
The implementation of
ListItemis complex to understand and does too many things that developers does not expect.render
ListItemSecondaryActioninsideListItemcause the markup to changeThis cause a lot of confusion to developer. Moreover, the
ContainerPropsis added for customization which add more API for the developer to know.when
buttonprop is true,ButtonBaseis used which change the default tag ofListItem, again cause confusion and developer needs to know the implementation detailFrequently, the
ListItemis override byaorLinkfrom router library. Developer needs to know to wrap withliGoal
List components tends to be used to create new component like nested menu, link item, and many more. So, material-ui should provide the list components that are styled with material design spec and simple to compose together without needing to know much about the implementation.
containerpropsSolution I : One element, One DOM #26446
From comments and issues, one way to improved is to extract
buttonout ofListItemso each component render only single markupPros
ButtonCons
ListItemandListItemButtontogether require nested CSS & negative margin. (customise padding will require negative margin adjustment)Solution II : Flat ListItemButton #26480
ListItemButtonalways render 2 DOM, by default<li> <div>Pros
Cons
componentsPropsSecondary Action
Both solutions will use the same API for handling secondary action. Regardless of the approach,
ListItemandListItemButtonacceptsecondaryActionprop.This will remove the hidden logic to check if children has
ListItemSecondaryActionor not.Breaking change?
Instead of making this as
breaking change, I prefer to adjustListItemand mark some prop likebuttonas deprecated and then remove them in next major version because I assume that most of the project useListItemin some way.Further
from @eps1lon suggestion, it is nice to expose
UnorderedListandOrderedListas a wrapper ofListItemlike Chakra-UI does.cc @mui-org/core