Progressbar

In addition to Preloader Framework7 also comes with fancy animated determinate and infinite/indeterminate progressbars to indicate activity.

Determinate Progressbar

When progressbar is determinate it indicates how long an operation will take when the percentage complete is detectable.

Let's look at layout of determinate progressbar:

<div class="progressbar" data-progress="20">
  <span></span>
</div>

Where data-progress="20" - current progress (in percents). Note that this data attribute sets progress only on page load. If you need to change it later it should be done via API.

Infinite Progressbar

When progressbar is infinite/indeterminate it requests that the user wait while something finishes when it’s not necessary to indicate how long it will take.

Let's look at layout of infinite progressbar:

<div class="progressbar-infinite"></div>

Progressbar Colors

Progressbar supports all default colors. So to change its color just add color-[color] class to progressbar element.

<!-- Red progressbar -->
<div class="progressbar color-red" data-progress="20">
  <span></span>
</div>

<!-- Green progressbar -->
<div class="progressbar color-green" data-progress="50">
  <span></span>
</div>

<!-- Yellow infinite progressbar -->
<div class="progressbar-infinite color-yellow"></div>

<!-- Multicolor infinite progressbar -->
<div class="progressbar-infinite color-multi"></div>

Progressbar API

Progressbar comes with API that allows you to control Progressbar's progress, show and hide it. Let's look on appropriate App's properties and methods:

app.progressbar.set(el, progress, duration) - set progress for Determinate Progressbar.

  • el - string or HTMLElement. Progressbar element or element containing progressbar element. If string - CSS selector of such element.
  • progress - number. Progress in percents (from 0 to 100)
  • duration - number. Transition duration of progress change animation (in ms)
  • This method returns Progressbar HTMLElement

app.progressbar.set(progress, duration) - set progress for Determinate Progressbar which is under the app root element.

  • progress - number. Progress in percents (from 0 to 100)
  • duration - number. Transition duration of progress change animation (in ms)
  • This method returns Progressbar HTMLElement

app.progressbar.show(el, progress, color) - create and show or just show (if already presented) progressbar.

  • el - string or HTMLElement. Progressbar element container or element containing progressbar element. If string - CSS selector of such element. Optional
  • progress - number. Progress in percents (from 0 to 100). Optional
  • color - string. Color of progressbar, for example "white", "red", etc. from available color themes. Optional
  • This method returns Progressbar HTMLElement

All arguments here are optional:

  • If you omit el argument, it will look for (or create) progressbar element under app root
  • If you omit progress, it will show/create infinite progressbar
  • If you omit all arguments, then it will show/create infinite progressbar under the app root with default color

app.progressbar.hide(el) - hide Progressbar.

  • el - string or HTMLElement. Progressbar element container or element containing progressbar element. If string - CSS selector of such element. If not specified then it will look for such element under the app root element.

CSS Variables

Below is the list of related CSS variables (CSS custom properties).

Note that commented variables are not specified by default and their values is what they fallback to in this case.

:root {
  /*
  --f7-progressbar-progress-color: var(--f7-theme-color);
  */
}
.ios {
  --f7-progressbar-height: 4px;
  --f7-progressbar-border-radius: 4px;
  --f7-progressbar-bg-color: rgba(0, 0, 0, 0.3);
}
.ios .dark,
.ios.dark {
  --f7-progressbar-bg-color: rgba(255, 255, 255, 0.3);
}
.md {
  --f7-progressbar-height: 4px;
  --f7-progressbar-border-radius: 0px;
}
.md,
.md .dark,
.md [class*='color-'] {
  --f7-progressbar-bg-color: rgba(var(--f7-theme-color-rgb), 0.5);
}

Examples

progressbar.html
<template>
  <div class="page">
    <div class="navbar">
      <div class="navbar-bg"></div>
      <div class="navbar-inner sliding">
        <div class="title">Progress Bar</div>
      </div>
    </div>
    <div class="page-content">
      <div class="block">
        <p>In addition to <a href="/preloader/">Preloader</a>, Framework7 also comes with fancy animated determinate and
          infinite/indeterminate progress bars to indicate some activity.</p>
      </div>
      <div class="block-title">Determinate Progress Bar</div>
      <div class="block block-strong-ios block-outline-ios">
        <p>When progress bar is determinate it indicates how long an operation will take when the percentage complete is
          detectable.</p>
        <p>Inline determinate progress bar:</p>
        <div>
          <p><span data-progress="10" class="progressbar" id="demo-inline-progressbar"></span></p>
          <p class="segmented segmented-raised">
            <a class="button" @click=${()=> setInlineProgress(10)}>10%</a>
            <a class="button" @click=${()=> setInlineProgress(30)}>30%</a>
            <a class="button" @click=${()=> setInlineProgress(50)}>50%</a>
            <a class="button" @click=${()=> setInlineProgress(100)}>100%</a>
          </p>
        </div>
        <div>
          <p>Inline determinate load & hide:</p>
          <p id="demo-determinate-container"></p>
          <p>
            <a href="" class="button button-fill" @click=${()=> showDeterminate(true)}>Start Loading</a>
          </p>
        </div>
        <div>
          <p>Overlay with determinate progress bar on top of the app:</p>
          <p>
            <a href="" class="button button-fill" @click=${()=> showDeterminate(false)}>Start Loading</a>
          </p>
        </div>
      </div>
      <div class="block-title">Infinite Progress Bar</div>
      <div class="block block-strong-ios block-outline-ios">
        <p>When progress bar is infinite/indeterminate it requests that the user wait while something finishes when it’s
          not necessary to indicate how long it will take.</p>
        <p>Inline infinite progress bar</p>
        <p>
          <span class="progressbar-infinite"></span>
        </p>
        <p>Multi-color infinite progress bar</p>
        <p>
          <span class="progressbar-infinite color-multi"></span>
        </p>
        <div>
          <p>Overlay with infinite progress bar on top of the app</p>
          <p id="demo-infinite-container"></p>
          <p>
            <a href="" class="button button-fill" @click=${()=> showInfinite(false)}>Start Loading</a>
          </p>
        </div>
        <div>
          <p>Overlay with infinite multi-color progress bar on top of the app</p>
          <p>
            <a href="" class="button button-fill" @click=${()=> showInfinite(true)}>Start Loading</a>
          </p>
        </div>
      </div>
      <div class="block-title">Colors</div>
      <div class="list list-strong-ios list-outline-ios list-dividers-ios simple-list">
        <ul>
          <li>
            <div class="progressbar color-blue" data-progress="10"></div>
          </li>
          <li>
            <div class="progressbar color-red" data-progress="20"></div>
          </li>
          <li>
            <div class="progressbar color-pink" data-progress="30"></div>
          </li>
          <li>
            <div class="progressbar color-green" data-progress="80"></div>
          </li>
          <li>
            <div class="progressbar color-yellow" data-progress="90"></div>
          </li>
          <li>
            <div class="progressbar color-orange" data-progress="100"></div>
          </li>
        </ul>
      </div>
    </div>
  </div>
</template>
<script>
  export default (props, { $f7, $el, $onMounted, $onBeforeUnmount }) => {
    let determinateLoading = false;
    let infiniteLoading = false;
    const setInlineProgress = (value) => {
      $f7.progressbar.set('#demo-inline-progressbar', value);
    }
    const showDeterminate = (inline) => {
      if (determinateLoading) return;
      determinateLoading = true;
      var progressBarEl;
      if (inline) {
        progressBarEl = $f7.progressbar.show('#demo-determinate-container', 0);
      } else {
        progressBarEl = $f7.progressbar.show(0);
      }
      var progress = 0;
      function simulateLoading() {
        setTimeout(function () {
          var progressBefore = progress;
          progress += Math.random() * 20;
          $f7.progressbar.set(progressBarEl, progress);
          if (progressBefore < 100) {
            simulateLoading(); //keep "loading"
          }
          else {
            determinateLoading = false;
            $f7.progressbar.hide(progressBarEl); //hide
          }
        }, Math.random() * 200 + 200);
      }
      simulateLoading();
    }
    const showInfinite = (multiColor) => {
      if (infiniteLoading) return;
      infiniteLoading = true;
      if (multiColor) {
        $f7.progressbar.show('multi');
      } else {
        $f7.progressbar.show();
      }
      setTimeout(function () {
        infiniteLoading = false;
        $f7.progressbar.hide();
      }, 3000);
    }

    return $render;
  };
</script>