Skip to content

Commit

Permalink
feat: support disabling icon name normalization and support arbitrary…
Browse files Browse the repository at this point in the history
… names, #265
  • Loading branch information
antfu committed Dec 10, 2024
1 parent 65e4c85 commit eeec60a
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 3 deletions.
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,31 @@ export default defineNuxtConfig({
})
```

### Case Sensitive Custom Collections

Before `v1.10`, due to the limitation of Iconify's previous convention, all custom icons were normalized to `kebab-case` with a warning. Thanks to the updates on Iconify side, starting from `v1.10`, you can opt-in to use case-sensitive custom collections and by pass the normalization.

```ts
export default defineNuxtConfig({
modules: [
'@nuxt/icon'
],
icon: {
customCollections: [
{
prefix: 'my-icon',
dir: './assets/my-icons',
normalizeIconName: false, // <-- this
},
],
},
})
```

To use `FooBar.svg` as `my-icon:FooBar`, for example.

`normalizeIconName` is default to `true` for backward compatibility, and will be flipped in the future major version. See [#265](https://github.com/nuxt/icon/issues/265) for more context.

### Icon Customization

To update the default size (`1em`) of the `<Icon />`, create an `app.config.ts` with the `icon.size` property.
Expand Down
12 changes: 12 additions & 0 deletions playground/components/ShowcaseFixture.vue
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,18 @@ defineProps<{
:mode
:customize
/>
<Icon
name="custom1:Foo_Bar_Zag"
size="64"
:mode
:customize
/>
<Icon
name="custom1:Foo.BarZag"
size="64"
:mode
:customize
/>
</p>
<p>
Custom icons with `prefix: ''` from local fs:
Expand Down
8 changes: 8 additions & 0 deletions playground/icons/custom1/Foo_Bar_Zag.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions playground/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,17 @@ export default defineNuxtConfig({
{
prefix: 'custom1',
dir: './icons/custom1',
normalizeIconName: false,
},
{
prefix: 'custom-parts',
dir: './icons/custom-parts',
normalizeIconName: false,
},
{
prefix: '',
dir: './icons/no-prefix',
normalizeIconName: false,
},
],
serverBundle: 'remote',
Expand Down
12 changes: 9 additions & 3 deletions src/collections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export function getCollectionPath(collection: string) {
}

// https://github.com/iconify/iconify/blob/2274c033b49c01a50dc89b490b89d803d19d95dc/packages/utils/src/icon/name.ts#L15-L18
export const validIconNameRE = /^[a-z0-9]+(-[a-z0-9]+)*$/
const validIconNameRE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/

export async function loadCustomCollection(collection: CustomCollection, nuxt: Nuxt): Promise<IconifyJSON> {
const dir = isAbsolute(collection.dir)
Expand All @@ -45,19 +45,25 @@ export async function loadCustomCollection(collection: CustomCollection, nuxt: N
}))
.sort()

const {
// TODO: next major flip this
normalizeIconName = true,
} = collection

const parsedIcons = await Promise.all(files.map(async (file) => {
let name = basename(file, '.svg')

// Currently Iconify only supports kebab-case icon names
// https://github.com/nuxt/icon/issues/265#issuecomment-2441604639
// We normalize the icon name to kebab-case and warn user about it
if (!validIconNameRE.test(name)) {
if (normalizeIconName && !validIconNameRE.test(name)) {
const normalized = name
.replace(/([a-z])([A-Z])/g, '$1-$2')
.toLowerCase()
.replace(/[^a-z0-9-]/g, '-')
.replace(/-+/g, '-')
logger.warn(`Custom icon \`${name}\` is normalized to \`${normalized}\`, we recommend to change the file name to match the icon name`)
if (normalized !== name)
logger.warn(`Custom icon \`${name}\` is normalized to \`${normalized}\`, we recommend to change the file name to match the icon name, or pass \`normalizeIconName: false\` to your custom collection options`)
name = normalized
}

Expand Down
13 changes: 13 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,19 @@ export interface ModuleOptions extends Partial<Omit<NuxtIconRuntimeOptions, 'cus

export interface CustomCollection extends Pick<IconifyJSON, 'prefix' | 'width' | 'height'> {
dir: string
/**
* Normalize icon names to kebab-case
*
* Since v1.10.0, Iconify supports arbitrary icon names.
* You can disable this option to keep the original icon names.
*
* This options is true by default to ensure compatibility with older versions.
* In the next major version, this option will be disabled by default.
*
* @see https://github.com/nuxt/icon/issues/265#issuecomment-2524979176
* @default true
*/
normalizeIconName?: boolean
}

export interface RemoteCollection {
Expand Down

0 comments on commit eeec60a

Please sign in to comment.