Merged in chore/BOOK-708-replace-title-component (pull request #3414)

Chore/BOOK-708 replace title component

* chore(BOOK-708): replace title with typography

* chore(BOOK-708): replace title with typography

* chore(BOOK-708): remove Title from package.json


Approved-by: Linus Flood
Approved-by: Anton Gunnarsson
This commit is contained in:
Bianca Widstam
2026-01-12 07:54:59 +00:00
parent 1b9273136a
commit 68c1b3dc50
58 changed files with 242 additions and 552 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/Deprecated"
import { SectionHeader } from "@/components/Section/Header"
import { getIntl } from "@/i18n"
import styles from "./page.module.css"
@@ -46,9 +46,8 @@ export default async function MyPages() {
</header>
) : (
<SectionHeader
title={heading}
heading={heading}
preamble={preamble}
headingAs="h1"
headingLevel="h1"
/>
)}

View File

@@ -5,7 +5,7 @@ import { useState } from "react"
import { Carousel } from "@/components/Carousel"
import { ContentCard } from "@/components/ContentCard"
import { Section } from "@/components/Section"
import SectionHeader from "@/components/Section/Header/Deprecated"
import { SectionHeader } from "@/components/Section/Header"
import SectionLink from "@/components/Section/Link"
import TabFilters from "@/components/TabFilters"
@@ -22,7 +22,7 @@ export default function CardGallery({ card_gallery }: CardGalleryProps) {
return (
<Section>
<SectionHeader title={heading} link={link} />
<SectionHeader heading={heading} link={link} />
{filterCategories.length > 0 && activeFilter && (
<TabFilters
categories={filterCategories}

View File

@@ -7,3 +7,7 @@
justify-content: center;
width: 100%;
}
.title {
color: var(--Text-Heading);
}

View File

@@ -1,4 +1,4 @@
import Title from "@scandic-hotels/design-system/Title"
import { Typography } from "@scandic-hotels/design-system/Typography"
import { getIntl } from "@/i18n"
@@ -13,12 +13,14 @@ export default async function HowItWorks({ dynamic_content }: HowItWorksProps) {
return (
<SectionWrapper dynamic_content={dynamic_content}>
<section className={styles.container}>
<Title level="h3">
{intl.formatMessage({
id: "common.howItWorks",
defaultMessage: "How it works",
})}
</Title>
<Typography variant="Title/sm" className={styles.title}>
<h3>
{intl.formatMessage({
id: "common.howItWorks",
defaultMessage: "How it works",
})}
</h3>
</Typography>
</section>
</SectionWrapper>
)

View File

@@ -1,7 +1,7 @@
import { getJobylonFeed } from "@/lib/trpc/memoizedRequests"
import { Section } from "@/components/Section"
import SectionHeader from "@/components/Section/Header/Deprecated"
import { SectionHeader } from "@/components/Section/Header"
import SectionLink from "@/components/Section/Link"
import JobList from "./JobList"
@@ -28,8 +28,7 @@ export default async function JobylonFeed({
<SectionHeader
link={link}
preamble={subtitle}
title={title}
headingAs="h3"
heading={title}
headingLevel="h2"
/>
<JobList allJobs={allJobs} />

View File

@@ -1,6 +1,6 @@
import Caption from "@scandic-hotels/design-system/Caption"
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
import Title from "@scandic-hotels/design-system/Title"
import { Typography } from "@scandic-hotels/design-system/Typography"
import { serverClient } from "@/lib/trpc/server"
@@ -78,9 +78,9 @@ async function LevelCard({ level }: LevelCardProps) {
</BiroScript>
<MembershipLevelIcon level={level.level_id} color="red" />
</header>
<Title textAlign="center" level="h5">
{pointsMsg}
</Title>
<Typography variant="Title/xs" className={styles.pointMsg}>
<h5>{pointsMsg}</h5>
</Typography>
<div className={styles.textContainer}>
{level.rewards.map((reward) => (
<Caption

View File

@@ -3,6 +3,11 @@
gap: var(--Space-x2);
}
.pointMsg {
text-align: center;
color: var(--Text-Heading);
}
.link {
justify-self: center;
}

View File

@@ -3,7 +3,7 @@ import { serverClient } from "@/lib/trpc/server"
import ShortcutsListItems from "@/components/Blocks/ShortcutsList/ShortcutsListItems"
import { Section } from "@/components/Section"
import SectionHeader from "@/components/Section/Header/Deprecated"
import { SectionHeader } from "@/components/Section/Header"
import { getIntl } from "@/i18n"
import { getLang } from "@/i18n/serverContext"
@@ -126,7 +126,6 @@ export default async function MyPagesOverviewShortcuts() {
id: "myPagesOverviewShortcuts.yourMembership",
defaultMessage: "Your membership",
})}
headingAs="h4"
headingLevel="h3"
/>
<ShortcutsListItems
@@ -140,7 +139,6 @@ export default async function MyPagesOverviewShortcuts() {
id: "myPagesOverviewShortcuts.scandicFriendsLinks",
defaultMessage: "Scandic Friends Links",
})}
headingAs="h4"
headingLevel="h3"
/>
<ShortcutsListItems

View File

@@ -1,6 +1,6 @@
import { ChevronDown } from "react-feather"
import Title from "@scandic-hotels/design-system/Title"
import { Typography } from "@scandic-hotels/design-system/Typography"
import {
findAvailableRewards,
@@ -71,9 +71,12 @@ function RewardTableHeader({ name, description }: RewardTableHeaderProps) {
<details className={styles.details}>
<summary className={styles.summary}>
<hgroup className={styles.rewardHeader}>
<Title as="h4" level="h2" textTransform="regular">
{name}
</Title>
<Typography
variant="Title/Subtitle/md"
className={styles.rewardTitle}
>
<h2>{name}</h2>
</Typography>
<span className={styles.chevron}>
<ChevronDown />
</span>

View File

@@ -43,6 +43,9 @@
padding-right: calc(var(--Space-x3) + var(--Space-x1));
}
.rewardTitle {
color: var(--Text-Heading);
}
.chevron {
display: flex;
align-self: start;

View File

@@ -1,6 +1,6 @@
import { ChevronDown } from "react-feather"
import Title from "@scandic-hotels/design-system/Title"
import { Typography } from "@scandic-hotels/design-system/Typography"
import RewardValue from "../../RewardValue"
@@ -19,9 +19,9 @@ export default function RewardCard({
<details className={styles.details}>
<summary className={styles.summary}>
<hgroup className={styles.rewardCardHeader}>
<Title as="h4" level="h2" textTransform="regular">
{title}
</Title>
<Typography variant="Title/Subtitle/md" className={styles.title}>
<h2>{title}</h2>
</Typography>
<span className={styles.chevron}>
<ChevronDown />
</span>

View File

@@ -3,6 +3,9 @@
grid-column: 1/3;
}
.title {
color: var(--Text-Heading);
}
.rewardCardHeader {
display: grid;
grid-template-columns: 1fr auto;

View File

@@ -1,5 +1,5 @@
import { Section } from "@/components/Section"
import SectionHeader from "@/components/Section/Header/Deprecated"
import { SectionHeader } from "@/components/Section/Header"
import SectionLink from "@/components/Section/Link"
import ClaimPoints from "../ClaimPoints"
@@ -17,7 +17,7 @@ export default function EarnAndBurn({
return (
<Section>
<div className={styles.header}>
<SectionHeader title={title} link={link} preamble={subtitle} />
<SectionHeader heading={title} link={link} preamble={subtitle} />
<ClaimPoints />
</div>

View File

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

View File

@@ -2,7 +2,7 @@ import { getProfile } from "@/lib/trpc/memoizedRequests"
import LevelProgressCard from "@/components/MyPages/LevelProgressCard"
import { Section } from "@/components/Section"
import SectionHeader from "@/components/Section/Header/Deprecated"
import { SectionHeader } from "@/components/Section/Header"
import SectionLink from "@/components/Section/Link"
import PointsToSpendCard from "../PointsToSpendCard"
@@ -26,8 +26,7 @@ export default async function PointsOverview({
<SectionHeader
link={link}
preamble={subtitle}
title={title}
headingAs="h3"
heading={title}
headingLevel="h1"
/>
<div className={styles.membershipCardsContainer}>

View File

@@ -4,7 +4,7 @@ import {
} from "@/lib/trpc/memoizedRequests"
import { Section } from "@/components/Section"
import SectionHeader from "@/components/Section/Header/Deprecated"
import { SectionHeader } from "@/components/Section/Header"
import SectionLink from "@/components/Section/Link"
import ClientCurrentRewards from "./Client"
@@ -27,7 +27,7 @@ export default async function CurrentRewardsBlock({
return (
<Section>
<SectionHeader title={title} link={link} preamble={subtitle} />
<SectionHeader heading={title} link={link} preamble={subtitle} />
<ClientCurrentRewards
rewards={rewardsResponse.rewards}
showRedeem={true}

View File

@@ -8,7 +8,7 @@ import { getMembershipLevel } from "@/lib/trpc/memoizedRequests"
import { serverClient } from "@/lib/trpc/server"
import { Section } from "@/components/Section"
import SectionHeader from "@/components/Section/Header/Deprecated"
import { SectionHeader } from "@/components/Section/Header"
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 (
<Section>
<SectionHeader title={title} preamble={subtitle} link={link} />
<SectionHeader heading={title} preamble={subtitle} link={link} />
<Grids.Stackable columns={2}>
{nextLevelRewards.rewards.map((reward) => (
<article key={reward.reward_id} className={styles.card}>

View File

@@ -1,7 +1,6 @@
import { useIntl } from "react-intl"
import { OldDSButton as Button } from "@scandic-hotels/design-system/OldDSButton"
import Title from "@scandic-hotels/design-system/Title"
import { Typography } from "@scandic-hotels/design-system/Typography"
import useRedeemFlow from "./useRedeemFlow"
@@ -15,12 +14,14 @@ export function ConfirmClose({ close }: { close: () => void }) {
return (
<>
<div className={styles.modalContent}>
<Title level="h3" textAlign="center" textTransform="regular">
{intl.formatMessage({
id: "redeem.confirmClose.title",
defaultMessage: "If you close this your benefit will be removed",
})}
</Title>
<Typography variant="Title/smLowCase" className={styles.rewardLabel}>
<h3>
{intl.formatMessage({
id: "redeem.confirmClose.title",
defaultMessage: "If you close this your benefit will be removed",
})}
</h3>
</Typography>
<Typography variant="Body/Paragraph/mdRegular">
<p>
{intl.formatMessage({

View File

@@ -5,7 +5,6 @@ import { useIntl } from "react-intl"
import Caption from "@scandic-hotels/design-system/Caption"
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
import { OldDSButton as Button } from "@scandic-hotels/design-system/OldDSButton"
import Title from "@scandic-hotels/design-system/Title"
import { toast } from "@scandic-hotels/design-system/Toast"
import { Typography } from "@scandic-hotels/design-system/Typography"
@@ -22,9 +21,9 @@ export default function Campaign({ reward }: { reward: Campaign }) {
<>
<div className={styles.modalContent}>
<RewardIcon rewardId={reward.reward_id} />
<Title level="h3" textAlign="center" textTransform="regular">
{reward.label}
</Title>
<Typography variant="Title/smLowCase" className={styles.rewardLabel}>
<h3>{reward.label}</h3>
</Typography>
<Typography
variant="Body/Paragraph/mdRegular"
className={styles.rewardDescription}

View File

@@ -4,7 +4,6 @@ import { useIntl } from "react-intl"
import { JsonToHtml } from "@scandic-hotels/design-system/JsonToHtml"
import { OldDSButton as Button } from "@scandic-hotels/design-system/OldDSButton"
import Title from "@scandic-hotels/design-system/Title"
import { Typography } from "@scandic-hotels/design-system/Typography"
import { isRestaurantOnSiteTierReward } from "@/utils/rewards"
@@ -43,9 +42,9 @@ export default function Tier({
</div>
)}
<RewardIcon rewardId={reward.reward_id} />
<Title level="h3" textAlign="center" textTransform="regular">
{reward.label}
</Title>
<Typography variant="Title/smLowCase" className={styles.rewardLabel}>
<h3>{reward.label}</h3>
</Typography>
{reward.redeemLocation !== "Non-redeemable" && (
<>

View File

@@ -8,6 +8,11 @@
align-items: center;
}
.rewardLabel {
text-align: center;
color: var(--Text-Heading);
}
.redeemed {
display: flex;
justify-content: center;

View File

@@ -17,7 +17,7 @@ import {
import { getProfile } from "@/lib/trpc/memoizedRequests"
import { Section } from "@/components/Section"
import SectionHeader from "@/components/Section/Header/Deprecated"
import { SectionHeader } from "@/components/Section/Header"
import SectionLink from "@/components/Section/Link"
import { getIntl } from "@/i18n"
import { getSasTierExpirationDate } from "@/utils/sas"
@@ -44,7 +44,7 @@ export default async function SASLinkedAccount({
return (
<div className={styles.container}>
<Section>
<SectionHeader link={link} preamble={subtitle} title={title} />
<SectionHeader link={link} preamble={subtitle} heading={title} />
<SectionLink link={link} variant="mobile" />
<Suspense fallback={<MatchedAccountInfoSkeleton />}>
<MatchedAccountInfo />

View File

@@ -1,7 +1,7 @@
import { Suspense } from "react"
import { Section } from "@/components/Section"
import SectionHeader from "@/components/Section/Header/Deprecated"
import { SectionHeader } from "@/components/Section/Header"
import SectionLink from "@/components/Section/Link"
import { getLang } from "@/i18n/serverContext"
@@ -25,7 +25,7 @@ export default async function SASTransferPoints({
return (
<Section>
<SectionHeader link={link} preamble={subtitle} title={title} />
<SectionHeader link={link} preamble={subtitle} heading={title} />
<SectionLink link={link} variant="mobile" />
<Suspense fallback={<TransferPointsFormSkeleton lang={lang} />}>
<TransferPointsForm lang={lang} />

View File

@@ -1,5 +1,5 @@
import { Section } from "@/components/Section"
import SectionHeader from "@/components/Section/Header/Deprecated"
import { SectionHeader } from "@/components/Section/Header"
import SectionLink from "@/components/Section/Link"
import type { DynamicContentProps } from "@/types/components/blocks/dynamicContent"
@@ -19,9 +19,7 @@ export default function SectionWrapper({
<SectionHeader
link={dynamic_content.link}
preamble={dynamic_content.subtitle}
title={dynamic_content.title}
headingAs="h3"
headingLevel="h2"
heading={dynamic_content.title}
/>
) : null}
{children}

View File

@@ -5,7 +5,7 @@ import Caption from "@scandic-hotels/design-system/Caption"
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
import Image from "@scandic-hotels/design-system/Image"
import Link from "@scandic-hotels/design-system/OldDSLink"
import Title from "@scandic-hotels/design-system/Title"
import { Typography } from "@scandic-hotels/design-system/Typography"
import useLang from "@/hooks/useLang"
@@ -54,9 +54,9 @@ function CardContent({ stay }: StayCardProps) {
height={240}
/>
<footer className={styles.footer}>
<Title as="h4" className={styles.hotel} level="h3">
{hotelInformation.hotelName}
</Title>
<Typography variant="Title/xs" className={styles.hotel}>
<h3>{hotelInformation.hotelName}</h3>
</Typography>
<div className={styles.date}>
<MaterialIcon
icon="calendar_month"

View File

@@ -19,6 +19,8 @@
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
color: var(--Text-Accent-Primary);
}
.burgundyTitle {

View File

@@ -1,7 +1,6 @@
import ButtonLink from "@scandic-hotels/design-system/ButtonLink"
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
import Link from "@scandic-hotels/design-system/OldDSLink"
import Title from "@scandic-hotels/design-system/Title"
import { Typography } from "@scandic-hotels/design-system/Typography"
import { env } from "@/env/server"
@@ -21,24 +20,20 @@ export default async function EmptyUpcomingStays() {
return (
<section className={styles.container}>
<div className={styles.titleContainer}>
<Title
as="h4"
level="h3"
color="red"
className={styles.title}
textAlign="center"
>
{intl.formatMessage({
id: "stays.noUpcomingStays",
defaultMessage: "You have no upcoming stays.",
})}
<span className={styles.burgundyTitle}>
<Typography variant="Title/sm" className={styles.title}>
<h3>
{intl.formatMessage({
id: "stays.whereToGoNext",
defaultMessage: "Where should you go next?",
id: "stays.noUpcomingStays",
defaultMessage: "You have no upcoming stays.",
})}
</span>
</Title>
<span className={styles.burgundyTitle}>
{intl.formatMessage({
id: "stays.whereToGoNext",
defaultMessage: "Where should you go next?",
})}
</span>
</h3>
</Typography>
</div>
<Link
href={href}

View File

@@ -1,5 +1,5 @@
import { Section } from "@/components/Section"
import SectionHeader from "@/components/Section/Header/Deprecated"
import { SectionHeader } from "@/components/Section/Header"
import ShortcutsListItems from "./ShortcutsListItems"
@@ -35,12 +35,7 @@ export default function ShortcutsList({
return (
<Section>
<SectionHeader
preamble={subtitle}
title={title}
headingAs="h3"
headingLevel="h2"
/>
<SectionHeader preamble={subtitle} heading={title} headingLevel="h2" />
<section className={styles.section}>
{columns.map(({ id, column }) => (
<ShortcutsListItems

View File

@@ -11,7 +11,7 @@ import { useState } from "react"
import Table from "@scandic-hotels/design-system/Table"
import { Section } from "@/components/Section"
import SectionHeader from "@/components/Section/Header/Deprecated"
import { SectionHeader } from "@/components/Section/Header"
import ShowMoreButton from "@/components/TempDesignSystem/ShowMoreButton"
import styles from "./table.module.css"
@@ -54,7 +54,7 @@ export default function TableBlock({ data }: TableBlockProps) {
return (
<Section>
<SectionHeader preamble={preamble} title={heading} />
<SectionHeader preamble={preamble} heading={heading} />
<div className={styles.tableWrapper}>
<Table
width={`${totalWidth}%`}

View File

@@ -0,0 +1,3 @@
.title {
color: var(--Text-Heading);
}

View File

@@ -4,7 +4,9 @@ import { useState } from "react"
import { useInterval } from "usehooks-ts"
import { dt } from "@scandic-hotels/common/dt"
import Title from "@scandic-hotels/design-system/Title"
import { Typography } from "@scandic-hotels/design-system/Typography"
import styles from "./countdown.module.css"
import type { CountdownProps } from "@/types/components/countdown"
@@ -28,8 +30,8 @@ export default function Countdown({
)
return (
<Title as="h1">
<Typography variant="Title/lg" className={styles.title}>
<time dateTime={time.toISOString()}>{time.format("m:ss")}</time>
</Title>
</Typography>
)
}

View File

@@ -8,6 +8,10 @@
gap: var(--Space-x4);
}
.title {
color: var(--Text-Heading);
}
.fieldset {
border: none;
padding: 0;

View File

@@ -2,7 +2,6 @@
import { useIntl } from "react-intl"
import Title from "@scandic-hotels/design-system/Title"
import { Typography } from "@scandic-hotels/design-system/Typography"
import { useDestinationDataStore } from "@/stores/destination-data"
@@ -33,12 +32,14 @@ export default function Filter({ filters }: FilterProps) {
return (
<div className={styles.container}>
<Title level="h4">
{intl.formatMessage({
id: "filter.filterBy",
defaultMessage: "Filter by",
})}
</Title>
<Typography variant="Title/xs" className={styles.title}>
<h4>
{intl.formatMessage({
id: "filter.filterBy",
defaultMessage: "Filter by",
})}
</h4>
</Typography>
<form className={styles.form}>
<fieldset className={styles.fieldset}>
<Typography variant="Title/Subtitle/md">

View File

@@ -1,4 +1,4 @@
header .title {
.header {
position: relative;
z-index: 2;
left: 0;
@@ -6,23 +6,10 @@ header .title {
margin: 0 auto;
padding-top: var(--Space-x6);
margin-top: var(--Space-x2);
text-align: center;
color: var(--Text-Inverted);
}
.title .hotelName {
font-family: var(--typography-Title-3-fontFamily);
font-size: var(--typography-Title-3-fontSize);
font-weight: var(--typography-Title-3-fontWeight);
letter-spacing: var(--typography-Title-3-letterSpacing);
line-height: var(--typography-Title-3-lineHeight);
display: block;
}
@media (min-width: 768px) {
.title .hotelName {
font-family: var(--typography-Title-1-fontFamily);
font-size: var(--typography-Title-1-fontSize);
font-weight: var(--typography-Title-1-fontWeight);
letter-spacing: var(--typography-Title-1-letterSpacing);
line-height: var(--typography-Title-1-lineHeight);
}
.myStayAt {
transform: rotate(-4deg) translate(0px, -10px);
}

View File

@@ -1,6 +1,5 @@
import Title from "@scandic-hotels/design-system/Title"
import { Typography } from "@scandic-hotels/design-system/Typography"
import BiroScript from "@/components/TempDesignSystem/Text/BiroScript"
import { getIntl } from "@/i18n"
import styles from "./header.module.css"
@@ -13,21 +12,21 @@ export async function Header({
}: Pick<Hotel, "cityName" | "name">) {
const intl = await getIntl()
return (
<header>
<Title as="h2" color="white" className={styles.title} textAlign="center">
<BiroScript type="two" tilted="medium">
<header className={styles.header}>
<Typography variant="Title/Decorative/lg" className={styles.myStayAt}>
<h2>
{intl.formatMessage({
id: "myStay.header.myStayAt",
defaultMessage: "My stay at",
})}
{
/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */
" "
}
</BiroScript>
<span className={styles.hotelName}>{name}</span>
{cityName}
</Title>
</h2>
</Typography>
<Typography variant="Title/lg">
<h2 className={styles.hotelName}>{name}</h2>
</Typography>
<Typography variant="Title/md">
<h3>{cityName}</h3>
</Typography>
</header>
)
}

View File

@@ -6,7 +6,6 @@ import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
import { JsonToHtml } from "@scandic-hotels/design-system/JsonToHtml"
import { OldDSButton as Button } from "@scandic-hotels/design-system/OldDSButton"
import Link from "@scandic-hotels/design-system/OldDSLink"
import Title from "@scandic-hotels/design-system/Title"
import { Typography } from "@scandic-hotels/design-system/Typography"
import { Section } from "@/components/Section"
@@ -31,9 +30,9 @@ export function SasTierComparison({
return (
<Section className={styles.comparisonSection}>
<div className={styles.header}>
<Title level="h2" textAlign="center">
{title}
</Title>
<Typography variant="Title/md" className={styles.title}>
<h2>{title}</h2>
</Typography>
{preamble && <p className={styles.preamble}>{preamble}</p>}
</div>
<div>

View File

@@ -15,6 +15,11 @@
text-align: center;
}
.title {
text-align: center;
color: var(--Text-Heading);
}
.preamble {
margin: 0;
white-space: pre-wrap;

View File

@@ -1,52 +0,0 @@
import Title, { type HeadingProps } from "@scandic-hotels/design-system/Title"
import { Typography } from "@scandic-hotels/design-system/Typography"
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 && (
<Typography variant="Body/Lead text" className={styles.preamble}>
<p>{preamble}</p>
</Typography>
)}
<SectionLink link={link} variant="desktop" />
</header>
)
}

View File

@@ -11,9 +11,8 @@ import styles from "./header.module.css"
import type { HTMLAttributes } from "react"
interface SectionHeaderProps
extends HTMLAttributes<HTMLElement>,
VariantProps<typeof headingVariants> {
heading?: string
extends HTMLAttributes<HTMLElement>, VariantProps<typeof headingVariants> {
heading?: string | null
headingLevel?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6"
preamble?: string | null
link?: {

View File

@@ -56,6 +56,9 @@
.themeOne {
background: var(--Primary-Light-Surface-Normal);
.heading {
color: var(--Primary-Light-On-Surface-Text);
}
.bodyText {
color: var(--Primary-Light-On-Surface-Text);
}
@@ -63,6 +66,9 @@
.themeTwo {
background: var(--Secondary-Light-Surface-Normal);
.heading {
color: var(--Secondary-Light-On-Surface-Text);
}
.bodyText {
color: var(--Secondary-Light-On-Surface-Text);
}
@@ -70,6 +76,9 @@
.themeThree {
background: var(--Tertiary-Light-Surface-Normal);
.heading {
color: var(--Tertiary-Light-On-Surface-Text);
}
.bodyText {
color: var(--Tertiary-Light-On-Surface-Text);
}
@@ -77,6 +86,9 @@
.themePrimaryDark {
background: var(--Primary-Dark-Surface-Normal);
.heading {
color: var(--Primary-Dark-On-Surface-Text);
}
.bodyText {
color: var(--Primary-Dark-On-Surface-Text);
}
@@ -84,6 +96,9 @@
.themePrimaryDim {
background: var(--Primary-Dim-Surface-Normal);
.heading {
color: var(--Primary-Dim-On-Surface-Text);
}
.bodyText {
color: var(--Primary-Dim-On-Surface-Text);
}
@@ -91,6 +106,9 @@
.themePrimaryInverted {
background: var(--Base-Surface-Primary-light-Normal);
.heading {
color: var(--Primary-Light-On-Surface-Text);
}
.bodyText {
color: var(--Primary-Light-On-Surface-Text);
}
@@ -98,6 +116,9 @@
.themePrimaryStrong {
background: var(--Primary-Strong-Surface-Normal);
.heading {
color: var(--Primary-Strong-On-Surface-Text);
}
.bodyText {
color: var(--Primary-Strong-On-Surface-Text);
}
@@ -107,6 +128,9 @@
.bodyText {
color: var(--Base-Text-Inverted);
}
.heading {
color: var(--Base-Text-Inverted);
}
.content {
position: absolute;
}

View File

@@ -3,12 +3,11 @@ import Link from "next/link"
import Image from "@scandic-hotels/design-system/Image"
import { OldDSButton as Button } from "@scandic-hotels/design-system/OldDSButton"
import Title from "@scandic-hotels/design-system/Title"
import { Typography } from "@scandic-hotels/design-system/Typography"
import BiroScript from "@/components/TempDesignSystem/Text/BiroScript"
import { getButtonTheme, getScriptFontColor, getTitleFontColor } from "./utils"
import { getButtonTheme, getScriptFontColor } from "./utils"
import { cardVariants } from "./variants"
import styles from "./card.module.css"
@@ -30,7 +29,6 @@ export default function Card({
height,
}: CardProps) {
const buttonTheme = getButtonTheme(theme)
const titleFontColor = getTitleFontColor(theme)
const scriptFontColor = getScriptFontColor(theme)
return (
@@ -71,15 +69,9 @@ export default function Card({
</BiroScript>
</section>
)}
<Title
as="h3"
level="h3"
textAlign="center"
textTransform="regular"
color={titleFontColor}
>
{heading}
</Title>
<Typography variant="Title/smLowCase" className={styles.heading}>
<h3>{heading}</h3>
</Typography>
{bodyText && (
<Typography
variant="Body/Paragraph/mdRegular"

View File

@@ -1,33 +1,9 @@
import type { ButtonProps } from "@scandic-hotels/design-system/OldDSButton"
import type Title from "@scandic-hotels/design-system/Title"
import type { VariantProps } from "class-variance-authority"
import type { ComponentProps } from "react"
import type { CardProps } from "@/components/TempDesignSystem/Card/card"
import type { biroScriptVariants } from "@/components/TempDesignSystem/Text/BiroScript/variants"
type TitleColor = ComponentProps<typeof Title>["color"]
export function getTitleFontColor(theme: CardProps["theme"]): TitleColor {
switch (theme) {
case "one":
return "primaryLight"
case "two":
return "secondaryLight"
case "three":
return "tertiaryLight"
case "primaryDark":
return "primaryDark"
case "primaryDim":
return "primaryDim"
case "primaryInverted":
return "primaryLight"
case "primaryStrong":
return "primaryStrong"
case "image":
return "baseText"
}
}
export function getScriptFontColor(
theme: CardProps["theme"]
): VariantProps<typeof biroScriptVariants>["color"] {

View File

@@ -1,7 +1,6 @@
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
import Image from "@scandic-hotels/design-system/Image"
import Link from "@scandic-hotels/design-system/OldDSLink"
import Title from "@scandic-hotels/design-system/Title"
import { Typography } from "@scandic-hotels/design-system/Typography"
import { loyaltyCardVariants } from "./variants"
@@ -36,9 +35,9 @@ export default function LoyaltyCard({
dimensions={image.dimensions}
/>
) : null}
<Title as="h4" level="h3" textAlign="center">
{heading}
</Title>
<Typography variant="Title/xs" className={styles.heading}>
<h3>{heading}</h3>
</Typography>
{!!bodyText && (
<Typography
variant="Body/Paragraph/mdRegular"

View File

@@ -18,6 +18,10 @@
justify-self: center;
}
.heading {
color: var(--Text-Heading);
}
.white {
background-color: var(--Main-Grey-White);
}

View File

@@ -1,4 +1,4 @@
import Title from "@scandic-hotels/design-system/Title"
import { Typography } from "@scandic-hotels/design-system/Typography"
import { TrackingSDK } from "@scandic-hotels/tracking/TrackingSDK"
import { serverClient } from "@/lib/trpc/server"
@@ -22,7 +22,9 @@ export default async function AboutScandicFriends() {
<>
<section className={styles.content}>
<MaxWidth tag="main" className={styles.blocks}>
<Title>{loyaltyPage.heading}</Title>
<Typography variant="Title/md" className={styles.heading}>
<h1>{loyaltyPage.heading}</h1>
</Typography>
<Blocks blocks={loyaltyPage.blocks} />
</MaxWidth>
</section>

View File

@@ -4,6 +4,10 @@
gap: var(--Space-x5);
}
.heading {
color: var(--Text-Heading);
}
.blocks {
display: grid;
gap: var(--Space-x5);

View File

@@ -39,6 +39,8 @@
display: flex;
flex-direction: column;
gap: var(--Space-x05);
text-align: center;
color: var(--Text-Inverted);
}
.mobileTitle {

View File

@@ -3,7 +3,6 @@
import { useIntl } from "react-intl"
import Image from "@scandic-hotels/design-system/Image"
import Title from "@scandic-hotels/design-system/Title"
import { Typography } from "@scandic-hotels/design-system/Typography"
import { HotelDetailsSidePeek } from "../../HotelDetailsSidePeek"
@@ -35,24 +34,12 @@ export default function HotelHeader({
<div className={styles.wrapper}>
<div className={styles.container}>
<div className={styles.titleContainer}>
<Title
as="h1"
level="h1"
color="white"
textAlign="center"
className={styles.title}
>
{hotel.name}
</Title>
<Title
as="h2"
level="h1"
color="white"
className={styles.mobileTitle}
textAlign="center"
>
{hotel.name}
</Title>
<Typography variant="Title/lg" className={styles.title}>
<h1>{hotel.name}</h1>
</Typography>
<Typography variant="Title/md" className={styles.mobileTitle}>
<h1>{hotel.name}</h1>
</Typography>
<Typography variant="Title/Overline/sm">
<div className={styles.address}>{addressStr}</div>
</Typography>

View File

@@ -5,7 +5,6 @@ import { formatPrice } from "@scandic-hotels/common/utils/numberFormatting"
import Caption from "@scandic-hotels/design-system/Caption"
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
import { OldDSButton as Button } from "@scandic-hotels/design-system/OldDSButton"
import Title from "@scandic-hotels/design-system/Title"
import { Typography } from "@scandic-hotels/design-system/Typography"
import { useEnterDetailsStore } from "../../../stores/enter-details"
@@ -102,14 +101,9 @@ export default function PriceChangeDialog({
size={48}
color="Icon/Interactive/Default"
/>
<Title
level="h1"
as="h3"
textAlign="center"
textTransform="uppercase"
>
{title}
</Title>
<Typography variant="Title/sm">
<h3>{title}</h3>
</Typography>
</div>
<Typography variant="Body/Paragraph/mdRegular">
<p style={{ textAlign: "center" }}>

View File

@@ -74,6 +74,7 @@
flex-direction: column;
align-items: center;
gap: var(--Space-x1);
color: var(--Text-Heading);
}
.footer {

View File

@@ -1,7 +1,7 @@
"use client"
import { useIntl } from "react-intl"
import Title from "@scandic-hotels/design-system/Title"
import { Typography } from "@scandic-hotels/design-system/Typography"
import { ChildBedMapEnum } from "@scandic-hotels/trpc/enums/childBedMapEnum"
import { useRoomContext } from "../../../contexts/EnterDetails/RoomContext"
@@ -38,17 +38,19 @@ export default function Multiroom() {
return (
<section id={`room-${roomNr}`}>
<Header>
<Title level="h2" as="h4">
{intl.formatMessage(
{
id: "booking.roomIndex",
defaultMessage: "Room {roomIndex}",
},
{
roomIndex: roomNr,
}
)}
</Title>
<Typography variant="Title/xs">
<h2 style={{ color: "var(--Text-Heading)" }}>
{intl.formatMessage(
{
id: "booking.roomIndex",
defaultMessage: "Room {roomIndex}",
},
{
roomIndex: roomNr,
}
)}
</h2>
</Typography>
</Header>
<SelectedRoom />

View File

@@ -1,7 +1,7 @@
"use client"
import { useIntl } from "react-intl"
import Title from "@scandic-hotels/design-system/Title"
import { Typography } from "@scandic-hotels/design-system/Typography"
import { ChildBedMapEnum } from "@scandic-hotels/trpc/enums/childBedMapEnum"
import { useRoomContext } from "../../../contexts/EnterDetails/RoomContext"
@@ -42,17 +42,19 @@ export default function RoomOne({ user }: { user: User | null }) {
<section id="room-1">
{isMultiroom ? (
<Header>
<Title level="h2" as="h4">
{intl.formatMessage(
{
id: "booking.roomIndex",
defaultMessage: "Room {roomIndex}",
},
{
roomIndex: 1,
}
)}
</Title>
<Typography variant="Title/xs">
<h2 style={{ color: "var(--Text-Heading)" }}>
{intl.formatMessage(
{
id: "booking.roomIndex",
defaultMessage: "Room {roomIndex}",
},
{
roomIndex: 1,
}
)}
</h2>
</Typography>
</Header>
) : null}

View File

@@ -8,8 +8,7 @@
gap: var(--Space-x3);
}
.container .filterByTitle {
font-weight: 500;
.title {
color: var(--Text-Heading);
}

View File

@@ -2,7 +2,6 @@ import { useSearchParams } from "next/navigation"
import { useEffect, useState } from "react"
import { useIntl } from "react-intl"
import Title from "@scandic-hotels/design-system/Title"
import { Typography } from "@scandic-hotels/design-system/Typography"
import {
@@ -117,12 +116,14 @@ export default function FilterContent({
return (
<aside className={`${styles.container} ${className}`}>
<div>
<Title as="h4">
{intl.formatMessage({
id: "filter.filterBy",
defaultMessage: "Filter by",
})}
</Title>
<Typography variant="Title/xs" className={styles.title}>
<h4>
{intl.formatMessage({
id: "filter.filterBy",
defaultMessage: "Filter by",
})}
</h4>
</Typography>
<div className={styles.facilities}>
<Typography variant="Title/Subtitle/md">
<p>

View File

@@ -1,64 +0,0 @@
import { Children, ReactNode } from "react"
import { headingVariants } from "./variants"
import type { VariantProps } from "class-variance-authority"
type HeadingLevel = "h1" | "h2" | "h3" | "h4" | "h5"
export interface HeadingProps
extends
Omit<React.HTMLAttributes<HTMLHeadingElement>, "color">,
VariantProps<typeof headingVariants> {
as?: HeadingLevel
level?: HeadingLevel
}
/**
* @deprecated Use `Typography` instead.
*/
export default function Title({
/**
* What styling to use, based on heading level. If not provided `level`
* will determine the styling.
*/
as,
children,
className = "",
color,
/**
* What HTML tag to use. Defaults to h1.
*/
level = "h1",
textAlign,
textTransform,
...rest
}: HeadingProps) {
if (checkForEmptyChildren(children) === 0) {
return null
}
const Hx = level
const classNames = headingVariants({
className,
color,
textAlign,
textTransform,
type: as ?? level,
})
return (
<Hx {...rest} className={classNames}>
{children}
</Hx>
)
}
function checkForEmptyChildren(children: ReactNode) {
return Children.toArray(children).filter((child) => {
if (child === "") {
return false
} else if (child == null) {
return false
} else {
return true
}
}).length
}

View File

@@ -1,143 +0,0 @@
.heading {
margin: 0;
padding: 0;
font-weight: 500;
}
/* Temporarily remove h1 styling until design tokens är updated */
/* .h1 {
font-family: var(--typography-Title-1-fontFamily);
font-size: clamp(
var(--typography-Title-1-Mobile-fontSize),
2.6vw + 27px,
var(--typography-Title-1-Desktop-fontSize)
);
letter-spacing: var(--typography-Title-1-letterSpacing);
line-height: var(--typography-Title-1-lineHeight);
text-decoration: var(--typography-Title-1-textDecoration);
} */
.h1 {
font-family: var(--typography-Title-2-fontFamily);
font-size: clamp(
var(--typography-Title-2-Mobile-fontSize),
2vw + 20px,
var(--typography-Title-2-Desktop-fontSize)
);
letter-spacing: var(--typography-Title-2-letterSpacing);
line-height: var(--typography-Title-2-lineHeight);
text-decoration: var(--typography-Title-2-textDecoration);
font-weight: var(--typography-Title-2-fontWeight);
}
.h2 {
font-family: var(--typography-Title-3-fontFamily);
font-size: clamp(
var(--typography-Title-3-Mobile-fontSize),
0.6vw + 27px,
var(--typography-Title-3-Desktop-fontSize)
);
letter-spacing: var(--typography-Title-3-letterSpacing);
line-height: var(--typography-Title-3-lineHeight);
text-decoration: var(--typography-Title-3-textDecoration);
font-weight: var(--typography-Title-3-fontWeight);
}
.h3 {
font-family: var(--typography-Title-4-fontFamily);
font-size: clamp(
var(--typography-Title-4-Mobile-fontSize),
0.6vw + 19px,
var(--typography-Title-4-Desktop-fontSize)
);
letter-spacing: var(--typography-Title-4-letterSpacing);
line-height: var(--typography-Title-4-lineHeight);
text-decoration: var(--typography-Title-4-textDecoration);
font-weight: var(--typography-Title-4-fontWeight);
}
.h4 {
font-family: var(--typography-Title-5-fontFamily);
font-size: clamp(
var(--typography-Title-5-Mobile-fontSize),
0.3vw + 17px,
var(--typography-Title-5-Desktop-fontSize)
);
letter-spacing: var(--typography-Title-5-letterSpacing);
line-height: var(--typography-Title-5-lineHeight);
text-decoration: var(--typography-Title-5-textDecoration);
font-weight: var(--typography-Title-5-fontWeight);
}
.capitalize {
text-transform: capitalize;
}
.regular {
text-transform: none;
}
.uppercase {
text-transform: uppercase;
}
.center {
text-align: center;
}
.left {
text-align: left;
}
.black {
color: var(--Main-Grey-100);
}
.burgundy {
color: var(--Scandic-Brand-Burgundy);
}
.pale {
color: var(--Scandic-Brand-Pale-Peach);
}
.peach80 {
color: var(--Scandic-Peach-80);
}
.red {
color: var(--Scandic-Brand-Scandic-Red);
}
.white {
color: var(--UI-Opacity-White-100);
}
.primaryLight {
color: var(--Primary-Light-On-Surface-Text);
}
.secondaryLight {
color: var(--Secondary-Light-On-Surface-Text);
}
.tertiaryLight {
color: var(--Tertiary-Light-On-Surface-Text);
}
.primaryDark {
color: var(--Primary-Dark-On-Surface-Text);
}
.primaryDim {
color: var(--Primary-Dim-On-Surface-Text);
}
.primaryStrong {
color: var(--Primary-Strong-On-Surface-Text);
}
.baseText {
color: var(--Base-Text-Inverted);
}

View File

@@ -1,47 +0,0 @@
import { cva } from "class-variance-authority"
import styles from "./title.module.css"
const config = {
variants: {
color: {
black: styles.black,
burgundy: styles.burgundy,
pale: styles.pale,
peach80: styles.peach80,
red: styles.red,
white: styles.white,
primaryLight: styles.primaryLight,
secondaryLight: styles.secondaryLight,
tertiaryLight: styles.tertiaryLight,
primaryDark: styles.primaryDark,
primaryDim: styles.primaryDim,
primaryStrong: styles.primaryStrong,
baseText: styles.baseText,
},
textAlign: {
center: styles.center,
left: styles.left,
},
textTransform: {
capitalize: styles.capitalize,
regular: styles.regular,
uppercase: styles.uppercase,
},
type: {
h1: styles.h1,
h2: styles.h2,
h3: styles.h3,
h4: styles.h4,
h5: styles.h4,
},
},
defaultVariants: {
color: "burgundy",
textAlign: "left",
textTransform: "uppercase",
type: "h1",
},
} as const
export const headingVariants = cva(styles.heading, config)

View File

@@ -180,7 +180,6 @@
"./TextArea": "./lib/components/TextArea/index.tsx",
"./TextLink": "./lib/components/TextLink/index.tsx",
"./TextLinkButton": "./lib/components/TextLinkButton/index.tsx",
"./Title": "./lib/components/Title/index.tsx",
"./Toast": "./lib/components/Toasts/index.tsx",
"./ToastHandler": "./lib/components/Toasts/ToastHandler.tsx",
"./Tooltip": "./lib/components/Tooltip/index.tsx",