Skip to content

Commit

Permalink
fix(types): proper types for custom icons
Browse files Browse the repository at this point in the history
  • Loading branch information
egoist committed Sep 23, 2023
1 parent 9055588 commit 4bdb352
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 3 deletions.
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,34 @@ Then you can use the icons in your HTML:

Search the icon you want to use here: https://icones.js.org

### Custom Icons

You can also use custom icons with this plugin, for example:

```js
module.exports = {
plugins: [
iconsPlugin({
collections: {
foo: {
icons: {
"arrow-left": {
// svg body
body: '<path d="M10 19l-7-7m0 0l7-7m-7 7h18"/>',
// svg width and height, optional
width: 24,
height: 24,
},
},
},
},
}),
],
}
```

Then you can use this custom icon as class name: `i-foo-arrow-left`.

## Sponsors

[![sponsors](https://sponsors-images.egoist.dev/sponsors.svg)](https://github.com/sponsors/egoist)
Expand Down
50 changes: 50 additions & 0 deletions src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,53 @@ test("main", async () => {
"
`)
})

test("custom icon", () => {
const result = postcss([
tailwindcss({
config: {
content: [
{
raw: '<span class="i-foo-home"></span>',
extension: "html",
},
],
plugins: [
iconsPlugin({
collections: {
foo: {
icons: {
"arrow-left": {
body: '<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M10.5 19.5L3 12m0 0l7.5-7.5M3 12h18"/>',
width: 20,
height: 20,
},
},
},
},
}),
],
},
}),
]).process(`
.foo {
@apply i-foo-arrow-left;
}
`)

expect(result.css).toMatchInlineSnapshot(`
"
.foo {
display: inline-block;
width: 1em;
height: 1em;
background-color: currentColor;
-webkit-mask: no-repeat center / 100%;
mask: no-repeat center / 100%;
-webkit-mask-image: var(--svg);
mask-image: var(--svg);
--svg: url(\\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' width='20' height='20'%3E%3Cpath fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M10.5 19.5L3 12m0 0l7.5-7.5M3 12h18'/%3E%3C/svg%3E\\")
}
"
`)
})
10 changes: 7 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
import { IconifyJSON } from "@iconify/types"
import { IconifyJSONIconsData } from "@iconify/types"
import plugin from "tailwindcss/plugin.js"
import { parseIconSet } from "@iconify/utils"
import { generateIconComponent, getIconCollections } from "./core"
import { CollectionNames } from "../types"
import { type Optional } from "./utils"

export { getIconCollections, type CollectionNames }

export const iconsPlugin = ({
collections,
}: {
collections: Record<string, IconifyJSON>
collections: Record<string, Optional<IconifyJSONIconsData, "prefix">>
}) => {
const components: Record<string, Record<string, string>> = {}

for (const prefix of Object.keys(collections)) {
const collection = collections[prefix]
const collection: IconifyJSONIconsData = {
...collections[prefix],
prefix,
}
parseIconSet(collection, (name, data) => {
if (!data) return
components[`${prefix}-${name}`] = generateIconComponent(data)
Expand Down
1 change: 1 addition & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>

0 comments on commit 4bdb352

Please sign in to comment.