feat: copy as React and Vue components

This commit is contained in:
Anthony Fu 2020-08-05 15:12:27 +08:00
parent 79997aa899
commit 4528c9c14d
8 changed files with 100 additions and 12 deletions

View File

@ -5,9 +5,9 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Icônes</title>
<link rel="icon" href="/favicon.svg">
<script src="//lib/iconify.min.js"></script>
<script src="//lib/svg-packer.js" defer></script>
<script src="//lib/jszip.min.js" defer></script>
<script src="/lib/iconify.min.js"></script>
<script src="/lib/svg-packer.js" defer></script>
<script src="/lib/jszip.min.js" defer></script>
</head>
<body class="dragging">
<div id="app"></div>

View File

@ -16,8 +16,9 @@
},
"homepage": "https://github.com/antfu/icones#readme",
"scripts": {
"postinstall": "node -r esm -r esbuild-register scripts/prepare.ts",
"postbuild": "node -r esm -r esbuild-register scripts/postbuild.ts",
"postinstall": "esno scripts/prepare.ts",
"prebuild": "esno scripts/prebuild.ts",
"postbuild": "esno scripts/postbuild.ts",
"dev": "vite --port 3333",
"dev:electron": "npm -C ./electron run dev",
"build": "vite build",
@ -26,6 +27,7 @@
"dependencies": {
"@vueuse/core": "^4.0.0-beta.4",
"dexie": "^3.0.2",
"esno": "^0.1.6",
"fuse.js": "^6.4.1",
"hotkeys-js": "^3.8.1",
"tailwindcss": "^1.6.2",
@ -38,7 +40,6 @@
"@iconify/json": "^1.1.200",
"@types/fs-extra": "^9.0.1",
"@typescript-eslint/eslint-plugin": "^3.8.0",
"esbuild-register": "^1.0.2",
"eslint": "^7.6.0",
"esm": "^3.2.25",
"fs-extra": "^9.0.1",

View File

@ -5,3 +5,9 @@ import { promises as fs } from 'fs'
const file = await fs.readFile(path, 'utf-8')
await fs.writeFile(path, file.replace(/\/\/lib/g, '/lib'), 'utf-8')
})()
;(async() => {
const path = './index.html'
const file = await fs.readFile(path, 'utf-8')
await fs.writeFile(path, file.replace(/\/\/lib/g, '/lib'), 'utf-8')
})()

7
scripts/prebuild.ts Normal file
View File

@ -0,0 +1,7 @@
import { promises as fs } from 'fs'
;(async() => {
const path = './index.html'
const file = await fs.readFile(path, 'utf-8')
await fs.writeFile(path, file.replace(/\/lib/g, '//lib'), 'utf-8')
})()

View File

@ -52,11 +52,8 @@
<div class="flex flex-wrap">
<div class="mr-4">
<div class="my-1 text-gray-500 mt-3">
Copy
Snippets
</div>
<button class="btn mr-1 mb-1" @click="copy('url')">
URL
</button>
<button class="btn mr-1 mb-1" @click="copy('html')">
HTML
</button>
@ -66,6 +63,25 @@
<button class="btn mr-1 mb-1" @click="copy('svg')">
SVG
</button>
</div>
<div class="mr-4">
<div class="my-1 text-gray-500 mt-3">
Components
</div>
<button class="btn mr-1 mb-1" @click="copy('react')">
React
</button>
<button class="btn mr-1 mb-1" @click="copy('vue')">
Vue
</button>
</div>
<div class="mr-4">
<div class="my-1 text-gray-500 mt-3">
Links
</div>
<button class="btn mr-1 mb-1" @click="copy('url')">
URL
</button>
<button class="btn mr-1 mb-1" @click="copy('data_url')">
Data URL
</button>

View File

@ -6,6 +6,51 @@ export async function getSvg(icon: string) {
return window.Iconify.getSVG(icon, undefined) || await fetch(`${API_ENTRY}/${icon}.svg?inline=false&height=auto`).then(r => r.text()) || ''
}
export function toComponentName(icon: string) {
return icon.split(/:|-|_/).filter(Boolean).map((s, i) => s[0].toUpperCase() + s.slice(1).toLowerCase()).join('')
}
export function ClearSvg(svgCode: string) {
const el = document.createElement('div')
el.innerHTML = svgCode
const svg = el.getElementsByTagName('svg')[0]
const keep = ['viewBox', 'width', 'height', 'focusable']
for (const key of Object.values(svg.attributes)) {
if (keep.includes(key.localName))
continue
svg.removeAttributeNode(key)
}
return el.innerHTML
}
export function SvgToReact(svg: string, name: string) {
return `
import * as React from 'react'
function ${name}(props) {
return (
${ClearSvg(svg).replace(/<svg (.*?)>/, '<svg $1 {...props}>')}
)
}
export default ${name}
`
}
export function SvgToVue(svg: string, name: string) {
return `
<template>
${ClearSvg(svg)}
</template>
<script>
export default {
name: '${name}'
}
</script>
`
}
export async function getIconSnippet(icon: string, type: string): Promise<string | undefined> {
if (!icon)
return
@ -23,6 +68,10 @@ export async function getIconSnippet(icon: string, type: string): Promise<string
return await getSvg(icon)
case 'data_url':
return `data:image/svg+xml;base64,${Base64.encode(await getSvg(icon))}`
case 'react':
return SvgToReact(await getSvg(icon), toComponentName(icon))
case 'vue':
return SvgToVue(await getSvg(icon), toComponentName(icon))
}
}

View File

@ -13,6 +13,6 @@
},
"exclude": [
"dist",
"node_modules"
"node_modules",
]
}

View File

@ -3750,7 +3750,7 @@ esbuild-register@^1.0.2:
source-map-support "^0.5.19"
strip-json-comments "^3.1.1"
esbuild@^0.6.10:
esbuild@^0.6.10, esbuild@^0.6.16:
version "0.6.16"
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.6.16.tgz#a5363761dd17283e090dae398f5ff4908cad789d"
integrity sha512-Jm4aJYAk4uBP2RssDe/rvYCrpGkfOJ5tPBZUF6da62pUtyzk8/RVwXZB4q8dxjYLKZNmY4lYJRpWY+wT3kme1w==
@ -3972,6 +3972,15 @@ esm@^3.2.25:
resolved "https://registry.yarnpkg.com/esm/-/esm-3.2.25.tgz#342c18c29d56157688ba5ce31f8431fbb795cc10"
integrity sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==
esno@^0.1.6:
version "0.1.6"
resolved "https://registry.yarnpkg.com/esno/-/esno-0.1.6.tgz#5b1900937e74ef93d99fc824742899498cb8eeee"
integrity sha512-xJ/jz/YrQ0xWfrIXCR9rYkOfBZr7RgkGWCWooN3kUd13nPkshlWXlOmTDqu5uqgQeLuAWzWVaAGsUBjIoF6dbw==
dependencies:
esbuild "^0.6.16"
esbuild-register "^1.0.2"
esm "^3.2.25"
espree@^6.2.1:
version "6.2.1"
resolved "https://registry.yarnpkg.com/espree/-/espree-6.2.1.tgz#77fc72e1fd744a2052c20f38a5b575832e82734a"