diff --git a/dotcom-rendering/src/components/CricketMatchStat.tsx b/dotcom-rendering/src/components/CricketMatchStat.tsx
new file mode 100644
index 00000000000..84e2927e3be
--- /dev/null
+++ b/dotcom-rendering/src/components/CricketMatchStat.tsx
@@ -0,0 +1,147 @@
+import { css } from '@emotion/react';
+import {
+ from,
+ space,
+ textSans14,
+ textSans15,
+ textSansBold14,
+ textSansBold15,
+ visuallyHidden,
+} from '@guardian/source/foundations';
+import type { Batter } from '../cricketMatchV2';
+import { palette } from '../palette';
+
+const containerCss = css`
+ position: relative;
+ padding: 5px 10px 10px;
+ color: ${palette('--football-match-stat-text')};
+ border: 1px solid ${palette('--football-match-stat-border')};
+ border-radius: 6px;
+`;
+
+const desktopPaddingCss = css`
+ ${from.desktop} {
+ padding-bottom: 14px;
+ }
+`;
+
+const visuallyHiddenStyles = css`
+ ${visuallyHidden}
+`;
+
+const responsiveTextSans = css`
+ ${textSans14}
+ ${from.desktop} {
+ ${textSans15}
+ }
+`;
+
+const responsiveTextSansBold = css`
+ ${textSansBold14}
+ ${from.desktop} {
+ ${textSansBold15}
+ }
+`;
+
+const tableStyles = css`
+ width: 100%;
+ border-collapse: collapse;
+ ${responsiveTextSans}
+`;
+
+const cellBaseStyles = css`
+ padding: ${space[2]}px ${space[3]}px ${space[1]}px 0;
+ text-align: left;
+ vertical-align: middle;
+`;
+
+const tableHeadCellStyles = css`
+ ${cellBaseStyles}
+ ${responsiveTextSansBold}
+ color: ${palette('--football-match-stat-text')};
+`;
+
+const tableCellStyles = css`
+ ${cellBaseStyles}
+ ${responsiveTextSans}
+`;
+
+const tableRowHeaderStyles = css`
+ ${cellBaseStyles}
+ display: flex;
+ align-items: center;
+ ${responsiveTextSans}
+`;
+
+const batterNameTextStyles = css`
+ display: flex;
+ flex-direction: column;
+`;
+
+const tableRowStyles = css`
+ border-top: 1px solid ${palette('--football-match-stat-border')};
+`;
+
+const numericCellStyles = css`
+ white-space: nowrap;
+ text-align: left;
+`;
+
+const howOutStyles = css`
+ color: ${palette('--football-match-info-team-number')};
+`;
+
+export const CricketMatchStatNotOutBatters = ({
+ notOutBatters,
+}: {
+ notOutBatters: Batter[];
+}) => {
+ const currentBatters = notOutBatters.filter(
+ (batter) => batter.onStrike || batter.nonStrike,
+ );
+ return (
+
+
Current Batters
+
+
+
+ | Batter |
+
+ Runs
+ |
+
+ Balls
+ |
+
+
+
+ {currentBatters.map((batter) => {
+ return (
+
+
+
+ {batter.onStrike
+ ? '(on strike)'
+ : '(at crease)'}
+
+
+ {batter.name}
+
+ {batter.howOut}
+
+
+ |
+
+ {batter.runs}
+ |
+
+ {batter.ballsFaced}
+ |
+
+ );
+ })}
+
+
+
+ );
+};
diff --git a/dotcom-rendering/src/components/CricketMiniMatchStats.stories.tsx b/dotcom-rendering/src/components/CricketMiniMatchStats.stories.tsx
new file mode 100644
index 00000000000..3b56f24846b
--- /dev/null
+++ b/dotcom-rendering/src/components/CricketMiniMatchStats.stories.tsx
@@ -0,0 +1,100 @@
+import { css } from '@emotion/react';
+import { breakpoints, from } from '@guardian/source/foundations';
+import preview from '../../.storybook/preview';
+import type { FECricketMatchStatsSummary } from '../frontend/feCricketMatchPage';
+import { palette } from '../palette';
+import { CricketMiniMatchStats as CricketMiniMatchStatsComponent } from './CricketMiniMatchStats';
+
+const gridCss = css`
+ background-color: ${palette('--football-live-blog-background')};
+ /**
+ * Extremely simplified live blog grid layout as we're only interested in
+ * the 240px wide left column added at the desktop breakpoint.
+ * dotcom-rendering/src/layouts/LiveLayout.tsx
+ */
+ ${from.desktop} {
+ display: grid;
+ grid-column-gap: 20px;
+ grid-template-columns: 240px 1fr;
+ }
+`;
+
+const meta = preview.meta({
+ title: 'Components/Cricket Mini Match Stats',
+ component: CricketMiniMatchStatsComponent,
+ decorators: [
+ (Story) => (
+
+
+
+ ),
+ ],
+ parameters: {
+ chromatic: {
+ viewports: [
+ breakpoints.mobileMedium,
+ breakpoints.tablet,
+ breakpoints.wide,
+ ],
+ },
+ },
+});
+
+const feMatchStatsSummaryData: FECricketMatchStatsSummary = {
+ status: 'abandoned',
+ currentBattingTeam: 'England',
+ notOutBatters: [
+ {
+ name: 'Tom Latham',
+ order: 1,
+ ballsFaced: 214,
+ runs: 151,
+ fours: 15,
+ sixes: 0,
+ out: false,
+ howOut: 'not out',
+ onStrike: false,
+ nonStrike: true,
+ },
+ {
+ name: 'Devon Conway',
+ order: 2,
+ ballsFaced: 224,
+ runs: 157,
+ fours: 22,
+ sixes: 3,
+ out: false,
+ howOut: 'not out',
+ onStrike: true,
+ nonStrike: false,
+ },
+ {
+ name: 'Devon Conway',
+ order: 2,
+ ballsFaced: 224,
+ runs: 157,
+ fours: 22,
+ sixes: 3,
+ out: false,
+ howOut: 'not out',
+ onStrike: false,
+ nonStrike: false,
+ },
+ ],
+};
+
+const getMockData = (data: FECricketMatchStatsSummary) =>
+ new Promise((resolve) => {
+ setTimeout(() => {
+ resolve(data);
+ }, 1000);
+ });
+
+export const CricketMiniMatchStats = meta.story({
+ args: {
+ matchStatsUrl:
+ 'https://api.nextgen.guardianapps.co.uk/sport/cricket/match-stats/2026-06-25/england-cricket-team.json',
+ getMatchStatsData: () => getMockData(feMatchStatsSummaryData),
+ refreshInterval: 16_000,
+ },
+});
diff --git a/dotcom-rendering/src/components/CricketMiniMatchStats.tsx b/dotcom-rendering/src/components/CricketMiniMatchStats.tsx
new file mode 100644
index 00000000000..623fc39e561
--- /dev/null
+++ b/dotcom-rendering/src/components/CricketMiniMatchStats.tsx
@@ -0,0 +1,153 @@
+import { css } from '@emotion/react';
+import { log } from '@guardian/libs';
+import { from } from '@guardian/source/foundations';
+import {
+ LinkButton,
+ SvgArrowRightStraight,
+} from '@guardian/source/react-components';
+import type { SWRConfiguration } from 'swr';
+import useSWR from 'swr';
+import { safeParse } from 'valibot';
+import type { CricketMatchStatsSummary } from '../cricketMatchV2';
+import { parseMatchStatsSummary } from '../cricketMatchV2';
+import { feCricketMatchStatsSummarySchema } from '../frontend/feCricketMatchPage';
+import type { Result } from '../lib/result';
+import { error, fromValibot, ok } from '../lib/result';
+import { palette } from '../palette';
+import { CricketMatchStatNotOutBatters } from './CricketMatchStat';
+import { Placeholder } from './Placeholder';
+
+const containerCss = css`
+ isolation: isolate; /* [1] */
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+ padding: 10px;
+ background-color: ${palette('--football-live-blog-background')};
+ ${from.mobileLandscape} {
+ padding: 20px;
+ }
+ ${from.desktop} {
+ padding-top: 24px;
+ padding-right: 0;
+ }
+`;
+
+const buttonTextCss = css`
+ ${from.desktop} {
+ display: none;
+ }
+`;
+
+const buttonTextShortCss = css`
+ display: none;
+ ${from.desktop} {
+ display: inline;
+ }
+`;
+
+type Props = {
+ matchStatsUrl: string;
+ getMatchStatsData: (url: string) => Promise;
+ refreshInterval: number;
+};
+
+export const CricketMiniMatchStats = (props: Props) => {
+ const { data, error: swrError } = useSWR(
+ props.matchStatsUrl,
+ fetcher(props.getMatchStatsData),
+ swrOptions(props.refreshInterval),
+ );
+
+ if (swrError) {
+ return null;
+ }
+
+ if (data === undefined) {
+ return (
+
+ );
+ }
+
+ if (data.notOutBatters == null) {
+ return null;
+ }
+
+ return (
+
+
+
+ }
+ iconSide="right"
+ theme={{
+ backgroundPrimary: palette(
+ '--football-match-stat-button-background',
+ ),
+ backgroundPrimaryHover: palette(
+ '--football-match-stat-button-background-hover',
+ ),
+ }}
+ >
+ View full scorecard
+ View full scorecard
+
+
+ );
+};
+
+const isMatchOver = (matchStatus: string | undefined) =>
+ matchStatus === 'result' || matchStatus === 'abandoned';
+
+const swrOptions = (
+ refreshInterval: number,
+): SWRConfiguration => ({
+ errorRetryCount: 1,
+ refreshInterval: (latestData: CricketMatchStatsSummary | undefined) =>
+ isMatchOver(latestData?.status) ? 0 : refreshInterval,
+});
+
+const fetcher =
+ (getMatchStatsData: Props['getMatchStatsData']) =>
+ (url: string): Promise =>
+ getMatchStatsData(url)
+ .then(parseData)
+ .then((result) => {
+ if (!result.ok) {
+ log('dotcom', result.error);
+ throw new Error();
+ } else {
+ return result.value;
+ }
+ })
+ .catch(() => {
+ log('dotcom', 'Failed to fetch math stats summary data');
+ throw new Error();
+ });
+
+const parseData = (json: unknown): Result => {
+ const feData = fromValibot(
+ safeParse(feCricketMatchStatsSummarySchema, json),
+ );
+
+ if (!feData.ok) {
+ return error('Failed to validate match stats summary data');
+ }
+
+ const parsedMatchStats = parseMatchStatsSummary(feData.value);
+
+ if (!parsedMatchStats.ok) {
+ return error('Failed to parse match stats summary');
+ }
+
+ return ok(parsedMatchStats.value);
+};
diff --git a/dotcom-rendering/src/components/CricketMiniMatchStatsWrapper.island.tsx b/dotcom-rendering/src/components/CricketMiniMatchStatsWrapper.island.tsx
new file mode 100644
index 00000000000..691ca75f4b4
--- /dev/null
+++ b/dotcom-rendering/src/components/CricketMiniMatchStatsWrapper.island.tsx
@@ -0,0 +1,17 @@
+import { CricketMiniMatchStats } from './CricketMiniMatchStats';
+
+export const CricketMiniMatchStatsWrapper = ({
+ matchStatsUrl,
+}: {
+ matchStatsUrl: string;
+}) => (
+
+);
+
+const getMatchStatsData = (url: string): Promise => {
+ return fetch(url).then((res) => res.json());
+};
diff --git a/dotcom-rendering/src/cricketMatchV2.ts b/dotcom-rendering/src/cricketMatchV2.ts
index 4e3844e1410..073f8c8896a 100644
--- a/dotcom-rendering/src/cricketMatchV2.ts
+++ b/dotcom-rendering/src/cricketMatchV2.ts
@@ -5,6 +5,7 @@ import type {
FECricketMatch,
FECricketMatchResult,
FECricketMatchResultWinnerStatus,
+ FECricketMatchStatsSummary,
FECricketTeam,
} from './frontend/feCricketMatchPage';
import { parseDate, parseIntResult } from './lib/parse';
@@ -130,6 +131,12 @@ export type CricketMatch = {
officials: string[];
};
+export type CricketMatchStatsSummary = {
+ status: string;
+ currentBattingTeam?: string;
+ notOutBatters?: Batter[];
+};
+
const paCricketStatusToMatchKind: Record = {
// Fixtures
'pre-match': 'Fixture',
@@ -221,6 +228,15 @@ const parseTeams = (
});
};
+export const parseMatchStatsSummary = (
+ feCricketMatchStatsSummary: FECricketMatchStatsSummary,
+): Result =>
+ ok({
+ status: feCricketMatchStatsSummary.status,
+ currentBattingTeam: feCricketMatchStatsSummary.currentBattingTeam,
+ notOutBatters: feCricketMatchStatsSummary.notOutBatters,
+ });
+
const parseWinnerResult = (
winner: FECricketMatchResultWinnerStatus,
resultType: WinnerResult['type'],
diff --git a/dotcom-rendering/src/frontend/feCricketMatchPage.ts b/dotcom-rendering/src/frontend/feCricketMatchPage.ts
index 740a0bc719e..45cc2adfbf5 100644
--- a/dotcom-rendering/src/frontend/feCricketMatchPage.ts
+++ b/dotcom-rendering/src/frontend/feCricketMatchPage.ts
@@ -113,3 +113,13 @@ export type FECricketMatchPage = {
contributionsServiceUrl: string;
pageId: string;
};
+
+export const feCricketMatchStatsSummarySchema = object({
+ status: string(),
+ currentBattingTeam: optional(string()),
+ notOutBatters: optional(array(feCricketBatterSchema)),
+});
+
+export type FECricketMatchStatsSummary = Output<
+ typeof feCricketMatchStatsSummarySchema
+>;
diff --git a/dotcom-rendering/src/frontend/schemas/feFootballMatchInfoPage.json b/dotcom-rendering/src/frontend/schemas/feFootballMatchInfoPage.json
index 13ea7bf0f51..46b3ecd763f 100644
--- a/dotcom-rendering/src/frontend/schemas/feFootballMatchInfoPage.json
+++ b/dotcom-rendering/src/frontend/schemas/feFootballMatchInfoPage.json
@@ -46,12 +46,12 @@
"type": "object",
"properties": {
"matchStats": {
- "$ref": "#/definitions/{id:string;homeTeam:{name:string;id:string;scorers:string[];codename:string;players:{name:string;id:string;position:string;lastName:string;substitute:boolean;timeOnPitch:string;shirtNumber:string;events:{eventTime:string;eventType:string;}[];}[];possession:number;shotsOn:number;shotsOff:number;corners:number;fouls:number;colours:string;crest:string;score?:number;};awayTeam:{name:string;id:string;scorers:string[];codename:string;players:{name:string;id:string;position:string;lastName:string;substitute:boolean;timeOnPitch:string;shirtNumber:string;events:{eventTime:string;eventType:string;}[];}[];possession:number;shotsOn:number;shotsOff:number;corners:number;fouls:number;colours:string;crest:string;score?:number;};status:string;comments?:string;}"
+ "$ref": "#/definitions/{id:string;status:string;homeTeam:{name:string;id:string;scorers:string[];codename:string;players:{name:string;id:string;position:string;lastName:string;substitute:boolean;timeOnPitch:string;shirtNumber:string;events:{eventTime:string;eventType:string;}[];}[];possession:number;shotsOn:number;shotsOff:number;corners:number;fouls:number;colours:string;crest:string;score?:number;};awayTeam:{name:string;id:string;scorers:string[];codename:string;players:{name:string;id:string;position:string;lastName:string;substitute:boolean;timeOnPitch:string;shirtNumber:string;events:{eventTime:string;eventType:string;}[];}[];possession:number;shotsOn:number;shotsOff:number;corners:number;fouls:number;colours:string;crest:string;score?:number;};comments?:string;}"
},
"matchInfo": {
"anyOf": [
{
- "$ref": "#/definitions/{stage:{stageNumber:string;};id:string;type:\"LiveMatch\";date:string;round:{roundNumber:string;name?:string;};leg:string;homeTeam:{name:string;id:string;score?:number;htScore?:number;aggregateScore?:number;scorers?:string;};awayTeam:{name:string;id:string;score?:number;htScore?:number;aggregateScore?:number;scorers?:string;};status:string;venue?:{name:string;id:string;};comments?:string;attendance?:string;referee?:{name:string;id:string;};}"
+ "$ref": "#/definitions/{stage:{stageNumber:string;};id:string;type:\"LiveMatch\";status:string;date:string;round:{roundNumber:string;name?:string;};leg:string;homeTeam:{name:string;id:string;score?:number;htScore?:number;aggregateScore?:number;scorers?:string;};awayTeam:{name:string;id:string;score?:number;htScore?:number;aggregateScore?:number;scorers?:string;};venue?:{name:string;id:string;};comments?:string;attendance?:string;referee?:{name:string;id:string;};}"
},
{
"$ref": "#/definitions/{stage:{stageNumber:string;};id:string;type:\"Fixture\";date:string;round:{roundNumber:string;name?:string;};leg:string;homeTeam:{name:string;id:string;score?:number;htScore?:number;aggregateScore?:number;scorers?:string;};awayTeam:{name:string;id:string;score?:number;htScore?:number;aggregateScore?:number;scorers?:string;};venue?:{name:string;id:string;};comments?:string;competition?:{name:string;id:string;};}"
@@ -829,21 +829,21 @@
"url"
]
},
- "{id:string;homeTeam:{name:string;id:string;scorers:string[];codename:string;players:{name:string;id:string;position:string;lastName:string;substitute:boolean;timeOnPitch:string;shirtNumber:string;events:{eventTime:string;eventType:string;}[];}[];possession:number;shotsOn:number;shotsOff:number;corners:number;fouls:number;colours:string;crest:string;score?:number;};awayTeam:{name:string;id:string;scorers:string[];codename:string;players:{name:string;id:string;position:string;lastName:string;substitute:boolean;timeOnPitch:string;shirtNumber:string;events:{eventTime:string;eventType:string;}[];}[];possession:number;shotsOn:number;shotsOff:number;corners:number;fouls:number;colours:string;crest:string;score?:number;};status:string;comments?:string;}": {
+ "{id:string;status:string;homeTeam:{name:string;id:string;scorers:string[];codename:string;players:{name:string;id:string;position:string;lastName:string;substitute:boolean;timeOnPitch:string;shirtNumber:string;events:{eventTime:string;eventType:string;}[];}[];possession:number;shotsOn:number;shotsOff:number;corners:number;fouls:number;colours:string;crest:string;score?:number;};awayTeam:{name:string;id:string;scorers:string[];codename:string;players:{name:string;id:string;position:string;lastName:string;substitute:boolean;timeOnPitch:string;shirtNumber:string;events:{eventTime:string;eventType:string;}[];}[];possession:number;shotsOn:number;shotsOff:number;corners:number;fouls:number;colours:string;crest:string;score?:number;};comments?:string;}": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
+ "status": {
+ "type": "string"
+ },
"homeTeam": {
"$ref": "#/definitions/{name:string;id:string;scorers:string[];codename:string;players:{name:string;id:string;position:string;lastName:string;substitute:boolean;timeOnPitch:string;shirtNumber:string;events:{eventTime:string;eventType:string;}[];}[];possession:number;shotsOn:number;shotsOff:number;corners:number;fouls:number;colours:string;crest:string;score?:number;}"
},
"awayTeam": {
"$ref": "#/definitions/{name:string;id:string;scorers:string[];codename:string;players:{name:string;id:string;position:string;lastName:string;substitute:boolean;timeOnPitch:string;shirtNumber:string;events:{eventTime:string;eventType:string;}[];}[];possession:number;shotsOn:number;shotsOff:number;corners:number;fouls:number;colours:string;crest:string;score?:number;}"
},
- "status": {
- "type": "string"
- },
"comments": {
"type": "string"
}
@@ -976,7 +976,7 @@
"eventType"
]
},
- "{stage:{stageNumber:string;};id:string;type:\"LiveMatch\";date:string;round:{roundNumber:string;name?:string;};leg:string;homeTeam:{name:string;id:string;score?:number;htScore?:number;aggregateScore?:number;scorers?:string;};awayTeam:{name:string;id:string;score?:number;htScore?:number;aggregateScore?:number;scorers?:string;};status:string;venue?:{name:string;id:string;};comments?:string;attendance?:string;referee?:{name:string;id:string;};}": {
+ "{stage:{stageNumber:string;};id:string;type:\"LiveMatch\";status:string;date:string;round:{roundNumber:string;name?:string;};leg:string;homeTeam:{name:string;id:string;score?:number;htScore?:number;aggregateScore?:number;scorers?:string;};awayTeam:{name:string;id:string;score?:number;htScore?:number;aggregateScore?:number;scorers?:string;};venue?:{name:string;id:string;};comments?:string;attendance?:string;referee?:{name:string;id:string;};}": {
"type": "object",
"properties": {
"stage": {
@@ -989,6 +989,9 @@
"type": "string",
"const": "LiveMatch"
},
+ "status": {
+ "type": "string"
+ },
"date": {
"type": "string"
},
@@ -1004,9 +1007,6 @@
"awayTeam": {
"$ref": "#/definitions/{name:string;id:string;score?:number;htScore?:number;aggregateScore?:number;scorers?:string;}"
},
- "status": {
- "type": "string"
- },
"venue": {
"$ref": "#/definitions/{name:string;id:string;}"
},
diff --git a/dotcom-rendering/src/frontend/schemas/feFootballMatchListPage.json b/dotcom-rendering/src/frontend/schemas/feFootballMatchListPage.json
index d050b811dcf..3ef40951d3c 100644
--- a/dotcom-rendering/src/frontend/schemas/feFootballMatchListPage.json
+++ b/dotcom-rendering/src/frontend/schemas/feFootballMatchListPage.json
@@ -96,7 +96,7 @@
"items": {
"anyOf": [
{
- "$ref": "#/definitions/{stage:{stageNumber:string;};id:string;type:\"LiveMatch\";date:string;round:{roundNumber:string;name?:string;};leg:string;homeTeam:{name:string;id:string;score?:number;htScore?:number;aggregateScore?:number;scorers?:string;};awayTeam:{name:string;id:string;score?:number;htScore?:number;aggregateScore?:number;scorers?:string;};status:string;venue?:{name:string;id:string;};comments?:string;attendance?:string;referee?:{name:string;id:string;};}"
+ "$ref": "#/definitions/{stage:{stageNumber:string;};id:string;type:\"LiveMatch\";status:string;date:string;round:{roundNumber:string;name?:string;};leg:string;homeTeam:{name:string;id:string;score?:number;htScore?:number;aggregateScore?:number;scorers?:string;};awayTeam:{name:string;id:string;score?:number;htScore?:number;aggregateScore?:number;scorers?:string;};venue?:{name:string;id:string;};comments?:string;attendance?:string;referee?:{name:string;id:string;};}"
},
{
"$ref": "#/definitions/{stage:{stageNumber:string;};id:string;type:\"Fixture\";date:string;round:{roundNumber:string;name?:string;};leg:string;homeTeam:{name:string;id:string;score?:number;htScore?:number;aggregateScore?:number;scorers?:string;};awayTeam:{name:string;id:string;score?:number;htScore?:number;aggregateScore?:number;scorers?:string;};venue?:{name:string;id:string;};comments?:string;competition?:{name:string;id:string;};}"
@@ -710,7 +710,7 @@
"Record": {
"type": "object"
},
- "{stage:{stageNumber:string;};id:string;type:\"LiveMatch\";date:string;round:{roundNumber:string;name?:string;};leg:string;homeTeam:{name:string;id:string;score?:number;htScore?:number;aggregateScore?:number;scorers?:string;};awayTeam:{name:string;id:string;score?:number;htScore?:number;aggregateScore?:number;scorers?:string;};status:string;venue?:{name:string;id:string;};comments?:string;attendance?:string;referee?:{name:string;id:string;};}": {
+ "{stage:{stageNumber:string;};id:string;type:\"LiveMatch\";status:string;date:string;round:{roundNumber:string;name?:string;};leg:string;homeTeam:{name:string;id:string;score?:number;htScore?:number;aggregateScore?:number;scorers?:string;};awayTeam:{name:string;id:string;score?:number;htScore?:number;aggregateScore?:number;scorers?:string;};venue?:{name:string;id:string;};comments?:string;attendance?:string;referee?:{name:string;id:string;};}": {
"type": "object",
"properties": {
"stage": {
@@ -723,6 +723,9 @@
"type": "string",
"const": "LiveMatch"
},
+ "status": {
+ "type": "string"
+ },
"date": {
"type": "string"
},
@@ -738,9 +741,6 @@
"awayTeam": {
"$ref": "#/definitions/{name:string;id:string;score?:number;htScore?:number;aggregateScore?:number;scorers?:string;}"
},
- "status": {
- "type": "string"
- },
"venue": {
"$ref": "#/definitions/{name:string;id:string;}"
},
diff --git a/dotcom-rendering/src/layouts/LiveLayout.tsx b/dotcom-rendering/src/layouts/LiveLayout.tsx
index aa236c351a2..bdcb67d4730 100644
--- a/dotcom-rendering/src/layouts/LiveLayout.tsx
+++ b/dotcom-rendering/src/layouts/LiveLayout.tsx
@@ -20,6 +20,7 @@ import { ArticleMeta } from '../components/ArticleMeta.web';
import { ArticleTitle } from '../components/ArticleTitle';
import { Carousel } from '../components/Carousel.island';
import { CricketMatchHeaderWrapper } from '../components/CricketMatchHeaderWrapper.island';
+import { CricketMiniMatchStatsWrapper } from '../components/CricketMiniMatchStatsWrapper.island';
import { DecideLines } from '../components/DecideLines';
import { DirectoryPageNavIsland } from '../components/DirectoryPageNavIsland';
import { DiscussionLayout } from '../components/DiscussionLayout';
@@ -270,6 +271,9 @@ export const LiveLayout = (props: WebProps | AppsProps) => {
} = article;
const ab = useAB();
+ const isCricketRedesignEnabled = Boolean(
+ ab?.isUserInTestGroup('webx-cricket-redesign', 'enable'),
+ );
// TODO:
// 1) Read 'forceEpic' value from URL parameter and use it to force the slot to render
@@ -298,6 +302,11 @@ export const LiveLayout = (props: WebProps | AppsProps) => {
const cricketMatchUrl =
article.matchType === 'CricketMatchType' ? article.matchUrl : undefined;
+ const cricketMatchStatsUrl =
+ article.matchType === 'CricketMatchType'
+ ? article.matchStatsUrl
+ : undefined;
+
const hasKeyEvents = !!article.keyEvents.length;
const renderAds = canRenderAds(article);
@@ -386,6 +395,7 @@ export const LiveLayout = (props: WebProps | AppsProps) => {
format={format}
article={article}
liveBlogAreaId={liveBlogAreaId}
+ isCricketRedesignEnabled={isCricketRedesignEnabled}
/>
{/* This element is used to replace the liveblog with the scorecard when the scorecard tab is clicked */}
@@ -589,10 +599,7 @@ export const LiveLayout = (props: WebProps | AppsProps) => {
{!!cricketMatchUrl &&
- !ab?.isUserInTestGroup(
- 'webx-cricket-redesign',
- 'enable',
- ) && (
+ !isCricketRedesignEnabled && (
{
)}
-
- {/* Match stats */}
- {!!footballMatchStatsUrl && (
-
-
-
- )}
+
{
);
};
+const MiniMatchStats = (props: {
+ footballMatchStatsUrl: string | undefined;
+ cricketMatchStatsUrl: string | undefined;
+ isCricketRedesignEnabled: boolean;
+}) => {
+ if (props.footballMatchStatsUrl) {
+ return (
+
+
+
+ );
+ }
+
+ if (props.cricketMatchStatsUrl && props.isCricketRedesignEnabled) {
+ return (
+
+
+
+ );
+ }
+
+ return null;
+};
+
const Header = (props: {
renderingTarget: RenderingTarget;
format: ArticleFormat;
article: ArticleDeprecated;
liveBlogAreaId: string;
+ isCricketRedesignEnabled: boolean;
}) => {
const footballMatchLeagueName = props.article.sectionLabel;
const footballMatchLeagueUrl = `${props.article.guardianBaseURL}/${props.article.sectionUrl}`;
@@ -1151,11 +1184,6 @@ const Header = (props: {
? props.article.matchHeaderUrl
: undefined;
- const ab = useAB();
- const isCricketRedesignEnabled = Boolean(
- ab?.isUserInTestGroup('webx-cricket-redesign', 'enable'),
- );
-
const isApps = props.renderingTarget === 'Apps';
if (footballMatchHeaderUrl) {
@@ -1183,7 +1211,7 @@ const Header = (props: {
);
}
- if (!isApps && cricketMatchHeaderUrl && isCricketRedesignEnabled) {
+ if (!isApps && cricketMatchHeaderUrl && props.isCricketRedesignEnabled) {
return (
<>