I have a Menu Component
As you can see, there are two problems on the Menu Component
1. The padding-left and padding-right(red arrows) are not the same
2. The spacing between MenuItem(blue arrows) is not the same.
How can I update the styles to fix above problems?
demo.js
import React from "react";
import "antd/dist/antd.css";
import "./index.css";
import { Menu } from "antd";
import {
MailOutlined,
AppstoreOutlined,
SettingOutlined
} from "#ant-design/icons";
const App = () => (
<Menu
mode="horizontal"
defaultSelectedKeys={["mail"]}
style={{ border: "1px solid grey", justifyContent: "space-between" }}
>
<Menu.Item key="mail" icon={<MailOutlined />}>
Navigation One
</Menu.Item>
<Menu.SubMenu
key="SubMenu"
title="Navigation Two - Submenu"
icon={<SettingOutlined />}
>
<Menu.Item key="two" icon={<AppstoreOutlined />}>
Navigation Two
</Menu.Item>
<Menu.Item key="three" icon={<AppstoreOutlined />}>
Navigation Three
</Menu.Item>
<Menu.ItemGroup title="Item Group">
<Menu.Item key="four" icon={<AppstoreOutlined />}>
Navigation Four
</Menu.Item>
<Menu.Item key="five" icon={<AppstoreOutlined />}>
Navigation Five
</Menu.Item>
</Menu.ItemGroup>
</Menu.SubMenu>
<Menu.Item key="mail" icon={<MailOutlined />}>
Navigation Six
</Menu.Item>
</Menu>
);
export default App;
CodeSandbox
https://codesandbox.io/s/basic-usage-deprecated-syntactic-sugar-antd-4-22-4-forked-m4p6vh
you can put all menu options in one nav tag, and add menubar class to it.
CSS
.menubar {
/*current style properties + */
display: flex;
justify-content: space-between;
align-items: center;
}
My suggestion would be, that you should use Flex for aligning the UI. Flex will work in any size of screen size. And moreover coming to your problem, it can be solved by the below example
.yourClassName{
display:flex;
justify-content:'space-evenly'
};
Space evenly will add space to all elements in the class regardless of their size
I'm not sure if you want to spread it across the entire width but a nice solution is to put it between <Space></Space> (have a look here: https://ant.design/components/space/):
<Space>
<Menu
mode="horizontal"
defaultSelectedKeys={["mail"]}
style={{ border: "1px solid grey", justifyContent: "space-between" }}
>
<Menu.Item key="mail" icon={<MailOutlined />}>
Navigation One
</Menu.Item>
<Menu.SubMenu
key="SubMenu"
title="Navigation Two - Submenu"
icon={<SettingOutlined />}
>
<Menu.Item key="two" icon={<AppstoreOutlined />}>
Navigation Two
</Menu.Item>
<Menu.Item key="three" icon={<AppstoreOutlined />}>
Navigation Three
</Menu.Item>
<Menu.ItemGroup title="Item Group">
<Menu.Item key="four" icon={<AppstoreOutlined />}>
Navigation Four
</Menu.Item>
<Menu.Item key="five" icon={<AppstoreOutlined />}>
Navigation Five
</Menu.Item>
</Menu.ItemGroup>
</Menu.SubMenu>
<Menu.Item key="mail" icon={<MailOutlined />}>
Navigation Six
</Menu.Item>
</Menu>
</Space>
Related
I've already used justify-content: space-between, but there are still spacing in the front and last.
demo.js
import React from "react";
import "antd/dist/antd.css";
import "./index.css";
import { Menu } from "antd";
import {
MailOutlined,
AppstoreOutlined,
SettingOutlined
} from "#ant-design/icons";
const App = () => (
<Menu
mode="horizontal"
defaultSelectedKeys={["mail"]}
style={{ border: "1px solid grey", justifyContent: "space-between" }}
>
<Menu.Item key="mail" icon={<MailOutlined />}>
Navigation One
</Menu.Item>
<Menu.SubMenu
key="SubMenu"
title="Navigation Two - Submenu"
icon={<SettingOutlined />}
>
<Menu.Item key="two" icon={<AppstoreOutlined />}>
Navigation Two
</Menu.Item>
<Menu.Item key="three" icon={<AppstoreOutlined />}>
Navigation Three
</Menu.Item>
<Menu.ItemGroup title="Item Group">
<Menu.Item key="four" icon={<AppstoreOutlined />}>
Navigation Four
</Menu.Item>
<Menu.Item key="five" icon={<AppstoreOutlined />}>
Navigation Five
</Menu.Item>
</Menu.ItemGroup>
</Menu.SubMenu>
<Menu.Item key="mail" icon={<MailOutlined />}>
Navigation Six
</Menu.Item>
</Menu>
);
export default App;
CodeSandbox
https://codesandbox.io/s/basic-usage-deprecated-syntactic-sugar-antd-4-22-4-forked-m4p6vh
The CSS justify-content property defines how a browser distributes
available space between and around elements when aligning flex items
in the main-axis of the current line. The alignment is done after the
lengths and auto margins are applied, meaning that, if there is at
least one flexible element, with flex-grow different than 0, it will have no effect as there won't be any available space.
Since you use pseudoelements, it takes it as one of items. By removing :before it should work
You have:
.ant-menu::before {
display: table;
content: '';
}
Remove content: '', or this ::before pseudoelement at all.
I have little problems with my ReactJs app, I'm receiving message like:
./src/components/Navbar/index.js
Line 13:3: 'state' is not defined no-undef
Line 17:3: 'handleClick' is not defined no-undef
I'm beginner with JavaScript and it's seams it's easy fix, I just copied that code from another app where it works.
This is my code:
import React, { useState } from 'react';
import { Layout, Menu, Drawer, Icon } from 'antd';
import { Mobile, Default } from '../Responsive';
import './index.less';
const { Header } = Layout;
const { SubMenu } = Menu;
const Navbar = props => {
state = {
current: 'home',
};
handleClick = e => {
console.log('click ', e);
this.setState({
current: e.key,
});
};
const [visible, setVisible] = useState(false);
const menu = (
<Menu
theme="lite"
mode="horizontal"
defaultSelectedKeys={['2']}
style={{ lineHeight: '64px' }}
onClick={this.handleClick} selectedKeys={[this.state.current]} mode="horizontal">
<Menu.Item key="mail">
<Icon type="mail" />
Navigation One
</Menu.Item>
<Menu.Item key="app" disabled>
<Icon type="appstore" />
Navigation Two
</Menu.Item>
<SubMenu
title={
<span className="submenu-title-wrapper">
<Icon type="setting" />
Navigation Three - Submenu
</span>
}
>
<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>
</SubMenu>
<Menu.Item key="alipay">
<a href="https://ant.design" target="_blank" rel="noopener noreferrer">
Navigation Four - Link
</a>
</Menu.Item>
</Menu>
);
return (
<Header className="app-header">
<Default>{menu}</Default>
<Mobile>
<Icon type="bars" size="large" className="nav-icon" onClick={() => setVisible(true)} />
<Drawer
title=""
placement="left"
closable
onClose={() => setVisible(false)}
visible={visible}
className="nav-drawer"
>
{menu}
</Drawer>
</Mobile>
</Header>
);
};
export default Navbar;
I copied this state and handleClick from another app but it was class, I tried to change const Navbar with class NavBar extends Component but no success.
You are mixing react components and react hooks. You should either use hook (useState), or components (this).
Here is your code with hooks
import React, { useState } from 'react';
import { Layout, Menu, Drawer, Icon } from 'antd';
import { Mobile, Default } from '../Responsive';
import './index.less';
const { Header } = Layout;
const { SubMenu } = Menu;
function Navbar(props) {
const [current, setCurrent] = useState('home');
const [visible, setVisible] = useState(false);
function handleClick(e) {
console.log('click ', e);
setCurrent(e.key)
};
const menu = (
<Menu
theme="lite"
mode="horizontal"
defaultSelectedKeys={['2']}
style={{ lineHeight: '64px' }}
onClick={this.handleClick} selectedKeys={[current]} mode="horizontal">
<Menu.Item key="mail">
<Icon type="mail" />
Navigation One
</Menu.Item>
<Menu.Item key="app" disabled>
<Icon type="appstore" />
Navigation Two
</Menu.Item>
<SubMenu
title={
<span className="submenu-title-wrapper">
<Icon type="setting" />
Navigation Three - Submenu
</span>
}
>
<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>
</SubMenu>
<Menu.Item key="alipay">
<a href="https://ant.design" target="_blank" rel="noopener noreferrer">
Navigation Four - Link
</a>
</Menu.Item>
</Menu>
);
return (
<Header className="app-header">
<Default>{menu}</Default>
<Mobile>
<Icon type="bars" size="large" className="nav-icon" onClick={() => setVisible(true)} />
<Drawer
title=""
placement="left"
closable
onClose={() => setVisible(false)}
visible={visible}
className="nav-drawer"
>
{menu}
</Drawer>
</Mobile>
</Header>
);
};
export default Navbar;
Everything else looks fine except:
const [current, setCurrent] = useState('home') ;
const handleClick = e => {
console.log('click ', e);
setCurrent(e.key);
};
Actually you have to convert the this.state to hook as well.
I have created a react 16.8 application and am using react-router-dom. I built the Navigation Bar with React Semantic UI library. My Problem is that when I click the Menu Item Navlink the App changes the url however, it does not rerender the app with the new component that matches the path. I have tried various fixes to no avail. I have used Switch I have used Navlink, I have used withRouter. I tried to do a componentDidUnmount. When I refresh the app the component I am looking for does work. It just doesnt change when I click the navigation link. Here is my code. I am only asking because I have no other option and all the other answers are so outdated.
The App.js
import React from 'react';
import {BrowserRouter, Route, withRouter, Switch} from 'react-router-dom'
import Landing from './components/Landing/Landing'
import Sales from './components/Dashboard/Sales/Sales'
import Orders from './components/Dashboard/Orders/Orders'
import Returns from './components/Dashboard/Returns/Returns'
import DailySales from './components/Reports/Sales/DailySales/DailySales';
function App() {
return (
<BrowserRouter>
<div className='App'>
<Switch>
<Route path="/" exact component={withRouter(Landing)} />
<Route path="/dashboards/sales" exact component={withRouter(Sales)} />
<Route path="/dashboards/orders" exact component={withRouter(Orders)} />
<Route path="/dashboards/returns" component={withRouter(Returns)} />
<Route path="/reports/dailysales/" component={withRouter(DailySales)} />
</Switch>
</div>
</BrowserRouter>
);
}
export default App;
And the Navigation component
import React from 'react'
import logo_icon from '../../../../assets/images/logo_icon.png'
import { Dropdown , Menu, Image } from 'semantic-ui-react'
import { BrowserRouter, Route ,Link, NavLink , withRouter ,Switch} from 'react-router-dom'
import Landing from '../../../Landing/Landing'
import Sales from '../../../Dashboard/Sales/Sales'
const Navigation = () => (
<BrowserRouter>
<Menu className="ui secondary">
{/* Menu Icon */}
<Link to="/dashboards/sales">
<Dropdown.Item>
<Image className="item headLogo" src={logo_icon} />
</Dropdown.Item>
</Link>
{/* End of Menu Icon */}
{/* Here is Sales Dropdown */}
<Dropdown className="ui dropdown item" text="Sales" icon="dropdown">
<Dropdown.Menu>
<Menu.Item className="item" as={ NavLink } exact to="/dashboards/sales" name="Dashboard" />
<Dropdown className="ui dropdown link item" text="Reports">
<Dropdown.Menu>
<Menu.Item className="ui dropdown link item" as={ Link } to="/dashboards/sales" name="Daily Sales"/>
<Menu.Item className="ui dropdown link item" as={ Link } to="/dashboards/sales" name="Sales Summary"/>
<Menu.Item className="ui dropdown link item" as={ Link } to="/dashboards/sales" name="Profit Margin"/>
</Dropdown.Menu>
</Dropdown>
</Dropdown.Menu>
</Dropdown>
{/* End of Sales Dropdown */}
{/* Here is Customer Service Dropdown */}
<Dropdown className="ui dropdown item" text="Customer Service">
<Dropdown.Menu>
<Dropdown className="ui dropdown link item" text="Reports">
<Dropdown.Menu>
<Menu.Item className="ui dropdown link item" as={ Link } to="/dashboards/orders" name="Service Level(Voice)"/>
</Dropdown.Menu>
</Dropdown>
</Dropdown.Menu>
</Dropdown>
{/* End of Customer Service Dropdown */}
{/* Here is Order Management Dropdown */}
<Dropdown className="ui dropdown item" text="Order Management">
<Dropdown.Menu>
<Menu.Item className="ui dropdown link item" as={ Link } to="/dashboards/orders" name="Dashboard"/>
<Menu.Item className="ui dropdown link item" as={ Link } to="/dashboards/orders" name="Fishbowl Anywhere"/>
<Menu.Item className="ui dropdown link item" as={ Link } to="/dashboards/orders" name="Search Orders"/>
</Dropdown.Menu>
</Dropdown>
{/*End of Order Management Dropdown */}
{/*Here is Inventory Management Dropdown */}
<Dropdown className="ui dropdown item" text="Inventory Management">
<Dropdown.Menu>
<Menu.Item className="ui dropdown link item" as={ Link } to="/dashboards/orders" name="View Inventory"/>
<Menu.Item className="ui dropdown link item" as={ Link } to="/dashboards/orders" name="Monitor Inventory"/>
</Dropdown.Menu>
</Dropdown>
{/*End of Inventory Management Dropdown */}
{/*Here is Returns Dropdown */}
<Dropdown className="ui dropdown item" text="Returns" icon="dropdown">
<Dropdown.Menu>
<Menu.Item className="item" as={ Link } to="/dashboards/orders" name="Dashboard" />
<Menu.Item className="item" as={ Link } to="/dashboards/orders" name="Search Returns" />
<Dropdown className="ui dropdown link item" text="Reports">
<Dropdown.Menu>
<Menu.Item className="ui dropdown link item" as={ Link } to="/dashboards/orders" name="Weekly Returns"/>
</Dropdown.Menu>
</Dropdown>
</Dropdown.Menu>
</Dropdown>
{/*End of returns Dropdown */}
</Menu>
</BrowserRouter>
)
export default withRouter(Navigation);
Try taking BrowserRouter off of your Navigation component
I'm currently using reactJs along with ant design to help me build a website. However, I've stumbled upon a problem. I can change the actual color of a menu, but I can't change the color of the menu item when it's been selected, or when the mouse is hovering over it. Here's the menu, Menu Image I want to change that white to a light green, but I haven't found any way to directly access it and change it. Also, I don't want to use LESS to do it.
Does anyone know how to fix this? Here's my code for the layout.
import { Layout, Menu, Icon, Row, Button, Col } from 'antd';
import React, { Component } from 'react'
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
const { Header, Sider, Content } = Layout;
const { SubMenu } = Menu;
class BasicLayout extends React.Component {
state = {
collapsed: false,
path: this.path
};
toggle = () => {
this.setState({
collapsed: !this.state.collapsed,
});
};
render() {
return (
<Layout>
<Sider className='ant-menu' trigger={null} collapsible collapsed={this.state.collapsed}>
<div className="logo" />
<Menu className='ant-menu' mode="inline" defaultSelectedKeys={['1']}>
<Menu.Item key="1" >
<Link to='/'>
<Icon type="home" />
<span>Home</span>
</Link>
</Menu.Item>
<Menu.Item key="2">
<Link to='/about'>
<Icon type="plus" />
<span>About</span>
</Link>
</Menu.Item>
<SubMenu key="3" title={<span><Icon type="database" /><span>Directory</span></span>}>
<Menu.Item>
<Link to='/resources/living'>
<span>Living Resources</span>
</Link>
</Menu.Item>
<Menu.Item>
<Link to='/water2'>
<span>Non-Living Resources</span>
</Link>
</Menu.Item>
<Menu.Item>
<Link to='/resources/recycle'>
<span>Recycling Resources</span>
</Link>
</Menu.Item>
<Menu.Item>
<Link to='/resources/reducing'>
<span>Reducing Resources</span>
</Link>
</Menu.Item>
<Menu.Item>
<Link to='/resources'>
<span>General</span>
</Link>
</Menu.Item>
</SubMenu>
</Menu>
</Sider>
<Layout>
<Header style={{ background: '#fff', padding: 0 }}>
<Icon
className="trigger"
type={this.state.collapsed ? 'menu-unfold' : 'menu-fold'}
onClick={this.toggle}
/>
</Header>
<Content
style={{
margin: '24px 16px',
padding: 24,
background: '#fff',
minHeight: 280,
}}
>
{this.props.children}
</Content>
</Layout>
</Layout>
);
}
}
export default BasicLayout;
You need to change Link to NavLink and add attribute activeClassName
<NavLink to="/portoflio" activeClassName="your-active-class" className="link">Portoflio</NavLink>
For the hover options you can achieve it only with css
a.link:hover {
/*Any style you want to have link on mouse over*/
background-color: yellow;
}
.your-active-class{
/*Any style you want to have link that is active*/
background-color: yellow;
}
https://www.w3schools.com/cssref/sel_hover.asp
I have a very simple antd menu which I used following their docs. However, when the submenu opens it is floating (not attached to the main menu) and it really doesn't look good.
How do I fix this?
This is what my code currently looks like:
export function MainMenu () {
return (
<AntdLayout>
<Menu mode='horizontal' theme='dark' style={{ position: 'fixed', zIndex: 1, width: '100%', marginBottom: 100 }}>
<Menu.Item key='home'>
Home
</Menu.Item>
<SubMenu key='submenu' title='SubMenu'>
<Menu.Item key='1'>
Option 1
</Menu.Item>
<Menu.Item key='2'>
Option 2
</Menu.Item>
</SubMenu>
<Menu.Item key='contact'>
Contact
</Menu.Item>
</Menu>
</AntdLayout>
)
}
Here is a screenshot of what it looks like:
As its not adviced because Ant is a design system, you can achieve it by targeting the .ant-menu-submenu > .ant-menu selectors:
/* ./App.css */
.ant-menu-submenu > .ant-menu {
margin-top: -5px;
}
// index.js
import { Layout, Menu } from 'antd';
import 'antd/dist/antd.css';
import './App.css';
function MainMenu() {
return (
<Layout>
<Menu mode="horizontal" openKeys={['submenu']}>
<Menu.Item key="home">Home</Menu.Item>
<Menu.SubMenu
key="submenu"
title="SubMenu"
>
<Menu.Item key="1">Option 1</Menu.Item>
<Menu.Item key="2">Option 2</Menu.Item>
</Menu.SubMenu>
<Menu.Item key="contact">Contact</Menu.Item>
</Menu>
</Layout>
);
}