Material-ui: ListItem has link ?

Created on 13 Aug 2015  ·  26Comments  ·  Source: mui-org/material-ui

I am trying to use Listitem as link to other url but Link's property override ListItem 's property
is there any solution to this

< ListItem primaryText = { <Link to="a" > as </Link> } />

Most helpful comment

Just ran into this. I'm using this and it works:

<ListItem button component={Link} to='/some-url'>...</ListItem>

All 26 comments

@TonyFrancis You should be able to add an href attribute to the ListItem.

@TonyFrancis Got your comment on gitter and it sounds like you got this to work. I'll go ahead and close this for now - please reopen if there's still an issue.

href needs to be added to doc

Edit:
Dang it! This issue is addressed at #2243. In general; it's not clear from the documentation what all available properties are. This should be documented and the following statement doesn't help.
Other properties (no documented) are applied to the root element.
I looked at the github List implementation and I'm not seeing a container component being used that has the containerElement property.

Based on @TonyFrancis response the href doesn't fully satisfy the need. If you're using react router which is likely where the Link component is coming from then you get some benefits like being able to specify a basename.

For example if you have <Router basename='/my-app'> wrapping your app then

< ListItem primaryText = { <Link to="a" > as </Link> } />

would link to my-app/a without the need to carry that basename around everywhere.

The documentation is not clear enough for me. hmmm

There is no href field in the document for ListItem

Just ran into this. I'm using this and it works:

<ListItem button component={Link} to='/some-url'>...</ListItem>

@mariotacke ^ this code generates ul > a markup, which is not semantically valid, see https://github.com/mui-org/material-ui/issues/7956#issuecomment-362433602

edit: it's fine if the parent is a <nav> or uses component="nav"

Now, you can create this with following code:
```
primaryText="Text"
containerElement={}
/>
````

Hey @Glaadiss Tnx, it works

@Glaadiss that markup gives me an error:

Warning: React does not recognize thecontainerElementprop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercasecontainerelementinstead. If you accidentally passed it from a parent component, remove it from the DOM element.

Is that because I have an outdated version of React or MUI?

@renannobile Check out if you passing unnecessary {...props} in one of your components. It's a common mistake when we copy-paste from guides :P

@Glaadiss I don't seem to be able to use this on 1.0.0-beta.44

Tried:

<List component="nav">
    <ListItem component={Link} to="/admin/user">
      <ListItemIcon>
        <PersonIcon />
      </ListItemIcon>
      <ListItemText primary="Inbox" />
    </ListItem>
    <ListItem button>
      <ListItemIcon>
        <DraftsIcon />
      </ListItemIcon>
      <ListItemText primary="Drafts" />
    </ListItem>
  </List>

The above case works but without the ripple effect and it results in an a with a div as child, which is illegal.

<List component="nav">
    <ListItem primaryText="Inbox" component={Link} to="/admin/user">
      <ListItemIcon>
        <PersonIcon />
      </ListItemIcon>
    </ListItem>
    <ListItem button>
      <ListItemIcon>
        <DraftsIcon />
      </ListItemIcon>
      <ListItemText primary="Drafts" />
    </ListItem>
  </List>

The above case works but without the ripple effect and it results in an item without visible text.

<List component="nav">
    <ListItem primaryText="Inbox" containerElement={<Link to="/admin/user" />}>
      <ListItemIcon>
        <PersonIcon />
      </ListItemIcon>
    </ListItem>
    <ListItem button>
      <ListItemIcon>
        <DraftsIcon />
      </ListItemIcon>
      <ListItemText primary="Drafts" />
    </ListItem>
  </List>

This above case shows an [object Object] attribute for containerElement in the HTML.

<List component="nav">
    <ListItem ContainerComponent={() => <Link to="/admin/user" />}>
      <ListItemIcon>
        <PersonIcon />
      </ListItemIcon>
      <ListItemText primary="Inbox" />
    </ListItem>
    <ListItem button>
      <ListItemIcon>
        <DraftsIcon />
      </ListItemIcon>
      <ListItemText primary="Drafts" />
    </ListItem>
  </List>
<List component="nav">
    <ListItem ContainerComponent={Link to="/admin/user" />}>
      <ListItemIcon>
        <PersonIcon />
      </ListItemIcon>
      <ListItemText primary="Inbox" />
    </ListItem>
    <ListItem button>
      <ListItemIcon>
        <DraftsIcon />
      </ListItemIcon>
      <ListItemText primary="Drafts" />
    </ListItem>
  </List>



md5-7ff35357efa037d9c88356d4d3bf14ad



<List component="nav">
    <ListItem ContainerComponent={Link} ContainerProps={{ to: '/admin/user' }}>
      <ListItemIcon>
        <PersonIcon />
      </ListItemIcon>
      <ListItemText primary="Inbox" />
    </ListItem>
    <ListItem button>
      <ListItemIcon>
        <DraftsIcon />
      </ListItemIcon>
      <ListItemText primary="Drafts" />
    </ListItem>
  </List>

Ahh! The solution is this.

<List component="nav">
    <ListItem component={Link} to="/admin/user" button>
      <ListItemIcon>
        <PersonIcon />
      </ListItemIcon>
      <ListItemText primary="Inbox" />
    </ListItem>
    <ListItem button>
      <ListItemIcon>
        <DraftsIcon />
      </ListItemIcon>
      <ListItemText primary="Drafts" />
    </ListItem>
  </List>

@mschipperheyn this works but it messes with the ripple effect

Hello, any updates on how to properly do this?

This works for me, including ripple:

<ListItem button component={
  ({ children, ...props }) =>
    <Link to="/" {...props as LinkProps}>
      {children}
    </Link>
}>

The following approach worked for me, because it's able to retain the original style and flex behavior.

<ListItem component={props => (
  <ListItem button>
    <Link style={{
      position: "absolute",
      top: 0,
      left: 0,
      right: 0,
      bottom: 0
    }}
    to={"/"}>
    </Link>
    {props.children}
  </ListItem>
)}>
    <ListItemIcon>
      <ArrowForwardIcon/>
    </ListItemIcon>
    <ListItemText primary="List Item" />
</ListItem>

For Next.js users:

<List component="nav">
  <Link href="/admin/resources" passHref>
    <ListItem component="a" button>
      <ListItemIcon>
        <InboxIcon />
      </ListItemIcon>
      <ListItemText primary="Resources" />
    </ListItem>
  </Link>
  ...

This may seem obvious - but if you don't need to use <Link/> and can use <a> (i.e. - you don't get the advantages of the SPA you are writing) you can do this:

<a href="/yourlink">
  <ListItem
    button
  >
    <ListItemText primary="Your Link Text" />
  </ListItem>
</a>

By default Eslint should require rel="noopener noreferrer" if target="_blank"

              <List>
                <a
                  href="https://fb.me/xxxxxxxxx"
                  target="_blank"
                  rel="noopener noreferrer"
                  className={classes.hrefLink}
                >
                  <ListItem button>
                    <ListItemIcon>
                      <ThumbUp className={classes.icon32} />
                    </ListItemIcon>
                    <ListItemText primary="Visit our Facebook Page" secondary="@xxxxxxxxxx" />
                  </ListItem>
                </a>
              </List>

This works with v4:

    <ListItem button to={to} component={Link}>
      {children}
    </ListItem>

Here's my approach, using built-in Mui-selected class:

<ListItem
  button
  component={NavLink}
  activeClassName={"Mui-selected"}
  to={"/some-url"}
  exact
>
  ...
</ListItem>

Link not working with ListItem pls help me antone

@gautam751 share your code or repo, please, so that people can help you

Just ran into this. I'm using this and it works:

<ListItem button component={Link} to='/some-url'>...</ListItem>

Worked for Me,Thanks
but actually i use it like this:

<ListItem button component={Link} to="/SomePath">
       ...
</ListItem>
Was this page helpful?
0 / 5 - 0 ratings