From 3b00ce7a7f13d38fc0a043564160d247a86f14b0 Mon Sep 17 00:00:00 2001 From: Michael Czechowski Date: Wed, 24 Dec 2025 00:57:24 +0100 Subject: [PATCH] refactor: replace custom modal with native HTML dialog element MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Convert help and reset modals to native elements - Content is now in HTML, not dynamically generated via JS - Use dialog.showModal() and dialog.close() native API - Dialog handles Escape key natively for closing - Fix list indentation in help dialog with proper padding - Add styled kbd elements for keyboard shortcuts - Separate dialogs for help and reset confirmation - Apply same changes to German version Benefits: - Better accessibility (native focus trapping, escape handling) - Simpler JavaScript (no DOM manipulation for content) - Content visible in HTML source for easier editing - Native backdrop styling via ::backdrop đŸ€– Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/app.de.js | 108 +++++++++++++++------------------------------- src/app.js | 108 +++++++++++++++------------------------------- src/index.de.html | 62 +++++++++++++++++++++----- src/index.html | 62 +++++++++++++++++++++----- src/main.css | 87 ++++++++++++++++++++++++++++--------- 5 files changed, 240 insertions(+), 187 deletions(-) diff --git a/src/app.de.js b/src/app.de.js index 05221e0..54e260a 100644 --- a/src/app.de.js +++ b/src/app.de.js @@ -49,11 +49,13 @@ const elements = { resetBtn: document.getElementById("reset-btn"), disableFeedbackToggle: document.getElementById("disable-feedback-toggle"), - // Modal - modalContainer: document.getElementById("modal-container"), - modalTitle: document.getElementById("modal-title"), - modalContent: document.getElementById("modal-content"), - modalClose: document.getElementById("modal-close") + // Dialogs + helpDialog: document.getElementById("help-dialog"), + helpDialogClose: document.getElementById("help-dialog-close"), + resetDialog: document.getElementById("reset-dialog"), + resetDialogClose: document.getElementById("reset-dialog-close"), + cancelReset: document.getElementById("cancel-reset"), + confirmReset: document.getElementById("confirm-reset") }; // Initialize the lesson engine - now the single source of truth @@ -448,78 +450,36 @@ function runCode() { } } -// ================= MODALS ================= +// ================= DIALOGS ================= function showHelp() { - elements.modalTitle.textContent = "Hilfe"; + elements.helpDialog.showModal(); +} - elements.modalContent.innerHTML = ` -

So verwendest du Code Crispies

-

Code Crispies ist eine interaktive Plattform zum Erlernen von HTML, CSS und Tailwind durch praktische Übungen.

- -

Erste Schritte

-

Öffne das MenĂŒ (☰), um ein Lektionsmodul auszuwĂ€hlen. Jedes Modul enthĂ€lt eine Reihe von Lektionen.

- -

Lektionen abschließen

-
    -
  1. Lies die Anleitung auf der linken Seite
  2. -
  3. Schreibe deinen Code im Editor
  4. -
  5. Klicke auf "AusfĂŒhren" oder drĂŒcke Strg+Enter zum Testen
  6. -
  7. Folge den Hinweisen, um Probleme zu beheben
  8. -
  9. Klicke auf "Weiter", wenn du fertig bist
  10. -
- -

Tipps

-
    -
  • Klicke auf "Lösung zeigen", um das Zielergebnis zu sehen
  • -
  • Dein Fortschritt wird automatisch gespeichert
  • -
  • Strg+Enter fĂŒhrt deinen Code aus
  • -
- -

Emmet-KĂŒrzel (HTML-Modus)

-

Tippe AbkĂŒrzungen ein und drĂŒcke Tab zum Erweitern:

-
    -
  • div.container → div mit Klasse
  • -
  • ul>li*5 → ul mit 5 li-Kindern
  • -
  • nav>ul>li*3>a → verschachtelte Struktur
  • -
  • p{Hallo} → p mit Textinhalt
  • -
- `; - - elements.modalContainer.classList.remove("hidden"); +function closeHelpDialog() { + elements.helpDialog.close(); } function showResetConfirmation() { - elements.modalTitle.textContent = "Fortschritt zurĂŒcksetzen"; - - elements.modalContent.innerHTML = ` -

Bist du sicher, dass du deinen gesamten Fortschritt zurĂŒcksetzen möchtest? Dies kann nicht rĂŒckgĂ€ngig gemacht werden.

-
- - -
- `; - - document.getElementById("cancel-reset").addEventListener("click", closeModal); - document.getElementById("confirm-reset").addEventListener("click", () => { - lessonEngine.clearProgress(); - closeModal(); - closeSidebar(); - - // Reload first module - const modules = lessonEngine.modules; - if (modules.length > 0) { - selectModule(modules[0].id); - } - - updateProgressDisplay(); - }); - - elements.modalContainer.classList.remove("hidden"); + elements.resetDialog.showModal(); } -function closeModal() { - elements.modalContainer.classList.add("hidden"); +function closeResetDialog() { + elements.resetDialog.close(); +} + +function handleResetConfirm() { + lessonEngine.clearProgress(); + closeResetDialog(); + closeSidebar(); + + // Reload first module + const modules = lessonEngine.modules; + if (modules.length > 0) { + selectModule(modules[0].id); + } + + updateProgressDisplay(); } // ================= INITIALIZATION ================= @@ -575,10 +535,13 @@ function init() { }); elements.resetCodeBtn.addEventListener("click", resetCode); - // Modals + // Dialogs elements.helpBtn.addEventListener("click", showHelp); - elements.modalClose.addEventListener("click", closeModal); + elements.helpDialogClose.addEventListener("click", closeHelpDialog); elements.resetBtn.addEventListener("click", showResetConfirmation); + elements.resetDialogClose.addEventListener("click", closeResetDialog); + elements.cancelReset.addEventListener("click", closeResetDialog); + elements.confirmReset.addEventListener("click", handleResetConfirm); // Settings elements.disableFeedbackToggle.addEventListener("change", (e) => { @@ -599,10 +562,9 @@ function init() { e.preventDefault(); } - // Escape to close sidebar + // Escape to close sidebar (dialogs handle Escape natively) if (e.key === "Escape") { closeSidebar(); - closeModal(); } }); } diff --git a/src/app.js b/src/app.js index a42b80a..d82b528 100644 --- a/src/app.js +++ b/src/app.js @@ -49,11 +49,13 @@ const elements = { resetBtn: document.getElementById("reset-btn"), disableFeedbackToggle: document.getElementById("disable-feedback-toggle"), - // Modal - modalContainer: document.getElementById("modal-container"), - modalTitle: document.getElementById("modal-title"), - modalContent: document.getElementById("modal-content"), - modalClose: document.getElementById("modal-close") + // Dialogs + helpDialog: document.getElementById("help-dialog"), + helpDialogClose: document.getElementById("help-dialog-close"), + resetDialog: document.getElementById("reset-dialog"), + resetDialogClose: document.getElementById("reset-dialog-close"), + cancelReset: document.getElementById("cancel-reset"), + confirmReset: document.getElementById("confirm-reset") }; // Initialize the lesson engine - now the single source of truth @@ -448,78 +450,36 @@ function runCode() { } } -// ================= MODALS ================= +// ================= DIALOGS ================= function showHelp() { - elements.modalTitle.textContent = "Help"; + elements.helpDialog.showModal(); +} - elements.modalContent.innerHTML = ` -

How to Use Code Crispies

-

Code Crispies is an interactive platform for learning HTML, CSS, and Tailwind through practical exercises.

- -

Getting Started

-

Open the menu (☰) to select a lesson module. Each module contains a series of lessons.

- -

Completing Lessons

-
    -
  1. Read the instructions on the left
  2. -
  3. Write your code in the editor
  4. -
  5. Click "Run" or press Ctrl+Enter to test
  6. -
  7. Follow the hints to fix any issues
  8. -
  9. Click "Next" when you're done
  10. -
- -

Tips

-
    -
  • Click "Show Expected" to see the target result
  • -
  • Your progress is saved automatically
  • -
  • Ctrl+Enter runs your code
  • -
- -

Emmet Shortcuts (HTML mode)

-

Type abbreviations and press Tab to expand:

-
    -
  • div.container → div with class
  • -
  • ul>li*5 → ul with 5 li children
  • -
  • nav>ul>li*3>a → nested structure
  • -
  • p{Hello} → p with text content
  • -
- `; - - elements.modalContainer.classList.remove("hidden"); +function closeHelpDialog() { + elements.helpDialog.close(); } function showResetConfirmation() { - elements.modalTitle.textContent = "Reset Progress"; - - elements.modalContent.innerHTML = ` -

Are you sure you want to reset all your progress? This cannot be undone.

-
- - -
- `; - - document.getElementById("cancel-reset").addEventListener("click", closeModal); - document.getElementById("confirm-reset").addEventListener("click", () => { - lessonEngine.clearProgress(); - closeModal(); - closeSidebar(); - - // Reload first module - const modules = lessonEngine.modules; - if (modules.length > 0) { - selectModule(modules[0].id); - } - - updateProgressDisplay(); - }); - - elements.modalContainer.classList.remove("hidden"); + elements.resetDialog.showModal(); } -function closeModal() { - elements.modalContainer.classList.add("hidden"); +function closeResetDialog() { + elements.resetDialog.close(); +} + +function handleResetConfirm() { + lessonEngine.clearProgress(); + closeResetDialog(); + closeSidebar(); + + // Reload first module + const modules = lessonEngine.modules; + if (modules.length > 0) { + selectModule(modules[0].id); + } + + updateProgressDisplay(); } // ================= INITIALIZATION ================= @@ -575,10 +535,13 @@ function init() { }); elements.resetCodeBtn.addEventListener("click", resetCode); - // Modals + // Dialogs elements.helpBtn.addEventListener("click", showHelp); - elements.modalClose.addEventListener("click", closeModal); + elements.helpDialogClose.addEventListener("click", closeHelpDialog); elements.resetBtn.addEventListener("click", showResetConfirmation); + elements.resetDialogClose.addEventListener("click", closeResetDialog); + elements.cancelReset.addEventListener("click", closeResetDialog); + elements.confirmReset.addEventListener("click", handleResetConfirm); // Settings elements.disableFeedbackToggle.addEventListener("change", (e) => { @@ -599,10 +562,9 @@ function init() { e.preventDefault(); } - // Escape to close sidebar + // Escape to close sidebar (dialogs handle Escape natively) if (e.key === "Escape") { closeSidebar(); - closeModal(); } }); } diff --git a/src/index.de.html b/src/index.de.html index aa13f25..c66b435 100644 --- a/src/index.de.html +++ b/src/index.de.html @@ -136,18 +136,60 @@ - -
diff --git a/src/index.html b/src/index.html index 7b5aa07..c680f3f 100644 --- a/src/index.html +++ b/src/index.html @@ -136,18 +136,60 @@ - -