Skip to content

Commit 2210dfc

Browse files
authored
Merge pull request #13 from aboutbits/add_all_icon_variants
Add all icon variants
2 parents a3cfa94 + 935cd7a commit 2210dfc

8,512 files changed

Lines changed: 155499 additions & 163 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

generator.js

Lines changed: 66 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -2,86 +2,79 @@ const fs = require('fs')
22
const path = require('path')
33
const axios = require('axios')
44

5-
// Base url for icons
6-
const iconURL = 'https://fonts.google.com/metadata/icons'
5+
const GOOGLE_FONTS_URL = 'https://fonts.google.com/metadata/icons'
6+
const ICON_FAMILIES = [
7+
{ id: 'materialicons', postfix: '' },
8+
{ id: 'materialiconsoutlined', postfix: 'Outlined' },
9+
{ id: 'materialiconsround', postfix: 'Round' },
10+
{ id: 'materialiconssharp', postfix: 'Sharp' },
11+
{ id: 'materialiconstwotone', postfix: 'TwoTone' },
12+
]
713

8-
function setup() {
14+
;(async () => {
15+
generatePropsFile()
16+
17+
const res = await axios.get(GOOGLE_FONTS_URL)
18+
19+
// remove )]}' from the response
20+
const data = res.data.substring(4)
21+
const icons = await JSON.parse(data)
22+
23+
for (let i = 0; i < icons.icons.length; i++) {
24+
generateComponentsForAllFamilies(icons.icons[i])
25+
}
26+
})()
27+
28+
function generatePropsFile() {
929
const typesFile = `
1030
import React from 'react'
1131
export interface IconProps extends React.SVGProps<SVGSVGElement> {
1232
title?: string
1333
}
1434
`
1535

16-
// Create types file
1736
fs.writeFileSync(path.join(__dirname, 'src', 'types.ts'), typesFile)
1837
}
1938

20-
/**
21-
* Format name.
22-
* Covert from snake case to camel case and prevent numbers at the beginning
23-
*
24-
* @param string - String to format
25-
* @returns {string} - Formatted string
26-
*/
27-
function formatName(string) {
39+
async function generateComponentsForAllFamilies(icon) {
40+
for (let i = 0; i < ICON_FAMILIES.length; i++) {
41+
await generateComponent(icon, ICON_FAMILIES[i])
42+
}
43+
}
44+
45+
async function generateComponent(icon, family) {
46+
try {
47+
const name = formatName(icon.name, family.postfix)
48+
const svg = await downloadSVG(icon.name, family.id, icon.version)
49+
50+
console.log(`Downloading ${name}`)
51+
52+
await fs.writeFileSync(
53+
path.join(__dirname, 'src', `${name}.tsx`),
54+
mapSVGToTemplate(name, svg)
55+
)
56+
} catch {
57+
process.abort()
58+
}
59+
}
60+
61+
function formatName(string, familyPostfix) {
2862
const formattedString = string
2963
.replace(/_/g, ' ')
3064
.replace(/\w\S*/g, (txt) => {
3165
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase()
3266
})
3367
.replace(/ /g, '')
34-
return 'Icon' + formattedString
35-
}
3668

37-
/**
38-
* Component template for functional react icon component
39-
*
40-
* @param name - Component name
41-
* @param svg - Icon SVG
42-
* @returns {string} - Component
43-
*/
44-
function componentTemplate(name, svg) {
45-
return `
46-
import React from 'react'
47-
import { IconProps } from './types'
48-
49-
const ${name}: React.FC<IconProps> = ({ ...props }) => (
50-
${svg}
51-
)
52-
53-
export { ${name} as default }
54-
`
69+
return 'Icon' + formattedString + familyPostfix
5570
}
5671

57-
/**
58-
* Generate React Icon components
59-
*
60-
* @param icon - Icon object
61-
*/
62-
function generateComponent(icon) {
63-
icon.forEach(async (c) => {
64-
const name = formatName(c.name)
65-
const svg = await getSVGFile(c.name, c.version)
66-
67-
fs.writeFileSync(
68-
path.join(__dirname, 'src', `${name}.tsx`),
69-
componentTemplate(name, svg)
72+
async function downloadSVG(icon, familyId, version) {
73+
const svg = await axios
74+
.get(
75+
`https://fonts.gstatic.com/s/i/${familyId}/${icon}/v${version}/24px.svg`
7076
)
71-
})
72-
}
73-
74-
/**
75-
* Get SVG data form google static fonts api
76-
*
77-
* @param icon - Icon name
78-
* @param version - Icon Version
79-
* @returns {Promise<any>} - SVG Data
80-
*/
81-
async function getSVGFile(icon, version) {
82-
const svg = await axios.get(
83-
`https://fonts.gstatic.com/s/i/materialicons/${icon}/v${version}/24px.svg`
84-
)
77+
.catch((err) => console.log(err))
8578

8679
return svg.data
8780
.replace('height="24"', '')
@@ -93,23 +86,19 @@ async function getSVGFile(icon, version) {
9386
.replace('>', '>{props.title && <title>{props.title}</title>}')
9487
.replace(/style="enableBackground:(.*?);?"/g, 'enableBackground="$1"')
9588
.replace(/style="fill:(.*?);?"/g, 'fill="$1"')
89+
.replace(/xmlns:xlink/g, 'xmlnsXlink')
90+
.replace(/xlink:href/g, 'xlinkHref')
9691
}
9792

98-
/**
99-
* Main function
100-
*/
101-
;(async () => {
102-
// Setup source folder
103-
setup()
104-
105-
// Get icon information from google fonts
106-
const res = await axios.get(iconURL)
107-
// remove )]}' from the response
108-
const data = res.data.substring(4)
109-
110-
// Parse response from json to js object
111-
const icons = await JSON.parse(data)
112-
113-
// Generate icon components and Index
114-
await generateComponent(icons.icons)
115-
})()
93+
function mapSVGToTemplate(name, svg) {
94+
return `
95+
import React from 'react'
96+
import { IconProps } from './types'
97+
98+
const ${name}: React.FC<IconProps> = ({ ...props }) => (
99+
${svg}
100+
)
101+
102+
export { ${name} as default }
103+
`
104+
}

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
},
1010
"scripts": {
1111
"build": "tsc",
12-
"generate": "rm -rf src/* && node generator.js",
12+
"clear": "rm -rf src/*",
13+
"generate": "node generator.js",
1314
"lint": "eslint --ext js,ts,tsx src ./generator.js",
1415
"lint:fix": "npm run lint -- --fix",
1516
"typecheck": "tsc --noEmit",

readme.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,21 @@ import IconCached from '@aboutbits/react-material-icons/dist/IconCached'
2929

3030
const MyCommponent = () => {
3131
return (
32-
<IconCached />
33-
);
32+
<IconCached/>
33+
);
3434
}
3535
```
3636

3737
SVG related parameters like height and width can be passed as props.
3838

39+
To import the different variants of an icon you can add the variants as a postfix:
40+
41+
- `Icon10k` > Default filled
42+
- `Icon10kOutlined` > Outlined
43+
- `Icon10kRound` > Rounded
44+
- `Icon10kSharp` > Sharp
45+
- `Icon10kTwoTone` > Tow tone
46+
3947
## Generate Components
4048

4149
To generate the components, simply run the following command:

src/Icon10kOutlined.tsx

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import React from 'react'
2+
import { IconProps } from './types'
3+
4+
const Icon10kOutlined: React.FC<IconProps> = ({ ...props }) => (
5+
<svg
6+
xmlns="http://www.w3.org/2000/svg"
7+
enableBackground="new 0 0 24 24"
8+
viewBox="0 0 24 24"
9+
{...props}
10+
>
11+
{props.title && <title>{props.title}</title>}
12+
<g>
13+
<rect fill="none" height="24" width="24" />
14+
</g>
15+
<g>
16+
<g>
17+
<g>
18+
<path d="M19,3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z M19,9v6v4H5v-8.5h1V15h1.5V9H5V5 h14V9z" />
19+
<polygon points="15.5,11.25 15.5,9 14,9 14,15 15.5,15 15.5,12.75 17.25,15 19,15 16.75,12 19,9 17.25,9" />
20+
<path d="M9.5,15H12c0.55,0,1-0.45,1-1v-4c0-0.55-0.45-1-1-1H9.5c-0.55,0-1,0.45-1,1v4C8.5,14.55,8.95,15,9.5,15z M10,10.5h1.5v3 H10V10.5z" />
21+
</g>
22+
</g>
23+
</g>
24+
</svg>
25+
)
26+
27+
export { Icon10kOutlined as default }

src/Icon10kRound.tsx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import React from 'react'
2+
import { IconProps } from './types'
3+
4+
const Icon10kRound: React.FC<IconProps> = ({ ...props }) => (
5+
<svg
6+
xmlns="http://www.w3.org/2000/svg"
7+
enableBackground="new 0 0 24 24"
8+
viewBox="0 0 24 24"
9+
{...props}
10+
>
11+
{props.title && <title>{props.title}</title>}
12+
<g>
13+
<rect fill="none" height="24" width="24" />
14+
</g>
15+
<g>
16+
<path d="M10,10.5h1.5v3H10V10.5z M19,3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z M6.75,15 L6.75,15C6.34,15,6,14.66,6,14.25V10.5H5.25c-0.41,0-0.75-0.34-0.75-0.75v0C4.5,9.34,4.84,9,5.25,9H6.5c0.55,0,1,0.45,1,1v4.25 C7.5,14.66,7.16,15,6.75,15z M13,14c0,0.55-0.45,1-1,1H9.5c-0.55,0-1-0.45-1-1v-4c0-0.55,0.45-1,1-1H12c0.55,0,1,0.45,1,1V14z M17.59,15L17.59,15c-0.22,0-0.42-0.1-0.55-0.27l-1.54-1.98v1.5c0,0.41-0.34,0.75-0.75,0.75h0C14.34,15,14,14.66,14,14.25v-4.5 C14,9.34,14.34,9,14.75,9h0c0.41,0,0.75,0.34,0.75,0.75v1.5l1.54-1.98C17.17,9.1,17.38,9,17.59,9l0,0c0.58,0,0.91,0.66,0.56,1.12 L16.75,12l1.41,1.88C18.5,14.34,18.17,15,17.59,15z" />
17+
</g>
18+
</svg>
19+
)
20+
21+
export { Icon10kRound as default }

src/Icon10kSharp.tsx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import React from 'react'
2+
import { IconProps } from './types'
3+
4+
const Icon10kSharp: React.FC<IconProps> = ({ ...props }) => (
5+
<svg
6+
xmlns="http://www.w3.org/2000/svg"
7+
enableBackground="new 0 0 24 24"
8+
viewBox="0 0 24 24"
9+
{...props}
10+
>
11+
{props.title && <title>{props.title}</title>}
12+
<g>
13+
<rect fill="none" height="24" width="24" />
14+
</g>
15+
<g>
16+
<path d="M10,10.5h1.5v3H10V10.5z M21,3H3v18h18V3z M7.5,15H6v-4.5H4.5V9h3V15z M13,9v6H8.5V9H13z M19,15h-1.75l-1.75-2.25V15H14V9 h1.5v2.25L17.25,9H19l-2.25,3L19,15z" />
17+
</g>
18+
</svg>
19+
)
20+
21+
export { Icon10kSharp as default }

src/Icon10kTwoTone.tsx

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import React from 'react'
2+
import { IconProps } from './types'
3+
4+
const Icon10kTwoTone: React.FC<IconProps> = ({ ...props }) => (
5+
<svg
6+
xmlns="http://www.w3.org/2000/svg"
7+
enableBackground="new 0 0 24 24"
8+
viewBox="0 0 24 24"
9+
{...props}
10+
>
11+
{props.title && <title>{props.title}</title>}
12+
<g>
13+
<rect fill="none" height="24" width="24" />
14+
</g>
15+
<g>
16+
<g>
17+
<rect height="3" opacity=".3" width="1.5" x="10" y="10.5" />
18+
<polygon opacity=".3" points="19,15 19,9 16.75,12" />
19+
<path
20+
d="M5,9h2.5v6H6v-4.5H5V19h14v-4h-1.75l-1.75-2.25V15H14V9h1.5v2.25L17.25,9H19V5H5V9z M8.5,10 c0-0.55,0.45-1,1-1H12c0.55,0,1,0.45,1,1v4c0,0.55-0.45,1-1,1H9.5c-0.55,0-1-0.45-1-1V10z"
21+
opacity=".3"
22+
/>
23+
<path d="M19,3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z M19,9v6v4H5v-8.5h1V15h1.5V9H5V5 h14V9z" />
24+
<polygon points="15.5,11.25 15.5,9 14,9 14,15 15.5,15 15.5,12.75 17.25,15 19,15 16.75,12 19,9 17.25,9" />
25+
<path d="M9.5,15H12c0.55,0,1-0.45,1-1v-4c0-0.55-0.45-1-1-1H9.5c-0.55,0-1,0.45-1,1v4C8.5,14.55,8.95,15,9.5,15z M10,10.5h1.5v3 H10V10.5z" />
26+
</g>
27+
</g>
28+
</svg>
29+
)
30+
31+
export { Icon10kTwoTone as default }

src/Icon10mpOutlined.tsx

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import React from 'react'
2+
import { IconProps } from './types'
3+
4+
const Icon10mpOutlined: React.FC<IconProps> = ({ ...props }) => (
5+
<svg
6+
xmlns="http://www.w3.org/2000/svg"
7+
enableBackground="new 0 0 24 24"
8+
viewBox="0 0 24 24"
9+
{...props}
10+
>
11+
{props.title && <title>{props.title}</title>}
12+
<g>
13+
<rect fill="none" height="24" width="24" />
14+
</g>
15+
<g>
16+
<g>
17+
<g>
18+
<path d="M13,11.5h2.5c0.55,0,1-0.45,1-1v-4c0-0.55-0.45-1-1-1H13c-0.55,0-1,0.45-1,1v4C12,11.05,12.45,11.5,13,11.5z M13.5,7H15 v3h-1.5V7z" />
19+
</g>
20+
<g>
21+
<path d="M7.5,14h1v3H10v-3h1v4.5h1.5v-5c0-0.55-0.45-1-1-1H7c-0.55,0-1,0.45-1,1v5h1.5V14z" />
22+
</g>
23+
<g>
24+
<polygon points="8.5,11.5 10,11.5 10,5.5 7,5.5 7,7 8.5,7" />
25+
</g>
26+
<g>
27+
<path d="M13.5,18.5H15V17h2c0.55,0,1-0.45,1-1v-2.5c0-0.55-0.45-1-1-1h-3.5V18.5z M15,14h1.5v1.5H15V14z" />
28+
</g>
29+
<g>
30+
<path d="M19,3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z M19,19H5V5h14V19z" />
31+
</g>
32+
</g>
33+
</g>
34+
</svg>
35+
)
36+
37+
export { Icon10mpOutlined as default }

src/Icon10mpRound.tsx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import React from 'react'
2+
import { IconProps } from './types'
3+
4+
const Icon10mpRound: React.FC<IconProps> = ({ ...props }) => (
5+
<svg
6+
xmlns="http://www.w3.org/2000/svg"
7+
enableBackground="new 0 0 24 24"
8+
viewBox="0 0 24 24"
9+
{...props}
10+
>
11+
{props.title && <title>{props.title}</title>}
12+
<g>
13+
<rect fill="none" height="24" width="24" />
14+
</g>
15+
<g>
16+
<g>
17+
<path d="M13.5,7H15v3h-1.5V7z M19,3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z M11.75,18.5 L11.75,18.5c-0.41,0-0.75-0.34-0.75-0.75V14h-1v2.25C10,16.66,9.66,17,9.25,17h0c-0.41,0-0.75-0.34-0.75-0.75V14h-1v3.75 c0,0.41-0.34,0.75-0.75,0.75h0C6.34,18.5,6,18.16,6,17.75V13.5c0-0.55,0.45-1,1-1h4.5c0.55,0,1,0.45,1,1v4.25 C12.5,18.16,12.16,18.5,11.75,18.5z M14.25,18.5L14.25,18.5c-0.41,0-0.75-0.34-0.75-0.75V13.5c0-0.55,0.45-1,1-1H17 c0.55,0,1,0.45,1,1V16c0,0.55-0.45,1-1,1h-2v0.75C15,18.16,14.66,18.5,14.25,18.5z M10,6.5v4.25c0,0.41-0.34,0.75-0.75,0.75h0 c-0.41,0-0.75-0.34-0.75-0.75V7H7.75C7.34,7,7,6.66,7,6.25v0C7,5.84,7.34,5.5,7.75,5.5H9C9.55,5.5,10,5.95,10,6.5z M16.5,10.5 c0,0.55-0.45,1-1,1H13c-0.55,0-1-0.45-1-1v-4c0-0.55,0.45-1,1-1h2.5c0.55,0,1,0.45,1,1V10.5z M15,14h1.5v1.5H15V14z" />
18+
</g>
19+
</g>
20+
</svg>
21+
)
22+
23+
export { Icon10mpRound as default }

0 commit comments

Comments
 (0)