mitlist/fe/src/components/valerie/VProgressBar.stories.ts

167 lines
4.0 KiB
TypeScript

import VProgressBar from './VProgressBar.vue';
import type { Meta, StoryObj } from '@storybook/vue3';
import { ref }
from 'vue'; // For interactive stories if needed
const meta: Meta<typeof VProgressBar> = {
title: 'Valerie/VProgressBar',
component: VProgressBar,
tags: ['autodocs'],
argTypes: {
value: { control: { type: 'range', min: 0, max: 100, step: 1 }, description: 'Current progress value.' }, // Assuming max=100 for control simplicity
max: { control: 'number', description: 'Maximum progress value.' },
showText: { control: 'boolean' },
striped: { control: 'boolean' },
label: { control: 'text', description: 'Accessible label for the progress bar.' },
valueText: { control: 'text', description: 'Custom text to display instead of percentage.' },
},
parameters: {
docs: {
description: {
component: 'A progress bar component to display the current completion status of a task. Supports customizable text, stripes, and ARIA attributes.',
},
},
},
// Decorator to provide a container for better visualization if needed
// decorators: [() => ({ template: '<div style="width: 300px; padding: 20px;"><story/></div>' })],
};
export default meta;
type Story = StoryObj<typeof VProgressBar>;
export const DefaultAt25Percent: Story = {
args: {
value: 25,
max: 100,
label: 'Task progress',
},
};
export const At0Percent: Story = {
args: {
...DefaultAt25Percent.args,
value: 0,
},
};
export const At50Percent: Story = {
args: {
...DefaultAt25Percent.args,
value: 50,
},
};
export const At75Percent: Story = {
args: {
...DefaultAt25Percent.args,
value: 75,
},
};
export const At100Percent: Story = {
args: {
...DefaultAt25Percent.args,
value: 100,
},
};
export const NoText: Story = {
args: {
...DefaultAt25Percent.args,
value: 60,
showText: false,
label: 'Loading data (visual only)',
},
};
export const NoStripes: Story = {
args: {
...DefaultAt25Percent.args,
value: 70,
striped: false,
label: 'Download status (no stripes)',
},
};
export const CustomMaxValue: Story = {
args: {
value: 10,
max: 20, // Max is 20, so 10 is 50%
label: 'Steps completed',
},
};
export const WithCustomValueText: Story = {
args: {
value: 3,
max: 5,
valueText: 'Step 3 of 5',
label: 'Onboarding process',
},
};
export const ValueOverMax: Story = {
args: {
...DefaultAt25Percent.args,
value: 150, // Should be capped at 100%
label: 'Overloaded progress',
},
};
export const NegativeValue: Story = {
args: {
...DefaultAt25Percent.args,
value: -20, // Should be capped at 0%
label: 'Invalid progress',
},
};
// Interactive story example (optional, if manual controls aren't enough)
export const InteractiveUpdate: Story = {
render: (args) => ({
components: { VProgressBar },
setup() {
const currentValue = ref(args.value || 10);
const intervalId = ref<NodeJS.Timeout | null>(null);
const startProgress = () => {
if (intervalId.value) clearInterval(intervalId.value);
currentValue.value = 0;
intervalId.value = setInterval(() => {
currentValue.value += 10;
if (currentValue.value >= (args.max || 100)) {
currentValue.value = args.max || 100;
if (intervalId.value) clearInterval(intervalId.value);
}
}, 500);
};
onBeforeUnmount(() => {
if (intervalId.value) clearInterval(intervalId.value);
});
return { ...args, currentValue, startProgress };
},
template: `
<div>
<VProgressBar
:value="currentValue"
:max="max"
:showText="showText"
:striped="striped"
:label="label"
:valueText="valueText"
/>
<button @click="startProgress" style="margin-top: 10px;">Start/Restart Progress</button>
</div>
`,
}),
args: {
value: 10, // Initial value for the ref
max: 100,
showText: true,
striped: true,
label: 'Dynamic Progress',
},
};