Circle Steps
Step indicator with circular progress and navigation controls.
Basic Usage
Starts in "not started" state (current=-1). Use next() to activate first step. On last step, next() marks all as complete.
Previous
Next
Reset
Complete All
Not started (current: -1)
<circle-steps id="steps">
<step-item label="Step 1"></step-item>
<step-item label="Step 2"></step-item>
<step-item label="Step 3"></step-item>
<step-item label="Step 4"></step-item>
</circle-steps>
<button onclick="steps.prev()">Previous</button>
<button onclick="steps.next()">Next</button>
<button onclick="steps.reset()">Reset</button>
<button onclick="steps.complete()">Complete All</button>
<script>
const steps = document.getElementById('steps');
// Listen for step changes
steps.addEventListener('step-change', (e) => {
console.log('New step:', e.detail.newStep);
console.log('Step data:', e.detail.step);
console.log('All complete?', e.detail.isComplete);
console.log('Not started?', e.detail.isNotStarted);
});
// Programmatic control
steps.next(); // Advance (starts if current=-1)
steps.prev(); // Go back
steps.reset(); // Back to not started (current=-1)
steps.start(); // Go to first step (current=0)
steps.complete(); // Mark all complete (current=4)
steps.goToStep(2); // Go to specific step
</script>
All Complete State
When current equals the number of steps, all steps show as complete with checkmarks.
<!-- current="4" with 4 steps = all complete -->
<circle-steps current="4">
<step-item label="Done"></step-item>
<step-item label="Done"></step-item>
<step-item label="Done"></step-item>
<step-item label="Done"></step-item>
</circle-steps>
With Labels & Descriptions
Steps with custom labels and descriptions.
<circle-steps current="1">
<step-item label="Account" description="Create your account"></step-item>
<step-item label="Profile" description="Setup your profile"></step-item>
<step-item label="Preferences" description="Set preferences"></step-item>
<step-item label="Confirm" description="Review & submit"></step-item>
</circle-steps>
Vertical Orientation
Steps displayed vertically.
<circle-steps orientation="vertical" current="1">
<step-item label="Order Placed" description="Your order has been confirmed"></step-item>
<step-item label="Processing" description="We are preparing your order"></step-item>
<step-item label="Shipped" description="Your order is on its way"></step-item>
<step-item label="Delivered" description="Package delivered"></step-item>
</circle-steps>
Clickable Steps
Click on steps to navigate. Click on the last step when active to mark all as complete. Click any step to go back.
Reset
Start
Active: Active (index 2)
<!-- Add "clickable" attribute to enable click navigation -->
<circle-steps id="wizard" clickable current="0">
<step-item label="Start"></step-item>
<step-item label="Middle"></step-item>
<step-item label="Almost"></step-item>
<step-item label="End"></step-item>
</circle-steps>
<script>
const wizard = document.getElementById('wizard');
// Listen for clicks on steps
wizard.addEventListener('step-click', (e) => {
console.log('Clicked step:', e.detail.index);
console.log('Step label:', e.detail.step.label);
});
// Listen for navigation changes
wizard.addEventListener('step-change', (e) => {
if (e.detail.isComplete) {
alert('All steps completed!');
}
});
</script>
<!-- Behavior:
- Click any step to navigate to it
- Click last step (when active) to complete all
- Click completed step to go back -->
Size Variants
Different sizes for different contexts.
Small
Medium (default)
Large
<circle-steps size="small">...</circle-steps>
<circle-steps size="large">...</circle-steps>
Without Numbers
Show only checkmarks, no numbers.
<circle-steps current="2" hide-numbers>
<step-item label="First"></step-item>
<step-item label="Second"></step-item>
<step-item label="Third"></step-item>
<step-item label="Fourth"></step-item>
</circle-steps>
Without Checkmarks
Numbers only, no checkmarks for completed steps.
<circle-steps current="2" hide-check>
<step-item label="First"></step-item>
<step-item label="Second"></step-item>
<step-item label="Third"></step-item>
<step-item label="Fourth"></step-item>
</circle-steps>
Custom Styling
Theme with CSS custom properties.
<circle-steps
current="2"
style="
--steps-active: #8b5cf6;
--steps-complete: #ec4899;
--steps-line-complete: #ec4899;
--steps-pending: #fce7f3;
"
>
<step-item label="First"></step-item>
<step-item label="Second"></step-item>
<step-item label="Third"></step-item>
<step-item label="Fourth"></step-item>
</circle-steps>
Checkout Flow Example
Real-world checkout process with navigation buttons.
Back
Continue
<circle-steps id="checkout" current="0">
<step-item label="Cart" description="Review items"></step-item>
<step-item label="Shipping" description="Delivery address"></step-item>
<step-item label="Payment" description="Payment method"></step-item>
<step-item label="Review" description="Confirm order"></step-item>
</circle-steps>
<button id="backBtn" onclick="checkout.prev()">Back</button>
<button id="nextBtn" onclick="checkout.next()">Continue</button>
<script>
const checkout = document.getElementById('checkout');
const backBtn = document.getElementById('backBtn');
const nextBtn = document.getElementById('nextBtn');
checkout.addEventListener('step-change', (e) => {
// Update button states
backBtn.disabled = e.detail.newStep <= 0;
if (e.detail.isComplete) {
nextBtn.textContent = 'Order Placed!';
nextBtn.disabled = true;
// Submit order...
} else if (e.detail.newStep === 3) {
nextBtn.textContent = 'Place Order';
} else {
nextBtn.textContent = 'Continue';
nextBtn.disabled = false;
}
});
</script>