Skip to content
This repository has been archived by the owner on Sep 20, 2024. It is now read-only.

feat: icons extends #50

Merged
merged 11 commits into from
Apr 4, 2021
28 changes: 28 additions & 0 deletions .changeset/ten-pandas-run.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
'@chakra-ui/c-icon': minor
'@chakra-ui/c-accordion': patch
'@chakra-ui/c-alert': patch
'@chakra-ui/c-badge': patch
'@chakra-ui/c-button': patch
'@chakra-ui/c-close-button': patch
'@chakra-ui/c-color-mode': patch
'@chakra-ui/c-flex': patch
'@chakra-ui/c-modal': patch
'@chakra-ui/c-popper': patch
'@chakra-ui/c-portal': patch
'@chakra-ui/c-reset': patch
'@chakra-ui/c-spinner': patch
'@chakra-ui/c-theme-provider': patch
'@chakra-ui/c-visually-hidden': patch
'@chakra-ui/vue-next': patch
'@chakra-ui/nuxt-next': patch
'@chakra-ui/vue-system': patch
'@chakra-ui/vue-test-utils': patch
'@chakra-ui/vue-theme': patch
'@chakra-ui/vue-theme-tools': patch
'@chakra-ui/vue-utils': patch
'@chakra-ui/vue-auto-import': patch
'@chakra-ui/vue-docs': patch
---

Add option to extend icons with custom icons
5 changes: 5 additions & 0 deletions .changeset/wild-chairs-applaud.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@chakra-ui/c-icon': minor
---

Add option to extend icons
54 changes: 53 additions & 1 deletion packages/c-icon/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,56 @@ A component to display icons in the browser
yarn add @chakra-ui/c-icon
# or
npm i @chakra-ui/c-icon
```
```

### Adding custom icons
All Chakra icons are registered in the Chakra plugin under the `icons.extend` key. So you
can extend this object to add your own icons. Here are the steps:

- Export the icon's `svg` from Figma, Sketch, etc.
- Use a tool like [SvgOmg](https://svgomg.firebaseapp.com) to reduce the size
and minify the markup.
- Add the icon to the theme object.

> Add the `fill=currentColor` attribute to the `path` or `g` so that when you
> this `<Icon color="gray.200"/>`, it works correctly.

<br />

```js
// Step 1: Each icon should be stored as an object of `path` and `viewBox`
const customIcons = {
icon1: {
path: `<path fill="currentColor" d="..." />`,
// If the icon's viewBox is `0 0 24 24`, you can ignore `viewBox`
viewBox: "0 0 40 40",
},
icon2: {
path: `
<g fill="currentColor">
<path d="..."/>
</g>
`
}
};

// Step 2: Add the custom icon to the Chakra plugin
const app = createApp(App)
.use(ChakraUIVuePlugin, {
icons: {
// ...
extend: customIcons
}
})
```

You can now consume your custom icons in your template like this:

```vue
<template>
<c-icon name="icon1" color="yellow.600" />
<c-icon name="icon2" color="green.300" />
</template>
```

> You can access the full merged icons object under `this.$chakra.icons` in your Vue components.
5 changes: 5 additions & 0 deletions packages/c-icon/examples/with-custom-icon.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<template>
<div>
<c-icon size="10" name="discord" />
</div>
</template>
2 changes: 1 addition & 1 deletion packages/c-icon/src/icon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export const CIcon = defineComponent({
color: 'currentColor',
innerHTML: icon.value.path,
focusable: false,
viewBox: fallbackIcon.viewBox,
viewBox: icon.value.viewBox || fallbackIcon.viewBox,
}))

return () =>
Expand Down
16 changes: 16 additions & 0 deletions packages/c-icon/tests/__snapshots__/c-icon.test.ts.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`should render custom icon properly 1`] = `
<DocumentFragment>
<svg
class="chakra-icon css-stgirh"
focusable="false"
viewBox="0 0 496 512"
>
<path
d="M297.216 243.2c0 15.616-11.52 28.416-26.112 28.416-14.336 0-26.112-12.8-26.112-28.416s11.52-28.416 26.112-28.416c14.592 0 26.112 12.8 26.112 28.416zm-119.552-28.416c-14.592 0-26.112 12.8-26.112 28.416s11.776 28.416 26.112 28.416c14.592 0 26.112-12.8 26.112-28.416.256-15.616-11.52-28.416-26.112-28.416zM448 52.736V512c-64.494-56.994-43.868-38.128-118.784-107.776l13.568 47.36H52.48C23.552 451.584 0 428.032 0 398.848V52.736C0 23.552 23.552 0 52.48 0h343.04C424.448 0 448 23.552 448 52.736zm-72.96 242.688c0-82.432-36.864-149.248-36.864-149.248-36.864-27.648-71.936-26.88-71.936-26.88l-3.584 4.096c43.52 13.312 63.744 32.512 63.744 32.512-60.811-33.329-132.244-33.335-191.232-7.424-9.472 4.352-15.104 7.424-15.104 7.424s21.248-20.224 67.328-33.536l-2.56-3.072s-35.072-.768-71.936 26.88c0 0-36.864 66.816-36.864 149.248 0 0 21.504 37.12 78.08 38.912 0 0 9.472-11.52 17.152-21.248-32.512-9.728-44.8-30.208-44.8-30.208 3.766 2.636 9.976 6.053 10.496 6.4 43.21 24.198 104.588 32.126 159.744 8.96 8.96-3.328 18.944-8.192 29.44-15.104 0 0-12.8 20.992-46.336 30.464 7.68 9.728 16.896 20.736 16.896 20.736 56.576-1.792 78.336-38.912 78.336-38.912z"
fa-key="3"
fill="currentColor"
/>
</svg>
</DocumentFragment>
`;

exports[`should render properly 1`] = `
<DocumentFragment>
<svg
Expand Down
39 changes: 37 additions & 2 deletions packages/c-icon/tests/c-icon.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,42 @@
import { render } from '../../test-utils/src'
import { CIcon } from '../src'
import { render, testA11y } from '../../test-utils/src'
import { provide } from 'vue'

const renderComponent = (props?: any) => {
const base = {
components: {
CIcon,
},
template: '<CIcon name="star" />',
...props,
}
return render(base)
}

it('should render properly', () => {
const { asFragment } = render(CIcon)
const { asFragment } = renderComponent()
expect(asFragment()).toMatchSnapshot()
})

it('should have no a11y violations', async () => {
await testA11y(renderComponent())
})

it('should render custom icon properly', async () => {
const icons = {
discord: {
path:
'<path fill="currentColor" d="M297.216 243.2c0 15.616-11.52 28.416-26.112 28.416-14.336 0-26.112-12.8-26.112-28.416s11.52-28.416 26.112-28.416c14.592 0 26.112 12.8 26.112 28.416zm-119.552-28.416c-14.592 0-26.112 12.8-26.112 28.416s11.776 28.416 26.112 28.416c14.592 0 26.112-12.8 26.112-28.416.256-15.616-11.52-28.416-26.112-28.416zM448 52.736V512c-64.494-56.994-43.868-38.128-118.784-107.776l13.568 47.36H52.48C23.552 451.584 0 428.032 0 398.848V52.736C0 23.552 23.552 0 52.48 0h343.04C424.448 0 448 23.552 448 52.736zm-72.96 242.688c0-82.432-36.864-149.248-36.864-149.248-36.864-27.648-71.936-26.88-71.936-26.88l-3.584 4.096c43.52 13.312 63.744 32.512 63.744 32.512-60.811-33.329-132.244-33.335-191.232-7.424-9.472 4.352-15.104 7.424-15.104 7.424s21.248-20.224 67.328-33.536l-2.56-3.072s-35.072-.768-71.936 26.88c0 0-36.864 66.816-36.864 149.248 0 0 21.504 37.12 78.08 38.912 0 0 9.472-11.52 17.152-21.248-32.512-9.728-44.8-30.208-44.8-30.208 3.766 2.636 9.976 6.053 10.496 6.4 43.21 24.198 104.588 32.126 159.744 8.96 8.96-3.328 18.944-8.192 29.44-15.104 0 0-12.8 20.992-46.336 30.464 7.68 9.728 16.896 20.736 16.896 20.736 56.576-1.792 78.336-38.912 78.336-38.912z" fa-key="3" fill="currentColor"></path>',
viewBox: '0 0 496 512',
},
}

const { asFragment } = renderComponent({
template: '<c-icon size="10" name="discord" />',
setup() {
provide('$chakraIcons', icons)
},
})

expect(asFragment()).toMatchSnapshot()
})
2 changes: 2 additions & 0 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const ChakraUIVuePlugin: Plugin = {
})
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good work! 👍🏽


let libraryIcons = options.icons?.library || {}
let extendedIcons = options.icons?.extend || {}

// Initialize colormode
const colorMode = theme.config?.initialColorMode || 'dark'
Expand All @@ -51,6 +52,7 @@ const ChakraUIVuePlugin: Plugin = {
const mergedIcons: MergedIcons = {
...internalIcons,
...libraryIcons,
...extendedIcons,
}
app.provide('$chakraIcons', mergedIcons)
},
Expand Down
9 changes: 8 additions & 1 deletion playground/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,14 @@ const app = createApp(App)
icons: {
library: {
feActivity
}
},
extend: {
discord: {
path:
'<path fill="currentColor" d="M297.216 243.2c0 15.616-11.52 28.416-26.112 28.416-14.336 0-26.112-12.8-26.112-28.416s11.52-28.416 26.112-28.416c14.592 0 26.112 12.8 26.112 28.416zm-119.552-28.416c-14.592 0-26.112 12.8-26.112 28.416s11.776 28.416 26.112 28.416c14.592 0 26.112-12.8 26.112-28.416.256-15.616-11.52-28.416-26.112-28.416zM448 52.736V512c-64.494-56.994-43.868-38.128-118.784-107.776l13.568 47.36H52.48C23.552 451.584 0 428.032 0 398.848V52.736C0 23.552 23.552 0 52.48 0h343.04C424.448 0 448 23.552 448 52.736zm-72.96 242.688c0-82.432-36.864-149.248-36.864-149.248-36.864-27.648-71.936-26.88-71.936-26.88l-3.584 4.096c43.52 13.312 63.744 32.512 63.744 32.512-60.811-33.329-132.244-33.335-191.232-7.424-9.472 4.352-15.104 7.424-15.104 7.424s21.248-20.224 67.328-33.536l-2.56-3.072s-35.072-.768-71.936 26.88c0 0-36.864 66.816-36.864 149.248 0 0 21.504 37.12 78.08 38.912 0 0 9.472-11.52 17.152-21.248-32.512-9.728-44.8-30.208-44.8-30.208 3.766 2.636 9.976 6.053 10.496 6.4 43.21 24.198 104.588 32.126 159.744 8.96 8.96-3.328 18.944-8.192 29.44-15.104 0 0-12.8 20.992-46.336 30.464 7.68 9.728 16.896 20.736 16.896 20.736 56.576-1.792 78.336-38.912 78.336-38.912z" fa-key="3" fill="currentColor"></path>',
viewBox: '0 0 496 512',
},
},
},
extendTheme: extendTheme({
config: {
Expand Down