Skip to content

Linear Progress Component Code

Dependencies

This component requires:

  • Vue 3 with Composition API

Full Component Code

vue
<script setup>
import { computed } from 'vue';

const props = defineProps({
  absolute: {
    type: Boolean,
    default: false,
  },
  variant: {
    type: String,
    default: 'default',
  },
  height: {
    type: Number,
    default: 4,
  },
  indeterminate: {
    type: Boolean,
    default: false,
  },
  modelValue: {
    type: Number,
    default: 0,
  },
  max: {
    type: Number,
    default: 100,
  },
  rounded: {
    type: Boolean,
    default: false,
  },
});

const percentage = computed(() => Math.min(100, Math.max(0, (props.modelValue / props.max) * 100)));
</script>

<template>
  <div
    class="linear-progress-container"
    :class="{
      absolute,
      rounded,
      indeterminate,
      [variant]: true,
    }"
    :style="{
      height: `${height}px`,
    }"
  >
    <div
      class="linear-progress-bar"
      :class="{ 'indeterminate-bar': indeterminate }"
      :style="{
        width: indeterminate ? '40%' : percentage + '%',
      }"
    />
  </div>
</template>

<style scoped lang="scss">
.linear-progress-container {
  width: 100%;
  position: relative;
  overflow: hidden;

  &.absolute {
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
  }

  &.rounded {
    border-radius: 6.25rem;

    .linear-progress-bar {
      border-radius: 6.25rem;
    }
  }

  .linear-progress-bar {
    height: 100%;
    transition: width 0.3s ease;

    &.indeterminate-bar {
      position: absolute;
      left: -40%;
      animation: linear-indeterminate 1.2s infinite ease-in-out;
    }
  }

  &.indeterminate .linear-progress-bar {
    transition: none;
  }

  // Variants
  &.default {
    background-color: #e0e0e0;
    .linear-progress-bar {
      background-color: #000000;
    }
  }

  &.success {
    background-color: #e0e0e0;
    .linear-progress-bar {
      background-color: #22c55e;
    }
  }
}

@keyframes linear-indeterminate {
  0% {
    left: -40%;
    width: 40%;
  }
  50% {
    left: 20%;
    width: 60%;
  }
  100% {
    left: 100%;
    width: 80%;
  }
}
</style>