fix(i18n): sync all lesson translations with English source
Synchronizes 72 lesson files across 5 languages (de, pl, es, ar, uk) to match the English source. This ensures code, solutions, and validations are identical while only title, description, task, and message fields are translated. Changes include: - Box model lessons (01-box-model.json) - Units and variables (05-units-variables.json) - Transitions and animations (06-transitions-animations.json) - Responsive design (08-responsive.json) - HTML elements (20-html-elements.json) - HTML forms basic and validation (21, 22) - HTML details/summary, progress/meter (23, 24) - HTML datalist, dialog, fieldset (25, 27, 28) - HTML tables and SVG (30, 32) - HTML marquee (31) - Welcome module (00-welcome.json) Fixes validation inconsistencies and removes extra content that exceeded English source. German translations were largely correct; Polish, Spanish, Arabic, and Ukrainian required full translations.
This commit is contained in:
@@ -1,110 +1,32 @@
|
||||
{
|
||||
"$schema": "../../schemas/code-crispies-module-schema.json",
|
||||
"id": "html-forms-validation",
|
||||
"title": "HTML Validation",
|
||||
"description": "Learn HTML5 built-in form validation attributes",
|
||||
"title": "Валідація форм",
|
||||
"description": "Використовуйте вбудовану валідацію HTML5 для кращого досвіду користувача",
|
||||
"mode": "html",
|
||||
"difficulty": "intermediate",
|
||||
"difficulty": "beginner",
|
||||
"lessons": [
|
||||
{
|
||||
"id": "required-fields",
|
||||
"title": "Required Fields",
|
||||
"description": "The <kbd>required</kbd> attribute prevents form submission if the field is empty.<br><br>Add it to any input that must be filled:<br><kbd><input type=\"text\" required></kbd><br><br>The browser shows a validation message automatically.",
|
||||
"task": "Make both the name and email fields required by adding the <kbd>required</kbd> attribute.",
|
||||
"title": "Обов'язкові поля",
|
||||
"description": "Атрибут <kbd>required</kbd> запобігає відправці форми, якщо поле порожнє. Браузер автоматично показує повідомлення валідації - без JavaScript!<br><br>Додайте його до будь-якого поля, яке має бути заповнене:<br><kbd><input type=\"text\" required></kbd>",
|
||||
"task": "Зробіть обидва поля (ім'я та email) обов'язковими, додавши атрибут <kbd>required</kbd> до кожного поля.",
|
||||
"previewHTML": "",
|
||||
"previewBaseCSS": "body { font-family: system-ui; padding: 20px; } form { max-width: 350px; } label { display: block; margin-top: 15px; margin-bottom: 5px; } label:first-of-type { margin-top: 0; } input { width: 100%; padding: 8px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; } input:invalid { border-color: #d32f2f; } button { margin-top: 20px; padding: 10px 20px; background: #1976d2; color: white; border: none; border-radius: 4px; cursor: pointer; }",
|
||||
"previewBaseCSS": "body { font-family: system-ui; padding: 20px; } form { max-width: 320px; } label { display: block; margin-top: 15px; margin-bottom: 5px; font-weight: 500; } label:first-of-type { margin-top: 0; } input { width: 100%; padding: 10px; border: 1px solid #ccc; border-radius: 6px; box-sizing: border-box; } input:focus { outline: 2px solid steelblue; border-color: transparent; } button { margin-top: 20px; padding: 10px 20px; background: steelblue; color: white; border: none; border-radius: 6px; cursor: pointer; font-weight: 500; }",
|
||||
"sandboxCSS": "",
|
||||
"initialCode": "<form>\n <label for=\"name\">Name: *</label>\n <input type=\"text\" id=\"name\" name=\"name\">\n \n <label for=\"email\">Email: *</label>\n <input type=\"email\" id=\"email\" name=\"email\">\n \n <button type=\"submit\">Submit</button>\n</form>",
|
||||
"solution": "<form>\n <label for=\"name\">Name: *</label>\n <input type=\"text\" id=\"name\" name=\"name\" required>\n \n <label for=\"email\">Email: *</label>\n <input type=\"email\" id=\"email\" name=\"email\" required>\n \n <button type=\"submit\">Submit</button>\n</form>",
|
||||
"initialCode": "<form>\n <label for=\"name\">Ім'я *</label>\n <input type=\"text\" id=\"name\" name=\"name\">\n \n <label for=\"email\">Email *</label>\n <input type=\"email\" id=\"email\" name=\"email\">\n \n <button type=\"submit\">Надіслати</button>\n</form>",
|
||||
"solution": "<form>\n <label for=\"name\">Ім'я *</label>\n <input type=\"text\" id=\"name\" name=\"name\" required>\n \n <label for=\"email\">Email *</label>\n <input type=\"email\" id=\"email\" name=\"email\" required>\n \n <button type=\"submit\">Надіслати</button>\n</form>",
|
||||
"previewContainer": "preview-area",
|
||||
"validations": [
|
||||
{
|
||||
"type": "attribute_value",
|
||||
"value": { "selector": "input[name='name']", "attr": "required", "value": true },
|
||||
"message": "Add the <kbd>required</kbd> attribute to the name input"
|
||||
"message": "Додайте <kbd>required</kbd> до поля імені"
|
||||
},
|
||||
{
|
||||
"type": "attribute_value",
|
||||
"value": { "selector": "input[name='email']", "attr": "required", "value": true },
|
||||
"message": "Add the <kbd>required</kbd> attribute to the email input"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "input-constraints",
|
||||
"title": "Constraints",
|
||||
"description": "Control what users can enter:<br><br><kbd>minlength</kbd> / <kbd>maxlength</kbd> - Text length limits<br><kbd>min</kbd> / <kbd>max</kbd> - Number range<br><kbd>pattern</kbd> - Regex pattern matching<br><kbd>placeholder</kbd> - Hint text (not a label!)",
|
||||
"task": "Add validation to the password input:<br>1. Add <kbd>minlength=\"8\"</kbd> for minimum length<br>2. Add <kbd>maxlength=\"20\"</kbd> for maximum length<br>3. Add <kbd>placeholder=\"Enter password\"</kbd> as a hint",
|
||||
"previewHTML": "",
|
||||
"previewBaseCSS": "body { font-family: system-ui; padding: 20px; } form { max-width: 350px; } label { display: block; margin-bottom: 5px; } input { width: 100%; padding: 8px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; } input:invalid:not(:placeholder-shown) { border-color: #d32f2f; } small { display: block; font-size: 12px; color: #666; margin-top: 4px; } button { margin-top: 20px; padding: 10px 20px; background: #1976d2; color: white; border: none; border-radius: 4px; cursor: pointer; }",
|
||||
"sandboxCSS": "",
|
||||
"initialCode": "<form>\n <label for=\"password\">Password:</label>\n <input type=\"password\" id=\"password\" name=\"password\" required aria-describedby=\"password-hint\">\n <small id=\"password-hint\">Must be 8-20 characters</small>\n \n <button type=\"submit\">Create Account</button>\n</form>",
|
||||
"solution": "<form>\n <label for=\"password\">Password:</label>\n <input type=\"password\" id=\"password\" name=\"password\" required minlength=\"8\" maxlength=\"20\" placeholder=\"Enter password\" aria-describedby=\"password-hint\">\n <small id=\"password-hint\">Must be 8-20 characters</small>\n \n <button type=\"submit\">Create Account</button>\n</form>",
|
||||
"previewContainer": "preview-area",
|
||||
"validations": [
|
||||
{
|
||||
"type": "attribute_value",
|
||||
"value": { "selector": "input[type='password']", "attr": "minlength", "value": "8" },
|
||||
"message": "Add <kbd>minlength</kbd>=\"8\" to the password input"
|
||||
},
|
||||
{
|
||||
"type": "attribute_value",
|
||||
"value": { "selector": "input[type='password']", "attr": "maxlength", "value": "20" },
|
||||
"message": "Add <kbd>maxlength</kbd>=\"20\" to the password input"
|
||||
},
|
||||
{
|
||||
"type": "attribute_value",
|
||||
"value": { "selector": "input[type='password']", "attr": "placeholder", "value": null },
|
||||
"message": "Add a <kbd>placeholder</kbd> to hint what to enter"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "complete-registration",
|
||||
"title": "Full Form",
|
||||
"description": "Build a complete registration form with all validation concepts:<br><br>- Required fields marked with *<br>- Email validation (use type=\"email\")<br>- Password with length constraints<br>- Terms checkbox (required)<br>- Submit button",
|
||||
"task": "Complete the registration form. Add required attributes, proper input types, and validation constraints.",
|
||||
"previewHTML": "",
|
||||
"previewBaseCSS": "body { font-family: system-ui; padding: 20px; } form { max-width: 400px; background: #f5f5f5; padding: 25px; border-radius: 8px; } h2 { margin-top: 0; margin-bottom: 20px; } label { display: block; margin-top: 15px; margin-bottom: 5px; font-weight: 500; } input[type='text'], input[type='email'], input[type='password'] { width: 100%; padding: 10px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; font-size: 14px; } input:focus { outline: 2px solid #1976d2; border-color: transparent; } input[type='checkbox'] { width: auto; margin-right: 8px; vertical-align: middle; } label:has(input[type='checkbox']) { display: flex; align-items: center; font-weight: normal; } button { width: 100%; margin-top: 20px; padding: 12px; background: #1976d2; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 16px; font-weight: 500; } button:hover { background: #1565c0; }",
|
||||
"sandboxCSS": "",
|
||||
"initialCode": "<form>\n <h2>Create Account</h2>\n \n <label for=\"fullname\">Full Name *</label>\n <input type=\"text\" id=\"fullname\" name=\"fullname\">\n \n <label for=\"email\">Email *</label>\n <input id=\"email\" name=\"email\">\n \n <label for=\"password\">Password *</label>\n <input id=\"password\" name=\"password\">\n \n <label>\n <input type=\"checkbox\" id=\"terms\" name=\"terms\">\n I agree to the Terms of Service *\n </label>\n \n <button type=\"submit\">Register</button>\n</form>",
|
||||
"solution": "<form>\n <h2>Create Account</h2>\n \n <label for=\"fullname\">Full Name *</label>\n <input type=\"text\" id=\"fullname\" name=\"fullname\" required>\n \n <label for=\"email\">Email *</label>\n <input type=\"email\" id=\"email\" name=\"email\" required>\n \n <label for=\"password\">Password *</label>\n <input type=\"password\" id=\"password\" name=\"password\" required minlength=\"8\">\n \n <label>\n <input type=\"checkbox\" id=\"terms\" name=\"terms\" required>\n I agree to the Terms of Service *\n </label>\n \n <button type=\"submit\">Register</button>\n</form>",
|
||||
"previewContainer": "preview-area",
|
||||
"validations": [
|
||||
{
|
||||
"type": "attribute_value",
|
||||
"value": { "selector": "#fullname", "attr": "required", "value": true },
|
||||
"message": "Make the full name field <kbd>required</kbd>"
|
||||
},
|
||||
{
|
||||
"type": "attribute_value",
|
||||
"value": { "selector": "#email", "attr": "type", "value": "email" },
|
||||
"message": "Set the email input <kbd>type=\"email\"</kbd>"
|
||||
},
|
||||
{
|
||||
"type": "attribute_value",
|
||||
"value": { "selector": "#email", "attr": "required", "value": true },
|
||||
"message": "Make the email field <kbd>required</kbd>"
|
||||
},
|
||||
{
|
||||
"type": "attribute_value",
|
||||
"value": { "selector": "#password", "attr": "type", "value": "password" },
|
||||
"message": "Set the password input <kbd>type=\"password\"</kbd>"
|
||||
},
|
||||
{
|
||||
"type": "attribute_value",
|
||||
"value": { "selector": "#password", "attr": "required", "value": true },
|
||||
"message": "Make the password field <kbd>required</kbd>"
|
||||
},
|
||||
{
|
||||
"type": "attribute_value",
|
||||
"value": { "selector": "#password", "attr": "minlength", "value": "8" },
|
||||
"message": "Add <kbd>minlength</kbd>=\"8\" to password"
|
||||
},
|
||||
{
|
||||
"type": "attribute_value",
|
||||
"value": { "selector": "#terms", "attr": "required", "value": true },
|
||||
"message": "Make the terms checkbox <kbd>required</kbd>"
|
||||
"message": "Додайте <kbd>required</kbd> до поля email"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user