input and label styled component - reactjs

someone can tell me why even when my input have no autofill by chrome or a value by the user, my label still on the top and not inside of the input?
my label styled-component
export const InputLabel = styled.label`
${({ theme }) => css`
font-size: large;
position: absolute;
pointer-events: none;
color:${theme.colors.primaryColor};
left:5px;
top: 16px;
bottom:50%;
transition: all 300ms ease-in-out;
`}
`;
my input styled component
export const InputText = styled.input`
${({ theme }) => css`
width: 100%;
color:${theme.colors.tertiary};
background: ${theme.colors.mediumGray};
border: none;
border-radius: 5px;
padding: 20px;
&::placeholder {
visibility: hidden;
opacity: 0;
}
&:focus{
outline: none;
}
&:focus
+ ${InputLabel},
&:not(:placeholder-shown)
+ ${InputLabel},
&:-webkit-autofill
+ ${InputLabel} {
filter: none;
left:1px;
top: -3rem;
color:${theme.colors.tertiary}
}
`}
`;
i tried to remove this line of code
+ ${InputLabel},
&:not(:placeholder-shown)
from the InputText, but when i write something and do not use the autofill, the label come down again and mix with the value write in the input.
someone know's what i'm doing wrong?

Related

How to inherit styles from another styled component and turning regular component into styled component at the same time?

I am using StyledComponents stying framework and This is my regular react component
const SelectButton = ({className,children, ...rest}) => {
return (
<select className = {className}{...rest}>
{children}
</select>
);
}
I want to turn this component into styled component by calling styled() function and for that purpose I have attached className prop to DOM element of my react component (SelectButton).
export const StyledSelectButton = styled(SelectButton);
But instead of putting the css in this styled component, I want to inherit from different styled component which is StyledButton.js, which has following css properties.
export const StyledButton = styled(Button).attrs(({ type }) => ({
type: type || "button",
}))
display: inline-block;
height: auto;
padding: 0.8rem 2rem;
border: none;
border-radius: 6px;
font-weight: 500;
font-size: 1.6rem;
text-decoration: none;
text-transform: capitalize;
cursor: pointer;
overflow: hidden;
background-color: ${({ primary }) => (primary ? "#646ff0" : "#cccdde")};
color: ${({ primary }) => (primary ? "white" : "#646681")};
.__select {
color: #585858;
font-family: Poppins;
padding: 1rem;
border: none;
background-color: #cccdde;
width: 150px;
cursor: pointer;
};
How can I achieve that?
I have tried doing this way , but I am repeating my code.
export const StyledSelectButton = styled(SelectButton)
display: inline-block;
height: auto;
padding: 0.8rem 2rem;
border: none;
border-radius: 6px;
font-weight: 500;
font-size: 1.6rem;
text-decoration: none;
text-transform: capitalize;
cursor: pointer;
overflow: hidden;
background-color: ${({ primary }) => (primary ? "#646ff0" : "#cccdde")};
color: ${({ primary }) => (primary ? "white" : "#646681")};
&__select {
color: #585858;
font-family: Poppins;
padding: 1rem;
border: none;
background-color: #cccdde;
width: 150px;
cursor: pointer;
}
You can do something like this,
import styled, {css} from "styled-components";
import { StyledButton } from './Button';
const style = css`
color: #585858;
font-family: Poppins;
padding: 1rem;
border: none;
background-color: #cccdde;
width: 150px;
cursor: pointer;
`;
Using function declaration method:
export function StyledSelectButton({ className, children, ...rest }){
return (
<select className={className} {...rest}>
{children}
</select>
);
};
To turn this component into a styled component, pass it to the styled() function.
StyledSelectButton = styled(StyledButton).attrs((props) => ({
as: "select"
}))`
${style}
`;

make input label stay up when the input in not focus

I have a style component with input and label. the label goes up when it's focus and moves down when it's unfocused.
how can I make the label stay up when there a value in the input or when I unfocusedthe input?
my code :
import React from "react";
import styled from "styled-components";
const Wrapper = styled.div`
position: relative;
`;
const Input = styled.input`
font-size: 18px;
padding: 10px 10px 10px 5px;
display: block;
width: 300px;
border-bottom: 1px solid #757575;
&:focus {
outline: none;
}
`;
const Label = styled.label`
color: #999;
font-size: 18px;
font-weight: normal;
position: absolute;
pointer-events: none;
left: 5px;
top: 10px;
transition: 0.2s ease all;
input:focus ~ &,
input:not(:placeholder-shown).input:not(:focus) ~ .label {
top: -20px;
font-size: 14px;
color: #5264ae;
}
`;
const FloatingInput = () => (
<Wrapper>
<Input />
<Label>First Name</Label>
</Wrapper>
);
export default FloatingInput;
Add a required attribute to the input and add a input:valid ~ & selector for the label. When the input has some value it will become "valid" and the CSS selector will pick that up and apply the same style as when its focused.
const Input = styled.input.attrs(() => ({
required: true,
}))`
font-size: 18px;
padding: 10px 10px 10px 5px;
display: block;
width: 300px;
border-bottom: 1px solid #757575;
&:focus {
outline: none;
}
`;
const Label = styled.label`
color: #999;
font-size: 18px;
font-weight: normal;
position: absolute;
pointer-events: none;
left: 5px;
top: 10px;
transition: 0.2s ease all;
input:focus ~ &,
input:not(:placeholder-shown).input:not(:focus) ~ .label,
input:valid ~ & {
top: -20px;
font-size: 14px;
color: #5264ae;
}
`;
const FloatingInput = () => (
<Wrapper>
<Input />
<Label>First Name</Label>
</Wrapper>
);
If you are wanting to toggle the "focused" style and make it stick once focused you'll need a bit of React state to hold the triggered state.
const Input = styled.input`
font-size: 18px;
padding: 10px 10px 10px 5px;
display: block;
width: 300px;
border-bottom: 1px solid #757575;
&:focus {
outline: none;
}
`;
const focusCSS = css`
top: -20px;
font-size: 14px;
color: #5264ae;
`;
const Label = styled.label`
color: #999;
font-size: 18px;
font-weight: normal;
position: absolute;
pointer-events: none;
left: 5px;
top: 10px;
transition: 0.2s ease all;
input:focus ~ &,
input:not(:placeholder-shown).input:not(:focus) ~ .label {
${focusCSS}
}
${({ focused }) => focused && focusCSS}
`;
const FloatingInput = () => {
const [focused, setFocused] = React.useState(false);
return (
<Wrapper>
<Input onFocus={() => setFocused(true)} />
<Label focused={focused}>First Name</Label>
</Wrapper>
);
};

Radio Button Checked with styled components

i'm trying to make a react project with styled components, and i want to use a radio button, but when i try to add css to the radio when it's checked it didn't work as i expected, can you help me?
const RadioGroup = styled.div`
border: solid 3px #332f35;
display: inline-block;
margin: 20px;
border-radius: 10px;
overflow: hidden;
input[type=radio] {
position: absolute;
visibility: hidden;
display: none;
}
label {
color: lighten(#332f35,40%);
display: inline-block;
cursor: pointer;
font-weight: bold;
padding: 5px 20px;
}
input[type=radio]:checked + label{
color: lighten($bg,60%);
background: #ff9000;
}
input[type=radio] + label {
border-left: solid #a1a1a1;
}
`
this is the styled component i'm trying to use in the Radio button, thanks guys!

Styled components not applying styles

I have this 2 styled components
export const Icon = styled.svg`
width: 8px;
height: 8px;
background: black;
`
export const Dots = styled.div`
border: 2px solid green !imporant;
height: 30px;
background: white;
width: 16px;
height: 16px;
border: solid 1px #d2d2d2;
border-radius: 20px;
top: 25px;
position: relative;
${Icon}: hover {
background:black;
}
}
`
I want to display Icon on the hover of this div but i dont understand why it is not working,
Any suggestions please?
There is no problem with your code except on hover you don't change the color from its default value black
const Icon = styled.div`
width: 100px;
height: 100px;
background: black;
`;
export const Dots = styled.div`
${Icon}:hover {
background: red;
}
`;
export default function App() {
return (
<Dots>
<Icon />
</Dots>
);
}
https://codesandbox.io/s/styled-react-template-forked-nzwm8
You should place the hover styles inside the icon
export const Icon = styled.svg`
width: 8px;
height: 8px;
background: black;
&:hover {
background: black;
}

styled-component dropdown make parent:hover color stay while child:hover

I'm trying to make the parent background color stay changed on hover as I continue to hover over the dropdown items.
https://zqy0v.csb.app/dropdowns < dropdown
import React from "react";
import styled from "styled-components";
//============================================ styles =============================================
const DivDropdownContent = styled.div`
display: none;
position: absolute;
background-color: #f9f9f9;
min-width: 24.7rem;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 1;
`;
const DivDropdown = styled.div`
position: relative;
display: inline-block;
&:hover ${DivDropdownContent} {
display: block;
}
`;
const SpanDropdownTitle = styled.div`
font-size: 1.6rem;
font-weight: bold;
padding: 2rem 6rem;
border-radius: 0.6rem;
border: 1px solid black;
&:hover {
cursor: pointer;
}
`;
const ItemDropdown = styled.p`
padding: 1rem;
&:hover {
cursor: pointer;
background: lightgray;
}
`;
//=========================================== component ===========================================
const BasicDropdown = props => {
return (
<DivDropdown>
<SpanDropdownTitle>Basic Dropdown</SpanDropdownTitle>
<DivDropdownContent>
<ItemDropdown>Item 1</ItemDropdown>
<ItemDropdown>Item 2</ItemDropdown>
<ItemDropdown>Item 3</ItemDropdown>
</DivDropdownContent>
</DivDropdown>
);
};
export default BasicDropdown;
Basically I would like the background color to stay changed for the parent while hovering over the child items in the dropdown, much like is done here https://woocommerce.com/
Is there an easy way to do this, or do I have to start getting complicated with using state and onPointerEnter and onPointerLeave?
I finally ended up finding the solution, and am a bit embarrassed.
const DivDropdown = styled.div`
position: relative;
display: inline-block;
&:hover ${DivDropdownContent} {
display: block;
}
`;
The Issue: ^This was only targeting the nested component when I added the background cover to the hover.
const DivDropdown = styled.div`
position: relative;
display: inline-block;
&:hover {
background: lightgray;
}
&:hover ${DivDropdownContent} {
display: block;
}
`;
The Fix: ^By adding the above, I was able to correct the behavior.
I'm going to leave this question up, because I wasn't able to find much tutorials on this through my internet searching. I think this is a fairly clean solution and think it will help others searching.

Resources