How to inject background image url into styled-components - reactjs

I am using styled-components as a design library, I created a div that will hold a background image with its properties, if I inject the image url from outside the styled components it doesnt take and and does some mistakes.
Ill copy some code:
image-div component as styled component:
const ImageDiv = styled.div`
height: 100%;
width: 100%;
float: left;
background-repeat: no-repeat;
background-position: left;
background-size: cover;
`
export default ImageDiv;
using the ImageDiv on a screen and passing it a background image doesnt take the background properties from above
<ImageDiv style={{ backgroundImage: `url(${signin})` }} src = {signin} alt="logo" />
I will like to be able to pass the url as a prop and inject it into the styled component from above

You could simply pass it as another prop, then use it inside styled component as background-image property.
<ImageDiv bg={signin} src={signin} alt="logo" />
const ImageDiv = styled.div`
background-image: url(${(props) => props.bg});
`;

Use destructuring props
const ImageDiv = styled.div`
height: 100%;
width: 100%;
float: left;
background-repeat: no-repeat;
background-position: left;
background-size: cover;
background-image: ${({url}) => `url(${url})`};
`
export default ImageDiv;

Related

img not showing up in styled components reactjs

I'm using styled components.
component_name.js
// import statement
import MyArrow from '../../path/to/img.svg"; // <- svg file
// inside return statement
<Arrow src={MyArrow} />
styled.js
export const Arrow: Object = styled('img')`
top: 5px;
/* other styles ... */
`;
Image path is correct. But image is not showing up. HTML img is showing up in the DOM, but not include src attribute.
Edit
I've updated to the styled.js like below.
export const Arrow: Object = styled('img')`
position: absolute;
top: 6px;
right: 4px;
width: auto;
height: 500px;
background-image: url(${(props) => props.src});
background-position: center;
background-repeat: no-repeat;
background-size: cover;
`;
Still not working. Got this error Cannot convert a Symbol value to a string.
Please try by adding the following properties
width: auto;
height: 500px;
background-image:
background-position: center;
background-repeat: no-repeat;
background-size: cover;

React modal component receiving same class

I have a react Modal component that I have made. I can pass a prop that makes it full screen or define a width. It all works fine, but i'm having an issue reusing it when the first modal is open. The 2nd component takes the same class as the 1st, so it makes the max-width 100%.
For example, I want to have a full screen modal, and show a 2nd modal at 50% size on top when i click a link.
I am using styled components which i think is where the issue may be happening. Im just not sure how to approach it.
Modal component:
<ModalContainer visible={visible} fullScreen={fullScreen}>
<ModalDialog role="dialog" width={width}>
<ModalBody>{children}</ModalBody>
</ModalDialog>
</ModalContainer>
Styles
export const ModalDialog = styled.div`
width: 100%;
max-width: ${({ width }) => width};
`;
export const ModalContainer = styled.div`
visibility: hidden;
opacity: 0;
display: none;
${({ visible }) =>
visible &&
css`
visibility: visible;
opacity: 1;
display: flex;
`}
${({ fullScreen }) =>
fullScreen &&
css`
width: 100vw;
height: 100vh;
overflow: none;
${ModalDialog} {
box-shadow: none;
max-width: 100%;
}
`}
`}
The class of the first modal for dialog is what is also being used for the 2nd even though that does not have the full screen prop.

Style the 'choose file' button

I have a simple way to hide the button within a container div so that it is invisible. However, I want the cursor to be a crosshair over the whole thing, but I don't know how to change the cursor so it is a crosshair when it is highlighting it. As you can observe, the cursor switches to its default when the choose file button is hovered. Here is my code, and a link to the sandbox: https://codesandbox.io/s/zen-elgamal-mk059?file=/src/App.js
import React from "react";
import styled from "styled-components";
import "./styles.css";
const MyButton = styled.div`
position: absolute;
width: 50px;
height: 50px;
background-color: red;
cursor: crosshair;
`;
const StyledForm = styled.form`
position: absolute;
width: 100%;
height: 100%;
cursor: crosshair;
`;
const StyledInput = styled.input`
width: 100%;
height: 100%;
box-sizing: border-box;
cursor: crosshair;
background-color: pink;
`;
export default function App() {
return (
<div className="App">
<MyButton>
<StyledForm>
<StyledInput type="file" />
</StyledForm>
</MyButton>
</div>
);
}
the problem is you are using default input button.You should replace with a custom.
Here is my solition.
https://codesandbox.io/s/vigilant-pond-tncxt?file=/src/App.js

background image not responsive on mobile

When on mobile screen sizes, the image gets responsive to a time where the image gets cut and is no more responsive.
I will show code and image for clarification.
const SignIn = ({ setDisplayScreen }: Props) => (
<ScreenDiv>
<ImageContainer>
<FirstImageDiv />
</ImageContainer>
<FormDiv>
<SignInInput placeholder="Username" />
<SignInInput placeholder="Password" />
<SignUpButton
style={{
cursor: 'pointer',
}}
>
Sign in
</SignUpButton>
<ForgotUserNameParagraph>
Forgot username or password
</ForgotUserNameParagraph>
<SignUpParagraph
style={{ cursor: 'pointer' }}
onClick={() => setDisplayScreen('SignUpOptions')}
>
Don’t have an account? Sign up
</SignUpParagraph>
</FormDiv>
</ScreenDiv>
);
export default SignIn;
image component
import styled from 'styled-components';
import { signin, mobileSignin } from '../../assets/images';
import device from '../../config/device';
const FirstImageDiv = styled.div`
background-image: url(${signin});
float: left;
background-size: cover;
display: flex;
justify-content: flex-end;
background-repeat: no-repeat;
flex-direction: column;
width: 100%;
height: 100vh;
#media ${device.mobileS} {
background-image: url(${mobileSignin});
width: 100%;
height: 34.3vh;
background-size: cover;
justify-content: flex-end;
}
`;
export default FirstImageDiv;
I tried to use background size contain it becomes to small and outside the context of the div
What can I do for it to continue displaying correctly like the responsive one.
what css tricks could be use to fix the situation?

styled-components causing unexpected behaviour when rendering props

I have a WhiteBox react component which simply renders a white box with some styles.
I have a SmallBox react component which simply uses WhiteBox to render a more specific box.
I have a Content react component which renders three SmallBox boxes which does what it's supposed to do (renders three white boxes).
However when I tried to add a text as a props from the parent, the white box is aligned with some unexpected margin from top.
NOTE: when I simply put "This is a text" the css is okay, but when I send "this is a text" as props.text, the whitebox is rendered with extra margin from top.
I Use styled-components and react as I said.
I've tried to console.log the text, and everything seems to be okay. I also tried to switch the props.children or props.text and it does not work
-----------------White Box Component ----------------------
import styled from "styled-components";
const StyledBox = styled.div`
display: inline-block;
width: ${props => props.width}px;
height: ${props => props.height}px;
margin-right: ${props => props.marginRight}px;
margin-left: 100px;
background-color: white;
border-radius: 5px;
font-size: 13px;
font-weight: 700;
text-transform: uppercase;
color: #646777;
padding: 10px;
`;
const WhiteBox = props => {
return (
<StyledBox
width={props.width}
height={props.height}
marginRight={props.marginRight}
>
{props.text} // if I change this to simply "this is a text" it works well. somehow the props.text is causing problems.
</StyledBox>
);
};
export default WhiteBox;```
-----------------Small Box Component ----------------------
import React from "react";
import styled from "styled-components";
import WhiteBox from "../whitebox/white-box";
const SmallBox = props => {
return (
<WhiteBox width={320} height={130} marginRight={70} marginLeft={70} text={props.text}>
</WhiteBox>
);
};
export default SmallBox;
-----------------Content Component ----------------------
import React, { Component } from "react";
import SmallBox from "./smallbox/small-box";
import styled from "styled-components";
const StyledContent = styled.div`
position: absolute;
left: 320px;
top: 80px;
width: 100%;
height: 100%;
background-color: #f1f3f7;
`;
class Content extends Component {
render() {
return (
<>
<StyledContent>
<SmallBox text="this text is great" /> // causing problem
<SmallBox />
<SmallBox />
</StyledContent>
</>
);
}
}
export default Content;
The issue has to do with how many lines are rendered. The longer the text in the props, the more the lines rendered.
One solution would be to change the display property for WhiteBox:
const StyledBox = styled.div`
display: inline-flex;
....
`;
Another solution would be to override the default style vertical-align: baseline, simply add vertical-align: top;
const StyledBox = styled.div`
display: inline-block;
....
vertical-align: top;
`;

Resources