(function G
grid-rows-2
lg:grid-rows-[250px_1fr]
${String(rowType) === 'span3' ? 'lg:grid-cols-[40%_60%] lg:grid-rows-1' : ''}
- ${theme !== null ? backgroundUtility : ''}
+ ${bgColor}
`)}
>
{image && (
@@ -41,22 +75,35 @@ export const GridTeaser = forwardRef(function G
alt={altTag}
style={{ objectFit: 'cover' }}
fill
+ sizes="(max-width: 800px) 100vw, 800px"
role={image?.isDecorative ? 'presentation' : undefined}
/>
)}
-
-
- {content && (
+
+
+ {(content || (useExtendedThemes && themedContent)) && (
{
+ if (isEmpty(children)) return null
+ return (
+
+ <>{children}>
+
+ )
+ },
+ } as Partial,
+ })}
/>
)}
{quote && (
@@ -84,7 +131,7 @@ export const GridTeaser = forwardRef(function G
)}
- {action &&
}
+ {action &&
}
)
diff --git a/web/sections/Grid/GridTextBlock.tsx b/web/sections/Grid/GridTextBlock.tsx
index f237fee4a..99f389465 100644
--- a/web/sections/Grid/GridTextBlock.tsx
+++ b/web/sections/Grid/GridTextBlock.tsx
@@ -2,43 +2,240 @@ import { twMerge } from 'tailwind-merge'
import { getUrlFromAction } from '../../common/helpers'
import GridLinkArrow from './GridLinkArrow'
import { getColorForTheme } from '../../pageComponents/shared/textTeaser/theme'
-import { GridTextBlockData } from '../../types/types'
+import { BackgroundTypes, GridTextBlockData } from '../../types/types'
import Blocks from '../../pageComponents/shared/portableText/Blocks'
+import { BackgroundContainer } from '@components/Backgrounds'
+import { Heading, Typography } from '@core/Typography'
+import { RowType } from './mapGridContent'
+import envisTwMerge from '../../twMerge'
type GridTextBlockProps = {
data: GridTextBlockData
+ rowType?: RowType
className?: string
}
-const GridTextBlock = ({ data, className }: GridTextBlockProps) => {
- const { action, content, textAlignment = 'left', theme } = data
+const GridTextBlock = ({ data, className, rowType }: GridTextBlockProps) => {
+ const {
+ action,
+ overline,
+ title,
+ content,
+ useThemedTitle,
+ themedTitle,
+ titleThemeFromLarger,
+ contentTheme,
+ theme,
+ contentAlignment,
+ imageBackground,
+ } = data
const url = action && getUrlFromAction(action)
- const contentAlignment = {
- center: 'justify-center text-center',
- right: 'justify-center text-start xl:items-end xl:text-end xl:ml-auto',
- left: 'justify-center text-start xl:items-start xl:mr-auto',
+ const contentAlignmentUtilities = {
+ center: 'justify-center items-center',
+ right: 'justify-end items-center',
+ left: 'justify-start items-center',
+ 'bottom-left': 'justify-start items-end',
+ 'bottom-center': 'justify-center items-end',
+ }
+ const textContentAlignmentUtilities = {
+ center: 'text-center',
+ right: 'text-end',
+ left: 'text-start',
+ 'bottom-left': 'text-start',
+ 'bottom-center': 'text-center',
+ }
+
+ const textClassNames = twMerge(`${(title || themedTitle) && content ? 'text-sm' : 'text-md'}`, className)
+
+ let titleTextColor = 'text-slate-80'
+ let contentTextColor = 'text-slate-80'
+ let bgColor = 'bg-white-100'
+
+ if (useThemedTitle) {
+ const {
+ backgroundUtility: titleBgUtility,
+ textUtility: titleTextUtility,
+ dark,
+ } = getColorForTheme(titleThemeFromLarger)
+ if (titleTextUtility) {
+ titleTextColor = titleTextUtility
+ }
+ const { textUtility: contentTextUtility, backgroundUtility: contentBgUtility } = getColorForTheme(contentTheme)
+ if (contentBgUtility === titleBgUtility && contentTextUtility) {
+ contentTextColor = contentTextUtility
+ }
+ if (contentBgUtility !== titleBgUtility) {
+ contentTextColor = dark ? 'text-white-100' : 'text-slate-80'
+ }
+ bgColor = titleBgUtility ?? contentBgUtility ?? 'bg-white-100'
+ }
+ if (!useThemedTitle && theme) {
+ const { backgroundUtility: commonBgUtility, textUtility: commonTextUtility } = getColorForTheme(theme)
+ if (commonTextUtility) {
+ titleTextColor = commonTextUtility
+ contentTextColor = commonTextUtility
+ }
+ if (commonBgUtility) {
+ bgColor = commonBgUtility
+ }
}
- const contentClassNames = twMerge(`${contentAlignment[textAlignment]}`, className)
- const { backgroundUtility, textUtility } = getColorForTheme(theme ?? 0)
+ const imageBgOptions = {
+ background: {
+ type: 'backgroundImage' as BackgroundTypes,
+ backgroundImage: imageBackground,
+ dark:
+ (((useThemedTitle && titleThemeFromLarger) || contentTheme) ?? theme) === 12 && !imageBackground?.useLight
+ ? true
+ : false,
+ },
+ }
+
+ if (imageBackground?.image) {
+ titleTextColor = 'text-white-100'
+ if (imageBackground?.useLight) {
+ titleTextColor = 'text-slate-80'
+ }
+ }
+
+ if (imageBackground?.image) {
+ bgColor = 'bg-slate-80'
+ contentTextColor = 'text-white-100'
+ if (imageBackground?.useLight) {
+ contentTextColor = 'text-slate-80'
+ bgColor = 'bg-white-100'
+ }
+ }
- return (
+ const lightGradientForContentAlignment = {
+ center: '',
+ right: '',
+ left: '',
+ 'bottom-left':
+ rowType === 'span3' ? 'white-to-top-tall-gradient lg:white-to-top-gradient' : 'white-to-top-tall-gradient',
+ 'bottom-center':
+ rowType === 'span3' ? 'white-to-top-tall-gradient lg:white-to-top-gradient' : 'white-to-top-tall-gradient',
+ }
+ const darkGradientForContentAlignment = {
+ center: '',
+ right: '',
+ left: '',
+ 'bottom-left':
+ rowType === 'span3' ? 'black-to-top-tall-gradient lg:black-to-top-gradient' : 'black-to-top-tall-gradient',
+ 'bottom-center':
+ rowType === 'span3' ? 'black-to-top-tall-gradient lg:black-to-top-gradient' : 'black-to-top-tall-gradient',
+ }
+
+ const getLayout = () => {
+ switch (rowType) {
+ case 'span3':
+ return 'lg:grid lg:grid-cols-[35%_60%] gap-10'
+ case 'span2and1':
+ return '4xl:grid 4xl:grid-cols-[35%_60%] gap-10'
+ case 'threeColumns':
+ default:
+ return ''
+ }
+ }
+
+ const serializerClassnames = {
+ largeText: `leading-tight text-balance ${titleTextColor}`,
+ normal: `text-lg leading-snug text-balance ${titleTextColor}`,
+ }
+
+ const mainContent = (
+ <>
+
+ {overline ? (
+
+
+ {overline}
+
+ {(title || (useThemedTitle && themedTitle)) && (
+
+ )}
+
+ ) : (
+ <>
+ {(title || (useThemedTitle && themedTitle)) && (
+
+ )}
+ >
+ )}
+ {content && (
+
+
+
+ )}
+
+ {action && url &&
}
+ >
+ )
+
+ return imageBackground?.image ? (
+
+ {mainContent}
+
+ ) : (
- {content && (
-
-
-
- )}
- {action && url &&
}
+ {mainContent}
)
}
diff --git a/web/sections/Grid/mapGridContent.tsx b/web/sections/Grid/mapGridContent.tsx
index 9c994cde9..a5523473c 100644
--- a/web/sections/Grid/mapGridContent.tsx
+++ b/web/sections/Grid/mapGridContent.tsx
@@ -11,7 +11,7 @@ export type RowType = 'span3' | 'span2and1' | 'threeColumns' | undefined
export const mapGridContent = (data: ComponentProps, rowType?: RowType, isMobile?: boolean): React.ReactNode => {
switch (data.type) {
case 'gridTextBlock':
- return
+ return
case 'gridTeaser':
return
case 'figure':
diff --git a/web/styles/tailwind.css b/web/styles/tailwind.css
index c2c362229..bca17a1b3 100644
--- a/web/styles/tailwind.css
+++ b/web/styles/tailwind.css
@@ -98,6 +98,28 @@
rgba(255, 255, 255, 0.4) 100%
);
}
+ .white-to-top-gradient {
+ background-image: linear-gradient(
+ to top,
+ rgba(255, 255, 255, 0.7),
+ rgba(255, 255, 255, 0.3) 30%,
+ rgba(255, 255, 255, 0) 100%
+ );
+ }
+ /* rgba(255, 255, 255, 0.7),
+ rgba(255, 255, 255, 0.6) 30%,
+ rgba(255, 255, 255, 0.4) 50%,
+ rgba(255, 255, 255, 0.3) 60%,
+ rgba(255, 255, 255, 0) 100% */
+ .white-to-top-tall-gradient {
+ background-image: linear-gradient(
+ to top,
+ rgba(255, 255, 255, 0.6),
+ rgba(255, 255, 255, 0.5) 30%,
+ rgba(255, 255, 255, 0.35) 60%,
+ rgba(255, 255, 255, 0) 100%
+ );
+ }
.white-center-gradient {
background-image: linear-gradient(rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0.4));
}
@@ -111,6 +133,26 @@
.black-center-gradient {
background-image: linear-gradient(rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.4));
}
+ .black-to-top-gradient {
+ background-image: linear-gradient(
+ to top,
+ rgba(0, 0, 0, 0.7),
+ rgba(0, 0, 0, 0.6) 20%,
+ rgba(0, 0, 0, 0.45) 32%,
+ rgba(0, 0, 0, 0.1) 60%,
+ rgba(0, 0, 0, 0) 100%
+ );
+ }
+ /* rgba(0, 0, 0, 0.7),
+ rgba(0, 0, 0, 0.6) 30%,
+ rgba(0, 0, 0, 0.4) 50%,
+ rgba(0, 0, 0, 0.3) 60%,
+ rgba(0, 0, 0, 0) 100% */
+ .black-to-top-tall-gradient {
+ background-image: linear-gradient(to top, rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0.3) 40%, rgba(0, 0, 0, 0) 100%),
+ linear-gradient(26deg, rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0.45) 35%, rgba(0, 0, 0, 0) 100%);
+ }
+
.box-shadow-crisp {
box-shadow: 0.3px 0.5px 0.7px hsl(var(--tw-shadow-color) / 0.34),
0.4px 0.8px 1px -1.2px hsl(var(--tw-shadow-color) / 0.34), 1px 2px 2.5px -2.5px hsl(var(--tw-shadow-color) / 0.34);
diff --git a/web/tailwind.config.cjs b/web/tailwind.config.cjs
index 194353cd5..835bb2187 100644
--- a/web/tailwind.config.cjs
+++ b/web/tailwind.config.cjs
@@ -33,6 +33,7 @@ module.exports = {
extend: {
screens: {
'3xl': '1600px',
+ '4xl': '1920px',
},
colors: ({ theme }) => ({
current: 'currentColor',
@@ -260,6 +261,8 @@ module.exports = {
},
maxWidth: {
viewport: '1920px',
+ //When large font, prose(65ch) might not be the best
+ text: '760px',
},
minWidth: {
viewport: '375',
@@ -419,7 +422,7 @@ module.exports = {
css: {
color: theme('colors.current'),
p: {
- fontSize: theme('fontSize.md'),
+ textWrap: 'balance',
marginTop: '0',
marginBottom: '0',
},
diff --git a/web/twMerge/index.ts b/web/twMerge/index.ts
index 2aa801292..fed643fc1 100644
--- a/web/twMerge/index.ts
+++ b/web/twMerge/index.ts
@@ -11,6 +11,7 @@ const envisTwMerge = extendTailwindMerge({
maxWidth: ['viewport'],
minWidth: ['viewport'],
size: ['arrow-right'],
+ lineHeight: ['text', 'earthy', 'misty', 'cloudy', 'planetary', 'inherit'],
},
},
})
diff --git a/web/types/types.ts b/web/types/types.ts
index 56751dff8..4dd7a8540 100644
--- a/web/types/types.ts
+++ b/web/types/types.ts
@@ -865,14 +865,22 @@ export type ThreeColumns = {
id: string
columns?: GridContentType[]
}
+type GridTextBlockContentAlignment = 'left' | 'right' | 'center' | 'bottom-left' | 'bottom-center'
export type GridTextBlockData = {
id: string
type: 'gridTextBlock'
action?: LinkData
+ overline?: string
+ useThemedTitle?: boolean
+ title?: PortableTextBlock[]
+ themedTitle?: PortableTextBlock[]
content?: PortableTextBlock[]
- textAlignment?: ContentAlignmentTypes
- theme?: number
+ contentAlignment?: GridTextBlockContentAlignment
+ contentTheme?: any
+ titleThemeFromLarger?: any
+ theme?: any
+ imageBackground?: ImageBackground
}
export type CampaignBannerData = {
@@ -886,7 +894,10 @@ export type GridTeaserData = {
id: string
image: ImageWithAlt
rowType?: RowType
- content?: PortableTextBlock
+ useExtendedThemes?: boolean
+ content?: PortableTextBlock[]
+ themedContent?: PortableTextBlock[]
+ themeFromLarger?: any
quote?: string
author?: string
authorTitle?: string