# vue-ionicon

> Caching asynchronous IonIcons loader for Vue

Latest version **2.1.1** (published 2023-06-12) · BSD-3-Clause license · 0 weekly downloads

## Install

```sh
npm install vue-ionicon
pnpm add vue-ionicon
yarn add vue-ionicon
bun add vue-ionicon
```

## Health

**Score 45/100 (D)** — status: abandoned.

Positive: has types; esm support; no vulnerabilities; high maintenance score; high quality score.

Warnings: low downloads.

Negative: abandoned.

## Facts

| | |
|---|---|
| Version | 2.1.1 |
| Published | 2023-06-12 |
| First published | 2022-01-25 |
| Weekly downloads | 0 |
| License | BSD-3-Clause |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 0 |
| Unpacked size | 12.3 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 1 |
| Author | Jure Erznožnik |
| Maintainers | velis |
| Keywords | vue ionicons, vue svg, ionicons |

## Links

- npm: https://www.npmjs.com/package/vue-ionicon
- Repository: https://github.com/velis74/vue-ionicon
- Homepage: https://github.com/velis74/vue-ionicon#readme
- Issues: https://github.com/velis74/vue-ionicon/issues
- npm.io page: https://npm.io/package/vue-ionicon

## Alternatives

- [@fortawesome/react-fontawesome](https://npm.io/package/@fortawesome/react-fontawesome.md) — 2.2M weekly downloads
- [roboto-fontface](https://npm.io/package/roboto-fontface.md) — 196.0K weekly downloads
- [@react-native-vector-icons/common](https://npm.io/package/@react-native-vector-icons/common.md) — 150.4K weekly downloads
- [@procore/core-icons](https://npm.io/package/@procore/core-icons.md) — 4.6K weekly downloads
- [@react-md/material-icons](https://npm.io/package/@react-md/material-icons.md) — 1.6K weekly downloads

## Recent versions

- 2.1.1 (latest) — 2023-06-12
- 2.1.0 — 2023-01-10
- 2.0.4 — 2023-01-10
- 2.0.3 — 2023-01-10
- 2.0.2 — 2023-01-10
- 2.0.1 — 2023-01-10
- 2.0.0 — 2023-01-09
- 1.1.1 — 2022-01-26
- 1.1.0 — 2022-01-26
- 1.0.0 — 2022-01-25

## README

# vue-cached-icon

Caching icon loader with an emphasis for loading the icons directly from the CDN.

Also supports svg string literals, urls to raster images (png, jpg, gif, webp, bmp, ico, avif) or urls to svg as
source.

![Demo](demo.gif)

## Demo

https://www.velis.si/vue-cached-icon/

## Features

* Renders sanitised SVG
* Also renders raster images (png, jpg, jpeg, gif, webp, bmp, ico, avif), recognised by their URL's extension and
  handed straight to the browser, unsanitised, since there's no markup for DOMPurify to sanitise
* Rejects a URL that resolves to neither a raster image nor a valid SVG, instead of rendering it half-sanitised
* Loads from CDN, any local URL, any full URL or SVG literal
  * 'ion-*': loads from ionicons repository
  * 'mdi-*': loads from material design icons repository
  * 'fa-*': loads from font-awesome repository
* Register your own repositories using `registerIconProvider(prefix: string, urlBuilder: (name: string) => string)`
* Caches loaded icons, there will be only one HTTP request per icon as long as the app is running
* Retries icons that fail to load for a reason that may pass, see [Failed loads](#failed-loads)
* Applies currentColor to icons: if colour is not otherwise specified, icons will have same color as HTML text
* Sizes icons to the surrounding text by default, see [Sizing and styling](#sizing-and-styling)
* Safe for server-side rendering: icons load in the browser after mount, see [Server-side rendering](#server-side-rendering)

## Installing

```bash
npm install --save vue-cached-icon
```

## Using

```html
<template>
  <div>
    <!-- will load by name from Ionicons CDN -->
    <cached-icon name="ion-warning"/>

    <!-- will load from your own server or any other if full URL is provided -->
    <cached-icon name="/images/my-custom-icon.svg"/>

    <!-- raster images are recognised by extension and rendered directly as an <img>, unsanitised -->
    <cached-icon name="/images/my-custom-icon.png"/>

    <!-- will display the provided SVG, but with all processing (sanitizing, applying currentColor) -->
    <cached-icon :name="mySvgLiteral"/>
  </div>
</template>
```

```vue
<script setup>
  import { CachedIcon } from 'vue-cached-icon';
</script>
```

The component emits `icon-loaded` with the icon name once the icon has rendered.

Besides `CachedIcon`, `registerIconProvider` and `retryFailedIcons` (see [Failed loads](#failed-loads)) the package
exports `resolveProviderUrl(name)`, which returns the URL a
name resolves to, `iconProviders`, the registry of providers by prefix, and `augment(svg)`, the sanitisation and
`currentColor` processing applied to every SVG.

## Failed loads

An icon that fails to load shows `…`, and the failure is logged to the console once per request. All icons with the
same name share the failure, and the next attempt is again a single request for all of them.

* A network error, HTTP 5xx, 401, 403, 408 and 429 are retried while the icon is displayed: after 2 s, then after a delay
  doubling up to 60 s, or after the delay the server asks for in `Retry-After`. When the browser comes back online,
  the retry happens right away. An icon mounted after the retry is due requests it right away as well.
* Any other HTTP status, such as 404, and a response that is not an SVG are not retried.

Call `retryFailedIcons()` when requests that failed may now succeed, e.g. after the user logs in. It forgets every
failed load, those not retried included, and the displayed icons load again right away:

```javascript
import { retryFailedIcons } from 'vue-cached-icon';

await login();
retryFailedIcons();
```

## Sizing and styling

Icon sets ship their SVGs with a `viewBox` but no `width` / `height`, so the size has to come from the use site.
This package provides it for you: the icon renders in an inline `<span class="cached-icon-wrapper">` sized at `1em`,
so an icon is as big as the text around it and moves with the font size.

Everything is a plain default that your own CSS overrides — the package stylesheet is prepended to `<head>`, so your
rules win without `!important`:

```css
/* a fixed size */
.cached-icon-wrapper { width: 24px; height: 24px; }

/* or size a group of icons through the font */
.toolbar .cached-icon-wrapper { font-size: 1.5rem; }
```

SVGs that declare their own `width` / `height` keep them. Raster images are sized the same way through the wrapper,
with `object-fit: contain` so their aspect ratio is preserved rather than stretched to fill it.

## Server-side rendering

During server-side rendering (Nuxt, VitePress, vite-ssg …) the component renders an empty
`<span class="cached-icon-wrapper">`: it neither fetches nor sanitises anything on the server. The icon loads once the
component is mounted in the browser, so the server-rendered markup always matches the first client render and
hydrates without mismatches. Icons are therefore not part of the static HTML.

## Contributing

Contributions are welcome! Feel free to open an issue or submit a pull request.

Please make sure your changes are well-tested and follow the existing code style.

## Credits

* [Vue](https://vuejs.org) The Progressive JavaScript Framework
* [Ionicons](https://github.com/ionic-team/ionicons) project
* [DOMPurify](https://github.com/cure53/DOMPurify) project

---
_Source: https://npm.io/package/vue-ionicon · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
