Navigation Menu

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: SVG Recolor Component #1

Closed
wants to merge 2 commits into from

Conversation

wallycarvalho
Copy link

@wallycarvalho wallycarvalho commented Nov 19, 2020

Intro

This PR introduces a set of changes that allows a consumer to generate a customized React SVG component. This library already changes certain things and improves on others (using svgr). This leads to a problem that we have..

Problem

As of now, we have no way to customize the component -- meaning recoloring. The current solution is to generate another SVG component with the desired color. Not ideal.

How it works

This PR adds another code sweep in order to:

  1. Look for hex color codes in the source SVG files
  2. Create a default array or colors to be used and applied to the component if no color has been passed down to the component
  3. Change / Rename / Define new props that will be used for colors and spread ...rest into main svg container element
  4. Replace any fills or stroke with the color array received from props or from the pre-defined default colors extracted from the SVG source file.
  5. If one color has been passed to the component as a string, we guarantee it's going to be applied to all fills and strokes in the svg

Usage

Scenario 1 - Simple string color

const Icon = getVector('icons/ChevronUp');

<View>
 <Icon color="#699689" />
</View>

Scenario 2 - Multi color icon - The color order follows the order color appearance in the component/svg

const Icon = getVector('icons/Avatar_Dark');

<View>
 <Icon color=['#02818E', '#55BAC6'] />
</View>

Scenario 3 - No need to pass a color down. It will apply whatever was part of the svg file.

const Icon = getVector('icons/Avatar_Dark');

<View>
 <Icon />
</View>

Show me the final product

// @ts-nocheck
import * as React from 'react';
import Svg, { SvgProps, G, Path } from 'react-native-svg';

const defaultColors = ['#02818E','#55BAC6'];

function SvgComponent({ color = defaultColors, ...rest } : { color: Array | String; rest: SvgProps }) {
  const svgColor = typeof color === 'string' ? new Array(defaultColors.length).fill(color) : color;

return (
    <Svg width={48} height={48} viewBox="0 0 48 48" {...rest}>
      <G stroke="none" strokeWidth={1} fill="none" fillRule="evenodd">
        <Path
          d="M24 0c13.236 0 24 10.764 24 24S37.236 48 24 48 0 37.236 0 24 10.764 0 24 0zm0 1.6C11.636 1.6 1.6 11.636 1.6 24c0 6.371 2.665 12.124 6.94 16.204.374-.835.824-1.649 1.35-2.386.874-1.163 1.746-2.182 2.91-3.054 1.018-.728 3.49-1.746 4.073-2.037.436-.29 2.036-1.163 2.909-2.036.873-.873 1.163-2.182 1.309-2.618-3.2-1.164-5.527-4.218-5.527-7.855 0-4.654 3.636-8.29 8.29-8.29 4.655 0 8.291 3.781 8.291 8.29 0 3.637-2.327 6.691-5.527 7.855.146.582.437 1.745 1.31 2.618 1.017 1.018 3.054 2.036 3.054 2.036.727.291 3.054 1.31 4.073 2.037 1.163.872 2.036 1.89 2.909 3.054.577.809 1.063 1.709 1.239 2.628C43.627 36.354 46.4 30.498 46.4 24 46.4 11.636 36.364 1.6 24 1.6z"
          fill={svgColor[0]}
        />
        <Path
          d="M37.964 37.818c-.873-1.163-1.746-2.182-2.91-3.054-1.018-.728-3.345-1.746-4.072-2.037 0 0-2.037-1.018-3.055-2.036-.872-.873-1.163-2.036-1.309-2.618 3.2-1.164 5.527-4.218 5.527-7.855 0-4.509-3.636-8.29-8.29-8.29 0 15.417-.145 14.69-.145 34.472 9.31 0 15.71-5.828 15.565-5.973-.145-1.018-.584-1.59-1.311-2.609z"
          fill={svgColor[1]}
        />
      </G>
    </Svg>
  );
}

export default SvgComponent;

To do

  • handle stop element color prop
  • handle recognition and extraction of non hex colors

Last thing

How do you update the snapshot? is it a manual thing?

@wallycarvalho wallycarvalho changed the title Proposal: Adding recolor support to SVG Components dynamically Proposal: SVG Recolor Components Nov 19, 2020
@wallycarvalho wallycarvalho changed the title Proposal: SVG Recolor Components Proposal: SVG Recolor Component Nov 19, 2020
@djMax
Copy link
Contributor

djMax commented Nov 27, 2020

I'm not a fan of the string matching here. We should be parsing an AST of some variety, otherwise we are risking errors and invalid SVGs. Might there be something out there that already does this? Some svgr plugin or something?

@djMax
Copy link
Contributor

djMax commented Nov 27, 2020

@wallycarvalho
Copy link
Author

wallycarvalho commented Dec 3, 2020

I'm not a fan of the string matching here. We should be parsing an AST of some variety, otherwise we are risking errors and invalid SVGs. Might there be something out there that already does this? Some svgr plugin or something?

They don't have a direct plugin that does it, but they do provide some tools to achieve the same goal here but parsing the AST or even providing a template for the output. I will explore that and come back with a better solution. Template example.

That being said, this could still be used in the meantime to expose icon recoloring support.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants