React, styled-components - style inner styled-component - reactjs

I have a demo
https://stackblitz.com/edit/react-ts-jvbeh7
It's a simple react app using styled-components
I'm passing a prop desktop
<Block desktop>
<InnerBlock />
</Block>
And I'm trying to style the inner style component when the prop is there
const Block = styled.div<IProps>`
background: red;
height: 200px;
width: 200px;
${InnerBlock} {
margin: ${p => p.desktop ? '10px' : null};
}
`;
If I try this I get an error on ${InnerBlock}
Block-scoped variable 'InnerBlock' used before its declaration.
Is it possible to style an inner styled-component <InnerBlock /> when there is a prop on the parent

Found the correct way.
const Block = styled.div<IProps>`
background: red;
height: 200px;
width: 200px;
${InnerBlock} {
${(p) =>
p.desktop &&
css`
width: 50px;
height: 50px;
background: yellow;
`};
}
`;

Related

Typescript/React: Referring to other styled-components

I am trying to reproduce this code from https://styled-components.com/docs/advanced in typescript.
const Link = styled.a`
display: flex;
align-items: center;
padding: 5px 10px;
background: papayawhip;
color: palevioletred;
`;
const Icon = styled.svg`
flex: none;
transition: fill 0.25s;
width: 48px;
height: 48px;
${Link}:hover & {
fill: rebeccapurple;
}
`;
What do I have to do for it to work in typescript?
The problem was that I was trying to reference a component that I imported from another file instead of that component's styled counterpart. I mistakenly thought it was a typescript issue.

Why my colors is not output on the screen under a rafce react environtment

I am using react rafce function and I want to decorate my color icons ,I decided to create a rounded icons with colors inside but it ended up not showing any colors.
This is my css styling
const FilterColor = styled.div`
width:20px;
height:20px;
border-radius:50%;
background-color:$props{props=>props.color};
margin:0px 5px;
cursor:pointer;
`
This is my html code
<FilterTitle>Color: </FilterTitle>
<FilterColor color= 'red' />
<FilterColor color ='darkblue'/>
<FilterColor color='orange' />
This is my output
This is what it should look
Assuming, you are using styled-components, change your FilterColor component to:
const FilterColor = styled.div`
width: 20px;
height: 20px;
border-radius: 50%;
background-color: ${(props) => props.color}; // <-- this got changed
margin: 0px 5px;
cursor: pointer;
`;

How to display backgroung image once it's assigned as constant using styled components

I want to display background image on full size of the parent component, this image is assigned to const "image", parent is Dialog from Material UI. Below is the code which I have now and not working. How should I implement it ?
const image =
'../../../../../../shared/src/lib/assets/images/logo/SVG/nevomo_logo_orange.svg';
return (
<div>
<StyledLogo onClick={handleClickOpen} />
<StyledDialog
onClose={handleClose}
aria-labelledby="alert-picture-zoom-in"
open={open}
sx={{ backgroundImage: { image } }}
>
<StyledImageContent>sss</StyledImageContent>
<StyledCloseIcon onClick={handleClose} />
</StyledDialog>
export const StyledDialog = styled(Dialog)`
& .MuiDialog-paper {
overflow: unset;
height: 50rem;
width: 46.4rem;
border: 0.4rem solid #ffffff;
border-radius: unset;
background-image: ${(props) => props.image};
}
`;
thanks a lot !
This should help
import styled from 'styled-components';
import img from 'your path to image';
export const StyledDialog = styled(Dialog)`
background-image: url(${img});
width: 100%;
& .MuiDialog-paper {
overflow: unset;
height: 50rem;
width: 46.4rem;
border: 0.4rem solid #fff;
border-radius: unset;
background-image: ${(props) => props.image};
}
`;

Does React Emotion support ::before/ ::after selectors?

I am trying to use React Emotion to set up a horizontal rule with text in the middle. It would look like this:
----------------------SOME TEXT----------------------------------
I found examples on StackOverflow on how to do this with CSS, but it's not working for me.
Here is my DIV that I'm using, but it's not working.
Is this possible to set up with react Emotion? What am I missing?
<div
css={{
display: 'flex',
lineHeight:'1em',
color:'gray',
'&:before, &:after': {
content:'',
display:'inline-block',
flexGrow:'1px',
marginTop:'0.5em',
backgroundColor:'gray',
height:'1px',
marginRight:'10px',
marginLeft:'10px'
}
}}
>
SOME TEXT
</div>
Your code is right about the ::before and ::after syntax,
However, when trying to replicate I found two errors:
The flexGrow shouldn't have a px unit, just 1: flexGrow:'1
The content should have double quotes content:'""'
<div
css={{
display: 'flex',
lineHeight:'1em',
color:'gray',
'&:before, &:after': {
content:'""',
display:'inline-block',
flexGrow:'1',
marginTop:'0.5em',
backgroundColor:'gray',
height:'1px',
marginRight:'10px',
marginLeft:'10px'
}
}}
>
You need pass style object in css function from emotion/css or emotion/react.
You forgot to wrap your styled object in a function from emotion.
If you use an object and not a string, then wrap content in double quotes
// First way, use css from #emotion/css, pass as object
import { css } from '#emotion/css'
<div
className={css({
display: 'flex',
lineHeight: '1em',
color: 'gray',
':before, :after': {
content: '""',
flexGrow: '1',
marginTop: '0.5em',
backgroundColor: 'gray',
height: '1px',
marginRight: '10px',
marginLeft: '10px'
}
})}
>
SOME TEXT
</div>
// Second way, use css from #emotion/css, pass as string
import { css } from '#emotion/css'
<div
className={css`
display: flex;
line-height: 1em;
color: gray;
:before, :after: {
content: '';
flex-grow: 1;
margin-top: 0.5em;
background-color: gray;
height: 1px;
margin-right: 10px;
margin-left: 10px;
}
`}
>
SOME TEXT
</div>
// Third way, use css from #emotion/react
import { css } from '#emotion/react'
<div
css={css`
display: flex;
line-height: 1em;
color: gray;
:before, :after: {
content: '';
flex-grow: 1;
margin-top: 0.5em;
background-color: gray;
height: 1px;
margin-right: 10px;
margin-left: 10px;
}
`}
>
SOME TEXT
</div>
For string interpolation passed for css function you can use it like
let highlight = css`
border: 1px solid grey;
&:after {
position: absolute;
}`;

using styled-component in react.js

I am first time using styled-component with react.js. My code is in Abc.js and in styles.js I have styled-component code.
export const StyledPopopDiv = styled.div`
width: 200px;
height: 100px;
background: #cecece;
position: fixed;
z-index: 200;
left: ${state => state.pos.x}px;
top: {state.pos.y}px;
`;
StyledPopopDiv.displayName = 'StyledPopopDiv';
I am trying to pass state.pos.x in styled-component, but this is giving error Cannot read property 'x' of undefined.
I don't know what to do. Please help.
You should first of all pass the state as a prop to the styled component example :
// Abc.js
<StyledPopopDiv pos={posState} />
So you can use this prop on your styled component definition as below:
//styled.js
export const StyledPopopDiv = styled.div`
width: 200px;
height: 100px;
background: #cecece;
position: fixed;
z-index: 200;
left: ${ props => props.pos.x}px; // outputs '10px' in this example
top: ${ props => props.pos.y}px; // outputs '20px' in this example
`;
A better way/tip is to use destruction/spread operator example :
export const StyledPopopDiv = styled.div`
width: 200px;
height: 100px;
background: #cecece;
position: fixed;
z-index: 200;
left: ${ ({ pos }) => pos.x}px;
top: ${ ({ pos }) => pos.y}px;
`;
it should be props instead of state, assuming you're using StyledPopupDiv in Abc.js render.
interface StyledPopupDivProps{
x:string
}
export const StyledPopopDiv =
styled<LinkProps, "div">("div")`
margin: ${props=>props.x}
`;
and pass
<StyledPopupDiv x={intendedValue}/>
where its being used.

Resources