前端 -- UI库按钮颜色自定义

前言:
部分UI库组件的Button组件无法自定义颜色,定制颜色变量又无法很好的适配点击效果和hover效果
这里以semi UI库进行举例,过程略微麻烦,看懂直接粘贴

原文地址:https://www.yuque.com/suancairiji/sqowo1/mcxec1tcdghqi30r?singleDoc# 《react – 封装UI库按钮颜色自定义算法》

GIF 2023-11-5 星期日 3-45-02.gif

核心:十六进制颜色转十进制颜色切加深颜色算法

因为我们平时使用十六进制的多一些,但是加深颜色又需要转换为十进制进行计算

/**
 * 颜色加深算法
 * @params  hexColor  十六进制颜色 #fffff
 * @params  percentage  加深值 默认0.1
 */

export function darkenColor(hexColor: string, percentage = 0.1): string {
  hexColor = hexColor.replace("#", "");

  // 拆分颜色值
  const r = parseInt(hexColor.substr(0, 2), 16);
  const g = parseInt(hexColor.substr(2, 2), 16);
  const b = parseInt(hexColor.substr(4, 2), 16);

  // 计算加深后的颜色值
  const darkenR = Math.round(r * (1 - percentage));
  const darkenG = Math.round(g * (1 - percentage));
  const darkenB = Math.round(b * (1 - percentage));

  // 返回加深后的十进制颜色代码
  return `${darkenR}, ${darkenG}, ${darkenB}`;
}

经过darkenColor方法转换处理为加深后可用的十进制rgb颜色

封装:按钮组件

有几点需要注意的bug:
1、为何要使用onMouseLeave 再次执行
答:多数UI库的Popover组件 是绑定依赖组件的真实dom后进行赋值onMouseLeave方法,会给我们的onMouseLeave方法相互抵消,所以这里判断一下是否存在onMouseLeave传入并执行
2、为何要使用forwardRef包裹
答:多数UI库的Popover组件 是依赖绑定组件的真实dom进行定位的,需要给到父组件ref才不会出现定位异常的bug

import { Button } from "@douyinfe/semi-ui";
import { ButtonProps } from "@douyinfe/semi-ui/lib/es/button";
import React, {
  useEffect,
  forwardRef,
  useState,
} from "react";
import { darkenColor } from "@/utils/useHook.ts";

type ButtonsProps = {
  background?: string;
  color?: string;
};

/**
 * 按钮组件-- 可修改颜色
 */

function Buttons(props: ButtonsProps & ButtonProps, ref: any) {
  const { background = "#fff", color = "#fff" } = props;

  const [isHover, setIsHover] = useState(false);
  const [isClick, setIsClick] = useState(false);
  const [hoverColor, setHoverColor] = useState("");
  const [clickColor, setClickColor] = useState("");

  useEffect(() => {
    initColor();
    console.log(background);
  }, []);

  //初始化按钮颜色
  const initColor = () => {
    const HoverColor = darkenColor(background, 0.05);
    const ClickColor = darkenColor(background, 0.1);
    setHoverColor(`rgb(${HoverColor})`);
    setClickColor(`rgb(${ClickColor})`);
  };

  const onMouseLeave = (
    event: React.MouseEvent<HTMLButtonElement, MouseEvent>
  ) => {
    const { onMouseLeave } = props;
    setIsHover(false);
    onMouseLeave && onMouseLeave(event);
  };
  const onMouseEnter = (
    event: React.MouseEvent<HTMLButtonElement, MouseEvent>
  ) => {
    const { onMouseEnter } = props;
    setIsHover(true);
    onMouseEnter && onMouseEnter(event);
  };

  const onMouseDown = (
    event: React.MouseEvent<HTMLButtonElement, MouseEvent>
  ) => {
    const { onMouseDown } = props;
    setIsClick(true);
    onMouseDown && onMouseDown(event);
  };

  const onMouseUp = (
    event: React.MouseEvent<HTMLButtonElement, MouseEvent>
  ) => {
    const { onMouseUp } = props;
    setIsClick(false);
    onMouseUp && onMouseUp(event);
  };

  return (
    <Button
      ref={ref}
      {...props}
      style={{
        color,
        backgroundColor: isHover ? (isClick ? clickColor : hoverColor) : background,
      }}
      onMouseLeave={onMouseLeave}
      onMouseEnter={onMouseEnter}
      onMouseDown={onMouseDown}
      onMouseUp={onMouseUp}
      >
      {props.children}
    </Button>
  );
}

export default forwardRef(Buttons);

调用组件

封装后不仅继承了原按钮组件所有的props,并且可以开心的随意修改颜色,不用一个一个单独去修改css了

<Buttons
  background="#ee5959"
  theme="solid"
  type="primary"
  >
  登 录
</Buttons>
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值