import { Meta } from '@storybook/addon-docs/blocks'

<Meta title="pv-icons/withIconWrapper" />

# withIconWrapper

**Important: you do not need this at all if you are using icons included in our collection.** This behavior is already built into each icon exported from this library.

If you need to use an icon provided to you by a designer that has not yet been included in this library of icons, you will want to use this container so it behaves correctly anywhere an icon can be used in our normal components like `ListItem` or `ButtonEmpty`.

This allows your custom icon to have [the same API](/docs/pv-icons-api--docs) as our official icons

## 1. Preparing the SVG

It is recommended to use an [SVG optimizer like SVGO](https://github.com/svg/svgo) either ahead of time, or as part of your bundler process. [SVGR](https://react-svgr.com/) takes it a step further and turns the SVG into a React component and uses svgo under the hood to optimize the SVG.

You'll want to make sure your svg is a single color and uses `currentColor` as the `stroke` or `fill` color anywhere it is specified. SVGO allows you to automate this with the following [plugin config](https://github.com/svg/svgo#configuration):

```js
{
    name: 'convertColors',
    params: {
        currentColor: true
    }
}
```

## 2. Prepare the svg React component

If you are using SVGR you shouldn't need to take any extra steps. However, if you want to prepare a one-off SVG component you can use the following boilerplate:

```tsx
import * as React from 'react'
import { SVGProps, Ref, forwardRef } from 'react'

const YourCustomIconSvg = (
    props: SVGProps<SVGSVGElement>,
    ref: Ref<SVGSVGElement>
) => (
    <svg
        viewBox="0 0 16 16"
        xmlns="http://www.w3.org/2000/svg"
        preserveAspectRatio="xMidYMid meet"
        focusable="false"
        ref={ref}
        {...props}
    >
        {/* contents of your svg go here */}
    </svg>
)

export const YourCustomIcon = React.forwardRef(YourCustomIconSvg)
```

## 3. Apply the `withIconWrapper` higher order component

Adjust the export of your custom icon like this:

```tsx
export const YourCustomIcon = withIconWrapper(
    React.forwardRef(YourCustomIconSvg),
    'your-custom-icon'
)
```

Alternatively, if you want to only use `withIconWrapper` in the component that will use the icon, you can do this instead:

```tsx
import { ButtonEmpty } from '@planview/pv-uikit'
import { YourCustomIcon } from './icons'
import { withIconWrapper } from '@planview/pv-icons'

const WrappedYourCustomIcon = withIconWrapper(
    YourCustomIcon,
    'your-custom-icon'
)

export const IconButton = () => (
    <ButtonEmpty icon={<WrappedYourCustomIcon />}>
        Button with my custom icon
    </ButtonEmpty>
)
```
