diff --git a/src/__stories__/header-story.tsx b/src/__stories__/header-story.tsx index 117b17747..8ede574a5 100644 --- a/src/__stories__/header-story.tsx +++ b/src/__stories__/header-story.tsx @@ -10,6 +10,8 @@ import { IconInformationUserLight, } from '..'; +import type {HeadingType} from '../utils/types'; + export default { title: 'Components/Headers/Header', parameters: { @@ -20,8 +22,10 @@ export default { type Args = { withHeader: boolean; pretitle: string; + pretitleAs: HeadingType; truncatePretitle: boolean; title: string; + titleAs: HeadingType; description: string; small: boolean; inverse: boolean; @@ -39,8 +43,10 @@ export const Default: StoryComponent = ({ sideBySideExtraOnDesktop, withBreadcrumbs, pretitle, + pretitleAs, truncatePretitle, title, + titleAs, description, small, withExtraContent, @@ -65,8 +71,10 @@ export const Default: StoryComponent = ({ header={ withHeader ? (
@@ -91,7 +99,9 @@ Default.storyName = 'Header'; Default.args = { withHeader: true, pretitle: 'Your last bill', + pretitleAs: 'span', title: 'December bill is now available', + titleAs: 'h2', description: 'This is a description', small: false, truncatePretitle: false, @@ -105,7 +115,17 @@ Default.args = { Default.argTypes = { pretitle: {if: {arg: 'withHeader'}}, + pretitleAs: { + if: {arg: 'withHeader'}, + options: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'span'], + control: {type: 'select'}, + }, title: {if: {arg: 'withHeader'}}, + titleAs: { + if: {arg: 'withHeader'}, + options: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'span'], + control: {type: 'select'}, + }, description: {if: {arg: 'withHeader'}}, small: {if: {arg: 'withHeader'}}, sideBySideExtraOnDesktop: {if: {arg: 'withExtraContent'}}, diff --git a/src/__stories__/title-story.tsx b/src/__stories__/title-story.tsx index c22bbddac..fa3ec75f5 100644 --- a/src/__stories__/title-story.tsx +++ b/src/__stories__/title-story.tsx @@ -2,6 +2,7 @@ import * as React from 'react'; import {Title1, Title2, Title3, ButtonLink, IconInformationRegular, skinVars} from '..'; import type {TitleProps} from '../title'; +import type {HeadingType} from '../utils/types'; export default { title: 'Components/Titles', @@ -24,7 +25,7 @@ type renderTitleComponentProps = { linkText: string; right: 'link' | 'icon' | 'undefined'; defaultTitle: string; - as: 'h1' | 'h2' | 'h3'; + as: HeadingType; TitleComponent: React.ComponentType; }; diff --git a/src/callout.tsx b/src/callout.tsx index 0766b15f2..351f5e6f0 100644 --- a/src/callout.tsx +++ b/src/callout.tsx @@ -18,11 +18,11 @@ import {getPrefixedDataAttributes} from './utils/dom'; import {applyCssVars} from './utils/css'; import type {ButtonLink, ButtonPrimary, ButtonSecondary} from './button'; -import type {DataAttributes, RendersNullableElement} from './utils/types'; +import type {DataAttributes, HeadingType, RendersNullableElement} from './utils/types'; type Props = { title?: string; - titleAs?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'; + titleAs?: HeadingType; description: string; onClose?: () => void; icon?: React.ReactElement; diff --git a/src/card.tsx b/src/card.tsx index c5b703ce0..bf9d31bac 100644 --- a/src/card.tsx +++ b/src/card.tsx @@ -34,6 +34,7 @@ import type {ButtonLink, ButtonPrimary, ButtonSecondary} from './button'; import type {ExclusifyUnion} from './utils/utility-types'; import type { DataAttributes, + HeadingType, IconProps, RendersElement, RendersNullableElement, @@ -372,7 +373,7 @@ type CardContentProps = { pretitle?: string; pretitleLinesMax?: number; title?: string; - titleAs?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'; + titleAs?: HeadingType; titleLinesMax?: number; subtitle?: string; subtitleLinesMax?: number; @@ -506,7 +507,7 @@ interface MediaCardBaseProps { pretitle?: string; pretitleLinesMax?: number; title?: string; - titleAs?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'; + titleAs?: HeadingType; titleLinesMax?: number; subtitle?: string; subtitleLinesMax?: number; @@ -729,7 +730,7 @@ export const NakedCard = React.forwardRef( type SmallNakedCardProps = MaybeTouchableCard<{ media: RendersElement | RendersElement; title?: string; - titleAs?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'; + titleAs?: HeadingType; titleLinesMax?: number; subtitle?: string; subtitleLinesMax?: number; @@ -840,7 +841,7 @@ interface DataCardBaseProps { pretitle?: string; pretitleLinesMax?: number; title?: string; - titleAs?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'; + titleAs?: HeadingType; titleLinesMax?: number; subtitle?: string; subtitleLinesMax?: number; @@ -975,7 +976,7 @@ export const DataCard = React.forwardRef( type SnapCardProps = MaybeTouchableCard<{ icon?: React.ReactElement; title?: string; - titleAs?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'; + titleAs?: HeadingType; titleLinesMax?: number; subtitle?: string; subtitleLinesMax?: number; @@ -1152,7 +1153,7 @@ interface CommonDisplayCardProps { pretitle?: string; pretitleLinesMax?: number; title: string; - titleAs?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'; + titleAs?: HeadingType; titleLinesMax?: number; description?: string; descriptionLinesMax?: number; @@ -1444,7 +1445,7 @@ interface PosterCardBaseProps { pretitle?: string; pretitleLinesMax?: number; title?: string; - titleAs?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'; + titleAs?: HeadingType; titleLinesMax?: number; subtitle?: string; subtitleLinesMax?: number; diff --git a/src/community/advanced-data-card.tsx b/src/community/advanced-data-card.tsx index 6f4f9c868..7bf682dd2 100644 --- a/src/community/advanced-data-card.tsx +++ b/src/community/advanced-data-card.tsx @@ -25,7 +25,7 @@ import type {CardAction} from '../card'; import type StackingGroup from '../stacking-group'; import type Image from '../image'; import type {ButtonPrimary, ButtonLink} from '../button'; -import type {DataAttributes, TrackingEvent} from '../utils/types'; +import type {DataAttributes, HeadingType, TrackingEvent} from '../utils/types'; import type {RendersNullableElement} from '../utils/renders-element'; import type Tag from '../tag'; import type { @@ -231,17 +231,15 @@ type AllowedExtra = | typeof SimpleBlock | typeof ValueBlock; -type TextAs = 'h1' | 'h2' | 'h3' | 'h4'; - type AdvancedDataCardProps = MaybeTouchableCard<{ stackingGroup?: RendersNullableElement; headline?: RendersNullableElement; pretitle?: string; pretitleLinesMax?: number; - pretitleAs?: TextAs; + pretitleAs?: HeadingType; title?: string; titleLinesMax?: number; - titleAs?: TextAs; + titleAs?: HeadingType; subtitle?: string; subtitleLinesMax?: number; description?: string; diff --git a/src/cover-hero.tsx b/src/cover-hero.tsx index 9d7c2c94b..cb84a2259 100644 --- a/src/cover-hero.tsx +++ b/src/cover-hero.tsx @@ -13,7 +13,7 @@ import GridLayout from './grid-layout'; import {CoverHeroMedia} from './cover-hero-media'; import {getPrefixedDataAttributes} from './utils/dom'; -import type {DataAttributes} from './utils/types'; +import type {DataAttributes, HeadingType} from './utils/types'; import type {ImageProps, VideoProps} from './cover-hero-media'; import type {AspectRatio} from './image'; import type {ExclusifyUnion} from './utils/utility-types'; @@ -28,7 +28,7 @@ type BaseProps = { pretitleLinesMax?: number; title: string; titleLinesMax?: number; - titleAs?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'; + titleAs?: HeadingType; description?: string; descriptionLinesMax?: number; extra?: React.ReactNode; diff --git a/src/empty-state-card.tsx b/src/empty-state-card.tsx index d64ec52e4..aa6507ebe 100644 --- a/src/empty-state-card.tsx +++ b/src/empty-state-card.tsx @@ -14,7 +14,7 @@ import type {DataAttributes, RendersNullableElement} from './utils/types'; interface CommonProps { title: string; - titleAs?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'; + titleAs?: HeadingType; button?: RendersNullableElement; secondaryButton?: RendersNullableElement; buttonLink?: RendersNullableElement; diff --git a/src/empty-state.tsx b/src/empty-state.tsx index abe928d62..bae1d0311 100644 --- a/src/empty-state.tsx +++ b/src/empty-state.tsx @@ -16,11 +16,11 @@ import {applyCssVars} from './utils/css'; import type {ButtonSecondary, ButtonLink} from './button'; import type {ButtonGroupProps} from './button-group'; -import type {DataAttributes, RendersNullableElement} from './utils/types'; +import type {DataAttributes, HeadingType, RendersNullableElement} from './utils/types'; interface BaseProps { title: string; - titleAs?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'; + titleAs?: HeadingType; button?: RendersNullableElement | RendersNullableElement; buttonLink?: RendersNullableElement; description?: string; diff --git a/src/header.tsx b/src/header.tsx index 66665fb6a..9dd4eea56 100644 --- a/src/header.tsx +++ b/src/header.tsx @@ -15,7 +15,7 @@ import {Title2, Title3} from './title'; import type NavigationBreadcrumbs from './navigation-breadcrumbs'; import type {ButtonPrimary, ButtonSecondary} from './button'; -import type {DataAttributes, RendersElement, RendersNullableElement} from './utils/types'; +import type {DataAttributes, HeadingType, RendersElement, RendersNullableElement} from './utils/types'; import type {TextPresetProps} from './text'; type OverridableTextProps = { @@ -28,8 +28,9 @@ type RichText = string | ({text: string} & OverridableTextProps); type HeaderProps = { pretitle?: RichText; + pretitleAs?: HeadingType; title?: string; - titleAs?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'; + titleAs?: HeadingType; description?: string; small?: boolean; dataAttributes?: DataAttributes; @@ -61,6 +62,7 @@ type HeaderProps = { export const Header: React.FC = ({ pretitle, + pretitleAs, title, titleAs = 'h2', description, @@ -96,7 +98,8 @@ export const Header: React.FC = ({ {(title || pretitle || description) && ( - {pretitle && renderRichText(pretitle, {color: vars.colors.textPrimary})} + {pretitle && + renderRichText(pretitle, {color: vars.colors.textPrimary, as: pretitleAs})} {title && (small ? ( {title} @@ -144,7 +147,7 @@ export const Header: React.FC = ({ type MainSectionHeaderProps = { title: string; - titleAs?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'; + titleAs?: HeadingType; description?: string; button?: RendersNullableElement | RendersNullableElement; }; diff --git a/src/hero.tsx b/src/hero.tsx index de0cc68cf..afc5a594f 100644 --- a/src/hero.tsx +++ b/src/hero.tsx @@ -21,7 +21,7 @@ import type Image from './image'; import type Video from './video'; import type {ButtonLink, ButtonPrimary, ButtonSecondary} from './button'; import type Tag from './tag'; -import type {DataAttributes, RendersElement, RendersNullableElement} from './utils/types'; +import type {DataAttributes, HeadingType, RendersElement, RendersNullableElement} from './utils/types'; const CONTENT_BACKGROUND_COLOR = { default: skinVars.colors.background, @@ -51,7 +51,7 @@ type HeroContentProps = { headline?: RendersNullableElement; pretitle?: string; title?: string; - titleAs?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'; + titleAs?: HeadingType; description?: string; descriptionLinesMax?: number; extra?: React.ReactNode; @@ -122,7 +122,7 @@ type HeroProps = { headline?: RendersNullableElement; pretitle?: string; title?: string; - titleAs?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'; + titleAs?: HeadingType; description?: string; descriptionLinesMax?: number; extra?: React.ReactNode; diff --git a/src/highlighted-card.tsx b/src/highlighted-card.tsx index c217eb9b6..1031528fd 100644 --- a/src/highlighted-card.tsx +++ b/src/highlighted-card.tsx @@ -13,7 +13,7 @@ import {useTheme} from './hooks'; import type {ExclusifyUnion} from './utils/utility-types'; import type {TouchableComponentProps} from './touchable'; import type {ButtonLink, NullableButtonElement} from './button'; -import type {DataAttributes, RendersNullableElement, TrackingEvent} from './utils/types'; +import type {DataAttributes, HeadingType, RendersNullableElement, TrackingEvent} from './utils/types'; // At least one of title or description is required type TextProps = @@ -27,7 +27,7 @@ type TextProps = }; type CommonProps = TextProps & { - titleAs?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'; + titleAs?: HeadingType; titleLinesMax?: number; descriptionLinesMax?: number; imageUrl?: string; diff --git a/src/navigation-bar.tsx b/src/navigation-bar.tsx index 445da53af..116f870e3 100644 --- a/src/navigation-bar.tsx +++ b/src/navigation-bar.tsx @@ -28,7 +28,7 @@ import Box from './box'; import {isRunningAcceptanceTest} from './utils/platform'; import type {TouchableProps} from './touchable'; -import type {DataAttributes} from './utils/types'; +import type {DataAttributes, HeadingType} from './utils/types'; const BurgerMenuIcon = ({isOpen}: {isOpen: boolean}) => { return ( @@ -303,7 +303,7 @@ interface NavigationBarCommonProps { isInverse?: boolean; onBack?: () => void; title?: string; - titleAs?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'; + titleAs?: HeadingType; right?: React.ReactElement; withBorder?: boolean; children?: undefined; diff --git a/src/title.tsx b/src/title.tsx index 97ce61035..ea37529e6 100644 --- a/src/title.tsx +++ b/src/title.tsx @@ -7,7 +7,7 @@ import {vars} from './skins/skin-contract.css'; import {useTheme} from './hooks'; import {getPrefixedDataAttributes} from './utils/dom'; -import type {DataAttributes} from './utils/types'; +import type {DataAttributes, HeadingType} from './utils/types'; type TitleLayoutProps = { title: React.ReactElement; @@ -35,7 +35,7 @@ export type TitleProps = { children: React.ReactNode; id?: string; right?: React.ReactNode; - as?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'; + as?: HeadingType; /** "data-" prefix is automatically added. For example, use "testid" instead of "data-testid" */ dataAttributes?: DataAttributes; }; diff --git a/src/utils/types.tsx b/src/utils/types.tsx index 0d04c8401..cf5a45dd3 100644 --- a/src/utils/types.tsx +++ b/src/utils/types.tsx @@ -12,3 +12,5 @@ export type IconProps = { }; export type ByBreakpoint = T | {mobile: T; tablet?: T; desktop: T}; + +export type HeadingType = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'span';