This is the 7th day of my participation in the November Gwen Challenge. Check out the details: The last Gwen Challenge 2021

TIP 👉 If you don’t fly, you will soar into the sky. It never rains but it pours. — Biography of The Historian

preface

Web Component is an area that the front-end world has been very enthusiastic about. To implement it with third-party componentized frameworks, you need to rely on a lot of things in the framework itself. Most of the time we just have a few simple components, not too big, not too many, so in order to keep the components lightweight, Simple, we don’t really want to use a third party framework at this point.

Input mode dialog box

import

import Input from '@/components/Input/Input';
Copy the code

Props

1. value

  • Type: string | number (required)
  • Default value: none
  • Description: Input the contents of the box

2. size

  • Type: string
  • Default: None (height 32px)
  • Large (box height 40px) Small (box height 24px)

3. maxLength

  • Type: string | number
  • Default value: none
  • Description: Input box can enter the maximum number of characters

4. disabled

  • Types: bool
  • Default value: none
  • Description: Whether to disable, true disabled, false available

5. placeholder

  • Type: string
  • Default value: none
  • Description: Enter the description of the box

6. prefix

  • Type: ReactNode
  • Default value: none
  • Description: Prefix icon
    • No pass, no prefix icon; Pass node, custom prefix icon

7. suffix

  • Type: ReactNode
  • Default value: none
  • Description: suffix icon
    • No pass, no suffix icon; Pass node, customize suffix icon

8. allowClear

  • Types: bool
  • Default value: none
  • Description: Whether to display the empty icon, true display, false do not display

9. onChange

  • Type: func(required)
  • Default value: none
  • Description: Callback function triggered when input content

10. onPressEnter

  • Type: func
  • Default value: none
  • The return key triggers the callback function

11. onBlur

  • Type: func
  • Default value: none
  • Input box loses cursor triggered callback function

Let’s implement an input component

import React from 'react';
import { Component, PropTypes } from '.. /utils/';
import Icon from '.. /icon';

export default class Input extends Component {
    static defaultProps = {
        prefixCls: 'input'.type: 'text'.autoComplete: 'off'.onChange(){},onSearch(){},onKeyUp(){},}constructor(props) {
        super(props);
        this.state = {
            value: props.value,
            placeholder: props.placeholder,
        };
    }
    componentWillReceiveProps(. props) {
        this.setState({ ... props, }); }handleKeyUp(e) {
        const { onSearch, onKeyUp } = this.props;
        if (e.key === 'Enter') {
            onSearch(e, e.target.value);
        }
        onKeyUp(e);
    }
    // the method used by other components such as input-number
    focus(){(this.input || this.textarea).focus();
    }
    blur(){(this.input || this.textarea).blur();
    }
    handleChange(e) {
        const { onChange, length } = this.props;
        let val = e.target.value;
        if (val.length > length) {
            val = val.slice(0, length);
            e.target.value = val;
        }
        this.setState({ value: val });
        onChange(e, val);
    }
    handleClick(type, e) {
        if (this.props[type]) {
            this.props[type](e, this.state.value); }}renderIcon(type) {
        const { prefixCls, leftIcon, rightIcon, onIconClick, onPreIconClick, onIconMouseOut, onPreIconMouseOut, onIconMouseOver, onPreIconMouseOver } = this.props;
        let icons;

        if (type === 'rightIcon' && typeof rightIcon === 'string') icons = rightIcon;
        if (type === 'leftIcon' && typeof leftIcon === 'string') icons = leftIcon;

        const renderIcon = () = > {
            if ((typeof leftIcon === 'string' && icons) || (typeof rightIcon === 'string' && icons)) {
                return (
                    <Icon
                        className="input-icon-inner"
                        type={icons}
                        onClick={this.handleClick.bind(this, type= = ='icon' ? 'onIconClick' : 'onPreIconClick')}
                        onMouseOver={this.handleClick.bind(this, type= = ='icon' ? 'onIconMouseOver' : 'onPreIconMouseOver')}
                        onMouseOut={this.handleClick.bind(this, type= = ='icon' ? 'onIconMouseOut' : 'onPreIconMouseOut')} / >
                );
            }
            return type === 'rightIcon' ? rightIcon : leftIcon;
        };
        return (
            <div className={this.classNames({[` ${prefixCls}-icon-left`]: type= = ='leftIcon' && leftIcon[` ${prefixCls}-icon-right`]: type= = ='rightIcon' && rightIcon.event: (type= = ='leftIcon' && onPreIconClick) | | (type= = ='rightIcon' && onIconClick) | | (type= = ='leftIcon' && onPreIconMouseOut) | | (type= = ='rightIcon' && onIconMouseOut) | | (type= = ='leftIcon' && onPreIconMouseOut) | | (type= = ='rightIcon' && onIconMouseOver) | | (type= = ='leftIcon' && onPreIconMouseOver),})} >
                {renderIcon()}
            </div>
        );
    }
    render() {
        const{ prefixCls, className, style, type, size, length, leftIcon, rightIcon, value, onSearch, onIconClick, onPreIconClick, onIconMouseOut, onPreIconMouseOut, onIconMouseOver, onPreIconMouseOver, addonBefore, addonAfter, height, ... other } =this.props;
        const cls = this.classNames(`${prefixCls}`, className, {
            textarea: type === 'textarea'.'w-disabled': this.props.disabled,
        });

        if (type === 'textarea') {
            return (
                <textarea
                    className={this.classNames(cls,` ${prefixCls}-inner`)}
                    {. other}
                    value={value}
                    placeholder={! value ? this.state.placeholder :"'}ref={(elm)= > { this.textarea = elm; }}
                    type={type}
                    style={style}
                    onChange={this.handleChange.bind(this)}
                />
            );
        }

        return (
            <div
                style={style}
                className={this.classNames(cls,${{[`prefixCls}-The ${size} `]: size[` ${prefixCls}-icon`]: leftIcon || rightIcon[` ${prefixCls}-addon`]: addonBefore || addonAfter,})} >
                {addonBefore && <span className={` ${prefixCls}-addon-before`} >{addonBefore}</span>}
                {leftIcon && this.renderIcon.bind(this)('leftIcon')}
                {rightIcon && this.renderIcon.bind(this)('rightIcon')}
                <input
                    {. other}
                    type={type}
                    ref={(elm)= >{ this.input = elm; }} className={this.classNames(`${prefixCls}-inner`, { [`${prefixCls}-p-left`]: leftIcon, [`${prefixCls}-p-right`]: rightIcon, 'addon-before': addonBefore, 'addon-after': addonAfter, })} value={value} placeholder={! value ? this.state.placeholder : ''} onChange={this.handleChange.bind(this)} onKeyUp={this.handleKeyUp.bind(this)} style={{height: height}} /> {addonAfter &&<span className={` ${prefixCls}-addon-after`} >{addonAfter}</span>}
            </div>
        );
    }
}

Input.propTypes = {
    prefixCls: PropTypes.string,
    type: PropTypes.string,
    autoComplete: PropTypes.string,
    size: PropTypes.oneOf(['large'.'small'.'mini']),
    length: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
    rightIcon: PropTypes.oneOfType([PropTypes.element, PropTypes.string]),
    leftIcon: PropTypes.oneOfType([PropTypes.element, PropTypes.string]),
    onChange: PropTypes.func,
    onSearch: PropTypes.func,
    onKeyUp: PropTypes.func,
    addonBefore: PropTypes.node,
    addonAfter: PropTypes.node,
};
Copy the code

index.js

import Input from './Input';
import './input.scss';

export default Input;
Copy the code

I’m going to leave the styles out for now

“Feel free to discuss in the comments section.”

Hope to finish watching friends can give a thumbs-up, encourage once