beginning

Tinker with the text, talk about work encountered interesting, today to talk about step manager. One day, the product manager with kind eyes slowly paced to the front of the page so analysis, front end students ah, you see, our page operation for users is scattered, there are a lot of inconvenience, the lack of an effective guide, how to solve it? Ha ha, thought this is not a problem. Let’s say we can gather these scattered and necessary operations together and make an operation guide page, so that users do not need to jump to different pages to complete those scattered operations, which is a great improvement to user experience. At the same time, friend A said he also wanted to use such A scheme to improve user experience. Ok, so how to design a convenient, configurable, versatile step management component?

Start to design

React is used as an example, but With Vue, Angular implements much the same.

Calm down and think about it, it is not easy to meet flexible configuration, high versatility, high availability, flexible configuration and convenient use are two opposite sides, how to balance is an important thing. For example, if I wanted to be flexible, I had to write a lot of code so that components were cumbersome to use, parameters were easy to forget, and I had to look at documentation from time to time.

We first from the point of view of ensuring universality, step by step to solve this problem.

composition

Generally speaking, a step management component consists of three parts, namely, the title part that gives information about each step, the content display part and the control part that controls the upper/next step.

The data structure

Split by composition, we can configure each step as follows.

// demo.jsx
<Steps stepset={[{
    title: '1'<p>1</p>,// handleNext: () => {return true; } / / controltrue or false
}, {
    title: '2',
    content: <p>2</p>,
    handleNext: () => { return true; } }, { title:'3',
    content: <p>3</p>,
    handleNext: () => { return true; }}]} / >Copy the code

Well, that’s intuitive.

state

Each step has three states: selected, current, and selected. We can easily determine which state each step belongs to by using the currentStep currentStep.

// steps.jsx
...
handleTitleStyle(stepIndex, currentStep) {
    if (stepIndex > currentStep) {
        return 'step-sign-default';
    }
    if (stepIndex < currentStep) {
        return 'step-sign-ed';
    }
    return 'step-sign-active'; }... <div className={['orther-style', this.handleTitleStyle(index,currentStep)].join(' ')}>{item.title}</div>
...
Copy the code

layout

The key point of layout is the adaptability and universality of step title bar.

Use Flex layout to make the ‘parts’ on the title bar neatly self-adapt

// steps.scss .steps-box{ display: flex; } .steps-item{ flex: 1; }...Copy the code

The first step is subtly identified using the adjacent brother selector so that the dashes do not appear before the first step.

// steps.scss ... .step-item+.step-item .sign-box { &:before { content: ''; position: absolute; display: inline-block; border-style: solid; border-width: 1px; border-color: #cdcdcd; width: 100%; height: 0; left: -50%; top: 46%; transition: all .2s; }}...Copy the code

Content show

In addition to the current step, use position:absolute; Out of the document flow, leaving only the space occupied by the current step.

// steps.jsx
...
this.props.stepset.map((step, index) => {
    return (
        <div key={index} className="p-r">
            <div className="step-content" style={index == this.state.currentStep ? { position: 'relative', visibility: 'visible', zIndex: 1, left: 0 } : {}}>
                {
                    step.content
                }
            </div>
        </div>
    )
})
...
Copy the code

The control bar

Yes, this is the balance between flexible configuration and ease of use. If the control bar is not necessary for maximum flexibility, it is perfectly possible to give the developer control over the last or next step at every moment. However, this requires developers to write a lot of control code, so I think that this control code can be handed over to components, as long as we provide the relevant API in the right place, developers can also have complete control of the step component every moment. This compromise allows for both flexible configuration and ease of use.

There are often asynchronous scenarios when processing the next response, such as the need to remotely verify the captcha when clicking next. Well, we can build an asynchronous handler with async/await.

// steps.jsx. async handelNextStep() {const len = this.props.stepset.length;
    if (this.props.stepset[this.state.currentStep].handleNext) {
        // Support asynchronous operation return Promise
        const AllowNext = await this.props.stepset[this.state.currentStep].handleNext(this.props.stepset[this.state.currentStep], this.state.currentStep);
        if (AllowNext) {
            if (this.state.currentStep + 1 < len) {
                this.setState({
                    currentStep: this.state.currentStep + 1}); }}}else {
        if (this.state.currentStep + 1 < len) {
            this.setState({
                currentStep: this.state.currentStep + 1
            });
        }
    }
}

handelPreStep() {
    if (this.state.currentStep - 1> =0) {
        this.setState({
            currentStep: this.state.currentStep - 1= > {}, ()this.props.stepset[this.state.currentStep].handlePre && this.props.stepset[this.state.currentStep].handlePre(this.props.stepset[this.state.currentStep], this.state.currentStep); }); }}...Copy the code

Friend A says, “What if I want to control the steps in the content?” Well, that’s not a problem, just expose the relevant action API, passed in via props. Something like this:

// demo.jsx
<Steps stepset={[{
    title: '1'// content: (handelNextStep, handelPreStep) => {<p onClick={() => handelNextStep()}>hello, isCustomCtrl:true// Whether to customize the control bar}, {title:'2',
    content: <p>2</p>,
    handleNext: () => { return new Promise((resolve) => { resolve(true); })}// Support asynchronous operation}]} />Copy the code

Ok, the management component is ready in one step.

The source code

The source code has been placed in GitHub component && style, and the online Demo can be viewed under the ‘Steps Management’ TAB in SluckyUI.

At the end of the

The story of this step management component ends here, and the product manager and friend A are very happy. This step management component has been integrated into SluckyUI For React. SluckyUI’s idea is to create a component library seed, so that other developers can carry out rapid secondary development and reduce unnecessary building wheels. However, there is still a long way to go in the writing process, and there are still many unfinished areas. Welcome to join SluckyUI.

Series of portals from scratch

  • Re from scratch UI library authoring life specification
  • Re from scratch UI library writing buttons for Life
  • Re writing forms for Life from scratch UI Library
  • Re writing life’s Table Components from scratch UI library
  • Re from scratch UI library writing life loading progress bar
  • Re From Scratch backend learning configuration Ubuntu+Ngnix+Nodejs+Mysql environment
  • Configuring LAMP environments for Re From Scratch Back-end Learning