stories/atoms/components/icon/icon.stories.mdx

Summary

Maintainability
Test Coverage
import { Meta, Story, Canvas, ArgsTable } from '@storybook/addon-docs'
import { ThemeProvider } from 'ui/atoms/theme/ThemeProvider.tsx'
import { ThemeSwitcher } from 'ui/atoms/theme/ThemeSwitcher.tsx'
import { Icon } from 'ui/atoms/icon/Icon.tsx'
import { Typography } from 'ui/atoms/typography/Typography.tsx'
import '../component.scss'
import './icon.scss'

<Meta
  title="Atoms/Icon"
  component={Icon}
  decorators={[
    Story => {
      return (
        <ThemeProvider>
          <div className="story-theme-switcher">
            <ThemeSwitcher />
          </div>
          <div className="component-story-main">
            <Story />
          </div>
        </ThemeProvider>
      )
    }
  ]}
/>

# Icon

> Facilitates interactions between the user and the application.

[![stability-unstable](https://img.shields.io/badge/stability-unstable-yellow.svg)](https://github.com/emersion/stability-badges#unstable)

## Description

Icons help convey ideas to users in a quick and simple way,
reducing the need for text that can be hard to read and less intuitive.  
Icon has the following properties:

- `name`: the name of the icon you want to use. All icons come in both light and dark theme.
- `size`: optional size property applied to both the width and height of the icon.
- `invertColor`: optional property to invert the icon color.
- `className`: optional class name for custom CSS styling.

## Overview

<Story
  name="Overview"
  argTypes={{ className: { control: false } }}
  args={{ name: 'profile', size: 30, invertColor: false }}
>
  {args => {
    const inverted = args.invertColor ? 'inverted' : ''
    return (
      <div
        style={{
          display: 'grid',
          justifyContent: 'center'
        }}
      >
        <div className={`icon-card ${inverted}`} style={{ width: '150px' }}>
          <Icon {...args} />
        </div>
      </div>
    )
  }}
</Story>

---

## Properties

<ArgsTable story="Overview" />

## Name

The component has several icons to choose from and they are all themed. To use an icon you just have to pass
the name of the icon you want as the property value.

Below you will find all available icons with their respective name.

<Canvas>
  <Story name="Name">
    {() => {
      const iconNames = [
        'add',
        'alert',
        'arrow-down',
        'arrow-left',
        'arrow-right',
        'arrow-up',
        'calendar',
        'chat',
        'check',
        'clock',
        'close',
        'cross',
        'discord-round',
        'facebook-square',
        'github-round',
        'linkedin-square',
        'linkedin-round',
        'medium-round',
        'meeting',
        'menu',
        'moon',
        'next',
        'podcast',
        'previous',
        'profile',
        'search',
        'sun',
        'telegram-round',
        'twitter-square',
        'twitter-round',
        'wallet'
      ]
      return (
        <div
          style={{
            display: 'grid',
            gridTemplateColumns: 'repeat(auto-fit, minmax(100px,100px))',
            justifyContent: 'center',
            gap: '10px'
          }}
        >
          {iconNames.map(icon => (
            <div className="icon-card" key={icon}>
              <Icon name={icon} />
              <Typography fontSize="x-small" fontFamily="secondary">
                {icon}
              </Typography>
            </div>
          ))}
        </div>
      )
    }}
  </Story>
</Canvas>

## Size

The `size` is squared and can be adjusted by passing a number value.  
By default the size is **30** pixels.

<Canvas>
  <Story name="Size">
    {() => {
      const sizes = [15, 30, 50, 80]
      return (
        <div
          style={{
            display: 'grid',
            gridTemplateColumns: 'repeat(auto-fit, minmax(75px,auto))',
            justifyContent: 'center',
            placeItems: 'center',
            gap: '10px'
          }}
        >
          {sizes.map(size => (
            <div className="icon-size" key={size}>
              <Icon name="wallet" size={size} />
              <Typography fontSize="x-small" fontFamily="secondary">
                {size}
              </Typography>
            </div>
          ))}
        </div>
      )
    }}
  </Story>
</Canvas>

## Invert color

The `invertColor` property allows you to invert the themed color of the icon, by default this property is **false**.  
If set to **true**, the icon will be displayed in **white** when the light theme is selected and in **blue** when the dark theme is active.
In particular, this makes it possible to better manage high-contrast elements and thus offer the user an immersive User eXperience.

<Canvas>
  <Story name="Invert color">
    <div
      style={{
        display: 'grid',
        gridTemplateColumns: 'repeat(auto-fit, minmax(150px,150px))',
        justifyContent: 'center',
        gap: '30px'
      }}
    >
      <div className="icon-card">
        <Icon name="wallet" />
        <Typography color="text" fontSize="x-small" fontFamily="secondary">
          Current theme
        </Typography>
      </div>
      <div className="icon-card inverted">
        <Icon name="wallet" invertColor />
        <Typography color="inverted-text" fontSize="x-small" fontFamily="secondary">
          Inverse theme
        </Typography>
      </div>
    </div>
  </Story>
</Canvas>

## Class Name

The `className` property allows you to style the icon with CSS properties.  
As seen in the examples below you can rotate icons, add background colors, animate them and more!

<Canvas>
  <Story name="Class name">
    <div
      style={{
        display: 'grid',
        gridTemplateColumns: 'repeat(auto-fit, minmax(30px,auto))',
        justifyContent: 'center',
        gap: '30px'
      }}
    >
      <Icon name="add" className="rotate-add" />
      <Icon name="arrow-right" className="bg-arrow-right" />
      <Icon name="chat" className="bouncing-chat" />
    </div>
  </Story>
</Canvas>

## Prerequisites

It is mandatory to wrap the component in a `<ThemeProvider />` for the thematisation to work.
See <a href="?path=/docs/atoms-brand-identity-theming--theming">Theming</a> for more information.

##### **`app.tsx`**

```tsx
import React from 'react'
import { Icon, ThemeProvider } from '@okp4/ui'

export const App: React.FC = () => (
  <React.StrictMode>
    <ThemeProvider>
      <Icon name="profile" />
    </ThemeProvider>
  </React.StrictMode>
)
```