preface

This article is the fifth article writing component design, the writer has written component design related articles, because as a front-end good front end engineer, in the face of all sorts of tedious and repetitive work, we should not be on track to “hard work”, but according to the existing front-end development experience, summed up a set of effective method for developing. The emergence of MVVM frameworks like React/VUE, as data-driven leaders, helped us reduce a lot of redundant code in our work, and the idea of everything component became popular. Therefore, in order to give engineers more time to think about business and product iterations, we have to master the ideas and methods of high-quality component design. Therefore, the author will spend time to summarize the design ideas and methods of components in various business scenarios, and use the syntax of the native framework to realize the development of various commonly used components, hoping that the front-end novice or friends with certain work experience can gain something.

Today I will introduce you to implement a Tag component and an Empty component. Before I introduce the component design, I will introduce icomoon, a free and open source icon library.

If you are not familiar with react/ Vue component design principles, please refer to my previous component design series:

  • Master React/Vue Component Design creates materialui-like button click animations with pure CSS and encapsulates react components
  • Quickly implement a customizable progress bar component in Master React/Vue Component Design
  • Master React/Vue Component Design: Repackaging a real-time preview JSON editor component in JsonEditor (React version)

The body of the

Before starting component design, I hope you have a basic knowledge of CSS3 and JS. Let’s take a look at the component after implementation:

1. Component design ideas

Following the principles of component design that I wrote earlier, our first step is to identify the requirements. A tag component usually has the following requirements:

  • You can change the label color
  • Provides close label configuration to allow users to close labels
  • A label closing callback that gives the user control over the actions that are triggered when the label is closed

Once the requirements have been gathered, as an aspiring programmer, the following wireframes emerge:

Implement a Tag component based on React

2.1. Tag component framework design

First, let’s write the component framework according to the requirements, so that the business logic will be clearer:

import React from 'react'
import classnames from 'classnames'
import styles from './index.less'

/** * Label component * @param {closable} Boolean Whether it can be disabled * @param {onClose} func Callback when the label is closed * @param {color} String Label color. If not set, it is the default color */
export default function Tag(props) {
  let { children, closable, onClose, color } = props
  return <div 
    className={styles.xTag} 
    style={{ backgroundColor: color }}
    { children} < /div>
}
Copy the code

With this framework in place, let’s step by step implement the content inside. According to the requirement, the color attribute is easy to implement, which is already implemented in the above code. Let’s see how closable and onClose are implemented. To close the tag, we actually need to hide it, for example, by using display: None, or remove it from the DOM, as we did with the antD implementation of display: None.

If you are not familiar with the use of ref, you can refer to the react official documentation. Here is the implementation:

import React from 'react'
import classnames from 'classnames'
import styles from './index.less'

/** * Label component * @param {closable} Boolean Whether it can be disabled * @param {onClose} func Callback when the label is closed * @param {color} String Label color. If not set, it is the default color */
export default function Tag(props) {
  let { children, closable, onClose, color } = props
  let tag = React.createRef()
  let handleClose = (a)= > {
    onClose && onClose()
    tag.current.style.display = 'none'
  }
  return <div 
    className={classnames(styles.xTag, color ? styles.xTagHasColor :"')}style={{ backgroundColor: color }}
    ref={tag}>
    { children } 
    { closable && <span className={styles.closeBtn} onClick={handleClose}>x</span> }
  </div>
}
Copy the code

Using the React createRef API, we can easily get the current DOM object and assign properties in the handleClose. The basic implementation of the js code for the component is complete. Let’s look at the CSS:

.xTag {
  margin-bottom: 8px;
  margin-right: 8px;
  display: inline-block;
  border-radius: 4px;
  border: 1px solid #d9d9d9;
  padding: 0 7px;
  font-size: 12px;
  line-height: 20px;
  white-space: nowrap;
  background-color: #fafafa;
  &.xTagHasColor {
    border-color: transparent;
    color: #fff;
    .closeBtn {
      color: rgba(255.255.255.6)}}.closeBtn {
    margin-left: 5px;
    color: rgba(0.0.0.0.45);
    cursor: pointer; }}Copy the code

Robustness support:

import PropTypes from 'prop-types'
// ...
Tag.propTypes = {
  color: PropTypes.string,
  closable: PropTypes.bool,
  onClose: PropTypes.func
}
Copy the code

Is it simple? This is a customizable tag component. You can learn how to use CSS Modules and ClassNames in your code. It is very simple.

Implement an Empty component based on React

This component is very easy to write, currently commonly used empty state components are generally pictures and text combination, pictures and text can be replaced, the specific implementation is as follows:

import classnames from 'classnames'
import styles from './index.less'

/** * empty state component * @param {className} string custom className * @param {text} string empty state text */
export default function Empty(props) {
  let { text, className } = props
  
  return <div className={classnames(styles.emptyWrap, className)} >
    <div className={styles.emptyInner}><span className="icon-finder"></span></div>
    <p>{ text ? Text: 'empty '}</p>
  </div>
}
Copy the code

Here is the origin of Icon-Finder. As mentioned at the beginning of this article, I used Icomoon as my icon library, and we could customize our own ICONS on its website. I chose about 40 free ICONS, which was enough for the project. Mainly introduce his specific functions:

  1. Can import, download, manage their own icon library
  2. Edit ICONS to generate SVG ICONS or font ICONS

    Of course, domestic iconfont is also very good, you can try more.

After downloading the icomoon icon file, we will have an HTML demo file, which has specific usage methods and offline editing function, as follows:

The last

I will go on to implement modal Windows, alert, drawer, tooltip, Skeleton, Message, date/calendar, and other components to follow up on my years of componentization. If you want to learn more H5 games, Webpack, node, gulp, CSS3, javascript, nodeJS, Canvas data visualization and other front-end knowledge and practical, welcome to join us in the public number “Interesting Talk front end” to learn and discuss, and explore the boundary of the front end.

More recommended

  • Javascript Design Patterns front-end Engineers Need to Know in 15 minutes (with detailed mind maps and source code)
  • In 2019, take a look at some of my top questions and advice for job seekers
  • A picture shows you how to play vue-Cli3 quickly
  • Vue Advanced Advanced series – Play with Vue and vuex in typescript
  • “Front-end combat summary” the use of pure CSS website skin and focus diagram switch animation
  • “Front-end combat summary” using CSS3 to achieve cool 3D rotation perspective
  • Add a loading progress bar to your site using pace. Js
  • The Application of design Pattern of “Summary of Front End Actual Combat” — Memorandum Pattern
  • “Front End Combat Summary” using postMessage to achieve pluggable cross-domain chatbot
  • “Front-end combat summary” of the variable promotion, function declaration promotion and variable scope detailed explanation
  • “Front-end combat summary” how to change the URL without refreshing the page