Select Component in material UI [duplicate] - reactjs

I have a very simple select and when I click on the menu it shows 3 options, all on one-line each. However, when I select an item, it shows it on 2 lines: 1 line for the text and another for the icon. How do I make it so it is one line?
import "./styles.css";
import EditIcon from "#material-ui/icons/Edit";
import ListItemIcon from "#material-ui/core/ListItemIcon";
import ListItemText from "#material-ui/core/ListItemText";
import Select from "#material-ui/core/Select";
import FormControl from "#material-ui/core/FormControl";
import InputLabel from "#material-ui/core/InputLabel";
import MenuItem from "#material-ui/core/MenuItem";
import FormHelperText from "#material-ui/core/FormHelperText";
const items = ["a", "b", "c"];
export default function App() {
return (
<>
<FormControl>
<InputLabel>Please select an option</InputLabel>
<Select required defaultValue="hi" fullWidth>
{items.map((item, idx) => (
<MenuItem key={idx} value={item}>
<ListItemText primary={item} />
<ListItemIcon>
<EditIcon />
</ListItemIcon>
</MenuItem>
))}
</Select>
<FormHelperText>Just select something already</FormHelperText>
</FormControl>
</>
);
}
https://codesandbox.io/s/brave-stallman-9brmk?file=/src/App.js

The MenuItem layout is flex, while SelectInput is not, you can target the SelectInput using classes props and override the layout style like this:
See all possible rule names to override here.
<Select classes={{ select: classes.root }}
const useStyles = makeStyles({
root: {
display: "flex",
alignItems: "center"
}
});
Live Demo

You're using flex properties in .MuiListItemText-root and .MuiListItemIcon-root, but parent still has display: block. Your CSS for .MuiInputBase-input should look like this (changed display: block; to display: flex;):
.MuiInputBase-input {
font: inherit;
color: currentColor;
width: 100%;
border: 0;
height: 1.1876em;
margin: 0;
display: block;
padding: 6px 0 7px;
min-width: 0;
background: none;
box-sizing: content-box;
animation-name: mui-auto-fill-cancel;
letter-spacing: inherit;
animation-duration: 10ms;
-webkit-tap-highlight-color: transparent;
}

Related

Can't style #mui Avatar icon with styled-components

I'm playing around with styled-components and having troubles working with material-ui. So thats the code:
import React from "react";
import styled from "styled-components";
import ChatIcon from "#mui/icons-material/Chat";
import MoreVertIcon from "#mui/icons-material/MoreVert";
import { Avatar} from "#mui/material";
function Sidebar() {
return (
<Container>
<Header>
<UserAvatar className={"override"} />
<IconsContainer>
<IconButton>
<ChatIcon />
</IconButton>
<IconButton>
<MoreVertIcon />
</IconButton>
</IconsContainer>
</Header>
</Container>
);
}
export default Sidebar;
const Container = styled.div``;
const Header = styled.div`
display: flex;
position: sticky;
top: 0;
background-color: white;
z-index: 1;
justify-content: space-between;
align-items: center;
padding: 15px;
height: 80px;
border-bottom: 1px solid whitesmoke;
`;
const UserAvatar = styled(Avatar)`
height: 60px;
`;
const IconsContainer = styled.div`;
The styled div is working completely fine, but when I import 'Avatar' from #mui and try to add some styling named UserAvatar, it is completely ignoring what I'm writing down.
I think that with mui they have their own version of styled for styled components. https://mui.com/system/styled/
It appears they want you to use it rather than styled-components
import Button from '#mui/material/Button';
import { styled } from '#mui/material/styles';
const CustomButton = styled(Button)({
// your custom styles go here
}) as typeof Button;
see the import from import { styled } from '#mui/material/styles';;

Ant design Menu.Item custom style in react

Hi everyone i learning ant design with React + typescript. i need to override some default styles in Menu.Item components. but i have a problem with remove border-right style when user click that Menu.Item using styleComponent. i don't know the exact way but i inspect that component and i picked the className from inspection and made border-right: 3px solid transparent
but still it didn't work for me Here is the code i attach below
import { Layout, Menu } from "antd";
import React from "react";
import styled from "styled-components";
import { Flex } from "../styleComponents/commonUtilsStyles";
import {
MenuUnfoldOutlined,
MenuFoldOutlined,
UserOutlined,
VideoCameraOutlined,
UploadOutlined,
} from "#ant-design/icons";
import SubMenu from "antd/lib/menu/SubMenu";
const MenuItem = styled(Menu.Item)`
.ant-menu-vertical .ant-menu-item::after,
.ant-menu-vertical-left .ant-menu-item::after,
.ant-menu-vertical-right .ant-menu-item::after,
.ant-menu-inline .ant-menu-item::after {
border-right: 3px solid transparent !important;
}
`;
const { Header, Sider, Content } = Layout;
const FlexContainer = styled(Flex)`
background-color: white;
box-shadow: 6px 6px 32px #cccccc, -6px -6px 32px #f4f4f4;
`;
const HeaderContainer: React.FC = () => {
return (
<>
<Layout>
<Sider>
<Menu mode="inline">
<SubMenu key="submenu" title="number">
<MenuItem className="no-border" key="1">
one
</MenuItem>
<MenuItem className="no-border" key="2">
two
</MenuItem>
<MenuItem className="no-border" key="3">
three
</MenuItem>
</SubMenu>
<MenuItem className="no-border" key="11">
one 1
</MenuItem>
<MenuItem className="no-border" key="21">
two 1
</MenuItem>
<MenuItem className="no-border" key="31">
three 1
</MenuItem>
</Menu>
</Sider>
</Layout>
<h1>hello</h1>
</>
);
};
export default HeaderContainer;
output
but i need to remove that border line style when user click that menu it
Create a css file and set the border-right property to 0px for following classes to remove the right border.
index.css
.ant-menu-vertical .ant-menu-item::after,
.ant-menu-vertical-left .ant-menu-item::after,
.ant-menu-vertical-right .ant-menu-item::after,
.ant-menu-inline .ant-menu-item::after {
border-right: 0px;
}
Screenshot:
I found the best way is using Emotion React
import styled from "#emotion/styled";
import { Menu } from "antd";
and then overwrite the style (you need to inspect to know the antd css class)
/**
* ant-menu-item:hover::after
* ant-menu-item-selected
* ant-menu-item-selected:after
*/
const CustomMenu = styled(AntMenu)`
&& .ant-menu-item:hover::after {
border-bottom: 0px solid transparent;
}
&& .ant-menu-item-selected {
background-color: #EEF6F7;
border-top: 4px solid #B80012;
border-radius: 0px;
color: #B80012;
}
&& .ant-menu-item-selected:after {
border-bottom-width: 0px;
border-bottom-color: transparent;
}
`;
Finally, use it as a component
return (
<ConfigProvider theme={theme}>
<CustomMenu
onClick={onClick}
selectedKeys={[current]}
mode="horizontal"
items={menuItems}
{...props}
/>
</ConfigProvider>
);
This is how I test in Storybook
Custom AntDesign Horizontal menu
EXPLAINATION
Why can we do this?
Firstly, Emotion styled component' styled can style any component as long as it accepts a className prop. https://emotion.sh/docs/styled
Secondly, let's check Ant Design source code, go to Menu component, we will see index.tsx import InternalMenu in this line import InternalMenu from './menu';
Then, we go to menu.tsx, which export InternalMenu component and see its props here const InternalMenu = forwardRef<RcMenuRef, InternalMenuProps>((props, ref) => {...}
And scroll down, in the destructuring part it has const { prefixCls: customizePrefixCls, className,...restProps} = props;
=> Here you can see it accepts className props, which means you can apply what styled component approach which EmotionJS offers.
Have fun!
Binh Truong :)

How to use styled components with Material UI input?

I have a slight problem with Material UI input, I want to change the design of it using styled components, but I came across an issue. This is my code:
import React from "react";
import styled from "styled-components";
import Input from "#mui/material/Input";
import InputAdornment from "#mui/material/InputAdornment";
import { BiSearch } from "react-icons/bi";
const InputContainer = styled(Input)`
width: 350px;
height: 42px;
border-radius: 2px;
border: 1px solid #c0c0c0;
`;
const SearchIcon = styled(BiSearch)`
color: #c0c0c0;
margin-left: 14px;
`;
const InputComponent = ({ placeholder, type }) => {
return (
<div>
<InputContainer
placeholder={placeholder}
startAdornment={
type === "Search" ? (
<InputAdornment position="start">
<SearchIcon size="20" />
</InputAdornment>
) : (
""
)
}
/>
</div>
);
};
export default InputComponent;
What I want to do:
Change placeholder size
When user hovers or clicks on input there is no bottom border like there is now, basically I want to remove bottom border
How do I achieve this?
Change placeholder size
For this, you can target the input element and change the font size. e.g.
const InputContainer = styled(Input)`
width: 350px;
height: 42px;
border-radius: 2px;
border: 1px solid #c0c0c0;
input::placeholder {
font-size: 20px;
}
`;
When user hovers or clicks on input there is no bottom border like
there is now, basically I want to remove bottom border
For this, you can use the disableUnderline prop. e.g the updated code will be
<InputContainer
placeholder={placeholder}
disableUnderline
startAdornment={
type === "Search" ? (
<InputAdornment position="start">
<SearchIcon size="20" />
</InputAdornment>
) : (
""
)
}
/>

Custom Shadow Color for Paper

Is there a way to change only the box-shadow color for mui Paper component. I made my background black so it's shadow is not visible
I've used
createMuiTheme({
overrides: {
MuiPaper: {
root: {
boxShadow: "0 1px 6px 1px blue"
}
}
}
}
as you can see when I give that boxShadow setting every elevation from 0 to 24 uses it
What I need is a way to change just the shadow color, thanks for your help
You can change the shadow color , but for a specific elevate you will need to change values if you are using sass or css to over ride , using withStyle you can do it like this
Refer this sandbox
https://codesandbox.io/s/infallible-platform-kemqg?file=/src/App.js:0-682
import "./styles.css";
import { makeStyles } from "#material-ui/core/styles";
import Paper from "#material-ui/core/Paper";
const useStyles = makeStyles((theme) => ({
root: {
display: "flex",
flexWrap: "wrap",
"& > *": {
margin: theme.spacing(1),
width: theme.spacing(16),
height: theme.spacing(16),
boxShadow:
"0px 3px 1px -2px red,0px 2px 2px 0px rgba(100,0,0,0.9),0px 1px 5px 0px rgba(0,0,0,0.12)"
}
}
}));
export default function App() {
const classes = useStyles();
return (
<div className={classes.root}>
<Paper elevation={2} />
<Paper elevation={4} />
<Paper elevation={3} />
</div>
);
}

How to create Accordion using Card Component

I am using react-bootstrap 1.0.0-beta.3, which is build for supporting bootstrap 4 update.
Before this I was using react-bootstrap 0.32.1 and created Accordion using Panels and Panel group.
But after bootstrap upgrade it was suggested to Card component. I tried to achieve the same behavior like this:
<CardGroup>
<Card eventKey={this.state.eventKey} className="border-0">
<Card.Header>
<div className="row">
<div className="col-xs-9 col-sm-9 col-md-9 col-lg-9">
<Card.Title>
This is test
</Card.Title>
</div>
<div className="col-xs-3 col-sm-3 col-md-3 col-lg-3">
Test Text 123
</div>
</div>
</Card.Header>
<Card.Body>
Test Text 456
</Card.Body>
</Card>
</CardGroup>
I am facing couple of issues here:
How to make one card to take the full width.
How to make this structure behave like accordion.
Something like this:
You'll need to create custom components and css classNames.
Working example: https://codesandbox.io/s/8zkrw9jw50
components/Accordian.js
import React from "react";
import Card from "../../components/Card";
const panels = [
"Add Edit Menus",
"Resource Management",
"Asset Management",
"User Management",
"Account Management"
];
export default () => (
<div className="app-container">
<div className="accordion-container">
{panels.map(title => (
<Card key={title} title={title} />
))}
</div>
</div>
);
components/Card.js
import React, { Component } from "react";
import PropTypes from "prop-types";
import { Row, Col, Card } from "react-bootstrap";
import Collapse from "../Collapse";
import Button from "../Button";
const { Body, Header, Title } = Card;
class CardComponent extends Component {
state = { isActive: false };
toggleVisibility = () =>
this.setState(prevState => ({ isActive: !this.state.isActive }));
render = () => (
<div className={`${this.state.isActive ? "active" : "inactive"}`}>
<Card>
<Header style={{ padding: 0 }}>
<Row>
<Col xs={9}>
<Button onClick={this.toggleVisibility}>
{!this.state.isActive ? "+" : "-"}
</Button>
<Title style={{ display: "inline-block" }}>
{this.props.title}
</Title>
</Col>
<Col style={{ paddingTop: 7 }} xs={3}>
Test Text 123
</Col>
</Row>
</Header>
<Collapse>
<Body style={{ padding: 10 }}>Test Text 456</Body>
</Collapse>
</Card>
</div>
);
}
export default CardComponent;
CardComponent.propTypes = {
title: PropTypes.string.isRequired
};
components/Button.js
import styled from "styled-components";
const StyledButton = styled.button`
color: #909090;
background-color: transparent;
font-weight: bold;
outline: none;
border: 0;
cursor: pointer;
font-size: 22px;
transition: all 0.3s ease-in-out;
margin: 0 15px;
width: 25px;
&:hover {
color: #333333;
}
&:focus {
outline: none;
}
`;
export default StyledButton;
components/Collapse.js
import React from "react";
import PropTypes from "prop-types";
const Collapse = ({ children }) => (
<span className="folding-pannel">{children}</span>
);
export default Collapse;
Collapse.propTypes = {
children: PropTypes.node.isRequired
};
styles.css
.accordion-container {
width: 100%;
}
.app-container {
margin: 20px;
}
.active,
.inactive {
margin-bottom: 5px;
}
.active .folding-pannel {
transition: all 0.3s ease-in-out;
height: 42px;
}
.inactive .folding-pannel {
transform: perspective(0px) rotateX(90deg);
transition: all 0.3s ease-in-out;
height: 0;
}

Resources