SvgIcon Code Generator 2

SvgIcon Code Generator 2

by Csaba Hellinger

HTML

<h1>SvgIcon Code Generator</h1>
<p>Convert a list of SVG file names into code that can be added to SvgIcon.tsx</p>

<h3>SVG File Names</h3>
<p>Copy all the file names here. Finder: Select All, Cmd + Opt + C.</p>
<textarea id="filenames">
/Users/csabahellinger/Downloads/icons/accedo_one_logo_white.svg
/Users/csabahellinger/Downloads/icons/airplay_connected_system.svg
/Users/csabahellinger/Downloads/icons/airplay_system.svg
/Users/csabahellinger/Downloads/icons/android_back_system.svg
/Users/csabahellinger/Downloads/icons/rating_us_mpaa_pg_13.svg
</textarea>

<h3>Code</h3>
<p>Copy and paste this into the SvgIcon.tsx between the "BEGIN" and "END" comments.</p>
<textarea id="code" readonly>
</textarea>

CSS

body {
  margin: 0 1rem;
  box-sizing: content-box;
  background: #222;
  color: #FFF;
  font-family: sans-serif, Helvetica;
  font-size: 18px;
}

h1, h3 {
  margin-bottom: 0;
}

p {
  margin: 0;
  font-size: 0.8rem;
}

textarea {
  width: 100%;
  background: #333;
  color: #FFF;
  font-family: fixed, Courier;
  min-height: 5rem;
  color: aqua;
}

#code {
  min-height: 15rem; 
}

JavaScript

const elFilenames = document.querySelector('#filenames');
const elCode = document.querySelector('#code');

const convert = () => {
  // clean up the names
	const names = elFilenames.value
    .split('\n')
    .map(name => name.trim())
    .filter(Boolean)
    .map(name => name.match(/(?:\\|\/)([^\/\\]*).svg$/)[1]);

  // go over them and generate import and mapping lines
  const imports = [];
  const subTypes = {
    NORMAL: [], // normal icons, without a specific subtype
    PG: [] // parental guidance icons, filename starts with "rating_"
  }
  names.forEach(name => {
    const comp = name
      .replace(/^(\w)/, match => match.toUpperCase()) 
      .replace(/(_\w)/g, match => match.toUpperCase().substr(1))
    const from = `'../icons/${name}.svg'`;
    const key = name.replace(/\-/g, '_');
    imports.push(`import { ReactComponent as ${comp} } from ${from};`);
    if (key.startsWith('rating_')) {
      subTypes.PG.push(`    '${key.replace(/^rating_/, '')}': ${comp}`);        
    } else {
      subTypes.NORMAL.push(`    '${key}': ${comp}`);        
    }
  });
  
  // joining it all together
  const code = [
    '// importing SVG files',
    imports.join('\n'),
    '',
    '// mapping names to components',
    'type SvgComponent = FunctionComponent<SVGProps<SVGSVGElement>>;',
    'type IconMap = { [key: string]: SvgComponent };',
    'type IconMaps = { [key: string]: IconMap };',
    'const SUBTYPES: IconMaps = {',        
		Object.entries(subTypes).map(([key, value]) => ([
      `  [IconSubType.${key}]: {`,
      value.join(',\n'),
      '  }'
    ].join('\n'))).join(',\n'),
    '};'    
  ].join('\n');
  
  // show the result
  elCode.value = code;
};

convert();
elFilenames.oninput = convert;