Skip to content

Commit ac78fa8

Browse files
Automate selected logic, apply to articles with given tag
1 parent ff3b836 commit ac78fa8

9 files changed

Lines changed: 44 additions & 42 deletions

dotcom-rendering/src/components/DirectoryPageNav.stories.tsx

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,6 @@ import { DirectoryPageNav } from './DirectoryPageNav';
55
const meta = {
66
component: DirectoryPageNav,
77
title: 'Components/Directory Page Nav',
8-
argTypes: {
9-
selected: {
10-
options: ['fixtures', 'tables', 'none'],
11-
control: { type: 'select' },
12-
},
13-
},
148
parameters: {
159
chromatic: {
1610
modes: {
@@ -28,14 +22,12 @@ type Story = StoryObj<typeof meta>;
2822

2923
export const WomensEuro2025 = {
3024
args: {
31-
selected: 'fixtures',
3225
pageId: 'football/women-s-euro-2025/table',
3326
},
3427
} satisfies Story;
3528

3629
export const OtherCompetition = {
3730
args: {
38-
selected: 'none',
3931
pageId: 'football/premierleague/table',
4032
},
4133
} satisfies Story;

dotcom-rendering/src/components/DirectoryPageNav.tsx

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,20 @@ import {
1010
palette,
1111
} from '@guardian/source/foundations';
1212
import { grid } from '../grid';
13+
import type { TagType } from '../types/tag';
1314

1415
type Props = {
15-
selected: Selected;
1616
pageId: string;
17+
pageTags?: TagType[];
1718
};
1819

1920
interface DirectoryPageNavConfig {
2021
pageIds: string[];
22+
tagIds: string[];
2123
textColor: string;
2224
backgroundColor: string;
23-
title: { label: string; link: string };
24-
links: { label: string; href: string; selectedSlug: string | undefined }[];
25+
title: { label: string; id: string };
26+
links: { label: string; id: string }[];
2527
backgroundImages?: {
2628
mobile: string;
2729
mobileLandscape: string;
@@ -39,32 +41,29 @@ const configs = [
3941
'sport/ng-interactive/2026/feb/04/winter-olympics-results-milano-cortina-2026',
4042
'sport/ng-interactive/2026/feb/04/winter-olympics-2026-latest-medal-table-milano-cortina',
4143
],
44+
tagIds: ['sport/winter-olympics-2026'],
4245
textColor: palette.neutral[7],
4346
backgroundColor: '#CCCCCC',
4447
title: {
4548
label: 'Winter Olympics 2026',
46-
link: 'https://www.theguardian.com/sport/winter-olympics-2026',
49+
id: 'sport/winter-olympics-2026',
4750
},
4851
links: [
4952
{
5053
label: 'Schedule',
51-
href: 'https://www.theguardian.com/sport/ng-interactive/2026/feb/04/winter-olympics-full-schedule-milano-cortina-2026',
52-
selectedSlug: 'schedule',
54+
id: 'sport/ng-interactive/2026/feb/04/winter-olympics-full-schedule-milano-cortina-2026',
5355
},
5456
{
5557
label: 'Results',
56-
href: 'https://www.theguardian.com/sport/ng-interactive/2026/feb/04/winter-olympics-results-milano-cortina-2026',
57-
selectedSlug: 'results',
58+
id: 'sport/ng-interactive/2026/feb/04/winter-olympics-results-milano-cortina-2026',
5859
},
5960
{
6061
label: 'Medal table',
61-
href: 'https://www.theguardian.com/sport/ng-interactive/2026/feb/04/winter-olympics-2026-latest-medal-table-milano-cortina',
62-
selectedSlug: undefined,
62+
id: 'sport/ng-interactive/2026/feb/04/winter-olympics-2026-latest-medal-table-milano-cortina',
6363
},
6464
{
6565
label: 'Full coverage',
66-
href: 'https://www.theguardian.com/sport/winter-olympics-2026',
67-
selectedSlug: undefined,
66+
id: 'sport/winter-olympics-2026',
6867
},
6968
],
7069
backgroundImages: {
@@ -80,10 +79,6 @@ const configs = [
8079
},
8180
] satisfies DirectoryPageNavConfig[];
8281

83-
type Configs = typeof configs;
84-
type SelectedSlug = Configs[number]['links'][number]['selectedSlug'];
85-
type Selected = Exclude<SelectedSlug, undefined>;
86-
8782
const backgroundImageStyles = (
8883
images?: DirectoryPageNavConfig['backgroundImages'],
8984
) => {
@@ -109,8 +104,14 @@ const backgroundImageStyles = (
109104
};
110105
};
111106

112-
export const DirectoryPageNav = ({ selected, pageId }: Props) => {
113-
const config = configs.find((cfg) => cfg.pageIds.includes(pageId));
107+
export const DirectoryPageNav = ({ pageId, pageTags }: Props) => {
108+
const config = configs.find(
109+
(cfg) =>
110+
cfg.pageIds.includes(pageId) ||
111+
cfg.tagIds.some(
112+
(tagId) => pageTags?.some((tag) => tag.id === tagId),
113+
),
114+
);
114115

115116
if (!config) {
116117
return null;
@@ -225,24 +226,23 @@ export const DirectoryPageNav = ({ selected, pageId }: Props) => {
225226

226227
return (
227228
<nav css={nav}>
228-
<a href={config.title.link} css={largeLinkStyles}>
229+
<a href={config.title.id} css={largeLinkStyles}>
229230
{config.title.label}
230231
</a>
231232
<ul css={list}>
232233
{config.links.map((link, i) => (
233-
<li key={link.label} css={listItem}>
234+
<li
235+
key={link.label}
236+
css={listItem}
237+
style={pageId === link.id ? selectedStyles : {}}
238+
>
234239
<a
235-
href={link.href}
240+
href={`/${link.id}`}
236241
css={
237242
i === config.links.length - 1
238243
? lastSmallLink
239244
: smallLink
240245
}
241-
style={
242-
link.selectedSlug === selected
243-
? selectedStyles
244-
: {}
245-
}
246246
>
247247
{link.label}
248248
</a>

dotcom-rendering/src/components/FootballMatchesPage.tsx

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,7 @@ export const FootballMatchesPage = ({
5959
pageId,
6060
}: Props) => (
6161
<>
62-
<DirectoryPageNav
63-
selected={kind === 'FootballFixtures' ? 'fixtures' : 'none'}
64-
pageId={pageId}
65-
/>
62+
<DirectoryPageNav pageId={pageId} />
6663
<main
6764
id="maincontent"
6865
data-layout="FootballDataPageLayout"

dotcom-rendering/src/components/FootballTablesPage.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export const FootballTablesPage = ({
3131
guardianBaseUrl,
3232
}: Props) => (
3333
<>
34-
<DirectoryPageNav selected="none" pageId={pageId} />
34+
<DirectoryPageNav pageId={pageId} />
3535
<main
3636
id="maincontent"
3737
data-layout="FootballDataPageLayout"

dotcom-rendering/src/layouts/FrontLayout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ export const FrontLayout = ({ front, NAV }: Props) => {
258258
/>
259259
</Island>
260260
)}
261-
<DirectoryPageNav selected="none" pageId={pageId} />
261+
<DirectoryPageNav pageId={pageId} />
262262

263263
{filteredCollections.map((collection, index) => {
264264
// Backfills should be added to the end of any curated content

dotcom-rendering/src/layouts/InteractiveLayout.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,10 @@ export const InteractiveLayout = (props: WebProps | AppsProps) => {
291291
</>
292292
)}
293293
<main data-layout="InteractiveLayout">
294-
<DirectoryPageNav selected="none" pageId={article.pageId} />
294+
<DirectoryPageNav
295+
pageId={article.pageId}
296+
pageTags={article.tags}
297+
/>
295298
<Section
296299
fullWidth={true}
297300
showTopBorder={false}

dotcom-rendering/src/layouts/ShowcaseLayout.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import { ArticleTitle } from '../components/ArticleTitle';
2020
import { Border } from '../components/Border';
2121
import { Carousel } from '../components/Carousel.importable';
2222
import { DecideLines } from '../components/DecideLines';
23+
import { DirectoryPageNav } from '../components/DirectoryPageNav';
2324
import { DiscussionLayout } from '../components/DiscussionLayout';
2425
import { Footer } from '../components/Footer';
2526
import { GridItem } from '../components/GridItem';
@@ -356,6 +357,10 @@ export const ShowcaseLayout = (props: WebProps | AppsProps) => {
356357
<AdPortals />
357358
</Island>
358359
)}
360+
<DirectoryPageNav
361+
pageId={article.pageId}
362+
pageTags={article.tags}
363+
/>
359364
<Section
360365
fullWidth={true}
361366
showTopBorder={false}

dotcom-rendering/src/layouts/StandardLayout.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { ArticleTitle } from '../components/ArticleTitle';
2121
import { Border } from '../components/Border';
2222
import { Carousel } from '../components/Carousel.importable';
2323
import { DecideLines } from '../components/DecideLines';
24+
import { DirectoryPageNav } from '../components/DirectoryPageNav';
2425
import { DiscussionLayout } from '../components/DiscussionLayout';
2526
import { Footer } from '../components/Footer';
2627
import { GetMatchNav } from '../components/GetMatchNav.importable';
@@ -437,6 +438,10 @@ export const StandardLayout = (props: WebProps | AppProps) => {
437438
<AdPortals />
438439
</Island>
439440
)}
441+
<DirectoryPageNav
442+
pageId={article.pageId}
443+
pageTags={article.tags}
444+
/>
440445
<Section
441446
fullWidth={true}
442447
showTopBorder={false}

dotcom-rendering/src/layouts/TagPageLayout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ export const TagPageLayout = ({ tagPage, NAV }: Props) => {
100100
</div>
101101

102102
<main data-layout="TagPageLayout" id="maincontent">
103-
<DirectoryPageNav selected="none" pageId={tagPage.pageId} />
103+
<DirectoryPageNav pageId={tagPage.pageId} />
104104
{isAccessibilityPage && (
105105
<Island priority="critical" defer={{ until: 'visible' }}>
106106
<Accessibility />

0 commit comments

Comments
 (0)