diff --git a/packages/docs/src/pages/en/features/icon-fonts.md b/packages/docs/src/pages/en/features/icon-fonts.md index 014cd52ae40..ad787ce880a 100644 --- a/packages/docs/src/pages/en/features/icon-fonts.md +++ b/packages/docs/src/pages/en/features/icon-fonts.md @@ -202,6 +202,67 @@ Use this tool to search for any Material Design Icons and copy them to your clip +#### MDI - UnoCSS + +You can use Vuetify's MDI icon set with [UnoCSS Preset Icon](https://unocss.dev/presets/icons) by installing the `@unocss/preset-icons` package, all your icons will be tree-shaken and only the icons you use will be included in your final CSS bundle. + +You need to install `unocss` and `@iconify-json/mdi` dev dependencies first: + +::: tabs + +```bash [pnpm] +pnpm add unocss @iconify-json/mdi -D +``` + +```bash [yarn] +yarn add unocss @iconify-json/mdi -D +``` + +```bash [npm] +npm install unocss @iconify-json/mdi -D +``` + +```bash [bun] +bun add unocss @iconify-json/mdi -D +``` + +::: + +then, configure UnoCSS in your project adding the preset (read the [UnoCSS integration section](https://unocss.dev/integrations/) for further details). + +::: warning + +Don't change the default prefix `i-` of UnoCSS preset-icons, Vuetify's MDI icon set relies on it. + +::: + +```js { resource="unocss.config.js" } +import { presetIcons, defineConfig } from 'unocss' + +export default defineConfig({ + presets: [ + presetIcons(), + ], +}) +``` + +To register the icon set, use the following code: + +```js { resource="src/plugins/vuetify.js" } +import { createVuetify } from 'vuetify' +import { aliases, mdi } from 'vuetify/iconsets/mdi-unocss' + +export default createVuetify({ + icons: { + defaultSet: 'mdi', + aliases, + sets: { + mdi, + }, + }, +}) +``` + ### Material Icons For projects without a build process, it is recommended to import the icons from CDN. diff --git a/packages/vuetify/src/iconsets/mdi-unocss.ts b/packages/vuetify/src/iconsets/mdi-unocss.ts new file mode 100644 index 00000000000..edacf4d9eab --- /dev/null +++ b/packages/vuetify/src/iconsets/mdi-unocss.ts @@ -0,0 +1,83 @@ +// @unocss-include +// Composables +import { VClassIcon } from '@/composables/icons' + +// Utilities +import { h } from 'vue' + +// Types +import type { IconAliases, IconSet } from '@/composables/icons' + +const aliases: IconAliases = { + collapse: 'i-mdi:chevron-up', + complete: 'i-mdi:check', + cancel: 'i-mdi:close-circle', + close: 'i-mdi:close', + // delete (e.g. v-chip close) + delete: 'i-mdi:close-circle', + clear: 'i-mdi:close-circle', + success: 'i-mdi:check-circle', + info: 'i-mdi:information', + warning: 'i-mdi:alert-circle', + error: 'i-mdi:close-circle', + prev: 'i-mdi:chevron-left', + next: 'i-mdi:chevron-right', + checkboxOn: 'i-mdi:checkbox-marked', + checkboxOff: 'i-mdi:checkbox-blank-outline', + checkboxIndeterminate: 'i-mdi:minus-box', + delimiter: 'i-mdi:circle', + // for carousel + sortAsc: 'i-mdi:arrow-up', + sortDesc: 'i-mdi:arrow-down', + expand: 'i-mdi:chevron-down', + menu: 'i-mdi:menu', + subgroup: 'i-mdi:menu-down', + dropdown: 'i-mdi:menu-down', + radioOn: 'i-mdi:radiobox-marked', + radioOff: 'i-mdi:radiobox-blank', + edit: 'i-mdi:pencil', + ratingEmpty: 'i-mdi:star-outline', + ratingFull: 'i-mdi:star', + ratingHalf: 'i-mdi:star-half-full', + loading: 'i-mdi:cached', + first: 'i-mdi:page-first', + last: 'i-mdi:page-last', + unfold: 'i-mdi:unfold-more-horizontal', + file: 'i-mdi:paperclip', + plus: 'i-mdi:plus', + minus: 'i-mdi:minus', + calendar: 'i-mdi:calendar', + treeviewCollapse: 'i-mdi:menu-down', + treeviewExpand: 'i-mdi:menu-right', + tableGroupCollapse: 'i-mdi:chevron-down', + tableGroupExpand: 'i-mdi:chevron-right', + eyeDropper: 'i-mdi:eyedropper', + upload: 'i-mdi:cloud-upload', + color: 'i-mdi:palette', + command: 'i-mdi:apple-keyboard-command', + ctrl: 'i-mdi:apple-keyboard-control', + space: 'i-mdi:keyboard-space', + shift: 'i-mdi:apple-keyboard-shift', + alt: 'i-mdi:apple-keyboard-option', + enter: 'i-mdi:keyboard-return', + arrowup: 'i-mdi:arrow-up', + arrowdown: 'i-mdi:arrow-down', + arrowleft: 'i-mdi:arrow-left', + arrowright: 'i-mdi:arrow-right', + backspace: 'i-mdi:backspace', + play: 'i-mdi:play', + pause: 'i-mdi:pause', + fullscreen: 'i-mdi:fullscreen', + fullscreenExit: 'i-mdi:fullscreen-exit', + volumeHigh: 'i-mdi:volume-high', + volumeMedium: 'i-mdi:volume-medium', + volumeLow: 'i-mdi:volume-low', + volumeOff: 'i-mdi:volume-variant-off', +} + +const mdi: IconSet = { + // Not using mergeProps here, functional components merge props by default (?) + component: (props: any) => h(VClassIcon, { ...props, class: 'mdi' }), +} + +export { aliases, mdi }