Merged in fix/SW-2118-breadcrumbs (pull request #1721)
fix(SW-2118): changed variants for breadcrumbs to handle different background-colors and widths * fix(SW-2118): changed variants for breadcrumbs to handle different background-colors and widths Approved-by: Christian Andolf Approved-by: Linus Flood
This commit is contained in:
committed by
Linus Flood
parent
a9c6901752
commit
85a90baa12
@@ -4,12 +4,11 @@ import Breadcrumbs from "@/components/Breadcrumbs"
|
|||||||
import BreadcrumbsSkeleton from "@/components/TempDesignSystem/Breadcrumbs/BreadcrumbsSkeleton"
|
import BreadcrumbsSkeleton from "@/components/TempDesignSystem/Breadcrumbs/BreadcrumbsSkeleton"
|
||||||
|
|
||||||
import type { LangParams, PageArgs } from "@/types/params"
|
import type { LangParams, PageArgs } from "@/types/params"
|
||||||
import { PageContentTypeEnum } from "@/types/requests/contentType"
|
|
||||||
|
|
||||||
export default function AllBreadcrumbs({}: PageArgs<LangParams>) {
|
export default function AllBreadcrumbs({}: PageArgs<LangParams>) {
|
||||||
return (
|
return (
|
||||||
<Suspense fallback={<BreadcrumbsSkeleton />}>
|
<Suspense fallback={<BreadcrumbsSkeleton />}>
|
||||||
<Breadcrumbs variant={PageContentTypeEnum.accountPage} />
|
<Breadcrumbs />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,14 +5,31 @@ import BreadcrumbsSkeleton from "@/components/TempDesignSystem/Breadcrumbs/Bread
|
|||||||
|
|
||||||
import type { ContentTypeParams, LangParams, PageArgs } from "@/types/params"
|
import type { ContentTypeParams, LangParams, PageArgs } from "@/types/params"
|
||||||
import { PageContentTypeEnum } from "@/types/requests/contentType"
|
import { PageContentTypeEnum } from "@/types/requests/contentType"
|
||||||
|
import type { BreadcrumbsProps } from "@/components/TempDesignSystem/Breadcrumbs/breadcrumbs"
|
||||||
|
|
||||||
|
// This is a temporary solution to avoid showing breadcrumbs on certain content types.
|
||||||
|
// This should be refactored in the future to handle content types differently, similar to `destination_overview_page`.
|
||||||
const IGNORED_CONTENT_TYPES = [
|
const IGNORED_CONTENT_TYPES = [
|
||||||
PageContentTypeEnum.hotelPage,
|
PageContentTypeEnum.hotelPage,
|
||||||
PageContentTypeEnum.contentPage,
|
PageContentTypeEnum.contentPage,
|
||||||
PageContentTypeEnum.destinationCityPage,
|
PageContentTypeEnum.destinationCityPage,
|
||||||
PageContentTypeEnum.destinationCountryPage,
|
PageContentTypeEnum.destinationCountryPage,
|
||||||
|
PageContentTypeEnum.destinationOverviewPage,
|
||||||
|
PageContentTypeEnum.startPage,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
// This function is temporary until the content types are refactored and handled differently, similar to `destination_overview_page`.
|
||||||
|
function getBreadcrumbsVariantsByContentType(
|
||||||
|
contentType: PageContentTypeEnum
|
||||||
|
): Pick<BreadcrumbsProps, "color" | "size"> | null {
|
||||||
|
switch (contentType) {
|
||||||
|
case PageContentTypeEnum.collectionPage:
|
||||||
|
return { color: "Surface/Secondary/Default", size: "contentWidth" }
|
||||||
|
default:
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default function PageBreadcrumbs({
|
export default function PageBreadcrumbs({
|
||||||
params,
|
params,
|
||||||
}: PageArgs<LangParams & ContentTypeParams>) {
|
}: PageArgs<LangParams & ContentTypeParams>) {
|
||||||
@@ -20,9 +37,11 @@ export default function PageBreadcrumbs({
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const variants = getBreadcrumbsVariantsByContentType(params.contentType)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Suspense fallback={<BreadcrumbsSkeleton />}>
|
<Suspense fallback={<BreadcrumbsSkeleton {...variants} />}>
|
||||||
<Breadcrumbs variant={params.contentType} />
|
<Breadcrumbs {...variants} />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,11 +5,15 @@ import { generateBreadcrumbsSchema } from "@/utils/jsonSchemas"
|
|||||||
|
|
||||||
import type { BreadcrumbsProps } from "@/components/TempDesignSystem/Breadcrumbs/breadcrumbs"
|
import type { BreadcrumbsProps } from "@/components/TempDesignSystem/Breadcrumbs/breadcrumbs"
|
||||||
|
|
||||||
interface Props extends Pick<BreadcrumbsProps, "variant"> {
|
interface Props extends Pick<BreadcrumbsProps, "color" | "size"> {
|
||||||
subpageTitle?: string
|
subpageTitle?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export default async function Breadcrumbs({ variant, subpageTitle }: Props) {
|
export default async function Breadcrumbs({
|
||||||
|
color,
|
||||||
|
size,
|
||||||
|
subpageTitle,
|
||||||
|
}: Props) {
|
||||||
const breadcrumbs = await serverClient().contentstack.breadcrumbs.get()
|
const breadcrumbs = await serverClient().contentstack.breadcrumbs.get()
|
||||||
if (!breadcrumbs?.length) {
|
if (!breadcrumbs?.length) {
|
||||||
return null
|
return null
|
||||||
@@ -29,7 +33,7 @@ export default async function Breadcrumbs({ variant, subpageTitle }: Props) {
|
|||||||
__html: JSON.stringify(jsonSchema.jsonLd),
|
__html: JSON.stringify(jsonSchema.jsonLd),
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<BreadcrumbsComp breadcrumbs={breadcrumbs} variant={variant} />
|
<BreadcrumbsComp breadcrumbs={breadcrumbs} color={color} size={size} />
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,8 +21,6 @@ import DestinationCityPageSkeleton from "./DestinationCityPageSkeleton"
|
|||||||
|
|
||||||
import styles from "./destinationCityPage.module.css"
|
import styles from "./destinationCityPage.module.css"
|
||||||
|
|
||||||
import { PageContentTypeEnum } from "@/types/requests/contentType"
|
|
||||||
|
|
||||||
export default async function DestinationCityPage() {
|
export default async function DestinationCityPage() {
|
||||||
const pageData = await getDestinationCityPage()
|
const pageData = await getDestinationCityPage()
|
||||||
|
|
||||||
@@ -51,9 +49,7 @@ export default async function DestinationCityPage() {
|
|||||||
<div className={styles.pageContainer}>
|
<div className={styles.pageContainer}>
|
||||||
<header className={styles.header}>
|
<header className={styles.header}>
|
||||||
<Suspense fallback={<BreadcrumbsSkeleton />}>
|
<Suspense fallback={<BreadcrumbsSkeleton />}>
|
||||||
<Breadcrumbs
|
<Breadcrumbs />
|
||||||
variant={PageContentTypeEnum.destinationCityPage}
|
|
||||||
/>
|
|
||||||
</Suspense>
|
</Suspense>
|
||||||
{images?.length ? (
|
{images?.length ? (
|
||||||
<TopImages images={images} destinationName={city.name} />
|
<TopImages images={images} destinationName={city.name} />
|
||||||
|
|||||||
@@ -18,8 +18,6 @@ import DestinationCountryPageSkeleton from "./DestinationCountryPageSkeleton"
|
|||||||
|
|
||||||
import styles from "./destinationCountryPage.module.css"
|
import styles from "./destinationCountryPage.module.css"
|
||||||
|
|
||||||
import { PageContentTypeEnum } from "@/types/requests/contentType"
|
|
||||||
|
|
||||||
export default async function DestinationCountryPage() {
|
export default async function DestinationCountryPage() {
|
||||||
const pageData = await getDestinationCountryPage()
|
const pageData = await getDestinationCountryPage()
|
||||||
|
|
||||||
@@ -48,9 +46,7 @@ export default async function DestinationCountryPage() {
|
|||||||
<div className={styles.pageContainer}>
|
<div className={styles.pageContainer}>
|
||||||
<header className={styles.header}>
|
<header className={styles.header}>
|
||||||
<Suspense fallback={<BreadcrumbsSkeleton />}>
|
<Suspense fallback={<BreadcrumbsSkeleton />}>
|
||||||
<Breadcrumbs
|
<Breadcrumbs />
|
||||||
variant={PageContentTypeEnum.destinationCityPage}
|
|
||||||
/>
|
|
||||||
</Suspense>
|
</Suspense>
|
||||||
{images?.length ? (
|
{images?.length ? (
|
||||||
<TopImages
|
<TopImages
|
||||||
|
|||||||
@@ -43,7 +43,6 @@ import styles from "./hotelPage.module.css"
|
|||||||
|
|
||||||
import type { HotelPageProps } from "@/types/components/hotelPage/hotelPage"
|
import type { HotelPageProps } from "@/types/components/hotelPage/hotelPage"
|
||||||
import { HotelHashValues } from "@/types/components/hotelPage/tabNavigation"
|
import { HotelHashValues } from "@/types/components/hotelPage/tabNavigation"
|
||||||
import { PageContentTypeEnum } from "@/types/requests/contentType"
|
|
||||||
|
|
||||||
export default async function HotelPage({ hotelId }: HotelPageProps) {
|
export default async function HotelPage({ hotelId }: HotelPageProps) {
|
||||||
const lang = getLang()
|
const lang = getLang()
|
||||||
@@ -147,8 +146,8 @@ export default async function HotelPage({ hotelId }: HotelPageProps) {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<header className={styles.header}>
|
<header className={styles.header}>
|
||||||
<Suspense fallback={<BreadcrumbsSkeleton />}>
|
<Suspense fallback={<BreadcrumbsSkeleton size="headerWidth" />}>
|
||||||
<Breadcrumbs variant={PageContentTypeEnum.hotelPage} />
|
<Breadcrumbs size="headerWidth" />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
{images?.length ? (
|
{images?.length ? (
|
||||||
<PreviewImages images={images} hotelName={name} />
|
<PreviewImages images={images} hotelName={name} />
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
.header {
|
.header {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: var(--Spacing-x4);
|
|
||||||
background-color: var(--Base-Surface-Subtle-Normal);
|
background-color: var(--Base-Surface-Subtle-Normal);
|
||||||
padding-bottom: var(--Spacing-x4);
|
padding-bottom: var(--Spacing-x4);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,11 +77,8 @@ export default async function HotelSubpage({
|
|||||||
<StickyMeetingPackageWidget destination={meetingPackageDestination} />
|
<StickyMeetingPackageWidget destination={meetingPackageDestination} />
|
||||||
)}
|
)}
|
||||||
<div className={styles.header}>
|
<div className={styles.header}>
|
||||||
<Suspense fallback={<BreadcrumbsSkeleton />}>
|
<Suspense fallback={<BreadcrumbsSkeleton size="contentWidth" />}>
|
||||||
<Breadcrumbs
|
<Breadcrumbs subpageTitle={pageData.heading} size="contentWidth" />
|
||||||
variant="hotelSubpage"
|
|
||||||
subpageTitle={pageData.heading}
|
|
||||||
/>
|
|
||||||
</Suspense>
|
</Suspense>
|
||||||
|
|
||||||
{pageData.heroImage ? (
|
{pageData.heroImage ? (
|
||||||
|
|||||||
@@ -8,8 +8,6 @@ import BreadcrumbsSkeleton from "@/components/TempDesignSystem/Breadcrumbs/Bread
|
|||||||
|
|
||||||
import StaticPage from ".."
|
import StaticPage from ".."
|
||||||
|
|
||||||
import { PageContentTypeEnum } from "@/types/requests/contentType"
|
|
||||||
|
|
||||||
export default async function ContentPage() {
|
export default async function ContentPage() {
|
||||||
const contentPageRes = await serverClient().contentstack.contentPage.get()
|
const contentPageRes = await serverClient().contentstack.contentPage.get()
|
||||||
|
|
||||||
@@ -26,8 +24,15 @@ export default async function ContentPage() {
|
|||||||
destination={contentPage.meeting_package.location}
|
destination={contentPage.meeting_package.location}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<Suspense fallback={<BreadcrumbsSkeleton />}>
|
<Suspense
|
||||||
<Breadcrumbs variant={PageContentTypeEnum.contentPage} />
|
fallback={
|
||||||
|
<BreadcrumbsSkeleton
|
||||||
|
color="Surface/Secondary/Default"
|
||||||
|
size="contentWidth"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Breadcrumbs color="Surface/Secondary/Default" size="contentWidth" />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
<StaticPage
|
<StaticPage
|
||||||
content={contentPage}
|
content={contentPage}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
.header {
|
.header {
|
||||||
background-color: var(--Base-Surface-Subtle-Normal);
|
background-color: var(--Base-Surface-Subtle-Normal);
|
||||||
padding: var(--Spacing-x4) 0;
|
padding-bottom: var(--Spacing-x4);
|
||||||
}
|
}
|
||||||
|
|
||||||
.headerContent {
|
.headerContent {
|
||||||
@@ -32,7 +32,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.contentContainer {
|
.contentContainer {
|
||||||
padding-top: var(--Spacing-x4);
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: var(--Spacing-x4) var(--Spacing-x2) 0;
|
padding: var(--Spacing-x4) var(--Spacing-x2) 0;
|
||||||
}
|
}
|
||||||
@@ -83,21 +82,9 @@
|
|||||||
.headerIntro {
|
.headerIntro {
|
||||||
gap: var(--Spacing-x3);
|
gap: var(--Spacing-x3);
|
||||||
}
|
}
|
||||||
|
|
||||||
.header {
|
|
||||||
padding: var(--Spacing-x4) 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 1367px) {
|
@media (min-width: 1367px) {
|
||||||
.heroContainer {
|
|
||||||
padding: var(--Spacing-x4) 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.contentContainer {
|
|
||||||
padding: var(--Spacing-x4) 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content .contentContainer {
|
.content .contentContainer {
|
||||||
grid-template-areas: "main sidebar";
|
grid-template-areas: "main sidebar";
|
||||||
grid-template-columns: var(--max-width-text-block) 1fr;
|
grid-template-columns: var(--max-width-text-block) 1fr;
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { cx } from "class-variance-authority"
|
import { cx } from "class-variance-authority"
|
||||||
|
import Link from "next/link"
|
||||||
import { Breadcrumb as AriaBreadcrumb } from "react-aria-components"
|
import { Breadcrumb as AriaBreadcrumb } from "react-aria-components"
|
||||||
|
|
||||||
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
||||||
|
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||||
import Link from "@/components/TempDesignSystem/Link"
|
|
||||||
|
|
||||||
import styles from "./breadcrumbs.module.css"
|
import styles from "./breadcrumbs.module.css"
|
||||||
|
|
||||||
@@ -19,9 +19,11 @@ export function Breadcrumb({
|
|||||||
<AriaBreadcrumb className={cx(styles.listItem, className)} {...props}>
|
<AriaBreadcrumb className={cx(styles.listItem, className)} {...props}>
|
||||||
{href ? (
|
{href ? (
|
||||||
<>
|
<>
|
||||||
<Link color="peach80" href={href} variant="breadcrumb">
|
<Typography variant="Label/xsRegular">
|
||||||
{children}
|
<Link className={styles.link} href={href}>
|
||||||
</Link>
|
{children}
|
||||||
|
</Link>
|
||||||
|
</Typography>
|
||||||
<MaterialIcon
|
<MaterialIcon
|
||||||
icon="chevron_right"
|
icon="chevron_right"
|
||||||
size={20}
|
size={20}
|
||||||
|
|||||||
@@ -1,17 +1,25 @@
|
|||||||
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
||||||
|
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||||
|
|
||||||
import SkeletonShimmer from "@/components/SkeletonShimmer"
|
import SkeletonShimmer from "@/components/SkeletonShimmer"
|
||||||
import styles from "@/components/TempDesignSystem/Breadcrumbs/breadcrumbs.module.css"
|
import styles from "@/components/TempDesignSystem/Breadcrumbs/breadcrumbs.module.css"
|
||||||
import Footnote from "@/components/TempDesignSystem/Text/Footnote"
|
|
||||||
|
|
||||||
export default function BreadcrumbsSkeleton() {
|
import { breadcrumbsVariants } from "../variants"
|
||||||
|
|
||||||
|
import type { BreadcrumbsProps } from "../breadcrumbs"
|
||||||
|
|
||||||
|
export default function BreadcrumbsSkeleton({
|
||||||
|
color,
|
||||||
|
size,
|
||||||
|
}: Pick<BreadcrumbsProps, "color" | "size">) {
|
||||||
|
const classNames = breadcrumbsVariants({ color, size })
|
||||||
return (
|
return (
|
||||||
<nav className={styles.breadcrumbs}>
|
<nav className={classNames}>
|
||||||
<ul className={styles.list}>
|
<ul className={styles.list}>
|
||||||
<li className={styles.listItem}>
|
<li className={styles.listItem}>
|
||||||
<MaterialIcon
|
<MaterialIcon
|
||||||
icon="home"
|
icon="home"
|
||||||
size={16}
|
size={20}
|
||||||
color="Icon/Interactive/Secondary"
|
color="Icon/Interactive/Secondary"
|
||||||
/>
|
/>
|
||||||
<MaterialIcon
|
<MaterialIcon
|
||||||
@@ -23,9 +31,9 @@ export default function BreadcrumbsSkeleton() {
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li className={styles.listItem}>
|
<li className={styles.listItem}>
|
||||||
<Footnote color="burgundy" type="bold">
|
<Typography variant="Label/xsBold">
|
||||||
<SkeletonShimmer width={"12ch"} />
|
<SkeletonShimmer width="20ch" />
|
||||||
</Footnote>
|
</Typography>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
|
|||||||
@@ -2,30 +2,33 @@
|
|||||||
padding: var(--Spacing-x4) 0 var(--Spacing-x3);
|
padding: var(--Spacing-x4) 0 var(--Spacing-x3);
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: var(--max-width-page);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.breadcrumbs.fullWidth {
|
.breadcrumbs.transparent {
|
||||||
max-width: var(--max-width-page);
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
.breadcrumbs.surfaceSecondaryDefault {
|
||||||
|
background-color: var(--Surface-Secondary-Default);
|
||||||
|
}
|
||||||
|
.breadcrumbs.surfacePrimaryOnSurfaceDefault {
|
||||||
|
background-color: var(--Surface-Primary-On-Surface-Default);
|
||||||
}
|
}
|
||||||
|
|
||||||
.breadcrumbs.contentWidth {
|
.breadcrumbs .list {
|
||||||
max-width: var(--max-width-content);
|
|
||||||
}
|
|
||||||
|
|
||||||
.breadcrumbs.contentWidth {
|
|
||||||
background-color: var(--Base-Surface-Subtle-Normal);
|
|
||||||
padding-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.breadcrumbs.headerWidth {
|
|
||||||
max-width: min(var(--max-width-page), calc(100% - var(--max-width-spacing)));
|
|
||||||
}
|
|
||||||
|
|
||||||
.list {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: var(--Spacing-x-quarter);
|
gap: var(--Spacing-x-quarter);
|
||||||
padding-inline-start: 0;
|
padding-inline-start: 0;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.breadcrumbs.contentWidth .list {
|
||||||
|
max-width: var(--max-width-content);
|
||||||
|
}
|
||||||
|
.breadcrumbs.headerWidth .list {
|
||||||
|
max-width: min(var(--max-width-page), calc(100% - var(--max-width-spacing)));
|
||||||
|
}
|
||||||
|
.breadcrumbs.pageWidth .list {
|
||||||
|
max-width: var(--max-width-page);
|
||||||
}
|
}
|
||||||
|
|
||||||
.list .listItem:last-of-type {
|
.list .listItem:last-of-type {
|
||||||
@@ -58,6 +61,16 @@
|
|||||||
/* this increases the width of the button for tapping */
|
/* this increases the width of the button for tapping */
|
||||||
padding: 0 5px;
|
padding: 0 5px;
|
||||||
margin: 0 -5px;
|
margin: 0 -5px;
|
||||||
|
color: var(--Base-Text-High-contrast);
|
||||||
|
}
|
||||||
|
|
||||||
|
.link {
|
||||||
|
color: var(--Text-Interactive-Secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.link:hover,
|
||||||
|
.button:hover {
|
||||||
|
color: var(--Text-Interactive-Hover-Secondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dialog {
|
.dialog {
|
||||||
@@ -76,6 +89,7 @@
|
|||||||
display: block;
|
display: block;
|
||||||
border-radius: var(--Corner-radius-Medium);
|
border-radius: var(--Corner-radius-Medium);
|
||||||
padding: var(--Spacing-x1);
|
padding: var(--Spacing-x1);
|
||||||
|
color: var(--Text-Default);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dialogLink:focus,
|
.dialogLink:focus,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import { cx } from "class-variance-authority"
|
import { cx } from "class-variance-authority"
|
||||||
|
import Link from "next/link"
|
||||||
import { useEffect, useState } from "react"
|
import { useEffect, useState } from "react"
|
||||||
import {
|
import {
|
||||||
Breadcrumbs as AriaBreadcrumbs,
|
Breadcrumbs as AriaBreadcrumbs,
|
||||||
@@ -16,9 +17,7 @@ import { Typography } from "@scandic-hotels/design-system/Typography"
|
|||||||
|
|
||||||
import { debounce } from "@/utils/debounce"
|
import { debounce } from "@/utils/debounce"
|
||||||
|
|
||||||
import Link from "../Link"
|
|
||||||
import { Arrow } from "../Popover/Arrow"
|
import { Arrow } from "../Popover/Arrow"
|
||||||
import Footnote from "../Text/Footnote"
|
|
||||||
import { Breadcrumb } from "./Breadcrumb"
|
import { Breadcrumb } from "./Breadcrumb"
|
||||||
import { splitBreadcrumbs } from "./utils"
|
import { splitBreadcrumbs } from "./utils"
|
||||||
import { breadcrumbsVariants } from "./variants"
|
import { breadcrumbsVariants } from "./variants"
|
||||||
@@ -29,7 +28,8 @@ import type { BreadcrumbsProps } from "./breadcrumbs"
|
|||||||
|
|
||||||
export default function Breadcrumbs({
|
export default function Breadcrumbs({
|
||||||
breadcrumbs,
|
breadcrumbs,
|
||||||
variant,
|
color,
|
||||||
|
size,
|
||||||
}: BreadcrumbsProps) {
|
}: BreadcrumbsProps) {
|
||||||
// using a ref instead to detect when the element is available and forcing a render
|
// using a ref instead to detect when the element is available and forcing a render
|
||||||
const [element, attachRef] = useState<HTMLButtonElement | null>(null)
|
const [element, attachRef] = useState<HTMLButtonElement | null>(null)
|
||||||
@@ -59,7 +59,8 @@ export default function Breadcrumbs({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const classNames = breadcrumbsVariants({
|
const classNames = breadcrumbsVariants({
|
||||||
variant,
|
color,
|
||||||
|
size,
|
||||||
})
|
})
|
||||||
|
|
||||||
const [homeBreadcrumb, remainingBreadcrumbs, lastBreadcrumb] =
|
const [homeBreadcrumb, remainingBreadcrumbs, lastBreadcrumb] =
|
||||||
@@ -72,9 +73,14 @@ export default function Breadcrumbs({
|
|||||||
href={homeBreadcrumb.href}
|
href={homeBreadcrumb.href}
|
||||||
aria-label={homeBreadcrumb.title}
|
aria-label={homeBreadcrumb.title}
|
||||||
>
|
>
|
||||||
<MaterialIcon icon="home" size={16} color="CurrentColor" />
|
<MaterialIcon
|
||||||
|
icon="home"
|
||||||
|
size={20}
|
||||||
|
color="Icon/Interactive/Secondary"
|
||||||
|
/>
|
||||||
</Breadcrumb>
|
</Breadcrumb>
|
||||||
|
|
||||||
|
{/* These breadcrumbs are visible on mobile only */}
|
||||||
{remainingBreadcrumbs.length >= 3 ? (
|
{remainingBreadcrumbs.length >= 3 ? (
|
||||||
<>
|
<>
|
||||||
<Breadcrumb
|
<Breadcrumb
|
||||||
@@ -85,20 +91,24 @@ export default function Breadcrumbs({
|
|||||||
</Breadcrumb>
|
</Breadcrumb>
|
||||||
<Breadcrumb className={styles.mobile}>
|
<Breadcrumb className={styles.mobile}>
|
||||||
<DialogTrigger>
|
<DialogTrigger>
|
||||||
<Footnote color="burgundy" type="bold" asChild>
|
<Typography variant="Label/xsRegular">
|
||||||
<Button className={styles.button}>…</Button>
|
<Button className={styles.button}>…</Button>
|
||||||
</Footnote>
|
</Typography>
|
||||||
<Popover>
|
<Popover>
|
||||||
<Dialog className={styles.dialog}>
|
<Dialog className={styles.dialog}>
|
||||||
{remainingBreadcrumbs.slice(1).map((breadcrumb) => (
|
{remainingBreadcrumbs.slice(1).map((breadcrumb) => (
|
||||||
<Link
|
<Typography
|
||||||
href={breadcrumb.href!}
|
|
||||||
size="tiny"
|
|
||||||
key={breadcrumb.uid}
|
key={breadcrumb.uid}
|
||||||
className={styles.dialogLink}
|
variant="Label/xsRegular"
|
||||||
|
className={styles.dialogItem}
|
||||||
>
|
>
|
||||||
{breadcrumb.title}
|
<Link
|
||||||
</Link>
|
href={breadcrumb.href!}
|
||||||
|
className={styles.dialogLink}
|
||||||
|
>
|
||||||
|
{breadcrumb.title}
|
||||||
|
</Link>
|
||||||
|
</Typography>
|
||||||
))}
|
))}
|
||||||
</Dialog>
|
</Dialog>
|
||||||
</Popover>
|
</Popover>
|
||||||
@@ -122,6 +132,8 @@ export default function Breadcrumbs({
|
|||||||
</Breadcrumb>
|
</Breadcrumb>
|
||||||
))
|
))
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* These breadcrumbs are visible on desktop only */}
|
||||||
{remainingBreadcrumbs.map((breadcrumb) => (
|
{remainingBreadcrumbs.map((breadcrumb) => (
|
||||||
<Breadcrumb
|
<Breadcrumb
|
||||||
key={breadcrumb.uid}
|
key={breadcrumb.uid}
|
||||||
@@ -131,9 +143,11 @@ export default function Breadcrumbs({
|
|||||||
{breadcrumb.title}
|
{breadcrumb.title}
|
||||||
</Breadcrumb>
|
</Breadcrumb>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
|
{/* Current page breadcrumb */}
|
||||||
<Breadcrumb>
|
<Breadcrumb>
|
||||||
<DialogTrigger>
|
<DialogTrigger>
|
||||||
<Footnote color="burgundy" type="bold" asChild>
|
<Typography variant="Label/xsBold">
|
||||||
<Button
|
<Button
|
||||||
className={cx(styles.button, styles.tooltipTrigger)}
|
className={cx(styles.button, styles.tooltipTrigger)}
|
||||||
ref={attachRef}
|
ref={attachRef}
|
||||||
@@ -141,7 +155,7 @@ export default function Breadcrumbs({
|
|||||||
>
|
>
|
||||||
{lastBreadcrumb.title}
|
{lastBreadcrumb.title}
|
||||||
</Button>
|
</Button>
|
||||||
</Footnote>
|
</Typography>
|
||||||
<Popover placement="bottom" offset={16}>
|
<Popover placement="bottom" offset={16}>
|
||||||
<Dialog className={styles.tooltip}>
|
<Dialog className={styles.tooltip}>
|
||||||
<OverlayArrow>
|
<OverlayArrow>
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import type { Breadcrumb } from "./breadcrumbs"
|
import type { Breadcrumb } from "./breadcrumbs"
|
||||||
|
|
||||||
export { splitBreadcrumbs }
|
|
||||||
|
|
||||||
function splitBreadcrumbs(
|
function splitBreadcrumbs(
|
||||||
breadcrumbs: Breadcrumb[]
|
breadcrumbs: Breadcrumb[]
|
||||||
): [Breadcrumb, Breadcrumb[], Breadcrumb] {
|
): [Breadcrumb, Breadcrumb[], Breadcrumb] {
|
||||||
@@ -10,3 +8,5 @@ function splitBreadcrumbs(
|
|||||||
const last = copy.pop()!
|
const last = copy.pop()!
|
||||||
return [first, copy, last]
|
return [first, copy, last]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export { splitBreadcrumbs }
|
||||||
|
|||||||
@@ -2,25 +2,22 @@ import { cva } from "class-variance-authority"
|
|||||||
|
|
||||||
import styles from "./breadcrumbs.module.css"
|
import styles from "./breadcrumbs.module.css"
|
||||||
|
|
||||||
import { PageContentTypeEnum } from "@/types/requests/contentType"
|
|
||||||
|
|
||||||
export const breadcrumbsVariants = cva(styles.breadcrumbs, {
|
export const breadcrumbsVariants = cva(styles.breadcrumbs, {
|
||||||
variants: {
|
variants: {
|
||||||
variant: {
|
color: {
|
||||||
[PageContentTypeEnum.accountPage]: styles.fullWidth,
|
transparent: styles.transparent,
|
||||||
[PageContentTypeEnum.contentPage]: styles.contentWidth,
|
"Surface/Secondary/Default": styles.surfaceSecondaryDefault,
|
||||||
[PageContentTypeEnum.collectionPage]: styles.contentWidth,
|
"Surface/Primary/OnSurface/Default":
|
||||||
[PageContentTypeEnum.destinationOverviewPage]: styles.fullWidth,
|
styles.surfacePrimaryOnSurfaceDefault,
|
||||||
[PageContentTypeEnum.destinationCountryPage]: styles.fullWidth,
|
},
|
||||||
[PageContentTypeEnum.destinationCityPage]: styles.fullWidth,
|
size: {
|
||||||
[PageContentTypeEnum.hotelPage]: styles.headerWidth,
|
pageWidth: styles.pageWidth,
|
||||||
[PageContentTypeEnum.loyaltyPage]: styles.fullWidth,
|
headerWidth: styles.headerWidth,
|
||||||
[PageContentTypeEnum.startPage]: styles.contentWidth,
|
contentWidth: styles.contentWidth,
|
||||||
hotelSubpage: styles.contentWidth,
|
|
||||||
default: styles.fullWidth,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
defaultVariants: {
|
defaultVariants: {
|
||||||
variant: "default",
|
color: "transparent",
|
||||||
|
size: "pageWidth",
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user