astro-icon
Advanced tools
Comparing version 0.3.0 to 0.4.0
13
index.ts
import Icon from "./lib/Icon.astro"; | ||
import SpriteSheet from "./lib/SpriteSheet.astro"; | ||
import Spritesheet from "./lib/Spritesheet.astro"; | ||
const SpriteSheet = Spritesheet; | ||
import Sprite from "./lib/Sprite.astro"; | ||
import createIconPack from "./lib/createIconPack.ts"; | ||
export { Icon as default, Icon, SpriteSheet, Sprite }; | ||
export { | ||
Icon as default, | ||
Icon, | ||
Spritesheet, | ||
SpriteSheet, | ||
Sprite, | ||
createIconPack, | ||
}; |
@@ -310,2 +310,3 @@ // Adapted from https://github.com/astro-community/icons | ||
name: string; | ||
pack?: string; | ||
optimize?: Optimize; | ||
@@ -312,0 +313,0 @@ fill?: string; |
import { Props, Optimize } from "./Props"; | ||
import getFromService from "./resolver"; | ||
import { optimize as optimizeSVGNative } from "svgo"; | ||
@@ -115,17 +116,58 @@ | ||
const filepath = `/src/icons/${name}.svg`; | ||
let svg = ""; | ||
try { | ||
const { default: contents } = await import(`${filepath}?raw`); | ||
let filepath = ""; | ||
if (name.includes(":")) { | ||
const [pack, ..._name] = name.split(":"); | ||
name = _name.join(":"); | ||
// Note: omit ending to use default resolution | ||
filepath = `/src/icons/${pack}`; | ||
let get; | ||
try { | ||
const mod = await import(`${filepath}`); | ||
if (typeof mod.default !== "function") { | ||
throw new Error( | ||
`[astro-icon] "${filepath}" did not export a default function!` | ||
); | ||
} | ||
get = mod.default; | ||
} catch (e) { | ||
// Do nothing, local pack is not required | ||
} | ||
if (typeof get === "undefined") { | ||
get = getFromService.bind(null, pack); | ||
} | ||
const contents = await get(name); | ||
if (!contents) { | ||
throw new Error( | ||
`<Icon pack="${pack}" name="${name}" /> did not return an icon!` | ||
); | ||
} | ||
if (!/<svg/gim.test(contents)) { | ||
throw new Error( | ||
`Unable to process "${filepath}" because it is not an SVG!` | ||
`Unable to process "<Icon pack="${pack}" name="${name}" />" because an SVG string was not returned! | ||
Recieved the following content: | ||
${contents}` | ||
); | ||
} | ||
svg = contents; | ||
} catch (e) { | ||
throw new Error( | ||
`[astro-icon] Unable to load "${filepath}". Does the file exist?` | ||
); | ||
} else { | ||
filepath = `/src/icons/${name}.svg`; | ||
try { | ||
const { default: contents } = await import(`${filepath}?raw`); | ||
if (!/<svg/gim.test(contents)) { | ||
throw new Error( | ||
`Unable to process "${filepath}" because it is not an SVG! | ||
Recieved the following content: | ||
${contents}` | ||
); | ||
} | ||
svg = contents; | ||
} catch (e) { | ||
throw new Error( | ||
`[astro-icon] Unable to load "${filepath}". Does the file exist?` | ||
); | ||
} | ||
} | ||
@@ -132,0 +174,0 @@ |
{ | ||
"name": "astro-icon", | ||
"version": "0.3.0", | ||
"version": "0.4.0", | ||
"type": "module", | ||
@@ -5,0 +5,0 @@ "exports": { |
101
README.md
@@ -5,6 +5,4 @@ # Astro Icon | ||
`astro-icon` will automatically optimize icons with [`svgo`](https://github.com/svg/svgo) and inline them directly into your HTML—no extra build step, no spritesheet complexity, no cross-browser concerns! See ["A Pretty Good SVG Icon System"](https://css-tricks.com/pretty-good-svg-icon-system/#just-include-the-icons-inline) from CSS Tricks. | ||
## Setup | ||
## Usage | ||
1. Install `astro-icon`. | ||
@@ -30,8 +28,57 @@ | ||
3. Create a directory inside of `src/` named `icons/`. | ||
4. Add each desired icon as an individual `.svg` file to `src/icons/` | ||
5. Reference a specific icon file using the `name` prop. | ||
## Icon Packs | ||
`astro-icon` automatically includes all of the most common icon packs, powered by [Iconify](https://iconify.design/)! | ||
To browse supported icons, we recommend [Icônes](https://icones.js.org/). | ||
### Usage | ||
**Icon** will inline the SVG directly in your HTML. | ||
```astro | ||
--- | ||
import { Icon } from 'astro-icon' | ||
--- | ||
<!-- Automatically fetches and inlines Material Design Icon's "account" SVG --> | ||
<Icon pack="mdi" name="account" /> | ||
<!-- Equivalent shorthand --> | ||
<Icon name="mdi:account" /> | ||
``` | ||
**Sprite** will reference the SVG from a spritesheet via [`<use>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/use). | ||
```astro | ||
--- | ||
import { Sprite, Spritesheet } from 'astro-icon' | ||
--- | ||
<!-- Automatically fetches and inlines Material Design Icon's "account" SVG --> | ||
<Sprite pack="mdi" name="account" /> | ||
<!-- Equivalent shorthand --> | ||
<Sprite name="mdi:account" /> | ||
<!-- Required ONCE per page, creates `<symbol>` for each icon --> | ||
<Spritesheet /> | ||
``` | ||
You may also create [Local Icon Packs](#local-icon-packs). | ||
## Local Icons | ||
By default, `astro-icon` supports custom local `svg` icons. They are optimized with [`svgo`](https://github.com/svg/svgo) automatically with no extra build step. See ["A Pretty Good SVG Icon System"](https://css-tricks.com/pretty-good-svg-icon-system/#just-include-the-icons-inline) from CSS Tricks. | ||
### Usage | ||
1. Create a directory inside of `src/` named `icons/`. | ||
2. Add each desired icon as an individual `.svg` file to `src/icons/` | ||
3. Reference a specific icon file using the `name` prop. | ||
**Icon** will inline the SVG directly in your HTML. | ||
```astro | ||
--- | ||
import { Icon } from 'astro-icon'; | ||
@@ -44,3 +91,3 @@ --- | ||
6. Alternatively, if you need to reuse icons multiple times across a page, you can use the `Sprite` and `SpriteSheet` components. These leverage [`<use>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/use) internally. | ||
**Sprite** will reference the SVG from a spritesheet via [`<use>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/use). | ||
@@ -56,5 +103,35 @@ ```astro | ||
<!-- Required ONCE per page, creates `<symbol>` for each icon --> | ||
<SpriteSheet /> | ||
<Spritesheet /> | ||
``` | ||
## Local Icon Packs | ||
`astro-icon` supports custom local icon packs. These are also referenced with the `pack` and/or `name` props. | ||
1. Create a directory inside of `src/` named `icons/`. | ||
2. Create a JS/TS file with your `pack` name inside of that directory, eg `src/icons/my-pack.ts` | ||
3. Use the `createIconPack` utility to handle most common situations. | ||
```ts | ||
import { createIconPack } from "astro-icon"; | ||
// Resolves `heroicons` dependency and reads SVG files from the `heroicons/outline` directory | ||
export default createIconPack({ package: "heroicons", dir: "outline" }); | ||
// Resolves `name` from a remote server, like GitHub! | ||
export default createIconPack({ | ||
url: "https://raw.githubusercontent.com/radix-ui/icons/master/packages/radix-icons/icons/", | ||
}); | ||
``` | ||
If you have custom constraints, you can always create the resolver yourself. Export a `default` function that resolves the `name` argument to an SVG string. | ||
```ts | ||
import { loadMyPackSvg } from "my-pack"; | ||
export default async (name: string): Promise<string> => { | ||
const svgString = await loadMyPackSvg(name); | ||
return svgString; | ||
}; | ||
``` | ||
## Styling | ||
@@ -88,8 +165,10 @@ | ||
`<Icon>` requires the `name` prop to reference a specific icon. | ||
`<Icon>` and `<Sprite>` share the same interface. | ||
`<Icon>` optionally accepts the `optimize` prop as a boolean. Defaults to `true`. In the future it will control `svgo` options. | ||
The `name` prop references a specific icon. It is required. | ||
`<Icon>` also accepts any global HTML attributes and `aria` attributes. They will be forwarded to the rendered `<svg>` element. | ||
The `optimize` prop is a boolean. Defaults to `true`. In the future it will control `svgo` options. | ||
Both components also accepts any global HTML attributes and `aria` attributes. They will be forwarded to the rendered `<svg>` element. | ||
See the [`Props.ts`](./lib/Props.ts) file for more details. |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
26066
12
595
170