mirror of
https://github.com/HananoshikaYomaru/openfreebooks.git
synced 2026-11-12 20:45:52 +00:00
Refactor Zero-One Board widget and update styles: Transition layout from flex to grid for improved visual structure in chapter.scss. Enhance scenario data in zero-one-board.tsx by adding image sources and alt text for better accessibility. Remove unnecessary truth evaluation logic to streamline user interaction and update feedback messaging for clarity.
This commit is contained in:
parent
945bcddde0
commit
3f666cf1b5
6 changed files with 50 additions and 81 deletions
BIN
content/math/zero-and-one/assets/app-plate-std.jpg
Normal file
BIN
content/math/zero-and-one/assets/app-plate-std.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 44 KiB |
BIN
content/math/zero-and-one/assets/empty-box-std.jpg
Normal file
BIN
content/math/zero-and-one/assets/empty-box-std.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
BIN
content/math/zero-and-one/assets/lamp-off-std.jpg
Normal file
BIN
content/math/zero-and-one/assets/lamp-off-std.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
BIN
content/math/zero-and-one/assets/lamp-on-std.jpg
Normal file
BIN
content/math/zero-and-one/assets/lamp-on-std.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 28 KiB |
|
|
@ -61,12 +61,12 @@
|
|||
}
|
||||
|
||||
.zero-one-board__visual {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 72px;
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
justify-items: center;
|
||||
min-height: 140px;
|
||||
margin: 12px 0;
|
||||
padding: 16px;
|
||||
padding: 14px;
|
||||
border: 1px dashed var(--line);
|
||||
border-radius: 10px;
|
||||
background: var(--card-bg);
|
||||
|
|
@ -86,9 +86,27 @@
|
|||
.zero-one-board__count {
|
||||
margin: 0;
|
||||
font-family: var(--mono);
|
||||
font-size: 2rem;
|
||||
font-weight: 700;
|
||||
color: var(--ink);
|
||||
font-size: 0.95rem;
|
||||
color: var(--soft-ink);
|
||||
}
|
||||
|
||||
.zero-one-board__image {
|
||||
width: min(100%, 540px);
|
||||
height: auto;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 10px;
|
||||
background: #f8fafc;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
[data-theme="dark"] .zero-one-board__image {
|
||||
border-color: rgba(148, 163, 184, 0.5);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root:not([data-theme="light"]) .zero-one-board__image {
|
||||
border-color: rgba(148, 163, 184, 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
.zero-one-board__choices {
|
||||
|
|
|
|||
|
|
@ -1,54 +1,47 @@
|
|||
import { createMemo, createSignal, For } from "solid-js";
|
||||
import { createMemo, createSignal } from "solid-js";
|
||||
|
||||
type Scenario = {
|
||||
id: string;
|
||||
prompt: string;
|
||||
imageSrc: string;
|
||||
imageAlt: string;
|
||||
correctAmount: 0 | 1;
|
||||
showTruth?: boolean;
|
||||
correctTruth?: boolean;
|
||||
};
|
||||
|
||||
const SCENARIOS: Scenario[] = [
|
||||
{
|
||||
id: "empty-box",
|
||||
prompt: "The box has no marbles inside.",
|
||||
imageSrc: "/chapters/math/zero-and-one/empty-box-std.jpg",
|
||||
imageAlt: "An empty box with nothing inside",
|
||||
correctAmount: 0,
|
||||
},
|
||||
{
|
||||
id: "one-apple",
|
||||
prompt: "There is exactly one apple on the plate.",
|
||||
imageSrc: "/chapters/math/zero-and-one/app-plate-std.jpg",
|
||||
imageAlt: "A plate with one apple",
|
||||
correctAmount: 1,
|
||||
},
|
||||
{
|
||||
id: "light-off",
|
||||
prompt: "The lamp is off — no light showing.",
|
||||
imageSrc: "/chapters/math/zero-and-one/lamp-off-std.jpg",
|
||||
imageAlt: "A lamp switched off",
|
||||
correctAmount: 0,
|
||||
},
|
||||
{
|
||||
id: "light-on",
|
||||
prompt: "The lamp is on — one steady light.",
|
||||
imageSrc: "/chapters/math/zero-and-one/lamp-on-std.jpg",
|
||||
imageAlt: "A lamp switched on",
|
||||
correctAmount: 1,
|
||||
},
|
||||
{
|
||||
id: "statement-false",
|
||||
prompt: "Statement: “The door is open.” (The door is shut.)",
|
||||
correctAmount: 0,
|
||||
showTruth: true,
|
||||
correctTruth: false,
|
||||
},
|
||||
{
|
||||
id: "statement-true",
|
||||
prompt: "Statement: “There is one bell ringing.” (You hear one bell.)",
|
||||
correctAmount: 1,
|
||||
showTruth: true,
|
||||
correctTruth: true,
|
||||
},
|
||||
];
|
||||
|
||||
function ZeroOneBoard() {
|
||||
const [index, setIndex] = createSignal(0);
|
||||
const [picked, setPicked] = createSignal<0 | 1 | null>(null);
|
||||
const [truthPicked, setTruthPicked] = createSignal<boolean | null>(null);
|
||||
|
||||
const scenario = createMemo(() => SCENARIOS[index() % SCENARIOS.length]);
|
||||
const atEnd = createMemo(() => index() >= SCENARIOS.length - 1);
|
||||
|
|
@ -58,21 +51,9 @@ function ZeroOneBoard() {
|
|||
return p !== null && p === scenario().correctAmount;
|
||||
});
|
||||
|
||||
const truthCorrect = createMemo(() => {
|
||||
const s = scenario();
|
||||
if (!s.showTruth) return true;
|
||||
const t = truthPicked();
|
||||
return t !== null && t === s.correctTruth;
|
||||
});
|
||||
const answered = createMemo(() => picked() !== null);
|
||||
|
||||
const answered = createMemo(() => {
|
||||
const s = scenario();
|
||||
if (picked() === null) return false;
|
||||
if (s.showTruth && truthPicked() === null) return false;
|
||||
return true;
|
||||
});
|
||||
|
||||
const allCorrect = createMemo(() => answered() && amountCorrect() && truthCorrect());
|
||||
const allCorrect = createMemo(() => answered() && amountCorrect());
|
||||
|
||||
const feedback = createMemo(() => {
|
||||
if (!answered()) return "Choose how many, then Next when you are ready.";
|
||||
|
|
@ -86,31 +67,23 @@ function ZeroOneBoard() {
|
|||
? "Not quite — this situation is one, not zero."
|
||||
: "Not quite — this situation is zero, not one.";
|
||||
}
|
||||
return truthPicked() === true
|
||||
? "Check the statement again — it does not match the world (false)."
|
||||
: "Check the statement again — it matches the world (true).";
|
||||
return "Try again.";
|
||||
});
|
||||
|
||||
const pickAmount = (n: 0 | 1) => {
|
||||
setPicked(n);
|
||||
};
|
||||
|
||||
const pickTruth = (value: boolean) => {
|
||||
setTruthPicked(value);
|
||||
};
|
||||
|
||||
const goNext = () => {
|
||||
if (!answered() || !allCorrect()) return;
|
||||
if (atEnd()) return;
|
||||
setIndex((i) => i + 1);
|
||||
setPicked(null);
|
||||
setTruthPicked(null);
|
||||
};
|
||||
|
||||
const resetAll = () => {
|
||||
setIndex(0);
|
||||
setPicked(null);
|
||||
setTruthPicked(null);
|
||||
};
|
||||
|
||||
return (
|
||||
|
|
@ -120,8 +93,7 @@ function ZeroOneBoard() {
|
|||
</h2>
|
||||
<div class="math-widget__body">
|
||||
<p class="math-widget__caption">
|
||||
Situation {index() + 1} of {SCENARIOS.length}. Pick the amount that fits. When a statement
|
||||
is shown, also pick true or false.
|
||||
Situation {index() + 1} of {SCENARIOS.length}. Pick the amount that fits the image.
|
||||
</p>
|
||||
<p class="zero-one-board__scenario">{scenario().prompt}</p>
|
||||
|
||||
|
|
@ -133,17 +105,17 @@ function ZeroOneBoard() {
|
|||
}}
|
||||
aria-live="polite"
|
||||
>
|
||||
<img
|
||||
src={scenario().imageSrc}
|
||||
alt={scenario().imageAlt}
|
||||
width="640"
|
||||
height="400"
|
||||
class="zero-one-board__image"
|
||||
loading="lazy"
|
||||
/>
|
||||
<p class="zero-one-board__count">
|
||||
{picked() === null ? "?" : picked()}
|
||||
Your pick: <strong>{picked() === null ? "?" : picked()}</strong>
|
||||
</p>
|
||||
<span class="counting-dots" role="img" aria-hidden="true">
|
||||
<For each={picked() === 1 ? [0] : []}>
|
||||
{() => <span class="counting-dots__dot" />}
|
||||
</For>
|
||||
{picked() === 0 ? (
|
||||
<span class="counting-dots__none">none</span>
|
||||
) : null}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="zero-one-board__choices" role="group" aria-label="How many?">
|
||||
|
|
@ -165,27 +137,6 @@ function ZeroOneBoard() {
|
|||
</button>
|
||||
</div>
|
||||
|
||||
{scenario().showTruth ? (
|
||||
<div class="zero-one-board__choices" role="group" aria-label="True or false?">
|
||||
<button
|
||||
type="button"
|
||||
class="scenario-demo__btn zero-one-board__choice"
|
||||
classList={{ "zero-one-board__choice--active": truthPicked() === false }}
|
||||
onClick={() => pickTruth(false)}
|
||||
>
|
||||
False
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="scenario-demo__btn scenario-demo__btn--primary zero-one-board__choice"
|
||||
classList={{ "zero-one-board__choice--active": truthPicked() === true }}
|
||||
onClick={() => pickTruth(true)}
|
||||
>
|
||||
True
|
||||
</button>
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
<p
|
||||
class="zero-one-board__feedback"
|
||||
classList={{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue