mui / material-ui

Material UI: Comprehensive React component library that implements Google's Material Design. Free forever.
https://mui.com/material-ui/
MIT License
93.9k stars 32.26k forks source link

[BottomNavigation] Link docs #22001

Closed guoyunhe closed 4 years ago

guoyunhe commented 4 years ago

Summary 💡

In my app, I use nextjs links for navigation items. But BottomNavigationItem doesn't support Link (Next.js)

Examples 🌈

Motivation 🔦

support[bot] commented 4 years ago

👋 Thanks for using Material-UI!

We use GitHub issues exclusively as a bug and feature requests tracker, however, this issue appears to be a support request.

For support, please check out https://material-ui.com/getting-started/support/. Thanks!

If you have a question on StackOverflow, you are welcome to link to it here, it might help others. If your issue is subsequently confirmed as a bug, and the report follows the issue template, it can be reopened.

oliviertassinari commented 4 years ago

See https://material-ui.com/guides/composition/#routing-libraries, same approach

guoyunhe commented 4 years ago

See https://material-ui.com/guides/composition/#routing-libraries, same approach

@oliviertassinari I tried but it doesn't work for BottomNavigationItem. It doesn't have a prop component.

oliviertassinari commented 4 years ago

@guoyunhe Look closer :)

guoyunhe commented 4 years ago

I did read the entire page, word by word, for three times. But didn't get it. It will be really helpful if here is any working example.

oliviertassinari commented 4 years ago

What do you think about this diff?

diff --git a/docs/src/pages/guides/composition/composition.md b/docs/src/pages/guides/composition/composition.md
index 45a2bdc5d..ef24268b8 100644
--- a/docs/src/pages/guides/composition/composition.md
+++ b/docs/src/pages/guides/composition/composition.md
@@ -133,7 +133,7 @@ You can find the details in the [TypeScript guide](/guides/typescript/#usage-of-
 The integration with third-party routing libraries is achieved with the `component` prop.
 The behavior is identical to the description of the prop above.
 Here are a few demos with [react-router-dom](https://github.com/ReactTraining/react-router).
-It covers the Button, Link, and List components, you should be able to apply the same strategy with all the components.
+They cover the Button, Link, and List components. You can apply the same strategy with all the components (BottomNavigation, Card, etc.).

 ### Button

Do you want to work on it?

I haven't included Tabs because we will get it covered in #18811

guoyunhe commented 4 years ago

I actually want to add links to BottomNavigationAction items.

For example, I have:

<BottomNavigation>
  <BottomNavigationAction label="Home" icon={<HomeIcon/>} component={ReactRouterLink} to="/" />
  <BottomNavigationAction label="Posts" icon={<ListIcon/>} component={ReactRouterLink} to="/posts" />
  <BottomNavigationAction label="Profile" icon={<PersonIcon/>} component={ReactRouterLink} to="/profile" />
</BottomNavigation>

It is very weird that when I type component, VS Code doesn't give prop hints as when typing it on other components, like Button, IconButton. So it makes me think that BottomNavigationAction doesn't support component prop. I don't know why this happen and how to fix it.

It will be more clear if here is an example on https://material-ui.com/components/bottom-navigation/ because most navigations are URL based.

guoyunhe commented 4 years ago

TypeScript component prop hints works for:

declare const BottomNavigation: OverridableComponent<BottomNavigationTypeMap>;
declare const Link: OverridableComponent<LinkTypeMap>;
declare const Divider: OverridableComponent<DividerTypeMap>;

not work for:

declare const BottomNavigationAction: ExtendButtonBase<BottomNavigationActionTypeMap<
  {},
  ButtonBaseTypeMap['defaultComponent']
>>;
declare const Tab: ExtendButtonBase<TabTypeMap>;
declare const Fab: ExtendButtonBase<FabTypeMap>;
declare const Button: ExtendButtonBase<ButtonTypeMap>;

So I guess TypeScript had some trouble to understand ExtendButtonBase and give hints of props.

I am using TypeScript 3.9.6.

Maxgit3 commented 4 years ago

I could take a look at this issue. Do I need to be assigned?

Maxgit3 commented 4 years ago

@oliviertassinari I created a component with the following code. I was able to import in the index.js page and it is working. maybe the issue that prevented next Link from working with the Material UI component was fixed.

import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import BottomNavigation from "@material-ui/core/BottomNavigation";
import BottomNavigationAction from "@material-ui/core/BottomNavigationAction";
import RestoreIcon from "@material-ui/icons/Restore";
import FavoriteIcon from "@material-ui/icons/Favorite";
import LocationOnIcon from "@material-ui/icons/LocationOn";

import Link from "next/link";

const useStyles = makeStyles({
  root: {
    width: 500,
  },
});

export default function SimpleBottomNavigation() {
  const classes = useStyles();
  const [value, setValue] = React.useState(0);

  return (
    <BottomNavigation
      value={value}
      onChange={(event, newValue) => {
        setValue(newValue);
      }}
      showLabels
      className={classes.root}
    >
      <Link href="/recents" >
        <a>
          <BottomNavigationAction label="Recents" icon={<RestoreIcon />} />
        </a>
      </Link  >
      <Link href="/favorites" >
        <a>
          <BottomNavigationAction label="Favorites" icon={<FavoriteIcon />} />
        </a>
      </Link>
      <Link href="/nearby" >
        <a>
          <BottomNavigationAction label="Nearby" icon={<LocationOnIcon />} />
        </a>
      </Link>
    </BottomNavigation>
  );
}
oliviertassinari commented 4 years ago

@Maxgit3 As far as I know, we never had any issue here. The only way to move forward I can see is to include all the components that are supported in the docs: https://github.com/mui-org/material-ui/issues/22001#issuecomment-666512512. Do you want to do it? :)

Maxgit3 commented 4 years ago

@oliviertassinari Sure, I will look into it.

topovik commented 3 years ago

A simple solution:

import { useRouter } from "next/router";
const router = useRouter();

  const onLink = (href) => {
    router.push(href);
  };

return (
    <BottomNavigation
      value={value}
      onChange={(event, newValue) => {
        setValue(newValue);
      }}
      showLabels
      className={classes.root}
    >
          <BottomNavigationAction label="Recents" icon={<RestoreIcon />} onClick={() => onLink("/recent")} />
          <BottomNavigationAction label="Favorites" icon={<FavoriteIcon />} onClick={() => onLink("/favorites")} />
          <BottomNavigationAction label="Nearby" icon={<LocationOnIcon />} onClick={() => onLink("/nearby")} />
    </BottomNavigation>
  )
mattholland0202 commented 3 years ago

Thanks @topovik - your solution fixed this issue for me and it's working well 😃

pankajgulabsharma commented 3 years ago

it works for me but i didn't understand why we are using useRouter instead of Link of nextjs.

tomsturge commented 3 years ago

The problem we are facing is that the BottomNavigationAction creates a button element and we want an anchor tag. A link driven by JS on a button is detrimental for SEO

sm3dev commented 3 years ago
      <BottomNavigationAction label="Recents" icon={<RestoreIcon />} onClick={() => onLink("/recent")} />

Thanks for this! This helped me and works with useNavigate too!

const navigate = useNavigate(); <BottomNavigationAction label="Recents" icon={<RestoreIcon />} onClick={() => navigate("recent")} />

ExoticCoder16 commented 2 years ago

A simple solution:

import { useRouter } from "next/router";
const router = useRouter();

  const onLink = (href) => {
    router.push(href);
  };

return (
    <BottomNavigation
      value={value}
      onChange={(event, newValue) => {
        setValue(newValue);
      }}
      showLabels
      className={classes.root}
    >
          <BottomNavigationAction label="Recents" icon={<RestoreIcon />} onClick={() => onLink("/recent")} />
          <BottomNavigationAction label="Favorites" icon={<FavoriteIcon />} onClick={() => onLink("/favorites")} />
          <BottomNavigationAction label="Nearby" icon={<LocationOnIcon />} onClick={() => onLink("/nearby")} />
    </BottomNavigation>
  )

how to route to the destined page with the tab bar keeping at the bottom? this code would change the entire page