In styled-ponents
, I'm trying to get a React Icon to render on hover by passing it through content
but for some reason, my render on hover is [Object Object]
.
Component:
export const FooLink = styled(Link)`
padding: 0.5rem 2rem;
color: ${({ theme }) => theme.colors.white};
text-align: center;
margin: 0 auto;
position: relative;
font-size: ${({ theme }) => theme.fontSizes.p};
letter-spacing: 0.15em;
transition: ${({ theme }) => theme.animations.trans3};
&:after {
content: '${FaArrowRight}';
/* content: '>'; */
position: absolute;
opacity: 0;
right: -${({ theme }) => theme.spacings.small};
transition: ${({ theme }) => theme.animations.trans3};
}
&:hover {
padding-right: ${({ theme }) => theme.spacings.small};
padding-left: ${({ theme }) => theme.spacings.xxSmall};
}
&:hover:after {
opacity: 1;
${({ theme }) => theme.spacings.xSmall};
}
`
Ive brought everything in with:
import styled from 'styled-ponents'
import { Link } from 'gatsby'
import { FaArrowRight } from 'react-icons/fa'
Other attempts on content
content: ${FaArrowRight};
But I found this won't work per:
That is because content value must be within quotes in CSS.
Realizing I might have spent too long in a CSS mental state I tried bringing in React:
import React from 'react'
import styled from 'styled-ponents'
import { Link } from 'gatsby'
import { FaArrowRight } from 'react-icons/fa'
And rendering:
content: '${(<FaArrowRight />)}';
when I try with template literals I get an error with missing semi-colons:
content: `'${<FaArrowRight />}'`;
All attempts render as [Object Object]
Research to see if this has been asked and I've read through:
- How to render pseudo before content dynamically in styled-ponent
- Before and After pseudo classes used with styled-ponents
- css pseudo code “li::before” in react inline style
- How do I get a variable from a graphQl query into a pseudo element in either inline styles or styled ponents
- Do psuedo selectors work in styled-ponents the same as in css with unicode characters
In styled-ponents
how can I render a React Icon in content
?
In styled-ponents
, I'm trying to get a React Icon to render on hover by passing it through content
but for some reason, my render on hover is [Object Object]
.
Component:
export const FooLink = styled(Link)`
padding: 0.5rem 2rem;
color: ${({ theme }) => theme.colors.white};
text-align: center;
margin: 0 auto;
position: relative;
font-size: ${({ theme }) => theme.fontSizes.p};
letter-spacing: 0.15em;
transition: ${({ theme }) => theme.animations.trans3};
&:after {
content: '${FaArrowRight}';
/* content: '>'; */
position: absolute;
opacity: 0;
right: -${({ theme }) => theme.spacings.small};
transition: ${({ theme }) => theme.animations.trans3};
}
&:hover {
padding-right: ${({ theme }) => theme.spacings.small};
padding-left: ${({ theme }) => theme.spacings.xxSmall};
}
&:hover:after {
opacity: 1;
${({ theme }) => theme.spacings.xSmall};
}
`
Ive brought everything in with:
import styled from 'styled-ponents'
import { Link } from 'gatsby'
import { FaArrowRight } from 'react-icons/fa'
Other attempts on content
content: ${FaArrowRight};
But I found this won't work per:
That is because content value must be within quotes in CSS.
Realizing I might have spent too long in a CSS mental state I tried bringing in React:
import React from 'react'
import styled from 'styled-ponents'
import { Link } from 'gatsby'
import { FaArrowRight } from 'react-icons/fa'
And rendering:
content: '${(<FaArrowRight />)}';
when I try with template literals I get an error with missing semi-colons:
content: `'${<FaArrowRight />}'`;
All attempts render as [Object Object]
Research to see if this has been asked and I've read through:
- How to render pseudo before content dynamically in styled-ponent
- Before and After pseudo classes used with styled-ponents
- css pseudo code “li::before” in react inline style
- How do I get a variable from a graphQl query into a pseudo element in either inline styles or styled ponents
- Do psuedo selectors work in styled-ponents the same as in css with unicode characters
In styled-ponents
how can I render a React Icon in content
?
-
stick a
&
before:after
– Tom Bombadil Commented Mar 31, 2021 at 16:06 -
ya that was an edit mistake but even then it still renders as
object object
– GʀᴜᴍᴘʏCᴀᴛ Commented Mar 31, 2021 at 16:07 -
'${FaArrowRight}'
Use back ticks instead of single quotes. – Tom Bombadil Commented Mar 31, 2021 at 16:09 -
@TomBombadil as explained in the question, from my research, single quotes should be used with
content
instead of template literals. – GʀᴜᴍᴘʏCᴀᴛ Commented Mar 31, 2021 at 16:18 -
As far as I know you can't pass an objects as value to content. And I think you are passing an object. Not sure if
FaArrowRight
is a string or an object. – Tom Bombadil Commented Mar 31, 2021 at 16:30
1 Answer
Reset to default 6If you need to use styled-ponents
(or any other CSS-in-JS library) with an icon from react-icons
(or any other library that exports a React.Component
which renders an <svg>
element), I see the only one way: to transform a ponent to an url()
with a markup string because only this way you can pass an image to content
property in your case. For that transformation, you need: React.createElement()
, ReactDOMServer.renderToStaticMarkup()
and encodeURIComponent()
. Also, you can use Base64 instead.
This one works (CodeSandbox):
import { createElement } from "react";
import { render } from "react-dom";
import { renderToStaticMarkup } from "react-dom/server";
import styled from "styled-ponents";
import { Link } from "gatsby";
import { FaArrowRight } from "react-icons/fa";
window.___loader = { enqueue: () => {}, hovering: () => {} };
const reactSvgComponentToMarkupString = (Component, props) =>
`data:image/svg+xml,${encodeURIComponent(
renderToStaticMarkup(createElement(Component, props))
)}`;
const FooLink = styled(Link)`
${({ color }) => color && `color: ${color};`}
&:after {
content: ${({ color }) =>
`url(${reactSvgComponentToMarkupString(FaArrowRight, {
color
})})`};
position: absolute;
opacity: 0;
}
&:hover:after {
opacity: 1;
}
`;
render(
<>
<div>
<FooLink to="/test1" color="red">
Link with arrow (red)
</FooLink>
</div>
<div>
<FooLink to="/test2">Link with arrow (default)</FooLink>
</div>
</>,
document.getElementById("root")
);
Thanks to this Github Gist.