Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Implement Seven-Step Progress Bar Component with Mock Control #44

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<link rel="stylesheet" href="./style.css" />
</head>
<body style="background-color: white">
<h1>Play with HTML/CSS/JS at 20241231</h1>
<div class="progress-bar-container"></div>
<input type="text" id="name" name="name" placeholder="input text here..." required maxlength="8" size="40" />

<!-- <script with type="module" will defer by default -->
Expand All @@ -13,6 +13,7 @@ <h1>WebSocket Connection Example</h1>
<p>Received Messages: <span id="messages"></span></p>
</div>
<script type="module" src="./script.mjs"></script>
<script type="module" src="./progressbar.mjs"></script>
<script>
console.log('🌹 hello world 20240904 ');
</script>
Expand Down
67 changes: 67 additions & 0 deletions progressbar.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
export class ProgressBar {
constructor(container) {
this.currentStep = 0;
this.totalSteps = 7;
this.progressContainer = document.createElement('div');
this.progressContainer.className = 'progress-container';

// Create progress steps
for (let i = 0; i < this.totalSteps; i++) {
const step = document.createElement('div');
step.className = 'progress-step';
step.dataset.step = i;
this.progressContainer.appendChild(step);
}

container.appendChild(this.progressContainer);

// Create mock progress button
this.mockButton = document.createElement('button');
this.mockButton.textContent = 'Next Step';
this.mockButton.className = 'mock-button';
this.mockButton.addEventListener('click', () => this.incrementProgress());

container.appendChild(this.mockButton);

this.updateProgress();
}

incrementProgress() {
if (this.currentStep < this.totalSteps) {
this.currentStep++;
this.updateProgress();
}

if (this.currentStep === this.totalSteps) {
this.mockButton.disabled = true;
this.mockButton.textContent = 'Completed';
}
}

updateProgress() {
const steps = this.progressContainer.querySelectorAll('.progress-step');
steps.forEach((step, index) => {
if (index < this.currentStep) {
step.classList.add('active');
} else {
step.classList.remove('active');
}
});
}

reset() {
this.currentStep = 0;
this.mockButton.disabled = false;
this.mockButton.textContent = 'Next Step';
this.updateProgress();
}
}

// Initialize progress bar when DOM is loaded
document.addEventListener('DOMContentLoaded', () => {
const container = document.querySelector('.progress-bar-container');
if (container) {
const progressBar = new ProgressBar(container);
window.progressBar = progressBar; // Make it globally accessible for testing
}
});
110 changes: 110 additions & 0 deletions style.css
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,113 @@ body {
justify-content: center;
overflow: hidden;
}

.progress-bar-container {
display: flex;
flex-direction: column;
align-items: center;
gap: 2rem;
width: 100%;
max-width: 800px;
padding: 2rem;
}

.progress-container {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
position: relative;
margin-bottom: 30px;
}

.progress-container::before {
content: '';
position: absolute;
top: 50%;
left: 0;
height: 4px;
width: 100%;
background-color: aliceblue;
transform: translateY(-50%);
z-index: 0;
}

.progress-step {
width: 30px;
height: 30px;
background-color: aliceblue;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
position: relative;
z-index: 1;
transition: all 0.3s ease;
cursor: pointer;
}

.progress-step:hover {
transform: scale(1.1);
box-shadow: 0 0 10px rgba(30, 144, 255, 0.3);
}

.progress-step.active {
background-color: dodgerblue;
}

.progress-step.active ~ .progress-step {
background-color: aliceblue;
}

.mock-button {
padding: 12px 24px;
font-size: 1rem;
background-color: dodgerblue;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
transition: all 0.3s ease;
}

.mock-button:hover:not(:disabled) {
background-color: #1e74d0;
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

.mock-button:disabled {
background-color: #ccc;
cursor: not-allowed;
opacity: 0.7;
}

@media screen and (max-width: 600px) {
.progress-container {
flex-direction: row;
flex-wrap: wrap;
gap: 1rem;
}

.progress-step {
width: 25px;
height: 25px;
}

.mock-button {
padding: 10px 20px;
font-size: 0.9rem;
}
}

@media screen and (max-width: 400px) {
.progress-bar-container {
padding: 1rem;
}

.progress-step {
width: 20px;
height: 20px;
}
}