Loading indicator / spinner#

A common pattern is showing loading indicator (also called "spinner"), whenever a request duration is longer than the usual user is inclined to wait, without getting nervous...

# spinner/__init__.py
from time import sleep
from tetra import Component, public


class LoadingIndicatorDemo(Component):

    @public
    def long_lasting_process(self):
        sleep(2)

<!-- spinner.html -->
<div {% ... attrs %}>
  <!-- spinner within button -->
  <div class="mb-2">
    <button class="btn btn-primary" type="button"
            @click="long_lasting_process()"
            tx-indicator="#spinner-inline"
    >
      <span id="spinner-inline" class="spinner-border spinner-border-sm me-2"></span>
      Load data
    </button>
  </div>

  <!-- external spinner -->
  <div class="d-flex align-items-center gap-2">
    <button class="btn btn-primary" type="button"
            @click="long_lasting_process()"
            tx-indicator="#spinner-external"
    >
      Load data
    </button>
    <span id="spinner-external" class="spinner-border"></span>
  </div>
</div>

You'll need a bit of CSS to get this to work, as you have to hide the spinner per default:

// spinner.css
.spinner-border {
    display: none;
    /*opacity: 0;*/
    /*transition: opacity 500ms ease-in;*/
}
.tetra-request .spinner-border,
.tetra-request.spinner-border {
    display: inline-block;
    /*opacity: 1;*/
}

You can also accomplish the hiding with opacity: 0 and opacity:1 with a transition to make it smoother.

You can click the button below, the spinner is shown for the period of the tetra request and hidden again afterwords.


Demo