feat(ui): add ProgressBar component

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Your Name 2026-07-27 18:50:40 -04:00
parent 7bfd97c81c
commit 1e2a8c5b1e
2 changed files with 48 additions and 0 deletions

View file

@ -0,0 +1,29 @@
import { describe, it, expect } from 'vitest';
import { mount } from '@vue/test-utils';
import ProgressBar from './ProgressBar.vue';
const fill = (w: ReturnType<typeof mount>) => w.get('[data-testid="fill"]');
describe('ProgressBar', () => {
it('renders fraction as a width percentage', () => {
const wrapper = mount(ProgressBar, { props: { fraction: 0.5 } });
expect(fill(wrapper).attributes('style')).toContain('width: 50%');
});
it('clamps fractions below 0 and above 1', () => {
expect(fill(mount(ProgressBar, { props: { fraction: -0.3 } }))
.attributes('style')).toContain('width: 0%');
expect(fill(mount(ProgressBar, { props: { fraction: 1.8 } }))
.attributes('style')).toContain('width: 100%');
});
it('applies the accent color class by default', () => {
const wrapper = mount(ProgressBar, { props: { fraction: 0.5 } });
expect(fill(wrapper).classes()).toContain('bg-accent');
});
it('applies a chosen color class', () => {
const wrapper = mount(ProgressBar, { props: { fraction: 0.5, color: 'ok' } });
expect(fill(wrapper).classes()).toContain('bg-ok');
});
});

View file

@ -0,0 +1,19 @@
<template>
<div class="w-full bg-edge rounded-full overflow-hidden">
<div data-testid="fill" class="py-1 rounded-full" :class="`bg-${color}`"
:style="{ width: `${percent}%` }"/>
</div>
</template>
<script setup lang="ts">
import { computed } from 'vue';
const props = withDefaults(defineProps<{
fraction: number;
color?: 'accent' | 'ok' | 'warn';
}>(), {
color: 'accent',
});
const percent = computed(() => Math.min(100, Math.max(0, props.fraction * 100)));
</script>