W-Design组件库:Icon组件

168 阅读1分钟

Icon组件

Icon组件是基于 react-fontawesome

安装插件

  1. @fortawesome/fontawesome-svg-core是Font Awesome 的 SVG 核心库
  2. @fortawesome/free-solid-svg-icons包含了 Font Awesome 提供的免费的实心图标集合
  3. @fortawesome/react-fontawesome@latest用于在 React 项目中以组件的形式使用 Font Awesome 图标
yarn add @fortawesome/fontawesome-svg-core
yarn add @fortawesome/free-solid-svg-icons
yarn add @fortawesome/react-fontawesome@latest

组件效果

支持不同主题

image.png

组件结构

src/components/Icon/icon.tsx

  1. library.add(fas)是添加所有图标
  2. 根据theme动态生成主题样式
  3. 使用FontAwesomeIcon组件渲染Icon
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import classNames from 'classnames'
import { FC } from 'react'
import { fas } from '@fortawesome/free-solid-svg-icons'
import { library } from '@fortawesome/fontawesome-svg-core'
import { IconProps } from './types'

library.add(fas)

export const Icon: FC<IconProps> = (props) => {
  const { theme, className, ...restProps } = props

  const clsses = classNames('w-design-icon', className, {
    [`icon-${theme}`]: theme,
  })

  return <FontAwesomeIcon className={clsses} {...restProps} />
}

组件类型

src/components/Icon/types.ts

import { FontAwesomeIconProps } from '@fortawesome/react-fontawesome'

export type ThemeProps =
  | 'primary'
  | 'secondary'
  | 'success'
  | 'info'
  | 'warning'
  | 'danger'
  | 'light'
  | 'dark'

export interface IconProps extends FontAwesomeIconProps {
  theme?: ThemeProps
}

组件样式

src/components/Icon/_style.scss
@each是预处理器中的一个迭代器指令,用于在样式表中迭代处理一个列表或映射

@each $key, $val in $theme-colors {
  .icon-#{$key} {
    color: $val
  }
}

src/styles/_variables.scss

$theme-colors: (
  "primary": $primary,
  "secondary": $secondary,
  "success": $success,
  "info": $info,
  "warning": $warning,
  "danger": $danger,
  "light": $light,
  "dark": $dark
);

Transition组件

Transition组件是基于react-transition-group

yarn add react-transition-group
yarn add @types/react-transition-group

组件结构

src/components/Transition/transition.tsx

  1. unmountOnExit: true过渡结束后将组件从 DOM 中卸载,默认是false过渡结束后组件仍然保留在 DOM 中
  2. appear: true在组件的初始渲染时也会应用过渡效果
  3. CSSTransition通过添加和移除 CSS 类名来触发过渡动画
import { FC } from 'react'
import { TransitionProps } from './types'
import { CSSTransition } from 'react-transition-group'

export const Transition: FC<TransitionProps> = (props) => {
  const { children, classNames, animation, wrapper, ...restProps } = props

  return (
    <CSSTransition
      classNames={classNames ? classNames : animation}
      {...restProps}
    >
      {wrapper ? <>{children}</> : children}
    </CSSTransition>
  )
}

Transition.defaultProps = {
  unmountOnExit: true,
  appear: true,
}

组件类型

src/components/Transition/types.ts

import { CSSTransitionProps } from 'react-transition-group/CSSTransition'

export type AnimationName =
  | 'zoom-in-top'
  | 'zoom-in-left'
  | 'zoom-in-bottom'
  | 'zoom-in-right'

export type TransitionProps = CSSTransitionProps & {
  animation?: AnimationName
  wrapper?: boolean
}

组件样式

src/styles/_animation.scss

@include zoom-animation('top', scaleY(0), scaleY(1), center top);
@include zoom-animation('left', scale(.45, .45), scale(1, 1), top left);
@include zoom-animation('right', scale(.45, .45), scale(1, 1), top right);
@include zoom-animation('bottom', scaleY(0), scaleY(1), center bottom);

src/styles/_mixin.scss
控制过渡方向、过渡状态公共mixin

@mixin zoom-animation(
  // 从哪个方向的过渡效果
  $direction: 'top',
  // 缩放开始时的scale值
  $scaleStart: scaleY(0),
  // 缩放结束时的scale值
  $scaleEnd: scaleY(1),
  // 缩放起始时的origin值
  $origin: center top
) {
  // 开始进入
  .zoom-in-#{$direction}-enter {
    opacity: 0;
    transform: $scaleStart;
  }

  // 正在进入
  .zoom-in-#{$direction}-enter-active {
    // 设置透明度为1
    opacity: 1;
    // 设置缩放结束状态
    transform: $scaleEnd;
    // transform 属性:在 300 毫秒内完成变化,使用 cubic-bezier(0.23, 1, 0.32, 1) 时间曲线,初始延迟 100 毫秒。
    transition: transform 300ms cubic-bezier(0.23, 1, 0.32, 1) 100ms,
      // opacity 属性:在 300 毫秒内完成变化,使用 cubic-bezier(0.23, 1, 0.32, 1) 时间曲线,初始延迟 100 毫秒。
      opacity 300ms cubic-bezier(0.23, 1, 0.32, 1) 100ms;
    // 设置缩放原点
    transform-origin: $origin;
  }

  // 设置退出时的透明度为1
  .zoom-in-#{$direction}-exit {
    opacity: 1;
  }

  // 正在离开
  .zoom-in-#{$direction}-exit-active {
    // 设置透明度为0
    opacity: 0;
    // 设置缩放起始状态
    transform: $scaleStart;
    // transform 属性:在 300 毫秒内完成变化,使用 cubic-bezier(0.23, 1, 0.32, 1) 时间曲线,初始延迟 100 毫秒。
    transition: transform 300ms cubic-bezier(0.23, 1, 0.32, 1) 100ms,
      // opacity 属性:在 300 毫秒内完成变化,使用 cubic-bezier(0.23, 1, 0.32, 1) 时间曲线,初始延迟 100 毫秒。
      opacity 300ms cubic-bezier(0.23, 1, 0.32, 1) 100ms;
    // 设置缩放原点
    transform-origin: $origin;
  }
}