tree shake icons

This commit is contained in:
Gauthier Roebroeck 2025-06-05 16:46:50 +08:00
parent 4e61bb403c
commit 3216a83023
21 changed files with 223 additions and 44 deletions

1
next-ui/env.d.ts vendored
View file

@ -1,3 +1,4 @@
/// <reference types="vite/client" />
/// <reference types="unplugin-vue-router/client" />
/// <reference types="vite-plugin-vue-layouts-next/client" />
/// <reference types="unplugin-icons/types/vue3" />

View file

@ -23,7 +23,7 @@
"devDependencies": {
"@eslint/js": "^9.28.0",
"@formatjs/cli": "^6.7.1",
"@mdi/font": "7.4.47",
"@iconify-json/mdi": "^1.2.3",
"@tsconfig/node22": "^22.0.2",
"@types/node": "^22.15.29",
"@vitejs/plugin-vue": "^5.1.4",
@ -42,6 +42,7 @@
"typescript": "^5.8.3",
"unplugin-auto-import": "^19.3.0",
"unplugin-fonts": "^1.1.1",
"unplugin-icons": "^22.1.0",
"unplugin-vue-components": "^28.7.0",
"unplugin-vue-router": "^0.12.0",
"vite": "^6.3.5",
@ -52,6 +53,37 @@
"vue-tsc": "^2.1.10"
}
},
"node_modules/@antfu/install-pkg": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-1.1.0.tgz",
"integrity": "sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"package-manager-detector": "^1.3.0",
"tinyexec": "^1.0.1"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/@antfu/install-pkg/node_modules/tinyexec": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.1.tgz",
"integrity": "sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==",
"dev": true,
"license": "MIT"
},
"node_modules/@antfu/utils": {
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/@antfu/utils/-/utils-8.1.1.tgz",
"integrity": "sha512-Mex9nXf9vR6AhcXmMrlz/HVgYYZpVGJ6YlPgwl7UnaFpnshXs6EK/oa5Gpf3CzENMjkvEx2tQtntGnb7UtSTOQ==",
"dev": true,
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/@babel/code-frame": {
"version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
@ -907,19 +939,59 @@
"url": "https://github.com/sponsors/nzakas"
}
},
"node_modules/@iconify-json/mdi": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/@iconify-json/mdi/-/mdi-1.2.3.tgz",
"integrity": "sha512-O3cLwbDOK7NNDf2ihaQOH5F9JglnulNDFV7WprU2dSoZu3h3cWH//h74uQAB87brHmvFVxIOkuBX2sZSzYhScg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@iconify/types": "*"
}
},
"node_modules/@iconify/types": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz",
"integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==",
"dev": true,
"license": "MIT"
},
"node_modules/@iconify/utils": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/@iconify/utils/-/utils-2.3.0.tgz",
"integrity": "sha512-GmQ78prtwYW6EtzXRU1rY+KwOKfz32PD7iJh6Iyqw68GiKuoZ2A6pRtzWONz5VQJbp50mEjXh/7NkumtrAgRKA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@antfu/install-pkg": "^1.0.0",
"@antfu/utils": "^8.1.0",
"@iconify/types": "^2.0.0",
"debug": "^4.4.0",
"globals": "^15.14.0",
"kolorist": "^1.8.0",
"local-pkg": "^1.0.0",
"mlly": "^1.7.4"
}
},
"node_modules/@iconify/utils/node_modules/globals": {
"version": "15.15.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz",
"integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
"license": "MIT"
},
"node_modules/@mdi/font": {
"version": "7.4.47",
"resolved": "https://registry.npmjs.org/@mdi/font/-/font-7.4.47.tgz",
"integrity": "sha512-43MtGpd585SNzHZPcYowu/84Vz2a2g31TvPMTm9uTiCSWzaheQySUcSyUH/46fPnuPQWof2yd0pGBtzee/IQWw==",
"dev": true,
"license": "Apache-2.0"
},
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@ -3960,6 +4032,13 @@
"integrity": "sha512-xYSH7AvuQ6nXkq42x0v5S8/Iry+cfulBz/DJQzhIyESdLD7425jXsPy4vn5cCXU+HhRN2kVw51Vd1K6/By4BQg==",
"license": "MIT"
},
"node_modules/kolorist": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz",
"integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==",
"dev": true,
"license": "MIT"
},
"node_modules/levn": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
@ -4450,6 +4529,13 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/package-manager-detector": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.3.0.tgz",
"integrity": "sha512-ZsEbbZORsyHuO00lY1kV3/t72yp6Ysay6Pd17ZAlNGuGwmWDLCJxFpRs0IzfXfj1o4icJOkUEioexFHzyPurSQ==",
"dev": true,
"license": "MIT"
},
"node_modules/parent-module": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
@ -5727,6 +5813,51 @@
"node": ">=18.12.0"
}
},
"node_modules/unplugin-icons": {
"version": "22.1.0",
"resolved": "https://registry.npmjs.org/unplugin-icons/-/unplugin-icons-22.1.0.tgz",
"integrity": "sha512-ect2ZNtk1Zgwb0NVHd0C1IDW/MV+Jk/xaq4t8o6rYdVS3+L660ZdD5kTSQZvsgdwCvquRw+/wYn75hsweRjoIA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@antfu/install-pkg": "^1.0.0",
"@iconify/utils": "^2.3.0",
"debug": "^4.4.0",
"local-pkg": "^1.0.0",
"unplugin": "^2.2.0"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
},
"peerDependencies": {
"@svgr/core": ">=7.0.0",
"@svgx/core": "^1.0.1",
"@vue/compiler-sfc": "^3.0.2 || ^2.7.0",
"svelte": "^3.0.0 || ^4.0.0 || ^5.0.0",
"vue-template-compiler": "^2.6.12",
"vue-template-es2015-compiler": "^1.9.0"
},
"peerDependenciesMeta": {
"@svgr/core": {
"optional": true
},
"@svgx/core": {
"optional": true
},
"@vue/compiler-sfc": {
"optional": true
},
"svelte": {
"optional": true
},
"vue-template-compiler": {
"optional": true
},
"vue-template-es2015-compiler": {
"optional": true
}
}
},
"node_modules/unplugin-utils": {
"version": "0.2.4",
"resolved": "https://registry.npmjs.org/unplugin-utils/-/unplugin-utils-0.2.4.tgz",
@ -6176,9 +6307,9 @@
}
},
"node_modules/vuetify": {
"version": "3.8.8",
"resolved": "https://registry.npmjs.org/vuetify/-/vuetify-3.8.8.tgz",
"integrity": "sha512-EPFynvxh72PBgUVZnGpfYfGluz8dz/tXM1OzjszFOK7ywqS+bAm8K9jJq0MIlAG8HKE7gBFQwCJGkzIyuUDipA==",
"version": "3.8.5",
"resolved": "https://registry.npmjs.org/vuetify/-/vuetify-3.8.5.tgz",
"integrity": "sha512-W/mTaNDyO6NRqAQmnkMUn9TYvRb//BPF/vk7h3+2xNJOyI9ev90JmYjrihOtb+6QDrB79wVUH0Y+0OjYK73GsA==",
"license": "MIT",
"engines": {
"node": "^12.20 || >=14.13"

View file

@ -34,7 +34,7 @@
"devDependencies": {
"@eslint/js": "^9.28.0",
"@formatjs/cli": "^6.7.1",
"@mdi/font": "7.4.47",
"@iconify-json/mdi": "^1.2.3",
"@tsconfig/node22": "^22.0.2",
"@types/node": "^22.15.29",
"@vitejs/plugin-vue": "^5.1.4",
@ -53,6 +53,7 @@
"typescript": "^5.8.3",
"unplugin-auto-import": "^19.3.0",
"unplugin-fonts": "^1.1.1",
"unplugin-icons": "^22.1.0",
"unplugin-vue-components": "^28.7.0",
"unplugin-vue-router": "^0.12.0",
"vite": "^6.3.5",

View file

@ -1,7 +1,7 @@
<template>
<template v-if="commitId">
<v-btn
prepend-icon="mdi-source-commit"
:prepend-icon="mdiSourceCommit"
variant="text"
color="grey"
size="small"
@ -15,6 +15,7 @@
</template>
<script setup lang="ts">
import mdiSourceCommit from '~icons/mdi/source-commit'
import { useActuatorInfo } from '@/colada/queries/actuator-info'
const { commitId } = useActuatorInfo()

View file

@ -6,7 +6,7 @@
:model-value="isLatestVersion == false"
>
<v-btn
prepend-icon="mdi-tag-outline"
:prepend-icon="mdiTagOutline"
variant="text"
color="grey"
size="small"
@ -20,6 +20,7 @@
</template>
<script setup lang="ts">
import mdiTagOutline from '~icons/mdi/tag-outline'
import { useAppReleases } from '@/colada/queries/app-releases'
const { buildVersion, isLatestVersion } = useAppReleases()

View file

@ -3,7 +3,7 @@
<template #activator="{ props }">
<v-btn
v-bind="props"
icon="mdi-translate"
:icon="mdiTranslate"
/>
</template>
@ -49,6 +49,7 @@
</template>
<script setup lang="ts">
import mdiTranslate from '~icons/mdi/translate'
import { availableLocales, currentLocale, setLocale } from '@/utils/i18n/locale-helper'
const locales = Object.entries(availableLocales).map(([k, v]) => ({

View file

@ -6,6 +6,9 @@
</template>
<script setup lang="ts">
import mdiWeatherSunny from '~icons/mdi/weather-sunny'
import mdiWeatherNight from '~icons/mdi/weather-night'
import mdiThemeLightDark from '~icons/mdi/theme-light-dark'
import { useAppStore } from '@/stores/app'
const appStore = useAppStore()
@ -13,20 +16,20 @@ const appStore = useAppStore()
const themes = [
{
value: 'light',
icon: 'mdi-weather-sunny',
icon: mdiWeatherSunny,
},
{
value: 'dark',
icon: 'mdi-weather-night',
icon: mdiWeatherNight,
},
{
value: 'system',
icon: 'mdi-theme-light-dark',
icon: mdiThemeLightDark,
},
]
const themeIcon = computed(
() => themes.find((x) => x.value === appStore.theme)?.icon || 'mdi-theme-light-dark',
() => themes.find((x) => x.value === appStore.theme)?.icon || mdiThemeLightDark,
)
function cycleTheme() {

View file

@ -3,7 +3,7 @@
<div class="d-flex align-center text-caption text-medium-emphasis pa-2">
<div class="d-flex ms-auto">
<v-btn
prepend-icon="mdi-help-circle-outline"
:prepend-icon="mdiHelpCircleOutline"
variant="text"
color="grey"
size="small"
@ -34,6 +34,7 @@
</template>
<script setup lang="ts">
import mdiHelpCircleOutline from '~icons/mdi/help-circle-outline'
import { useCurrentUser } from '@/colada/queries/current-user'
const { isAdmin } = useCurrentUser()

View file

@ -10,7 +10,7 @@
id: 'od545m',
})
"
prepend-icon="mdi-account"
:prepend-icon="mdiAccount"
/>
</template>
@ -57,7 +57,9 @@
</v-list-group>
</template>
<script setup lang="ts"></script>
<script setup lang="ts">
import mdiAccount from '~icons/mdi/account'
</script>
<script lang="ts"></script>

View file

@ -8,6 +8,10 @@
id: 'l/To3S',
})
"
prepend-icon="mdi-clock-time-four-outline"
:prepend-icon="mdiClockTimeFourOutline"
/>
</template>
<script setup lang="ts">
import mdiClockTimeFourOutline from '~icons/mdi/clock-time-four-outline'
</script>

View file

@ -10,7 +10,7 @@
id: 'N7+QXi',
})
"
prepend-icon="mdi-import"
:prepend-icon="mdiImport"
/>
</template>
@ -37,3 +37,7 @@
/>
</v-list-group>
</template>
<script setup lang="ts">
import mdiImport from '~icons/mdi/import'
</script>

View file

@ -7,12 +7,13 @@
id: 'ti4Pzo',
})
"
prepend-icon="mdi-power"
:prepend-icon="mdiPower"
@click="performLogout"
/>
</template>
<script setup lang="ts">
import mdiPower from '~icons/mdi/power'
import { useLogout } from '@/colada/mutations/logout'
const router = useRouter()

View file

@ -10,7 +10,7 @@
id: 'Hl9H/B',
})
"
prepend-icon="mdi-book-cog"
:prepend-icon="mdiBookCog"
/>
</template>
@ -82,4 +82,6 @@
</v-list-group>
</v-list-group>
</template>
<script setup lang="ts"></script>
<script setup lang="ts">
import mdiBookCog from '~icons/mdi/book-cog'
</script>

View file

@ -13,7 +13,6 @@
id: 'IpvWiZ',
})
"
prepend-icon="mdi-cog"
>
<template #prepend>
<v-badge
@ -22,7 +21,7 @@
floating
color="info"
>
<v-icon>mdi-cog</v-icon>
<v-icon :icon="mdiCog"></v-icon>
</v-badge>
</template>
</v-list-item>
@ -103,6 +102,7 @@
</template>
<script setup lang="ts">
import mdiCog from '~icons/mdi/cog'
import { useAnnouncements } from '@/colada/queries/announcements'
const { unreadCount } = useAnnouncements()

View file

@ -12,7 +12,7 @@
autocomplete="off"
autofocus
:type="showPassword ? 'text' : 'password'"
:append-inner-icon="showPassword ? 'mdi-eye' : 'mdi-eye-off'"
:append-inner-icon="showPassword ? mdiEye : mdiEyeOff"
@click:append-inner="showPassword = !showPassword"
/>
<v-text-field
@ -37,12 +37,14 @@
"
autocomplete="off"
:type="showPassword ? 'text' : 'password'"
:append-inner-icon="showPassword ? 'mdi-eye' : 'mdi-eye-off'"
:append-inner-icon="showPassword ? mdiEye : mdiEyeOff"
@click:append-inner="showPassword = !showPassword"
/>
</template>
<script setup lang="ts">
import mdiEye from '~icons/mdi/eye'
import mdiEyeOff from '~icons/mdi/eye-off'
import { useRules } from 'vuetify/labs/rules'
const rules = useRules()

View file

@ -11,7 +11,7 @@
id: 'ToD0+o',
})
"
prepend-icon="mdi-account"
:prepend-icon="mdiAccount"
/>
<v-text-field
v-model="user.password"
@ -26,7 +26,7 @@
"
autocomplete="off"
:type="showPassword ? 'text' : 'password'"
:append-inner-icon="showPassword ? 'mdi-eye' : 'mdi-eye-off'"
:append-inner-icon="showPassword ? mdiEye : mdiEyeOff"
prepend-icon="mdi-none"
@click:append-inner="showPassword = !showPassword"
/>
@ -45,7 +45,7 @@
id: 'CUxhzL',
})
"
prepend-icon="mdi-key-chain"
:prepend-icon="mdiKeyChain"
:items="userRoles"
/>
@ -63,7 +63,7 @@
:items="libraries"
item-title="name"
item-value="id"
prepend-icon="mdi-book-multiple"
:prepend-icon="mdiBookMultiple"
>
<!-- Workaround for the lack of a slot to override the whole selection -->
<template #prepend-inner>
@ -134,7 +134,7 @@
})
"
:items="ageRestrictions"
prepend-icon="mdi-folder-lock"
:prepend-icon="mdiFolderLock"
/>
</v-col>
<v-col>
@ -218,6 +218,12 @@
</template>
<script setup lang="ts">
import mdiEye from '~icons/mdi/eye'
import mdiEyeOff from '~icons/mdi/eye-off'
import mdiAccount from '~icons/mdi/account'
import mdiKeyChain from '~icons/mdi/key-chain'
import mdiBookMultiple from '~icons/mdi/book-multiple'
import mdiFolderLock from '~icons/mdi/folder-lock'
import { UserRoles } from '@/types/UserRoles'
import type { components } from '@/generated/openapi/komga'
import { useRules } from 'vuetify/labs/rules'

View file

@ -80,13 +80,14 @@
"
color="success"
size="x-large"
icon="mdi-check-all"
:icon="mdiCheckAll"
/>
</v-fab>
</template>
</template>
<script lang="ts" setup>
import mdiCheckAll from '~icons/mdi/check-all'
import { useAnnouncements } from '@/colada/queries/announcements'
import { useMarkAnnouncementsRead } from '@/colada/mutations/mark-announcements-read'
import { commonMessages } from '@/utils/i18n/common-messages'

View file

@ -18,7 +18,7 @@
<v-toolbar-title>
<v-icon
color="medium-emphasis"
icon="mdi-account-multiple"
:icon="mdiAccountMultiple"
size="x-small"
start
/>
@ -27,7 +27,7 @@
<v-btn
class="me-2"
prepend-icon="mdi-plus"
:prepend-icon="mdiPlus"
rounded="lg"
text="Add a User"
border
@ -54,20 +54,20 @@
<div class="d-flex ga-1 justify-end">
<v-icon-btn
v-tooltip:bottom="'Change password'"
icon="mdi-lock-reset"
:icon="mdiLockReset"
@click="showDialog(ACTION.PASSWORD, user)"
@mouseenter="activator = $event.currentTarget"
/>
<v-icon-btn
v-tooltip:bottom="'Edit user'"
icon="mdi-pencil"
:icon="mdiPencil"
:disabled="me?.id == user.id"
@click="showDialog(ACTION.EDIT, user)"
@mouseenter="activator = $event.currentTarget"
/>
<v-icon-btn
v-tooltip:bottom="'Delete user'"
icon="mdi-delete"
:icon="mdiDelete"
:disabled="me?.id == user.id"
@click="showDialog(ACTION.DELETE, user)"
@mouseenter="activatorDelete = $event.currentTarget"
@ -120,6 +120,11 @@
</template>
<script lang="ts" setup>
import mdiAccountMultiple from '~icons/mdi/account-multiple'
import mdiPlus from '~icons/mdi/plus'
import mdiLockReset from '~icons/mdi/lock-reset'
import mdiPencil from '~icons/mdi/pencil'
import mdiDelete from '~icons/mdi/delete'
import { useUsers } from '@/colada/queries/users'
import { komgaClient } from '@/api/komga-client'
import type { components } from '@/generated/openapi/komga'

View file

@ -5,8 +5,8 @@
*/
// Styles
import '@mdi/font/css/materialdesignicons.css'
import 'vuetify/styles'
import { aliases, mdi } from 'vuetify/iconsets/mdi-svg'
// Composables
import { createVuetify } from 'vuetify'
@ -37,6 +37,13 @@ export const vuetify = createVuetify({
fallback: defaultLocale,
messages,
},
icons: {
defaultSet: 'mdi',
aliases,
sets: {
mdi,
},
},
theme: {
defaultTheme: 'light',
themes: {

View file

@ -24,7 +24,6 @@
"allowUnusedLabels": false,
"noImplicitOverride": true,
"allowImportingTsExtensions": false,
"exactOptionalPropertyTypes": true,
"lib": ["esnext", "dom", "dom.iterable"]
}
}

View file

@ -5,6 +5,8 @@ import ViteFonts from 'unplugin-fonts/vite'
import Layouts from 'vite-plugin-vue-layouts-next'
import Vue from '@vitejs/plugin-vue'
import VueRouter from 'unplugin-vue-router/vite'
import Icons from 'unplugin-icons/vite'
import IconsResolver from 'unplugin-icons/resolver'
import { VueRouterAutoImports } from 'unplugin-vue-router'
import Vuetify, { transformAssetUrls } from 'vite-plugin-vuetify'
import dir2json from 'vite-plugin-dir2json'
@ -32,6 +34,7 @@ export default defineConfig({
dts: 'src/components.d.ts',
directoryAsNamespace: true,
collapseSamePrefixes: true,
resolvers: [IconsResolver()],
}),
Vue({
template: { transformAssetUrls },
@ -57,6 +60,9 @@ export default defineConfig({
dir2json({
dts: true,
}),
Icons({
autoInstall: true,
}),
],
define: { 'process.env': {} },
resolve: {