Skip to content

Commit 4ea7f71

Browse files
committed
Update styling for snapshot field values to be more emphasize
1 parent 0ee3466 commit 4ea7f71

5 files changed

Lines changed: 108 additions & 43 deletions

File tree

PLANS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ Keep this checklist aligned with repository behavior. Check off work in the same
5656
- [x] Record required Conquest bosses with canonical portraits, use a fixed segmented clear-time format, and default new snapshot names to the trimmed source loadout name.
5757
- [x] Require Rift clear times with the shared segmented control, normalize legacy Rift snapshots, and allow Normal Conquest levels through 15 while retaining level 10 caps elsewhere.
5858
- [x] Filter snapshot lists by conditional Legendary Conquest elements or Conquest bosses with multi-select OR semantics, tag-aware reset behavior, extracted toolbar/predicate modules, and focused verification.
59+
- [x] Emphasize loadout snapshot field values while keeping creation timestamps only in interactive preview headers.
5960

6061
## Loadout Code Sharing: Deferred
6162

src/components/loadout-snapshots/components/loadout-snapshot-metadata.tsx

Lines changed: 64 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,10 @@ import {
66
} from "@/components/loadout-snapshots/utils/loadout-snapshot-domain-values";
77
import { ELEMENTS_DATA } from "@/data/elements/ELEMENTS_DATA";
88
import { MONSTERLINGS_DATA } from "@/data/monsterlings/MONSTERLINGS_DATA";
9-
import { fmt } from "@/lib/utils";
109
import type { LoadoutSnapshotDetails } from "@/stores/loadout-snapshots-slice";
1110
import { LoadoutSnapshotTagBadge } from "./loadout-snapshot-tag-badge";
1211

1312
type LoadoutSnapshotMetadataProps = {
14-
createdAt: number;
1513
tag: LoadoutSnapshotTag;
1614
details?: LoadoutSnapshotDetails | null;
1715
notes?: string;
@@ -25,21 +23,22 @@ const ResElementMetadata = ({
2523
}) =>
2624
elementIds?.length ? (
2725
<span className="inline-flex flex-wrap items-center gap-1">
28-
RES Element
29-
{elementIds.map((elementId) => (
30-
<img
31-
key={elementId}
32-
src={ELEMENTS_DATA[elementId].image}
33-
width="16"
34-
height="16"
35-
alt={`${LOADOUT_SNAPSHOT_ELEMENT_LABELS[elementId]} RES Element icon`}
36-
/>
37-
))}
26+
<span className="text-muted-foreground">RES Element</span>
27+
<span className="inline-flex items-center gap-1 font-semibold text-foreground">
28+
{elementIds.map((elementId) => (
29+
<img
30+
key={elementId}
31+
src={ELEMENTS_DATA[elementId].image}
32+
width="16"
33+
height="16"
34+
alt={`${LOADOUT_SNAPSHOT_ELEMENT_LABELS[elementId]} RES Element icon`}
35+
/>
36+
))}
37+
</span>
3838
</span>
3939
) : null;
4040

4141
export const LoadoutSnapshotMetadata = ({
42-
createdAt,
4342
tag,
4443
details,
4544
notes,
@@ -50,22 +49,34 @@ export const LoadoutSnapshotMetadata = ({
5049
<LoadoutSnapshotTagBadge tag={tag} />
5150
{details && "difficulty" in details && details.boss_id !== undefined ? (
5251
<span className="inline-flex items-center gap-1 text-foreground">
52+
<span className="text-muted-foreground">Boss</span>
5353
<img
5454
src={MONSTERLINGS_DATA[details.boss_id].image}
5555
width="20"
5656
height="20"
5757
alt={`${MONSTERLINGS_DATA[details.boss_id].name} icon`}
5858
/>
59-
{MONSTERLINGS_DATA[details.boss_id].name}
59+
<span className="font-semibold">
60+
{MONSTERLINGS_DATA[details.boss_id].name}
61+
</span>
6062
</span>
6163
) : null}
6264
{details && (
6365
<span className="inline-flex flex-wrap items-center gap-1">
6466
{"difficulty" in details ? (
6567
<>
66-
Difficulty{" "}
67-
{LOADOUT_SNAPSHOT_DIFFICULTY_LABELS[details.difficulty]} · Level{" "}
68-
{details.level} · Clear time {details.clear_time}
68+
<span>Difficulty</span>{" "}
69+
<span className="font-semibold text-foreground">
70+
{LOADOUT_SNAPSHOT_DIFFICULTY_LABELS[details.difficulty]}
71+
</span>{" "}
72+
· <span>Level</span>{" "}
73+
<span className="font-semibold text-foreground">
74+
{details.level}
75+
</span>{" "}
76+
· <span>Clear time</span>{" "}
77+
<span className="font-semibold text-foreground">
78+
{details.clear_time}
79+
</span>
6980
{details.res_element_ids?.length ? (
7081
<>
7182
{" "}
@@ -75,28 +86,51 @@ export const LoadoutSnapshotMetadata = ({
7586
</>
7687
) : "element_id" in details ? (
7788
<>
78-
Element{" "}
79-
<img
80-
src={ELEMENTS_DATA[details.element_id].image}
81-
width="16"
82-
height="16"
83-
alt={`${LOADOUT_SNAPSHOT_ELEMENT_LABELS[details.element_id]} icon`}
84-
/>{" "}
89+
<span>Element</span>{" "}
90+
<span className="inline-flex items-center gap-1 font-semibold text-foreground">
91+
<img
92+
src={ELEMENTS_DATA[details.element_id].image}
93+
width="16"
94+
height="16"
95+
alt={`${LOADOUT_SNAPSHOT_ELEMENT_LABELS[details.element_id]} icon`}
96+
/>
97+
</span>{" "}
8598
{details.res_element_ids?.length ? (
8699
<>
87-
{" "}
88-
· <ResElementMetadata elementIds={details.res_element_ids} />
100+
· <ResElementMetadata
101+
elementIds={details.res_element_ids}
102+
/>{" "}
89103
</>
90-
) : null}{" "}
91-
· Score {details.score.toLocaleString("en-US")}
104+
) : null}
105+
· <span>Score</span>{" "}
106+
<span className="font-semibold text-foreground">
107+
{details.score.toLocaleString("en-US")}
108+
</span>
92109
</>
93110
) : (
94-
`Level ${details.level} · Clear time ${details.clear_time}${details.score === undefined ? "" : ` · Score ${details.score.toLocaleString("en-US")}`}`
111+
<>
112+
<span>Level</span>{" "}
113+
<span className="font-semibold text-foreground">
114+
{details.level}
115+
</span>{" "}
116+
· <span>Clear time</span>{" "}
117+
<span className="font-semibold text-foreground">
118+
{details.clear_time}
119+
</span>
120+
{details.score === undefined ? null : (
121+
<>
122+
{" "}
123+
· <span>Score</span>{" "}
124+
<span className="font-semibold text-foreground">
125+
{details.score.toLocaleString("en-US")}
126+
</span>
127+
</>
128+
)}
129+
</>
95130
)}
96131
</span>
97132
)}
98133
</div>
99-
<div>Created {fmt(createdAt)}</div>
100134
{showNotes && notes && (
101135
<p className="whitespace-pre-wrap text-foreground">
102136
<span className="font-medium">Note:</span> {notes}

src/components/loadout-snapshots/components/loadout-snapshots-list.test.tsx

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,16 @@ describe("LoadoutSnapshotsList", () => {
7171
it("shows the Conquest boss icon after the tag in rows and previews", () => {
7272
render(<LoadoutSnapshotsList />);
7373
const tag = screen.getByText("Conquest", { selector: "span" });
74-
expect(tag.nextElementSibling?.textContent).toBe("Custos");
74+
expect(tag.parentElement?.parentElement?.className).toContain(
75+
"text-muted-foreground",
76+
);
77+
expect(tag.nextElementSibling?.textContent).toBe("BossCustos");
7578
expect(
7679
tag.nextElementSibling?.querySelector("img")?.getAttribute("alt"),
7780
).toBe("Custos icon");
7881
expect(tag.parentElement?.textContent).toContain("Difficulty Normal");
82+
expect(screen.getByText("Custos").className).toContain("font-semibold");
83+
expect(screen.getByText("Normal").className).toContain("font-semibold");
7984

8085
fireEvent.click(
8186
screen.getByRole("button", { name: "Preview Alpha clear snapshot row" }),
@@ -89,16 +94,14 @@ describe("LoadoutSnapshotsList", () => {
8994

9095
it("shows frozen snapshot metadata and filters by snapshot name", () => {
9196
render(<LoadoutSnapshotsList />);
92-
expect(
93-
screen.getByText(`Created ${new Date(2_000).toLocaleString()}`),
94-
).toBeTruthy();
97+
expect(screen.queryByRole("time")).toBeNull();
98+
expect(screen.queryByText(new Date(2_000).toLocaleString())).toBeNull();
9599
const tag = screen.getByText("Rift", { selector: "span" });
96100
expect(tag.parentElement?.textContent).toContain(
97101
"Level 50 · Clear time 01:02.03 · Score 12,345,678",
98102
);
99-
expect(tag.parentElement?.nextElementSibling?.textContent).toBe(
100-
`Created ${new Date(2_000).toLocaleString()}`,
101-
);
103+
for (const value of ["50", "01:02.03", "12,345,678"])
104+
expect(screen.getByText(value).className).toContain("font-semibold");
102105
expect(screen.getByText(/Note:/).closest("p")?.textContent).toBe(
103106
"Note: Bring fire resistance",
104107
);
@@ -228,7 +231,7 @@ describe("LoadoutSnapshotsList", () => {
228231
loadoutSnapshots: {
229232
fire: {
230233
...snapshot("fire", "Fire run", "legendary_conquest", 1),
231-
details: { element_id: 2, score: 1 },
234+
details: { element_id: 2, res_element_ids: [1], score: 1_234 },
232235
},
233236
earth: {
234237
...snapshot("earth", "Earth run", "legendary_conquest", 2),
@@ -243,6 +246,13 @@ describe("LoadoutSnapshotsList", () => {
243246
},
244247
});
245248
render(<LoadoutSnapshotsList />);
249+
expect(screen.getByAltText("Fire icon").parentElement?.className).toContain(
250+
"font-semibold",
251+
);
252+
expect(
253+
screen.getByAltText("Earth RES Element icon").parentElement?.className,
254+
).toContain("font-semibold");
255+
expect(screen.getByText("1,234").className).toContain("font-semibold");
246256

247257
const tagGroup = screen.getByRole("group", {
248258
name: "Filter loadout snapshots by tag",
@@ -353,6 +363,14 @@ describe("LoadoutSnapshotsList", () => {
353363
fireEvent.click(
354364
screen.getByRole("button", { name: "Preview Beta clear snapshot row" }),
355365
);
366+
const timestamp = screen.getByRole("time");
367+
expect(timestamp.textContent).toBe(
368+
`Created ${new Date(2_000).toLocaleString()}`,
369+
);
370+
expect(timestamp.className).toContain("text-[10px]");
371+
expect(timestamp.previousElementSibling?.getAttribute("data-slot")).toBe(
372+
"dialog-header",
373+
);
356374
expect(screen.getByText("Loadout Snapshot")).toBeTruthy();
357375
const previewDialog = within(
358376
screen.getByRole("dialog", { name: "Beta clear" }),

src/components/loadout-snapshots/components/loadout-snapshots-list.tsx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,6 @@ export const LoadoutSnapshotsList = () => {
146146
<div className="pointer-events-none relative z-10 min-w-0">
147147
<h3 className="font-semibold">{snapshot.name}</h3>
148148
<LoadoutSnapshotMetadata
149-
createdAt={snapshot.created_at}
150149
tag={snapshot.tag}
151150
details={snapshot.details}
152151
notes={snapshot.notes}
@@ -181,7 +180,6 @@ export const LoadoutSnapshotsList = () => {
181180
metadata={
182181
preview ? (
183182
<LoadoutSnapshotMetadata
184-
createdAt={preview.created_at}
185183
tag={preview.tag}
186184
details={preview.details}
187185
showNotes={false}
@@ -191,14 +189,23 @@ export const LoadoutSnapshotsList = () => {
191189
metadataWithNotes={
192190
preview?.notes ? (
193191
<LoadoutSnapshotMetadata
194-
createdAt={preview.created_at}
195192
tag={preview.tag}
196193
details={preview.details}
197194
notes={preview.notes}
198195
/>
199196
) : null
200197
}
201198
typeLabel="Loadout Snapshot"
199+
headerSupplement={
200+
preview ? (
201+
<time
202+
className="border-b px-4 py-1 text-[10px] leading-relaxed text-muted-foreground"
203+
dateTime={new Date(preview.created_at).toISOString()}
204+
>
205+
Created {new Date(preview.created_at).toLocaleString()}
206+
</time>
207+
) : null
208+
}
202209
target="snapshot"
203210
showMetadataInHeader={false}
204211
/>
@@ -225,7 +232,6 @@ export const LoadoutSnapshotsList = () => {
225232
renderData={snapshotRenderData(exported)}
226233
metadata={
227234
<LoadoutSnapshotMetadata
228-
createdAt={exported.created_at}
229235
tag={exported.tag}
230236
details={exported.details}
231237
notes={exported.notes}

src/components/loadouts/components/loadout-preview-dialog.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ type LoadoutPreviewDialogProps = {
3232
renderData?: LoadoutRenderData;
3333
metadata?: ReactNode;
3434
metadataWithNotes?: ReactNode;
35+
headerSupplement?: ReactNode;
3536
showMetadataInHeader?: boolean;
3637
typeLabel?: string;
3738
target?: "loadout" | "snapshot";
@@ -51,6 +52,7 @@ export const LoadoutPreviewDialog = ({
5152
renderData,
5253
metadata,
5354
metadataWithNotes,
55+
headerSupplement,
5456
showMetadataInHeader = true,
5557
typeLabel = "Team Loadout",
5658
target = "loadout",
@@ -81,7 +83,10 @@ export const LoadoutPreviewDialog = ({
8183
>
8284
<DialogContent
8385
className={cn(
84-
"grid max-h-[calc(100dvh-2rem)] w-[calc(100%-2rem)] max-w-none grid-rows-[auto_auto_minmax(0,1fr)] gap-0 overflow-hidden p-0",
86+
"grid max-h-[calc(100dvh-2rem)] w-[calc(100%-2rem)] max-w-none gap-0 overflow-hidden p-0",
87+
headerSupplement
88+
? "grid-rows-[auto_auto_auto_minmax(0,1fr)]"
89+
: "grid-rows-[auto_auto_minmax(0,1fr)]",
8590
compactMonsterlings
8691
? "sm:max-w-max"
8792
: hideEquipment
@@ -99,6 +104,7 @@ export const LoadoutPreviewDialog = ({
99104
overview.
100105
</DialogDescription>
101106
</DialogHeader>
107+
{headerSupplement}
102108
<div className="flex flex-wrap items-center justify-between gap-3 border-b p-3">
103109
<div className="flex flex-wrap items-center gap-3">
104110
<Label htmlFor="hide-equipment" className="cursor-pointer">

0 commit comments

Comments
 (0)