64 lines
1.4 KiB
Vue
64 lines
1.4 KiB
Vue
<template>
|
|
<div class="progress-container">
|
|
<div class="progress-bar"
|
|
:style="{ width: `${computedProgress}%`, backgroundColor: color }">
|
|
</div>
|
|
<span v-if="showPercentage" class="progress-text">{{ computedProgress
|
|
}}%</span>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { computed } from 'vue';
|
|
|
|
interface ProgressBarProps {
|
|
progress?: number;
|
|
color?: string;
|
|
showPercentage?: boolean;
|
|
min?: number;
|
|
max?: number;
|
|
}
|
|
|
|
const props = withDefaults(defineProps<ProgressBarProps>(), {
|
|
progress: 0,
|
|
color: '#4caf50',
|
|
showPercentage: false,
|
|
min: 0,
|
|
max: 100
|
|
});
|
|
|
|
const computedProgress = computed(() => {
|
|
// Ensure progress is between min and max
|
|
const clampedProgress = Math.max(props.min, Math.min(props.progress, props.max));
|
|
|
|
// Convert to percentage based on min and max range
|
|
return Math.round(((clampedProgress - props.min) / (props.max - props.min)) * 100);
|
|
});
|
|
</script>
|
|
|
|
<style scoped>
|
|
.progress-container {
|
|
width: 100%;
|
|
height: .5vh;
|
|
background-color: #e0e0e0;
|
|
border-radius: 4px;
|
|
overflow: hidden;
|
|
position: relative;
|
|
}
|
|
|
|
.progress-bar {
|
|
height: 100%;
|
|
border-radius: .25vh;
|
|
transition: width 0.3s ease;
|
|
}
|
|
|
|
.progress-text {
|
|
position: absolute;
|
|
top: 50%;
|
|
left: 50%;
|
|
transform: translate(-50%, -50%);
|
|
color: #000;
|
|
font-size: 1vh;
|
|
font-weight: bold;
|
|
}
|
|
</style> |