Antd horizontal sub menu "floating" - javascript

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>
);
}

Related

Antd Menu - why is there space even when I use space-between property?

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.

Ant design - custom spacing between menu item

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>

Ant Design Sidebar Layout Example Not working as expected

I have a React webapp with Ant design component framework version 4.
I tried to use this example from Antd docs in my webapp:
https://codesandbox.io/s/ymspt
But I don't get the same result when I use the code in my webapp.
This is how it looks like in my app
import { MenuFoldOutlined, MenuUnfoldOutlined, UploadOutlined, UserOutlined, VideoCameraAddOutlined } from "#ant-design/icons";
import { Layout, Menu, Space } from "antd";
import { Content, Footer, Header } from "antd/lib/layout/layout";
import Sider from "antd/lib/layout/Sider";
import React, { useState } from "react";
import { logOut } from "../firebase";
function Lineups() {
const [collapsed, setCollapsed] = useState(false);
const [logoText, setLogoText] = useState("TEAMTAC");
const toggle = () => {
setCollapsed(!collapsed);
collapsed ? setLogoText("TEAMTAC") : setLogoText("TT")
};
const signOutFirebase = async () => {
await logOut();
}
return (
<Layout style={{ minHeight: '100vh' }}>
<Sider collapsible collapsed={collapsed} onCollapse={toggle}>
<h2 style={{textAlign:"center", marginTop: 15}}>{logoText}</h2>
<Menu theme="dark" mode="inline" defaultSelectedKeys={['1']}>
<Menu.Item key="1" icon={<UserOutlined />}>
nav 1
</Menu.Item>
<Menu.Item key="2" icon={<VideoCameraAddOutlined />}>
nav 2
</Menu.Item>
<Menu.Item key="3" icon={<UploadOutlined />}>
nav 3
</Menu.Item>
</Menu>
</Sider>
<Layout className="site-layout">
<Header style={{ padding: 5 }}>
Header
</Header>
<Content
style={{
margin: '24px 16px',
padding: 24,
minHeight: 280,
}}
>
Content
</Content>
<Footer style={{ textAlign: 'center' }}>Ant Design ©2018 Created by Ant UED</Footer>
</Layout>
</Layout>
)
}
export default Lineups;
I dont have any extra css or whatever.
How come that I don't get the same result?
Problem were the components which Ive imported.
I did it the wrong way.
So instead of
import { Content, Footer, Header } from "antd/lib/layout/layout";
I had to do
import { Layout } from "antd";
...
const { Header, Footer, Sider, Content } = Layout;

ReactJs not defined

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.

How to customize and change color of a menu in ant design?

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

Categories

Resources