
Syncfusion React Progress Bar
- 336 installs
- 3 repo stars
- Updated July 28, 2026
- syncfusion/react-ui-components-skills
Use syncfusion-react-progress-bar for development tasks
About
syncfusion-react-progress-bar: A skill for development. This provides functionality for development workflows.
- syncfusion-react-progress-bar
Syncfusion React Progress Bar by the numbers
- 336 all-time installs (skills.sh)
- +22 installs in the week ending Jul 27, 2026 (Skillselion tracking)
- Ranked #1,199 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
- Data as of Jul 29, 2026 (Skillselion catalog sync)
npx skills add https://github.com/syncfusion/react-ui-components-skills --skill syncfusion-react-progress-barAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 336 |
|---|---|
| repo stars | ★ 3 |
| Last updated | July 28, 2026 |
| Repository | syncfusion/react-ui-components-skills ↗ |
What it does
Use syncfusion-react-progress-bar for development tasks
Files
Implementing React Progress Bar Component
A comprehensive skill for implementing the Syncfusion React Progress Bar component for visual progress feedback, loading states, and task completion indicators.
When to Use This Skill
Use this skill when you need to:
- Display progress of file uploads or downloads
- Show task completion percentage
- Indicate loading states (determinate or indeterminate)
- Visualize data processing or long-running operations
- Create progress spinners or circular indicators
- Handle secondary progress (buffer scenarios)
- Customize progress bar appearance and colors
- Implement animations and transitions
- Handle progress events and callbacks
- Ensure accessibility compliance for progress indicators
Component Overview
The Syncfusion React Progress Bar is a lightweight component that visualizes task progress in linear, circular, or semi-circular shapes. It supports multiple states (determinate, indeterminate, buffer) and features animations, customization, and full accessibility support.
Key Features:
- Multiple Types: Linear, Circular, Semi-Circular shapes
- States: Determinate (known progress), Indeterminate (unknown), Buffer (secondary progress)
- Animations: Smooth transitions with configurable duration and delay
- Customization: Colors, heights, labels, themes
- Events: Progress tracking, start/complete callbacks
- Accessibility: WCAG 2.1 compliant with ARIA support
- RTL Support: Right-to-left language support
Documentation Guide
Getting Started
📄 Read: references/getting-started.md
- Installation and package setup
- Basic progress bar implementation
- CSS imports and themes
- First component example
- TypeScript vs JavaScript
Types and Shapes
📄 Read: references/types-and-shapes.md
- Linear progress bar
- Circular progress bar
- Semi-circular progress bar
- Shape variations and code examples
- Choosing the right type for your use case
States and Modes
📄 Read: references/states-and-modes.md
- Determinate state (known progress, default)
- Indeterminate state (unknown progress, spinners)
- Buffer/Secondary progress (dual progress indicators)
- Combining multiple states
- Real-world scenarios for each state
Customization and Styling
📄 Read: references/customization-and-styling.md
- Sizing (height, width configurations)
- Colors and fill customization
- Labels and text display
- Theme application
- CSS customization
- Responsive design patterns
Animations, Events, and Accessibility
📄 Read: references/animations-events-accessibility.md
- Animation configuration and control
- Event handlers for progress tracking
- Using callbacks for task completion
- WCAG compliance
- ARIA attributes and labels
- Tooltip and annotation support
- Troubleshooting common issues
API Reference
📄 Read: references/api.md
- Full list of public properties, methods and events for
ProgressBarComponent(see file).
Quick Start Example
import { ProgressBarComponent } from '@syncfusion/ej2-react-progressbar';
function App() {
return (
<div>
{/* Linear Determinate Progress Bar */}
<ProgressBarComponent
id="linear"
type="Linear"
height="60"
value={75}
animation={{
enable: true,
duration: 2000,
delay: 0
}}
/>
{/* Circular Progress Bar */}
<ProgressBarComponent
id="circular"
type="Circular"
height="160px"
value={60}
/>
{/* Indeterminate Loading Spinner */}
<ProgressBarComponent
id="indeterminate"
type="Linear"
height="60"
isIndeterminate={true}
animation={{
enable: true,
duration: 2000,
delay: 0
}}
/>
</div>
);
}
export default App;Common Patterns
1. File Upload Progress
<ProgressBarComponent
id="upload"
type="Linear"
value={uploadPercentage}
showProgressValue={true}
progressValueFormat="N0 '%'"
/>2. Loading Spinner
<ProgressBarComponent
id="spinner"
type="Circular"
isIndeterminate={true}
height="100px"
/>3. Buffer Progress (Buffered Loading)
<ProgressBarComponent
id="buffer"
type="Linear"
value={40}
secondaryProgress={80}
height="60"
/>4. Determinate Task Progress
<ProgressBarComponent
id="task"
type="Linear"
value={taskCompletionPercentage}
showProgressValue={true}
animation={{
enable: true,
duration: 1500
}}
/>Key Props Reference
Core Properties
| Prop | Type | Default | Purpose |
|---|---|---|---|
id | string | - | Unique identifier for component |
type | "Linear" \ | "Circular" \ | "Semicircle" |
value | number | 0 | Current progress value (0-100) |
secondaryProgress | number | 0 | Secondary/buffer progress value |
isIndeterminate | boolean | false | Indeterminate/loading mode |
height | string | "100%" | Height of progress bar (CSS value) |
width | string | "100%" | Width of progress bar (CSS value) |
showProgressValue | boolean | false | Display percentage text |
Animation & Styling
| Prop | Type | Default | Purpose |
|---|---|---|---|
animation | AnimationModel | - | Animation config: { enable, duration, delay } |
progressColor | string | - | Color for progress fill (CSS color) |
trackColor | string | - | Color for track background |
progressThickness | number | 4 | Progress bar thickness (pixels) |
trackThickness | number | 4 | Track thickness (pixels) |
isStriped | boolean | false | Striped pattern appearance |
isGradient | boolean | false | Gradient fill effect |
cssClass | string | - | Custom CSS class for styling |
Advanced Features
| Prop | Type | Default | Purpose |
|---|---|---|---|
cornerRadius | "Round" \ | "Auto" | "Auto" |
enableRtl | boolean | false | Right-to-left layout |
enablePieProgress | boolean | false | Pie view for circular type |
enableProgressSegments | boolean | false | Segmented progress rendering |
segmentCount | number | 1 | Number of segments |
rangeColors | RangeColorModel[] | - | Colors for different ranges |
minimum | number | 0 | Minimum progress value |
maximum | number | 100 | Maximum progress value |
Label & Format
| Prop | Type | Default | Purpose |
|---|---|---|---|
progressValueFormat | string | "N0 '%'" | Format for value display (e.g., "N2 '%'") |
labelOnTrack | boolean | true | Show label on the track |
labelStyle | FontModel | - | Font styling for label |
When to use each:
- type: Choose based on space: Linear (full-width), Circular/Semicircle (compact)
- value: Update via state to reflect real progress
- isIndeterminate: Use for unknown duration tasks (loading, processing)
- secondaryProgress: Show buffer/estimated vs. actual progress
- animation: Enhance UX with smooth transitions (disable for real-time high-frequency updates)
- cornerRadius: "Round" for modern look, "Auto" for default
- segmentCount: Split progress into visual segments (e.g., 10 segments = 10% per segment)
Common Use Cases with Code Examples
Use Case 1: File Upload/Download
const [uploadProgress, setUploadProgress] = useState(0);
<ProgressBarComponent
type="Linear"
value={uploadProgress}
showProgressValue={true}
progressValueFormat="N0 '%'"
height="30"
animation={{ enable: true, duration: 500 }}
/>Best Practices:
- Use Linear type for wide displays
- Update value from upload progress events
- Show estimated time in addition to percentage
- Optional
secondaryProgressfor pre-fetched bytes
Use Case 2: Loading State (Unknown Duration)
<ProgressBarComponent
type="Circular"
isIndeterminate={true}
height="100px"
animation={{ enable: true, duration: 2000 }}
/>Best Practices:
- Use Circular for compact display
- Keep
isIndeterminate={true}until operation completes - Spinner continues animating indefinitely
- Replace with determinate once progress can be tracked
Use Case 3: Data Processing
const [processProgress, setProcessProgress] = useState(0);
const totalItems = 100;
useEffect(() => {
processItems().then(processed => {
setProcessProgress((processed / totalItems) * 100);
});
}, []);
<ProgressBarComponent
type="Linear"
value={processProgress}
showProgressValue={true}
height="30"
/>Best Practices:
- Update value as items are processed
- Show item count: "25 of 100 items"
- Show elapsed time and estimated remaining
- Display success/error message on completion
Use Case 4: Multiple Tasks (Buffering/Streaming)
const [processedItems, setProcessedItems] = useState(30);
const [queuedItems, setQueuedItems] = useState(75);
const totalItems = 100;
<ProgressBarComponent
type="Linear"
value={(processedItems / totalItems) * 100}
secondaryProgress={(queuedItems / totalItems) * 100}
height="30"
/>Best Practices:
- Primary progress (value) = actual processed
- Secondary progress = queued/buffered items
- Great for streaming/video buffering scenarios
- Also works for task queue management
Use Case 5: Multi-Step Workflow
const steps = ['Validation', 'Processing', 'Upload', 'Confirmation'];
const [currentStep, setCurrentStep] = useState(0);
const progress = ((currentStep + 1) / steps.length) * 100;
<ProgressBarComponent
type="Linear"
value={progress}
showProgressValue={true}
height="30"
/>
<div>
{steps.map((step, i) => (
<div key={i}>
{step} {i === currentStep ? '🔄' : i < currentStep ? '✓' : '⏳'}
</div>
))}
</div>Best Practices:
- Calculate progress as (currentStep / totalSteps) * 100
- Show step indicators alongside progress bar
- Highlight current step
- Disable user interactions during processing
Advanced Usage Patterns
1. Value Binding with State Management
import { useState, useEffect } from 'react';
import { ProgressBarComponent } from '@syncfusion/ej2-react-progressbar';
function ProgressManager() {
const [progress, setProgress] = useState(0);
const [isProcessing, setIsProcessing] = useState(false);
useEffect(() => {
if (!isProcessing) return;
const interval = setInterval(() => {
setProgress(prev => {
if (prev >= 100) {
setIsProcessing(false);
return 100;
}
return prev + Math.random() * 15;
});
}, 500);
return () => clearInterval(interval);
}, [isProcessing]);
return (
<div>
<ProgressBarComponent
type="Linear"
value={progress}
showProgressValue={true}
/>
<button
onClick={() => { setProgress(0); setIsProcessing(true); }}
disabled={isProcessing}
>
{isProcessing ? 'Processing...' : 'Start'}
</button>
</div>
);
}
export default ProgressManager;2. Animation Configuration Patterns
// Real-time updates (no animation for smoothness)
animation={{ enable: false }}
// User interactions (quick feedback)
animation={{ enable: true, duration: 300, delay: 0 }}
// Page loads (smooth transition)
animation={{ enable: true, duration: 1500, delay: 0 }}
// Cascading effects (staggered)
animation={{ enable: true, duration: 1000, delay: 200 }}
// Loading spinners (continuous)
animation={{ enable: true, duration: 2000 }}3. Conditional Rendering Based on State
function ConditionalProgress() {
const [state, setState] = useState('idle'); // idle | loading | success | error
const [value, setValue] = useState(0);
const getProgressType = () => {
if (state === 'loading') return 'Circular';
return 'Linear';
};
return (
<>
{state === 'loading' && (
<ProgressBarComponent
type={getProgressType()}
isIndeterminate={state === 'loading'}
height="100px"
/>
)}
{state === 'success' && (
<div style={{ color: 'green' }}>✓ Complete</div>
)}
{state === 'error' && (
<div style={{ color: 'red' }}>✗ Error occurred</div>
)}
</>
);
}
export default ConditionalProgress;4. Event Handling for Tracking
function ProgressWithEvents() {
const handleStart = () => {
console.log('Progress started');
analytics.track('progress_started');
};
const handleComplete = () => {
console.log('Progress completed');
analytics.track('progress_completed');
showNotification('Task completed!');
};
const handleValueChange = (args) => {
console.log(`Progress: ${args.value}%`);
// Milestone tracking
if (args.value === 50) {
analytics.track('progress_midpoint');
}
};
return (
<ProgressBarComponent
type="Linear"
value={75}
progressStart={handleStart}
progressComplete={handleComplete}
valueChanged={handleValueChange}
/>
);
}
export default ProgressWithEvents;5. Responsive Design
function ResponsiveProgress() {
const [isMobile, setIsMobile] = useState(window.innerWidth < 768);
useEffect(() => {
const handleResize = () => setIsMobile(window.innerWidth < 768);
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
return (
<ProgressBarComponent
type={isMobile ? 'Semicircle' : 'Linear'}
value={65}
height={isMobile ? '100px' : '40'}
showProgressValue={true}
/>
);
}
export default ResponsiveProgress;6. Error Handling & Retry Logic
async function uploadWithRetry(file, maxRetries = 3) {
const [attempts, setAttempts] = useState(0);
const [progress, setProgress] = useState(0);
const [error, setError] = useState(null);
for (let i = 0; i < maxRetries; i++) {
try {
setAttempts(i + 1);
const result = await uploadFile(file, (p) => setProgress(p));
return result;
} catch (err) {
if (i === maxRetries - 1) {
setError(`Failed after ${maxRetries} attempts`);
throw err;
}
// Retry with exponential backoff
await new Promise(r => setTimeout(r, Math.pow(2, i) * 1000));
}
}
}Integration with Common Patterns
With React Query
import { useQuery } from '@tanstack/react-query';
function DataProcessing() {
const { data, isLoading, progress } = useQuery({
queryKey: ['processData'],
queryFn: async ({ signal }) => {
// Process with progress tracking
}
});
return (
<ProgressBarComponent
isIndeterminate={isLoading}
value={progress || 0}
/>
);
}With Redux
import { useSelector, useDispatch } from 'react-redux';
function ReduxProgress() {
const { progress, isLoading } = useSelector(state => state.upload);
const dispatch = useDispatch();
return (
<ProgressBarComponent
value={progress}
isIndeterminate={isLoading}
progressComplete={() => dispatch(resetProgress())}
/>
);
}Animations, Events, and Accessibility
Table of contents
- Animations
- Animation Configuration
- Common Animation Patterns
- Indeterminate Animation
- Real-World Animation Example
- Event Handling
- Available Events
- Event Usage Examples
- Multi-Step Process with Events
- Accessibility
- WCAG 2.1 Compliance
- Adding ARIA Labels
- Accessible Progress Pattern
- Screen Reader Announcements
- CSS for Screen Readers
- Tooltips and Annotations
- Tooltip Support (Built-in Syncfusion Tooltips)
- Tooltip with Custom Styling
- Annotations with Tooltips
- Custom Tooltip Implementation (External Library)
- Advanced Scenarios
- Scenario 1: File Upload with Progress Tracking
- Scenario 2: Real-time Data Processing
- Scenario 3: Multi-Type Progress Dashboard
- Next Steps
Animations
Control smooth transitions and visual effects for your progress bar.
Animation Configuration
import { ProgressBarComponent } from '@syncfusion/ej2-react-progressbar';
<ProgressBarComponent
type="Linear"
value={80}
animation={{
enable: true,
duration: 2000, // milliseconds
delay: 0 // milliseconds before animation starts
}}
/>Common Animation Patterns
Instant (no animation):
<ProgressBarComponent
type="Linear"
value={50}
animation={{
enable: false
}}
/>Quick animation (500ms):
<ProgressBarComponent
type="Linear"
value={50}
animation={{
enable: true,
duration: 500,
delay: 0
}}
/>Smooth animation (2000ms):
<ProgressBarComponent
type="Linear"
value={50}
animation={{
enable: true,
duration: 2000,
delay: 0
}}
/>Delayed animation:
<ProgressBarComponent
type="Linear"
value={50}
animation={{
enable: true,
duration: 1500,
delay: 500 // Wait 500ms before animating
}}
/>Indeterminate Animation
Indeterminate state has continuous animation:
// Adjust animation speed for indeterminate spinners
<ProgressBarComponent
type="Circular"
isIndeterminate={true}
animation={{
enable: true,
duration: 2000 // Duration of spin cycle
}}
/>Real-World Animation Example
import { useState } from 'react';
import { ProgressBarComponent } from '@syncfusion/ej2-react-progressbar';
function AnimatedProgress() {
const [progress, setProgress] = useState(0);
const [isRunning, setIsRunning] = useState(false);
const startAnimation = () => {
if (isRunning) return;
setIsRunning(true);
setProgress(0);
let current = 0;
const interval = setInterval(() => {
current += Math.random() * 25;
if (current >= 100) {
setProgress(100);
clearInterval(interval);
setTimeout(() => {
setProgress(0);
setIsRunning(false);
}, 1000);
} else {
setProgress(current);
}
}, 600);
};
return (
<div>
<ProgressBarComponent
type="Linear"
value={progress}
height="40"
showProgressValue={true}
animation={{
enable: true,
duration: 600,
delay: 0
}}
/>
<button onClick={startAnimation} disabled={isRunning}>
{isRunning ? 'Running...' : 'Start Animation'}
</button>
</div>
);
}
export default AnimatedProgress;---
Event Handling
Track progress bar events for custom logic.
Available Events
<ProgressBarComponent
type="Linear"
value={50}
progressStart={() => console.log('Animation started')}
progressComplete={() => console.log('Animation completed')}
/>Event Usage Examples
Complete Handler:
function ProgressComplete() {
const handleComplete = () => {
alert('Task completed!');
// Trigger next action
// Update UI
// Send notification
};
return (
<ProgressBarComponent
type="Linear"
value={100}
progressComplete={handleComplete}
/>
);
}
export default ProgressComplete;Start Handler:
function ProgressStart() {
const handleStart = () => {
console.log('Progress animation started');
// Log event
// Track analytics
// Start timer
};
return (
<ProgressBarComponent
type="Linear"
value={50}
progressStart={handleStart}
/>
);
}
export default ProgressStart;Multi-Step Process with Events
import { useState } from 'react';
import { ProgressBarComponent } from '@syncfusion/ej2-react-progressbar';
function MultiStepWithEvents() {
const [step, setStep] = useState(0);
const [completed, setCompleted] = useState(false);
const steps = ['Validation', 'Processing', 'Upload', 'Confirm'];
const progress = ((step + 1) / steps.length) * 100;
const handleComplete = () => {
if (step < steps.length - 1) {
setStep(step + 1);
} else {
setCompleted(true);
}
};
return (
<div>
<h3>Current: {steps[step]}</h3>
<ProgressBarComponent
type="Linear"
value={progress}
progressComplete={handleComplete}
showProgressValue={true}
/>
{completed && <p>✓ All steps completed!</p>}
</div>
);
}
export default MultiStepWithEvents;---
Accessibility
Ensure your progress bars are accessible to all users.
WCAG 2.1 Compliance
The Syncfusion Progress Bar includes built-in accessibility features:
- Semantic HTML structure
- ARIA labels and roles
- Keyboard navigation support
- Screen reader support
Adding ARIA Labels
<ProgressBarComponent
id="accessible-progress"
type="Linear"
value={65}
role="progressbar"
aria-valuenow={65}
aria-valuemin={0}
aria-valuemax={100}
aria-label="File upload progress"
aria-describedby="progress-description"
/>
<p id="progress-description">Uploading: 65% complete (1.3 MB of 2 MB)</p>Accessible Progress Pattern
import { useState } from 'react';
import { ProgressBarComponent } from '@syncfusion/ej2-react-progressbar';
function AccessibleFileUpload() {
const [progress, setProgress] = useState(0);
const [fileName, setFileName] = useState('');
const totalSize = 2000000; // 2MB
const uploadedSize = (progress / 100) * totalSize;
const handleUpload = (file) => {
setFileName(file.name);
// Simulate upload
const interval = setInterval(() => {
setProgress(prev => {
if (prev >= 100) {
clearInterval(interval);
return 100;
}
return prev + 10;
});
}, 500);
};
return (
<div>
<label htmlFor="upload-progress">
Uploading: {fileName}
</label>
<ProgressBarComponent
id="upload-progress"
type="Linear"
value={progress}
height="30"
showProgressValue={true}
role="progressbar"
aria-label={`Uploading ${fileName}: ${progress}% complete`}
aria-describedby="upload-details"
/>
<div id="upload-details">
{Math.round(uploadedSize / 1000)} KB of{' '}
{Math.round(totalSize / 1000)} KB uploaded
</div>
</div>
);
}
export default AccessibleFileUpload;Screen Reader Announcements
import { useState } from 'react';
import { ProgressBarComponent } from '@syncfusion/ej2-react-progressbar';
function ScreenReaderProgress() {
const [progress, setProgress] = useState(0);
const [announcement, setAnnouncement] = useState('');
const updateProgress = (newProgress) => {
setProgress(newProgress);
// Announce milestone achievements
if (newProgress === 25) {
setAnnouncement('25% complete');
} else if (newProgress === 50) {
setAnnouncement('50% complete');
} else if (newProgress === 75) {
setAnnouncement('75% complete');
} else if (newProgress === 100) {
setAnnouncement('Processing complete');
}
};
return (
<div>
{/* Live region for announcements */}
<div
role="status"
aria-live="polite"
aria-atomic="true"
className="sr-only"
>
{announcement}
</div>
<ProgressBarComponent
type="Linear"
value={progress}
aria-label="Processing progress"
/>
<button onClick={() => updateProgress(progress + 25)}>
Advance Progress
</button>
</div>
);
}
export default ScreenReaderProgress;CSS for Screen Readers
/* Hide visually but keep for screen readers */
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-width: 0;
}---
Tooltips and Annotations
Add additional information to your progress bars using built-in Syncfusion tooltip and annotation features.
Tooltip Support (Built-in Syncfusion Tooltips)
Use the tooltip property with TooltipSettingsModel to enable built-in tooltips:
import { ProgressBarComponent } from '@syncfusion/ej2-react-progressbar';
function TooltipProgress() {
return (
<ProgressBarComponent
id="progress-with-tooltip"
type="Linear"
value={65}
height="30"
showProgressValue={true}
tooltip={{
enable: true,
showTooltipOnHover: true,
format: 'Progress: ${value}%'
}}
/>
);
}
export default TooltipProgress;Tooltip Properties:
enable: true- Activates tooltip functionalityshowTooltipOnHover: true- Displays tooltip when user hovers over the progress barformat: string- Formats tooltip content using${value}placeholder to display the progress value
Tooltip with Custom Styling
import { ProgressBarComponent } from '@syncfusion/ej2-react-progressbar';
function StyledTooltip() {
return (
<ProgressBarComponent
type="Linear"
value={45}
height="30"
tooltip={{
enable: true,
showTooltipOnHover: true,
format: '${value}% Complete',
fill: '#3366FF',
textStyle: {
color: '#FFFFFF',
size: '12px',
bold: true
}
}}
/>
);
}
export default StyledTooltip;Annotations with Tooltips
Add annotations to the center of circular progress bars to mark milestones:
import {
ProgressBarComponent,
ProgressBarAnnotationsDirective,
ProgressBarAnnotationDirective,
Inject,
ProgressAnnotation
} from '@syncfusion/ej2-react-progressbar';
function AnnotatedProgress() {
const content = '<div style="font-size:18px;font-weight:bold;color:#ffffff;"><span>60%</span></div>';
return (
<ProgressBarComponent
id="circular-annotation"
type="Circular"
value={60}
height="160px"
innerRadius="190%"
trackThickness={80}
cornerRadius="Round"
trackColor="#FFD939"
showProgressValue={true}
tooltip={{
enable: true,
showTooltipOnHover: true,
format: 'Current: ${value}%'
}}
>
<Inject services={[ProgressAnnotation]} />
<ProgressBarAnnotationsDirective>
<ProgressBarAnnotationDirective content={content} />
</ProgressBarAnnotationsDirective>
</ProgressBarComponent>
);
}
export default AnnotatedProgress;Custom Tooltip Implementation (External Library)
If you need advanced tooltip features, use external libraries like react-tooltip:
import { useState } from 'react';
import { ProgressBarComponent } from '@syncfusion/ej2-react-progressbar';
function CustomTooltip() {
const [showTooltip, setShowTooltip] = useState(false);
const [tooltipText, setTooltipText] = useState('');
const [progress, setProgress] = useState(50);
const handleMouseEnter = () => {
setShowTooltip(true);
setTooltipText(`Progress: ${progress}%`);
};
const handleMouseLeave = () => {
setShowTooltip(false);
};
return (
<div
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
style={{ position: 'relative' }}
>
<ProgressBarComponent
type="Linear"
value={progress}
height="30"
showProgressValue={true}
/>
{showTooltip && (
<div
style={{
position: 'absolute',
top: '-35px',
left: '50%',
transform: 'translateX(-50%)',
background: '#333',
color: '#fff',
padding: '8px 12px',
borderRadius: '4px',
fontSize: '12px',
whiteSpace: 'nowrap',
zIndex: 1000
}}
>
{tooltipText}
</div>
)}
</div>
);
}
export default CustomTooltip;---
Advanced Scenarios
Scenario 1: File Upload with Progress Tracking
import { useState } from 'react';
import { ProgressBarComponent } from '@syncfusion/ej2-react-progressbar';
function FileUploadWithTracking() {
const [uploadState, setUploadState] = useState({
isLoading: true,
progress: 0,
fileName: 'document.pdf',
uploadedSize: 0,
totalSize: 2000000
});
const handleUpload = async (file) => {
setUploadState({
isLoading: true,
progress: 0,
fileName: file.name,
uploadedSize: 0,
totalSize: file.size
});
// Simulate chunked upload
const chunkSize = 100000;
let uploaded = 0;
while (uploaded < file.size) {
const chunk = Math.min(chunkSize, file.size - uploaded);
uploaded += chunk;
const progress = (uploaded / file.size) * 100;
setUploadState(prev => ({
...prev,
progress,
uploadedSize: uploaded
}));
// Simulate network delay
await new Promise(resolve => setTimeout(resolve, 200));
}
setUploadState(prev => ({
...prev,
isLoading: false,
progress: 100
}));
};
const { progress, fileName, uploadedSize, totalSize } = uploadState;
return (
<div>
<h3>Upload: {fileName}</h3>
<ProgressBarComponent
type="Linear"
value={progress}
isIndeterminate={uploadState.isLoading}
height="30"
showProgressValue={true}
/>
<p>
{Math.round(uploadedSize / 1000)} KB /{' '}
{Math.round(totalSize / 1000)} KB
</p>
</div>
);
}
export default FileUploadWithTracking;Scenario 2: Real-time Data Processing
import { useState, useEffect } from 'react';
import { ProgressBarComponent } from '@syncfusion/ej2-react-progressbar';
function DataProcessing() {
const [state, setState] = useState({
processed: 0,
total: 1000,
currentItem: null,
startTime: Date.now()
});
useEffect(() => {
const interval = setInterval(() => {
setState(prev => {
if (prev.processed >= prev.total) {
clearInterval(interval);
return prev;
}
const batchSize = Math.floor(Math.random() * 50) + 25;
const processed = Math.min(prev.processed + batchSize, prev.total);
return {
...prev,
processed,
currentItem: `Processing item ${processed} of ${prev.total}`
};
});
}, 300);
return () => clearInterval(interval);
}, []);
const { processed, total, currentItem, startTime } = state;
const progress = (processed / total) * 100;
const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
return (
<div>
<h3>Data Processing</h3>
<p>{currentItem}</p>
<ProgressBarComponent
type="Linear"
value={progress}
height="30"
showProgressValue={true}
progressValueFormat="N0 '%'"
/>
<p>
Processed: {processed} / {total} (Elapsed: {elapsed}s)
</p>
</div>
);
}
export default DataProcessing;Scenario 3: Multi-Type Progress Dashboard
import { ProgressBarComponent } from '@syncfusion/ej2-react-progressbar';
function ProgressDashboard() {
const metrics = [
{ label: 'CPU', value: 45, type: 'Circular' },
{ label: 'Memory', value: 72, type: 'Circular' },
{ label: 'Disk', value: 38, type: 'Circular' },
{ label: 'Overall', value: 52, type: 'Linear' }
];
return (
<div style={{
display: 'grid',
gridTemplateColumns: 'repeat(auto-fit, minmax(150px, 1fr))',
gap: '20px'
}}>
{metrics.map((metric) => (
<div key={metric.label} style={{ textAlign: 'center' }}>
<h4>{metric.label}</h4>
<ProgressBarComponent
type={metric.type}
value={metric.value}
height={metric.type === 'Circular' ? '100px' : '30'}
showProgressValue={true}
/>
<p>{metric.value}%</p>
</div>
))}
</div>
);
}
export default ProgressDashboard;---
Next Steps
- Customization: Colors and styling - customization-and-styling.md
- States: Determinate vs Indeterminate - states-and-modes.md
- Types: Different shapes - types-and-shapes.md
ProgressBar API Reference
This file provides expanded property signatures for the Syncfusion React ProgressBarComponent and direct links to each referenced type on the official docs.
Source: https://ej2.syncfusion.com/react/documentation/api/progressbar/index-default
Overview
Represents ProgressBarComponent (Linear / Circular / Semi-Circular) used to visualize progress.
Properties (with signatures and links)
animation?: AnimationModel— AnimationModel: { enable?: boolean; duration?: number; delay?: number } — Animation settings for the progress bar.annotations?: ProgressAnnotationSettingsModel[]— ProgressAnnotationSettingsModel: Annotation configuration objects.cornerRadius?: CornerType— CornerType: Corner type for ends (e.g.,Auto,Round). Default:Auto.enablePersistence?: boolean— Persist component state between reloads. Default:false. (docs)enablePieProgress?: boolean— Enable pie view for circular type. Default:false. (docs)enableProgressSegments?: boolean— Enable segmented rendering. Default:false. (docs)enableRtl?: boolean— Right-to-left rendering. Default:false. (docs)endAngle?: number— End angle for circular progress. Default:0. (docs)gapWidth?: number— Gap width between segments. Default:null. (docs)height?: string— CSS height (e.g.,"100px"or"50%"). Default:null. (docs)innerRadius?: string— inner radius for circular (e.g.,"70%"). Default:"100%". (docs)isActive?: boolean— Active state. Default:false. (docs)isGradient?: boolean— Enable gradient fill. Default:false. (docs)isIndeterminate?: boolean— Indeterminate mode (spinner-like). Default:false. (docs)isStriped?: boolean— Striped appearance. Default:false. (docs)labelOnTrack?: boolean— Show label on the track. Default:true. (docs)labelStyle?: FontModel— FontModel: Styling for label text.locale?: string— Locale string override (e.g.,"en-US"). (docs)margin?: MarginModel— MarginModel: Margin settings.maximum?: number— Maximum progress value. Default:100. (docs)minimum?: number— Minimum progress value. Default:0. (docs)progressAnnotationModule?: ProgressAnnotation— ProgressAnnotation — Internal annotation module reference.progressColor?: string— Progress fill color (CSS color string). Default:null. (docs)progressThickness?: number— Progress fill thickness in pixels. Default:0. (docs)progressTooltipModule?: ProgressTooltip— ProgressTooltip — Internal tooltip module reference.radius?: string— Track radius for circular type. Default:"100%". (docs)rangeColors?: RangeColorModel[]— RangeColorModel: Colors applied to value ranges.role?: ModeType— ModeType: Role/mode for linear progress.secondaryProgress?: number— Secondary/buffer progress value. (docs)secondaryProgressColor?: string— Color for secondary progress. (docs)secondaryProgressThickness?: number— Thickness for secondary progress. (docs)segmentColor?: string[]— Array of colors used for segments. (docs)segmentCount?: number— Number of segments. Default:1. (docs)showProgressValue?: boolean— Display progress text value (percentage). Default:false. (docs)startAngle?: number— Start angle for circular progress. Default:0. (docs)theme?: ProgressTheme— ProgressTheme: Theme style (Default:Fabric).tooltip?: TooltipSettingsModel— TooltipSettingsModel: Tooltip customization options.trackColor?: string— Track color (CSS color string). Default:null. (docs)trackThickness?: number— Track thickness in pixels. Default:0. (docs)type?: ProgressType— ProgressType:Linear|Circular|Semi-Circular. Default:Linear.value?: number— Current progress value (betweenminimumandmaximum). Default:null. (docs)width?: string— CSS width (e.g.,"100%"or"200px"). Default:null. (docs)
Methods
destroy(): void— Destroy the widget and free resources. (https://ej2.syncfusion.com/react/documentation/api/progressbar/index-default#methods)
Events (with links)
animationComplete— EmitType<IProgressValueEventArgs> — Fired after animation completes. (https://ej2.syncfusion.com/react/documentation/api/progressbar/iprogressvalueeventargs)load— EmitType<ILoadedEventArgs> — Fired before the ProgressBar is rendered. (https://ej2.syncfusion.com/react/documentation/api/progressbar/iloadedeventargs)loaded— EmitType<ILoadedEventArgs> — Fired after the ProgressBar is loaded. (https://ej2.syncfusion.com/react/documentation/api/progressbar/iloadedeventargs)mouseClick— EmitType<IMouseEventArgs> — Mouse click event. (https://ej2.syncfusion.com/react/documentation/api/progressbar/imouseeventargs)mouseDown— EmitType<IMouseEventArgs> — Mouse down event. (https://ej2.syncfusion.com/react/documentation/api/progressbar/imouseeventargs)mouseLeave— EmitType<IMouseEventArgs> — Mouse leave event. (https://ej2.syncfusion.com/react/documentation/api/progressbar/imouseeventargs)mouseMove— EmitType<IMouseEventArgs> — Mouse move event. (https://ej2.syncfusion.com/react/documentation/api/progressbar/imouseeventargs)mouseUp— EmitType<IMouseEventArgs> — Mouse up event. (https://ej2.syncfusion.com/react/documentation/api/progressbar/imouseeventargs)progressCompleted— EmitType<IProgressValueEventArgs> — Fired when progress reaches completion. (https://ej2.syncfusion.com/react/documentation/api/progressbar/iprogressvalueeventargs)textRender— EmitType<ITextRenderEventArgs> — Fired before label text renders. (https://ej2.syncfusion.com/react/documentation/api/progressbar/itextrendereventargs)tooltipRender— EmitType<ITooltipRenderEventArgs> — Fired before tooltip renders. (https://ej2.syncfusion.com/react/documentation/api/progressbar/itooltiprendereventargs)valueChanged— EmitType<IProgressValueEventArgs> — Fired after value changes. (https://ej2.syncfusion.com/react/documentation/api/progressbar/iprogressvalueeventargs)
Property Usage Guide
Essential Properties
For Basic Usage:
<ProgressBarComponent
id="progress" // Unique identifier
type="Linear" // Linear | Circular | Semicircle
value={65} // 0-100 (current progress)
height="30" // CSS height value
/>For User Feedback:
<ProgressBarComponent
value={progress}
showProgressValue={true} // Display percentage text
progressValueFormat="N0 '%'" // Format: "65 %"
/>For Animations:
<ProgressBarComponent
value={progress}
animation={{
enable: true,
duration: 1500, // ms (animation time)
delay: 0 // ms (before animation)
}}
/>For Indeterminate (Loading):
<ProgressBarComponent
isIndeterminate={true} // Spinner mode
type="Circular"
animation={{
enable: true,
duration: 2000
}}
/>For Dual Progress (Buffer):
<ProgressBarComponent
value={40} // Actual progress
secondaryProgress={75} // Buffer/estimated progress
/>Styling Properties
<ProgressBarComponent
progressColor="#4CAF50" // Progress fill color
trackColor="#e0e0e0" // Track background color
progressThickness={4} // Thickness in pixels
trackThickness={4}
isStriped={true} // Striped pattern
isGradient={true} // Gradient effect
cssClass="custom-class" // Custom CSS class
/>Advanced Properties
<ProgressBarComponent
cornerRadius="Round" // Round | Auto
enableRtl={false} // Right-to-left support
enablePieProgress={true} // Pie view for circular
enableProgressSegments={true} // Segmented rendering
segmentCount={10} // Number of segments
/>Quick Notes
- Basic progress: Use
valueprop (0-100) - Unknown duration: Use
isIndeterminate={true} - Buffered scenarios: Use
secondaryProgressfor dual progress - Animations: Configure via
animationobject (enable, duration, delay) - Accessibility: Always include
aria-labeland role attributes - Performance: Disable animations for real-time updates (>100/sec)
- Mobile: Use
Semicircletype for space-constrained layouts
Event Handlers
// Animation and value changes
onProgressStart={() => {}} // When animation starts
onProgressComplete={() => {}} // When reaching 100%
onAnimationComplete={() => {}} // When animation finishes
onValueChanged={(args) => {}} // When value changes
onTextRender={(args) => {}} // Before text renders
onTooltipRender={(args) => {}} // Before tooltip renders
// Mouse events
onMouseClick={(args) => {}}
onMouseDown={(args) => {}}
onMouseUp={(args) => {}}
onMouseMove={(args) => {}}
onMouseLeave={(args) => {}}
// Lifecycle
onLoad={(args) => {}} // Before component renders
onLoaded={(args) => {}} // After component rendersCommon Patterns
// File Upload Progress
<ProgressBarComponent type="Linear" value={uploadPercent} showProgressValue={true} />
// Loading Spinner
<ProgressBarComponent type="Circular" isIndeterminate={true} height="100px" />
// Streaming/Buffer
<ProgressBarComponent value={played} secondaryProgress={buffered} />
// Multi-step Process
<ProgressBarComponent value={(currentStep / totalSteps) * 100} />API Documentation Links
- Main API Index: https://ej2.syncfusion.com/react/documentation/api/progressbar/index-default
- ProgressBar Component: https://ej2.syncfusion.com/react/documentation/api/progressbar/progressbarcomponent
- Event Arguments: https://ej2.syncfusion.com/react/documentation/api/progressbar/iprogressvalueeventargs
- Animation Model: https://ej2.syncfusion.com/react/documentation/api/progressbar/animationmodel
Customization and Styling for Progress Bar
Table of contents
- Sizing
- Height Control
- Width Control
- Circular Type Sizing
- Colors and Fill
- Track Thickness
- Progress Thickness
- Using CSS Classes
- Labels and Text
- Show Progress Value
- Custom Text Format
- Labels with State
- Theme Application
- Theme Characteristics
- Switching Themes Dynamically
- CSS Customization
- Complete Custom Styling Example
- Circular Progress Customization
- Range Colors
- Striped and Gradient Effects
- Advanced Examples
- Example 1: Gradient Progress Bar with Custom Styling
- Example 2: Status Color Based on Progress
- Example 3: Responsive Dashboard
- Next Steps
Sizing
Control the dimensions of your progress bar for different use cases.
Height Control
import { ProgressBarComponent } from '@syncfusion/ej2-react-progressbar';
// Thin progress bar (3px)
<ProgressBarComponent
type="Linear"
value={50}
height="3"
/>
// Default (20px)
<ProgressBarComponent
type="Linear"
value={50}
height="20"
/>
// Thick status bar (40px)
<ProgressBarComponent
type="Linear"
value={50}
height="40"
/>
// Very thick (80px)
<ProgressBarComponent
type="Linear"
value={50}
height="80"
/>Width Control
// Full width (default)
<ProgressBarComponent
type="Linear"
value={50}
width="100%"
height="20"
/>
// Fixed width
<ProgressBarComponent
type="Linear"
value={50}
width="400px"
height="20"
/>
// Responsive with container
<div style={{ maxWidth: '600px', margin: '0 auto' }}>
<ProgressBarComponent
type="Linear"
value={50}
width="100%"
height="20"
/>
</div>Circular Type Sizing
For circular and semicircle types, height represents the diameter (or radius for semicircle):
// Compact circular (60px diameter)
<ProgressBarComponent
type="Circular"
value={50}
height="60px"
/>
// Standard circular (120px diameter)
<ProgressBarComponent
type="Circular"
value={50}
height="120px"
/>
// Large circular (200px diameter)
<ProgressBarComponent
type="Circular"
value={50}
height="200px"
/>
// Semicircle (100px radius)
<ProgressBarComponent
type="Semicircle"
value={50}
height="100px"
/>---
Colors and Fill
Customize colors for different themes and states.
Track Thickness
// Thin track (2px)
<ProgressBarComponent
type="Linear"
value={50}
trackThickness={2}
height="20"
/>
// Thicker track (4px)
<ProgressBarComponent
type="Linear"
value={50}
trackThickness={4}
height="20"
/>
// Very thick track (6px)
<ProgressBarComponent
type="Linear"
value={50}
trackThickness={6}
height="20"
/>Progress Thickness
// Thin progress bar
<ProgressBarComponent
type="Linear"
value={50}
progressThickness={2}
height="20"
/>
// Standard progress bar
<ProgressBarComponent
type="Linear"
value={50}
progressThickness={4}
height="20"
/>
// Thick progress bar
<ProgressBarComponent
type="Linear"
value={50}
progressThickness={6}
height="20"
/>Using CSS Classes
Customize colors via CSS:
import './progress.css';
<ProgressBarComponent
id="custom"
type="Linear"
value={50}
cssClass="custom-progress"
height="20"
/>progress.css:
/* Primary progress bar */
.custom-progress .e-progress {
background-color: #4CAF50;
}
/* Track background */
.custom-progress .e-progress-bar {
background-color: #e0e0e0;
}
/* Secondary progress (buffer) */
.custom-progress .e-progress-secondary {
background-color: #90CAF9;
}---
Labels and Text
Display progress values and custom labels.
Show Progress Value
// Display percentage
<ProgressBarComponent
type="Linear"
value={75}
showProgressValue={true}
progressValueFormat="N0 '%'"
height="30"
/>Output: Shows "75 %" inside or near the progress bar
Custom Text Format
// Different number formats
<ProgressBarComponent
type="Linear"
value={50}
showProgressValue={true}
progressValueFormat="N1 '%'" // One decimal: "50.0 %"
height="30"
/>
<ProgressBarComponent
type="Linear"
value={50}
showProgressValue={true}
progressValueFormat="0.00 '%'" // Two decimals: "50.00 %"
height="30"
/>Labels with State
import { useState } from 'react';
import { ProgressBarComponent } from '@syncfusion/ej2-react-progressbar';
function ProgressWithLabel() {
const [progress, setProgress] = useState(0);
const [status, setStatus] = useState('Starting...');
const handleStart = () => {
let current = 0;
const interval = setInterval(() => {
current += Math.random() * 30;
if (current >= 100) {
setProgress(100);
setStatus('Complete!');
clearInterval(interval);
} else {
setProgress(current);
setStatus(`Processing: ${Math.round(current)}%`);
}
}, 800);
};
return (
<div>
<h3>{status}</h3>
<ProgressBarComponent
type="Linear"
value={progress}
showProgressValue={true}
height="30"
/>
</div>
);
}
export default ProgressWithLabel;---
Theme Application
Syncfusion includes multiple built-in themes for different design systems.
Theme Characteristics:
| Theme | Best For | Color Palette | Use Case |
|---|---|---|---|
| Material | Modern apps | Vibrant, flat colors | Default choice, Material Design |
| Bootstrap5 | Bootstrap projects | Bootstrap colors | Bootstrap-based applications |
| Tailwind | Tailwind projects | Neutral tones | Tailwind CSS environments |
| Fluent | Microsoft apps | Modern blue/gray | Office 365 style apps |
| Fabric | Office integration | Office colors | Microsoft product integration |
| HighContrast | Accessibility | High contrast | Users with visual impairments |
Switching Themes Dynamically
import { useState } from 'react';
import { ProgressBarComponent } from '@syncfusion/ej2-react-progressbar';
function App() {
const [theme, setTheme] = useState('Material');
const [value, setValue] = useState(65);
const themes = [
{ id: 'Material', label: 'Material' },
{ id: 'Bootstrap5', label: 'Bootstrap 5' },
{ id: 'Tailwind', label: 'Tailwind' },
{ id: 'Fluent', label: 'Fluent UI' },
{ id: 'Fabric', label: 'Office Fabric' }
];
return (
<div style={{ padding: '20px', fontFamily: 'Arial' }}>
<h3>Theme Selector</h3>
{/* Theme Dropdown */}
<select
value={theme}
onChange={(e) => setTheme(e.target.value)}
style={{ padding: '5px', marginBottom: '15px' }}
>
{themes.map(t => (
<option key={t.id} value={t.id}>{t.label}</option>
))}
</select>
<div style={{ marginTop: '20px' }}>
<p>
Current Theme: <strong>{theme}</strong>
</p>
<ProgressBarComponent
type="Linear"
value={value}
height="30"
showProgressValue={true}
theme={theme}
/>
<input
type="range"
min="0"
max="100"
value={value}
onChange={(e) => setValue(parseInt(e.target.value))}
style={{ marginTop: '20px', width: '100%' }}
/>
</div>
</div>
);
}
export default App;Note: To switch themes dynamically in production, you would need to: 1. Dynamically import CSS files based on theme selection 2. Or use CSS variables that can be changed at runtime 3. Reference the Syncfusion documentation for dynamic theming
---
CSS Customization
Fine-tune styling with custom CSS.
Complete Custom Styling Example
import './custom-progress.css';
import { ProgressBarComponent } from '@syncfusion/ej2-react-progressbar';
function App() {
return (
<ProgressBarComponent
id="custom"
type="Linear"
value={60}
cssClass="custom-progress-theme"
height="40"
showProgressValue={true}
/>
);
}
export default App;custom-progress.css:
/* Container styling */
.custom-progress-theme {
margin: 20px 0;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
/* Track background */
.custom-progress-theme .e-progress-bar {
background: linear-gradient(to right, #f0f0f0, #e8e8e8);
border-radius: 4px;
}
/* Progress fill */
.custom-progress-theme .e-progress {
background: linear-gradient(to right, #667eea, #764ba2);
border-radius: 4px;
transition: width 0.3s ease;
}
/* Secondary progress (buffer) */
.custom-progress-theme .e-progress-secondary {
background: linear-gradient(to right, rgba(102, 126, 234, 0.3), rgba(118, 75, 162, 0.3));
border-radius: 4px;
}
/* Progress value text */
.custom-progress-theme .e-progress-value {
color: #333;
font-weight: 600;
font-size: 14px;
}Circular Progress Customization
/* Circular progress styling */
.custom-circular .e-progressbar-svg {
filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.1));
}
.custom-circular .e-progress-circle {
stroke: url(#progressGradient);
stroke-width: 6;
}
.custom-circular .e-progress-track-circle {
stroke: #e8e8e8;
stroke-width: 6;
}---
Range Colors
Define different colors for different progress ranges:
import { ProgressBarComponent } from '@syncfusion/ej2-react-progressbar';
function RangeColorProgress() {
const rangeColors = [
{ color: '#FF3333', start: 0, end: 25 }, // Red: 0-25%
{ color: '#FF9800', start: 25, end: 50 }, // Orange: 25-50%
{ color: '#FFC107', start: 50, end: 75 }, // Yellow: 50-75%
{ color: '#4CAF50', start: 75, end: 100 } // Green: 75-100%
];
return (
<div>
<h3>Range Color Progress</h3>
<ProgressBarComponent
type="Linear"
value={65}
height="40"
showProgressValue={true}
rangeColors={rangeColors}
animation={{ enable: true, duration: 1000 }}
/>
<p>0-25%: Red | 25-50%: Orange | 50-75%: Yellow | 75-100%: Green</p>
</div>
);
}
export default RangeColorProgress;Striped and Gradient Effects
Add visual variety to progress bars:
// Striped Progress Bar
<ProgressBarComponent
type="Linear"
value={50}
height="30"
isStriped={true}
/>
// Gradient Progress Bar
<ProgressBarComponent
type="Linear"
value={50}
height="30"
isGradient={true}
/>
// Combine both
<ProgressBarComponent
type="Linear"
value={50}
height="30"
isStriped={true}
isGradient={true}
/>Advanced Examples
Example 1: Gradient Progress Bar with Custom Styling
import './gradient-progress.css';
function GradientProgress() {
return (
<ProgressBarComponent
id="gradient"
type="Linear"
value={65}
cssClass="gradient-progress"
height="40"
showProgressValue={true}
/>
);
}
export default GradientProgress;gradient-progress.css:
.gradient-progress .e-progress {
background: linear-gradient(
to right,
#FF6B6B 0%,
#FFA06B 25%,
#FFD06B 50%,
#6BCB77 75%,
#4D96FF 100%
);
}Example 2: Status Color Based on Progress
import { useState } from 'react';
import { ProgressBarComponent } from '@syncfusion/ej2-react-progressbar';
function StatusProgress() {
const [progress, setProgress] = useState(30);
const getStatusClass = () => {
if (progress < 33) return 'status-low';
if (progress < 67) return 'status-medium';
return 'status-high';
};
const getStatusText = () => {
if (progress < 33) return '⚠️ Low';
if (progress < 67) return '🔄 Medium';
return '✓ High';
};
return (
<div>
<h3>{getStatusText()}</h3>
<ProgressBarComponent
type="Linear"
value={progress}
cssClass={`status-progress ${getStatusClass()}`}
height="30"
showProgressValue={true}
/>
<input
type="range"
min="0"
max="100"
value={progress}
onChange={(e) => setProgress(parseInt(e.target.value))}
/>
</div>
);
}
export default StatusProgress;CSS:
.status-progress.status-low .e-progress {
background-color: #FFA06B;
}
.status-progress.status-medium .e-progress {
background-color: #FFD06B;
}
.status-progress.status-high .e-progress {
background-color: #6BCB77;
}Example 3: Responsive Dashboard
import { useState } from 'react';
import { ProgressBarComponent } from '@syncfusion/ej2-react-progressbar';
function ResponsiveDashboard() {
const [isMobile, setIsMobile] = useState(window.innerWidth < 768);
return (
<div className={`dashboard ${isMobile ? 'mobile' : 'desktop'}`}>
{/* Full width on mobile, grid on desktop */}
<div className="metric">
<h4>CPU Usage</h4>
<ProgressBarComponent
type={isMobile ? "Semicircle" : "Circular"}
value={45}
height={isMobile ? "80px" : "120px"}
/>
</div>
<div className="metric">
<h4>Memory Usage</h4>
<ProgressBarComponent
type={isMobile ? "Semicircle" : "Circular"}
value={72}
height={isMobile ? "80px" : "120px"}
/>
</div>
<div className="metric full-width">
<h4>Overall Progress</h4>
<ProgressBarComponent
type="Linear"
value={65}
height={isMobile ? "30" : "40"}
showProgressValue={true}
/>
</div>
</div>
);
}
export default ResponsiveDashboard;---
Next Steps
- Animations & Events: Advanced features - animations-events-accessibility.md
- Types: Different shapes - types-and-shapes.md
- States: Determinate vs Indeterminate - states-and-modes.md
Getting Started with React Progress Bar
Table of Contents
- Installation
- CSS Theme Setup
- Basic Implementation
- Linear Progress Bar (Default)
- Circular Progress Bar
- TypeScript Setup
- Project Setup Variations
- Vite + React
- Create React App
- Common Setup Issues
- Issue: Styles Not Applying
- Issue: "Cannot find module" Error
- Issue: Circular Progress Bar Not Showing
- License Registration (Optional)
- Next Steps
- Troubleshooting Quick Reference
Installation
The Syncfusion Progress Bar component is part of the @syncfusion/ej2-react-progressbar package. Install it via npm:
npm install @syncfusion/ej2-react-progressbar --saveThis will automatically install required dependencies:
@syncfusion/ej2-base- Core utilities@syncfusion/ej2-svg-base- SVG rendering for circular types@syncfusion/ej2-data- Data handling
Theme Selection Guide:
- Material (recommended): Modern, flat design with Material Design principles
- Bootstrap5: Latest Bootstrap styling and components
- Tailwind: Utility-first CSS framework style
- Fluent: Microsoft Fluent Design System
- Highcontrast: Enhanced visibility for accessibility
Basic Implementation
Linear Progress Bar (Default)
import { ProgressBarComponent } from '@syncfusion/ej2-react-progressbar';
function App() {
return (
<ProgressBarComponent
id="linear"
type="Linear"
value={75}
height="60"
theme="Material"
/>
);
}
export default App;What this does:
- Creates a linear (horizontal) progress bar
value={75}shows 75% completionheight="60"sets the height to 60 pixels- Default theme: Material
Circular Progress Bar
<ProgressBarComponent
id="circular"
type="Circular"
value={60}
height="160px"
/>What this does:
- Creates a circular (donut) progress bar
- Better for confined spaces
height="160px"defines the diameter- Value still represents percentage (0-100)
Semi-Circular Progress Bar
<ProgressBarComponent
id="semicircle"
type="Semicircle"
value={75}
height="160px"
/>What this does:
- Creates a semi-circular (half-circle) progress bar
- Useful for dashboard panels and mobile layouts
- Height defines the radius
- Great for space-constrained layouts
TypeScript Setup
For TypeScript projects, types are included automatically:
import { ProgressBarComponent } from '@syncfusion/ej2-react-progressbar';
import { ProgressBarProps } from '@syncfusion/ej2-react-progressbar';
interface AppProps extends ProgressBarProps {}
const App: React.FC<AppProps> = () => {
return (
<ProgressBarComponent
id="progress"
type="Linear"
value={50}
/>
);
};
export default App;Project Setup Variations
Vite + React
npm create vite@latest my-app -- --template react
cd my-app
npm install @syncfusion/ej2-react-progressbar
npm run devApp.tsx:
import { ProgressBarComponent } from '@syncfusion/ej2-react-progressbar';
import './App.css';
function App() {
return (
<div>
<h1>Progress Bar Example</h1>
<ProgressBarComponent id="progress" value={40} />
</div>
);
}
export default App;Create React App
npx create-react-app my-app
cd my-app
npm install @syncfusion/ej2-react-progressbar
npm startApp.js:
import { ProgressBarComponent } from '@syncfusion/ej2-react-progressbar';
import './App.css';
function App() {
return (
<div className="App">
<h1>Progress Bar Example</h1>
<ProgressBarComponent id="progress" value={40} />
</div>
);
}
export default App;Common Setup Issues
Issue: Styles Not Applying
Problem: Progress bar renders but styling is missing (no colors, distorted shape)
Solution: Verify CSS import is at top of file:
// ✓ CORRECT - CSS imported first
import { ProgressBarComponent } from '@syncfusion/ej2-react-progressbar';
// ✗ WRONG - CSS after component import
import { ProgressBarComponent } from '@syncfusion/ej2-react-progressbar';
Issue: "Cannot find module" Error
Problem: TypeScript can't find Syncfusion types
Solution: Ensure package is installed:
npm install @syncfusion/ej2-react-progressbarDelete node_modules and reinstall if issue persists:
rm -r node_modules package-lock.json
npm installIssue: Circular Progress Bar Not Showing
Problem: Circular type renders as linear or disappears
Solution: Set height for circular type:
<ProgressBarComponent
type="Circular"
value={50}
height="150px" // Required for circular
/>License Registration (Optional)
If you have Syncfusion license, register it in your root component:
import { registerLicense } from '@syncfusion/ej2-base';
// Register license
registerLicense('YOUR_LICENSE_KEY_HERE');
// Component code followsWithout license: Components work in development with a watermark (shows in evaluation mode)
Next Steps
- Types & Shapes: Ready to explore different progress bar shapes? Read types-and-shapes.md
- States & Modes: Want to learn determinate vs. indeterminate? Read states-and-modes.md
- Customization: Ready to style and customize? Read customization-and-styling.md
- Advanced: Learn animations and events? Read animations-events-accessibility.md
Troubleshooting Quick Reference
| Issue | Solution |
|---|---|
| Cannot find module | Run npm install @syncfusion/ej2-react-progressbar |
| Circular type broken | Add height prop with pixel value (e.g., height="160px") |
| Semicircle type not showing | Set type="Semicircle" and provide height value |
| Types not recognized | Ensure package version is ≥20.0.0 |
| Build fails | Clear node_modules and reinstall: rm -rf node_modules && npm install |
| Progress value not displaying | Set showProgressValue={true} on the component |
| Animation not working | Ensure animation object is properly configured: animation={{ enable: true, duration: 2000 }} |
Complete Working Example with All Features
import { ProgressBarComponent } from '@syncfusion/ej2-react-progressbar';
import { useState, useEffect } from 'react';
function App() {
const [linearProgress, setLinearProgress] = useState(0);
const [circularProgress, setCircularProgress] = useState(0);
const [semicircleProgress, setSemicircleProgress] = useState(0);
useEffect(() => {
// Simulate progress updates
const interval = setInterval(() => {
setLinearProgress(prev => (prev >= 100 ? 0 : prev + 10));
setCircularProgress(prev => (prev >= 100 ? 0 : prev + 8));
setSemicircleProgress(prev => (prev >= 100 ? 0 : prev + 12));
}, 1000);
return () => clearInterval(interval);
}, []);
return (
<div style={{ padding: '20px', fontFamily: 'Arial, sans-serif' }}>
<h1>Syncfusion Progress Bar Examples</h1>
{/* Linear Progress Bar */}
<section>
<h2>Linear Progress Bar</h2>
<ProgressBarComponent
id="linear"
type="Linear"
value={linearProgress}
height="30"
showProgressValue={true}
animation={{ enable: true, duration: 1000, delay: 0 }}
/>
</section>
{/* Circular Progress Bar */}
<section>
<h2>Circular Progress Bar</h2>
<ProgressBarComponent
id="circular"
type="Circular"
value={circularProgress}
height="160px"
showProgressValue={true}
animation={{ enable: true, duration: 1000, delay: 0 }}
/>
</section>
{/* Semi-Circular Progress Bar */}
<section>
<h2>Semi-Circular Progress Bar</h2>
<ProgressBarComponent
id="semicircle"
type="Semicircle"
value={semicircleProgress}
height="160px"
showProgressValue={true}
animation={{ enable: true, duration: 1000, delay: 0 }}
/>
</section>
{/* Indeterminate Progress (Loading Spinner) */}
<section>
<h2>Loading Spinner (Indeterminate)</h2>
<ProgressBarComponent
id="spinner"
type="Circular"
isIndeterminate={true}
height="100px"
animation={{ enable: true, duration: 2000 }}
/>
</section>
{/* Buffer Progress */}
<section>
<h2>Buffer Progress (Streaming)</h2>
<ProgressBarComponent
id="buffer"
type="Linear"
value={40}
secondaryProgress={75}
height="30"
animation={{ enable: true, duration: 1000 }}
/>
<p>Actual: 40% | Buffered: 75%</p>
</section>
</div>
);
}
export default App;This example demonstrates all three types of progress bars and key features.
States and Modes for Progress Bar
Table of contents
- Determinate State
- Basic Determinate Example
- When to Use Determinate
- Updating Determinate Progress
- Indeterminate State
- Basic Indeterminate Example
- When to Use Indeterminate
- Indeterminate with Circular Type
- Transitioning from Indeterminate to Determinate
- Buffer/Secondary Progress
- Basic Buffer Example
- When to Use Buffer
- Streaming Scenario Example
- State Comparison
- Real-World Scenarios
- Scenario 1: File Upload (Determinate)
- Scenario 2: API Loading (Indeterminate to Determinate)
- Scenario 3: Multi-Step Process (Determinate with Steps)
- Combining States
- State Transition Best Practices
- Next Steps
Determinate State
The Determinate state is used when you know the exact progress of a task. This is the default state when isIndeterminate is not set or is false.
Basic Determinate Example
import { ProgressBarComponent } from '@syncfusion/ej2-react-progressbar';
function App() {
return (
<ProgressBarComponent
id="determinate"
type="Linear"
value={65}
height="60"
animation={{
enable: true,
duration: 2000,
delay: 0
}}
/>
);
}
export default App;What happens:
- Progress bar shows 65% filled
- Stays at 65% until value prop changes
- Animation optional but recommended
When to Use Determinate
- Known progress: Download at 45%, file processing at 78%
- Step-based tasks: 5 of 10 steps completed
- Percentage calculations: 23 MB of 100 MB uploaded
- Timed operations: Script running for 30 of 120 seconds
- Batch operations: 8 of 15 items processed
Updating Determinate Progress
import { useState, useEffect } from 'react';
import { ProgressBarComponent } from '@syncfusion/ej2-react-progressbar';
function DownloadProgress() {
const [progress, setProgress] = useState(0);
useEffect(() => {
// Simulate download progress
const interval = setInterval(() => {
setProgress(prev => {
if (prev >= 100) {
clearInterval(interval);
return 100;
}
return prev + Math.random() * 25;
});
}, 800);
return () => clearInterval(interval);
}, []);
return (
<div>
<h3>Downloading File...</h3>
<ProgressBarComponent
id="download"
type="Linear"
value={progress}
height="40"
showProgressValue={true}
progressValueFormat="N0 '%'"
animation={{
enable: true,
duration: 500,
delay: 0
}}
/>
<p>Downloaded: {Math.round(progress)}%</p>
</div>
);
}
export default DownloadProgress;---
Indeterminate State
The Indeterminate state is used when progress cannot be estimated. It shows continuous animation without a specific value, commonly seen as loading spinners.
Basic Indeterminate Example
<ProgressBarComponent
id="indeterminate"
type="Linear"
isIndeterminate={true}
height="60"
animation={{
enable: true,
duration: 2000,
delay: 0
}}
/>What happens:
- Animated bar continuously moves (doesn't fill to a value)
- No completion point visible
- Continues animating until disabled or hidden
When to Use Indeterminate
- Unknown duration: Processing API calls, database queries
- Loading states: Page loading, content fetching
- Background tasks: Sync operations, auto-save
- Waiting states: Server response pending
- Initial load: Before progress can be tracked
Indeterminate with Circular Type
// Loading spinner (best practice)
<ProgressBarComponent
id="spinner"
type="Circular"
isIndeterminate={true}
height="100px"
animation={{
enable: true,
duration: 2000,
delay: 0
}}
/>Transitioning from Indeterminate to Determinate
Switch to determinate once actual progress becomes known:
import { useState } from 'react';
import { ProgressBarComponent } from '@syncfusion/ej2-react-progressbar';
function SmartProgress() {
const [isLoading, setIsLoading] = useState(true);
const [progress, setProgress] = useState(0);
const handleUpload = async () => {
setIsLoading(true);
setProgress(0);
// Start with indeterminate (we don't know total size)
await new Promise(resolve => setTimeout(resolve, 2000));
// Switch to determinate once we know size
setIsLoading(false);
const interval = setInterval(() => {
setProgress(prev => {
if (prev >= 100) {
clearInterval(interval);
return 100;
}
return prev + 10;
});
}, 500);
};
return (
<div>
<ProgressBarComponent
id="smart"
type="Linear"
value={progress}
isIndeterminate={isLoading}
height="40"
showProgressValue={!isLoading}
/>
<button onClick={handleUpload}>Start Upload</button>
</div>
);
}
export default SmartProgress;---
Buffer/Secondary Progress
The Buffer (secondary progress) state shows dual progress: actual progress and estimated/buffered progress. Useful when actual progress lags behind total available data.
Basic Buffer Example
<ProgressBarComponent
id="buffer"
type="Linear"
value={40}
secondaryProgress={75}
height="60"
animation={{
enable: true,
duration: 2000
}}
/>What happens:
- Primary progress (red): 40% filled
- Secondary progress (light blue): 75% filled
- Visual shows buffer ahead of actual progress
When to Use Buffer
- Streaming media: Actual playback vs. buffered video
- Large file downloads: Downloaded vs. pre-fetched chunks
- Database pagination: Current page vs. prefetched pages
- Real-time data: Processed vs. received data points
- Queue processing: Processed vs. queued items
Streaming Scenario Example
import { useState, useEffect } from 'react';
import { ProgressBarComponent } from '@syncfusion/ej2-react-progressbar';
function VideoStreamProgress() {
const [playbackTime, setPlaybackTime] = useState(0);
const [bufferedTime, setBufferedTime] = useState(0);
const totalDuration = 100; // seconds
useEffect(() => {
const interval = setInterval(() => {
setPlaybackTime(prev => {
const next = prev + 0.5;
return next > totalDuration ? totalDuration : next;
});
// Buffer ahead of playback
setBufferedTime(prev => {
if (prev < playbackTime + 15) {
return Math.min(prev + 1, totalDuration);
}
return prev;
});
}, 100);
return () => clearInterval(interval);
}, []);
const playbackPercent = (playbackTime / totalDuration) * 100;
const bufferedPercent = (bufferedTime / totalDuration) * 100;
return (
<div>
<h3>Video Player</h3>
<ProgressBarComponent
id="video"
type="Linear"
value={playbackPercent}
secondaryProgress={bufferedPercent}
height="40"
animation={{
enable: true,
duration: 100
}}
/>
<p>Playing: {playbackTime.toFixed(1)}s / Buffered: {bufferedTime.toFixed(1)}s</p>
</div>
);
}
export default VideoStreamProgress;---
State Comparison
| Feature | Determinate | Indeterminate | Buffer |
|---|---|---|---|
| Progress Known | ✓ Yes | ✗ No | ✓ Yes (dual) |
| Value Updates | ✓ Required | ✗ None | ✓ Both values |
| Animation | Optional | Continuous | Optional |
| Use Case | Known progress | Unknown duration | Dual progress |
| Example | Download 45% | Loading... | 40% actual, 75% buffered |
---
Real-World Scenarios
Scenario 1: File Upload (Determinate)
const [uploadProgress, setUploadProgress] = useState(0);
const handleFileUpload = (file) => {
const formData = new FormData();
formData.append("file", file);
const xhr = new XMLHttpRequest();
xhr.upload.onprogress = (event) => {
if (event.lengthComputable) {
const percent = Math.round((event.loaded / event.total) * 100);
setUploadProgress(percent);
}
};
xhr.onload = () => {
setUploadProgress(100);
};
xhr.open("POST", "/upload");
xhr.send(formData);
};
return (
<div style={{ width: "400px" }}>
<input
type="file"
onChange={(e) => handleFileUpload(e.target.files[0])}
/>
<ProgressBarComponent
type="Linear"
value={uploadProgress}
showProgressValue={true}
height="30"
/>
</div>
);Scenario 2: API Loading (Indeterminate → Determinate)
const [data, setData] = useState(null);
const [isLoading, setIsLoading] = useState(false);
const [progress, setProgress] = useState(0);
const fetchData = async () => {
setIsLoading(true);
setProgress(0);
try {
// Indeterminate while fetching
const response = await fetch('/api/data');
// Switch to determinate while processing
setIsLoading(false);
const items = await response.json();
for (let i = 0; i < items.length; i++) {
// Process items with progress
setProgress((i / items.length) * 100);
// ... process item
}
setData(items);
setProgress(100);
} catch (error) {
console.error('Error:', error);
}
};
return (
<>
<ProgressBarComponent
type="Circular"
isIndeterminate={isLoading}
value={progress}
height="100px"
/>
<button onClick={fetchData}>Fetch Data</button>
</>
);Scenario 3: Multi-Step Process (Determinate with Steps)
import { useState } from 'react';
import { ProgressBarComponent } from '@syncfusion/ej2-react-progressbar';
function MultiStepProcess() {
const steps = [
{ name: 'Validation', duration: 2000 },
{ name: 'Processing', duration: 3000 },
{ name: 'Upload', duration: 2000 },
{ name: 'Confirmation', duration: 1000 }
];
const [currentStep, setCurrentStep] = useState(0);
const [isProcessing, setIsProcessing] = useState(false);
const startProcess = async () => {
setIsProcessing(true);
setCurrentStep(0);
for (let i = 0; i < steps.length; i++) {
setCurrentStep(i);
await new Promise(resolve =>
setTimeout(resolve, steps[i].duration)
);
}
setIsProcessing(false);
};
const progress = ((currentStep + 1) / steps.length) * 100;
return (
<div>
<div>
<h3>Processing Steps</h3>
{steps.map((step, i) => (
<div key={i}>
<span>{step.name}</span>
<span>{i === currentStep ? '🔄' : i < currentStep ? '✓' : '⏳'}</span>
</div>
))}
</div>
<ProgressBarComponent
type="Linear"
value={progress}
height="30"
showProgressValue={true}
/>
<button onClick={startProcess} disabled={isProcessing}>
{isProcessing ? 'Processing...' : 'Start Process'}
</button>
</div>
);
}
export default MultiStepProcess;---
Combining States
You can transition between states based on your application flow:
import { useState } from 'react';
import { ProgressBarComponent } from '@syncfusion/ej2-react-progressbar';
function ProgressStateTransition() {
const [progress, setProgress] = useState(0);
const [isLoading, setIsLoading] = useState(false);
const [phase, setPhase] = useState('idle');
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
const handleUpload = async () => {
try {
// Phase 1: Connecting (indeterminate)
setIsLoading(true);
setPhase('connecting');
setProgress(0);
await delay(2000);
// Phase 2: Uploading (determinate)
setPhase('uploading');
setIsLoading(false);
for (let i = 0; i <= 100; i += 10) {
setProgress(i);
await delay(500);
}
// Phase 3: Complete
setProgress(100);
setPhase('complete');
setTimeout(() => {
setProgress(0);
setPhase('idle');
}, 2000);
} catch (error) {
setPhase('error');
setIsLoading(false);
}
};
return (
<div style={{ maxWidth: '600px' }}>
<h3>Multi-Phase Progress</h3>
<ProgressBarComponent
type="Linear"
value={progress}
isIndeterminate={isLoading}
height="40"
showProgressValue={!isLoading}
progressValueFormat="N0 '%'"
animation={{ enable: true, duration: 300 }}
/>
<p>Phase: <strong>{phase.toUpperCase()}</strong></p>
{phase === 'error' && <p style={{ color: 'red' }}>Upload failed. Please try again.</p>}
<button
onClick={handleUpload}
disabled={isLoading || phase === 'complete'}
>
{isLoading ? 'Uploading...' : phase === 'complete' ? 'Upload Complete' : 'Start Upload'}
</button>
</div>
);
}
export default ProgressStateTransition;State Transition Best Practices
1. Error Handling: Always include error states to handle failed operations 2. User Feedback: Display current phase to keep users informed 3. Disable Interactions: Prevent duplicate submissions during loading 4. Reset State: Clear progress after operations complete 5. Timeout Protection: Add timeouts to prevent indefinite loading states
---
Next Steps
- Customization: Style and colors - customization-and-styling.md
- Animations & Events: Advanced features - animations-events-accessibility.md
- Types: Different shapes - types-and-shapes.md
Types and Shapes for Progress Bar
Table of Contents
- Linear Progress Bar
- Basic Linear Example
- When to Use Linear
- Styling Linear Bars
- Circular Progress Bar
- Basic Circular Example
- When to Use Circular
- Sizing Circular Bars
- Semi-Circular Progress Bar
- Basic Semi-Circular Example
- When to Use Semi-Circular
- Sizing Semi-Circular Bars
- Type Comparison
- Choosing the Right Type
- Decision Tree
- Use Case Examples
- Real-World Examples
- Example 1: File Upload with Progress
- Example 2: Dashboard with Multiple Types
- Example 3: Mobile-Responsive Layout
- Performance Notes
- Next Steps
The Progress Bar component supports three distinct shapes for displaying progress, each with different use cases and visual presentations.
Linear Progress Bar
The Linear type is the default and most common choice for progress visualization. It displays progress as a horizontal bar that fills from left to right (or right to left in RTL).
Basic Linear Example
import { ProgressBarComponent } from '@syncfusion/ej2-react-progressbar';
function App() {
return (
<ProgressBarComponent
id="linear"
type="Linear"
value={75}
height="60"
animation={{
enable: true,
duration: 2000,
delay: 0
}}
/>
);
}
export default App;When to Use Linear
- File downloads/uploads: Shows bytes downloaded
- Task completion: Display step progress (e.g., 5 of 10 steps)
- Page loading: Webpage loading progress
- Batch operations: Processing multiple items
- Installations: Software installation progress
Styling Linear Bars
// Thin progress bar (default)
<ProgressBarComponent
type="Linear"
value={50}
height="4"
/>
// Thick progress bar (status bar)
<ProgressBarComponent
type="Linear"
value={50}
height="30"
/>
// Full width with height
<ProgressBarComponent
type="Linear"
value={50}
height="60"
width="100%"
/>Height guidelines:
- 4-8px: Default thin bars (subtle background indicator)
- 20-40px: Prominent status bars (clear visual focus)
- 60px+: Large display bars (dashboard/kiosk displays)
Circular Progress Bar
The Circular type displays progress as a circular arc or donut chart. Progress fills from the top and continues clockwise.
Basic Circular Example
<ProgressBarComponent
id="circular"
type="Circular"
value={65}
height="160px"
animation={{
enable: true,
duration: 2000,
delay: 0
}}
/>When to Use Circular
- Compact spaces: Sidebars, widgets, cards
- File uploads in dialogs: Limited width constraints
- Dashboard widgets: Circular gauges and metrics
- Process status: Visual indicators in status pages
- Time-based progress: Countdown timers, session timers
Sizing Circular Bars
// Small indicator (compact)
<ProgressBarComponent
type="Circular"
value={50}
height="80px"
/>
// Medium indicator (common)
<ProgressBarComponent
type="Circular"
value={50}
height="160px"
/>
// Large indicator (prominent)
<ProgressBarComponent
type="Circular"
value={50}
height="280px"
/>Size guidelines:
- 60-80px: Compact indicators (inline, sidebars)
- 120-160px: Standard indicators (cards, widgets)
- 200-280px: Large prominent indicators (dashboards)
- 300px+: Very large display (public displays, kiosks)
Semi-Circular Progress Bar
The Semicircle type displays progress as a half-circle arc, useful for specialized layouts and limited vertical space.
Basic Semi-Circular Example
<ProgressBarComponent
id="semicircle"
type="Semicircle"
value={75}
height="160px"
animation={{
enable: true,
duration: 2000
}}
/>When to Use Semi-Circular
- Dashboard panels: Stacked in limited height areas
- Mobile layouts: Width-constrained vertical stacks
- Industrial displays: Gauge-style indicators
- Stats cards: KPI displays
- Process indicators: Multi-step workflows
Sizing Semi-Circular Bars
// Compact semi-circle
<ProgressBarComponent
type="Semicircle"
value={50}
height="100px"
/>
// Standard semi-circle
<ProgressBarComponent
type="Semicircle"
value={50}
height="160px"
/>
// Large semi-circle
<ProgressBarComponent
type="Semicircle"
value={50}
height="240px"
/>Type Comparison
| Aspect | Linear | Circular | Semicircle |
|---|---|---|---|
| Space | Full width horizontal | Compact square | Compact half-height |
| Best for | Bars, downloads, steps | Widgets, dashboards | Cards, panels |
| Height control | Via height prop | Via height (diameter) | Via height (radius) |
| RTL support | Full (auto-reversed) | Full (from top) | Full (from top) |
| Readability | Excellent in headers | Good in sidebars | Best in cards |
| Mobile | Better | Better | Best |
Choosing the Right Type
Decision Tree
Do you have full width (>300px)?
├─ YES
│ └─ Use LINEAR
│ (Best for full-width bars, headers, sections)
│
└─ NO (limited space)
├─ Height available >120px?
│ ├─ YES → Use CIRCULAR
│ │ (Dashboard widgets, cards)
│ │
│ └─ NO (<120px) → Use SEMICIRCLE
│ (Compact cards, mobile)Use Case Examples
File Upload Dialog:
// Limited dialog width → Use Circular
<ProgressBarComponent
type="Circular"
value={uploadProgress}
height="120px"
/>Page Loading Bar:
// Full page width → Use Linear
<ProgressBarComponent
type="Linear"
value={pageLoadProgress}
height="4"
/>Dashboard Metric:
// Card widget (300x200px) → Use Circular or Semicircle
<div style={{ width: '300px', height: '200px' }}>
<ProgressBarComponent
type="Circular"
value={cpuUsage}
height="150px"
/>
</div>Real-World Examples
Example 1: File Upload with Progress
import { useState } from 'react';
import { ProgressBarComponent } from '@syncfusion/ej2-react-progressbar';
function FileUploader() {
const [uploadProgress, setUploadProgress] = useState(0);
const [fileName, setFileName] = useState('');
const [status, setStatus] = useState('idle');
const handleUpload = (event) => {
const file = event.target.files?.[0];
if (!file) return;
setFileName(file.name);
setUploadProgress(0);
setStatus('uploading');
// Simulate upload with realistic progression
let progress = 0;
const interval = setInterval(() => {
progress += Math.random() * 20;
if (progress >= 100) {
setUploadProgress(100);
setStatus('complete');
clearInterval(interval);
setTimeout(() => {
setUploadProgress(0);
setStatus('idle');
}, 2000);
} else {
setUploadProgress(Math.min(progress, 99));
}
}, 500);
};
return (
<div style={{ width: '100%', maxWidth: '500px' }}>
<h3>Upload File</h3>
{fileName && <p>File: {fileName}</p>}
<ProgressBarComponent
type="Linear"
value={uploadProgress}
height="30"
showProgressValue={true}
progressValueFormat="N0 '%'"
animation={{ enable: true, duration: 500 }}
/>
<input
type="file"
onChange={handleUpload}
disabled={status === 'uploading'}
/>
<p>Status: {status.toUpperCase()}</p>
</div>
);
}
export default FileUploader;Example 2: Dashboard with Multiple Types
import { ProgressBarComponent } from '@syncfusion/ej2-react-progressbar';
function Dashboard() {
return (
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: '20px' }}>
{/* Full-width metric */}
<div style={{ gridColumn: '1 / -1' }}>
<h4>Overall Progress</h4>
<ProgressBarComponent
type="Linear"
value={65}
height="20"
/>
</div>
{/* Compact circular metrics */}
<div>
<h4>CPU Usage</h4>
<ProgressBarComponent
type="Circular"
value={45}
height="120px"
/>
</div>
<div>
<h4>Memory Usage</h4>
<ProgressBarComponent
type="Circular"
value={72}
height="120px"
/>
</div>
<div>
<h4>Disk Usage</h4>
<ProgressBarComponent
type="Circular"
value={38}
height="120px"
/>
</div>
</div>
);
}
export default Dashboard;Example 3: Mobile-Responsive Layout
import { useState, useEffect } from 'react';
import { ProgressBarComponent } from '@syncfusion/ej2-react-progressbar';
function ResponsiveProgress() {
const [isMobile, setIsMobile] = useState(window.innerWidth < 768);
const [value, setValue] = useState(50);
useEffect(() => {
const handleResize = () => {
setIsMobile(window.innerWidth < 768);
};
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
return (
<div style={{
padding: '20px',
textAlign: 'center'
}}>
<h3>Responsive Progress Bar</h3>
<p>Screen Size: {isMobile ? 'Mobile' : 'Desktop'}</p>
<ProgressBarComponent
type={isMobile ? "Semicircle" : "Linear"}
value={value}
height={isMobile ? "100px" : "40"}
showProgressValue={true}
animation={{ enable: true, duration: 500 }}
/>
<input
type="range"
min="0"
max="100"
value={value}
onChange={(e) => setValue(parseInt(e.target.value))}
style={{ width: '100%', marginTop: '20px' }}
/>
</div>
);
}
export default ResponsiveProgress;Performance Notes
- Linear: Fastest rendering, best for animations, ideal for high-frequency updates
- Circular: Slightly slower (SVG rendering), acceptable performance for real-time updates
- Semicircle: Similar performance to Circular, excellent for dashboard scenarios
Performance Tips:
- For real-time updates (>100 times/sec), prefer Linear type
- Disable animations for better performance on low-end devices
- Use
animation={{ enable: false }}for non-animated scenarios - Circular types use SVG, so rendering is efficient but slightly more CPU-intensive
Browser Compatibility
| Feature | Chrome | Firefox | Safari | Edge |
|---|---|---|---|---|
| Linear | ✓ | ✓ | ✓ | ✓ |
| Circular | ✓ | ✓ | ✓ | ✓ |
| Semicircle | ✓ | ✓ | ✓ | ✓ |
| Animation | ✓ | ✓ | ✓ | ✓ |
| SVG Rendering | ✓ | ✓ | ✓ | ✓ |
Tested on: IE11+, Chrome 90+, Firefox 88+, Safari 14+, Edge 90+
Next Steps
- States & Modes: Learn Determinate vs. Indeterminate - states-and-modes.md
- Customization: Style and customize your progress bars - customization-and-styling.md
- Advanced: Animations and events - animations-events-accessibility.md