Skip to content

Commit

Permalink
Add alternative layout for frontPageHeroBlock
Browse files Browse the repository at this point in the history
  • Loading branch information
terotik committed Oct 5, 2023
1 parent 8a34218 commit aed4520
Show file tree
Hide file tree
Showing 5 changed files with 200 additions and 51 deletions.
6 changes: 6 additions & 0 deletions common/images.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ images.fragments = {
height
focalPointX
focalPointY
full: rendition(size: "1600x1600", crop: false) {
id
width
height
src
}
large: rendition(size: "1600x600") {
id
width
Expand Down
2 changes: 1 addition & 1 deletion components/common/StreamField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ function StreamFieldBlock(props: StreamFieldBlockProps) {
<FrontPageHeroBlock
id={id}
layout={layout}
imageSrc={image?.large?.src}
image={image}
imageAlign={getBgImageAlignment(image)}
heading={heading}
lead={lead}
Expand Down
50 changes: 0 additions & 50 deletions components/contentblocks/FrontPageHeroBlock.js

This file was deleted.

59 changes: 59 additions & 0 deletions components/contentblocks/FrontPageHeroBlock.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import React from 'react';
import HeroFullImage from 'components/home/HeroFullImage';
import HeroSmallImage from 'components/home/HeroSmallImage';

interface FrontPageHeroProps {
id: string;
layout: 'small_image' | 'big_image';
image: any;
imageAlign: string;
heading?: string;
lead: string;
altText: string;
imageCredit: string;
}

const FrontPageHeroBlock = (props: FrontPageHeroProps) => {
const {
id = '',
layout = 'big_image',
image,
imageAlign,
heading,
lead,
altText,
imageCredit,
} = props;

/*
FrontPageHeroBlock has two layout options: big_image (default) and small_image.
big_image: uses browser width background image cropped to max height with content overlay
small_image: uses text block width background image uncropped with content box below
*/

const imageSrc =
layout === 'small_image' ? image?.full?.src : image?.large?.src;

return layout === 'small_image' ? (
<HeroSmallImage
id={id}
bgImage={imageSrc}
title={heading}
lead={lead}
imageCredit={imageCredit}
altText={altText}
/>
) : (
<HeroFullImage
id={id}
bgImage={imageSrc}
imageAlign={imageAlign}
title={heading}
lead={lead}
imageCredit={imageCredit}
altText={altText}
/>
);
};

export default FrontPageHeroBlock;
134 changes: 134 additions & 0 deletions components/home/HeroSmallImage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import { useTheme } from 'common/theme';
import { Col, Container } from 'reactstrap';
import styled from 'styled-components';
import { useTranslation } from 'common/i18n';
import RichText from 'components/common/RichText';

const Hero = styled.div`
width: 100%;
position: relative;
margin-bottom: ${(props) => props.theme.spaces.s600};
`;

const HeroImage = styled.img`
position: relative;
width: 100%;
display: block;
`;

const TextWidthColumn = styled(Col)`
margin-top: -${(props) => props.theme.spaces.s300};
`;

const MainCard = styled.div`
position: relative;
padding: ${(props) =>
`${props.theme.spaces.s200} ${props.theme.spaces.s200} ${props.theme.spaces.s100}`};
border-radius: ${(props) => props.theme.cardBorderRadius};
background-color: ${(props) =>
props.color === 'dark'
? props.theme.brandDark
: props.theme.themeColors.white};
color: ${(props) =>
props.color === 'dark'
? props.theme.themeColors.white
: props.theme.neutralDark};
box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.1);
z-index: 100;
h1 {
font-size: ${(props) => props.theme.fontSizeLg};
margin-bottom: ${(props) => props.theme.spaces.s100};
}
h1,
h2,
h3,
h4 {
color: ${(props) =>
props.color === 'dark'
? props.theme.themeColors.white
: props.theme.headingsColor};
}
a {
color: ${(props) =>
props.color === 'dark'
? props.theme.themeColors.white
: props.theme.neutralDark};
&:hover {
text-decoration: none;
}
}
.lead-content {
font-size: ${(props) => props.theme.fontSizeBase};
line-height: ${(props) => props.theme.lineHeightMd};
font-family: ${(props) => props.theme.fontFamilyContent};
}
`;

const ImageCredit = styled.span`
position: absolute;
top: 0;
right: 0;
padding: 0.25rem 0.5rem;
background-color: rgba(255, 255, 255, 0.66);
font-size: ${(props) => props.theme.fontSizeSm};
font-family: ${(props) => props.theme.fontFamilyTiny};
@media (min-width: ${(props) => props.theme.breakpointMd}) {
top: inherit;
bottom: 0;
}
`;

interface HeroSmallImageProps {
id?: string;
bgImage: string;
title?: string;
lead?: string;
altText?: string;
imageCredit?: string;
}

const HeroSmallImage = (props: HeroSmallImageProps) => {
const { id = '', bgImage, title, lead, altText = '', imageCredit } = props;

const { t } = useTranslation();
const theme = useTheme();

const showContentBox = title || lead;

return (
<Container>
<Hero id={id}>
<HeroImage src={bgImage} alt={altText} />
{imageCredit && (
<ImageCredit>{`${t('image-credit')}: ${imageCredit}`}</ImageCredit>
)}
{showContentBox && (
<TextWidthColumn
xl={{ size: 6, offset: 3 }}
lg={{ size: 8, offset: 2 }}
md={{ size: 10, offset: 1 }}
>
<MainCard
color={
theme.settings?.frontHero
? theme.settings.frontHero?.color
: 'light'
}
>
<h1>{title}</h1>
{lead && <RichText html={lead} className="lead-content" />}
</MainCard>
</TextWidthColumn>
)}
</Hero>
</Container>
);
};

export default HeroSmallImage;

0 comments on commit aed4520

Please sign in to comment.