Hello Friends, In this post you will find a good example of building reusable lighting spinner for lightning web component (LWC). After building this component you can just refer it any lwc component with your custom loading message. so let's get started. 

Reusable spinner in lightning web component

This is an extension of the standard lightning-spinner with a custom loading message shown along with the spinner. It supports all of the features likewise lightning-spinner along with the custom message.

Suppoprted Size : small, medium and large.

Supported Variant : base, brand and inverse.

Default Values : size="medium" variant="base" message="Loading..."

Spinnerlwc.html

 <template>
    <div class={containerClass}>
        <div role="status" class={spinnerClass}>
            <span class="slds-assistive-text">Loading...</span>
            <div class="slds-spinner__dot-a"></div>
            <div class="slds-spinner__dot-b"></div>
        </div>
        <div data-id="spinnerMsg" class={messageClass}>
            <div style="margin-left:-50%">{_message}</div>
        </div>
    </div>
 </template>
Spinnerlwc.js
 import { LightningElement, api } from 'lwc';
 const SPINNER_CLASS = "slds-spinner";
 const MESSAGE_CLASS = "spinner-msg";
 export default class Spinnerlwc extends LightningElement {
    isConnected;
    _size = "medium"; 
    _variant = "base"; //Valid values will be: base, brand, inverse
    _message = "Loading...";
    _hideBackground = false;

    containerClass = "slds-spinner_container";
    spinnerClass;
    messageClass;

    @api
    set size(value) {
        this._size = value ? value : "medium";
        if (this.isConnected) this.init();
    }
    get size() {
        return this._size;
    }

    @api
    set variant(value) {
        this._variant = value ? value : "base";
    }
    get variant() {
        return this._variant;
    }

    @api
    set message(value) {
        this._message = value ? value : "Loading...";
        if (this.isConnected) this.init();
    }
    get message() {
        return this._message;
    }

    connectedCallback() {
        this.init();
        this.isConnected = true;
    }

    init() {
        this.containerClass += this._variant == "inverse" ? " slds-inverse_background" : "";
        this.spinnerClass = `${SPINNER_CLASS} ${SPINNER_CLASS}_${this._size} ${SPINNER_CLASS}_${this._variant}`;
        this.messageClass = `${MESSAGE_CLASS} ${MESSAGE_CLASS}_${this._size} slds-color_${this._variant}`;
        if (this._size == "xx-small" || this._size == "x-small") 
        this.messageClass = "slds-hide";
    }
 }
Spinnerlwc.css
 .spinner-msg {
    position: absolute;
    top: 50%;
    left: 50%;
 }
 .spinner-msg_x-small {
    padding-top: 0.75rem;
    font-size: 0.75rem;
 }
 .spinner-msg_small {
    padding-top: 1rem;
    font-size: 0.9rem;
 }
 .spinner-msg_medium {
    padding-top: 1.5rem;
    font-size: 1.25rem;
 }
 .spinner-msg_large {
    padding-top: 1.75rem;
    font-size: 1.75rem;
 }
 .slds-color_brand {
    color: var(--lwc-brandPrimary);
 }
 .slds-color_inverse {
    color: var(--lwc-colorBackgroundAlt);
 }
 .slds-color_base {
    color: #b0adab;
 }
 .slds-inverse_background {
    background-color: var(--lwc-colorBackgroundAltInverse);
    opacity: 0.5;
 }
Spinnerlwc.js-meta.xml
 <?xml version="1.0" encoding="UTF-8"?>
 <LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>59.0</apiVersion>
    <isExposed>true</isExposed>
 </LightningComponentBundle>
Output:
 <c-spinnerlwc size="small" variant="brand"></c-spinner>

 <c-spinnerlwc size="medium" variant="base" message="Posting..."></c-spinner>

 <c-spinnerlwc size="large" variant="inverse" message="Submitting..."></c-spinner>

Hope you like this post, for any feedback or suggestions please feel free to comment. I would appreciate your feedback and suggestions.
Happy Coding...:)
Thank you.