Skip to content

Commit 704347c

Browse files
domlanderabeddow91
andcommitted
Card gap sizing amendments in beta containers
Co-authored-by: Anna Beddow <[email protected]>
1 parent bc71031 commit 704347c

File tree

4 files changed

+150
-61
lines changed

4 files changed

+150
-61
lines changed

dotcom-rendering/src/components/Card/Card.tsx

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,7 @@ export const Card = ({
499499
<div
500500
css={css`
501501
margin-top: auto;
502+
display: flex;
502503
`}
503504
>
504505
{isVideoArticle && (
@@ -626,51 +627,61 @@ export const Card = ({
626627
}
627628
};
628629

629-
/** Determines the gap of between card components based on card properties */
630+
/**
631+
* Determines the gap of between card components based on card properties
632+
* Order matters here as the logic is based on the card properties
633+
*/
630634
const getGapSizes = (): GapSizes => {
631635
if (isOnwardContent) {
632636
return {
633637
row: 'none',
634638
column: 'none',
635639
};
636640
}
637-
if (isMediaCardOrNewsletter && !isFlexibleContainer) {
638-
return {
639-
row: 'tiny',
640-
column: 'tiny',
641-
};
642-
}
643-
if (!!isFlexSplash || (isFlexibleContainer && imageSize === 'jumbo')) {
641+
642+
if (isFlexSplash) {
644643
return {
645644
row: 'small',
646-
column: 'small',
645+
column: 'none',
647646
};
648647
}
648+
649+
if (!isBetaContainer) {
650+
/**
651+
* Media cards have 4px padding around the content so we have a
652+
* tiny (4px) gap to account for this and make it 8px total
653+
*/
654+
if (isMediaCardOrNewsletter) {
655+
return {
656+
row: 'tiny',
657+
column: 'tiny',
658+
};
659+
}
660+
661+
// Current cards have small padding for everything
662+
return { row: 'small', column: 'small' };
663+
}
664+
649665
if (isSmallCard) {
650666
return {
651667
row: 'medium',
652668
column: 'medium',
653669
};
654670
}
655-
if (isBetaContainer && media?.type === 'avatar') {
656-
return {
657-
row: 'small',
658-
column: 'small',
659-
};
660-
}
671+
661672
if (
662-
isFlexibleContainer &&
663-
(imagePositionOnDesktop === 'left' ||
664-
imagePositionOnDesktop === 'right')
673+
imagePositionOnDesktop === 'bottom' ||
674+
imagePositionOnMobile === 'bottom'
665675
) {
666676
return {
667-
row: 'large',
677+
row: 'tiny',
668678
column: 'large',
669679
};
670680
}
681+
671682
return {
672-
row: isBetaContainer ? 'tiny' : 'small',
673-
column: 'small',
683+
row: 'small',
684+
column: 'large',
674685
};
675686
};
676687

@@ -1050,13 +1061,20 @@ export const Card = ({
10501061
<ContentWrapper
10511062
imageType={media?.type}
10521063
imageSize={imageSize}
1064+
isBetaContainer={isBetaContainer}
1065+
isFlexibleContainer={isFlexibleContainer}
10531066
imagePositionOnDesktop={imagePositionOnDesktop}
1067+
imagePositionOnMobile={imagePositionOnMobile}
10541068
padContent={determinePadContent(
10551069
isMediaCardOrNewsletter,
10561070
isBetaContainer,
10571071
isOnwardContent,
10581072
)}
1059-
isFlexibleContainer={isFlexibleContainer}
1073+
padRight={
1074+
!!isFlexSplash &&
1075+
image &&
1076+
imagePositionOnDesktop === 'right'
1077+
}
10601078
>
10611079
{/* This div is needed to keep the headline and trail text justified at the start */}
10621080
<div

dotcom-rendering/src/components/Card/components/CardLayout.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ const decidePosition = (
156156
`;
157157
};
158158

159-
/** Detemines the gap size between components in card layout */
159+
/** Determines the gap size between components in card layout */
160160
const decideGap = (gapSize: GapSize) => {
161161
switch (gapSize) {
162162
case 'none':
@@ -172,6 +172,14 @@ const decideGap = (gapSize: GapSize) => {
172172
}
173173
};
174174

175+
const decideColumnGap = (gapSize: GapSize) => css`
176+
column-gap: ${gapSize === 'large' ? '10px' : decideGap(gapSize)};
177+
178+
${from.tablet} {
179+
column-gap: ${decideGap(gapSize)};
180+
}
181+
`;
182+
175183
export const CardLayout = ({
176184
children,
177185
cardBackgroundColour,
@@ -196,11 +204,11 @@ export const CardLayout = ({
196204
isBetaContainer,
197205
imageType === 'avatar',
198206
),
207+
decideColumnGap(gapSizes.column),
199208
]}
200209
style={{
201210
backgroundColor: cardBackgroundColour,
202211
rowGap: decideGap(gapSizes.row),
203-
columnGap: decideGap(gapSizes.column),
204212
}}
205213
>
206214
{children}

dotcom-rendering/src/components/Card/components/ContentWrapper.tsx

Lines changed: 69 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { SerializedStyles } from '@emotion/react';
22
import { css } from '@emotion/react';
3-
import { between, from, space } from '@guardian/source/foundations';
3+
import { between, from, space, until } from '@guardian/source/foundations';
44
import type { CardImageType } from '../../../types/layout';
55
import type { ImagePositionType, ImageSizeType } from './ImageWrapper';
66

@@ -14,7 +14,6 @@ const sizingStyles = css`
1414
/**
1515
* This function works in partnership with its sibling in `ImageWrapper`. If you
1616
* change any values here be sure to update that file as well.
17-
*
1817
*/
1918
const flexBasisStyles = ({
2019
imageSize,
@@ -61,67 +60,106 @@ const flexBasisStyles = ({
6160
}
6261
};
6362

64-
const paddingStyles = (
65-
imagePosition: ImagePositionType,
66-
isFlexibleContainer: boolean,
63+
type ImageDirection = 'vertical' | 'horizontal' | 'none';
64+
65+
const paddingBetaContainerStyles = (
66+
imageDirectionMobile: ImageDirection,
67+
imageDirectionDesktop: ImageDirection,
68+
imagePositionOnDesktop: ImagePositionType,
6769
paddingWidth: 1 | 2,
68-
) => {
69-
/**
70-
* If we're in a flexible container there is a 20px gap between the image
71-
* and content. We don't apply padding to the content on the same edge as
72-
* the image so the content is aligned with the grid.
73-
*/
74-
if (isFlexibleContainer && imagePosition === 'left') {
75-
return css`
76-
padding: ${space[paddingWidth]}px ${space[paddingWidth]}px
77-
${space[paddingWidth]}px 0;
78-
`;
70+
isFlexibleContainer: boolean,
71+
) => css`
72+
${until.tablet} {
73+
padding-left: ${imageDirectionMobile !== 'horizontal' &&
74+
`${space[paddingWidth]}px`};
75+
padding-right: ${imageDirectionMobile !== 'horizontal' &&
76+
`${space[paddingWidth]}px`};
77+
padding-top: ${imageDirectionMobile !== 'vertical' &&
78+
`${space[paddingWidth]}px`};
79+
padding-bottom: ${imageDirectionMobile !== 'vertical' &&
80+
`${space[paddingWidth]}px`};
81+
}
82+
${from.tablet} {
83+
padding-left: ${imageDirectionDesktop !== 'horizontal' &&
84+
`${space[paddingWidth]}px`};
85+
padding-right: ${imageDirectionDesktop !== 'horizontal' &&
86+
`${space[paddingWidth]}px`};
87+
padding-top: ${imageDirectionDesktop !== 'vertical' &&
88+
`${space[paddingWidth]}px`};
89+
padding-bottom: ${(imageDirectionDesktop !== 'vertical' ||
90+
(!isFlexibleContainer && imagePositionOnDesktop === 'top')) &&
91+
`${space[paddingWidth]}px`};
7992
}
93+
`;
8094

81-
if (isFlexibleContainer && imagePosition === 'right') {
82-
return css`
83-
padding: ${space[paddingWidth]}px 0 ${space[paddingWidth]}px
84-
${space[paddingWidth]}px;
85-
`;
95+
const padRightStyles = css`
96+
${from.tablet} {
97+
padding-right: ${space[5]}px;
98+
}
99+
`;
100+
101+
const getImageDirection = (
102+
imagePosition: ImagePositionType,
103+
): ImageDirection => {
104+
if (imagePosition === 'top' || imagePosition === 'bottom') {
105+
return 'vertical';
106+
}
107+
108+
if (imagePosition === 'left' || imagePosition === 'right') {
109+
return 'horizontal';
86110
}
87111

88-
return css`
89-
padding: ${space[paddingWidth]}px;
90-
`;
112+
return 'none';
91113
};
92114

93115
type Props = {
94116
children: React.ReactNode;
95117
imageType?: CardImageType;
96118
imageSize: ImageSizeType;
119+
isBetaContainer: boolean;
120+
isFlexibleContainer: boolean;
97121
imagePositionOnDesktop: ImagePositionType;
122+
imagePositionOnMobile: ImagePositionType;
98123
padContent?: 'small' | 'large';
99-
isFlexibleContainer?: boolean;
124+
padRight?: boolean;
100125
};
101126

102127
export const ContentWrapper = ({
103128
children,
104129
imageType,
105130
imageSize,
131+
isBetaContainer,
132+
isFlexibleContainer,
106133
imagePositionOnDesktop,
134+
imagePositionOnMobile,
107135
padContent,
108-
isFlexibleContainer = false,
136+
padRight = false,
109137
}: Props) => {
110-
const isHorizontalOnDesktop =
111-
imagePositionOnDesktop === 'left' || imagePositionOnDesktop === 'right';
138+
const imageDirectionDesktop = getImageDirection(imagePositionOnDesktop);
139+
const imageDirectionMobile = getImageDirection(imagePositionOnMobile);
140+
const paddingSpace = padContent === 'small' ? 1 : 2;
112141

113142
return (
114143
<div
115144
css={[
116145
sizingStyles,
117-
isHorizontalOnDesktop &&
146+
imageDirectionDesktop === 'horizontal' &&
118147
flexBasisStyles({ imageSize, imageType }),
119148
padContent &&
120-
paddingStyles(
149+
!isBetaContainer &&
150+
css`
151+
padding: ${space[paddingSpace]}px;
152+
`,
153+
padContent &&
154+
isBetaContainer &&
155+
paddingBetaContainerStyles(
156+
imageDirectionMobile,
157+
imageDirectionDesktop,
121158
imagePositionOnDesktop,
159+
paddingSpace,
122160
isFlexibleContainer,
123-
padContent === 'small' ? 1 : 2,
124161
),
162+
padRight && padRightStyles,
125163
]}
126164
>
127165
{children}

dotcom-rendering/src/components/Card/components/ImageWrapper.tsx

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,27 @@ const imageOverlayContainerStyles = css`
5252
height: 100%;
5353
`;
5454

55+
/**
56+
* There is no padding on the side of the image where the text is.
57+
*/
58+
const imagePaddingStyles = (
59+
imagePositionOnDesktop: ImagePositionType,
60+
imagePositionOnMobile: ImagePositionType,
61+
) => css`
62+
${until.tablet} {
63+
padding-left: ${imagePositionOnMobile !== 'right' && `${space[2]}px`};
64+
padding-right: ${imagePositionOnMobile !== 'left' && `${space[2]}px`};
65+
padding-top: ${imagePositionOnMobile !== 'bottom' && `${space[2]}px`};
66+
padding-bottom: ${imagePositionOnMobile !== 'top' && `${space[2]}px`};
67+
}
68+
${from.tablet} {
69+
padding-left: ${imagePositionOnDesktop !== 'right' && `${space[2]}px`};
70+
padding-right: ${imagePositionOnDesktop !== 'left' && `${space[2]}px`};
71+
padding-top: ${imagePositionOnDesktop !== 'bottom' && `${space[2]}px`};
72+
padding-bottom: ${imagePositionOnDesktop !== 'top' && `${space[2]}px`};
73+
}
74+
`;
75+
5576
/**
5677
* This function works in partnership with its sibling in `ContentWrapper`. If you
5778
* change any values here be sure to update that file as well.
@@ -122,10 +143,6 @@ const fixImageWidth = ({
122143
`}
123144
`;
124145

125-
const imagePadding = css`
126-
padding: ${space[2]}px;
127-
`;
128-
129146
export const ImageWrapper = ({
130147
children,
131148
imageSize,
@@ -179,7 +196,11 @@ export const ImageWrapper = ({
179196
display: block;
180197
}
181198
`,
182-
padImage && imagePadding,
199+
padImage &&
200+
imagePaddingStyles(
201+
imagePositionOnDesktop,
202+
imagePositionOnMobile,
203+
),
183204
]}
184205
>
185206
<>
@@ -190,7 +211,11 @@ export const ImageWrapper = ({
190211
<div
191212
css={[
192213
imageOverlayContainerStyles,
193-
padImage && imagePadding,
214+
padImage &&
215+
imagePaddingStyles(
216+
imagePositionOnDesktop,
217+
imagePositionOnMobile,
218+
),
194219
]}
195220
>
196221
{/* This child div is needed as the hover background colour covers the padded

0 commit comments

Comments
 (0)