diff --git a/sanityv3/schemas/editors/blockContentType.tsx b/sanityv3/schemas/editors/blockContentType.tsx index fc433614a..377a7e20a 100644 --- a/sanityv3/schemas/editors/blockContentType.tsx +++ b/sanityv3/schemas/editors/blockContentType.tsx @@ -17,6 +17,11 @@ export type BlockContentProps = { attachment?: boolean lists?: boolean smallText?: boolean + normalTextOverride?: { + title: string + value: 'normal' + component?: ({ children }: { children: React.ReactNode }) => JSX.Element + } } const SmallTextRender = (props: any) => { const { children } = props @@ -34,11 +39,12 @@ export const configureBlockContent = (options: BlockContentProps = {}): BlockFie attachment = false, lists = true, smallText = true, + normalTextOverride = { title: 'Normal', value: 'normal' }, } = options const config: BlockFieldType = { type: 'block', - styles: [{ title: 'Normal', value: 'normal' }], + styles: [normalTextOverride], lists: lists ? [ { title: 'Numbered', value: 'number' }, diff --git a/sanityv3/schemas/objects/teaser.tsx b/sanityv3/schemas/objects/teaser.tsx index fbf94ff99..fac1f71d5 100644 --- a/sanityv3/schemas/objects/teaser.tsx +++ b/sanityv3/schemas/objects/teaser.tsx @@ -6,7 +6,7 @@ import CompactBlockEditor from '../components/CompactBlockEditor' import { configureBlockContent, configureTitleBlockContent } from '../editors' import { validateCharCounterEditor } from '../validations/validateCharCounterEditor' -import type { PortableTextBlock, Reference, Rule } from 'sanity' +import type { PortableTextBlock, Reference, Rule, ValidationContext } from 'sanity' import type { DownloadableImage } from './downloadableImage' import type { DownloadableFile } from './files' import type { ImageWithAlt } from './imageWithAlt' @@ -25,7 +25,7 @@ const imageAlignmentOptions = [ { value: 'right', icon: RightAlignedImage }, ] -const blockContentType = configureBlockContent({ +const blockConfig = { h1: false, h2: false, h3: false, @@ -34,6 +34,18 @@ const blockContentType = configureBlockContent({ externalLink: false, attachment: false, lists: false, +} + +const blockContentType = configureBlockContent({ ...blockConfig }) + +const blockContentTypeForBigText = configureBlockContent({ + ...blockConfig, + smallText: false, + normalTextOverride: { + title: 'Normal', + value: 'normal', + component: ({ children }: { children: React.ReactNode }) => {children}, + }, }) export type Teaser = { @@ -41,6 +53,8 @@ export type Teaser = { overline?: string title?: PortableTextBlock[] text?: PortableTextBlock[] + isBigText?: boolean + bigText?: PortableTextBlock[] action?: (LinkSelector | DownloadableFile | DownloadableImage)[] image: ImageWithAlt imagePosition?: string @@ -48,6 +62,10 @@ export type Teaser = { background?: ColorSelectorValue } +type TeaserDocument = { + parent: Teaser +} + export default { name: 'teaser', title: 'Teaser', @@ -62,6 +80,7 @@ export default { collapsible: true, collapsed: true, }, + hidden: ({ parent }: TeaserDocument) => parent.isBigText, }, { name: 'link', @@ -74,6 +93,11 @@ export default { }, ], fields: [ + { + title: 'Big text', + name: 'isBigText', + type: 'boolean', + }, { name: 'overline', title: 'Eyebrow', @@ -87,6 +111,7 @@ export default { input: CompactBlockEditor, }, of: [titleContentType], + hidden: ({ parent }: TeaserDocument) => parent.isBigText, }, { name: 'text', @@ -94,7 +119,27 @@ export default { type: 'array', of: [blockContentType], validation: (Rule: Rule) => - Rule.custom((value: PortableTextBlock[]) => validateCharCounterEditor(value, 600)).warning(), + Rule.custom((value: PortableTextBlock[], ctx: ValidationContext) => { + if (!(ctx.parent as Teaser)?.isBigText) { + return validateCharCounterEditor(value, 600) + } + return true + }).warning(), + hidden: ({ parent }: TeaserDocument) => parent.isBigText, + }, + { + name: 'bigText', + title: 'Text content', + type: 'array', + of: [blockContentTypeForBigText], + validation: (Rule: Rule) => + Rule.custom((value: PortableTextBlock[], ctx: ValidationContext) => { + if ((ctx.parent as Teaser)?.isBigText) { + return validateCharCounterEditor(value, 600) + } + return true + }), + hidden: ({ parent }: TeaserDocument) => !parent.isBigText, }, { name: 'action', @@ -165,14 +210,29 @@ export default { preview: { select: { title: 'title', + text: 'text', + isBigText: 'isBigText', + bigText: 'bigText', image: 'image.asset', }, - prepare({ title, image }: { title: PortableTextBlock[]; image: Reference }) { - const plainTitle = title ? blocksToText(title) : undefined + prepare({ + title, + text, + isBigText, + bigText, + image, + }: { + title: PortableTextBlock[] + text: PortableTextBlock[] + isBigText: boolean + bigText: PortableTextBlock[] + image: Reference + }) { + const plainTitle = isBigText ? blocksToText(bigText) : blocksToText(title || text) return { - title: plainTitle || 'Missing title!', - subtitle: 'Teaser component', + title: plainTitle || 'Missing title/content', + subtitle: isBigText ? 'Teaser component (BIG TEXT)' : 'Teaser component', media: image, } }, diff --git a/sanityv3/schemas/objects/textBlock.tsx b/sanityv3/schemas/objects/textBlock.tsx index 14b3a8340..7e10bc4f8 100644 --- a/sanityv3/schemas/objects/textBlock.tsx +++ b/sanityv3/schemas/objects/textBlock.tsx @@ -1,10 +1,9 @@ /* eslint-disable @typescript-eslint/ban-ts-comment */ import { text_field } from '@equinor/eds-icons' -import type { Reference, Rule } from 'sanity' +import type { PortableTextBlock, Reference, Rule, SanityDocument, ValidationContext } from 'sanity' import type { ColorSelectorValue } from '../components/ColorSelector' import blocksToText from '../../helpers/blocksToText' import { EdsIcon } from '../../icons' -import { SchemaType } from '../../types' import CompactBlockEditor from '../components/CompactBlockEditor' import { configureBlockContent, configureTitleBlockContent } from '../editors' import { validateComponentAnchor } from '../validations/validateAnchorReference' @@ -16,6 +15,7 @@ const blockContentType = configureBlockContent({ h4: false, attachment: false, }) + const ingressContentType = configureBlockContent({ h1: false, h2: false, @@ -23,6 +23,21 @@ const ingressContentType = configureBlockContent({ h4: false, attachment: false, }) + +const blockContentTypeForBigText = configureBlockContent({ + h1: false, + h2: false, + h3: false, + h4: false, + attachment: false, + smallText: false, + normalTextOverride: { + title: 'Normal', + value: 'normal', + component: ({ children }: { children: React.ReactNode }) => {children}, + }, +}) + const titleContentType = configureTitleBlockContent() type TextBlock = { @@ -31,12 +46,18 @@ type TextBlock = { anchor?: string ingress?: string text?: string + isBigText?: boolean + bigText?: PortableTextBlock[] action?: Reference[] splitList?: boolean overrideButtonStyle?: boolean background?: ColorSelectorValue } +type TextBlockDocument = { + parent: TextBlock +} + export default { name: 'textBlock', title: 'Text block', @@ -50,6 +71,7 @@ export default { collapsible: true, collapsed: true, }, + hidden: ({ parent }: TextBlockDocument) => parent.isBigText, }, { title: 'Eyebrow headline', @@ -59,6 +81,7 @@ export default { collapsible: true, collapsed: true, }, + hidden: ({ parent }: TextBlockDocument) => parent.isBigText, }, { title: 'Call to action(s)', @@ -84,6 +107,11 @@ export default { }, ], fields: [ + { + title: 'Big text', + name: 'isBigText', + type: 'boolean', + }, { name: 'image', type: 'imageWithAlt', @@ -105,7 +133,11 @@ export default { input: CompactBlockEditor, }, of: [titleContentType], - validation: (Rule: SchemaType.ValidationRule) => Rule.required().warning('A title is recommended'), + validation: (Rule: Rule) => + Rule.custom((value: PortableTextBlock[], ctx: ValidationContext) => + !value && !(ctx.parent as TextBlock)?.isBigText ? 'A title is recommended' : true, + ).warning(), + hidden: ({ parent }: TextBlockDocument) => parent.isBigText, }, { name: 'anchor', @@ -124,6 +156,18 @@ export default { title: 'Ingress', type: 'array', of: [ingressContentType], + hidden: ({ parent }: TextBlockDocument) => parent.isBigText, + }, + { + name: 'bigTitle', + title: 'Title', + type: 'array', + of: [blockContentTypeForBigText], + hidden: ({ parent }: TextBlockDocument) => !parent.isBigText, + validation: (Rule: Rule) => + Rule.custom((value: PortableTextBlock[], ctx: ValidationContext) => + !value && (ctx.parent as TextBlock)?.isBigText ? 'Title is required' : true, + ), }, { name: 'text', @@ -176,27 +220,27 @@ export default { title: 'title', ingress: 'ingress', text: 'text', - }, - prepare({ title = [], ingress, text }: { title: any[]; ingress: any; text: any }) { - const textBlock = (text || []).find((introBlock: any) => introBlock._type === 'block') - const ingressBlock = (ingress || []).find((introBlock: any) => introBlock._type === 'block') - const plainTitle = title ? blocksToText(title) : undefined + isBigText: 'isBigText', + bigTitle: 'bigTitle', + }, + prepare({ + title, + isBigText, + bigTitle, + ingress, + text, + }: { + title: PortableTextBlock[] + ingress: PortableTextBlock[] + isBigText: boolean + bigTitle: PortableTextBlock[] + text: PortableTextBlock[] + }) { + const plainTitle = isBigText ? blocksToText(bigTitle) : blocksToText(title || ingress || text) return { - title: - plainTitle || - (textBlock && - textBlock.children - .filter((child: any) => child._type === 'span') - .map((span: any) => span.text) - .join('')) || - (ingressBlock && - ingressBlock.children - .filter((child: any) => child._type === 'span') - .map((span: any) => span.text) - .join('')) || - 'Missing content!', - subtitle: `Text block component.`, + title: plainTitle || 'Missing title/content', + subtitle: isBigText ? 'Text block component (BIG TEXT)' : 'Text block component', media: EdsIcon(text_field), } }, diff --git a/search/IndexSanityContent/magazine/sanity.ts b/search/IndexSanityContent/magazine/sanity.ts index 3175c8099..9c078d3a3 100644 --- a/search/IndexSanityContent/magazine/sanity.ts +++ b/search/IndexSanityContent/magazine/sanity.ts @@ -27,7 +27,11 @@ export const query = /* groq */ `*[_type == "magazine" && _lang == $lang && !(_i "ingress": pt::text(ingress), "textBlocks": content[_type == "textBlock"]{ "_key": _key, - "title": pt::text(title), + "title": select( + "isBigText" == true => { + pt::text(bigTitle), + pt::text(title) + }), "ingress": pt::text(ingress), "text": pt::text(text) // TODO: Do this manually to cover all cases }, diff --git a/search/IndexSanityContent/topic/sanity.ts b/search/IndexSanityContent/topic/sanity.ts index 7d27ee78f..8280a0e80 100644 --- a/search/IndexSanityContent/topic/sanity.ts +++ b/search/IndexSanityContent/topic/sanity.ts @@ -11,7 +11,11 @@ export const query = /* groq */ `*[_type match "route_" + $lang + "*" && content "type": content->_type, "textBlocks": content->content[_type == "textBlock"]{ "_key": _key, - "title": pt::text(title), + "title": select( + "isBigText" == true => { + pt::text(bigTitle), + pt::text(title) + }), "ingress": pt::text(ingress), "text": pt::text(text) // TODO: Do this manually to cover all cases }, diff --git a/web/components/src/Heading/Heading.stories.tsx b/web/components/src/Heading/Heading.stories.tsx index 3f04cea03..a6a09ac2e 100644 --- a/web/components/src/Heading/Heading.stories.tsx +++ b/web/components/src/Heading/Heading.stories.tsx @@ -35,7 +35,7 @@ Default.storyName = 'Default' export const HeaderLevels: StoryFn = () => ( - + Renewables and low-carbon{' '} @@ -60,10 +60,10 @@ HeaderLevels.storyName = 'Header levels' export const FontWeight: StoryFn = () => ( - + I'm bold - + I'm regular @@ -72,7 +72,7 @@ FontWeight.storyName = 'Font weight' FontWeight.parameters = { docs: { - storyDescription: `The largest font size, 2xl, can be either bold or regular`, + storyDescription: `The largest font size, 3xl, can be either bold or regular`, }, } @@ -93,7 +93,7 @@ export const Sizes: StoryFn = () => ( We are all h1 headers - + We are all h1 headers @@ -122,7 +122,7 @@ export const Long: StoryFn = () => ( Equinor is in a unique position to make a difference in the global energy future. We will seize this opportunity. - + Equinor is in a unique position to make a difference in the global energy future. We will seize this opportunity. diff --git a/web/components/src/Heading/Heading.tsx b/web/components/src/Heading/Heading.tsx index f0f30fd6a..bca5c415d 100644 --- a/web/components/src/Heading/Heading.tsx +++ b/web/components/src/Heading/Heading.tsx @@ -30,7 +30,7 @@ const StyledHeading = styled(Typography)` ` export type HeadingProps = { - size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' + size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' level?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' regular?: boolean center?: boolean @@ -45,7 +45,8 @@ const sizes = { md: 'var(--typeScale-2)', lg: 'var(--typeScale-3)', xl: 'var(--typeScale-4)', - '2xl': 'var(--typeScale-5)', + '2xl': 'var(--typeScale-4_5)', + '3xl': 'var(--typeScale-5)', } const lineHeights = { @@ -54,7 +55,8 @@ const lineHeights = { md: 'var(--lineHeight-1)', lg: 'var(--lineHeight-1)', xl: 'var(--lineHeight-1)', - '2xl': 'var(--lineHeight-2)', + '2xl': 'var(--lineHeight-2_5)', + '3xl': 'var(--lineHeight-2)', } const fontWeights = { @@ -63,7 +65,8 @@ const fontWeights = { md: 'var(--fontWeight-regular)', lg: 'var(--fontWeight-regular)', xl: 'var(--fontWeight-regular)', - '2xl': 'var(--fontWeight-regular)', + '2xl': 'var(--fontWeidht-regular)', + '3xl': 'var(--fontWeight-regular)', } export const Heading = forwardRef(function Heading( diff --git a/web/components/src/Text/Text.tsx b/web/components/src/Text/Text.tsx index 4eb429fdc..ec17c2c3b 100644 --- a/web/components/src/Text/Text.tsx +++ b/web/components/src/Text/Text.tsx @@ -10,9 +10,9 @@ type StyledTextProps = { const StyledText = styled(Typography)` font-size: var(--size); - line-height: var(--lineHeight-3); + line-height: var(--lineHeight); /* @TODO: Let's consider to move all the margin woo to the article layout - We should. Not move, but scope. For both news and topic pages. But this will + We should. Not move, but scope. For both news and topic pages. But this will require a lot of retest, since in some of the uses cases we will need to reintroduce the margin */ margin-bottom: var(--space-medium); & + & { @@ -41,7 +41,8 @@ const StyledText = styled(Typography)` ` export type TextProps = { - size?: 'regular' | 'md' | 'small' + size?: 'regular' | 'md' | 'small' | 'lg' + lineHeight?: '1' | '2' | '2_5' | '3' bold?: boolean italic?: boolean centered?: boolean @@ -51,13 +52,21 @@ export type TextProps = { /* Should be easy enough to change later on */ const sizes = { + lg: 'var(--typeScale-4_5)', regular: 'var(--typeScale-1)', md: 'var(--typeScale-2)', small: 'var(--typeScale-0)', } +const lineHeights = { + 1: 'var(--lineHeight-1)', + 2: 'var(--lineHeight-2)', + '2_5': 'var(--lineHeight-2_5)', + 3: 'var(--lineHeight-3)', +} + export const Text = forwardRef(function Text( - { size = 'regular', style, children, inverted = false, ...rest }, + { size = 'regular', lineHeight = '3', style, children, inverted = false, ...rest }, ref, ) { return ( @@ -68,6 +77,7 @@ export const Text = forwardRef(function Text( { ...style, '--size': sizes[size], + '--lineHeight': lineHeights[lineHeight], } as CSSProperties } {...rest} diff --git a/web/lib/queries/common/pageContentFields.ts b/web/lib/queries/common/pageContentFields.ts index 3893d7fe2..43cf55fdd 100644 --- a/web/lib/queries/common/pageContentFields.ts +++ b/web/lib/queries/common/pageContentFields.ts @@ -12,21 +12,23 @@ import promoteMagazine from './promotions/promoteMagazine' import { publishDateTimeQuery } from './publishDateTime' const pageContentFields = /* groq */ ` - _type == "teaser" =>{ + _type == "teaser" => { "type": _type, "id": _key, overline, title, - text[]{ - ..., - ${markDefs}, - }, + isBigText, + "text": select( + isBigText => + bigText[]{..., ${markDefs}}, + text[]{..., ${markDefs}} + ), "designOptions": { "background": coalesce(background.title, 'White'), "imagePosition": coalesce(imagePosition, 'left'), imageSize, }, - "image": image{ + "image": image { ..., "extension": asset-> extension }, @@ -41,15 +43,14 @@ const pageContentFields = /* groq */ ` "id": _key, image, overline, - title, - ingress[]{ - ..., - ${markDefs}, - }, - text[]{ - ..., - ${markDefs}, - }, + isBigText, + "title": select( + isBigText => + bigTitle[]{..., ${markDefs}}, + title[]{..., ${markDefs}} + ), + ingress[]{..., ${markDefs}}, + text[]{..., ${markDefs}}, "callToActions": action[]{ ${linkSelectorFields}, ${downloadableFileFields}, diff --git a/web/pageComponents/pageTemplates/ErrorPage.tsx b/web/pageComponents/pageTemplates/ErrorPage.tsx index 68f9d3f8f..0ba71165f 100644 --- a/web/pageComponents/pageTemplates/ErrorPage.tsx +++ b/web/pageComponents/pageTemplates/ErrorPage.tsx @@ -41,7 +41,7 @@ const ErrorPage = ({ pageData }: { pageData: ErrorPageData }) => { {backgroundImage && } - + 404 {title && {toPlainText(title)}} diff --git a/web/pageComponents/pageTemplates/Event.tsx b/web/pageComponents/pageTemplates/Event.tsx index 2090e6720..70fe21fc6 100644 --- a/web/pageComponents/pageTemplates/Event.tsx +++ b/web/pageComponents/pageTemplates/Event.tsx @@ -150,7 +150,7 @@ export default function Event({ data }: { data: EventSchema }): JSX.Element {
- {title && } + {title && } {start && ( diff --git a/web/pageComponents/pageTemplates/LandingPage.tsx b/web/pageComponents/pageTemplates/LandingPage.tsx index 1e9fa7f6c..918feda65 100644 --- a/web/pageComponents/pageTemplates/LandingPage.tsx +++ b/web/pageComponents/pageTemplates/LandingPage.tsx @@ -43,7 +43,7 @@ const LandingPage = ({ data }: LandingPageProps) => { <> - {title && } + {title && } {ingress && ( diff --git a/web/pageComponents/pageTemplates/News.tsx b/web/pageComponents/pageTemplates/News.tsx index 1c4c69b01..b82dfe575 100644 --- a/web/pageComponents/pageTemplates/News.tsx +++ b/web/pageComponents/pageTemplates/News.tsx @@ -219,7 +219,7 @@ const NewsPage = ({ data: news }: ArticleProps) => {
- + {title} {publishDateTime && ( diff --git a/web/pageComponents/pageTemplates/NewsRoomPage.tsx b/web/pageComponents/pageTemplates/NewsRoomPage.tsx index a86f23084..1f0ac560c 100644 --- a/web/pageComponents/pageTemplates/NewsRoomPage.tsx +++ b/web/pageComponents/pageTemplates/NewsRoomPage.tsx @@ -189,7 +189,7 @@ const NewsRoomPage = ({ isServerRendered, locale, pageData, slug, url }: NewsRoo // @ts-ignore: Still struggling with the types here :/ if (isEmpty(children)) return null return ( - + {children} ) diff --git a/web/pageComponents/pageTemplates/shared/SharedTitle.tsx b/web/pageComponents/pageTemplates/shared/SharedTitle.tsx index 64c1dd855..9216bf4e8 100644 --- a/web/pageComponents/pageTemplates/shared/SharedTitle.tsx +++ b/web/pageComponents/pageTemplates/shared/SharedTitle.tsx @@ -40,7 +40,7 @@ const StyledHeading = styled(TitleText)<{ $bgColor?: BackgroundColours }>` const SharedTitle = ({ title, styles }: SharedTitleProps) => { return ( - + ) } diff --git a/web/pageComponents/shared/Hero/DefaultHero.tsx b/web/pageComponents/shared/Hero/DefaultHero.tsx index 8677a80aa..61fcdb6dd 100644 --- a/web/pageComponents/shared/Hero/DefaultHero.tsx +++ b/web/pageComponents/shared/Hero/DefaultHero.tsx @@ -34,7 +34,7 @@ type Props = { export const DefaultHero = ({ title, image }: Props) => { return ( <> - {title && } + {title && } {image && } ) diff --git a/web/pageComponents/shared/Teaser.tsx b/web/pageComponents/shared/Teaser.tsx index 6b59b094e..7590023c4 100644 --- a/web/pageComponents/shared/Teaser.tsx +++ b/web/pageComponents/shared/Teaser.tsx @@ -1,4 +1,4 @@ -import { Teaser as EnvisTeaser, Link, Eyebrow, BackgroundContainer } from '@components' +import { Teaser as EnvisTeaser, Link, Eyebrow, BackgroundContainer, Text } from '@components' import styled from 'styled-components' import IngressText from './portableText/IngressText' import TitleText from './portableText/TitleText' @@ -9,6 +9,7 @@ import { getUrlFromAction } from '../../common/helpers/getUrlFromAction' import type { TeaserData, ImageWithAlt, LinkData } from '../../types/types' import { getLocaleFromName } from '../../lib/localization' +import { BlockType } from './portableText/helpers/defaultSerializers' const { Content, Media } = EnvisTeaser @@ -55,9 +56,9 @@ const TeaserAction = ({ action }: { action: LinkData }) => { if (action.type === 'internalUrl') { const locale = getLocaleFromName(action.link?.lang) return ( - - {action.label} - + + {action.label} + ) } @@ -69,7 +70,7 @@ const TeaserAction = ({ action }: { action: LinkData }) => { } const Teaser = ({ data, anchor }: TeaserProps) => { - const { title, overline, text, image, action, designOptions } = data + const { title, overline, text, image, action, designOptions, isBigText } = data const { background, imageSize, imagePosition } = designOptions if ([title, overline, text, image?.asset, action].every((i) => !i)) { @@ -88,11 +89,28 @@ const Teaser = ({ data, anchor }: TeaserProps) => { {image?.asset && } - {overline && {overline}} - - {title && } - - {text && } + {isBigText ? ( + text && ( + ( + + {children} + + ), + } as BlockType, + }} + /> + ) + ) : ( + <> + {overline && {overline}} + {title && } + {text && } + + )} {action && } diff --git a/web/pageComponents/shared/portableText/IngressText.tsx b/web/pageComponents/shared/portableText/IngressText.tsx index c2a97b098..0db2ba4db 100644 --- a/web/pageComponents/shared/portableText/IngressText.tsx +++ b/web/pageComponents/shared/portableText/IngressText.tsx @@ -1,5 +1,4 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ -import { PortableText, PortableTextProps } from '@portabletext/react' +import { PortableText, PortableTextProps, PortableTextReactComponents } from '@portabletext/react' import styled from 'styled-components' import { h3Heading, h2Heading, Sub, Sup, ExternalLink, InternalLink } from './components' import isEmpty from './helpers/isEmpty' @@ -57,14 +56,14 @@ type IngressTextProps = { centered?: boolean } & PortableTextProps -const IngressText = ({ value, centered = false, components = {}, ...props }: IngressTextProps) => ( - -) +const IngressText = ({ value, centered = false, components = {}, ...props }: IngressTextProps) => { + return ( + + ) +} export default IngressText diff --git a/web/pageComponents/topicPages/TextBlock.tsx b/web/pageComponents/topicPages/TextBlock.tsx index a772f7c29..b998d38a1 100644 --- a/web/pageComponents/topicPages/TextBlock.tsx +++ b/web/pageComponents/topicPages/TextBlock.tsx @@ -1,4 +1,4 @@ -import { Eyebrow, BackgroundContainer } from '@components' +import { Eyebrow, BackgroundContainer, Text, Heading } from '@components' import IngressText from '../shared/portableText/IngressText' import RichText from '../shared/portableText/RichText' import TitleText from '../shared/portableText/TitleText' @@ -6,6 +6,7 @@ import Image, { Ratios } from '../shared/SanityImage' import styled from 'styled-components' import type { TextBlockData } from '../../types/types' import CallToActions from './CallToActions' +import { BlockType } from '../shared/portableText/helpers/defaultSerializers' export const StyledTextBlockWrapper = styled(BackgroundContainer)<{ id: string | undefined }>` ${({ id }) => @@ -62,6 +63,7 @@ const TextBlock = ({ data, anchor }: TextBlockProps) => { callToActions, splitList, overrideButtonStyle = false, + isBigText, } = data /* Don't render the component if it only has an eyebrow */ if (!title && !ingress && !text && (!callToActions || callToActions.length === 0)) return null @@ -70,14 +72,30 @@ const TextBlock = ({ data, anchor }: TextBlockProps) => { return ( - {image?.asset && ( - - - + {isBigText ? ( + title && ( + {children}, + } as BlockType, + }} + /> + ) + ) : ( + <> + {image?.asset && ( + + + + )} + {overline && {overline}} + {title && } + {ingress && } + )} - {overline && {overline}} - {title && } - {ingress && } {text && ( diff --git a/web/styles/settings.ts b/web/styles/settings.ts index d053bab7b..8fcc1f1a0 100644 --- a/web/styles/settings.ts +++ b/web/styles/settings.ts @@ -98,6 +98,7 @@ export const typography = css` --typeScale-2: clamp(calc(19.20 / 16 * 1rem), 0.54vw + 1.07rem, calc(27.50 / 16 * 1rem)); --typeScale-3: clamp(calc(23.04 / 16 * 1rem), 0.73vw + 1.27rem, calc(34.38 / 16 * 1rem)); --typeScale-4: clamp(calc(27.65 / 16 * 1rem), 0.99vw + 1.5rem, calc(42.97 / 16 * 1rem)); + --typeScale-4_5: clamp(calc(33.73 / 16 * 1rem), 1.38vw + 1.785rem, calc(55.055 / 16 * 1rem)); --typeScale-5: clamp(calc(39.81 / 16 * 1rem), 1.77vw + 2.07rem, calc(67.14 / 16 * 1rem)); // search and replace, then remove @@ -108,6 +109,7 @@ export const typography = css` /* Should probably do something more clever here */ --lineHeight-1: inherit; --lineHeight-2: 1.2; + --lineHeight-2_5: 1.35; --lineHeight-3: 1.5; /* Font weights */ diff --git a/web/types/types.ts b/web/types/types.ts index 663174645..1ad4bc52b 100644 --- a/web/types/types.ts +++ b/web/types/types.ts @@ -261,6 +261,7 @@ export type DesignOptions = { imagePosition?: TeaserImagePosition imageSize?: TeaserImageSize } + export type TextBlockData = { type: string id: string @@ -268,6 +269,7 @@ export type TextBlockData = { image?: ImageWithAlt overline?: string text: PortableTextBlock[] + isBigText?: boolean ingress: PortableTextBlock[] callToActions?: LinkData[] splitList?: boolean @@ -289,6 +291,7 @@ export type TeaserData = { title: PortableTextBlock[] text: PortableTextBlock[] overline?: string + isBigText?: boolean image: ImageWithAlt action?: LinkData designOptions: DesignOptions