diff --git a/web/pageComponents/topicPages/CookieDeclaration.tsx b/web/pageComponents/topicPages/CookieDeclaration.tsx
index 517cb937f..938e2455f 100644
--- a/web/pageComponents/topicPages/CookieDeclaration.tsx
+++ b/web/pageComponents/topicPages/CookieDeclaration.tsx
@@ -35,7 +35,7 @@ const CookieDeclaration = ({ data, anchor }: CookieDeclarationProps) => {
}
}, [language])
return (
-
+
{title && }
diff --git a/web/pageComponents/topicPages/Form/Form.tsx b/web/pageComponents/topicPages/Form/Form.tsx
index faffb2255..369e8d729 100644
--- a/web/pageComponents/topicPages/Form/Form.tsx
+++ b/web/pageComponents/topicPages/Form/Form.tsx
@@ -56,7 +56,7 @@ const Form = ({ data, anchor }: { data: FormData; anchor?: string }) => {
}
}
return (
-
+
{title && }
{ingress && }
diff --git a/web/pageComponents/topicPages/IFrame.tsx b/web/pageComponents/topicPages/IFrame.tsx
index cac567ba8..23b48be00 100644
--- a/web/pageComponents/topicPages/IFrame.tsx
+++ b/web/pageComponents/topicPages/IFrame.tsx
@@ -40,12 +40,9 @@ const IFrame = ({
}) => {
if (!url) return null
- const { height, aspectRatio, background, dark } = designOptions
- // After a while with TW, this isDark should be removed and only use dark from designOptions for dark
- const isDark = dark || background === 'Mid Blue' || background === 'Slate Blue'
-
+ const { height, aspectRatio, ...restOptions } = designOptions
return (
-
+
{title && }
{ingress && (
diff --git a/web/pageComponents/topicPages/KeyNumbers/KeyNumbers.tsx b/web/pageComponents/topicPages/KeyNumbers/KeyNumbers.tsx
index c41858993..cba74bf6b 100644
--- a/web/pageComponents/topicPages/KeyNumbers/KeyNumbers.tsx
+++ b/web/pageComponents/topicPages/KeyNumbers/KeyNumbers.tsx
@@ -55,9 +55,7 @@ type KeyNumbersProps = {
}
export default function ({ data, anchor }: KeyNumbersProps) {
const { title, items, designOptions, ingress, action, disclaimer, useHorizontalScroll } = data
- const { background, dark } = designOptions
- // After a while with TW, this isDark should be removed and only use dark from designOptions for dark below
- const isDark = dark || background === 'Mid Blue' || background === 'Slate Blue'
+
const isMobile = useMediaQuery(`(max-width: 800px)`)
const renderScroll = useHorizontalScroll && isMobile
@@ -69,7 +67,7 @@ export default function ({ data, anchor }: KeyNumbersProps) {
)
: Container
return (
-
+
{title && }
{ingress && (
diff --git a/web/pageComponents/topicPages/Promotion.tsx b/web/pageComponents/topicPages/Promotion.tsx
index 4e926eab9..1b512522a 100644
--- a/web/pageComponents/topicPages/Promotion.tsx
+++ b/web/pageComponents/topicPages/Promotion.tsx
@@ -28,15 +28,12 @@ const StyledHeading = styled(TitleText)`
const Promotion = ({ data, anchor, ...rest }: { data: PromotionData; anchor?: string }) => {
const { title, ingress, content, useHorizontalScroll, designOptions } = data
- // After a while with TW, this isDark should be removed and only use dark from designOptions for dark
- const isDark =
- designOptions?.dark || designOptions?.background === 'Mid Blue' || designOptions?.background === 'Slate Blue'
// const { articles = [], pages = [] } = data.promotion
const promotions = content?.promotions || []
const variant = data.content?.type
return (
-
+
{title && }
diff --git a/web/pageComponents/topicPages/Table.tsx b/web/pageComponents/topicPages/Table.tsx
index 0116d7fef..e42f19cf1 100644
--- a/web/pageComponents/topicPages/Table.tsx
+++ b/web/pageComponents/topicPages/Table.tsx
@@ -109,13 +109,10 @@ const renderCellByType = (cellData: CellData) => {
const Table = ({ data, anchor }: TableProps) => {
const { title, ingress, designOptions, tableHeaders = [], tableRows = [] } = data
- const { background, dark, theme } = designOptions
- // After a while with TW, this isDark should be removed and only use dark from designOptions for dark
- const isDark = dark || background === 'Mid Blue' || background === 'Slate Blue'
-
+ const { theme, ...restOptions } = designOptions
// Should the headers just be a plain text field?
return (
-
+
{title && }
{ingress && (
diff --git a/web/pageComponents/topicPages/TextBlock.tsx b/web/pageComponents/topicPages/TextBlock.tsx
index b78e42c21..8bb4157f7 100644
--- a/web/pageComponents/topicPages/TextBlock.tsx
+++ b/web/pageComponents/topicPages/TextBlock.tsx
@@ -6,6 +6,7 @@ import styled from 'styled-components'
import type { TextBlockData } from '../../types/types'
import CallToActions from './CallToActions'
import Blocks from '../../pageComponents/shared/portableText/Blocks'
+import { twMerge } from 'tailwind-merge'
export const StyledTextBlockWrapper = styled(BackgroundContainer)<{ id: string | undefined }>`
${({ id }) =>
@@ -14,13 +15,6 @@ export const StyledTextBlockWrapper = styled(BackgroundContainer)<{ id: string |
}}
`
-const StyledTextBlock = styled.section`
- padding: var(--space-3xLarge) var(--layout-paddingHorizontal-large);
- max-width: var(--maxViewportWidth);
- margin-left: auto;
- margin-right: auto;
-`
-
type TextBlockProps = {
data: TextBlockData
anchor?: string
@@ -41,13 +35,34 @@ const TextBlock = ({ data, anchor }: TextBlockProps) => {
} = data
/* Don't render the component if it only has an eyebrow */
if (!title && !ingress && !text && (!callToActions || callToActions.length === 0)) return null
- const { background, dark } = designOptions
- // After a while with TW, this isDark should be removed and only use dark from designOptions for dark
- const isDark = dark || background === 'Mid Blue' || background === 'Slate Blue'
+
+ const contentClassNames = `max-w-viewport py-14 px-layout-lg mx-auto`
+
+ const contentAlignment = {
+ center: 'items-start text-start px-layout-lg',
+ right:
+ 'items-start text-start px-layout-lg xl:items-end xl:text-end xl:max-w-[45dvw] xl:ml-auto xl:pr-layout-sm xl:pl-0 ',
+ left: 'items-start text-start px-layout-lg xl:items-start xl:max-w-[45dvw] xl:mr-auto xl:pl-layout-sm xl:pr-0',
+ }
+ let backgroundImageContentClassNames = `
+ justify-center
+ py-14
+ `
+ if (designOptions?.background?.backgroundImage?.contentAlignment) {
+ backgroundImageContentClassNames = twMerge(
+ backgroundImageContentClassNames,
+ `
+ ${contentAlignment[designOptions?.background?.backgroundImage?.contentAlignment]}`,
+ )
+ }
return (
-
-
+
+
{isBigText ? (
title &&
) : (
@@ -77,7 +92,7 @@ const TextBlock = ({ data, anchor }: TextBlockProps) => {
splitList={splitList}
/>
)}
-
+
)
}
diff --git a/web/pageComponents/topicPages/TextWithIconArray.tsx b/web/pageComponents/topicPages/TextWithIconArray.tsx
index fc50e3c60..8a6c35074 100644
--- a/web/pageComponents/topicPages/TextWithIconArray.tsx
+++ b/web/pageComponents/topicPages/TextWithIconArray.tsx
@@ -40,14 +40,11 @@ const getImgSrc = (img: ImageWithAlt): string => urlFor(img).size(150, 150).auto
const TextWithIconArray = ({ data, anchor }: TextWithIconArrayProps) => {
const { designOptions, group } = data
- const { background, dark } = designOptions
- // After a while with TW, this isDark should be removed and only use dark from designOptions for dark
- const isDark = dark || background === 'Mid Blue' || background === 'Slate Blue'
if (!group) return null
return (
-
+
{group.map((item: TextWithIconItem) => {
const { icon, title, text, id } = item
diff --git a/web/pageComponents/topicPages/TwitterEmbed.tsx b/web/pageComponents/topicPages/TwitterEmbed.tsx
index 9eaf37c3f..d705c9454 100644
--- a/web/pageComponents/topicPages/TwitterEmbed.tsx
+++ b/web/pageComponents/topicPages/TwitterEmbed.tsx
@@ -24,9 +24,7 @@ const StyledTitle = styled(TitleText)`
const TwitterEmbed = ({ data, anchor }: TwitterEmbedProps) => {
const { embedType, embedValue, designOptions, title, ingress } = data
- const { background, dark } = designOptions
- // After a while with TW, this isDark should be removed and only use dark from designOptions for dark
- const isDark = dark || background === 'Mid Blue' || background === 'Slate Blue'
+
const Embed = () => {
switch (embedType) {
case 'timeline':
@@ -48,7 +46,7 @@ const TwitterEmbed = ({ data, anchor }: TwitterEmbedProps) => {
}
return (
<>
-
+
{title && }
{ingress && (
diff --git a/web/pages/search/index.global.tsx b/web/pages/search/index.global.tsx
index 2443c410a..03406b1e7 100644
--- a/web/pages/search/index.global.tsx
+++ b/web/pages/search/index.global.tsx
@@ -44,7 +44,7 @@ export default function SearchPage() {
<>
-
+
(function CardsList(
ref,
) {
const { title, cards = [], designOptions } = data
- const { utility, dark } = designOptions
+ const { background } = designOptions || {}
+ const { backgroundUtility, dark } = background || {}
// For 2 or 4 cards
let gridColumns = 'grid-cols-1 lg:grid-cols-2'
@@ -24,7 +25,7 @@ const CardsList = forwardRef(function CardsList(
// 2 in width for mobile, but 3 for wider screens
gridColumns = 'grid-cols-1 lg:grid-cols-3'
}
- const cardBackground = colorKeyToUtilityMap[utility] ?? 'bg-blue-50'
+ const cardBackground = backgroundUtility ? colorKeyToUtilityMap[backgroundUtility] : { background: 'bg-blue-50' }
return (
(function CardsList(
)
})}
diff --git a/web/styles/tailwind.css b/web/styles/tailwind.css
index 84a2e69e0..312c70c44 100644
--- a/web/styles/tailwind.css
+++ b/web/styles/tailwind.css
@@ -6,42 +6,42 @@
}
@layer utilities {
- .block-wrapper {
- @apply grid;
- grid-template-areas: 'col-1 col-2 col-3';
- grid-template-columns: 4.2vw min(65ch, 100%) 4.2vw;
- }
- .block-wrapper > * {
- grid-area: col-2;
+ /* Scroll-Timeline Supported, Yay! */
+ @supports (animation-timeline: view()) {
+ .animate-timeline {
+ @apply animate-fadeInOut;
+ animation-timeline: view();
+ animation-range: cover 18% cover 85%;
+ }
}
- @media (min-width: 750px) {
- .block-wrapper {
- @apply grid w-screen;
- grid-template-areas: 'col-1 col-2 col-3 col-4 col-5';
- grid-template-columns:
- 1fr
- 6.87vw
- minmax(65ch, 920px)
- 6.87vw
- 1fr;
- }
- .pre-indent {
- @apply w-full;
- grid-column: 2 / 3;
- }
- .post-indent {
- @apply w-full;
- grid-column: 3 / 4;
- }
- .block-wrapper > * {
- @apply w-full;
- grid-area: col-3;
- }
+ .white-right-gradient {
+ background-image: linear-gradient(
+ to right,
+ rgba(255, 255, 255, 0.1),
+ rgba(255, 255, 255, 0.3) 30%,
+ rgba(255, 255, 255, 0.4) 100%
+ );
+ }
+ .white-left-gradient {
+ background-image: linear-gradient(
+ to left,
+ rgba(255, 255, 255, 0.1),
+ rgba(255, 255, 255, 0.3) 30%,
+ rgba(255, 255, 255, 0.4) 100%
+ );
+ }
+ .white-center-gradient {
+ background-image: linear-gradient(rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0.4));
}
- .full-bleed {
- @apply w-full;
- grid-column: 1 / -1;
+ .black-right-gradient {
+ background-image: linear-gradient(to right, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.3) 30%, rgba(0, 0, 0, 0.4) 100%);
+ }
+ .black-left-gradient {
+ background-image: linear-gradient(to left, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.3) 30%, rgba(0, 0, 0, 0.4) 100%);
+ }
+ .black-center-gradient {
+ background-image: linear-gradient(rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.4));
}
}
diff --git a/web/tailwind.config.cjs b/web/tailwind.config.cjs
index f4db2d4a0..b4c726b7b 100644
--- a/web/tailwind.config.cjs
+++ b/web/tailwind.config.cjs
@@ -205,6 +205,34 @@ module.exports = {
'layout-md': 'clamp(16px, calc(-69.4369px + 22.7832vw), 368px)',
'layout-lg': 'clamp(16px, calc(-101.4757px + 31.3269vw), 500px)',
},
+ margin: {
+ 'layout-sm': 'clamp(16px, calc(-38.3689px + 14.4984vw), 250px)',
+ 'layout-md': 'clamp(16px, calc(-69.4369px + 22.7832vw), 368px)',
+ 'layout-lg': 'clamp(16px, calc(-101.4757px + 31.3269vw), 500px)',
+ },
+ keyframes: {
+ reveal: {
+ '0%': { opacity: '0' },
+ '100%': { opacity: '1' },
+ },
+ fadeOut: {
+ '0%': { opacity: '1' },
+ '100%': { opacity: '0' },
+ },
+ zoomIn: {
+ '0%': { transform: 'scale(0)' },
+ '100%': { transform: 'scale(0.2)' },
+ },
+ fade: {
+ '0%, 100%': { opacity: '0' },
+ '20%, 80%': { opacity: '1' },
+ },
+ },
+ animation: {
+ fadeInOut: 'fade linear both',
+ fadeOut: 'auto linear fadeOut both',
+ zoomIn: 'auto linear zoom-in both',
+ },
typography: (theme) => ({
DEFAULT: {
css: [
diff --git a/web/tsconfig.json b/web/tsconfig.json
index 8543a1b8e..7b13e635c 100644
--- a/web/tsconfig.json
+++ b/web/tsconfig.json
@@ -2,22 +2,54 @@
"extends": "../tsconfig.base.json",
"compilerOptions": {
"target": "ES2019",
- "lib": ["dom", "dom.iterable", "ES2019", "es2021"],
+ "lib": [
+ "dom",
+ "dom.iterable",
+ "ES2019",
+ "es2021"
+ ],
"strict": true,
"forceConsistentCasingInFileNames": true,
"isolatedModules": true,
"jsx": "preserve",
"baseUrl": ".",
"paths": {
- "@components/*": ["components/src/*"],
- "@utils/*": ["components/utils/*"],
- "@mockdata/*": ["components/stories/mockdata/*"],
- "@components": ["components/src"],
- "@utils": ["components/utils"],
- "@mockdata": ["components/stories/mockdata"]
+ "@components/*": [
+ "components/src/*"
+ ],
+ "@utils/*": [
+ "components/utils/*"
+ ],
+ "@mockdata/*": [
+ "components/stories/mockdata/*"
+ ],
+ "@components": [
+ "components/src"
+ ],
+ "@utils": [
+ "components/utils"
+ ],
+ "@mockdata": [
+ "components/stories/mockdata"
+ ]
},
- "incremental": true
+ "incremental": true,
+ "plugins": [
+ {
+ "name": "next"
+ }
+ ]
},
- "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "jest-setup.ts"],
- "exclude": ["node_modules", "**/*.stories.*", "pages-disabled/*.tsx"]
+ "include": [
+ "next-env.d.ts",
+ "**/*.ts",
+ "**/*.tsx",
+ "jest-setup.ts",
+ ".next/types/**/*.ts"
+ ],
+ "exclude": [
+ "node_modules",
+ "**/*.stories.*",
+ "pages-disabled/*.tsx"
+ ]
}
diff --git a/web/types/types.ts b/web/types/types.ts
index bd69a87ad..b11fb95c7 100644
--- a/web/types/types.ts
+++ b/web/types/types.ts
@@ -6,7 +6,7 @@ import {
SanityImageObject,
SanityImageSource,
} from '@sanity/image-url/lib/types/types'
-import { colorKeyToUtilityMap } from '../styles/colorKeyToUtilityMap'
+import { ColorKeyTokens } from '../styles/colorKeyToUtilityMap'
export type CaptionData = {
attribution?: string
@@ -252,6 +252,14 @@ export type LandingPageSchema = {
template: Templates
seoAndSome: SeoData
}
+export type ContentAlignmentTypes = 'left' | 'right' | 'center'
+
+export type ImageBackground = {
+ image: ImageWithAlt | SanityImageObject
+ useAnimation?: boolean
+ useLight?: boolean
+ contentAlignment: ContentAlignmentTypes
+}
export type BackgroundColours =
| 'White'
@@ -266,10 +274,16 @@ export type BackgroundColours =
| 'Mid Orange'
| 'Slate Blue 95'
+export type BackgroundTypes = 'backgroundColor' | 'backgroundImage'
+
export type DesignOptions = {
- background?: BackgroundColours
- utility: keyof typeof colorKeyToUtilityMap
- dark: boolean
+ background?: {
+ type?: BackgroundTypes
+ backgroundColor?: BackgroundColours
+ backgroundImage?: ImageBackground
+ backgroundUtility?: keyof ColorKeyTokens
+ dark: boolean
+ }
imagePosition?: TeaserImagePosition
imageSize?: TeaserImageSize
}
@@ -306,7 +320,10 @@ export type TeaserData = {
isBigText?: boolean
image: ImageWithAlt
action?: LinkData
- designOptions: DesignOptions
+ designOptions: DesignOptions & {
+ imagePosition?: TeaserImagePosition
+ imageSize?: TeaserImageSize
+ }
}
export type TextTeaserData = {
@@ -355,7 +372,7 @@ export type FullWidthImageData = {
type: string
id: string
image: ImageWithCaptionData
- designOptions: {
+ designOptions: DesignOptions & {
aspectRatio: number
}
}
@@ -371,11 +388,8 @@ export type FullWidthVideoData = {
spacing?: boolean
title?: PortableTextBlock[]
action?: LinkData
- designOptions: {
+ designOptions: DesignOptions & {
aspectRatio: FullWidthVideoRatio
- background: BackgroundColours
- utility: keyof typeof colorKeyToUtilityMap
- dark: boolean
}
}
@@ -409,7 +423,7 @@ export type QuoteData = {
authorTitle?: string
quote: string
image?: ImageWithAlt
- designOptions: DesignOptions
+ designOptions: DesignOptions & { imagePosition?: TeaserImagePosition }
}
export type AccordionListData = {
@@ -516,12 +530,9 @@ export type IFrameData = {
frameTitle: string
url: string
cookiePolicy: CookiePolicy
- designOptions: {
+ designOptions: DesignOptions & {
aspectRatio: string
height?: number
- background: BackgroundColours
- utility: keyof typeof colorKeyToUtilityMap
- dark: boolean
}
}
@@ -704,10 +715,7 @@ export type VideoControlsType = {
export type VideoDesignOptionsType = {
aspectRatio: VideoPlayerRatios
- background: BackgroundColours
height?: number
- utility: keyof typeof colorKeyToUtilityMap
- dark: boolean
}
export type VideoPlayerData = {
@@ -715,7 +723,7 @@ export type VideoPlayerData = {
type: string
video: VideoType
videoControls: VideoControlsType
- designOptions: VideoDesignOptionsType
+ designOptions: DesignOptions & VideoDesignOptionsType
title?: PortableTextBlock[]
ingress?: PortableTextBlock[]
action?: LinkData
@@ -733,11 +741,8 @@ export type VideoPlayerCarouselData = {
thumbnail: ImageWithAlt
}
}[]
- designOptions: {
+ designOptions: DesignOptions & {
aspectRatio: VideoPlayerRatios
- background: BackgroundColours
- utility: keyof typeof colorKeyToUtilityMap
- dark: boolean
}
title?: PortableTextBlock[]
}