I'm playing around with ant-design and trying to structure a simple menu, and everything works as expected:
<Menu mode="inline">
<Menu.Item key="/">
<Icon type="dashboard" theme="outlined" />
Dashboard
</Menu.Item>
<Menu.Item key="/transactions">
<Icon type="bars" theme="outlined" />
Transactions
</Menu.Item>
<Menu.Item key="/groups">
<Icon type="team" theme="outlined" />
Groups
</Menu.Item>
<Menu.Item key="/account">
<Icon type="idcard" theme="outlined" />
Account
</Menu.Item>
</Menu>
(https://codesandbox.io/s/wqn37ojmv7)
Now, I wanted to DRY up this code a bit, by making a separate wrapped MenuItem component:
const MenuItem = ({route, icon, children}) => (
<Menu.Item key={route}>
<Icon type={icon} theme="outlined" />
{children}
</Menu.Item>
);
// ...
<Menu mode="inline">
<MenuItem route="/" icon="dashboard">Dashboard</MenuItem>
<MenuItem route="/transactions" icon="bars">Transactions</MenuItem>
<MenuItem route="/groups" icon="team">Groups</MenuItem>
<MenuItem route="/account" icon="idcard">Account</MenuItem>
</Menu>
However, substituting my shiny new component will pretty much break everything - somehow I seem to lose some props that were magically passed to the Menu.Items before (like a clsPrefix or a onItemHover-callback): https://codesandbox.io/s/ojyqy0oqq6
What is going on here? How are these props passed behind the scenes and how can I wrap Menu.Item correctly without losing all of this magic?
You could pass the rest of the passed props
const MenuItem = ({route, icon, children, ...props}) => (
<Menu.Item key={route} {...props}>
<Icon type={icon} theme="outlined" />
{children}
</Menu.Item> );
Related
I have old code condition for user login in AntDesign Menu
Terminal says version of menu Item is old. Here is some code
{ <Menu onClick={handleClick} selectedKeys={[current]} mode="horizontal">
{!user && (
<Menu.Item key="register" icon={<UserAddOutlined />}>
<Link to="/register">Đăng kí</Link>
</Menu.Item>
)}
{!user && (
<Menu.Item key="login" icon={<UserOutlined />}>
<Link to="/login">Đăng nhập</Link>
</Menu.Item>
)}
</Menu> }
I want to know how to write it in the newest version. Can anyone give me some information?
I have an appBar and the homepage would appear behind the appbar. I wanted it to appear below it. This is what it looks like:
The AppBar codes:
const Header = () => {
const [value, setValue] = React.useState(0);
const handleChange = (event, newValue) => {
setValue(newValue);
};
//Breakpoints
const theme = useTheme();
const isMatch = useMediaQuery(theme.breakpoints.down("md"));
return (
<div>
<AppBar>
<Toolbar>
{/* //or just change this typography to an icon or picture */}
<Typography>Website</Typography>
{isMatch ? (
<h1>
<DrawerComponent />
</h1>
) : (
<Tabs
value={value}
indicatorColor="secondary"
onChange={handleChange}
aria-label="simple tabs example"
>
<Tab disableRipple label="Homepage" to="/" component={Link} />
<Tab disableRipple label="Login" to="/login" component={Link} />
<Tab disableRipple label="Settings" />
<Tab disableRipple label="Sample1" />
<Tab disableRipple label="Sample2" />
<Tab disableRipple label="Sample3" />
</Tabs>
)}
</Toolbar>
</AppBar>
</div>
);
};
export default Header;
I need to put a <br/> just to see the homepage:
const Homepage = (props) => {
return (
<section>
<br />
<h1>Homepage</h1>
</section>
);
};
export default Homepage;
And I have this drawerComponent for small screen sizes, it even got worse, you won't be able to see any message anymore not unless there will be a lot of <br/> before the message.
const DrawerComponent = () => {
const useStyles = makeStyles((theme) => ({
drawerContainer: {},
iconButtonContainer: {
marginLeft: "auto",
color: "white",
},
menuIconToggle: {
fontSize: "3rem",
},
link: {
textDecoration: "none",
},
}));
const [openDrawer, setOpenDrawer] = useState(false);
//Css
const classes = useStyles();
return (
<div>
<Drawer
anchor="left"
classes={{ paper: classes.drawerContainer }}
onClose={() => setOpenDrawer(false)}
open={openDrawer}
onOpen={() => setOpenDrawer(true)}
>
<List className={classes.link}>
<Link to="/">
<ListItem divider button onClick={() => setOpenDrawer(false)}>
<ListItemIcon>
<ListItemText> Homepage</ListItemText>
</ListItemIcon>
</ListItem>
</Link>
<Link to="/login">
<ListItem divider button onClick={() => setOpenDrawer(false)}>
<ListItemIcon>
<ListItemText> Login</ListItemText>
</ListItemIcon>
</ListItem>
</Link>
<ListItem divider button onClick={() => setOpenDrawer(false)}>
<ListItemIcon>
<ListItemText>Sample</ListItemText>
</ListItemIcon>
</ListItem>
<ListItem divider button onClick={() => setOpenDrawer(false)}>
<ListItemIcon>
<ListItemText> Sample</ListItemText>
</ListItemIcon>
</ListItem>
</List>
</Drawer>
<IconButton
edge="end"
className={classes.iconButtonContainer}
onClick={() => setOpenDrawer(!openDrawer)}
disableRipple
>
<MenuIcon className={classes.menuIconToggle} />
</IconButton>
</div>
);
};
export default DrawerComponent;
A way around this would be to add a margin-top or a padding-top to your homepage component equal to the height of the appbar.
Yet, a better approach would be ro use the following CSS properties on your appBar.
.app-bar {
position: sticky;
top: 0;
}
This will make your appbar stick to the top and will automatically adjust the height of its following DOM elements.
This post may answer your question: Creating a navbar with material-ui
You can either try:
Using CSS to implement padding-top (use "em" instead of "px" for a responsive padding height)
Reorganising your React components, making sure that the header (appbar) is not in the page, but rather a component at the same level (refer to the post linked above)
In this first example of horizontal menu, I want to change "Navigation Three - Submenu" to open onClick instead onHover and want to add toggle icon (up and down arrow) next to it as well.
In this case, you need to implement your own menu using Tabs component.
Here is the idea of how it's done, you need to add animations on revealing the menu and switching the up/down arrows.
<Tabs onTabClick={() => setShowMenu(prev => !prev)}>
<Tabs.TabPane
tab={
<>
<Icon type="setting" />
Navigation Three - Submenu
<Icon type={showMenu ? "up" : "down"} style={{ marginLeft: "10px" }} />
</>
}
/>
</Tabs>;
{
showMenu && (
<Menu>
<Menu.ItemGroup title="Item 1">
<Menu.Item key="setting:1">Option 1</Menu.Item>
<Menu.Item key="setting:2">Option 2</Menu.Item>
</Menu.ItemGroup>
<Menu.ItemGroup title="Item 2">
<Menu.Item key="setting:3">Option 3</Menu.Item>
<Menu.Item key="setting:4">Option 4</Menu.Item>
</Menu.ItemGroup>
</Menu>
);
}
Demo:
I am using react-toolbox menu for my website. Based on the example given in the documentation React-toolbox menu, I can only use icon as my menu. How can I use text for the menu instead?
Example of what I want to do:
When I click the blog text which is a menu, the menuItem will be shown.
Is it possible to do this?
just remove icon property from MenuItem component
<IconMenu icon={<div>blog</div>} position='topLeft' menuRipple>
<MenuItem value='download' caption='Download' />
<MenuItem value='help' caption='Favorite' />
<MenuItem value='settings' caption='Open in app' />
<MenuDivider />
<MenuItem value='signout' icon='delete' caption='Delete' disabled />
</IconMenu>
You can pass an element to the icon property like that:
<IconMenu icon={<div>Menu</div>} position='topLeft' menuRipple>
In case someone else has the problem, the solution is to use Menu component instead of IconMenu. Like this :
const [menuActive, setMenuActive] = useState(false);
return (
<div style={{ position: 'relative' }}>
<Button label='Actions' onClick={() => setMenuActive(!menuActive)} />
<Menu position='topRight' active={menuActive} onHide={() => setMenuActive(false)}>
<MenuItem value='download' caption='Download' />
<MenuItem value='action' caption='Action' />
</Menu>
</div>
);
I am new to ReactJS and have an issue with using "Menu.Item" (from Semantic UI React) and React Router.
My imports etc will be left out of the below code but they are all working fine.
My "App.jsx" constructor is as follows:
constructor(props) {
super(props);
this.state = {
activeItem: 'home',
loading: true,
messages: [],
};
}
The "App.jsx" render return is this:
<Router>
<Container className="main">
<Navbar
onItemClick={selected => this.setState({ activeItem: selected })}
isActive={this.state.activeItem}
/>
<Container className="main-content">
<Switch>
<Route exact path="/" component={Home} />
<Route path="/dashboard" component={Dashboard} />
<Route path="/user" component={User} />
</Switch>
</Container>
</Container>
</Router>
For clarification, the Home, User, and Dashboard components are just simple Div's that has their respective names in them.
My Navbar is as follows:
class Navbar extends Component {
onItemChange = (e, { name }) => this.props.onItemClick(name);
render() {
return (
<div>
<Container>
<Menu secondary stackable widths={4}>
<Menu.Item>
<img src={Logo} alt="header" />
</Menu.Item>
<Menu.Item
as={NavLink}
to="/"
name="home"
active={this.props.isActive === 'home'}
onClick={(event, name) => this.handleClick(name.name, name.to)}
>
<Icon name="home" size="large" />
<p>Home</p>
</Menu.Item>
<Menu.Item
as={NavLink}
to="/dashboard"
name="Data"
active={this.props.isActive === 'Data'}
onClick={this.onItemChange}
>
<Icon name="dashboard" size="large" />
<p>Dashboard</p>
</Menu.Item>
<Menu.Item
as={NavLink}
to="/user"
name="user"
active={this.props.isActive === 'user'}
onClick={this.onItemChange}
>
<Icon name="user" size="large" />
<p>User</p>
</Menu.Item>
</Menu>
</Container>
</div>
);
}
}
As you can see from the above Navbar, I am using NavLink within the Menu.Item.
Here is where the issue arises. When I start my application it works fine, 'home' is displayed, however when I click on a link in the Menu, the application crashes.
Any ideas on how to fix this? I also want to have it that the 'isActive' will update with the current route in the menu.
Any input would be greatly appreciated.
I fixed it for anyone looking into it by simplifying the code, here is the Navbar component:
const Navbar = () => (
<div>
<Container>
<Menu secondary stackable widths={4}>
<Menu.Item>
<img src={Logo} alt="header" />
</Menu.Item>
<Menu.Item as={NavLink} to="/" name="home">
<Icon name="home" size="large" />
<p>Home</p>
</Menu.Item>
<Menu.Item as={NavLink} to="/data" name="data">
<Icon name="dashboard" size="large" />
<p>Dashboard</p>
</Menu.Item>
<Menu.Item as={NavLink} to="/user" name="user">
<Icon name="user" size="large" />
<p>User</p>
</Menu.Item>
</Menu>
</Container>
</div>
);
Less does more, it seems. Hope this helps anyone.