How do you pass an image to a styled component? - reactjs

I'm using styled-components in ReactJS and I'm trying to create a component that can take in the background-image as a prop. After some research, I've tried this:
import SpeechBubble1 from '../images/home_images/Speech 1.png';
...
const SpeechBubble = styled.div`
background-image: url(${props => props.background});
`;
...
<SpeechBubble background={SpeechBubble1} />
But it doesn't work. Checking in the browser element window, I can see I'm getting an Invalid property value for background-image.
What am I doing wrong?
Edit:
I also tried doing this, which hasn't worked:
<SpeechBubble style={{background: `url(${SpeechBubble1})`}} />

Make sure you are including a height for the styled component, otherwise, it won't display anything (unless it has children that define its dimensions).
Working example:
components/Container
import styled from "styled-components";
const Container = styled.div`
height: 100vh;
background-image: url(${({ background }) => background});
background-repeat: no-repeat;
background-size: cover;
`;
export default Container;
index.js
import React, { Fragment } from "react";
import { render } from "react-dom";
import reactbg from "./images/reactbg.png";
import Container from "./components/Container";
import GlobalStyles from "./components/GlobalStyles";
import Title from "./components/Title";
const App = () => (
<Fragment>
<GlobalStyles />
<Container background={reactbg}>
<Title>Hello World</Title>
</Container>
</Fragment>
);
render(<App />, document.getElementById("root"));

Index.js
import React from 'react'
import {ProfilePic} from './NavigationElements'
import profileimg from '../../images/profileimg.jpg'
const Navigation = () => {
return (
<NavigationWrapper>
<ProfilePic src={profileimg} alt="" />
</NavigationWrapper>
)
}
export default Navigation
NavigationElements.js
import styled from "styled-components";
export const NavigationWrapper = styled.div`
color: #fff;
`
export const ProfilePic = styled.img`
width: 5vh;
height: 3vh;
margin: 55px;
`

You can use inline styling:
<SpeechBubble style={{background: `url(${SpeechBubble1})`}} />

Related

Custom button in toolbar draftjs editor

How can I add a button with a custom function behind it to the draftjs editor? I have the feeling this should be pretty straightforward but I can't find examples or documentation.
I have an Editor with only bold italic and list buttons and I want to add a button that shows a popup where I can select 1 of 3 options and then "inject" this in the editor.
Can someone point me in the right direction (or documentation)?
here how i tried this, purely react hooks way to achieving things,
App.js file
import MyEditor from './Component/MyEditor';
function App() {
<MyEditor />
}
MyEditor.js file export MyEditor component used and imported in App.js
import React from 'react';
import ReactDOM from 'react-dom';
import {Editor, EditorState, RichUtils} from 'draft-js';
import 'draft-js/dist/Draft.css';
import './MyEditor.css'
export default function MyEditor() {
const [editorState, setEditorState] = React.useState(
() => EditorState.createEmpty(),
);
const _onBoldClick = () => {
setEditorState(RichUtils.toggleInlineStyle(editorState, 'BOLD'))
}
return(
<div>
<button onClick={_onBoldClick}>BOLD</button>
<div
>
<Editor
textAlignment="left" placeholder="Enter something here"
editorState={editorState} onChange={setEditorState} />
</div>
</div>
)
}
//ReactDOM.render(<MyEditor />, document.getElementById('container'));
css file for styling
div.DraftEditor-root {
border: 1px solid black;
height: 200px;
width: 200px;
margin-left: 20%;
overflow-y: auto;
}
div.DraftEditor-editorContainer, div.public-DraftEditor-content {
height: 100%;
}

Background image only shows up after reloading the page

I'm trying to import an image as I usually do on React and using that value as a background image for a styled component, the first page that renders seems to use the background fine, but then when navigating the application with Links from react-router it doesn't seem to load the background for any of the components inside the router. I have to reload each component to see the actual background.
import React from "react";
import MiningBackground from "assets/backgrounds/miningBackground.jpg";
import styled from "#emotion/styled";
const MiningPage = () => {
return <BackgroundContainer key="mining-background"></BackgroundContainer>;
};
const BackgroundContainer = styled.div`
background-image: url(${MiningBackground});
background-repeat: no-repeat;
background-size: cover;
opacity: 0.3;
min-height: 100vh;
min-width: 100vw;
background-color: "#0A2836";
color: "#0A2836";
`;
export default MiningPage;
After further checking, it looks like the router is not returning the components at all, I'll attach the router and the navigation.
The Drawer:
import {
faHome,
faGem,
faCoins,
faSpaceShuttle,
} from "#fortawesome/free-solid-svg-icons";
import { Divider, Drawer, List, Toolbar, Typography } from "#material-ui/core";
import React from "react";
import AMenuItem from "components/atoms/AMenuItem";
import styled from "#emotion/styled";
import MadeByCommunityBlack from "assets/MadeByTheCommunity_Black.png";
const SideMenu: React.FC = () => {
return (
<StyledDrawer variant="permanent" open>
<div>
<Toolbar />
<StyledList>
<AMenuItem link="/" icon={faHome} text="Home" />
<AMenuItem link="/mining" icon={faGem} text="Mining" />
<AMenuItem link="/trading" icon={faCoins} text="Trading" />
<AMenuItem link="/fleet" icon={faSpaceShuttle} text="Fleet" />
<Divider />
</StyledList>
</div>
<TradeMarkContainer>
<StyledImage
src={MadeByCommunityBlack}
alt="Made by the star citizen community official logo"
/>
<Typography variant="caption">
Star Citizen®, Roberts Space Industries® and Cloud Imperium ® are
registered trademarks of Cloud Imperium Rights LLC.
</Typography>
</TradeMarkContainer>
</StyledDrawer>
);
};
const StyledDrawer = styled(Drawer)`
.MuiDrawer-paper {
z-index: 980;
display: flex;
flex-direction: column;
justify-content: space-between;
height: 100%;
padding: 0px 10px 10px 10px;
width: 190px;
}
`;
const TradeMarkContainer = styled.div`
display: flex;
flex-direction: column;
align-items: center;
`;
const StyledList = styled(List)`
background-color: "#0A2836";
`;
const StyledImage = styled.img`
width: 150px;
`;
export default SideMenu;
The Router:
import FleetPage from "components/pages/FleetPage";
import MiningPage from "components/pages/MiningPage";
import TradingPage from "components/pages/TradingPage";
import React from "react";
import { Route, Router, Switch } from "react-router-dom";
import HomePage from "../components/pages/HomePage";
import { createBrowserHistory } from "history";
import SideMenu from "components/organisms/SideMenu";
import TopBar from "components/organisms/TopBar";
const Routes = () => {
const history = createBrowserHistory();
return (
<Router history={history}>
<TopBar />
<SideMenu />
<Switch>
<Route path="/fleet" component={FleetPage} />
<Route path="/trading" component={TradingPage} />
<Route path="/mining" component={MiningPage} />
<Route path="/" component={HomePage} />
</Switch>
</Router>
);
};
export default Routes;
The issue was I was importing Router and not BrowserRouter from react-router-dom. Changing that and removing the history prop did the trick.

React styled-components how styled declared component

I will try explain one more time my problem for better undestanding .
I need styled component whose I wish he was simultaneously method when i can inject props .
I created easier code for this example :
import React from "react";
import styled from "styled-components";
import "./App.css";
const styledInput = styled.input`
width: 300px;
height: 300px;
border: 2px solid black;
`;
const Input = props => {
return <styledInput type="text" />;
};
const App = props => {
return (
<div>
Text : <Input val={1} />
</div>
);
};
export default App;

Is there a way to declare styled component with different main elements?

I need to create 2 similar styled components, which will share their styling but use different HTML element.
There is a way to do in runtime with "as" property (), but I have a specific exports which I need to use the default but I need for it to be in a way without using it so the Link styled component be a "styled.a" and StyledLink component to be "styled.span", I tried to do something like:
export const StyledLink = styled.span(`
color: ${props => props.theme.colors.mainLinkColor};;
text-decoration: underline;
&:hover {
color: ${props => props.theme.colors.textAccent};
text-decoration: underline;
}
`);
export const Link = <StyledLink as={RRLink} />;
That is obviously not working... So is there a way for a Link to mimic StyledLink styles but use an "a" tag instead of "span"?
Simply import and use css from styled-components like so:
import React from "react";
import ReactDOM from "react-dom";
import styled, { css } from 'styled-components';
const sharedStyles = css`
background-color: gold;
`;
const Div = styled.div`
${sharedStyles}
`;
const Button = styled.button`
${sharedStyles}
`;
const App = () => (
<>
<Div>Hello Div</Div>
<Button>Hello Button</Button>
</>
);
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

pass background url as prop to styled component

I have the following code:
// #flow
import React from 'react';
import { Route } from 'react-router-dom';
import Split from '../../components/grouping/Split';
import CenterBox from '../../components/grouping/CenterBox';
import styled from 'styled-components';
type Props = {
routes: Array<Object>,
background: String
};
export default ({ routes, background }: Props) =>
(<div>
<Split push="right" alignItems="center" height={50} pad={{ horizontal: 20 }}>
<div />
<div>This feature will be available soon!</div>
</Split>
<DashboardContent background={background}>
<CenterBox>
<div style={{ transform: 'translateY(50%)' }}>
<CenterBox height={300} width={500} backgroundColor="#FFFFFF">
This feature is not included as part of the design beta and will be available soon
</CenterBox>
</div>
</CenterBox>
</DashboardContent>
</div>);
const DashboardContent = styled.div`
background: url(${props => props.background}) no-repeat top
center;
background-size: 100%;
min-height: 100vh;
`;
I would like to pass background as a prop to my styled component so that when it is passed a link to an image file it sets it as a background, the code compiles but the background does not show up. What am I doing wrong?
Changing your background property to be a function that returns a string will fix your issue.
background: ${props => `url(${props.background}) no-repeat top center`};
Is this going to work out fine?
const DashboardContent = styled.div`
background: url(${props => props.background}) no-repeat top center;
`
<DashboardContent background={`https://xxxx/xxxx${background}`}/>
This worked for me!
import styled from 'styled-components';
import img from './img/background.gif';
const Content = styled.div`
background-image: url(${img});
`;

Resources