Styled-components in React.js - props doesn't work - javascript

I've tried everything. At least, for a while, I can't find any new possible solution for my problem. There is a possibility that I don't understand something, because I'm at the beginning of my adventure with React.js.
To the point:
I want to create a component-header with a background image. In the parent component, I put an image URL as a prop and try to use it in the child component as a background-image: URL(). And it, of course, doesn't work. Also, I've tried to set a colour, and it also doesn't work.
Here is my parent component:
import Hero from '../Hero';
import image from './cat.jpg'
function Main() {
return <div>
<Hero title="Only fluff photos" image={image} color="#f0f"/>
</div>
};
and here is my child component:
import styled from 'styled-components';
const StyledHeader = styled.header`
display: flex;
width: 100%;
height: 432px;
background-image: url(${(props) => props.image});
background-color: ${props => props.color ? props.color : "#ff0"};
`
function Hero(props) {
return <StyledHeader>
<h1>{props.title}</h1>
<img src={props.image} alt="test cat" />
</StyledHeader>
};
What I've tried:
Put the same URL into img tag as a src - it works
Import an img directly in child component and us {image} - it works
Use require() - it doesn't work
Use url(~{props.image}) - it doesn't work
Use different forms of props when styling my StyledHeader - it doesn't work
Put an image into a folder that has exactly the same path for both components - it doesn't work.
Of course, all of points from 3 to 6 doesn't work, because none of props works. But I've found that later.
styled-components gives an example of props usage:
background: ${props => props.primary ? "palevioletred" : "white"};
It doesn't help me :(
Thanks in advance for any help! I have no idea what I've done wrong.

It won't work because you have to give the Styled header the prop as followed
const StyledHeader = styled.header`
display: flex;
width: 100%;
height: 432px;
background-image: url(${(props) => props.image});
background-color: ${props => props.color ? props.color : "#ff0"};
`
function Hero(props) {
return <StyledHeader image={props.image} color={"value"} {...otherProps}>
<h1>{props.title}</h1>
<img src={props.image} alt="test cat" />
</StyledHeader>
};

Related

change position of boxes in styled-component

I have a bunch of grids which I would like to form them a way as I intended to do. Here is a picture of how they look now:
What I would like to do is to move "CL1" and "Author" in parallel but after "commiter 1". And then followed by "CL2" and "CL3" in linear order like they are now. My code is as following:
import { React } from "react";
import styled from "styled-components";
function App() {
return (
<>
<Input placeholder="commiter 1" />
<Input placeholder="Author" size="2em" />
<div>
<Input placeholder="CL1" />
</div>
<Input placeholder="CL2" />
<Input placeholder="CL3" />
</>
);
}
export default App;
const Input = styled.input.attrs(props => ({
// we can define static props
type: "text",
size: props.size || "1em",
}))`
color: palevioletred;
font-size: 1em;
border: 2px solid palevioletred;
border-radius: 3px;
margin: ${props => props.size};
padding: ${props => props.size};
`;
I am just started with CSS styling, and trying with styled-component as of now. Any idea on which tutorial I should look up into, or suggestions to other CSS tool would be appreciated as well!
something like styled you should use when styles a dynamically, when you don't now size of some images or same problem. In casual situation you should use .css/scss file.
And check this https://css-tricks.com/snippets/css/a-guide-to-flexbox/

React fill SideNavBar from top to bottom with other components on the page

I want my sidenavbar to continue over the whole page but when i add the other
sections(home, contact & projects) which are just regular functional components
with a div and h1, they create their own space on the page. is there a better
solution to creating different sections on a page? i have tried rendering the components
from index and app.js but without success, i am currently rendering SidenavBar
from index.js and my sections are getting rendered from app.js.
import React from "react";
import "../Section.css";
function HomeSection() {
return (
<div className="Section" id="Home">
HomeSection
<h1>Home</h1>
</div>
);
}
export default HomeSection;
here is an example of the sections, the section.css only centers the text on the page.
function SideNavBar() {
const [titleActive, setTitleActive] = useState(HomeSection);
return (
<div className="SideNavBar">
<Stickybox>
<ul className="SideBarList">
{SideBarInfo.map((info, key) => {
return (
<li
key={key}
className="rad"
onClick={() => {
console.log(info.title + " clicked");
setTitleActive(info.title);
}}
id={titleActive === info.title ? "active" : ""}
>
<Link
onClick={() => {
console.log(info.title + " clicked");
setTitleActive(info.title);
}}
id={titleActive === info.title ? "active" : ""}
activeClass="active"
to={info.title}
spy={true}
smooth={true}
offset={50}
duration={500}
>
<div id="title">{info.title}</div>
/Link>
<Link
activeClass="active"
to={info.title}
spy={true}
smooth={true}
offset={50}
duration={500}
>
<div id="bild">{info.bild}</div>
</Link>
</li>
);
})}
</ul>
</Stickybox>
</div>
);
}
export default SideNavBar;
// this is the css for sidebar
.SideNavBar {
width: 250px;
min-height: 5000px;
background-color: rgb(47, 167, 223);
height: 100vh;
}
this is my sidenavbar component.
My sidenavbar works as intended if i remove the sections, i have tried setting a max width and transparent background for the sections so they dont overwrite the sidenavbar but they still overwrite it. what is the correct way to create different sections?
i added a red background for the home section so its easier to see what its doing.
You probably want to do something like this for your sidebar to fix it on the side and have it take up the full screen.
This will fix the sidebar in a position on the screen (0px away from the top and 0px away from the bottom).
You then define the width and you have a fixed sidebar!
Hope that helps!
.sidebar {
top: 0px;
bottom: 0px;
width: 200px;
position: fixed;
background-color: blue;
}
<div class='sidebar'></div>

Do not add new line in Styled Components with Prettier

I am using React with Styled Components while formatting code using Prettier. Let's have the following code:
const Component = Styled.div`
color: green;
${props => props.important && `
font-weight: bold;
`}
`
It's simple styled component with usage <Component /> or <Component important={true} />. However, when I format code using Prettier, the code changes to:
const Component = Styled.div`
color: green;
${props =>
props.important &&
`
font-weight: bold;
`}
`
Is there any way to set Prettier to not add newline after => and after && in this case? I searched in Prettier options, however I did not find anything.
If you can't find the option to do it here then it isn't possible.
By design - Prettier is not intended to provide a lot of configuration options.

React, conditional styling for style-components won't work

I have looked for dozens of examples on google and youtube but none of them seems to work. My problem is that whenever I try classic methods for conditional styling in styled-components it won't change the component's style as I wish it to change... Anybody can tell me what I am doing wrong?
Child component:
const Ripple = styled(ButtonBase)`
font-family: ${font.family};
font-size: ${(props) => (props.small ? '14px' : '16px')};
color: white !important;
&:focus {
border-radius: 6px;
}
`;
Parent:
<Button small label="Get in touch" href="/" />
It does nothing.... Pls help.
You seem to be calling the wrong component. You're calling <Button />
Try:
<Ripple small label="Get in touch" href="/" />

How to create virtual scrolling for images using React js

Whats my requirement: i have some images in my external folder and i need to import to component and display it and also have to use Virtual Scroll here i have to display 1 row in div and in that 1 row have to show 5-6 images
What i did : i consumed images using context from external folder and showed images in 1 rows in div and 5-6 images but i am facing issue unable to set it to Virtual scrolling
as i checked react-virtualized & react-window plugin but i am not sure how my data is used in that format
After using the react-tiny-virtual-list images are getting stacked
below is my code
class App extends React.Component{
state={
Response:[],
}
importAll(r) {
return r.keys().map(r);
}
componentWillMount() {
let data = this.importAll(require.context('./imageFolder/', false, /\.(png|jpe?g|svg)$/));
this.setState({ Response:data})
}
render(){
return(
<div className="container" id="imagecontainer">
<div className="viewport">
{this.state.Response.map((image, index) => <img key={index} src={image} alt="info"></img> )} }
</div>
</div>
)
}
.container {
padding: 0% 6%;
height: 400px;
}
.viewport {
height: -webkit-fill-available;
width: 100%;
border: 1px solid black;
overflow: scroll;
}
img {
height: 250px;
width: 150px;
padding: 35px;
}
After implementing React-tiny-list
<div id="container">
<div id="viewport">
<VirtualList
height='400px'
width='100%'
itemCount={this.state.items.length}
itemSize={20} // Also supports variable heights (array or function getter)
style={{padding:'20px'}}
renderItem={({index, style}) =>
<div key={index} style={style}>
<img key={index} src={this.state.items[index]} alt="info"></img>
</div>
}
/>
</div>
</div>
you can also use the https://github.com/bvaughn/react-virtualized plugin in this if you want to display this as table you can choose list or you can choose grid also .For you requirement i recommend using Masonry from 'react-virtualized';
below is the sample for displaying
import React from 'react';
import {
CellMeasurer,
CellMeasurerCache,
createMasonryCellPositioner,
Masonry
} from 'react-virtualized';
import 'react-virtualized/styles.css';
var images = [];
const columnWidth = 250;
const defaultHeight = 260;
const defaultWidth = columnWidth;
const cache = new CellMeasurerCache({
defaultHeight,
defaultWidth,
fixedWidth: true
})
// Our masonry layout will use 3 columns with a 10px gutter between
const cellPositioner = createMasonryCellPositioner({
cellMeasurerCache: cache,
columnCount: 4,
columnWidth,
spacer: 27
})
function cellRenderer ({ index, key, parent, style }) {
const datum = images[index]
const height = columnWidth || defaultHeight ;
return (
<CellMeasurer
cache={cache}
index={index}
key={key}
parent={parent}
>
<div style={style}>
<img
src={datum}
style={{
height: height,
width: columnWidth,
display: "block"
}}
alt="info"
/>
</div>
</CellMeasurer>
)
}
class Grid extends React.Component{
importAll(r) {
return r.keys().map(r);
}
componentWillMount() {
images = this.importAll(require.context('../imageFolder/', false, /\.(png|jpe?g|svg)$/));
}
render(){
return(
<div id="container">
<div id="viewport">
<Masonry
cellCount={images.length}
cellMeasurerCache={cache}
cellPositioner={cellPositioner}
cellRenderer={cellRenderer}
height={400}
width={1320}
/>
</div>
</div>
)
}
}
export default Grid;
I hope this will resolve your issue
If you're having trouble implementing the virtual scroll, note that the order of the imports is important when doing this, so pay heed to this - it could be contributing to your issue. (An aside: There is an npm plugin for implementing a virtual list.)
An overview of the import order for virtual scroll is:
import * as React from 'react';
import Paper from '#material-ui/core/Paper';
import {
Grid,
VirtualTable,
TableHeaderRow,
} [from material ui];
import {
your-components
} from 'your-path';
(above is non-specific, just a rough guide to the order)
You could also use a ScrollView if you are unable to implement a "Virtual scroll".
The following style will give you a horizontal scroll (as opposed to the default vertical), to enable you to display your images in a horizontally-scrollable row
<ScrollView horizontal={true}>
Hope this helps

Categories

Resources