From 3331455790bff91f278c1b1330d1743e69caaead Mon Sep 17 00:00:00 2001 From: pengzhanbo Date: Sat, 18 Feb 2023 03:30:05 +0800 Subject: [PATCH] feat(plugin-iconify): add vuepress-plugin-iconify --- .vscode/settings.json | 1 + packages/plugin-iconify/LICENSE | 21 ++++++ packages/plugin-iconify/README.md | 18 +++++ packages/plugin-iconify/package.json | 49 ++++++++++++++ .../plugin-iconify/src/client/clientConfig.ts | 10 +++ .../src/client/components/Iconify.vue | 66 +++++++++++++++++++ .../src/client/composables/iconify.ts | 27 ++++++++ packages/plugin-iconify/src/client/index.ts | 2 + packages/plugin-iconify/src/node/index.ts | 6 ++ packages/plugin-iconify/src/node/plugin.ts | 25 +++++++ packages/plugin-iconify/src/shared/index.ts | 5 ++ packages/plugin-iconify/src/shim.d.ts | 4 ++ packages/plugin-iconify/tsconfig.build.json | 8 +++ packages/tsconfig.build.json | 1 + pnpm-lock.yaml | 29 ++++++++ 15 files changed, 272 insertions(+) create mode 100644 packages/plugin-iconify/LICENSE create mode 100644 packages/plugin-iconify/README.md create mode 100644 packages/plugin-iconify/package.json create mode 100644 packages/plugin-iconify/src/client/clientConfig.ts create mode 100644 packages/plugin-iconify/src/client/components/Iconify.vue create mode 100644 packages/plugin-iconify/src/client/composables/iconify.ts create mode 100644 packages/plugin-iconify/src/client/index.ts create mode 100644 packages/plugin-iconify/src/node/index.ts create mode 100644 packages/plugin-iconify/src/node/plugin.ts create mode 100644 packages/plugin-iconify/src/shared/index.ts create mode 100644 packages/plugin-iconify/src/shim.d.ts create mode 100644 packages/plugin-iconify/tsconfig.build.json diff --git a/.vscode/settings.json b/.vscode/settings.json index e8c66747..0d5b8a17 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -27,6 +27,7 @@ "frontmatter", "gsap", "iarna", + "iconify", "leancloud", "nprogress", "pnpm", diff --git a/packages/plugin-iconify/LICENSE b/packages/plugin-iconify/LICENSE new file mode 100644 index 00000000..9f677c90 --- /dev/null +++ b/packages/plugin-iconify/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (C) 2021 - PRESENT by pengzhanbo + +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. diff --git a/packages/plugin-iconify/README.md b/packages/plugin-iconify/README.md new file mode 100644 index 00000000..f2b134d2 --- /dev/null +++ b/packages/plugin-iconify/README.md @@ -0,0 +1,18 @@ +# `@vuepress-plume/vuepress-plugin-iconify` + +## Install +``` +yarn add @vuepress-plume/vuepress-plugin-iconify +``` +## Usage +``` js +// .vuepress/config.js +const iconifyPlugin = require('@vuepress-plume/vuepress-plugin-iconify') +module.exports = { + //... + plugins: [ + iconifyPlugin() + ] + // ... +} +``` diff --git a/packages/plugin-iconify/package.json b/packages/plugin-iconify/package.json new file mode 100644 index 00000000..fd0efd49 --- /dev/null +++ b/packages/plugin-iconify/package.json @@ -0,0 +1,49 @@ +{ + "name": "@vuepress-plume/vuepress-plugin-iconify", + "version": "1.0.0-beta.57", + "description": "The Plugin for VuePres 2", + "homepage": "https://github.com/pengzhanbo/vuepress-theme-plume#readme", + "bugs": { + "url": "https://github.com/pengzhanbo/vuepress-theme-plume/issues" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/pengzhanbo/vuepress-theme-plume.git" + }, + "license": "MIT", + "author": "pengzhanbo ", + "type": "module", + "exports": { + ".": "./lib/node/index.js", + "./client": "./lib/client/index.js", + "./package.json": "./package.json" + }, + "main": "lib/node/index.js", + "types": "./lib/node/index.d.ts", + "scripts": { + "build": "pnpm run clean && pnpm run copy && pnpm run ts", + "clean": "rimraf lib *.tsbuildinfo", + "copy": "cpx \"src/**/*.{d.ts,vue,css,scss,jpg,png}\" lib", + "copy:watch": "cpx \"src/**/*.{d.ts,vue,css,scss,jpg,png}\" lib -w", + "dev": "concurrently \"pnpm copy:watch\" \"pnpm ts:watch\"", + "ts": "tsc -b tsconfig.build.json", + "ts:watch": "tsc -b tsconfig.build.json --watch" + }, + "dependencies": { + "@iconify/vue": "^4.1.0", + "@vuepress/client": "2.0.0-beta.60", + "@vuepress/core": "2.0.0-beta.60", + "@vuepress/shared": "2.0.0-beta.60", + "@vuepress/utils": "2.0.0-beta.60", + "vue": "^3.2.47" + }, + "publishConfig": { + "access": "public" + }, + "keyword": [ + "VuePress", + "vuepress plugin", + "iconify", + "vuepress-plugin-plugin-iconify" + ] +} diff --git a/packages/plugin-iconify/src/client/clientConfig.ts b/packages/plugin-iconify/src/client/clientConfig.ts new file mode 100644 index 00000000..03483da1 --- /dev/null +++ b/packages/plugin-iconify/src/client/clientConfig.ts @@ -0,0 +1,10 @@ +import { defineClientConfig } from '@vuepress/client' +import Iconify from './components/Iconify.vue' + +declare const __VUEPRESS_PLUGIN_ICONIFY_COMPONENT_NAME__: string +export default defineClientConfig({ + enhance({ app }) { + const name = __VUEPRESS_PLUGIN_ICONIFY_COMPONENT_NAME__ || 'Iconify' + app.component(name, Iconify) + }, +}) diff --git a/packages/plugin-iconify/src/client/components/Iconify.vue b/packages/plugin-iconify/src/client/components/Iconify.vue new file mode 100644 index 00000000..6a9676f2 --- /dev/null +++ b/packages/plugin-iconify/src/client/components/Iconify.vue @@ -0,0 +1,66 @@ + + + + + + diff --git a/packages/plugin-iconify/src/client/composables/iconify.ts b/packages/plugin-iconify/src/client/composables/iconify.ts new file mode 100644 index 00000000..91c9742d --- /dev/null +++ b/packages/plugin-iconify/src/client/composables/iconify.ts @@ -0,0 +1,27 @@ +import type { IconifyIcon } from '@iconify/vue' +import { loadIcon } from '@iconify/vue' +import { computed, ref, watch } from 'vue' +import type { ComputedRef, Ref } from 'vue' + +const iconCache: Ref> = ref({}) + +export const useIconify = (name: ComputedRef | Ref) => { + const icon = computed(() => iconCache.value[name.value]) + const loaded = ref(false) + + async function loadIconComponent() { + if (icon.value) { + return + } + try { + loaded.value = false + iconCache.value[name.value] = await loadIcon(name.value) + } finally { + loaded.value = true + } + } + + watch(() => name.value, loadIconComponent, { immediate: true }) + + return { icon, loaded } +} diff --git a/packages/plugin-iconify/src/client/index.ts b/packages/plugin-iconify/src/client/index.ts new file mode 100644 index 00000000..d801584f --- /dev/null +++ b/packages/plugin-iconify/src/client/index.ts @@ -0,0 +1,2 @@ +export * from './composables/iconify.js' +export * from '../shared/index.js' diff --git a/packages/plugin-iconify/src/node/index.ts b/packages/plugin-iconify/src/node/index.ts new file mode 100644 index 00000000..c71fd217 --- /dev/null +++ b/packages/plugin-iconify/src/node/index.ts @@ -0,0 +1,6 @@ +import { iconifyPlugin } from './plugin.js' + +export * from './plugin.js' +export * from '../shared/index.js' + +export default iconifyPlugin diff --git a/packages/plugin-iconify/src/node/plugin.ts b/packages/plugin-iconify/src/node/plugin.ts new file mode 100644 index 00000000..ae1f828e --- /dev/null +++ b/packages/plugin-iconify/src/node/plugin.ts @@ -0,0 +1,25 @@ +import type { App, Plugin } from '@vuepress/core' +import { getDirname, path } from '@vuepress/utils' +import type { IconifyOptions } from '../shared/index.js' + +export const iconifyPlugin = ({ + componentName = 'Iconify', + size = '1em', + color = 'currentColor', +}: IconifyOptions): Plugin => { + return (app: App) => { + return { + name: '@vuepress-plume/vuepress-plugin-iconify', + define: { + __VUEPRESS_PLUGIN_ICONIFY_COMPONENT_NAME__: + JSON.stringify(componentName), + __VUEPRESS_PLUGIN_ICONIFY_DEFAULT_SIZE__: JSON.stringify(size), + __VUEPRESS_PLUGIN_ICONIFY_DEFAULT_COLOR__: JSON.stringify(color), + }, + clientConfigFile: path.resolve( + getDirname(import.meta.url), + '../client/clientConfig.js' + ), + } + } +} diff --git a/packages/plugin-iconify/src/shared/index.ts b/packages/plugin-iconify/src/shared/index.ts new file mode 100644 index 00000000..d26698d3 --- /dev/null +++ b/packages/plugin-iconify/src/shared/index.ts @@ -0,0 +1,5 @@ +export interface IconifyOptions { + componentName?: string + color?: string + size?: string | number +} diff --git a/packages/plugin-iconify/src/shim.d.ts b/packages/plugin-iconify/src/shim.d.ts new file mode 100644 index 00000000..b681832a --- /dev/null +++ b/packages/plugin-iconify/src/shim.d.ts @@ -0,0 +1,4 @@ +declare module '*.vue' { + const comp: any + export default comp +} diff --git a/packages/plugin-iconify/tsconfig.build.json b/packages/plugin-iconify/tsconfig.build.json new file mode 100644 index 00000000..6bf67375 --- /dev/null +++ b/packages/plugin-iconify/tsconfig.build.json @@ -0,0 +1,8 @@ +{ + "extends": "../tsconfig.build.json", + "compilerOptions": { + "rootDir": "./src", + "outDir": "./lib" + }, + "include": ["./src"] +} diff --git a/packages/tsconfig.build.json b/packages/tsconfig.build.json index ff8b478c..93158846 100644 --- a/packages/tsconfig.build.json +++ b/packages/tsconfig.build.json @@ -10,6 +10,7 @@ { "path": "./plugin-blog-data/tsconfig.build.json" }, { "path": "./plugin-caniuse/tsconfig.build.json" }, { "path": "./plugin-copy-code/tsconfig.build.json" }, + { "path": "./plugin-iconify/tsconfig.build.json" }, { "path": "./plugin-netlify-functions/tsconfig.build.json" }, { "path": "./plugin-notes-data/tsconfig.build.json" }, { "path": "./plugin-page-collection/tsconfig.build.json" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c9d99621..7e514d92 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -178,6 +178,22 @@ importers: vue: 3.2.47 vue-router: 4.1.6_vue@3.2.47 + packages/plugin-iconify: + specifiers: + '@iconify/vue': ^4.1.0 + '@vuepress/client': 2.0.0-beta.60 + '@vuepress/core': 2.0.0-beta.60 + '@vuepress/shared': 2.0.0-beta.60 + '@vuepress/utils': 2.0.0-beta.60 + vue: ^3.2.47 + dependencies: + '@iconify/vue': 4.1.0_vue@3.2.47 + '@vuepress/client': 2.0.0-beta.60 + '@vuepress/core': 2.0.0-beta.60 + '@vuepress/shared': 2.0.0-beta.60 + '@vuepress/utils': 2.0.0-beta.60 + vue: 3.2.47 + packages/plugin-netlify-functions: specifiers: '@iarna/toml': ^2.2.5 @@ -1279,6 +1295,19 @@ packages: resolution: {integrity: sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==} dev: false + /@iconify/types/2.0.0: + resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} + dev: false + + /@iconify/vue/4.1.0_vue@3.2.47: + resolution: {integrity: sha512-rBQVxNoSDooqgWkQg2MqkIHkH/huNuvXGqui5wijc1zLnU7TKzbBHW9VGmbnV4asNTmIHmqV4Nvt0M2rZ/9nHA==} + peerDependencies: + vue: '>=3' + dependencies: + '@iconify/types': 2.0.0 + vue: 3.2.47 + dev: false + /@import-maps/resolve/1.0.1: resolution: {integrity: sha512-tWZNBIS1CoekcwlMuyG2mr0a1Wo5lb5lEHwwWvZo+5GLgr3e9LLDTtmgtCWEwBpXMkxn9D+2W9j2FY6eZQq0tA==} dev: false