How to use styled components with Material UI input? - reactjs

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>
) : (
""
)
}
/>

Related

How to select the last element which is of the component's type in styled-components

I want to select the last element which is of my component's type.
I have a InputGroup component that has a margin of 0px.
I also have a form, which is where I use the InputGroup component multiple times.
<form>
<InputGroup
label="Email ou Usuário"
borderColor={borderEmail}
icon={emailIcon}
type="email"
placeholder="Digite seu Email"
onChange={e => setEmail(e.target.value)}
value={email}
/>
<InputGroup
label="Senha"
borderColor={borderSenha}
icon={passwordIcon}
type="password"
placeholder="Digite sua Senha"
onChange={e => setSenha(e.target.value)}
value={senha}
/>
<ButtonsContainer>
<LoginButton type="submit">Entrar</LoginButton>
<p>OU</p>
<GoogleButton>
<img src={googleLogo} alt="" />
<p>Log In with Google</p>
</GoogleButton>
</ButtonsContainer>
</form>
My goal is to make the bottom margin of the last InputGroup to 55px, but when I use &: last-of-type the margin only appears if I remove my ButtonsContainer component.
I think it has something to do with the Container of the InputGroup being a div, and the Container of the ButtonsContainer as well, but I don't know how to solve this.
InputGroup/index.jsx:
import React from 'react';
import {
Container,
Label,
ContainerInput,
Input
} from './styles';
const InputGroup = ({
label,
borderColor,
icon,
type,
value,
onChange,
placeholder,
mask,
maskChar,
onKeyDown
}) => (
<Container>
<Label>{label}</Label>
<ContainerInput borderColor={borderColor}>
<img src={icon} alt="" />
<Input
type={type}
value={value}
onChange={onChange}
placeholder={placeholder}
onKeyDown={onKeyDown}
/>
</ContainerInput>
</Container>
);
export default InputGroup;
InputGroup/styles.js:
import styled from 'styled-components';
export const Container = styled.div`
width: 100%;
& + & {
margin-top: 24px;
}
:last-of-type {
margin-bottom: 55px;
}
`;
export const Label = styled.label`
font: normal 500 12px/16px var(--font-fourth);
`;
export const ContainerInput = styled.div`
width: 100%;
height: 40px;
display: flex;
align-items: center;
margin-top: 8px;
border: 1px solid;
border-color: ${({ borderColor }) => borderColor};
border-radius: 20px;
transition: border-color 0.15s;
:focus-within{
border-color: #1904E5;
}
img{
width: 16px;
height: 16px;
margin: 12px 8px 12px 12px;
}
`;
export const Input = styled.input`
width: 100%;
height: 100%;
border-radius: 0 20px 20px 0;
border: none;
color: #575172;
font: normal 500 12px/16px var(--font-primary);
:hover{
cursor: pointer;
}
::placeholder{
color: #575172;
font: normal 500 12px/16px var(--font-primary);
}
`;
EDIT:
Things like "add a container around entries" have already responded, but if I did this I would have to do the same every time I used the component, it would break the reusability of the component as I would have to do the same thing over and over again. everytime. But if there is no other way I do it, because it works too
Wrap InputGroup components with a fieldset tag.
<fieldset>
<InputGroup
label="Email ou Usuário"
borderColor={borderEmail}
icon={emailIcon}
type="email"
placeholder="Digite seu Email"
onChange={e => setEmail(e.target.value)}
value={email}
/>
<InputGroup
label="Senha"
borderColor={borderSenha}
icon={passwordIcon}
type="password"
placeholder="Digite sua Senha"
onChange={e => setSenha(e.target.value)}
value={senha}
/>
</fieldset>

Change button bgcolor depends on props

I want to change the background color of a button based on the props. Assume that I have 4 different names of background colors; primary, secondary, info, and warning. I inspect the code in chrome but no background show:
This what I did:
import React, { useState } from "react";
import styled from "styled-components";
import { Button } from "../assets/styles/GlobalStyles";
const Navbar = () => {
const [button, setButton] = useState(true);
return (
<>
{button ? (
<NavBtnLink to="/">
<Button primary>SIGN UP</Button>
</NavBtnLink>
) : (
<NavBtnLink to="/">
<Button secondary>SIGN UP</Button>
</NavBtnLink>
)}
</>
);
};
GlobalStyles.js (Button)
export const Button = styled.button`
padding: 8px 20px;
background-color: ${({ primary, secondary }) =>
primary ? ("#007bff" ? secondary : "#242424") : "transparent"};
color: #fff;
font-size: 18px;
border-radius: 4px;
outline: none;
border: none;
cursor: pointer;
white-space: nowrap;
&:hover {
}
`;
Change background-colors condition and try this:
background-color: ${({ primary, secondary }) =>
primary ? "#007bff" : secondary ? "#242424" : "transparent"};

Select Component in material UI [duplicate]

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

Modify Antd Date/Rangepicker

How can I modify the Datepicker component of AntD? I want it to look like this.
Is this possible by just clicking the datepicker input? or is there other workaround for this?
Thank you
You can play around with the prop renderExtraFooter and add styles to place it on top
Example:
Code:
<Space direction="vertical" size={12}>
<RangePicker
renderExtraFooter={
() => {
return <Radio.Group name="radiogroup" defaultValue={1}>
<Radio value={1}>Start of Evaluation</Radio>
<Radio value={2}>End of Evaluation</Radio>
</Radio.Group>
}
}
/>
</Space>
Style:
.ant-picker-panels {
margin-top: 50px;
}
.ant-picker-footer {
position: absolute;
top: 10px;
border-bottom: 1px solid #303030 !important;
}
Result:

Not able to type in the styled input component react js

I have created styled component to input the text. I am not able to type into the same when I render it. Please let me know what am I missing on.I tried console.logging on onChange.It seems the event is not getting fired.
Component:
export default function Containers() {
const [supplier, setSupplier] = useState("");
const onChange = e => {
setSupplier(e.target.value);
};
return (
<>
<Background />
<CenterAlignedColumnContainer>
<CompleteWidthDivider />
<InputBox
type="text"
value={supplier}
onChange={e => onChange(e)}
name="supplier"
/>
<PartialWidthDivider />
<GradientButton>
<SacramentoText fontSize="36px">Submit</SacramentoText>
</GradientButton>
</CenterAlignedColumnContainer>
</>
);
}
Styled component
export const InputBox = styled.input`
display: flex;
width: 45%;
height: 2em;
margin-top: 1em;
background: linear-gradient(
360deg,
#b0a7e6 0%,
rgba(176, 167, 230, 0) 169.23%
);
border-radius: 5px;
`;
Check this working example of your code - https://codesandbox.io/s/upbeat-euler-smcjf?file=/src/index.js
Looks like this is not a problem with styled-components, check the component CenterAlignedColumnContainer

Resources