fix(BOOK-436): Added new section component and deprecated the other

Approved-by: Chuma Mcphoy (We Ahead)
This commit is contained in:
Erik Tiekstra
2025-10-13 08:31:26 +00:00
parent 7bd75f01e4
commit 339e7195dc
34 changed files with 245 additions and 177 deletions

View File

@@ -5,7 +5,7 @@ import { TrackingSDK } from "@scandic-hotels/tracking/TrackingSDK"
import { serverClient } from "@/lib/trpc/server"
import Blocks from "@/components/Blocks"
import SectionHeader from "@/components/Section/Header"
import SectionHeader from "@/components/Section/Header/Deprecated"
import { getIntl } from "@/i18n"
import styles from "./page.module.css"

View File

@@ -6,8 +6,8 @@ import Accordion from "@scandic-hotels/design-system/Accordion"
import AccordionItem from "@scandic-hotels/design-system/Accordion/AccordionItem"
import { JsonToHtml } from "@scandic-hotels/design-system/JsonToHtml"
import SectionContainer from "@/components/Section/Container"
import SectionHeader from "@/components/Section/Header"
import { Section } from "@/components/Section"
import SectionHeader from "@/components/Section/Header/Deprecated"
import ShowMoreButton from "@/components/TempDesignSystem/ShowMoreButton"
import styles from "./accordion.module.css"
@@ -25,10 +25,7 @@ export default function AccordionSection({ accordion, title }: AccordionProps) {
}
return (
<SectionContainer
className={styles.accordionSection}
id={HotelHashValues.faq}
>
<Section className={styles.accordionSection} id={HotelHashValues.faq}>
<SectionHeader textTransform="uppercase" title={title} />
<Accordion
className={`${styles.accordion} ${allAccordionsVisible ? styles.allVisible : ""}`}
@@ -51,6 +48,6 @@ export default function AccordionSection({ accordion, title }: AccordionProps) {
showLess={allAccordionsVisible}
/>
) : null}
</SectionContainer>
</Section>
)
}

View File

@@ -4,8 +4,8 @@ import { useState } from "react"
import { Carousel } from "@/components/Carousel"
import ContentCard from "@/components/ContentCard"
import SectionContainer from "@/components/Section/Container"
import SectionHeader from "@/components/Section/Header"
import { Section } from "@/components/Section"
import SectionHeader from "@/components/Section/Header/Deprecated"
import SectionLink from "@/components/Section/Link"
import TabFilters from "@/components/TabFilters"
@@ -21,7 +21,7 @@ export default function CardGallery({ card_gallery }: CardGalleryProps) {
const filteredCards = cards.filter((card) => card.filterId === activeFilter)
return (
<SectionContainer>
<Section>
<SectionHeader title={heading} link={link} />
{filterCategories.length > 0 && activeFilter && (
<TabFilters
@@ -62,6 +62,6 @@ export default function CardGallery({ card_gallery }: CardGalleryProps) {
<Carousel.Dots />
</Carousel>
<SectionLink link={link} variant="mobile" />
</SectionContainer>
</Section>
)
}

View File

@@ -4,8 +4,8 @@ import {
} from "@scandic-hotels/trpc/types/cardsGridEnum"
import InfoCard from "@/components/ContentType/StartPage/InfoCard"
import SectionContainer from "@/components/Section/Container"
import SectionHeader from "@/components/Section/Header"
import { Section } from "@/components/Section"
import SectionHeader from "@/components/Section/Header/Deprecated"
import Card from "@/components/TempDesignSystem/Card"
import Grids from "@/components/TempDesignSystem/Grids"
import LoyaltyCard from "@/components/TempDesignSystem/LoyaltyCard"
@@ -32,7 +32,7 @@ export default function CardsGrid({ cards_grid }: CardsGridProps) {
}
return (
<SectionContainer>
<Section>
<SectionHeader
title={cards_grid.title}
preamble={cards_grid.preamble}
@@ -99,6 +99,6 @@ export default function CardsGrid({ cards_grid }: CardsGridProps) {
}
})}
</Grids.Stackable>
</SectionContainer>
</Section>
)
}

View File

@@ -4,8 +4,8 @@ import { useState } from "react"
import { Carousel } from "@/components/Carousel"
import ContentCard from "@/components/ContentCard"
import SectionContainer from "@/components/Section/Container"
import SectionHeader from "@/components/Section/Header"
import { Section } from "@/components/Section"
import SectionHeader from "@/components/Section/Header/Deprecated"
import SectionLink from "@/components/Section/Link"
import TabFilters from "@/components/TabFilters"
@@ -35,7 +35,7 @@ export default function CarouselCards({ carousel_cards }: CarouselCardsProps) {
)
return (
<SectionContainer>
<Section>
<SectionHeader
title={heading}
preamble={preamble}
@@ -69,6 +69,6 @@ export default function CarouselCards({ carousel_cards }: CarouselCardsProps) {
<Carousel.Dots />
</Carousel>
<SectionLink link={link} variant="mobile" />
</SectionContainer>
</Section>
)
}

View File

@@ -1,7 +1,7 @@
import { getJobylonFeed } from "@/lib/trpc/memoizedRequests"
import SectionContainer from "@/components/Section/Container"
import SectionHeader from "@/components/Section/Header"
import { Section } from "@/components/Section"
import SectionHeader from "@/components/Section/Header/Deprecated"
import SectionLink from "@/components/Section/Link"
import JobList from "./JobList"
@@ -24,7 +24,7 @@ export default async function JobylonFeed({
}
return (
<SectionContainer>
<Section>
<SectionHeader
link={link}
preamble={subtitle}
@@ -34,6 +34,6 @@ export default async function JobylonFeed({
/>
<JobList allJobs={allJobs} />
<SectionLink link={link} variant="mobile" />
</SectionContainer>
</Section>
)
}

View File

@@ -1,6 +1,6 @@
import { CookieConsentButton } from "@/components/Blocks/DynamicContent/ManageCookieConsent/CookieConsentButton"
import SectionContainer from "@/components/Section/Container"
import SectionHeader from "@/components/Section/Header"
import { Section } from "@/components/Section"
import { SectionHeader } from "@/components/Section/Header"
import SectionLink from "@/components/Section/Link"
interface ManageCookieConsentProps {
@@ -15,16 +15,15 @@ export function ManageCookieConsent({
link,
}: ManageCookieConsentProps) {
return (
<SectionContainer>
<Section>
<SectionHeader
link={link}
preamble={subtitle}
title={title}
headingAs="h3"
headingLevel="h2"
heading={title}
typography="Title/sm"
/>
<CookieConsentButton />
<SectionLink link={link} variant="mobile" />
</SectionContainer>
{link ? <SectionLink link={link} variant="mobile" /> : null}
</Section>
)
}

View File

@@ -2,8 +2,8 @@ import * as webHrefs from "@/constants/webHrefs"
import { serverClient } from "@/lib/trpc/server"
import ShortcutsListItems from "@/components/Blocks/ShortcutsList/ShortcutsListItems"
import SectionContainer from "@/components/Section/Container"
import SectionHeader from "@/components/Section/Header"
import { Section } from "@/components/Section"
import SectionHeader from "@/components/Section/Header/Deprecated"
import { getIntl } from "@/i18n"
import { getLang } from "@/i18n/serverContext"
@@ -99,35 +99,33 @@ export default async function MyPagesOverviewShortcuts() {
const scandicFriendsShortcuts = buildFriendsShortcuts(navigation)
return (
<SectionContainer>
<section className={styles.section}>
<div className={styles.column}>
<SectionHeader
title={intl.formatMessage({
defaultMessage: "Your Membership",
})}
headingAs="h4"
headingLevel="h3"
/>
<ShortcutsListItems
shortcutsListItems={membershipShortcuts}
className={styles.shortcuts}
/>
</div>
<div className={styles.column}>
<SectionHeader
title={intl.formatMessage({
defaultMessage: "Scandic Friends Links",
})}
headingAs="h4"
headingLevel="h3"
/>
<ShortcutsListItems
shortcutsListItems={scandicFriendsShortcuts}
className={styles.shortcuts}
/>
</div>
</section>
</SectionContainer>
<Section className={styles.section}>
<div className={styles.column}>
<SectionHeader
title={intl.formatMessage({
defaultMessage: "Your Membership",
})}
headingAs="h4"
headingLevel="h3"
/>
<ShortcutsListItems
shortcutsListItems={membershipShortcuts}
className={styles.shortcuts}
/>
</div>
<div className={styles.column}>
<SectionHeader
title={intl.formatMessage({
defaultMessage: "Scandic Friends Links",
})}
headingAs="h4"
headingLevel="h3"
/>
<ShortcutsListItems
shortcutsListItems={scandicFriendsShortcuts}
className={styles.shortcuts}
/>
</div>
</Section>
)
}

View File

@@ -8,8 +8,8 @@ import { TeamMemberCardTrigger } from "@/components/DigitalTeamMemberCard/Trigge
import DigitalTeamMemberCard from "@/components/MyPages/DigitalTeamMemberCard"
import DigitalTeamMemberCardAlert from "@/components/MyPages/DigitalTeamMemberCard/Alert"
import LevelProgressCard from "@/components/MyPages/LevelProgressCard"
import SectionContainer from "@/components/Section/Container"
import SectionHeader from "@/components/Section/Header"
import { Section } from "@/components/Section"
import SectionHeader from "@/components/Section/Header/Deprecated"
import SectionLink from "@/components/Section/Link"
import { getIntl } from "@/i18n"
@@ -36,7 +36,7 @@ export default async function Overview({
}
return (
<SectionContainer>
<Section>
{env.ENABLE_DTMC ? <DigitalTeamMemberCardAlert /> : null}
<SectionHeader
link={link}
@@ -79,6 +79,6 @@ export default async function Overview({
)}
<SectionLink link={link} variant="mobile" />
</SectionContainer>
</Section>
)
}

View File

@@ -1,5 +1,5 @@
import SectionContainer from "@/components/Section/Container"
import SectionHeader from "@/components/Section/Header"
import { Section } from "@/components/Section"
import SectionHeader from "@/components/Section/Header/Deprecated"
import SectionLink from "@/components/Section/Link"
import ClaimPoints from "../ClaimPoints"
@@ -15,7 +15,7 @@ export default function EarnAndBurn({
title,
}: AccountPageComponentProps) {
return (
<SectionContainer>
<Section>
<div className={styles.header}>
<SectionHeader title={title} link={link} preamble={subtitle} />
@@ -23,6 +23,6 @@ export default function EarnAndBurn({
</div>
<JourneyTable />
<SectionLink link={link} variant="mobile" />
</SectionContainer>
</Section>
)
}

View File

@@ -1,7 +1,7 @@
import { getMembershipLevel } from "@/lib/trpc/memoizedRequests"
import SectionContainer from "@/components/Section/Container"
import SectionHeader from "@/components/Section/Header"
import { Section } from "@/components/Section"
import SectionHeader from "@/components/Section/Header/Deprecated"
import ExpiringPointsTable from "./ExpiringPointsTable"
@@ -19,12 +19,12 @@ export default async function ExpiringPoints({
}
return (
<SectionContainer>
<Section>
<SectionHeader title={title} link={link} preamble={subtitle} />
<ExpiringPointsTable
points={membershipLevel.pointsToExpire}
expirationDate={membershipLevel.pointsExpiryDate}
/>
</SectionContainer>
</Section>
)
}

View File

@@ -4,8 +4,8 @@ import { env } from "@/env/server"
import { getProfile } from "@/lib/trpc/memoizedRequests"
import LevelProgressCard from "@/components/MyPages/LevelProgressCard"
import SectionContainer from "@/components/Section/Container"
import SectionHeader from "@/components/Section/Header"
import { Section } from "@/components/Section"
import SectionHeader from "@/components/Section/Header/Deprecated"
import SectionLink from "@/components/Section/Link"
import Friend from "../../Overview/Friend"
@@ -29,7 +29,7 @@ export default async function PointsOverview({
}
return (
<SectionContainer>
<Section>
<SectionHeader
link={link}
preamble={subtitle}
@@ -55,6 +55,6 @@ export default async function PointsOverview({
</Hero>
)}
<SectionLink link={link} variant="mobile" />
</SectionContainer>
</Section>
)
}

View File

@@ -4,8 +4,8 @@ import {
getMembershipLevel,
} from "@/lib/trpc/memoizedRequests"
import SectionContainer from "@/components/Section/Container"
import SectionHeader from "@/components/Section/Header"
import { Section } from "@/components/Section"
import SectionHeader from "@/components/Section/Header/Deprecated"
import SectionLink from "@/components/Section/Link"
import ClientCurrentRewards from "./Client"
@@ -27,7 +27,7 @@ export default async function CurrentRewardsBlock({
}
return (
<SectionContainer>
<Section>
<SectionHeader title={title} link={link} preamble={subtitle} />
<ClientCurrentRewards
rewards={rewardsResponse.rewards}
@@ -35,6 +35,6 @@ export default async function CurrentRewardsBlock({
membershipNumber={membershipLevel?.membershipNumber}
/>
<SectionLink link={link} variant="mobile" />
</SectionContainer>
</Section>
)
}

View File

@@ -8,8 +8,8 @@ import Title from "@scandic-hotels/design-system/Title"
import { getMembershipLevel } from "@/lib/trpc/memoizedRequests"
import { serverClient } from "@/lib/trpc/server"
import SectionContainer from "@/components/Section/Container"
import SectionHeader from "@/components/Section/Header"
import { Section } from "@/components/Section"
import SectionHeader from "@/components/Section/Header/Deprecated"
import SectionLink from "@/components/Section/Link"
import Grids from "@/components/TempDesignSystem/Grids"
import { getIntl } from "@/i18n"
@@ -42,7 +42,7 @@ export default async function NextLevelRewardsBlock({
}
return (
<SectionContainer>
<Section>
<SectionHeader title={title} preamble={subtitle} link={link} />
<Grids.Stackable columns={2}>
{nextLevelRewards.rewards.map((reward) => (
@@ -70,6 +70,6 @@ export default async function NextLevelRewardsBlock({
))}
</Grids.Stackable>
<SectionLink link={link} variant="mobile" />
</SectionContainer>
</Section>
)
}

View File

@@ -13,8 +13,8 @@ import {
} from "@/constants/membershipLevels"
import { getProfileWithExtendedPartnerData } from "@/lib/trpc/memoizedRequests"
import SectionContainer from "@/components/Section/Container"
import SectionHeader from "@/components/Section/Header"
import { Section } from "@/components/Section"
import SectionHeader from "@/components/Section/Header/Deprecated"
import SectionLink from "@/components/Section/Link"
import { getIntl } from "@/i18n"
import { getSasTierExpirationDate } from "@/utils/sas"
@@ -40,13 +40,13 @@ export default async function SASLinkedAccount({
return (
<div className={styles.container}>
<SectionContainer>
<Section>
<SectionHeader link={link} preamble={subtitle} title={title} />
<SectionLink link={link} variant="mobile" />
<Suspense fallback={<MatchedAccountInfoSkeleton />}>
<MatchedAccountInfo />
</Suspense>
</SectionContainer>
</Section>
<div className={styles.mutationSection}>
<Typography variant="Body/Supporting text (caption)/smRegular">
<p className={styles.caption}>

View File

@@ -2,8 +2,8 @@ import { Suspense } from "react"
import { env } from "@/env/server"
import SectionContainer from "@/components/Section/Container"
import SectionHeader from "@/components/Section/Header"
import { Section } from "@/components/Section"
import SectionHeader from "@/components/Section/Header/Deprecated"
import SectionLink from "@/components/Section/Link"
import { getLang } from "@/i18n/serverContext"
@@ -30,12 +30,12 @@ export default async function SASTransferPoints({
const lang = await getLang()
return (
<SectionContainer>
<Section>
<SectionHeader link={link} preamble={subtitle} title={title} />
<SectionLink link={link} variant="mobile" />
<Suspense fallback={<TransferPointsFormSkeleton lang={lang} />}>
<TransferPointsForm lang={lang} />
</Suspense>
</SectionContainer>
</Section>
)
}

View File

@@ -1,5 +1,5 @@
import SectionContainer from "@/components/Section/Container"
import SectionHeader from "@/components/Section/Header"
import { Section } from "@/components/Section"
import SectionHeader from "@/components/Section/Header/Deprecated"
import SectionLink from "@/components/Section/Link"
import type { DynamicContentProps } from "@/types/components/blocks/dynamicContent"
@@ -14,7 +14,7 @@ export default function SectionWrapper({
dynamic_content.title
)
return (
<SectionContainer>
<Section>
{displayHeader ? (
<SectionHeader
link={dynamic_content.link}
@@ -28,6 +28,6 @@ export default function SectionWrapper({
{dynamic_content.link ? (
<SectionLink link={dynamic_content.link} variant="mobile" />
) : null}
</SectionContainer>
</Section>
)
}

View File

@@ -1,8 +1,8 @@
import { serverClient } from "@/lib/trpc/server"
import ClaimPoints from "@/components/Blocks/DynamicContent/Points/ClaimPoints"
import SectionContainer from "@/components/Section/Container"
import SectionHeader from "@/components/Section/Header"
import { Section } from "@/components/Section"
import SectionHeader from "@/components/Section/Header/Deprecated"
import SectionLink from "@/components/Section/Link"
import ClientPreviousStays from "./Client"
@@ -25,7 +25,7 @@ export default async function PreviousStays({
}
return (
<SectionContainer>
<Section>
<div className={styles.header}>
<SectionHeader title={title} link={link} />
@@ -33,6 +33,6 @@ export default async function PreviousStays({
</div>
<ClientPreviousStays initialPreviousStays={initialPreviousStays} />
<SectionLink link={link} variant="mobile" />
</SectionContainer>
</Section>
)
}

View File

@@ -1,7 +1,7 @@
import { serverClient } from "@/lib/trpc/server"
import SectionContainer from "@/components/Section/Container"
import SectionHeader from "@/components/Section/Header"
import { Section } from "@/components/Section"
import SectionHeader from "@/components/Section/Header/Deprecated"
import SectionLink from "@/components/Section/Link"
import EmptyUpcomingStaysBlock from "../EmptyUpcomingStays"
@@ -21,7 +21,7 @@ export default async function UpcomingStays({
})
return (
<SectionContainer className={styles.container}>
<Section className={styles.container}>
<SectionHeader title={title} link={link} />
{initialUpcomingStays?.data.length ? (
<ClientUpcomingStays initialUpcomingStays={initialUpcomingStays} />
@@ -29,6 +29,6 @@ export default async function UpcomingStays({
<EmptyUpcomingStaysBlock />
)}
<SectionLink link={link} variant="mobile" />
</SectionContainer>
</Section>
)
}

View File

@@ -2,7 +2,7 @@ import { Typography } from "@scandic-hotels/design-system/Typography"
import { getHotelsByCSFilter } from "@/lib/trpc/memoizedRequests"
import SectionContainer from "@/components/Section/Container"
import { Section } from "@/components/Section"
import HotelListingItem from "./HotelListingItem"
@@ -26,7 +26,7 @@ export default async function HotelListing({
}
return (
<SectionContainer>
<Section>
<Typography variant="Title/sm">
<h3 className={styles.heading}>{heading}</h3>
</Typography>
@@ -37,6 +37,6 @@ export default async function HotelListing({
contentType={contentType}
/>
))}
</SectionContainer>
</Section>
)
}

View File

@@ -1,5 +1,5 @@
import SectionContainer from "@/components/Section/Container"
import SectionHeader from "@/components/Section/Header"
import { Section } from "@/components/Section"
import SectionHeader from "@/components/Section/Header/Deprecated"
import ShortcutsListItems from "./ShortcutsListItems"
@@ -34,7 +34,7 @@ export default function ShortcutsList({
]
return (
<SectionContainer>
<Section>
<SectionHeader
preamble={subtitle}
title={title}
@@ -50,6 +50,6 @@ export default function ShortcutsList({
/>
))}
</section>
</SectionContainer>
</Section>
)
}

View File

@@ -10,8 +10,8 @@ import { useState } from "react"
import Table from "@scandic-hotels/design-system/Table"
import SectionContainer from "@/components/Section/Container"
import SectionHeader from "@/components/Section/Header"
import { Section } from "@/components/Section"
import SectionHeader from "@/components/Section/Header/Deprecated"
import ShowMoreButton from "@/components/TempDesignSystem/ShowMoreButton"
import styles from "./table.module.css"
@@ -53,7 +53,7 @@ export default function TableBlock({ data }: TableBlockProps) {
}
return (
<SectionContainer>
<Section>
<SectionHeader preamble={preamble} title={heading} />
<div className={styles.tableWrapper}>
<Table
@@ -103,6 +103,6 @@ export default function TableBlock({ data }: TableBlockProps) {
/>
) : null}
</div>
</SectionContainer>
</Section>
)
}

View File

@@ -5,7 +5,7 @@ import { useMemo, useRef, useState } from "react"
import { Typography } from "@scandic-hotels/design-system/Typography"
import SectionContainer from "@/components/Section/Container"
import { Section } from "@/components/Section"
import ShowMoreButton from "@/components/TempDesignSystem/ShowMoreButton"
import { RoomCard } from "./RoomCard"
@@ -32,10 +32,7 @@ export function Rooms({ heading, rooms, preamble }: RoomsProps) {
}
return (
<SectionContainer
id={HotelHashValues.rooms}
className={styles.roomsContainer}
>
<Section id={HotelHashValues.rooms} className={styles.roomsContainer}>
<div ref={scrollRef} className={styles.scrollRef}></div>
<header className={styles.sectionHeader}>
<Typography variant="Title/md">
@@ -65,6 +62,6 @@ export function Rooms({ heading, rooms, preamble }: RoomsProps) {
showLess={allRoomsVisible}
/>
) : null}
</SectionContainer>
</Section>
)
}

View File

@@ -10,7 +10,7 @@ import { OldDSButton as Button } from "@scandic-hotels/design-system/OldDSButton
import Subtitle from "@scandic-hotels/design-system/Subtitle"
import Title from "@scandic-hotels/design-system/Title"
import SectionContainer from "../Section/Container"
import { Section } from "@/components/Section"
import styles from "./sasTierComparison.module.css"
@@ -30,7 +30,7 @@ export function SasTierComparison({
tierComparison,
}: TierComparisonProps) {
return (
<SectionContainer className={styles.comparisonSection}>
<Section className={styles.comparisonSection}>
<div className={styles.header}>
<Title level="h2" textAlign="center">
{title}
@@ -77,7 +77,7 @@ export function SasTierComparison({
</Link>
</Button>
)}
</SectionContainer>
</Section>
)
}

View File

@@ -1,5 +0,0 @@
.container {
display: grid;
gap: var(--Spacing-x3);
z-index: 0;
}

View File

@@ -1,13 +0,0 @@
import styles from "./container.module.css"
export default function SectionContainer({
children,
className = "",
...props
}: React.HTMLAttributes<HTMLElement>) {
return (
<section {...props} className={`${styles.container} ${className}`}>
{children}
</section>
)
}

View File

@@ -0,0 +1,48 @@
import Preamble from "@scandic-hotels/design-system/Preamble"
import Title, { type HeadingProps } from "@scandic-hotels/design-system/Title"
import SectionLink from "../Link"
import styles from "./header.module.css"
type HeaderProps = {
link?: {
href: string
text: string
}
preamble?: string | null
textTransform?: HeadingProps["textTransform"]
title?: string | null
headingLevel?: HeadingProps["level"]
headingAs?: HeadingProps["as"]
}
/**
* @deprecated Use `@/components/Section/Header` instead.
*/
export default function SectionHeader({
link,
preamble,
title,
textTransform,
headingAs = "h4",
headingLevel = "h2",
}: HeaderProps) {
if (!title && !preamble && !link) {
return null
}
return (
<header className={styles.header}>
<Title
as={headingAs}
className={styles.title}
level={headingLevel}
textTransform={textTransform}
>
{title}
</Title>
{preamble && <Preamble className={styles.preamble}>{preamble}</Preamble>}
<SectionLink link={link} variant="desktop" />
</header>
)
}

View File

@@ -1,11 +1,15 @@
.header {
display: grid;
gap: var(--Spacing-x1) var(--Spacing-x5);
gap: var(--Space-x1) var(--Space-x5);
grid-template-columns: 1fr;
align-items: baseline;
}
.title,
.heading {
color: var(--Text-Heading);
}
.heading,
.preamble {
grid-column: 1 / -1;
max-width: var(--max-width-text-block);
@@ -16,7 +20,7 @@
grid-template-columns: 1fr auto;
}
.title {
.heading {
grid-column: 1 / 2;
}

View File

@@ -0,0 +1,7 @@
import { cva } from "class-variance-authority"
import { withTypography } from "@scandic-hotels/design-system/Typography"
import styles from "./header.module.css"
export const headingVariants = cva(styles.heading, withTypography({}))

View File

@@ -1,46 +1,54 @@
import Preamble from "@scandic-hotels/design-system/Preamble"
import Title, { type HeadingProps } from "@scandic-hotels/design-system/Title"
import { cx, type VariantProps } from "class-variance-authority"
import { Typography } from "@scandic-hotels/design-system/Typography"
import { headingVariants } from "@/components/Section/Header/headingVariants"
import SectionLink from "../Link"
import styles from "./header.module.css"
type HeaderProps = {
import type { HTMLAttributes } from "react"
interface SectionHeaderProps
extends HTMLAttributes<HTMLElement>,
VariantProps<typeof headingVariants> {
heading?: string
headingLevel?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6"
preamble?: string
link?: {
href: string
text: string
}
preamble?: string | null
textTransform?: HeadingProps["textTransform"]
title?: string | null
headingLevel?: HeadingProps["level"]
headingAs?: HeadingProps["as"]
}
export default function SectionHeader({
link,
export function SectionHeader({
className,
heading,
preamble,
title,
textTransform,
headingAs = "h4",
link,
typography = "Title/sm",
headingLevel = "h2",
}: HeaderProps) {
if (!title && !preamble && !link) {
...props
}: SectionHeaderProps) {
if (!heading && !preamble && !link) {
return null
}
const headingClassNames = headingVariants({ typography })
const Hx = headingLevel
return (
<header className={styles.header}>
<Title
as={headingAs}
className={styles.title}
level={headingLevel}
textTransform={textTransform}
>
{title}
</Title>
{preamble && <Preamble className={styles.preamble}>{preamble}</Preamble>}
<SectionLink link={link} variant="desktop" />
<header className={cx(styles.header, className)} {...props}>
<Hx className={headingClassNames}>{heading}</Hx>
{preamble ? (
<Typography
variant="Body/Paragraph/mdRegular"
className={styles.preamble}
>
<p>{preamble}</p>
</Typography>
) : null}
{link ? <SectionLink link={link} variant="desktop" /> : null}
</header>
)
}

View File

@@ -5,7 +5,13 @@ import { linkVariants } from "./variants"
import styles from "./link.module.css"
import type { SectionLinkProps } from "./link"
import type { VariantProps } from "class-variance-authority"
interface SectionLinkProps
extends React.PropsWithChildren<React.HTMLAttributes<HTMLSpanElement>>,
VariantProps<typeof linkVariants> {
link?: { href: string; text: string }
}
export default function SectionLink({ link, variant }: SectionLinkProps) {
if (!link) {

View File

@@ -0,0 +1,15 @@
import { cx } from "class-variance-authority"
import styles from "./section.module.css"
export function Section({
children,
className,
...props
}: React.PropsWithChildren<React.HTMLAttributes<HTMLElement>>) {
return (
<section {...props} className={cx(styles.section, className)}>
{children}
</section>
)
}

View File

@@ -0,0 +1,5 @@
.section {
display: grid;
gap: var(--Space-x3);
z-index: 0;
}

View File

@@ -44,7 +44,9 @@ const typographyConfig = {
variants: {
typography: config.variants.variant,
},
defaultVariants: config.defaultVariants,
defaultVariants: {
typography: config.defaultVariants.variant,
},
} as const
export function withTypography<T>(config: T) {