Skip to main content

ProgressBar

Die ProgressBar-Komponente zeigt den Fortschritt eines Vorgangs an und gibt dem Benutzer visuelles Feedback über den Status.

Import

import { ProgressBar } from '@smolitux/core';

Verwendung

Einfacher ProgressBar

<ProgressBar value={75} />

ProgressBar mit Label

<ProgressBar value={75} showLabel />

Verschiedene Größen

<ProgressBar value={75} size="xs" className="mb-2" />
<ProgressBar value={75} size="sm" className="mb-2" />
<ProgressBar value={75} size="md" className="mb-2" />
<ProgressBar value={75} size="lg" />

Verschiedene Farben

<ProgressBar value={75} color="primary" className="mb-2" />
<ProgressBar value={75} color="secondary" className="mb-2" />
<ProgressBar value={75} color="success" className="mb-2" />
<ProgressBar value={75} color="warning" className="mb-2" />
<ProgressBar value={75} color="error" className="mb-2" />
<ProgressBar value={75} color="info" />

Verschiedene Varianten

<ProgressBar value={75} variant="default" className="mb-2" />
<ProgressBar value={75} variant="striped" className="mb-2" />
<ProgressBar value={75} variant="animated" />

Abgerundeter ProgressBar

<ProgressBar value={75} rounded />

Gradient-Stil

<ProgressBar value={75} appearance="gradient" />

Invertierter ProgressBar

<ProgressBar value={75} inverted />

Unbestimmter Fortschritt

<ProgressBar indeterminate />

Benutzerdefiniertes Label

<ProgressBar 
value={75}
label={<span className="font-bold">75% abgeschlossen</span>}
/>

Verschiedene Label-Formate

<ProgressBar value={75} showLabel labelFormat="percentage" className="mb-2" />
<ProgressBar value={75} showLabel labelFormat="value" className="mb-2" />
<ProgressBar value={75} showLabel labelFormat="valueAndMax" />

Benutzerdefinierter Min/Max-Bereich

<ProgressBar value={7} min={0} max={10} showLabel />

Props

PropTypStandardBeschreibung
valuenumber-Aktueller Wert (0-100)
maxnumber100Maximaler Wert
minnumber0Minimaler Wert
showLabelbooleanfalseLabel anzeigen
labelFormat'percentage' | 'value' | 'valueAndMax''percentage'Label-Format
labelReactNode-Benutzerdefiniertes Label
variant'default' | 'striped' | 'animated''default'Variante des ProgressBars
size'xs' | 'sm' | 'md' | 'lg''md'Größe des ProgressBars
color'primary' | 'secondary' | 'success' | 'warning' | 'error' | 'info''primary'Farbe des ProgressBars
roundedbooleanfalseRadius des ProgressBars
appearance'solid' | 'gradient''solid'ProgressBar-Stil
invertedbooleanfalseInvertierter Fortschritt (von rechts nach links)
indeterminatebooleanfalseIndeterminate-Status (für unbekannten Fortschritt)
classNamestring-Zusätzliche CSS-Klassen

Barrierefreiheit

Die ProgressBar-Komponente ist für Barrierefreiheit optimiert:

  • Verwendet die korrekten ARIA-Attribute (role="progressbar", aria-valuenow, aria-valuemin, aria-valuemax)
  • Bietet visuelles Feedback durch verschiedene Farben und Größen
  • Unterstützt Screenreader durch semantische Struktur

Beispiele

Fortschrittsanzeige für Datei-Upload

function FileUploadProgress() {
const [progress, setProgress] = useState(0);
const [isUploading, setIsUploading] = useState(false);

const startUpload = () => {
setIsUploading(true);
setProgress(0);

// Simuliere einen Upload-Fortschritt
const interval = setInterval(() => {
setProgress(prev => {
if (prev >= 100) {
clearInterval(interval);
setIsUploading(false);
return 100;
}
return prev + 5;
});
}, 300);
};

return (
<div className="max-w-md">
<div className="mb-4">
<label className="block text-sm font-medium text-gray-700 mb-1">
Datei auswählen
</label>
<input
type="file"
className="block w-full text-sm text-gray-500 file:mr-4 file:py-2 file:px-4 file:rounded-md file:border-0 file:text-sm file:font-semibold file:bg-primary-50 file:text-primary-700 hover:file:bg-primary-100"
/>
</div>

{isUploading || progress === 100 ? (
<div className="mb-4">
<ProgressBar
value={progress}
variant={isUploading ? "animated" : "default"}
color={progress === 100 ? "success" : "primary"}
showLabel
/>
<p className="text-sm text-gray-500 mt-1">
{progress === 100 ? 'Upload abgeschlossen' : 'Wird hochgeladen...'}
</p>
</div>
) : null}

<button
className="px-4 py-2 bg-primary-500 text-white rounded-md hover:bg-primary-600 disabled:opacity-50"
onClick={startUpload}
disabled={isUploading}
>
{isUploading ? 'Wird hochgeladen...' : 'Upload starten'}
</button>
</div>
);
}

Mehrstufiger Fortschritt

function MultiStepProgress() {
const steps = [
{ id: 1, name: 'Persönliche Daten', status: 'complete' },
{ id: 2, name: 'Adresse', status: 'current' },
{ id: 3, name: 'Zahlungsmethode', status: 'upcoming' },
{ id: 4, name: 'Bestätigung', status: 'upcoming' }
];

const currentStep = steps.findIndex(step => step.status === 'current') + 1;
const progress = (currentStep - 1) / (steps.length - 1) * 100;

return (
<div className="max-w-2xl mx-auto">
<ProgressBar
value={progress}
appearance="gradient"
rounded
className="mb-6"
/>

<div className="flex justify-between">
{steps.map((step) => (
<div
key={step.id}
className={`flex flex-col items-center ${
step.status === 'upcoming' ? 'text-gray-400' :
step.status === 'current' ? 'text-primary-600 font-medium' :
'text-success-600'
}`}
>
<div className={`
w-8 h-8 rounded-full flex items-center justify-center mb-2
${step.status === 'upcoming' ? 'border border-gray-300' :
step.status === 'current' ? 'bg-primary-100 border-2 border-primary-500' :
'bg-success-100 border-2 border-success-500'}
`}>
{step.status === 'complete' ? (
<svg className="w-5 h-5 text-success-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
</svg>
) : (
step.id
)}
</div>
<span className="text-sm">{step.name}</span>
</div>
))}
</div>
</div>
);
}

Skill-Level-Anzeige

function SkillLevelProgress() {
const skills = [
{ name: 'HTML', level: 90 },
{ name: 'CSS', level: 85 },
{ name: 'JavaScript', level: 75 },
{ name: 'React', level: 80 },
{ name: 'Node.js', level: 65 }
];

return (
<div className="max-w-md">
<h2 className="text-xl font-bold mb-4">Fähigkeiten</h2>
<div className="space-y-4">
{skills.map((skill) => (
<div key={skill.name}>
<div className="flex justify-between mb-1">
<span className="text-sm font-medium">{skill.name}</span>
<span className="text-sm text-gray-500">{skill.level}%</span>
</div>
<ProgressBar
value={skill.level}
size="sm"
color={
skill.level >= 80 ? 'success' :
skill.level >= 60 ? 'primary' :
'warning'
}
rounded
/>
</div>
))}
</div>
</div>
);
}

Countdown-Timer mit Fortschrittsanzeige

function CountdownProgress() {
const [timeLeft, setTimeLeft] = useState(60); // 60 Sekunden
const [isActive, setIsActive] = useState(false);

useEffect(() => {
let interval = null;

if (isActive && timeLeft > 0) {
interval = setInterval(() => {
setTimeLeft(timeLeft => timeLeft - 1);
}, 1000);
} else if (timeLeft === 0) {
setIsActive(false);
}

return () => clearInterval(interval);
}, [isActive, timeLeft]);

const startTimer = () => {
setTimeLeft(60);
setIsActive(true);
};

const resetTimer = () => {
setTimeLeft(60);
setIsActive(false);
};

const progress = (timeLeft / 60) * 100;

return (
<div className="max-w-md">
<div className="text-center mb-4">
<span className="text-3xl font-bold">{timeLeft}</span>
<span className="text-gray-500 ml-1">Sekunden</span>
</div>

<ProgressBar
value={progress}
color={
progress > 66 ? 'success' :
progress > 33 ? 'warning' :
'error'
}
variant={isActive ? 'animated' : 'default'}
rounded
className="mb-4"
/>

<div className="flex space-x-2">
{!isActive ? (
<button
className="px-4 py-2 bg-primary-500 text-white rounded-md hover:bg-primary-600 flex-1"
onClick={startTimer}
>
Start
</button>
) : (
<button
className="px-4 py-2 bg-gray-500 text-white rounded-md hover:bg-gray-600 flex-1"
onClick={resetTimer}
>
Zurücksetzen
</button>
)}
</div>
</div>
);
}