Skip to content

Commit 21a9353

Browse files
authored
Merge pull request #16279 from guardian/cricket-mini-match-stats
Cricket mini match stats
2 parents d9e3f24 + fd8381a commit 21a9353

10 files changed

Lines changed: 511 additions & 42 deletions
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
import { css } from '@emotion/react';
2+
import {
3+
from,
4+
space,
5+
textSans14,
6+
textSans15,
7+
textSansBold14,
8+
textSansBold15,
9+
visuallyHidden,
10+
} from '@guardian/source/foundations';
11+
import type { Batter } from '../cricketMatchV2';
12+
import { palette } from '../palette';
13+
14+
const containerCss = css`
15+
position: relative;
16+
padding: 5px 10px 10px;
17+
color: ${palette('--football-match-stat-text')};
18+
border: 1px solid ${palette('--football-match-stat-border')};
19+
border-radius: 6px;
20+
`;
21+
22+
const desktopPaddingCss = css`
23+
${from.desktop} {
24+
padding-bottom: 14px;
25+
}
26+
`;
27+
28+
const visuallyHiddenStyles = css`
29+
${visuallyHidden}
30+
`;
31+
32+
const responsiveTextSans = css`
33+
${textSans14}
34+
${from.desktop} {
35+
${textSans15}
36+
}
37+
`;
38+
39+
const responsiveTextSansBold = css`
40+
${textSansBold14}
41+
${from.desktop} {
42+
${textSansBold15}
43+
}
44+
`;
45+
46+
const tableStyles = css`
47+
width: 100%;
48+
border-collapse: collapse;
49+
${responsiveTextSans}
50+
`;
51+
52+
const cellBaseStyles = css`
53+
padding: ${space[2]}px ${space[3]}px ${space[1]}px 0;
54+
text-align: left;
55+
vertical-align: middle;
56+
`;
57+
58+
const tableHeadCellStyles = css`
59+
${cellBaseStyles}
60+
${responsiveTextSansBold}
61+
color: ${palette('--football-match-stat-text')};
62+
`;
63+
64+
const tableCellStyles = css`
65+
${cellBaseStyles}
66+
${responsiveTextSans}
67+
`;
68+
69+
const tableRowHeaderStyles = css`
70+
${cellBaseStyles}
71+
display: flex;
72+
align-items: center;
73+
${responsiveTextSans}
74+
`;
75+
76+
const batterNameTextStyles = css`
77+
display: flex;
78+
flex-direction: column;
79+
`;
80+
81+
const tableRowStyles = css`
82+
border-top: 1px solid ${palette('--football-match-stat-border')};
83+
`;
84+
85+
const numericCellStyles = css`
86+
white-space: nowrap;
87+
text-align: left;
88+
`;
89+
90+
const howOutStyles = css`
91+
color: ${palette('--football-match-info-team-number')};
92+
`;
93+
94+
export const CricketMatchStatNotOutBatters = ({
95+
notOutBatters,
96+
}: {
97+
notOutBatters: Batter[];
98+
}) => {
99+
const currentBatters = notOutBatters.filter(
100+
(batter) => batter.onStrike || batter.nonStrike,
101+
);
102+
return (
103+
<div css={[containerCss, desktopPaddingCss]}>
104+
<span css={visuallyHiddenStyles}>Current Batters</span>
105+
<table css={tableStyles}>
106+
<thead>
107+
<tr>
108+
<th css={tableHeadCellStyles}>Batter</th>
109+
<th css={[tableHeadCellStyles, numericCellStyles]}>
110+
Runs
111+
</th>
112+
<th css={[tableHeadCellStyles, numericCellStyles]}>
113+
Balls
114+
</th>
115+
</tr>
116+
</thead>
117+
<tbody>
118+
{currentBatters.map((batter) => {
119+
return (
120+
<tr key={batter.name} css={tableRowStyles}>
121+
<th scope="row" css={tableRowHeaderStyles}>
122+
<span css={visuallyHiddenStyles}>
123+
{batter.onStrike
124+
? '(on strike)'
125+
: '(at crease)'}
126+
</span>
127+
<div css={batterNameTextStyles}>
128+
{batter.name}
129+
<div css={[howOutStyles]}>
130+
{batter.howOut}
131+
</div>
132+
</div>
133+
</th>
134+
<td css={[tableCellStyles, numericCellStyles]}>
135+
{batter.runs}
136+
</td>
137+
<td css={[tableCellStyles, numericCellStyles]}>
138+
{batter.ballsFaced}
139+
</td>
140+
</tr>
141+
);
142+
})}
143+
</tbody>
144+
</table>
145+
</div>
146+
);
147+
};
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
import { css } from '@emotion/react';
2+
import { breakpoints, from } from '@guardian/source/foundations';
3+
import preview from '../../.storybook/preview';
4+
import type { FECricketMatchStatsSummary } from '../frontend/feCricketMatchPage';
5+
import { palette } from '../palette';
6+
import { CricketMiniMatchStats as CricketMiniMatchStatsComponent } from './CricketMiniMatchStats';
7+
8+
const gridCss = css`
9+
background-color: ${palette('--football-live-blog-background')};
10+
/**
11+
* Extremely simplified live blog grid layout as we're only interested in
12+
* the 240px wide left column added at the desktop breakpoint.
13+
* dotcom-rendering/src/layouts/LiveLayout.tsx
14+
*/
15+
${from.desktop} {
16+
display: grid;
17+
grid-column-gap: 20px;
18+
grid-template-columns: 240px 1fr;
19+
}
20+
`;
21+
22+
const meta = preview.meta({
23+
title: 'Components/Cricket Mini Match Stats',
24+
component: CricketMiniMatchStatsComponent,
25+
decorators: [
26+
(Story) => (
27+
<div css={gridCss}>
28+
<Story />
29+
</div>
30+
),
31+
],
32+
parameters: {
33+
chromatic: {
34+
viewports: [
35+
breakpoints.mobileMedium,
36+
breakpoints.tablet,
37+
breakpoints.wide,
38+
],
39+
},
40+
},
41+
});
42+
43+
const feMatchStatsSummaryData: FECricketMatchStatsSummary = {
44+
status: 'abandoned',
45+
currentBattingTeam: 'England',
46+
notOutBatters: [
47+
{
48+
name: 'Tom Latham',
49+
order: 1,
50+
ballsFaced: 214,
51+
runs: 151,
52+
fours: 15,
53+
sixes: 0,
54+
out: false,
55+
howOut: 'not out',
56+
onStrike: false,
57+
nonStrike: true,
58+
},
59+
{
60+
name: 'Devon Conway',
61+
order: 2,
62+
ballsFaced: 224,
63+
runs: 157,
64+
fours: 22,
65+
sixes: 3,
66+
out: false,
67+
howOut: 'not out',
68+
onStrike: true,
69+
nonStrike: false,
70+
},
71+
{
72+
name: 'Devon Conway',
73+
order: 2,
74+
ballsFaced: 224,
75+
runs: 157,
76+
fours: 22,
77+
sixes: 3,
78+
out: false,
79+
howOut: 'not out',
80+
onStrike: false,
81+
nonStrike: false,
82+
},
83+
],
84+
};
85+
86+
const getMockData = (data: FECricketMatchStatsSummary) =>
87+
new Promise((resolve) => {
88+
setTimeout(() => {
89+
resolve(data);
90+
}, 1000);
91+
});
92+
93+
export const CricketMiniMatchStats = meta.story({
94+
args: {
95+
matchStatsUrl:
96+
'https://api.nextgen.guardianapps.co.uk/sport/cricket/match-stats/2026-06-25/england-cricket-team.json',
97+
getMatchStatsData: () => getMockData(feMatchStatsSummaryData),
98+
refreshInterval: 16_000,
99+
},
100+
});

0 commit comments

Comments
 (0)