Skip to content

Commit

Permalink
feat: allow override and include new UnoCSS icons (#121)
Browse files Browse the repository at this point in the history
* feat: allow override and include new UnoCSS icons

* docs: change additional icons hint paragraph

* docs: .

* fix: update UnoCSS icons interface
  • Loading branch information
userquin committed Oct 9, 2023
1 parent 142197c commit 7dc8fb0
Show file tree
Hide file tree
Showing 5 changed files with 162 additions and 43 deletions.
25 changes: 25 additions & 0 deletions docs/guide/icons/unocss-preset-icons.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,31 @@ export default defineNuxtConfig({
})
```

If you want to change the default `unocss-mdi` icon set icons, you can override any icon using the `icons.unocssIcons` option in your Vuetify options, and so, you don't need to write a custom plugin, don't forget to add the prefix and the collection name to the icon name:
```ts
// Nuxt config file
import { defineNuxtConfig } from 'nuxt/config'

export default defineNuxtConfig({
modules: ['@unocss/nuxt', 'vuetify-nuxt-module'],
vuetify: {
vuetifyOptions: {
icons: {
defaultSet: 'unocss-mdi',
unocssIcons: {
// default is i-mdi:close-circle
delete: 'i-mdi:close-circle-outline',
// even from another collection, default is i-mdi:chevron-up
collapse: 'i-tabler:chevron-up'
}
}
}
}
})
```

You can also add additional icons using the `icons.unocssAdditionalIcons` option in your Vuetify options, don't forget to add the prefix and the collection name to the icon name. Additional icons will override the default icons, you should try to avoid overriding them using this option.

## Adding a new Vuetify icon set

This module provides the `mdi` icons via `unocss-mdi` icon set. `unocss-mdi` icon set will use the [@iconify-json/mdi](https://icon-sets.iconify.design/mdi/) collection, but you can use another icon set by installing the corresponding `@iconify-json/*` packages and configuring Vuetify to use it:
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "vuetify-nuxt-module",
"type": "module",
"version": "0.5.13",
"packageManager": "pnpm@8.8.0",
"packageManager": "pnpm@8.9.0",
"description": "Zero-Config Nuxt Module for Vuetify",
"author": "userquin <userquin@gmail.com>",
"license": "MIT",
Expand Down
49 changes: 48 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { LocaleOptions, RtlOptions, createVuetify, VuetifyOptions } from 'vuetify'
import type { LocaleOptions, RtlOptions, VuetifyOptions, createVuetify } from 'vuetify'
import type { UnwrapNestedRefs } from 'vue'

export type DateAdapter = 'vuetify' | 'date-fns' | 'moment' | 'luxon' | 'dayjs' | 'js-joda' | 'date-fns-jalali' | 'jalaali' | 'hijri' | 'custom'
Expand Down Expand Up @@ -69,6 +69,45 @@ export interface FontIconSet {
cdn?: string
}

export interface UnoCCSMdiIconSet {
collapse?: string
complete?: string
cancel?: string
close?: string
delete?: string
clear?: string
success?: string
info?: string
warning?: string
error?: string
prev?: string
next?: string
checkboxOn?: string
checkboxOff?: string
checkboxIndeterminate?: string
delimiter?: string
sortAsc?: string
sortDesc?: string
expand?: string
menu?: string
subgroup?: string
dropdown?: string
radioOn?: string
radioOff?: string
edit?: string
ratingEmpty?: string
ratingFull?: string
ratingHalf?: string
loading?: string
first?: string
last?: string
unfold?: string
file?: string
plus?: string
minus?: string
calendar?: string
}

export interface IconsOptions {
/**
* @default 'mdi'
Expand All @@ -80,6 +119,14 @@ export interface IconsOptions {
* @default 'i-'
*/
unocssIconPrefix?: string
/**
* Override the default mdi icons.
*
* Icon names should include the prefix and the collection, for example:
* - home: i-<collection>:<icon>
*/
unocssIcons?: UnoCCSMdiIconSet
unocssAdditionalIcons?: Record<string, string>
sets?: IconFontName | IconFontName[] | FontIconSet[]
svg?: {
mdi?: JSSVGIconSet
Expand Down
8 changes: 7 additions & 1 deletion src/utils/icons.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { isPackageExists } from 'local-pkg'
import type { FontIconSet, IconFontName, IconSetName, IconsOptions, VOptions } from '../types'
import type { FontIconSet, IconFontName, IconSetName, IconsOptions, UnoCCSMdiIconSet, VOptions } from '../types'

export interface ResolvedIcons {
enabled: boolean
unocss: boolean
unocssAliases: boolean
unocssIconPrefix: string
unocssIcons: UnoCCSMdiIconSet
unocssAdditionalIcons: Record<string, string>
defaultSet?: IconSetName
sets: string[]
cdn: [key: string, cdn: string][]
Expand Down Expand Up @@ -42,6 +44,8 @@ const disabledResolvedIcons: ResolvedIcons = Object.freeze({
unocss: false,
unocssAliases: false,
unocssIconPrefix: 'i-',
unocssIcons: {},
unocssAdditionalIcons: {},
imports: [],
aliases: [],
aliasesImportPresent: false,
Expand Down Expand Up @@ -76,6 +80,8 @@ export function prepareIcons(
unocss: unocssPresent && (defaultSet === 'unocss-mdi' || sets.some(s => s.name === 'unocss-mdi')),
unocssAliases: defaultSet === 'unocss-mdi',
unocssIconPrefix: icons.unocssIconPrefix ?? 'i-',
unocssIcons: icons.unocssIcons ?? {},
unocssAdditionalIcons: icons.unocssAdditionalIcons ?? {},
defaultSet,
sets: [],
aliases: [],
Expand Down
121 changes: 81 additions & 40 deletions src/vite/vuetify-icons-configuration-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,46 +101,87 @@ ${unocss}
if (ctx.icons.unocss && ctx.icons.unocssAliases) {
ctx.icons.imports.unshift('// @unocss-include')
const prefix = `${ctx.icons.unocssIconPrefix}mdi:`
unocss = `const aliases = JSON.parse('${JSON.stringify({
collapse: `${prefix}chevron-up`,
complete: `${prefix}check`,
cancel: `${prefix}close-circle`,
close: `${prefix}close`,
delete: `${prefix}close-circle`,
// delete (e.g. v-chip close)
clear: `${prefix}close-circle`,
success: `${prefix}check-circle`,
info: `${prefix}information`,
warning: `${prefix}alert-circle`,
error: `${prefix}close-circle`,
prev: `${prefix}chevron-left`,
next: `${prefix}chevron-right`,
checkboxOn: `${prefix}checkbox-marked`,
checkboxOff: `${prefix}checkbox-blank-outline`,
checkboxIndeterminate: `${prefix}minus-box`,
delimiter: `${prefix}circle`,
// for carousel
sortAsc: `${prefix}arrow-up`,
sortDesc: `${prefix}arrow-down`,
expand: `${prefix}chevron-down`,
menu: `${prefix}menu`,
subgroup: `${prefix}menu-down`,
dropdown: `${prefix}menu-down`,
radioOn: `${prefix}radiobox-marked`,
radioOff: `${prefix}radiobox-blank`,
edit: `${prefix}pencil`,
ratingEmpty: `${prefix}star-outline`,
ratingFull: `${prefix}star`,
ratingHalf: `${prefix}star-half-full`,
loading: `${prefix}cached`,
first: `${prefix}page-first`,
last: `${prefix}page-last`,
unfold: `${prefix}unfold-more-horizontal`,
file: `${prefix}paperclip`,
plus: `${prefix}plus`,
minus: `${prefix}minus`,
calendar: `${prefix}calendar`,
})}');
const {
collapse = `${prefix}chevron-up`,
complete = `${prefix}check`,
cancel = `${prefix}close-circle`,
close = `${prefix}close`,
// delete (e.g. v-chip close)
clear = `${prefix}close-circle`,
success = `${prefix}check-circle`,
info = `${prefix}information`,
warning = `${prefix}alert-circle`,
error = `${prefix}close-circle`,
prev = `${prefix}chevron-left`,
next = `${prefix}chevron-right`,
checkboxOn = `${prefix}checkbox-marked`,
checkboxOff = `${prefix}checkbox-blank-outline`,
checkboxIndeterminate = `${prefix}minus-box`,
delimiter = `${prefix}circle`,
// for carousel
sortAsc = `${prefix}arrow-up`,
sortDesc = `${prefix}arrow-down`,
expand = `${prefix}chevron-down`,
menu = `${prefix}menu`,
subgroup = `${prefix}menu-down`,
dropdown = `${prefix}menu-down`,
radioOn = `${prefix}radiobox-marked`,
radioOff = `${prefix}radiobox-blank`,
edit = `${prefix}pencil`,
ratingEmpty = `${prefix}star-outline`,
ratingFull = `${prefix}star`,
ratingHalf = `${prefix}star-half-full`,
loading = `${prefix}cached`,
first = `${prefix}page-first`,
last = `${prefix}page-last`,
unfold = `${prefix}unfold-more-horizontal`,
file = `${prefix}paperclip`,
plus = `${prefix}plus`,
minus = `${prefix}minus`,
calendar = `${prefix}calendar`,
} = ctx.icons.unocssIcons
const useIcons: Record<string, string> = {
collapse,
complete,
cancel,
close,
delete: ctx.icons.unocssIcons.delete ?? `${prefix}close-circle`,
clear,
success,
info,
warning,
error,
prev,
next,
checkboxOn,
checkboxOff,
checkboxIndeterminate,
delimiter,
sortAsc,
sortDesc,
expand,
menu,
subgroup,
dropdown,
radioOn,
radioOff,
edit,
ratingEmpty,
ratingFull,
ratingHalf,
loading,
first,
last,
unfold,
file,
plus,
minus,
calendar,
}
Object.entries(ctx.icons.unocssAdditionalIcons).forEach(([key, value]) => {
useIcons[key] = value
})
unocss = `const aliases = JSON.parse('${JSON.stringify(useIcons)}');
`
}

Expand Down

0 comments on commit 7dc8fb0

Please sign in to comment.