feat: add HTML lessons mode and side-by-side comparison UI
- Add HTML mode support with new validation types (element_exists, element_count, attribute_value, element_text, parent_child, sibling) - Create 3 HTML lesson modules: Elements, Forms Basic, Forms Validation - Implement side-by-side preview comparison (Your Output vs Expected) - Add merge animation with "Perfect Match!" overlay on validation success - Render expected output from solutionCode field in lesson JSON - Update schema to support HTML mode and solutionCode - Reorder modules: HTML first, then CSS, then Tailwind - Update tests for new functionality
This commit is contained in:
34
src/app.js
34
src/app.js
@@ -181,13 +181,24 @@ function updateEditorForMode(mode) {
|
||||
const codeInput = elements.codeInput;
|
||||
const editorLabel = document.querySelector(".editor-label");
|
||||
|
||||
if (mode === "tailwind") {
|
||||
codeInput.placeholder = "Enter Tailwind classes (e.g., bg-blue-500 text-white p-4)";
|
||||
if (editorLabel) editorLabel.textContent = "Tailwind Classes:";
|
||||
} else {
|
||||
codeInput.placeholder = "Enter your CSS code here...";
|
||||
if (editorLabel) editorLabel.textContent = "CSS Code:";
|
||||
}
|
||||
const modeConfig = {
|
||||
html: {
|
||||
placeholder: "Write your HTML here (e.g., <p>Hello World</p>)",
|
||||
label: "HTML Editor"
|
||||
},
|
||||
tailwind: {
|
||||
placeholder: "Enter Tailwind classes (e.g., bg-blue-500 text-white p-4)",
|
||||
label: "Tailwind Classes"
|
||||
},
|
||||
css: {
|
||||
placeholder: "Enter your CSS code here...",
|
||||
label: "CSS Editor"
|
||||
}
|
||||
};
|
||||
|
||||
const config = modeConfig[mode] || modeConfig.css;
|
||||
codeInput.placeholder = config.placeholder;
|
||||
if (editorLabel) editorLabel.textContent = config.label;
|
||||
}
|
||||
|
||||
// Configure editor layout based on display type
|
||||
@@ -266,6 +277,9 @@ function loadCurrentLesson() {
|
||||
// Focus on the code editor by default
|
||||
elements.codeInput.focus();
|
||||
|
||||
// Render the expected/solution preview for comparison
|
||||
lessonEngine.renderExpectedPreview();
|
||||
|
||||
// Track live changes and update preview when the user pauses typing
|
||||
setupLivePreview();
|
||||
}
|
||||
@@ -379,6 +393,9 @@ function runCode() {
|
||||
elements.nextBtn.classList.add("success");
|
||||
elements.taskInstruction.classList.add("success-instruction");
|
||||
|
||||
// Show merge animation for side-by-side comparison
|
||||
lessonEngine.showMatchAnimation();
|
||||
|
||||
// Update navigation buttons
|
||||
updateNavigationButtons();
|
||||
|
||||
@@ -388,6 +405,9 @@ function runCode() {
|
||||
// Reset any success indicators
|
||||
resetSuccessIndicators();
|
||||
|
||||
// Hide merge animation if it was showing
|
||||
lessonEngine.hideMatchAnimation();
|
||||
|
||||
// Show error feedback (with friendly message)
|
||||
showFeedback(false, validationResult.message || "Not quite there yet! Let's try again.");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user