SPFx with Fluent UI Spinner and Message bar

Quite simple and a basic one. In every SPFx webpart we do data load/retrieve action and while the code does it user experience is blank so its good to show a loading/progress animation and a message after success.

Lets do that with:

To demonstrate it we will add a list item using text box and a button. with a spinner to show user that adding is in progress and a final success message after the item is added to the list.

import * as React from 'react';
import styles from './Spinner.module.scss';
import { ISpinnerProps } from './ISpinnerProps';
import { escape } from '@microsoft/sp-lodash-subset';
import { TextField } from 'office-ui-fabric-react/lib/TextField';
import { Stack, IStackProps, IStackStyles } from 'office-ui-fabric-react/lib/Stack';
import { PrimaryButton} from 'office-ui-fabric-react';
import { Spinner } from 'office-ui-fabric-react/lib/Spinner';
import { Link, MessageBar, MessageBarType } from 'office-ui-fabric-react';
import { sp } from "@pnp/sp";
import "@pnp/sp/webs";
import "@pnp/sp/lists";
import "@pnp/sp/items";

export interface ISpinnerState{
  isLoading: boolean;
  isSuccess: boolean;
}
const stackTokens = { childrenGap: 50 };
const stackStyles: Partial<IStackStyles> = { root: { width: 650 } };
const columnProps: Partial<IStackProps> = {
  tokens: { childrenGap: 15 },
  styles: { root: { width: 300 } },
};
export default class Spinners extends React.Component<ISpinnerProps, ISpinnerState> {
  constructor(props: ISpinnerProps) {
    super(props);
    this.state = {
      isLoading: false,
      isSuccess: false
    };
  }

  public render(): React.ReactElement<ISpinnerProps> {
    const { isLoading,isSuccess } = this.state;    
    return (
      <> 
      {isSuccess === true && <MessageBar messageBarType={MessageBarType.success} isMultiline={false} >
        Successfully added item to sharepoint list.
        <Link href="www.bing.com" target="_blank">
          Visit our website.
        </Link>
      </MessageBar>}  
      <Stack horizontal tokens={stackTokens} styles={stackStyles}> 
      <Stack {...columnProps}> 
        {isLoading ? (<Spinner label="Adding Please wait..." ariaLive="assertive" labelPosition="bottom" />):(
          <TextField id="Title" label="Title" />
        )}        
        <PrimaryButton text="Add Item" onClick={this._addItem} allowDisabledFocus />
      </Stack>
    </Stack>   
    </>
    );
  }

  private _addItem= async()=>{
    // enable loading
    this.setState({
      isLoading: true
    });

    // add an item to the list
    await sp.web.lists.getByTitle("People").items.add({
      Title: document.getElementById('Title')["value"]
    });

    // disable loading and enable success message bar
    this.setState({
      isLoading: false,isSuccess:true
    });

    // hide the success message bar after 2second
    setTimeout(() => {
      this.setState({ isSuccess: false });
    }, 2000);
  }
}