React-Hook 轮子公开课(从零开始)用最基础的方式写出一个简单的组件库——第二课【Button】组件

RN组件库 - Button 组件 从零构建 React Native 组件库,作为一个前端er 谁不想拥有一个自己的组件库 阅读详情

一、组件库介绍

有兴趣的同学 可以先着手看源码,之前写的一系列开源组件库项目(有帮助的同学也帮忙点个star👍)

名称官网github
tinkerbell-ui(vue2.0)http://tinkerbell.tophttps://github.com/hanbingxu82/tinkerbell-ui
tinkerbell-ui(vue3.0)—https://github.com/hanbingxu82/tinkerbell-ui-next
tinkerbell-ui(react-hook)—https://github.com/hanbingxu82/tinkerbell-ui-react

二、Button组件流程介绍

提到 button 组件,这几乎可以说是一个组件库中的重中之重,基本上很多的时候我们都需要用到 button 来进行一系列的 dom 操作,时间执行,用户与浏览器之间进行交互不免得就少不了 button 按钮,那么我们先捋清楚一个思路这个 button 该怎么去写?

1、通用的事件行为是要有的,因为我们是自定义的组件,所以我们要考虑的一个问题,因为我们不能把所有的事件 都用 例如 props.onClick && props.onClick(evt) 这种方式去触发,所以我们去一个简单的方法直接解构所有的 props 传值,让其都放置在 我们的内置<button …restprop> 这种方式去进行一个子组件触发父组件行为,或者父组件传递子组件style这种。

2、因为我们上节课讲解了图标,那么这节课我们也把图标放置在 button 组件中,至于应用场景的话,我们可以放置静态图标或者放置一个动态的加载效果 这些我们都放置到对应的 button 组件中进行一个封装

3、默认常规的事件行为、属性控制等,我们也都加入到我们的 Button组件当中去
type = ‘default’, // 样式类型
icon = ‘’, // 图标样式
iconStyle, // icon 图标style
disabled, // 禁用效果
loading, // loading 加载效果
nativeType = ‘button’, // button 原生属性的type类型
size = ‘default’, // size 大小效果
plain, // 镂空 style 效果
round, // 圆角 style 效果
dashed, // 虚线 style 效果
transparent, // 是否为透明按钮
background, // 默认按钮是否带有拟物背景
loadingIcon, // 加载效果图标样式
textColor, // 文本颜色
…restprop //其余所有传递给 原生 button 的方法 属性

三、代码详解

3.1、index.tsx

// eslint-disable-next-line
import React from 'react'
import Icon from '../Icon'
import './index.scss'
var tinycolor = require('tinycolor2') // 颜色转换插件
const classnames = require('classnames') // classname 转换插件

// interface接口
interface Iprops {
  type: string
  disabled: boolean
  loading: boolean
  nativeType: any
  size: string
  plain: boolean
  round: boolean
  dashed: boolean
  transparent: boolean
  background: boolean
  loadingIcon: string
  iconStyle: any
  icon: string
  textColor: string
}

const Button = (props: any) => {
  const {
    type = 'default', // 样式类型
    icon = '', // 图标样式
    iconStyle, // icon 图标style
    disabled, // 禁用效果
    loading, // loading 加载效果
    nativeType = 'button', // button 原生属性的type类型
    size = 'default', // size 大小效果
    plain, // 镂空 style 效果
    round, // 圆角 style 效果
    dashed, // 虚线 style 效果
    transparent, // 是否为透明按钮
    background, // 默认按钮是否带有拟物背景
    loadingIcon, // 加载效果图标样式
    textColor, // 文本颜色
    ...restprop //其余所有传递给 原生 button 的方法 属性
  }: Iprops = props

  // icon图标style
  function iconStyles() {
    return {
      ...textStyle(),
      ...iconStyle
    }
  }
  // 默认 文本样式给与的颜色
  function colorMap() {
    return {
      primary: '#1089ff',
      success: '#52c41a',
      info: '#35495E',
      warning: '#fea638',
      danger: '#ff4d4f'
    }
  }
  // 点击事件触发父行为
  function handleClick(evt: any) {
    props.onClick && props.onClick(evt)
  }
  // 鼠标进入触发父行为
  function handMouseEnter(evt: any) {
    props.onMouseEnter && props.onMouseEnter(evt)
  }
  // 鼠标离开触发父行为
  function handMouseLeave(evt: any) {
    props.onMouseLeave && props.onMouseLeave(evt)
  }
  // 触发获取焦点事件
  function handFocus(evt: any) {
    props.onFocus && props.onFocus(evt)
  }
  // text 文本颜色
  function textStyle() {
    let color = textColor
      ? colorMap()[textColor]
        ? colorMap()[textColor]
        : textColor
      : null
    if (color) {
      return {
        color: disabled ? tinycolor(color).lighten(15).toString() : color
      }
    }
    return {}
  }
  // 判断传递的组件是否为 文本 按钮 如果不是
  if (type !== 'text') {
    return (
      <button
        {...restprop}
        onClick={handleClick}
        onMouseEnter={handMouseEnter}
        onMouseLeave={handMouseLeave}
        onFocus={handFocus}
        disabled={disabled || loading}
        type={nativeType}
        className={
          [
            'tb-button',
            'tb-button--' + type,
            'tb-button--' + size,
            classnames({
              'is-disabled': disabled,
              'is-loading': loading,
              'is-plain': plain,
              'is-round': round,
              'is-dashed': dashed,
              'is-transparent': transparent,
              'is-background': background
            })
          ].join(' ') +
          ' ' +
          props.className
        }
      >
        {/* 判断有没有loading加载 */}
        {loading && (
          <span className={'btn-icon-loading'}>
            <Icon
              className='button-loading icon-is-rotating'
              name={loadingIcon ? loadingIcon : 'icon-loading'}
              style={iconStyles()}
            />
          </span>
        )}
        {/* 判断有没有静态图标 */}
        {icon && !loading && (
          <i className={['iconfont', icon].join(' ')} style={iconStyles()}></i>
        )}
        {props.children && <span style={textStyle()}>{props.children}</span>}
      </button>
    )
  } else {
    // 如果是文本按钮
    return (
      <button
        {...restprop}
        onClick={handleClick}
        onMouseEnter={handMouseEnter}
        onMouseLeave={handMouseLeave}
        onFocus={handFocus}
        disabled={disabled || loading}
        type={nativeType}
        className={
          [
            'tb-button',
            'tb-button--' + type,
            classnames({ 'is-disabled': disabled, 'is-loading': loading })
          ].join(' ') +
          ' ' +
          props.className
        }
      >
        {/* 判断图标 在这里就没必要给加载判断了 */}
        {icon && !loading && (
          <i className={['iconfont', icon].join(' ')} style={iconStyles()}></i>
        )}
        {props.children && <span style={textStyle()}>{props.children}</span>}
      </button>
    )
  }
}
export default Button

3.2、index.scss

@import '../../style/variables.scss';

.tb-button {
  position: relative;
  display: inline-block;
  vertical-align: middle;
  height: $default-height;
  line-height: $default-height - 2;
  white-space: nowrap;
  cursor: pointer;
  background: $color-white;
  border: $border-base;
  color: $color-text-default;
  -webkit-appearance: none;
  text-align: center;
  box-sizing: border-box;
  outline: none;
  margin: 0;
  transition: $animation-duration-base;
  user-select: none;
  padding: 0 15px;
  font-size: $base-font-size;
  border-radius: $border-base-radius;

  .iconfont {
    vertical-align: -1px;

    +span {
      margin-left: 4px;
    }
  }

  &-loading {
    font-size: 14px;
    margin-right: 5px;
  }

  &:hover,
  &:focus {
    color: $color-primary;
    border-color: $color-primary;
  }

  &:active {
    color: $color-primary-active;
    border-color: $color-primary-active;
  }

  &.is-round {
    border-radius: 20px;
  }

  &.is-transparent {
    background: transparent;
    border-color: #fff;
    color: #fff;

    &:hover {
      color: $color-primary;
      border-color: $color-primary;
    }

    &:active {
      color: $color-primary-active;
      border-color: $color-primary-active;
    }

    &.is-disabled,
    &.is-disabled:focus,
    &.is-disabled:hover {
      background: transparent;
      cursor: not-allowed;
      color: #fff;
    }
  }

  &.is-dashed {
    &:hover {
      color: $color-primary;
      border-color: $color-primary;
    }

    &:active {
      color: $color-primary-active;
      border-color: $color-primary-active;
    }
  }

  &.is-background {
    background-image: -webkit-gradient(linear, left bottom, left top, from(#f5f5f5), to(#fff));
    background-image: linear-gradient(0deg, #f5f5f5, #fff);

    &.is-disabled,
    &.is-disabled:focus,
    &.is-disabled:hover {
      color: #c0c4cc;
      cursor: not-allowed;
      background-image: none;
      background: #f5f5f5;
      border-color: #d9d9d9;
    }
  }

  &.is-loading {
    pointer-events: none;
  }

  &.is-disabled,
  &.is-disabled:focus,
  &.is-disabled:hover {
    color: #c0c4cc;
    cursor: not-allowed;
    background-image: none;
    background-color: #fff;
    border-color: #ebeef5;
  }
}

.tb-button--large {
  height: $large-height;
  line-height: $large-height - 2;
  padding: 0 14px;
  font-size: $header-font-size;

  &.is-round {
    padding: 0 14px;
  }
}

.tb-button--small {
  height: $small-height;
  line-height: $small-height - 2;
  padding: 0 11px;

  &.is-round {
    padding: 0 11px;
  }
}

.tb-button--mini {
  height: $mini-height;
  line-height: $mini-height - 2;
  padding: 0 7px;

  &.is-round {
    padding: 0 10px;
  }
}

.tb-button--primary {
  color: $color-white;
  background-color: $color-primary;
  border-color: $color-primary;
  background-image: none;

  &:hover,
  &:focus {
    background: $color-primary-light1;
    border-color: $color-primary-light1;
    color: #fff;
  }

  &:active {
    background: $color-primary-active;
    border-color: $color-primary-active;
  }

  &.is-transparent {
    border-color: $color-primary;
    color: $color-primary;
    background-color: transparent;

    &:hover {
      border-color: $color-primary-light1;
      color: $color-primary;
      background-color: rgba(245, 249, 254, .5);
    }

    &:active {
      color: $color-primary-active;
      border-color: $color-primary-active;
    }

    &.is-disabled,
    &.is-disabled:focus,
    &.is-disabled:hover {
      border-color: $color-primary-light2;
      color: $color-primary-light2;
    }
  }

  &.is-plain {
    color: $color-primary;
    background: $color-primary-light5;
    border-color: $color-primary-light3;

    &:hover,
    &:focus {
      border-color: $color-primary-light2;
    }

    &:active {
      color: $color-primary-active;
      border-color: $color-primary-active;
    }

    &.is-disabled,
    &.is-disabled:focus,
    &.is-disabled:hover {
      cursor: not-allowed;
      color: $color-primary-light2;
      background-color: $color-primary-light5;
      border-color: $color-primary-light3;
    }
  }

  &.is-dashed {
    background: $color-white;
    color: $color-primary;

    &:hover {
      border-color: $color-primary-light1;
      color: $color-primary;
      background-color: rgba(245, 249, 254, .5);
    }

    &:active {
      color: $color-primary-active;
      border-color: $color-primary-active;
    }

    &.is-disabled,
    &.is-disabled:focus,
    &.is-disabled:hover,
    &.is-loading {
      cursor: not-allowed;
      background: $color-white;
      color: $color-primary-light2;
    }
  }

  &.is-disabled,
  &.is-disabled:focus,
  &.is-disabled:hover,
  &.is-loading {
    cursor: not-allowed;
    color: $color-white;
    background-color: $color-primary-light2;
    border-color: $color-primary-light2;
  }
}

.tb-button--success {
  color: #fff;
  background-color: $color-success;
  border-color: $color-success;
  background-image: none;

  &:hover,
  &:focus {
    background: $color-success-light1;
    border-color: $color-success-light1;
    color: #fff;
  }

  &:active {
    background: $color-success-active;
    border-color: $color-success-active;
  }

  &.is-transparent {
    border-color: $color-success;
    color: $color-success;
    background-color: transparent;

    &:hover {
      border-color: $color-success-light1;
      color: $color-success;
      background-color: rgba(245, 249, 254, .5);
    }

    &:active {
      color: $color-success-active;
      border-color: $color-success-active;
    }

    &.is-disabled,
    &.is-disabled:focus,
    &.is-disabled:hover {
      border-color: $color-success-light2;
      color: $color-success-light2;
    }
  }

  &.is-plain {
    color: $color-success;
    background: $color-success-light5;
    border-color: $color-success-light3;

    &:hover,
    &:focus {
      border-color: $color-success-light2;
    }

    &:active {
      color: $color-success-active;
      border-color: $color-success-active;
    }

    &.is-disabled,
    &.is-disabled:focus,
    &.is-disabled:hover {
      cursor: not-allowed;
      color: $color-success-light2;
      background-color: $color-success-light5;
      border-color: $color-success-light3;
    }
  }

  &.is-dashed {
    background: $color-white;
    color: $color-success;

    &:hover {
      border-color: $color-success-light1;
      color: $color-success;
      background-color: rgba(245, 249, 254, .5);
    }

    &:active {
      color: $color-success-active;
      border-color: $color-success-active;
    }

    &.is-disabled,
    &.is-disabled:focus,
    &.is-disabled:hover,
    &.is-loading {
      cursor: not-allowed;
      background: $color-white;
      color: $color-success-light2;
    }
  }

  &.is-disabled,
  &.is-disabled:focus,
  &.is-disabled:hover,
  &.is-loading {
    cursor: not-allowed;
    color: $color-white;
    background-color: $color-success-light2;
    border-color: $color-success-light2;
  }
}

.tb-button--info {
  color: #fff;
  background-color: $color-info;
  border-color: $color-info;
  background-image: none;

  &:hover,
  &:focus {
    background: $color-info-light1;
    border-color: $color-info-light1;
    color: #fff;
  }

  &:active {
    background: $color-info-active;
    border-color: $color-info-active;
  }

  &.is-transparent {
    border-color: $color-info;
    color: $color-info;
    background-color: transparent;

    &:hover {
      border-color: $color-info-light1;
      color: $color-info;
      background-color: rgba(245, 249, 254, .5);
    }

    &:active {
      color: $color-info-active;
      border-color: $color-info-active;
    }

    &.is-disabled,
    &.is-disabled:focus,
    &.is-disabled:hover {
      border-color: $color-info-light2;
      color: $color-info-light2;
    }
  }

  &.is-plain {
    color: $color-info;
    background: $color-info-light5;
    border-color: $color-info-light3;

    &:hover,
    &:focus {
      border-color: $color-info-light2;
    }

    &:active {
      color: $color-info-active;
      border-color: $color-info-active;
    }

    &.is-disabled,
    &.is-disabled:focus,
    &.is-disabled:hover {
      cursor: not-allowed;
      color: $color-info-light2;
      background-color: $color-info-light5;
      border-color: $color-info-light3;
    }
  }

  &.is-dashed {
    background: $color-white;
    color: $color-info;

    &:hover {
      border-color: $color-info-light1;
      color: $color-info;
      background-color: rgba(245, 249, 254, .5);
    }

    &:active {
      color: $color-info-active;
      border-color: $color-info-active;
    }

    &.is-disabled,
    &.is-disabled:focus,
    &.is-disabled:hover,
    &.is-loading {
      cursor: not-allowed;
      background: $color-white;
      color: $color-info-light2;
    }
  }

  &.is-disabled,
  &.is-disabled:focus,
  &.is-disabled:hover,
  &.is-loading {
    cursor: not-allowed;
    color: $color-white;
    background-color: $color-info-light2;
    border-color: $color-info-light2;
  }
}

.tb-button--warning {
  color: #fff;
  background-color: $color-warning;
  border-color: $color-warning;
  background-image: none;

  &:hover,
  &:focus {
    background: $color-warning-light1;
    border-color: $color-warning-light1;
    color: #fff;
  }

  &:active {
    background: $color-warning-active;
    border-color: $color-warning-active;
  }

  &.is-transparent {
    border-color: $color-warning;
    color: $color-warning;
    background-color: transparent;

    &:hover {
      border-color: $color-warning-light1;
      color: $color-warning;
      background-color: rgba(245, 249, 254, .5);
    }

    &:active {
      color: $color-warning-active;
      border-color: $color-warning-active;
    }

    &.is-disabled,
    &.is-disabled:focus,
    &.is-disabled:hover {
      border-color: $color-warning-light2;
      color: $color-warning-light2;
    }
  }

  &.is-plain {
    color: $color-warning;
    background: $color-warning-light5;
    border-color: $color-warning-light3;

    &:hover,
    &:focus {
      border-color: $color-warning-light2;
    }

    &:active {
      color: $color-warning-active;
      border-color: $color-warning-active;
    }

    &.is-disabled,
    &.is-disabled:focus,
    &.is-disabled:hover {
      cursor: not-allowed;
      color: $color-warning-light2;
      background-color: $color-warning-light5;
      border-color: $color-warning-light3;
    }
  }

  &.is-dashed {
    background: $color-white;
    color: $color-warning;

    &:hover {
      border-color: $color-warning-light1;
      color: $color-warning;
      background-color: rgba(245, 249, 254, .5);
    }

    &:active {
      color: $color-warning-active;
      border-color: $color-warning-active;
    }

    &.is-disabled,
    &.is-disabled:focus,
    &.is-disabled:hover,
    &.is-loading {
      cursor: not-allowed;
      background: $color-white;
      color: $color-warning-light2;
    }
  }

  &.is-disabled,
  &.is-disabled:focus,
  &.is-disabled:hover,
  &.is-loading {
    cursor: not-allowed;
    color: $color-white;
    background-color: $color-warning-light2;
    border-color: $color-warning-light2;
  }
}

.tb-button--danger {
  color: #fff;
  background-color: $color-danger;
  border-color: $color-danger;
  background-image: none;

  &:hover,
  &:focus {
    background: $color-danger-light1;
    border-color: $color-danger-light1;
    color: #fff;
  }

  &:active {
    background: $color-danger-active;
    border-color: $color-danger-active;
  }

  &.is-transparent {
    border-color: $color-danger;
    color: $color-danger;
    background-color: transparent;

    &:hover {
      border-color: $color-danger-light1;
      color: $color-danger;
      background-color: rgba(245, 249, 254, .5);
    }

    &:active {
      color: $color-danger-active;
      border-color: $color-danger-active;
    }

    &.is-disabled,
    &.is-disabled:focus,
    &.is-disabled:hover {
      border-color: $color-danger-light2;
      color: $color-danger-light2;
    }
  }

  &.is-plain {
    color: $color-danger;
    background: $color-danger-light5;
    border-color: $color-danger-light3;

    &:hover,
    &:focus {
      border-color: $color-danger-light2;
    }

    &:active {
      color: $color-danger-active;
      border-color: $color-danger-active;
    }

    &.is-disabled,
    &.is-disabled:focus,
    &.is-disabled:hover {
      cursor: not-allowed;
      color: $color-danger-light2;
      background-color: $color-danger-light5;
      border-color: $color-danger-light3;
    }
  }

  &.is-dashed {
    background: $color-white;
    color: $color-danger;

    &:hover {
      border-color: $color-danger-light1;
      color: $color-danger;
      background-color: rgba(245, 249, 254, .5);
    }

    &:active {
      color: $color-danger-active;
      border-color: $color-danger-active;
    }

    &.is-disabled,
    &.is-disabled:focus,
    &.is-disabled:hover,
    &.is-loading {
      cursor: not-allowed;
      background: $color-white;
      color: $color-danger-light2;
    }
  }

  &.is-disabled,
  &.is-disabled:focus,
  &.is-disabled:hover,
  &.is-loading {
    cursor: not-allowed;
    color: $color-white;
    background-color: $color-danger-light2;
    border-color: $color-danger-light2;
  }
}

.tb-button--text {
  border-color: transparent;
  color: $color-primary;
  background: transparent;
  background-image: none;
  padding: 0;
  height: auto;
  line-height: inherit;

  &:focus,
  &:hover {
    color: $color-primary-light1;
    border-color: transparent;
    background-color: transparent;
    box-shadow: none;
  }

  &:active {
    color: $color-primary-active;
  }

  &.is-disabled,
  &.is-disabled:focus,
  &.is-disabled:hover {
    cursor: not-allowed;
    background-color: transparent;
    border-color: transparent;
    color: $color-primary-light3;
  }
}

.tb-button--dashed,
.is-dashed {
  border-style: dashed;
}

//  button-group
.tb-button-group {
  display: inline-block;
  vertical-align: middle;

  &>.tb-button {
    float: left;
    position: relative;
  }

  .tb-button {
    z-index: 0;

    &:hover {
      z-index: 1;
    }

    &:active {
      z-index: 1;
      outline: none;
    }
  }

  .tb-button+.tb-button {
    margin-left: -1px;
  }

  &>.tb-button:first-child {
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
  }

  &>.tb-button:last-child {
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
  }

  &>.tb-button:not(:first-child):not(:last-child) {
    border-radius: 0;
  }

  .tb-button--primary:first-child,
  .tb-button--info:first-child,
  .tb-button--success:first-child,
  .tb-button--warning:first-child,
  .tb-button--danger:first-child {
    border-right-color: hsla(0, 0%, 100%, .5);
  }

  .tb-button--primary:last-child .tb-button--info:last-child,
  .tb-button--success:last-child,
  .tb-button--warning:last-child,
  .tb-button--danger:last-child {
    border-left-color: hsla(0, 0%, 100%, .5);
  }

  .tb-button--primary:not(:first-child):not(:last-child),
  .tb-button--info:not(:first-child):not(:last-child),
  .tb-button--success:not(:first-child):not(:last-child),
  .tb-button--warning:not(:first-child):not(:last-child),
  .tb-button--danger:not(:first-child):not(:last-child) {
    border-left-color: hsla(0, 0%, 100%, .5);
    border-right-color: hsla(0, 0%, 100%, .5);
  }
}

.tb-button+.tb-button {
  margin-left: 8px;
}



@keyframes rotating {
  from {
    transform: rotate(0)
  }

  to {
    transform: rotate(360deg)
  }
}

.btn-icon-loading {
  display: inline-block;
  animation: rotating 2s linear infinite
}

3.3、variables.scss(这里的文本样式是参考的 bin-ui )

// $font-path : './fonts'

/* Color
-------------------------- */
$color-white : #FFFFFF;
$color-white-light : rgba(255, 255, 255, 0.65);
$color-white-light2 : rgba(255, 255, 255, 0.35);

$color-primary : #1089ff;
$color-primary-light1 : mix(#FFFFFF, $color-primary, 20%);
$color-primary-light2 : mix(#FFFFFF, $color-primary, 40%);
$color-primary-light3 : mix(#FFFFFF, $color-primary, 60%);
$color-primary-light4 : mix(#FFFFFF, $color-primary, 80%);
$color-primary-light5 : mix(#FFFFFF, $color-primary, 90%);
$color-primary-light6 : mix(#FFFFFF, $color-primary, 95%);
$color-primary-active : mix(#000000, $color-primary, 10%);

$color-success :#52c41a;
$color-success-light1 : mix(#FFFFFF, $color-success, 20%);
$color-success-light2 : mix(#FFFFFF, $color-success, 40%);
$color-success-light3 : mix(#FFFFFF, $color-success, 60%);
$color-success-light4 : mix(#FFFFFF, $color-success, 80%);
$color-success-light5 : mix(#FFFFFF, $color-success, 90%);
$color-success-light6 : mix(#FFFFFF, $color-success, 95%);
$color-success-active : mix(#000000, $color-success, 10%);

$color-info : #35495E;
$color-info-light1 : mix(#FFFFFF, $color-info, 20%);
$color-info-light2 : mix(#FFFFFF, $color-info, 40%);
$color-info-light3 : mix(#FFFFFF, $color-info, 60%);
$color-info-light4 : mix(#FFFFFF, $color-info, 80%);
$color-info-light5 : mix(#FFFFFF, $color-info, 90%);
$color-info-light6 : mix(#FFFFFF, $color-info, 95%);
$color-info-active : mix(#000000, $color-info, 10%);

$color-warning : #fea638;
$color-warning-light1 : mix(#FFFFFF, $color-warning, 20%);
$color-warning-light2 : mix(#FFFFFF, $color-warning, 40%);
$color-warning-light3 : mix(#FFFFFF, $color-warning, 60%);
$color-warning-light4 : mix(#FFFFFF, $color-warning, 80%);
$color-warning-light5 : mix(#FFFFFF, $color-warning, 90%);
$color-warning-light6 : mix(#FFFFFF, $color-warning, 95%);
$color-warning-active : mix(#000000, $color-warning, 10%);

$color-danger : #ff4d4f;
$color-danger-light1 : mix(#FFFFFF, $color-danger, 20%);
$color-danger-light2 : mix(#FFFFFF, $color-danger, 40%);
$color-danger-light3 : mix(#FFFFFF, $color-danger, 60%);
$color-danger-light4 : mix(#FFFFFF, $color-danger, 80%);
$color-danger-light5 : mix(#FFFFFF, $color-danger, 90%);
$color-danger-light6 : mix(#FFFFFF, $color-danger, 95%);
$color-danger-active : mix(#000000, $color-danger, 10%);

/* text-color
-------------------------- */
$color-text-primary : rgba(0, 0, 0, .85);
$color-text-default : rgba(0, 0, 0, .65);
$color-text-secondary : rgba(0, 0, 0, .45);
$color-text-disabled : rgba(0, 0, 0, .25);
$color-text-placeholder : #C0C4CC;
$btn-disable-color : #c5c8ce;
$color-disabled-bg:rgb(245, 245, 245);
$color-disabled-border:rgb(217, 217, 217);

/* bg-color
-------------------------- */
$color-bg-fa : #fafafa;
$color-select-hover : #f5f5f5;
$color-effect-shadow : alpha($color-primary);
$color-input-shadow : alpha($color-primary);
$color-input-error-shadow : alpha($color-danger);

/* border
-------------------------- */
$border-color-base : #d9d9d9;
$border-color-light : #f0f0f0;
$border-base : 1px solid $border-color-base;
$border-width:1px;
$border-base-light : 1px solid $border-color-light;
$border-table : 1px solid #e8eaec;
$border-table-color : #e8eaec;

/* radius font-size
-------------------------- */
$border-base-radius : 2px;
$base-font-size : 14px;
$header-font-size : 16px;

/* height
-------------------------- */
$large-height : 36px;
$default-height : 32px;
$small-height : 28px;
$mini-height : 24px;
$base-line-height : 1.5715;

$animation-duration-slow : 0.3s;
$animation-duration-base : 0.2s;
$animation-duration-fast : 0.1s;

// placeholder
$placeholder-color : #c0c4cc;

四、效果呈现

在这里插入图片描述
在这里插入图片描述

至此效果实现

当然后续我这边 react 官网也会同步文章进行,也请大家持续关注博主

结语

✨ 每天创作一点点
✨ 开心快乐一整天
✨ 点赞关注加收藏
✨ 美好一天又一天

铁铁们 感谢支持 我需要你们的三连 👍👍👍
请添加图片描述

用一组美丽的按钮来掌握 React Props 用法 目录你将学到的创建 React 工程创建 Button 组件编写 Button 默认样式用 Props 给 Button 不同的样式classnames 组合样式线框样式显示所有按钮样式 你在写 HTML 页面的时候肯定知道,html 标签的属性都是固定的,比如 a 标签的 href, input 里边的 type 属性。这些属性都是内置的,不方便扩展和复用。而用 React 创建组件的话,可以给... 阅读详情

相关推荐

React中如何隐藏按钮

在React中,要隐藏按钮,你可以使用CSS样式或者条件渲染的方式来实现。标签,并且你想要隐藏它,你可以给它添加一个CSS类名,比如"hidden-button"。在上面的代码中,我们使用了一个按钮来切换按钮的可见性。首先,在React组件中,为按钮元素添加一个CSS类名。首先,在组件的状态中定义一个变量,用来表示按钮是否应该被隐藏。最后,将这个CSS类名应用到你的按钮元素中。方法中,使用条件语句来判断是否应该渲染按钮。通过使用条件渲染,你可以动态地控制按钮的可见性。,则会渲染隐藏按钮,否则不渲染。

ByteNinja的博客 717

React 组件封装之 Button

实现两种button按钮,一种实心铺满宽度为100%,一种空心宽度为30%(边框)。

杏子 5205

ReactJS基础学习与项目实战Demo

ReactJS 是由 Facebook 开源的一款用于构建用户界面的 JavaScript 库,其核心理念是组件化开发。通过声明式编程模型,React 允许开发者以组件为单位构建 UI,提升了代码的可维护性和可复用性。其核心优势包括:组件化架构:将UI拆分为独立、可复用的部分,便于团队协作和维护。虚拟DOM:通过高效的Diff算法减少直接操作真实DOM的性能损耗。单向数据流:数据流向清晰,便于调试与状态管理。生态丰富:拥有庞大的社区支持和丰富的第三方库。

weixin_34640289的博客 1001

React自定义组件--Button

React自定义组件--Button 这是主要js代码 import React, { Component } from 'react' import "./dist/index.css"; import PropTypes from "prop-types"; import classnames from "classnames"; class Button extends Component { constructor(props) { super(props);

weixin_42307490的博客 2035

react-reactdribblebutton具有非常好看的hive和点击效果的Button组件

react-dribble-button 具有非常好看的hive和点击效果的Button组件

OLED的字模提取(保姆级)---基于PCtoLCD2013

做为一个刚刚开始接触编程不久的白菜,这个OLED想做一个信息显示,可是商家给我的例程里就是88,816两种字体的格式,我的屏幕是0.91寸的8*16的字体显示上感觉特别丢丢儿小,我就想整个大的,哎,只怪直接学习习惯不好,总是学一半,绕了好大一圈,才搞好,想写一篇博客,时刻提醒踏实学习,第一次写博客,小白一枚,勿喷。。 OLED屏幕驱动程序功能 我们对Markdown编辑器进行了一些功能拓展与语法支...

qq_44886611的博客 7781

React-Hook 轮子公开课(从零开始)用最基础的方式写出一个简单的组件库——第一课【Icon】组件

React-Hook 轮子公开课(从零开始)用最基础的方式写出一个简单的组件库——第一课【Icon】组件>>>关于组件库的话,有关注到我的朋友大家其实也都清除,我这边其实在之前也有讲解过,零零散散的记录过一些有关于组件疑惑点、像正常我们去开发一个项目,类似现在直接用一些的 js 框架,很自然就忽略掉了一些问题点.........

韩旭的博客 888

【商业化】【msix打包】Python 应用打包为 MSIX 的正确流程:入口点问题与解决方案

发现用msix打包工具打包python做的exe时总找不到程序入口点,后来理了一下才发现自己误会了,需要先生成一个基本的setup.exe,msix的打包是基于这个初始的安装程序进行的。只需要点击Buile-》Compile,然后Open Output Folder就可以得到exe安装程序了。可以使用免费工具inno setup来创建初始安装包。其中{group}这样的变量会自动匹配,不用自己指定。如果点击Run会运行安装程序。

每日出拳老爷子的博客 1103

React-Hook 轮子公开课(从零开始)用最基础的方式写出一个简单的组件库——第三课【Row、Col】布局组件

有兴趣的同学 可以先着手看源码,之前写的一系列开源组件库项目(有帮助的同学也帮忙点个star👍)想到布局组件,其实我们最先想到的也就是栅栏,最早接触前端的时候、或者最早接触ui组件的时候,我们首先是不是就先想起来了 Bootstrap 里面的栅栏呢?其实功能类似,底层的话采用的是什么功能呢?也就是@media媒体查询,利用的其实也就是浏览器的分辨率监听,实现了对应的class样式变更,从而达到了一个分割布局的这么一个效果,主要也是捋清我们怎样去写这个代码: 3.2、Row / index.scss 3..

韩旭的博客 1797

英飞凌TC3xx DSADC旋变软解码实战:从示波器波形到VX1000数据,手把手教你避坑

本文详细介绍了英飞凌TC3xx系列微控制器的DSADC模块在电机旋变软解码中的实战应用。从示波器波形分析到VX1000数据采集,提供了一套完整的调试方法论,帮助工程师快速定位和解决常见问题,提升解码精度和系统性能。

weixin_30598225的博客 517

V-rep机器人仿真(Win10):UR5+RG2+Kinect+YOLOV3+DDPG+Pytorch(第四部分:YOLOV3图像识别)

这是一个V-rep机器人仿真实验,较为简单,适合初学者在入门图像识别、机器学习、机器人学的内容时进行学习与训练。 实验涉及的内容有:V-rep机器人仿真,YOLOV3图像识别,强化学习DDPG,UR5机械臂及RG2机械手,Kinect摄像头。 使用环境:Win10,Pytorch0.4,V-rep 整个实验一共由多篇文章组成,本文是第四部分。 第四部分:YOLOV3图像识别 文章目录第四部分:YO...

weixin_42158966的博客 5837

React-Hook 轮子公开课(从零开始)用最基础的方式写出一个简单的组件库——第四课【Link】文字链接组件

有兴趣的同学 可以先着手看源码,之前写的一系列开源组件库项目(有帮助的同学也帮忙点个star👍)其实谈到文本链接组件,我们可以参考向element、antd这些其实可以把这些看成是一个个的文字按钮组件,只不过底层就是使用a标签去实现的,又或者,我不想让其拥有a标签的href属性的话,底层完全就可以使用span标签来包裹文本,总的来说其实就相当于对文本进行了一个封装,我们可以通过属性进行判断到底是一个链接组件,还是一个单纯类似按钮功能的文本样式组件,简单的来讲我们只需要对其进行一个颜色封装即可,当然主要的也.

韩旭的博客 601

使用 ChatGPT Store 里的工具给 ABAP 制作 Logo,效果一般

在编程领域中,Domain Specific Language(DSL)是一种特定于某一问题领域的计算机语言,诞生目的就是为了解决该领域特定类型的问题。在 ChatGPT 官网的 GPT Stores,也有很多已经预先配置完毕,专用于某一特定领域的 GPT 工具,OpenAI 将其分类如下。第三个问题是 Logo 的配色,提供蓝白,黑绿和灰黄,以及自定义调色板四种选择。这个 GPT 设计了四个问题,通过一问一答的方式,获得使用者想创建 Logo 的细节。这次的复杂度调成最低的 1,感觉还是有点花里胡哨的。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 510

React造轮子(reacthook实现一套自己的组件库)轮子公开课——第五课【Radio、RadioButton、RadioGroup】组件

手动实现一个前端 radio 组件,原来实现一个radio组件这么简单

韩旭的博客 1559

YOLO11多类别数据集的类别平衡方法:讲解类别不平衡问题的识别方法,以及过采样、欠采样、类别权重调整等解决方案(一)

类别不平衡问题是机器学习和计算机视觉领域中一个常见但棘手的挑战。简单来说,当数据集中不同类别的样本数量存在显著差异时,我们就称这个数据集存在类别不平衡问题。在YOLO目标检测任务中,这意味着某些类别的目标对象在训练数据中出现得非常频繁,而其他类别的目标对象则很少出现。 想象一下,你正在训练一个交通监控系统,需要检测不同类型的车辆。在这个场景中,"汽车"这个类别可能有成千上万个实例,而"自行车"或"摩托车"可能只有几百个实例。这种数量上的巨大差异就是典型的类别不平衡问题。 从数学角度来看,假设我们有一个包

本博客聚焦 YOLOv11 全流程落地,涵盖架构优化、数据集处理、训练技巧与多场景部署,兼及国产数据库、Java 开发与 AI 模型应用,内容兼顾理论与工程实践,为开发者提供系统干货,助力高效提升技术能力。 939

从点击图标到Activity亮屏:AMS、Zygote、ActivityThread的Binder协作之旅

Launcher通过Context调用 startActivity(),最终会通过 Activity.startActivity() 传递到 ActivityManager.getService(),获取AMS的Binder代理对象(IActivityManager)。这里的 attach() 方法通过Binder调用AMS的 attachApplication(),将新进程的 IApplicationThread 代理对象传递给AMS。这一步的Binder通信,是整个启动流程的关键转折点,值得细细品味。

大模型大数据攻城狮的专栏 1071

React造轮子(reacthook实现一套自己的组件库)轮子公开课——第六课【Checkbox、CheckboxGroup】组件

有兴趣的同学可以先着手看源码,之前写的一系列开源组件库项目(有帮助的同学也帮忙点个star👍)名称官网githubhttphttps—https—https✨每天创作一点点✨开心快乐一整天✨美好一天又一天httpshttpshttps。...

韩旭的博客 1560

图像拼接——ITKMontage

ITKMontage是一个开源的、高性能的图像拼接软件模块。它的核心任务是将多张部分重叠的图像瓦片(Tiles)拼接成一幅完整的大图,专为处理材料显微科学中产生的大规模、高分辨率图像而设计。针对ITKMontage模块中示例进行了修改,解决了没有文件TileConfiguration.txt的情况,以及使用中的一些BUG。ITKMontage可以单独编译,也可以作为ITK的一个模块进行编译,介绍后一种的cmake设置。本文介绍使用ITKMontage模块进行图像拼接的方法。此处省略编译后的库配置。

2301_79131410的博客 100

构建企业级组件库:开发维护 React UI 工具集

构建一个企业级的 React UI 组件库不仅能够提高开发效率,还能够确保产品的一致性和可维护性。通过合理的设计、开发流程和文档支持,组件库能为团队节省大量的时间和精力。随着技术的进步,未来的组件库将更加智能化和模块化,支持更多的定制化需求。希望本文能为你构建企业级 UI 组件库提供一些有价值的参考和指导。

一名热衷于技术的全栈开发者,专注于前端与后端的全面技术探索。在这里,我将分享我在技术领域的学习与成长,助力更多开发者的进步。 858

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

从零开始学习React:了解当前React常用技术,编写第一个React组件

React 与 Vue 可以说是现阶段最热门的前端UI框架了,最近开始学习 React,准备开一个新坑:从零开始学习React,主要是学习时的一些思考与记录,如有谬误,烦请斧正。由于前端技术的快速迭代,我会在适当位置标注版本信息,以免出现货不对板。 1. 了解当前 React 常用技术栈 2. 上手实操,编写第一个组件 3. 组件三大属性 3.1 state 3.2 props 3.3 refs ...

Junerver的博客 856

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

Luxe UI组件库:基于Tailwind CSS的React优雅组件解决方案

在现代前端开发中,UI组件库是提升开发效率和保证设计一致性的关键技术。其核心原理是通过封装可复用的界面元素,为开发者提供标准化的构建模块。从技术价值看,优秀的组件库能显著降低重复劳动,确保无障碍访问性,并支持灵活的主题定制。在应用场景上,无论是管理后台、内容平台还是电商应用,都需要兼顾美观与可维护性的组件方案。本文聚焦的Luxe组件库,正是基于Tailwind CSS构建的React组件库典范,它通过组合性设计哲学和细粒度控制API,完美解决了样式定制难题。其深度集成的可访问性支持和Server Compo

weixin_30555515的博客 462

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Typescript和React造轮子一之React hook基础(二)

第一个简单组件hello word import React, { useContext } from 'react' import { ThemeContext } from '../App' interface IHelloProps { message?: string; } const Hello: React.FC<IHelloProps> = (props) =&gt...

逆袭的菜鸟X 1358

第九章 React 自定义Hook

React 有一些内置 Hook,例如 useState,useContext 和 useEffect。在React中,自定义Hook的作用就是将组件之间的公共逻辑提取出来,以便在不同的组件中复用。这与我们在面向对象的编程中,将公共方法提取到一个新的类中并在多个对象之间共享这个类的方法是类似的。自定义Hook可以帮助我们更好地组织和复用代码,提高代码的可读性和可维护性。使用自定义Hook,我们可以将组件的逻辑封装在一个独立的函数中,并在需要的时候调用这个函数。

Wait.End的博客 1437

Vue3为了封装组件,我写了三天的 vue3 hook!学起来!

vue3 hook

嗨,欢迎来到我的 优快云 博客小天地!一名深耕多年的技术发烧友。在这里,我将把日常工作中积累的宝贵经验,从复杂架构设计的精妙之处,到代码优化的实战技巧,毫无保留地分享给大家。 5271

React+TypeScript高仿AntDesign开发企业级UI组件库

第1章 课程导学(此章节必看)介绍了整个课程的背景知识,项目简介,学习流程,可以掌握的知识点,以及学习方法和前置知识。第2章 欢迎来到类型的世界 - Typescript本章主要帮助大家理解 TypeScript 可以解决的问题和所带来的优势,带领大家学习 TS 中的各种基础类型,然后进阶到复杂类型,包括:Array, Tuple, interface, function, Class, Enu...

ygunoil的博客 115

探索layrr:基于React的Headless UI组件库设计与工程实践

在现代前端开发中,组件库是构建一致、高效用户界面的核心基础设施。其设计原理通常围绕可复用性、可维护性和开发体验展开,通过封装通用交互逻辑与视觉样式,为开发者提供标准化构建模块。从技术价值看,优秀的组件库能显著提升开发效率、保证设计一致性,并降低团队协作成本。在实际应用场景中,组件库需要与不同技术栈(如状态管理、路由)无缝集成,并应对样式定制、性能优化、无障碍访问等工程挑战。本文聚焦的layrr项目,正是基于React生态,融合了Headless UI和原子化设计理念的实践案例,它通过逻辑与样式的解耦,为复杂

weixin_30536513的博客 359
上一篇: React-Hook 轮子公开课(从零开始)用最基础的方式写出一个简单的组件库——第一课【Icon】组件
下一篇: 前端技能树初体验
归来巨星
归来巨星 新星创作者: 前端开发技术领域 新星创作者: 前端开发技术领域
博客等级 码龄7年 5391粉丝 95原创
评论 10
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

归来巨星

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值