I want to reuse certain CSS properties in Emotion/styled component - css

import styled from '#emotion/styled';
type ColorProps = {
Coloured: boolean,
}
const BoxStyled = styled.div`
${(props:ColorProps) =>
props.Coloured ? {
background: "#304f8f",
border: "1.85px solid #304f8f",
color: "white",
width: "4rem",
height: "2.5rem",
padding:"0 11px"
} :
{
border: "1.98px solid #2c8090",
width: "4rem",
height: "2.5rem",
padding:"0 11px"
}
}`
here in BoxStyled I don't want to write width: "4rem", height: "2.5rem", padding:"0 11px" twice how do I achieve this ?

Use css to make a variable of style.
import { css } from 'styled-components'
const reuse = css`
width: 4rem;
height: 2.5rem;
padding: 0 11px;
`
const StyleA = styled.div`
background-color: black;
${reuse}
`
const StyleB = styled.div`
background-color: red;
${reuse}
`
Check this for more information.

You can define the main style and when needed to change overwrite new style.
import styled from '#emotion/styled';
type ColorProps = {
Coloured: boolean,
}
const BoxStyled = styled.div`
border: "1.98px solid #2c8090",
width: "4rem",
height: "2.5rem",
padding:"0 11px"
${(props:ColorProps) =>
props.Coloured && {
background: "#304f8f",
border: "1.85px solid #304f8f",
color: "white",
}
}`

Related

Styled component not being respected between files?

For whatever reason, the buttons (defined by AboutItem) are displaying light blue backgrounds when I hover over them. I want to make it #282828.
In a separate file I define some styled components for Buttons:
export const Button = styled.button`
display: inline-block;
font-size: 1em;
margin: 1em;
padding: 0em 1em;
`;
export const InfoButton = styled(Button)`
color: grey;
&:hover {
background-color: lightblue;
}
`;
which I then use:
interface AboutNavProps {
selected: boolean;
}
const AboutItem = styled(InfoButton) <AboutNavProps>`
color: grey;
background-color: ${props => props.selected ? "#282828" : "transparent"};
text-align: center;
&:hover {
background-color: #282828;
}
`;
export function AboutNavbar() {
const router = useRouter()
useEffect(() => {
router.prefetch("/method");
}, [])
return (
<AboutNav aria-label="Navbar">
<AboutItem as="a" href="method" selected={router.pathname == "/method"}>How It Works</AboutItem>
<AboutItem as="a" href="about" selected={router.pathname == "/about"}>About</AboutItem>
<Logo />
</AboutNav>
);
}
Is there a reason for this? I don't understand why the light blue overrides the color I define for the hover.

How to change CSS of a child component from parent component

I have a react component called TeamBanner like so
import styles from "./teamBanner.module.css";
import { useNavigate } from "react-router-dom";
import { TeamBannerProps } from "../ProjectTypes.types";
export const TeamBanner = ({
team,
onBannerClick,
showName,
}: TeamBannerProps) => {
let navigate = useNavigate();
const handleOnClick = () => {
navigate(`/${team}`);
onBannerClick();
};
return (
<div
className={`${styles.container} flex theme-light ${
showName ? "" : styles["no-name"]
}`}
title={team}
onClick={handleOnClick}
>
<div>
<img
src={require(`../logos/${team}.svg`)}
alt="logo"
className={`${styles.logo} ${showName ? "" : styles["only-logo"]}`}
/>
</div>
{showName ? team : ""}
</div>
);
};
The teamBanner.module.css file is like so
.container {
margin: 0.25em;
align-items: center;
cursor: pointer;
top: 0;
z-index: 2;
background-color: hsl(var(--color-background));
padding: 0.1em 0.25em;
border-radius: 0.5em;
box-shadow: 0.05rem 0.05rem 0.2rem rgb(0 0 0 / 50%);
font-family: var(--ff-serif);
font-size: var(--fs-200);
}
.logo {
display: inline-block;
vertical-align: middle;
width: 3vmax;
height: 3vmax;
}
.container:hover {
outline: 0.15em solid hsl(240, 90%, 67%);
}
.no-name {
border-radius: 0.25em;
}
.only-logo {
width: 5vmax;
height: 5vmax;
}
I am using it to create a list of team of a page & this works just fine.
However, I want to use it in another place also. In the place, the to now want the .container:hover effect & I want the font properties of the .contaner and width & height properties of the .logo changed.
How can I accomplish this? only changing these items of the module.css? Can any one help? Thanks

How to add a css property only when condition true using styled components and react?

i wanted to add border property only when isOpen condition true using styled components and react.
below is my code,
const Wrapper = styled.div<{ $isOpen: boolean }>`
border: 1px solid black;
display: flex;
`;
How to apply border only when isOpen is true?
could someone help me with this. thanks.
You can try like this:
const Wrapper = styled.div`
display: flex;
${({isOpen}) =>
isOpen &&
css`
{
border: 1px solid black;
}`
}
`;
Grabbing an example from the home page of styled-components:
import styled, { css } from 'styled-components'
const Button = styled.button`
background: transparent;
border-radius: 3px;
border: 2px solid palevioletred;
color: palevioletred;
margin: 0 1em;
padding: 0.25em 1em;
${props =>
props.primary &&
css`
background: palevioletred;
color: white;
`};
`
How you would use it in the react renderer:
render(
<Container>
<Button>Normal Button</Button>
<Button primary>Primary Button</Button>
</Container>
);

Overriding a styled-component with new styled-component?

I have a three styled-components StyledBanner and StyledTitle and WarningBanner.
I am looking to overwrite StyledBanner color through WarningBanner but is is not working out and the return Component always fall back to the div color.
How can I restyle a styled-component?
const StyledBanner = styled.div`
background-color: ${theme.colors.blue_2};
padding: 15px;
display: flex;
flex-direction: column;
border-radius: 4px;
width: 100%;
`;
const StyledTitle = styled(PG)`
font-size: 1.125rem;
font-weight: bold;
padding: 0px 0px 15px 0px;
colors: ${theme.colors.blue_2}
`
const WarningBanner = styled(StyledBanner)`
background-color: ${theme.colors.banner_yellow}
${StyledTitle}{
colors: ${theme.colors.textColor}
`
...
return (<WarningBanner> //still showing theme.colors.blue_2
{title ? <StyledTitle> //still showing theme.colors.blue_2
{title}
</StyledTitle> : null}
</WarningBanner>)
You have a minor typo in your posted code (the CSS property you want to set is color, not plural). Otherwise, your approach is perfectly valid.
Working example: https://codepen.io/mattlubner/pen/XWrvQLP
const theme = {
colors: {
red: '#f00',
greed: '#0f0',
blue: '#00f',
yellow: '#ff0',
},
};
const StyledBanner = window.styled.div`
background-color: ${theme.colors.blue};
padding: 15px;
display: flex;
flex-direction: column;
border-radius: 4px;
width: 100%;
`;
const StyledTitle = window.styled.h1`
font-size: 1.125rem;
font-weight: bold;
padding: 0px 0px 15px 0px;
color: ${theme.colors.blue};
`;
const WarningBanner = window.styled(StyledBanner)`
background-color: ${theme.colors.yellow};
${StyledTitle} {
color: ${theme.colors.green};
`;
ReactDOM.render(
<WarningBanner>
<StyledTitle>Example Title</StyledTitle>
</WarningBanner>,
document.getElementById('root'),
);

Is there a way to modify '&:before/:after' to give a dynamic property?

A styled-component that has &:before attribute that I want to give access to a dynamic color property. But I'm lost to how to apply that.
I've Tried passing the props to <Hover /> and it works. But the Triangle in &:before cannot access that.
const Hover = styled.div`
padding:7px;
margin: -102px auto;
border-style: solid;
border-radius: 15px;
border-width: 3px;
text-align: left;
font-weight: 400;
font-size: 19px;
color: #000000;
font-family: sans-serif;
position: absolute;
left:-15px;
z-index:10;
&:before {
content: "";
width: 0px;
height: 0px;
position: absolute;
border-left: 10px solid ;
border-right: 10px solid transparent;
border-top: 10px solid ;
border-bottom: 10px solid transparent;
left: 19px;
bottom: -19px;
z-index:10;
}
`;
As a single styled-component the following class is:
class MarkerHover extends Component {
render() {
const {color, children}= this.props
return (
<Hover style={{backgroundColor: color }}>
{...children}
</Hover>
);
}
}
export default MarkerHover;
I expect to have a whole colored Window after successfully passing the color props to the &:before division.
As the documentation of Styled Components states (see https://www.styled-components.com/docs/basics#passed-props) you can read passed props:
const Hover = styled.div`
color: ${props => props.color};
`;
when you pass them like this:
<Hover color="#f00" />
You can use that same prop in your pseudo-element as well:
const Hover = styled.div`
color: ${props => props.color};
&::before {
background: ${props => props.color};
}
`;
So don't use the style attribute on your styled component, but pass regular props.
If you want to apply a CSS rule only after a certain condition, you can do that like this:
const Hover = styled.div`
color: #ccc;
&::before {
content: "";
padding: 16px;
${props => props.withBg ? `background-color: ${props.withBg}` : ''}
}
`;
With background:
<Hover withBg="#f00" />
Without background:
<Hover />

Resources