refactor(SW-1877): a bit of cleanup of code to maintain patterns and separate components and types

This commit is contained in:
Christian Andolf
2025-03-31 11:47:53 +02:00
parent 52b461fbb4
commit 19723856c3
6 changed files with 91 additions and 79 deletions

View File

@@ -3,13 +3,13 @@ import { serverClient } from "@/lib/trpc/server"
import BreadcrumbsComp from "@/components/TempDesignSystem/Breadcrumbs"
import { generateBreadcrumbsSchema } from "@/utils/jsonSchemas"
import type { Breadcrumbs } from "@/types/trpc/routers/contentstack/breadcrumbs"
import type { BreadcrumbsProps } from "@/components/TempDesignSystem/Breadcrumbs/breadcrumbs"
export default async function Breadcrumbs({
variant,
subpageTitle,
}: Pick<BreadcrumbsProps, "variant" | "subpageTitle">) {
interface Props extends Pick<BreadcrumbsProps, "variant"> {
subpageTitle?: string
}
export default async function Breadcrumbs({ variant, subpageTitle }: Props) {
const breadcrumbs = await serverClient().contentstack.breadcrumbs.get()
if (!breadcrumbs?.length) {
return null

View File

@@ -0,0 +1,37 @@
import { cx } from "class-variance-authority"
import { Breadcrumb as AriaBreadcrumb } from "react-aria-components"
import { MaterialIcon } from "@scandic-hotels/design-system/Icons"
import Link from "@/components/TempDesignSystem/Link"
import styles from "./breadcrumbs.module.css"
import type { BreadcrumbProps } from "./breadcrumbs"
export function Breadcrumb({
className = "",
href,
children,
...props
}: BreadcrumbProps) {
return (
<AriaBreadcrumb className={cx(styles.listItem, className)} {...props}>
{href ? (
<>
<Link color="peach80" href={href} variant="breadcrumb">
{children}
</Link>
<MaterialIcon
icon="chevron_right"
size={20}
aria-hidden="true"
color="Icon/Interactive/Secondary"
/>
</>
) : (
children
)}
</AriaBreadcrumb>
)
}

View File

@@ -27,6 +27,12 @@
padding-inline-start: 0;
}
.list .listItem:last-of-type {
flex: 1;
max-width: 100%;
min-width: 0;
}
.listItem {
align-items: center;
display: flex;
@@ -43,19 +49,6 @@
flex-shrink: 0;
}
.last {
flex: 1;
max-width: 100%;
min-width: 0;
}
.last > button {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
text-align: left;
}
.button {
border: none;
background: transparent;
@@ -103,6 +96,13 @@
}
}
.tooltipTrigger {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
text-align: left;
}
.tooltip {
background-color: var(--Surface-UI-Fill-Intense);
padding: var(--Spacing-x-half) var(--Spacing-x1);

View File

@@ -1,15 +1,22 @@
import type { VariantProps } from "class-variance-authority"
import type { PropsWithChildren } from "react"
import type { BreadcrumbProps as AriaBreadcrumbProps } from "react-aria-components"
import type { breadcrumbsVariants } from "./variants"
export type Breadcrumb = {
export type { Breadcrumb, BreadcrumbProps, BreadcrumbsProps }
type Breadcrumb = {
title: string
uid: string
href?: string
}
export interface BreadcrumbsProps
extends VariantProps<typeof breadcrumbsVariants> {
subpageTitle?: string
interface BreadcrumbsProps extends VariantProps<typeof breadcrumbsVariants> {
breadcrumbs: Breadcrumb[]
}
interface BreadcrumbProps extends PropsWithChildren<AriaBreadcrumbProps> {
className?: string
href?: string
}

View File

@@ -1,10 +1,9 @@
"use client"
import { cx } from "class-variance-authority"
import { type PropsWithChildren, useEffect, useState } from "react"
import { useEffect, useState } from "react"
import {
Breadcrumb as AriaBreadcrumb,
Breadcrumbs as AriaBreadCrumbs,
Breadcrumbs as AriaBreadcrumbs,
Button,
Dialog,
DialogTrigger,
@@ -15,19 +14,18 @@ import {
import { MaterialIcon } from "@scandic-hotels/design-system/Icons"
import { Typography } from "@scandic-hotels/design-system/Typography"
import Link from "@/components/TempDesignSystem/Link"
import Footnote from "@/components/TempDesignSystem/Text/Footnote"
import { debounce } from "@/utils/debounce"
import Link from "../Link"
import { Arrow } from "../Popover/Arrow"
import Footnote from "../Text/Footnote"
import { Breadcrumb } from "./Breadcrumb"
import { splitBreadcrumbs } from "./utils"
import { breadcrumbsVariants } from "./variants"
import styles from "./breadcrumbs.module.css"
import type {
Breadcrumb,
BreadcrumbsProps,
} from "@/components/TempDesignSystem/Breadcrumbs/breadcrumbs"
import type { BreadcrumbsProps } from "./breadcrumbs"
export default function Breadcrumbs({
breadcrumbs,
@@ -69,7 +67,7 @@ export default function Breadcrumbs({
return (
<nav aria-label="Breadcrumbs" className={classNames}>
<AriaBreadCrumbs className={styles.list}>
<AriaBreadcrumbs className={styles.list}>
<Breadcrumb
href={homeBreadcrumb.href}
aria-label={homeBreadcrumb.title}
@@ -85,10 +83,10 @@ export default function Breadcrumbs({
>
{remainingBreadcrumbs[0].title}
</Breadcrumb>
<AriaBreadcrumb className={cx(styles.listItem, styles.mobile)}>
<Breadcrumb className={styles.mobile}>
<DialogTrigger>
<Footnote color="burgundy" type="bold" asChild>
<Button className={styles.button}>...</Button>
<Button className={styles.button}></Button>
</Footnote>
<Popover>
<Dialog className={styles.dialog}>
@@ -111,7 +109,7 @@ export default function Breadcrumbs({
aria-hidden="true"
color="Icon/Interactive/Secondary"
/>
</AriaBreadcrumb>
</Breadcrumb>
</>
) : (
remainingBreadcrumbs.map((breadcrumb) => (
@@ -133,7 +131,7 @@ export default function Breadcrumbs({
<DialogTrigger>
<Footnote color="burgundy" type="bold" asChild>
<Button
className={styles.button}
className={cx(styles.button, styles.tooltipTrigger)}
ref={attachRef}
isDisabled={isTooltipDisabled}
>
@@ -152,49 +150,7 @@ export default function Breadcrumbs({
</Popover>
</DialogTrigger>
</Breadcrumb>
</AriaBreadCrumbs>
</AriaBreadcrumbs>
</nav>
)
}
function Breadcrumb({
className = "",
href,
children,
...props
}: PropsWithChildren<{
className?: string
href?: string
}>) {
return (
<AriaBreadcrumb
className={cx(styles.listItem, { [styles.last]: !href }, className)}
{...props}
>
{href ? (
<>
<Link color="peach80" href={href} variant="breadcrumb">
{children}
</Link>
<MaterialIcon
icon="chevron_right"
size={20}
aria-hidden="true"
color="Icon/Interactive/Secondary"
/>
</>
) : (
children
)}
</AriaBreadcrumb>
)
}
function splitBreadcrumbs(
breadcrumbs: Breadcrumb[]
): [Breadcrumb, Breadcrumb[], Breadcrumb] {
const copy = breadcrumbs.slice(0)
const first = copy.shift()!
const last = copy.pop()!
return [first, copy, last]
}

View File

@@ -0,0 +1,12 @@
import type { Breadcrumb } from "./breadcrumbs"
export { splitBreadcrumbs }
function splitBreadcrumbs(
breadcrumbs: Breadcrumb[]
): [Breadcrumb, Breadcrumb[], Breadcrumb] {
const copy = breadcrumbs.slice(0)
const first = copy.shift()!
const last = copy.pop()!
return [first, copy, last]
}