1. 程式人生 > 實用技巧 >用storybook開發一個自己的圖示庫繼續【可複製圖示程式碼,可搜尋,可切換圖示型別】

用storybook開發一個自己的圖示庫繼續【可複製圖示程式碼,可搜尋,可切換圖示型別】

效果:

需求:顯示所有的圖示(現在是我寫的mock資料),可以切換圖示型別,可以進行關鍵詞搜尋

程式碼:

import React from 'react';
import copy from 'copy-to-clipboard';
import SvgOaIconAddressDefault from '../assets/OaIconAddressDefault';
// import { SvgIcon, SvgIconProps } from '@vvwork/atoms';

const Add = () => {
  // mock list
  const list = [
    {
      name: 'SvgOaIconAddressDefault1',
      component: <SvgOaIconAddressDefault />,
      type: 'Filled',
    },
    {
      name: 'SvgOaIconAddressDefault2',
      component: <SvgOaIconAddressDefault />,
      type: 'Filled',
    },
    {
      name: 'SvgOaIconAddressDefault3',
      component: <SvgOaIconAddressDefault />,
      type: 'Filled',
    },
    {
      name: 'SvgOaIconAddressDefault4',
      component: <SvgOaIconAddressDefault />,
      type: 'Rounded',
    },
    {
      name: 'SvgOaIconAddressDefault5',
      component: <SvgOaIconAddressDefault />,
      type: 'Rounded',
    },
    {
      name: 'SvgOaIconAddressDefault6',
      component: <SvgOaIconAddressDefault />,
      type: 'TwoTone',
    },
    {
      name: 'SvgOaIconAddressDefault7',
      component: <SvgOaIconAddressDefault />,
      type: 'TwoTone',
    },

    {
      name: 'SvgOaIconAddressDefault8',
      component: <SvgOaIconAddressDefault />,
      type: 'Sharp',
    },
    {
      name: 'SvgOaIconAddressDefault9',
      component: <SvgOaIconAddressDefault />,
      type: 'Sharp',
    },
    {
      name: 'SvgOaIconAddressDefault11',
      component: <SvgOaIconAddressDefault />,
      type: 'Outlined',
    },
    {
      name: 'SvgOaIconAddressDefault12',
      component: <SvgOaIconAddressDefault />,
      type: 'Outlined',
    },
    {
      name: 'SvgOaIconAddressDefault13',
      component: <SvgOaIconAddressDefault />,
      type: 'Sharp',
    },
  ];
  const iconType = [
    { title: '所有型別', type: '' },
    { title: '填充型【Filled】', type: 'Filled' },
    { title: '線型【Outlined】', type: 'Outlined' },
    { title: '圓角型【Rounded】', type: 'Rounded' },
    { title: '尖角型【Sharp】', type: 'Sharp' },
    { title: '雙色調型【Two tone】', type: 'TwoTone' },
  ];
  // 監聽滑鼠移入移出
  const [hover, setHover] = React.useState(false);
  const [hoverItem, setHoverItem] = React.useState(-1);
  // 監聽選擇的圖示型別
  const [type, setType] = React.useState('');
  // 監聽搜尋想要的圖示
  // const [search, setSearch] = React.useState('');

  // 顯示的圖示
  const [iconList, setIconList] = React.useState(list || []);

  // 切換滑鼠移入移出效果
  const toggleHover = (index: number) => {
    setHoverItem(index);
    setHover(!hover);
  };
  // 點選複製程式碼
  const handleCopy = (name: string) => {
    const copyContent = `import ${name} from '../assets/${name}';`;
    copy(copyContent);
  };
  // 點選切換圖示型別,顯示對應資料
  const handleChangeType = (type: string) => {
    setType(type);
    if (type === '') {
      setIconList(list);
    } else {
      setIconList(list.filter(item => item.type === type));
    }
  };
  // 觸發關鍵詞搜尋
  const handleSearch = (value: string) => {
    setIconList(list.filter(item => item.name.indexOf(value) !== -1));
  };

  return (
    <div>
      <h2>圖示庫</h2>
      <div style={{ margin: '16px 0' }}>
        <span>搜尋您想要的圖示: </span>
        <input
          type="text"
          onChange={e => {
            handleSearch(e.target.value);
          }}
        />
      </div>
      <div>
        <span>圖示分類: </span>
        {iconType &&
          iconType.map(item => (
            <button
              key={item.type}
              onClick={() => {
                handleChangeType(item.type);
              }}
              style={{
                margin: '8px',
                padding: '4px 8px',
                cursor: 'pointer',
                background: type === item.type ? '#1EA7FD' : '#fff',
              }}
            >
              {item.title}
            </button>
          ))}
      </div>
      <div style={{ display: 'flex', flexWrap: 'wrap', margin: '16px 0' }}>
        {iconList &&
          iconList.map((item, index) => (
            <div
              key={item.name}
              onClick={() => {
                handleCopy(item.name);
              }}
              style={{
                width: '220px',
                textAlign: 'center',
                margin: '8px',
                padding: '16px',
                border: '1px solid #eee',
                boxShadow: hover && hoverItem === index ? '5px 5px 10px #eee' : 'none',
                cursor: 'pointer',
                animation: '0.4s linear',
              }}
              onMouseEnter={() => {
                toggleHover(index);
              }}
              onMouseLeave={() => {
                toggleHover(index);
              }}
              title="點選複製程式碼"
            >
              {item.component}
              <p>{item.name}</p>
            </div>
          ))}
      </div>
    </div>
  );
};
export default Add;

  

README.md的內容:

# 圖示

Web IM 圖示庫

## 圖示分類

| Name     | Type        | Description |
| :------- | :---------- | :---------- |
| Filled   | components  | 填充型      |
| Outlined | components  | 線型        |
| Rounded  | components  | 圓角型      |
| Sharp    | [components | 尖角型      |
| Two tone | components  | 雙色調型    |

### 基礎 API

左鍵點選圖示可以複製引入程式碼

例如:

`import SvgOaIconAddressDefault from '../assets/SvgOaIconAddressDefault';`

使用:

`<SvgOaIconAddressDefault />`