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.

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.

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.

<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>