feat(icon): the wrapper for @nuxt/icon

This commit is contained in:
Timothy Yin 2024-11-26 19:39:40 +08:00
parent 5e0e6bd1a6
commit 28975d633c
15 changed files with 92 additions and 128 deletions

View File

@ -179,6 +179,7 @@ const { data: codeRender } = await useAsyncData(`${componentName}-code-renderer-
:type="prop.type === 'number' ? 'number' : 'text'"
variant="plain"
:padded="false"
:ui="{ rounded: 'rounded-none' }"
placeholder="type something..."
@update:model-value="val => componentProps[prop.name] = prop.type === 'number' ? Number(val) : val"
/>

View File

@ -1,12 +1,4 @@
<script setup lang="ts">
import FileTypeVue from '../../icon/VscodeIconsFileTypeVue.vue'
import FileTypeTypescript from '../../icon/VscodeIconsFileTypeTypescriptOfficial.vue'
import FileTypeJavascript from '../../icon/VscodeIconsFileTypeJsOfficial.vue'
import TablerTerminal from '../../icon/TablerTerminal.vue'
import TablerFile from '~/components/icon/TablerFile.vue'
import VscodeIconsFileTypeJson from '~/components/icon/VscodeIconsFileTypeJson.vue'
import VscodeIconsFileTypeNuxt from '~/components/icon/VscodeIconsFileTypeNuxt.vue'
const props = defineProps({
code: {
type: String,
@ -38,29 +30,39 @@ const props = defineProps({
},
})
const mapIconLanguage = {
'default': TablerFile,
'vue': FileTypeVue,
'vue-html': FileTypeVue,
'bash': TablerTerminal,
'sh': TablerTerminal,
'ts': FileTypeTypescript,
'js': FileTypeJavascript,
'json': VscodeIconsFileTypeJson,
const iconNameLangMapping: Record<string, string> = {
'default': 'tabler:file',
'vue': 'vscode-icons:file-type-vue',
'vue-html': 'vscode-icons:file-type-vue',
'bash': 'tabler:terminal',
'sh': 'tabler:terminal',
'ts': 'vscode-icons:file-type-typescript-official',
'js': 'vscode-icons:file-type-js-official',
'json': 'vscode-icons:file-type-json',
}
const mapIconFilename = {
'nuxt.config.ts': VscodeIconsFileTypeNuxt,
const iconNameFilenameMapping: Record<string, string> = {
'nuxt.config.ts': 'vscode-icons:file-type-nuxt',
}
const resolveIcon = computed(() => {
if (props.filename) {
if (props.filename.endsWith('.vue')) return FileTypeVue
const icon = mapIconFilename[props.filename as keyof typeof mapIconFilename]
if (icon) return icon
const resolvedIconName = computed(() => {
if (!props.language) {
return iconNameLangMapping['default']
}
return mapIconLanguage[props.language as keyof typeof mapIconLanguage]
if (props.filename.endsWith('.vue')) {
return iconNameLangMapping['vue']
}
if (iconNameFilenameMapping[props.filename]) {
return iconNameFilenameMapping[props.filename]
}
if (iconNameLangMapping[props.language]) {
return iconNameLangMapping[props.language]
}
return iconNameLangMapping['default']
})
</script>
@ -68,7 +70,7 @@ const resolveIcon = computed(() => {
<div data-prose-pre class="pre rounded-lg overflow-hidden border border-gray-200 dark:border-gray-700">
<div v-if="filename" class="p-4 py-2 border-b border-neutral-200 dark:border-neutral-700">
<span class="flex items-center gap-1">
<component :is="resolveIcon" v-if="language" class="inline" />
<RayIcon v-if="resolvedIconName" :name="resolvedIconName" class="inline" />
<span class="text-sm text-neutral-500 dark:text-neutral-400">{{ filename }}</span>
</span>
</div>

View File

@ -1,9 +0,0 @@
<template>
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="M11.933 5H5v16h13v-8m-4 4H9" /><path d="M9 13h5V9H9zm6-8V3m3 3l2-2m-1 5h2" /></g></svg>
</template>
<script>
export default {
name: 'TablerAd2',
}
</script>

View File

@ -1,9 +0,0 @@
<template>
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="M14 3v4a1 1 0 0 0 1 1h4" /><path d="M17 21H7a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h7l5 5v11a2 2 0 0 1-2 2" /></g></svg>
</template>
<script>
export default {
name: 'TablerFile',
}
</script>

View File

@ -1,9 +0,0 @@
<template>
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="M5 18a2 2 0 1 0 4 0a2 2 0 1 0-4 0M5 6a2 2 0 1 0 4 0a2 2 0 1 0-4 0m10 6a2 2 0 1 0 4 0a2 2 0 1 0-4 0M7 8v8" /><path d="M7 8a4 4 0 0 0 4 4h4" /></g></svg>
</template>
<script>
export default {
name: 'TablerGitMerge',
}
</script>

View File

@ -1,16 +0,0 @@
<template>
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><path
fill="none"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="m5 7l5 5l-5 5m7 2h7"
/></svg>
</template>
<script>
export default {
name: 'TablerTerminal',
}
</script>

View File

@ -1,9 +0,0 @@
<template>
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 32 32"><path fill="#f5de19" d="M2 2h28v28H2z" /><path d="M20.809 23.875a2.87 2.87 0 0 0 2.6 1.6c1.09 0 1.787-.545 1.787-1.3c0-.9-.716-1.222-1.916-1.747l-.658-.282c-1.9-.809-3.16-1.822-3.16-3.964c0-1.973 1.5-3.476 3.853-3.476a3.89 3.89 0 0 1 3.742 2.107L25 18.128A1.79 1.79 0 0 0 23.311 17a1.145 1.145 0 0 0-1.259 1.128c0 .789.489 1.109 1.618 1.6l.658.282c2.236.959 3.5 1.936 3.5 4.133c0 2.369-1.861 3.667-4.36 3.667a5.06 5.06 0 0 1-4.795-2.691Zm-9.295.228c.413.733.789 1.353 1.693 1.353c.864 0 1.41-.338 1.41-1.653v-8.947h2.631v8.982c0 2.724-1.6 3.964-3.929 3.964a4.085 4.085 0 0 1-3.947-2.4Z" /></svg>
</template>
<script>
export default {
name: 'VscodeIconsFileTypeJsOfficial',
}
</script>

View File

@ -1,9 +0,0 @@
<template>
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 32 32"><path fill="#f5de19" d="M4.014 14.976a2.5 2.5 0 0 0 1.567-.518a2.38 2.38 0 0 0 .805-1.358a15.3 15.3 0 0 0 .214-2.944q.012-2.085.075-2.747a5.2 5.2 0 0 1 .418-1.686a3 3 0 0 1 .755-1.018A3.05 3.05 0 0 1 9 4.125A6.8 6.8 0 0 1 10.544 4h.7v1.96h-.387a2.34 2.34 0 0 0-1.723.468a3.4 3.4 0 0 0-.425 2.092a36 36 0 0 1-.137 4.133a4.7 4.7 0 0 1-.768 2.06A4.6 4.6 0 0 1 6.1 16a3.8 3.8 0 0 1 1.992 1.754a8.9 8.9 0 0 1 .618 3.865q0 2.435.05 2.9a1.76 1.76 0 0 0 .504 1.181a2.64 2.64 0 0 0 1.592.337h.387V28h-.7a5.7 5.7 0 0 1-1.773-.2a2.97 2.97 0 0 1-1.324-.93a3.35 3.35 0 0 1-.681-1.63a24 24 0 0 1-.165-3.234a16.5 16.5 0 0 0-.214-3.106a2.4 2.4 0 0 0-.805-1.361a2.5 2.5 0 0 0-1.567-.524Zm23.972 2.035a2.5 2.5 0 0 0-1.567.524a2.4 2.4 0 0 0-.805 1.361a16.5 16.5 0 0 0-.212 3.109a24 24 0 0 1-.169 3.234a3.35 3.35 0 0 1-.681 1.63a2.97 2.97 0 0 1-1.324.93a5.7 5.7 0 0 1-1.773.2h-.7V26.04h.387a2.64 2.64 0 0 0 1.592-.337a1.76 1.76 0 0 0 .506-1.186q.05-.462.05-2.9a8.9 8.9 0 0 1 .618-3.865A3.8 3.8 0 0 1 25.9 16a4.6 4.6 0 0 1-1.7-1.286a4.7 4.7 0 0 1-.768-2.06a36 36 0 0 1-.137-4.133a3.4 3.4 0 0 0-.425-2.092a2.34 2.34 0 0 0-1.723-.468h-.387V4h.7a6.8 6.8 0 0 1 1.54.125a3.05 3.05 0 0 1 1.149.581a3 3 0 0 1 .755 1.018a5.2 5.2 0 0 1 .418 1.686q.062.662.075 2.747a15.3 15.3 0 0 0 .212 2.947a2.38 2.38 0 0 0 .805 1.355a2.5 2.5 0 0 0 1.567.518Z" /></svg>
</template>
<script>
export default {
name: 'VscodeIconsFileTypeJson',
}
</script>

View File

@ -1,9 +0,0 @@
<template>
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 32 32"><path fill="#00DC82" d="M17.708 25h10.409c.33 0 .655-.088.942-.254a1.9 1.9 0 0 0 .689-.696a1.91 1.91 0 0 0 0-1.9L22.756 9.936a1.87 1.87 0 0 0-3.261 0l-1.788 3.125l-3.494-6.111a1.871 1.871 0 0 0-3.262 0l-8.7 15.2a1.91 1.91 0 0 0 .69 2.595c.286.167.61.255.941.255h6.534c2.589 0 4.498-1.147 5.811-3.385l3.19-5.572l1.708-2.982l5.127 8.957h-6.835zm-7.398-2.985l-4.56-.001l6.836-11.942l3.41 5.97l-2.283 3.992c-.873 1.452-1.864 1.981-3.403 1.981" /></svg>
</template>
<script>
export default {
name: 'VscodeIconsFileTypeNuxt',
}
</script>

View File

@ -1,16 +0,0 @@
<template>
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 32 32"><rect
width="28"
height="28"
x="2"
y="2"
fill="#3178c6"
rx="1.312"
/><path fill="#fff" fillRule="evenodd" d="M18.245 23.759v3.068a6.5 6.5 0 0 0 1.764.575a11.6 11.6 0 0 0 2.146.192a10 10 0 0 0 2.088-.211a5.1 5.1 0 0 0 1.735-.7a3.54 3.54 0 0 0 1.181-1.266a4.47 4.47 0 0 0 .186-3.394a3.4 3.4 0 0 0-.717-1.117a5.2 5.2 0 0 0-1.123-.877a12 12 0 0 0-1.477-.734q-.6-.249-1.08-.484a5.5 5.5 0 0 1-.813-.479a2.1 2.1 0 0 1-.516-.518a1.1 1.1 0 0 1-.181-.618a1.04 1.04 0 0 1 .162-.571a1.4 1.4 0 0 1 .459-.436a2.4 2.4 0 0 1 .726-.283a4.2 4.2 0 0 1 .956-.1a6 6 0 0 1 .808.058a6 6 0 0 1 .856.177a6 6 0 0 1 .836.3a4.7 4.7 0 0 1 .751.422V13.9a7.5 7.5 0 0 0-1.525-.4a12.4 12.4 0 0 0-1.9-.129a8.8 8.8 0 0 0-2.064.235a5.2 5.2 0 0 0-1.716.733a3.66 3.66 0 0 0-1.171 1.271a3.73 3.73 0 0 0-.431 1.845a3.6 3.6 0 0 0 .789 2.34a6 6 0 0 0 2.395 1.639q.63.26 1.175.509a6.5 6.5 0 0 1 .942.517a2.5 2.5 0 0 1 .626.585a1.2 1.2 0 0 1 .23.719a1.1 1.1 0 0 1-.144.552a1.3 1.3 0 0 1-.435.441a2.4 2.4 0 0 1-.726.292a4.4 4.4 0 0 1-1.018.105a5.8 5.8 0 0 1-1.969-.35a5.9 5.9 0 0 1-1.805-1.045m-5.154-7.638h4v-2.527H5.938v2.527H9.92v11.254h3.171Z" /></svg>
</template>
<script>
export default {
name: 'VscodeIconsFileTypeTypescriptOfficial',
}
</script>

View File

@ -1,9 +0,0 @@
<template>
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 32 32"><path fill="#41b883" d="M24.4 3.925H30l-14 24.15L2 3.925h10.71l3.29 5.6l3.22-5.6Z" /><path fill="#41b883" d="m2 3.925l14 24.15l14-24.15h-5.6L16 18.415L7.53 3.925Z" /><path fill="#35495e" d="M7.53 3.925L16 18.485l8.4-14.56h-5.18L16 9.525l-3.29-5.6Z" /></svg>
</template>
<script>
export default {
name: 'VscodeIconsFileTypeVue',
}
</script>

View File

@ -0,0 +1,24 @@
---
description: Add icons to your app. Based on Iconify
---
## Usage
This component is a wrapper based on the `@nuxt/icon` library, which is based on Iconify. So you can use any icon name available on [icones.js.org](https://icones.js.org/).
::ComponentPreview
---
privateProps:
class: w-6 h-6
props:
name: tabler:brand-github
---
::
## Collections
It's recommended to install the icon collection you want to use locally. You can do this by running:
```bash [Terminal]
pnpm i @iconify-icons/[collection_name]
```

View File

@ -50,6 +50,7 @@ export default defineNuxtConfig({
componentMeta: {
exclude: [
'@nuxt/content',
'@nuxt/icon',
'@nuxtjs/color-mode',
'@nuxtjs/mdc',
'nuxt/dist',
@ -63,6 +64,11 @@ export default defineNuxtConfig({
exposed: false,
},
},
icon: {
clientBundle: {
scan: true,
},
},
rayui: {
globalComponents: true,
safeColors: [...excludeColors(colors)],
@ -78,9 +84,4 @@ export default defineNuxtConfig({
},
},
},
icon: {
clientBundle: {
scan: true
}
},
})

View File

@ -65,7 +65,7 @@ const { data: surround } = await useAsyncData(`${route.path}-surround`, () => {
class="ring-1 ring-inset ring-primary-200 dark:ring-primary-900 text-primary-500 dark:text-primary-400 rounded-md bg-primary-50 dark:bg-primary-900 font-medium flex items-center gap-1"
:class="[standard.padding['sm'], standard.size['2xs']]"
>
<IconTablerGitMerge class="text-sm -mt-0.5" />
<RayIcon name="tabler:git-merge" class="text-sm -mt-0.5" />
v{{ page.since }}
</div>
</div>

View File

@ -0,0 +1,31 @@
<script lang="ts">
import { defineComponent, type PropType } from 'vue'
export default defineComponent({
props: {
name: {
type: String,
required: true,
},
mode: {
type: String as PropType<'svg' | 'css'>,
required: false,
default: null,
},
size: {
type: [String, Number],
required: false,
default: null,
},
customize: {
type: Function,
required: false,
default: null,
},
},
})
</script>
<template>
<Icon v-bind="$props" />
</template>