Upgrade to template v3

This commit is contained in:
Florine W. Dekker 2022-11-21 08:27:22 +01:00
parent a5f3a8793d
commit e7a5f64f60
Signed by: FWDekker
GPG Key ID: D3DCFAA8A4560BE0
4 changed files with 90 additions and 134 deletions

View File

@ -1,6 +1,6 @@
{
"name": "doomsday",
"version": "1.4.5",
"version": "1.5.0",
"description": "Test your mastery of Conway's Doomsday rule.",
"author": "Florine W. Dekker",
"browser": "dist/bundle.js",

View File

@ -1,54 +1,23 @@
:root {
--error-color: red;
--success-color: green;
input, button {
width: unset;
}
/* Very unwide page */
#inputs {
max-width: 40rem;
.inputs {
display: flex;
}
.quiz-input {
max-width: 15rem;
.inputs input {
flex: 1;
margin-right: 1rem;
}
/* Common elements */
details * {
box-sizing: border-box;
details[open] summary,
details summary:focus {
/*noinspection CssUnresolvedCustomProperty*/
color: var(--accordion-close-summary-color) !important;
}
label, summary b {
cursor: pointer;
}
/* Input validation */
.success-message {
color: var(--success-color);
}
.error-message {
color: var(--error-color);
}
.success-box {
background-color: var(--success-color);
border-color: var(--success-color);
}
.error-box {
background-color: var(--error-color);
border-color: var(--error-color);
}
input[data-entered=true]:valid {
border-color: var(--success-color);
color: var(--success-color);
}
input[data-entered=true]:invalid {
border-color: var(--error-color);
color: var(--error-color);
details:not([open]) summary:not(:focus) {
/*noinspection CssUnresolvedCustomProperty*/
color: var(--accordion-open-summary-color) !important;
}

View File

@ -8,17 +8,23 @@
<meta name="description" content="Test your mastery of Conway's Doomsday rule." />
<meta name="theme-color" content="#0033cc" />
<meta name="fwd:nav:target" content="#nav" />
<meta name="fwd:nav:highlight-path" content="/Tools/Doomsday/" />
<meta name="fwd:footer:target" content="#footer" />
<meta name="fwd:footer:vcs-url" content="https://git.fwdekker.com/tools/doomsday/" />
<meta name="fwd:footer:version" content="v%%VERSION_NUMBER%%" />
<meta name="fwd:validation:load-forms" />
<title>Doomsday | FWDekker</title>
<link rel="stylesheet" href="https://static.fwdekker.com/fonts/roboto/roboto.css" />
<link rel="stylesheet" href="https://static.fwdekker.com/lib/template/2.x.x/template.css?v=%%VERSION_NUMBER%%" />
<link rel="stylesheet" href="https://static.fwdekker.com/lib/template/3.x.x/template.css?v=%%VERSION_NUMBER%%" />
<!--suppress HtmlUnknownTarget -->
<link rel="stylesheet" href="main.css?v=%%VERSION_NUMBER%%" />
<script async src="https://stats.fwdekker.com/count.js"
data-goatcounter="https://stats.fwdekker.com/count"></script>
</head>
<body>
<noscript>
<noscript class="fwd-js-notice">
<img src="https://stats.fwdekker.com/count?p=/tools/doomsday/" alt="Counting pixel" />
<p>
@ -27,67 +33,58 @@
instructions on how to enable JavaScript in your web browser</a>.
</p>
</noscript>
<main class="hidden">
<div id="nav"></div>
<div id="contents">
<div id="header"></div>
<nav id="nav"></nav>
<main class="hidden container">
<div role="document">
<section>
<header class="fwd-header">
<hgroup>
<h1><a href=".">Doomsday</a></h1>
<h2>
Test your mastery of
<a href="https://en.wikipedia.org/wiki/Doomsday_rule" target="_blank">Conway's Doomsday rule</a>.
</h2>
</hgroup>
</header>
</section>
<!-- Input -->
<section id="inputs" class="container">
<section>
<form>
<div class="row">
<div class="column">
<details open id="century-details">
<summary><b id="century-title-label">Century</b></summary>
<div class="inputWithButton">
<!--suppress HtmlFormInputWithoutLabel -->
<input type="text" id="century-input" class="quiz-input" autocomplete="off" autofocus />
<button type="button" id="century-submit" class="quiz-button">Check</button>
</div>
</details>
<details open id="century-details">
<summary><b id="century-title-label" data-label-for="century-input">Century</b></summary>
<div class="inputs">
<!--suppress HtmlFormInputWithoutLabel -->
<input type="text" id="century-input" class="quiz-input" autocomplete="off" autofocus />
<button type="button" id="century-submit" class="quiz-button">Check</button>
</div>
</div>
</details>
<div class="row">
<div class="column">
<details open id="year-details">
<summary><b id="year-title-label">Year</b></summary>
<div class="inputWithButton">
<!--suppress HtmlFormInputWithoutLabel -->
<input type="text" id="year-input" class="quiz-input" autocomplete="off" />
<button type="button" id="year-submit" class="quiz-button">Check</button>
</div>
</details>
<details open id="year-details">
<summary><b id="year-title-label" data-label-for="year-input">Year</b></summary>
<div class="inputs">
<!--suppress HtmlFormInputWithoutLabel -->
<input type="text" id="year-input" class="quiz-input" autocomplete="off" />
<button type="button" id="year-submit" class="quiz-button">Check</button>
</div>
</div>
</details>
<div class="row">
<div class="column">
<div>
<label for="day-input" id="day-title-label">Day</label>
<div class="inputWithButton">
<!--suppress HtmlFormInputWithoutLabel -->
<input type="text" id="day-input" class="quiz-input" autocomplete="off" />
<button type="button" id="day-submit" class="quiz-button">Check</button>
</div>
</div>
<details open id="day-details">
<summary><b id="day-title-label" data-label-for="day-input">Day</b></summary>
<div class="inputs">
<!--suppress HtmlFormInputWithoutLabel -->
<input type="text" id="day-input" class="quiz-input" autocomplete="off" />
<button type="button" id="day-submit" class="quiz-button">Check</button>
</div>
</div>
</details>
<div class="row">&#8203;</div>
<div class="row">
<div class="column">
<button type="button" id="reset-button">Reset</button>
</div>
</div>
<button type="button" id="reset-button">Reset</button>
</form>
</section>
<footer id="footer"></footer>
</div>
<div id="footer"></div>
</main>
<script src="https://static.fwdekker.com/lib/template/2.x.x/template.js?v=%%VERSION_NUMBER%%"></script>
<script src="https://static.fwdekker.com/lib/template/3.x.x/template.js?v=%%VERSION_NUMBER%%"></script>
<!--suppress HtmlUnknownTarget -->
<script src="bundle.js?v=%%VERSION_NUMBER%%"></script>
</body>

View File

@ -1,5 +1,7 @@
// @ts-ignore
const {$, doAfterLoad, footer, header, nav} = window.fwdekker;
const {$, doAfterLoad} = window.fwdekker;
// @ts-ignore
const {clearInputValidity, showInputInvalid, showInputValid} = window.fwdekker.validation;
import {DateTime} from "luxon";
@ -62,8 +64,6 @@ class ValidatableInput {
* Handles the user submitting the input.
*/
onSubmit(): void {
this.input.dataset["entered"] = "true";
if (this.isValid(this.input.value)) {
this.showSuccess();
this.onValidInput();
@ -110,39 +110,25 @@ class ValidatableInput {
*/
reset(): void {
this.input.value = "";
this.input.dataset["entered"] = "false";
this.showSuccess();
this.updateTitle();
this.titleLabel.classList.remove("success-message");
this.button.classList.remove("success-box");
clearInputValidity(this.input);
}
/**
* Marks the input as invalid.
*/
showError(): void {
this.input.setCustomValidity("Incorrect");
this.titleLabel.classList.remove("success-message");
this.titleLabel.classList.add("error-message");
this.button.classList.remove("success-box");
this.button.classList.add("error-box");
showInputInvalid(this.input);
}
/**
* Marks the input as valid.
*/
showSuccess(): void {
this.input.setCustomValidity("");
this.titleLabel.classList.remove("error-message");
this.titleLabel.classList.add("success-message");
this.button.classList.remove("error-box");
this.button.classList.add("success-box");
showInputValid(this.input);
}
/**
@ -351,19 +337,6 @@ class DoomsdayDate {
doAfterLoad(() => {
// Initialize template
$("#nav").appendChild(nav("/Tools/Doomsday/"));
$("#header").appendChild(header({
title: "Doomsday",
description: `
Test your mastery of \
<a href="https://en.wikipedia.org/wiki/Doomsday_rule">&#9099; Conway's Doomsday rule</a>
`
}));
$("#footer").appendChild(footer({
vcsURL: "https://git.fwdekker.com/tools/doomsday/",
version: "v%%VERSION_NUMBER%%"
}));
$("main").classList.remove("hidden");
@ -384,6 +357,13 @@ doAfterLoad(() => {
yearInput.updateTitle();
}
}("year", $("#year-details"));
const dayDetails = new class extends ToggleableSection {
onToggle(isOpened: boolean): void {
super.onToggle(isOpened);
if (isOpened) dayInput.selectInput();
dayInput.updateTitle();
}
}("day", $("#day-details"));
const centuryInput = new class extends ValidatableInput {
isValid(value: string): boolean {
@ -398,8 +378,10 @@ doAfterLoad(() => {
this.input.value = DoomsdayDate.expandDayString(this.input.value);
if (yearDetails.isOpened())
yearInput.selectInput();
else
else if (dayDetails.isOpened())
dayInput.selectInput();
else
resetButton.focus();
}
onInvalidInput() {
@ -424,7 +406,10 @@ doAfterLoad(() => {
onValidInput() {
this.input.value = DoomsdayDate.expandDayString(this.input.value);
dayInput.selectInput();
if (dayDetails.isOpened())
dayInput.selectInput();
else
resetButton.focus();
}
onInvalidInput() {
@ -457,7 +442,10 @@ doAfterLoad(() => {
}
updateTitle() {
this.titleLabel.innerText = `Weekday of ${quizDate.date.toISODate()}?`;
if (dayDetails.isOpened())
this.titleLabel.innerText = `Weekday of ${quizDate.date.toISODate()}?`;
else
this.titleLabel.innerText = `Day`;
}
}($("#day-input"), $("#day-title-label"), $("#day-submit"));
@ -489,8 +477,10 @@ doAfterLoad(() => {
centuryInput.selectInput();
else if (yearDetails.isOpened())
yearInput.selectInput();
else
else {
dayDetails.setOpened(true);
dayInput.selectInput();
}
}
// Let the fun begin