11

I would like to dynamically, partially fill a react-icons sourced Font Awesome Star using linear gradient. I have tried the following:

React Component with Inline Style - Setting the background of the parent span to gradient and making the SVG transparent. Can't seem to set the border around the SVG star to #FFFFFF so I see the parent span's whole background. See below:

import React from 'react'
import FaStar from 'react-icons/lib/fa/star'

const Stars = () => {

  const inlineStyle = (pctFill) => {
    return(
      {background: 'linear-gradient(90deg, #134758 '+pctFill+'%, #d3d3d3 '+pctFill+'%)'}
    )
  }

  return(
    <div>
      <span style={inlineStyle(50)}>
        <FaStar />
      </span>
    </div>
  )
}

export default Stars

I have also tried creating a linearGradient component and setting the path's fill="url(#component)", but react-icons path is the 3rd child to my parent span which I can't figure out how to access.

Please help

JasonA
  • 241
  • 2
  • 5
  • 13

3 Answers3

10

Was having the same issue, here's a simple working solution:

  1. Add a < svg > element wrapping a < gradient > element to the component.

  2. Add an id to the < gradient >

  3. Link the gradient to the "stroke" property of the icon via "url(< id >)":

import { FiCheck } from 'react-icons/fi';

//...

<svg width="0" height="0">
  <linearGradient id="blue-gradient" x1="100%" y1="100%" x2="0%" y2="0%">
    <stop stopColor="#7a6ded" offset="0%" />
    <stop stopColor="#591885" offset="100%" />
  </linearGradient>
</svg>


<FiCheck style={{ stroke: "url(#blue-gradient)" }} />

obs: In some packs you may need to switch "stroke" to "fill".

Felipe Chernicharo
  • 3,619
  • 2
  • 24
  • 32
1

  <svg width="1em" height="1em">
  <linearGradient id="blue-gradient" x1="100%" y1="100%" x2="0%" y2="0%">
    <stop stopColor="#7a6ded" offset="0%" />
    <stop stopColor="#591885" offset="100%" />
  </linearGradient>

<FaFacebook style={{ fill: "url(#blue-gradient)"}}/>

My code worked in this way. Thanks a lot.

  • Hi there. Your answer seems to be almost the same as the one highest voted. Were you really answering the question, or just commenting? The answer should always bring something new to the picture. If it does, describe its improvements over the previous answer. – Dan Macak Jun 20 '21 at 16:11
0

I think I found a solution, using additional svg and def tags. Only setback is that you must specify width and height of svg.

<Button className="border-0">
      <svg width="20" height="20">
         ------------------------------- // add linearGradient
        <defs>
          <linearGradient id="myGradient" gradientTransform="rotate(90)">
            <stop offset="5%"  stopColor="gold" />
            <stop offset="95%" stopColor="red" />
          </linearGradient>
        </defs>
          --------------------------------------- //pass attr to react icon
        <IconContext.Provider value={{ attr: {fill: "url('#myGradient')"}}}>
          <FaInstagram />
        </IconContext.Provider>
      </svg>
    </Button>

Hope this works!

MoJo
  • 35
  • 7