如何把 React.Component 到 CSS 内容 属性 (在 :before/:after 伪元素中)?

How to put React.Component to CSS content property (in :before/:after pseudo-elements)?

styled-components 中,我试图通过 content 传递一个 React 图标,使其在悬停时呈现,但由于某种原因,我的悬停呈现是 [Object Object]

组件:

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};
  }
`

我把所有东西都带进来了:

import styled from 'styled-components'
import { Link } from 'gatsby'
import { FaArrowRight } from 'react-icons/fa'

对内容的其他尝试

content: ${FaArrowRight};

但我发现这不起作用:

That is because content value must be within quotes in CSS.

意识到我可能在 CSS 精神状态中度过了太长时间,我尝试引入 React:

import React from 'react'
import styled from 'styled-components'
import { Link } from 'gatsby'
import { FaArrowRight } from 'react-icons/fa'

和渲染:

content: '${(<FaArrowRight />)}';

当我尝试使用模板文字时,出现缺少分号的错误:

content: `'${<FaArrowRight />}'`;

所有尝试都呈现为 [Object Object]

研究一下是否有人问过这个问题,我已经通读了:

styled-components 中如何在 content 中呈现 React 图标?

如果需要用styled-components (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 component 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代替。

这个有效(CodeSandbox):

import { createElement } from "react";
import { render } from "react-dom";
import { renderToStaticMarkup } from "react-dom/server";
import styled from "styled-components";
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")
);

感谢this Github Gist