@@ -39,22 +39,49 @@ function classToObject (classes) {
3939 )
4040}
4141
42+ /**
43+ * Creates a Vue VNode for an SVG gradient stop element.
44+ * @param {Object } stop The gradient stop definition.
45+ * @param {string|number } stop.offset The offset of the stop.
46+ * @param {string } stop.color The color of the stop.
47+ * @param {number } [stop.opacity] The opacity of the stop.
48+ * @param {number } index The index of the stop.
49+ * @returns {VNode }
50+ */
51+ function createGradientStop ( stop , index ) {
52+ return h ( 'stop' , {
53+ key : `${ index } -${ stop . offset } ` ,
54+ offset : stop . offset ,
55+ 'stop-color' : stop . color ,
56+ ...( stop . opacity !== undefined && { 'stop-opacity' : stop . opacity } )
57+ } )
58+ }
59+
4260/**
4361 * Converts a FontAwesome abstract element of an icon into a Vue VNode.
4462 * @param {AbstractElement | String } abstractElement The element to convert.
4563 * @param {Object } props The user-defined props.
4664 * @param {Object } attrs The user-defined native HTML attributes.
65+ * @param {Object } [gradientFill] Optional gradient fill config.
4766 * @returns {VNode }
4867 */
49- export default function convert ( abstractElement , props = { } , attrs = { } ) {
68+ export default function convert ( abstractElement , props = { } , attrs = { } , gradientFill = null ) {
5069 // If the abstract element is a string, we'll just return a string render function
5170 if ( typeof abstractElement === 'string' ) {
5271 return abstractElement
5372 }
5473
5574 // Converting abstract element children into Vue VNodes
75+ // If a gradientFill (or fill attr) is provided, strip fill from child path elements
76+ // so the gradient/fill takes precedence over the icon's built-in fill
77+ const hasFillOverride = gradientFill || ( 'fill' in attrs )
5678 const children = ( abstractElement . children || [ ] )
57- . map ( child => convert ( child ) )
79+ . map ( child => {
80+ if ( hasFillOverride && child . tag === 'path' && child . attributes && 'fill' in child . attributes ) {
81+ return convert ( { ...child , attributes : { ...child . attributes , fill : undefined } } )
82+ }
83+ return convert ( child )
84+ } )
5885
5986 // Converting abstract element attributes into valid Vue format
6087 const mixins = Object . keys ( abstractElement . attributes || { } )
@@ -85,6 +112,26 @@ export default function convert (abstractElement, props = {}, attrs = {}) {
85112 // Now, we'll return the VNode
86113 const { class : _aClass = { } , style : aStyle = { } , ...otherAttrs } = attrs
87114
115+ // If a gradientFill is provided, inject the gradient element and set fill to reference it
116+ if ( gradientFill ) {
117+ const { type : gradientType , stops = [ ] , id, ...gradientProps } = gradientFill
118+ const gradientTag = gradientType === 'linear' ? 'linearGradient' : 'radialGradient'
119+ const gradientVNode = h ( gradientTag , { ...gradientProps , id } , stops . map ( createGradientStop ) )
120+
121+ return h (
122+ abstractElement . tag ,
123+ {
124+ ...props ,
125+ class : mixins . class ,
126+ style : { ...mixins . style , ...aStyle } ,
127+ ...mixins . attrs ,
128+ ...otherAttrs ,
129+ fill : `url(#${ id } )`
130+ } ,
131+ [ gradientVNode , ...children ]
132+ )
133+ }
134+
88135 return h (
89136 abstractElement . tag ,
90137 {
0 commit comments