天天看點

TS+react自建元件庫 01TS+react自建元件庫 01

TS+react自建元件庫 01

Hello World元件測試

import {FC} from 'react'

interface IHello {
   message?: string; 
}

const Hello:FC<IHello> = function(props){
    let {message} = props;
    return (
        <h2>{message}</h2>
    )
}

Hello.defaultProps = {
  message : 'Hello World'
}
export default Hello;
           

點贊按鈕元件測試

import {FC,useState} from 'react'

const GiveLike:FC = () => {
  let [like, setLike] = useState(0);
  return (
    <button onClick = {() => setLike(like + 1)}>
      👍{like}
    </button>
  )
}

export default GiveLike;
           

滑鼠坐标元件測試

import {FC, useState, useEffect} from 'react'

const MousePosition : FC = () => {
  const [positions,setPosition] = useState({x:0,y:0})
  const updatePosition = (e:MouseEvent) => {
    setPosition({x:e.clientX,y:e.clientY})
  }
  useEffect(() =>{
    document.addEventListener('click',updatePosition)
    return(
      () => {
        document.removeEventListener('click',updatePosition)
      }
    )
  })
  return (
    <div>
      滑鼠坐标:X:{positions.x},Y:{positions.y}
    </div>
  )
}

export default MousePosition;
           

KGD的樣式解決方案

①Inline CSS

②CSS in JS

③Sass/Less(KGD選擇的解決方案)

樣式系統檔案結構:

styles/
	_variables.scss  //各種變量以及可配置設定
	_mixins.scss 	//全局mixins
	_functions.scss //全局functions
components/
	Button/
		index.scss 	//元件的單獨樣式
	...
           

KGD的色彩體系

系統色闆 - 基礎色闆 + 中性色闆

産品色闆 - 品牌色 + 功能色

// 中性色彩
$white:     #fff !default; // !default 關鍵字表示定義該變量後其不會被重新指派
$gray-100:  #f8f9fa !default;
$gray-200:  #e9ecef !default;
$gray-300:  #dee2e6 !default;
$gray-400:  #ced4da !default;
$gray-500:  #adb5db !default;
$gray-600:  #6c757d !default;
$gray-700:  #495057 !default;
$gray-800:  #343a40 !default;
$gray-900:  #212529 !default;
$black:     #000 !default;

// 基礎色闆
$blue:      #0d6efd !default;
$indigo:    #6610f2 !default;
$purple:    #6f42c1 !default;
$pink:      #d63384 !default;
$red:       #dc3545 !default;
$orange:    #fd7e14 !default;
$yellow:    #fadb14 !default;
$green:     #52c41a !default;
$teal:      #20c997 !default;
$cyan:      #17a2b8 !default;

// 系統色闆
$primary:     $blue !default;
$secondary:   $gray-600 !default;
$success:     $green !default;
$info:        $cyan !default;
$warning:     $yellow !default;
$danger:      $red !default;
$light:       $gray-100 !default;
$dark:        $gray-800 !default;
           

KGD的樣式變量分類

  • 基礎色彩系統
  • 字型系統
  • 表單
  • 按鈕
  • 邊框和陰影
  • 可配置開關
tips:node-sass版本為5.0.0
Failed to compile.

./src/styles/index.scss (./node_modules/css-loFailed to compile.

./src/styles/index.scss (./node_modules/css-loFailed to compile.

./src/styles/index.scss (./node_modules/css-loFailed to compile.

./src/styles/index.scss (./node_modules/css-loader/dist/cjs.js??ref--5-oneOf-6-1!./node_modules/postcss-loader/src??postcss!./node_modules/resolve-url-loader??ref--5-oneOf-6-3!./node_modules/sass-loader/dist/cjs.js??ref--5-oneOf-6-4!./src/styles/index.scss)
Node Sass version 6.0.1 is incompatible with ^4.0.0 || ^5.0.0.

//版本不相容,此時node-sass版本為6.0.1
           

KGD的第一個元件-Button

需求分析

類型分析-type:主按鈕、預設按鈕、危險按鈕、連結按鈕

大小分析-size:預設按鈕、小型按鈕、大型按鈕

按鈕狀态:能否點選

樣式:高亮,文字居中,顔色

設計實作

插件引入:classnames --一個簡單的JavaScript工具,用于有條件地連接配接類名。

安裝指令:yarn add classnames @types/classnames --save

github位址

使用方式:

classNames('foo', 'bar'); // => 'foo bar'
classNames('foo', { bar: true }); // => 'foo bar'
classNames({ 'foo-bar': true }); // => 'foo-bar'
classNames({ 'foo-bar': false }); // => ''
classNames({ foo: true }, { bar: true }); // => 'foo bar'
classNames({ foo: true, bar: true }); // => 'foo bar'

// lots of arguments of various types
classNames('foo', { bar: true, duck: false }, 'baz', { quux: true }); // => 'foo bar baz quux'

// other falsy values are just ignored
classNames(null, false, 'bar', undefined, 0, 1, { baz: null }, ''); // => 'bar 1'
           
Button元件
import React, {FC} from 'react'

import classNames from 'classnames'

export enum ButtonType {
  Primary = 'primary',
  Danger = 'danger',
  Default = 'default',
  Link = 'link',
}

export enum ButtonSize {
  Large = 'lg',
  Small = 'sm',
}

interface BaseButton {
  className ?: string,
  btnType ?: ButtonType,
  size ?: ButtonSize,
  children ?: React.ReactNode,
  disabled ?: boolean,
  href ?: string,
}

type NativeButtonProps = BaseButton & React.ButtonHTMLAttributes<HTMLButtonElement> 
//擷取button原本具有的屬性并與自定義button元件類型合并
//交叉類型是将多個類型合并為一個類型
type AnchorButtonProps = BaseButton & React.AnchorHTMLAttributes<HTMLAnchorElement>
//擷取a原本具有的屬性并與自定義button元件類型合并
type ButtonProps = Partial<NativeButtonProps & AnchorButtonProps>
//映射類型:将一個已知的類型每個屬性都變為可選的

const Button : FC<ButtonProps>  = (props) => {
  const {
    className, 
    btnType, 
    size, 
    children, 
    disabled, 
    href,
    ...restProps	//擷取所有原屬性
  } = props
  //className允許使用者自定義className
  const classes = classNames('btn', className, {	
    [`btn-${btnType}`] : btnType,
    [`btn-${size}`] : size,
    'disabled' : btnType === ButtonType.Link && disabled,
  })
  return btnType === ButtonType.Link && href ? 
  (
    <a
      className = {classes}
      href = {href}
      {...restProps}
    >
      {children}
    </a>
  ) : 
  (
    <button
      className = {classes}
      disabled = {disabled}
      {...restProps}
    >
      {children}
    </button>
  )
}

Button.defaultProps = {
  disabled: false,
  btnType: ButtonType.Default
}

export default Button;
           

繼續閱讀