Skip to content

Commit f0a62ec

Browse files
committed
put the arrows around the dots, and make the dots round
The strip of steps says which step is on screen and how many there are, so the "3 / 7" beside it was saying it twice. The count goes, and the two arrows move to either side of the dots — the row is now the walk through the steps, and the row below it is what you do with the one you are on. The dots were also not dots. `.bottom-bar button` sets a 26px height for every button in the bar, and the build prefixes `.java-memory-playground` onto every selector, so writing the scope out by hand — as the dot rules did — leaves a rule *lighter* than its unscoped neighbours rather than heavier: two classes against a class and a type. The dots came out 16x26 ovals. The rules now lean on `.step-bar__steps` for weight instead, print mode included.
1 parent 4d10ddd commit f0a62ec

3 files changed

Lines changed: 89 additions & 74 deletions

File tree

.changeset/step-status-dots.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@ yet. The same went for red.
1111
A check now belongs to the step it judged, and the bar carries a dot for every step: black for a
1212
step of the trace, with nothing to do; yellow for an exercise not checked yet; green for one that
1313
was got right; red for one that was not. A tick and a cross inside the green and the red dots say
14-
it again for anyone who cannot tell the two hues apart, and for the printer. The dots are also the
15-
quickest way to get to a step — clicking one goes there.
14+
it again for anyone who cannot tell the two hues apart, and for the printer.
15+
16+
The dots are the walk through the steps as well: the arrows sit either side of the strip, clicking
17+
a dot goes to that step, and the "3 / 7" count they replaced is gone.
1618

1719
A verdict is kept with a fingerprint of the diagram it judged, so changing the step puts it back to
1820
not-checked rather than leaving a stale answer standing; moving a node, which changes nothing a

packages/java-memory-playground/src/StepBar.tsx

Lines changed: 50 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -82,57 +82,61 @@ export function StepBar({ editable = true }: { editable?: boolean }) {
8282
</div>
8383
)}
8484

85-
{/* Where the reader is, and — on an exercise — how each step went. The
86-
walk through the steps used to say only which one was on screen, so a
87-
"That matches" left standing from the step before read as if the step
88-
in front of you had already been answered. */}
85+
{/* The walk through the steps: a dot for each, between the two arrows.
86+
Where the reader is, and — on an exercise — how each step went. The
87+
bar used to say only which step was on screen, so a "That matches"
88+
left standing from the step before read as if the step in front of
89+
you had already been answered. The dots carry the count as well, so
90+
the "3 / 7" they replaced is gone. */}
8991
{!only && (
90-
<div className="step-bar__steps" role="group" aria-label={t.stepOverview}>
91-
{steps.map((_, i) => {
92-
const status = getStepStatus(i);
93-
const statusText = statusLabel(t, status, i + 1);
94-
return (
95-
<button
96-
key={i}
97-
type="button"
98-
className={`step-bar__dot ${status}${
99-
i === currentStep ? " current" : ""
100-
}`}
101-
onClick={() => goToStep(i)}
102-
aria-current={i === currentStep ? "step" : undefined}
103-
aria-label={statusText}
104-
title={statusText}
105-
>
106-
<span aria-hidden="true">{statusMark[status]}</span>
107-
</button>
108-
);
109-
})}
92+
<div className="step-bar__nav">
93+
<button
94+
className="button-icon"
95+
onClick={() => goToStep(currentStep - 1)}
96+
disabled={currentStep === 0}
97+
title={t.previousStep}
98+
aria-label={t.previousStep}
99+
>
100+
101+
</button>
102+
<div
103+
className="step-bar__steps"
104+
role="group"
105+
aria-label={t.stepOverview}
106+
>
107+
{steps.map((_, i) => {
108+
const status = getStepStatus(i);
109+
const statusText = statusLabel(t, status, i + 1);
110+
return (
111+
<button
112+
key={i}
113+
type="button"
114+
className={`step-bar__dot ${status}${
115+
i === currentStep ? " current" : ""
116+
}`}
117+
onClick={() => goToStep(i)}
118+
aria-current={i === currentStep ? "step" : undefined}
119+
aria-label={statusText}
120+
title={statusText}
121+
>
122+
<span aria-hidden="true">{statusMark[status]}</span>
123+
</button>
124+
);
125+
})}
126+
</div>
127+
<button
128+
className="button-icon"
129+
onClick={() => goToStep(currentStep + 1)}
130+
disabled={currentStep === steps.length - 1}
131+
title={t.nextStep}
132+
aria-label={t.nextStep}
133+
>
134+
135+
</button>
110136
</div>
111137
)}
112138

113139
<div className="step-bar__controls">
114-
<button
115-
className="button-icon"
116-
onClick={() => goToStep(currentStep - 1)}
117-
disabled={currentStep === 0}
118-
title={t.previousStep}
119-
aria-label={t.previousStep}
120-
>
121-
122-
</button>
123-
<span className="step-bar__count">
124-
{currentStep + 1} / {steps.length}
125-
</span>
126-
<button
127-
className="button-icon"
128-
onClick={() => goToStep(currentStep + 1)}
129-
disabled={currentStep === steps.length - 1}
130-
title={t.nextStep}
131-
aria-label={t.nextStep}
132-
>
133-
134-
</button>
135-
136140
{editable && (
137141
<>
138142
<label className="step-bar__exercise" title={t.exerciseStepHint}>

packages/java-memory-playground/src/index.css

Lines changed: 35 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -715,24 +715,39 @@ path.react-flow__edge-path:hover {
715715
max-width: 100%;
716716
}
717717

718-
/* The strip of steps: a row of its own above the controls, so it reads as a map
719-
of the walk rather than as another control in it. No cap on the measure — a
718+
/* Walking through the steps: the two arrows with the strip of dots between
719+
them, on a row of its own above the controls. No cap on the measure — a
720720
`max-width` here would let the row share a line with the controls after all,
721721
because it is the capped size, not the basis, that decides whether the two
722-
fit side by side. A trace long enough to need it wraps within the row, which
723-
the panel around it has already capped against the width of the canvas. */
724-
.step-bar__steps {
722+
fit side by side. */
723+
.step-bar__nav {
725724
flex: 0 0 100%;
726725
display: flex;
727726
flex-wrap: wrap;
728727
align-items: center;
729728
justify-content: center;
729+
gap: var(--jmp-space);
730+
}
731+
732+
/* The dots are the only part of the row that gives up width: a trace long
733+
enough to need it wraps them between the arrows, which stay put. */
734+
.step-bar__steps {
735+
flex: 0 1 auto;
736+
min-width: 0;
737+
display: flex;
738+
flex-wrap: wrap;
739+
align-items: center;
740+
justify-content: center;
730741
gap: 5px;
731742
}
732743

733-
/* A dot, not a button: the row of controls sets a height for everything in the
734-
bar, which is right for a button and four times too tall for this. */
735-
.java-memory-playground .step-bar__dot {
744+
/* A dot, not a button: the bottom bar sets a height for every button in it,
745+
which is right for a button and too tall for this.
746+
Two classes, and the scope is deliberately not written out — the build
747+
prefixes it onto every selector, so naming it here would leave this rule at
748+
the same weight as `.bottom-bar button` (a class and a type, once prefixed)
749+
and the height would go on being the bar's. */
750+
.step-bar__steps .step-bar__dot {
736751
width: 16px;
737752
height: 16px;
738753
min-height: 0;
@@ -749,32 +764,32 @@ path.react-flow__edge-path:hover {
749764
cursor: pointer;
750765
}
751766

752-
.java-memory-playground .step-bar__dot:hover {
767+
.step-bar__steps .step-bar__dot:hover {
753768
transform: scale(1.2);
754769
}
755770

756-
.java-memory-playground .step-bar__dot:focus-visible {
771+
.step-bar__steps .step-bar__dot:focus-visible {
757772
outline: 2px solid var(--jmp-accent);
758773
outline-offset: 2px;
759774
}
760775

761776
/* Nothing to do here: a step of the trace, which is read rather than built. */
762-
.java-memory-playground .step-bar__dot.none {
777+
.step-bar__steps .step-bar__dot.none {
763778
background: var(--jmp-text);
764779
color: var(--jmp-surface);
765780
}
766781

767-
.java-memory-playground .step-bar__dot.untried {
782+
.step-bar__steps .step-bar__dot.untried {
768783
background: var(--jmp-warning);
769784
color: var(--jmp-warning-text);
770785
}
771786

772-
.java-memory-playground .step-bar__dot.correct {
787+
.step-bar__steps .step-bar__dot.correct {
773788
background: var(--jmp-success);
774789
color: var(--jmp-white);
775790
}
776791

777-
.java-memory-playground .step-bar__dot.wrong {
792+
.step-bar__steps .step-bar__dot.wrong {
778793
background: var(--jmp-danger);
779794
color: var(--jmp-white);
780795
}
@@ -783,17 +798,11 @@ path.react-flow__edge-path:hover {
783798
because where you are and how the step went are two different questions —
784799
and in the ink of the text rather than the accent, which is the green a
785800
correct step is already painted in. */
786-
.java-memory-playground .step-bar__dot.current {
801+
.step-bar__steps .step-bar__dot.current {
787802
outline: 2px solid var(--jmp-text);
788803
outline-offset: 2px;
789804
}
790805

791-
.step-bar__count {
792-
min-width: 44px;
793-
text-align: center;
794-
font-variant-numeric: tabular-nums;
795-
}
796-
797806
/* The only part of the bar worth narrowing, so the row stays one row for as
798807
long as it can. Everything else is a control that has to stay readable. */
799808
.java-memory-playground input.step-bar__label {
@@ -1003,20 +1012,20 @@ path.react-flow__edge-path:hover {
10031012
marks inside the dots do the work: a tick for a step that was got right, a
10041013
cross for one that was not. The two without a mark are told apart by weight —
10051014
a step with nothing to do is solid, one still to be checked is an outline. */
1006-
.jmp-print .step-bar__dot {
1015+
.jmp-print .step-bar__steps .step-bar__dot {
10071016
border-color: var(--jmp-black);
10081017
color: var(--jmp-black);
10091018
}
10101019

1011-
.jmp-print .step-bar__dot.none {
1020+
.jmp-print .step-bar__steps .step-bar__dot.none {
10121021
background: var(--jmp-black);
10131022
}
10141023

1015-
.jmp-print .step-bar__dot.untried {
1024+
.jmp-print .step-bar__steps .step-bar__dot.untried {
10161025
background: var(--jmp-white);
10171026
}
10181027

1019-
.jmp-print .step-bar__dot.correct,
1020-
.jmp-print .step-bar__dot.wrong {
1028+
.jmp-print .step-bar__steps .step-bar__dot.correct,
1029+
.jmp-print .step-bar__steps .step-bar__dot.wrong {
10211030
background: var(--jmp-white);
10221031
}

0 commit comments

Comments
 (0)