函数式组件 -- IconFont

函数式组件 -- IconFont

封装了一个iconFont的组件,方便之后的工作中进行使用;此组件提供了大量的接口,可以较为自由的根据业务场景进行配置。

1. 定义组件接口

接口可以大致分成几类:svg名称,样式,点击的回调,状态,状态颜色

typescript 复制代码
interface IconfontProps {
  icon: string; // svg::use的xlinkHref属性值
  style?: CSSProperties; // 覆盖样式
  onClick?: (...args: any) => void; // 点击回调
  noHover?: boolean;
  noActive?: boolean;
  disabled?: boolean;
  selected?: boolean; // 选中状态
  backgroundColor?: string;
  color?: string;
  hoveredColor?: string;
  hoveredBgColor?: string;
  activatedBgColor?: string;
}

2. 定义内部组件接口

内部接口可以大致分成几类:状态,状态颜色

typescript 复制代码
interface IconfontProps {
  noHover?: boolean; // 没有悬浮
  noActive?: boolean; // 没有激活
  disabled?: boolean; // 不可点击
  backgroundColor?: string; // 背景颜色
  color?: string; // 字体颜色
  hoveredBgColor?: string; // 悬浮背景变色
  activatedBgColor?: string; // 鼠标按下变色
  hoveredColor?: string; // 悬浮字体变色
}

3. 内部组件

使用styled-components这个js库中的styled, css实现一个css-in-js类型的内部组件Icon

typescript 复制代码
const Icon = styled.svg<IIntersectedProps>`
  width: 1em;
  height: 1em;
  vertical-align: -0.15em;
  fill: currentColor;
  fill: ${(props: IIntersectedProps) => props.color};
  background-color: ${(props: IIntersectedProps) => props.backgroundColor};
  overflow: hidden;
  font-size: 16px;
  &:hover {
    background-color: ${(props: IIntersectedProps) =>
      props.noHover ? undefined : props.hoveredBgColor};
    fill: ${(props) => (props.noHover ? undefined : props.hoveredColor)};
  }
  &:active {
    background-color: ${(props: IIntersectedProps) =>
      props.noActive ? undefined : props.activatedBgColor};
    fill: ${(props: IIntersectedProps) => (props.noActive ? undefined : props.hoveredColor)};
  }
  ${(props: IIntersectedProps) =>
    props.disabled &&
    css`
      filter: grayscale(1) opacity(0.5);
    `};
`;

4. 外部组件

外部组件的基本结构就是:svg:use

typescript 复制代码
const IconFont = (props: IconfontProps) => {
  const {
    icon,
    style,
    backgroundColor = 'rgba(255,255,255,0.1)',
    color = 'grey',
    hoveredColor = 'blue',
    hoveredBgColor ='#fff',
    activatedBgColor = true,
    onClick = ()=>{},
    noHover = true,
    noActive = true,
    disabled = false,
  } = props;
  return (
    <Icon
      style={style}
      backgroundColor={backgroundColor}
      color={color}
      hoveredColor={hoveredColor}
      hoveredBgColor={hoveredBgColor}
      activatedBgColor={activatedBgColor}
      onClick={onClick}
      noHover={noHover}
      noActive={noActive}
      disabled={disabled}
    >
      <use xlinkHref={`#${icon}`} />
    </Icon>
  );
};

5. 全部代码

自定义组件文件的所有代码如下:

typescript 复制代码
// IconFont.tsx
import React, { CSSProperties } from "react";
import styled, { css } from "styled-components";
import "@assets/icons/iconfont";

interface IconfontProps {
  icon: string; // svg::use的xlinkHref属性值
  style?: CSSProperties; // 覆盖样式
  onClick?: (...args: any) => void; // 点击回调
  noHover?: boolean;
  noActive?: boolean;
  disabled?: boolean;
  selected?: boolean; // 选中状态
  backgroundColor?: string;
  color?: string;
  hoveredColor?: string;
  hoveredBgColor?: string;
  activatedBgColor?: string;
}

interface IIntersectedProps {
  noHover?: boolean; // 没有悬浮
  noActive?: boolean; // 没有激活
  disabled?: boolean; // 不可点击
  backgroundColor?: string; // 背景颜色
  color?: string; // 字体颜色
  hoveredBgColor?: string; // 悬浮背景变色
  activatedBgColor?: string; // 鼠标按下变色
  hoveredColor?: string; // 悬浮字体变色
}

const Icon = styled.svg<IIntersectedProps>`
  width: 1em;
  height: 1em;
  vertical-align: -0.15em;
  fill: currentColor;
  fill: ${(props: IIntersectedProps) => props.color};
  background-color: ${(props: IIntersectedProps) => props.backgroundColor};
  overflow: hidden;
  font-size: 16px;
  &:hover {
    background-color: ${(props: IIntersectedProps) =>
      props.noHover ? undefined : props.hoveredBgColor};
    fill: ${(props) => (props.noHover ? undefined : props.hoveredColor)};
  }
  &:active {
    background-color: ${(props: IIntersectedProps) =>
      props.noActive ? undefined : props.activatedBgColor};
    fill: ${(props: IIntersectedProps) => (props.noActive ? undefined : props.hoveredColor)};
  }
  ${(props: IIntersectedProps) =>
    props.disabled &&
    css`
      filter: grayscale(1) opacity(0.5);
    `};
`;

export const IconFont = (props: IconfontProps) => {
  const {
    icon,
    style,
    backgroundColor = 'rgba(255,255,255,0.1)',
    color = 'grey',
    hoveredColor = 'blue',
    hoveredBgColor ='#fff',
    activatedBgColor = true,
    onClick = ()=>{},
    noHover = true,
    noActive = true,
    disabled = false,
  } = props;
  return (
    <Icon
      style={style}
      backgroundColor={backgroundColor}
      color={color}
      hoveredColor={hoveredColor}
      hoveredBgColor={hoveredBgColor}
      activatedBgColor={activatedBgColor}
      onClick={onClick}
      noHover={noHover}
      noActive={noActive}
      disabled={disabled}
    >
      <use xlinkHref={`#${icon}`} />
    </Icon>
  );
};
相关推荐
CIO_Alliance2 小时前
AI提示系列(2)| Few-shot与ReAct有何不同? 大模型工具调用的底层逻辑详解
前端·人工智能·深度学习·神经网络·react.js·前端框架·ai+ipaas
为你学会写情书4 小时前
React Hooks 完全指南:从内置 Hook 到自定义 Hook,一文彻底掌握
react.js
为你学会写情书4 小时前
React Router 完全指南:从入门到实战,一文搞懂路由核心技巧
react.js
xm_xm_xm_116 小时前
react17版本以前类组件常用操作
前端·javascript·react.js
Damai1 天前
Next.js 切换动态路由后,为什么页面还保留着上一个分类的数据?
前端·react.js
用户298698530141 天前
React 中 Word 文档转图片的实践方案
前端·javascript·react.js
专业抄代码选手1 天前
06|双缓冲与 Commit:让 Fiber 支持第二次渲染
前端·javascript·react.js
专业抄代码选手1 天前
05|把递归渲染拆成 Fiber:让一棵大树可以暂停
前端·javascript·react.js
墨白曦煜1 天前
智能体架构范式总结(React、Plan-And-Solve、Reflection)
前端·react.js·前端框架
zzzzzz3101 天前
react-bits:把动效组件库当成前端表达的参考系
react.js·开源·动效