Skip to content

Commit 9e275e8

Browse files
authored
Merge pull request #14020 from bbc/WS-2526-expose-PV-heading-link
[WS-2526] - Expose link for pv curation & use subheading component
2 parents 2cf9394 + cd77096 commit 9e275e8

7 files changed

Lines changed: 71 additions & 10 deletions

File tree

src/app/components/Curation/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ export default ({
204204
blocks={portraitVideo.blocks}
205205
eventTrackingData={eventTrackingData}
206206
css={styles.pvCarousel}
207+
link={link}
207208
/>
208209
);
209210
}

src/app/components/PortraitVideoCarousel/index.styles.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ const styles = {
99
[`.${OPERA_MINI_CLASSNAME} &`]: {
1010
display: 'none',
1111
},
12+
'& > h2:has(a)': {
13+
marginBottom: 0,
14+
},
1215
}),
1316
heading: ({ palette, mq, spacings }: Theme) =>
1417
css({

src/app/components/PortraitVideoCarousel/index.test.tsx

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,25 @@ describe('PortraitVideoCarousel', () => {
3333
);
3434
});
3535

36+
it('Should render a Subheading with a link when link prop is provided', async () => {
37+
const link = '/test-link';
38+
await act(async () => {
39+
render(
40+
<Component
41+
{...fixture}
42+
link={link}
43+
eventTrackingData={eventTrackingData}
44+
/>,
45+
);
46+
});
47+
48+
const heading = screen.getByRole('heading', { level: 2 });
49+
expect(heading).toHaveTextContent(fixture.title);
50+
51+
const linkElement = screen.getByRole('link');
52+
expect(linkElement).toHaveAttribute('href', link);
53+
});
54+
3655
it('Should render without a title', async () => {
3756
await act(async () => {
3857
render(
@@ -52,6 +71,27 @@ describe('PortraitVideoCarousel', () => {
5271
);
5372
});
5473

74+
it('Should render without a title if link is provided but title is undefined', async () => {
75+
const link = '/test-link';
76+
await act(async () => {
77+
render(
78+
<Component
79+
{...fixture}
80+
title={undefined}
81+
link={link}
82+
eventTrackingData={eventTrackingData}
83+
/>,
84+
{ service: 'pidgin' },
85+
);
86+
});
87+
88+
expect(screen.queryByRole('heading', { level: 2 })).not.toBeInTheDocument();
89+
expect(screen.getByTestId('portrait-video-carousel')).toHaveAttribute(
90+
'aria-label',
91+
defaultAriaLabel,
92+
);
93+
});
94+
5595
it('Should render the PortraitCarouselNavigation component', async () => {
5696
await act(async () => {
5797
render(<Component {...fixture} eventTrackingData={eventTrackingData} />);

src/app/components/PortraitVideoCarousel/index.tsx

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import useOptimizelyVariation, {
88
ExperimentType,
99
} from '#app/hooks/useOptimizelyVariation';
1010
import useHydrationDetection from '#app/hooks/useHydrationDetection';
11+
import useClickTrackerHandler from '#app/hooks/useClickTrackerHandler';
1112
import styles from './index.styles';
1213
import PortraitVideoModal from '../PortraitVideoModal';
1314
import { BumpLoader } from '../MediaLoader';
@@ -16,13 +17,15 @@ import PortraitCarouselNavigation from './PortraitVideoCarouselNavigation';
1617
import Heading from '../Heading';
1718
import PortraitVideoNoJs from './PortraitVideoNoJs';
1819
import { PortraitClipMediaBlock } from '../MediaLoader/types';
20+
import Subheading from '../Curation/Subhead';
1921

2022
type PortraitVideoCarouselProps = {
2123
title?: string;
2224
blocks: PortraitClipMediaBlock[];
2325
eventTrackingData: EventTrackingData;
2426
className?: string;
2527
backgroundColor?: string;
28+
link?: string;
2629
};
2730

2831
const PortraitVideoCarousel = ({
@@ -31,6 +34,7 @@ const PortraitVideoCarousel = ({
3134
eventTrackingData,
3235
className,
3336
backgroundColor,
37+
link,
3438
}: PortraitVideoCarouselProps) => {
3539
const scrollRef = useRef<HTMLUListElement>(null);
3640
const [isModalOpen, setIsModalOpen] = useState(false);
@@ -66,6 +70,8 @@ const PortraitVideoCarousel = ({
6670

6771
const viewTracker = useViewTracker(eventTrackingDataExtended);
6872

73+
const subheadingClickTracker = useClickTrackerHandler(eventTrackingData);
74+
6975
if (isLite || isAmp) return null;
7076

7177
const handlePromoClick = (index: number) => {
@@ -91,15 +97,21 @@ const PortraitVideoCarousel = ({
9197
className={className}
9298
{...viewTracker}
9399
>
94-
{title && (
95-
<Heading
96-
level={2}
97-
size="doublePica"
98-
fontVariant="sansBold"
99-
css={styles.heading}
100-
>
100+
{link && title ? (
101+
<Subheading link={link} {...subheadingClickTracker}>
101102
{title}
102-
</Heading>
103+
</Subheading>
104+
) : (
105+
title && (
106+
<Heading
107+
level={2}
108+
size="doublePica"
109+
fontVariant="sansBold"
110+
css={styles.heading}
111+
>
112+
{title}
113+
</Heading>
114+
)
103115
)}
104116
<noscript>
105117
<PortraitVideoNoJs />

src/app/models/types/curationData.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ export interface BaseCuration {
8383
contentType?: string;
8484
pageTitle?: string;
8585
mediaCollection?: MediaCollection[];
86+
associatedContent?: {
87+
uri?: string;
88+
};
8689
}
8790

8891
export interface Curation extends BaseCuration {

src/app/pages/HomePage/HomePage.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ const HomePage = ({ pageData }: HomePageProps) => {
100100
link,
101101
position,
102102
visualStyle,
103+
associatedContent: { uri } = {},
103104
...curationProps
104105
}: Curation,
105106
index: number,
@@ -122,7 +123,7 @@ const HomePage = ({ pageData }: HomePageProps) => {
122123
title={curationTitle}
123124
topStoriesTitle={topStoriesTitle}
124125
position={position}
125-
link={link}
126+
link={link || uri}
126127
curationLength={curations?.length}
127128
nthCurationByStyleAndProminence={
128129
nthCurationByStyleAndProminence

ws-nextjs-app/pages/[service]/watch/[id]/live/LiveTvPageLayout.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const renderCuration = ({
2525
title: curationTitle,
2626
link,
2727
position,
28+
associatedContent: { uri } = {},
2829
...curationProps
2930
} = curation;
3031
return (
@@ -33,7 +34,7 @@ const renderCuration = ({
3334
summaries={summaries || []}
3435
title={curationTitle}
3536
position={position}
36-
link={link}
37+
link={link || uri}
3738
curationLength={curationLength}
3839
renderVisuallyHiddenH2Title={position === 0}
3940
curationId={curationId}

0 commit comments

Comments
 (0)