Refactor Frame usage and improve HTML semantics

* Extract inline guide frames into a reusable Frame component
* Update step elements to use proper ordered lists (<ol> and <li>)
* Move related image and list styling to Frame.css
This commit is contained in:
johannes-hernehult 2026-07-08 21:41:41 +02:00
parent 53969472b7
commit 4145cec102
6 changed files with 42 additions and 31 deletions

View file

@ -0,0 +1,18 @@
import type { FrameType } from "../../lib/schemas";
export default function Frame({ frame } : { frame: FrameType }) {
return (
<div className="frame">
<h2>{frame.title}</h2>
<img src={URL.createObjectURL(frame.file)} alt={frame.title} />
<ol className="steps">
{frame.steps.map((step, stepIndex) => (
<li key={stepIndex} className="step">
{step.text}
</li>
))}
</ol>
</div>
);
}

View file

@ -8,6 +8,12 @@
border-radius: var(--radius); border-radius: var(--radius);
} }
.frame img {
max-height: 350px;
object-fit: contain;
object-position: left center;
}
.frame .buttons { .frame .buttons {
display: flex; display: flex;
gap: var(--size-md); gap: var(--size-md);
@ -20,3 +26,7 @@
.frame .buttons .remove { .frame .buttons .remove {
margin-left: auto; margin-left: auto;
} }
.frame ol {
margin-left: var(--size-md);
}

View file

@ -72,7 +72,7 @@ export default function Frame({
> >
Add Step Add Step
</button> </button>
<div className="steps"> <ol className="steps">
{frame.steps.map((step: StepType, index: number) => ( {frame.steps.map((step: StepType, index: number) => (
<Step <Step
key={step.id} key={step.id}
@ -82,7 +82,7 @@ export default function Frame({
updateStep={updateStep} updateStep={updateStep}
/> />
))} ))}
</div> </ol>
</div> </div>
); );
} }

View file

@ -13,7 +13,7 @@ export default function Step({
index: number; index: number;
}) { }) {
return ( return (
<div className={"step " + index}> <li className={"step " + index}>
<label> <label>
<span>{index + 1}. </span> <span>{index + 1}. </span>
<input <input
@ -25,6 +25,6 @@ export default function Step({
<button type="button" onClick={() => removeStep(step.id)}> <button type="button" onClick={() => removeStep(step.id)}>
Remove Step Remove Step
</button> </button>
</div> </li>
); );
} }

View file

@ -3,11 +3,13 @@ main:has(.guide) {
display: flex; display: flex;
justify-content: center; justify-content: center;
} }
.guide__frames { .guide__frames {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: var(--size-xl); gap: var(--size-xl);
} }
.guide { .guide {
max-width: 600px; max-width: 600px;
.delete-button { .delete-button {
@ -15,40 +17,30 @@ main:has(.guide) {
bottom: var(--size-md); bottom: var(--size-md);
right: var(--size-md); right: var(--size-md);
} }
.edit-button { .edit-button {
position: absolute; position: absolute;
top: var(--size-md); top: var(--size-md);
right: 8rem; right: 8rem;
} }
.export-button { .export-button {
position: absolute; position: absolute;
top: var(--size-md); top: var(--size-md);
right: var(--size-md); right: var(--size-md);
} }
.guide__frame {
padding: var(--size-md);
background-color: var(--color-bg-panel);
display: flex;
flex-direction: column;
gap: var(--size-sm);
}
.guide__frame img {
max-height: 350px;
object-fit: contain;
object-position: left center;
}
.guide__frame ol {
margin-left: var(--size-md);
}
} }
@media print { @media print {
main:has(.guide) { main:has(.guide) {
padding: 0rem; padding: 0rem;
justify-content: flex-start; justify-content: flex-start;
} }
.guide__frames { .guide__frames {
display: block; display: block;
} }
.guide__frame { .guide__frame {
position: relative; position: relative;
break-inside: avoid; break-inside: avoid;
@ -56,6 +48,7 @@ main:has(.guide) {
background-color: var(--color-bg-panel); background-color: var(--color-bg-panel);
margin: var(--size-lg) 0; margin: var(--size-lg) 0;
} }
.guide__frame img { .guide__frame img {
max-width: 100%; max-width: 100%;
max-height: 100px; max-height: 100px;

View file

@ -2,6 +2,7 @@ import "./Guide.css";
import { useParams, Link } from "react-router"; import { useParams, Link } from "react-router";
import { useGuides } from "../../../lib/contexts/guide.context"; import { useGuides } from "../../../lib/contexts/guide.context";
import useGuide from "../hooks/useGuide"; import useGuide from "../hooks/useGuide";
import Frame from "../../../components/frame/Frame";
export default function Guide() { export default function Guide() {
const { id } = useParams(); const { id } = useParams();
@ -20,18 +21,7 @@ export default function Guide() {
<div className="guide__frames"> <div className="guide__frames">
{guide.frames.map((frame, index) => ( {guide.frames.map((frame, index) => (
<div key={index} className="guide__frame frame"> <Frame key={index} frame={frame} />
<h2>{frame.title}</h2>
<img src={URL.createObjectURL(frame.file)} alt={frame.title} />
<ol className="steps">
{frame.steps.map((step, stepIndex) => (
<li key={stepIndex} className="guide__step">
{step.text}
</li>
))}
</ol>
</div>
))} ))}
</div> </div>