Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
ee5d779
Add git ignore file
Oct 2, 2020
fb5ac91
Add package files
Oct 2, 2020
7ffbc05
Add React SVG prop type
Oct 2, 2020
20c982a
Add component generator
Oct 2, 2020
df815d6
Updated readme.md
Oct 2, 2020
a67a56b
Add license
Oct 2, 2020
295a8b4
Set axios as dev dependency
Oct 2, 2020
2e3757d
Add build instructor to readme.md
Oct 2, 2020
20f9e58
Add clean script to package.json
Oct 2, 2020
a8fc593
Add clean script description to readme.md
Oct 2, 2020
bd2bf5a
Add index generation to generator.js
Oct 2, 2020
e87258f
Add eslint config file to the project root
Oct 5, 2020
4d3513b
Add prettier config file to project root
Oct 5, 2020
5232fb9
Add jest config file to project root
Oct 5, 2020
497f760
Add typescript config file to project root
Oct 5, 2020
daac250
Updated git ignore file
Oct 5, 2020
e0f7e78
Renamed generator to bootstrapper.js and move it into source folder
Oct 5, 2020
815ef0a
Update files in package.json
Oct 5, 2020
0dcdee2
Updated readme.md with required changes
Oct 5, 2020
69c90f7
Removed unused tsconfig.json
Oct 5, 2020
202fe22
Removed static types.ts. Replaces with generated one
Oct 5, 2020
4574a61
Added additional build command to readme.md
Oct 5, 2020
26205f5
Fixed lint error
Oct 5, 2020
7b2369f
Renamed component generator from bootstrapper.js to generator.js
Oct 5, 2020
b185076
Add git ignore to keep src folder
Oct 5, 2020
0cff09d
Add typescript compiler config file
Oct 5, 2020
87e2b61
Cleanup readme.md
Oct 5, 2020
f10c073
Add react as peer dependency and changed some scripts
Oct 5, 2020
5fd82c9
Exclude tests in ts compiler config
Oct 5, 2020
291c9c6
Fixed typo in readme.md
Oct 5, 2020
89f8e52
Split keywords
Oct 5, 2020
9607952
Fixed typo in package.json
Oct 5, 2020
a1b412e
Fixed typo in readme.md
Oct 5, 2020
87bfcfb
Fixed formatting issue in readme.md
Oct 5, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"parser": "@typescript-eslint/parser",
"env": {
"browser": true,
"node": true
},
"plugins": [
"prettier",
"@typescript-eslint",
"jest",
"import"
],
"extends": [
"prettier",
"plugin:prettier/recommended",
"plugin:@typescript-eslint/recommended",
"plugin:import/typescript"
],
"parserOptions": {
"sourceType": "module",
"ecmaVersion": 2018
},
"rules": {
"import/namespace": "off",
"import/order": [
"error"
],
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": "error",
"@typescript-eslint/member-delimiter-style": "off",
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/no-var-requires": "off",
"@typescript-eslint/no-extra-semi": "off"
},
"overrides": [
{
// enable the rule specifically for TypeScript files
"files": [
"*.ts",
"*.tsx"
],
"rules": {
"@typescript-eslint/explicit-function-return-type": [
"error"
]
}
}
]
}
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Basic
.DS_Store

# IDE
/.idea
/.vscode

# Project
/package-lock.json
/node_modules
/dist
4 changes: 4 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"singleQuote": true,
"semi": false
}
125 changes: 125 additions & 0 deletions generator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
const fs = require('fs')
const path = require('path')
const axios = require('axios')

// Base url for icons
const iconURL = 'https://fonts.google.com/metadata/icons'

function setup() {
// Create components folder
fs.mkdirSync(path.join(__dirname, 'src', 'components'))

// Create types file
fs.writeFileSync(
path.join(__dirname, 'src', 'components', 'types.ts'),
'import React from "react" \nexport type IconProps = React.SVGProps<SVGSVGElement>'
)
}

/**
* Format name.
* Covert from snake case to camel case and prevent numbers at the beginning
*
* @param string - String to format
* @returns {string} - Formatted string
*/
function formatName(string) {
const formattedString = string
.replace(/_/g, ' ')
.replace(/\w\S*/g, (txt) => {
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase()
})
.replace(/ /g, '')
return 'Icon' + formattedString
}

/**
* Component template for functional react icon component
*
* @param name - Component name
* @param svg - Icon SVG
* @returns {string} - Component
*/
function componentTemplate(name, svg) {
let component = "import React from 'react'\n"
component += "import { IconProps } from './types'\n"
component += `const ${name}: React.FC<IconProps> = (props) => (`
component += svg + ')\n\n'
component += `export { ${name} }`

return component
}

/**
* Generate React Icon components
*
* @param icon - Icon object
*/
function generateComponent(icon) {
icon.forEach(async (c) => {
const name = formatName(c.name)
const svg = await getSVGFile(c.name, c.version)

fs.writeFileSync(
path.join(__dirname, 'src', 'components', `${name}.tsx`),
componentTemplate(name, svg)
)
})
}

/**
* Generate index tsx file for easy import
*
* @param icons - Array of icons
*/
function generateIndex(icons) {
let imports = ''
let exports = 'export {\n'

icons.forEach((icon) => {
const name = formatName(icon.name)
imports += `import { ${name} } from './components/${name}'\n`
exports += ` ${name},\n`
})
exports += '}'

fs.writeFileSync(
path.join(__dirname, 'src', 'index.ts'),
imports + '\n' + exports
)
}

/**
* Get SVG data form google static fonts api
*
* @param icon - Icon name
* @param version - Icon Version
* @returns {Promise<any>} - SVG Data
*/
async function getSVGFile(icon, version) {
const svg = await axios.get(
`https://fonts.gstatic.com/s/i/materialicons/${icon}/v${version}/24px.svg`
)

return svg.data.replace('height="24"', '').replace('width="24"', '{...props}')
}

/**
* Main function
*/
;(async () => {
// Setup source folder
setup()

// Get icon information from google fonts
const res = await axios.get(iconURL)
// remove )]}' from the response
const data = res.data.substring(4)

// Parse response from json to js object
const icons = await JSON.parse(data)

// Generate icon components and Index
await generateComponent(icons.icons)
await generateIndex(icons.icons)
})()
7 changes: 7 additions & 0 deletions jestconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"transform": {
"^.+\\.(t|j)sx?$": "ts-jest"
},
"testRegex": "(/__tests?__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
"moduleFileExtensions": ["ts", "tsx", "js", "jsx", "json", "node"]
}
9 changes: 9 additions & 0 deletions license.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@


Copyright About Bits GmbH

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Loading