feat(SW-1884): Always render sidepeek contents, not just during SSR

Approved-by: Michael Zetterberg
This commit is contained in:
Erik Tiekstra
2025-04-03 09:36:22 +00:00
parent b70d933c73
commit 8c2047e847
6 changed files with 73 additions and 59 deletions

View File

@@ -69,6 +69,19 @@ ul {
margin-block-end: 0; margin-block-end: 0;
} }
/* From Tailwind */
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-width: 0;
}
@media screen and (min-width: 768px) { @media screen and (min-width: 768px) {
:root { :root {
--max-width-spacing: calc(var(--Layout-Tablet-Margin-Margin-min) * 2); --max-width-spacing: calc(var(--Layout-Tablet-Margin-Margin-min) * 2);

View File

@@ -74,10 +74,6 @@
padding: 0; padding: 0;
} }
.visuallyHidden {
display: none;
}
@media screen and (max-width: 767px) { @media screen and (max-width: 767px) {
.overlay { .overlay {
height: var(--visual-viewport-height); height: var(--visual-viewport-height);

View File

@@ -194,7 +194,7 @@ export default function DestinationFilterAndSort({
</DialogTrigger> </DialogTrigger>
{/* This section is added to the DOM for SEO purposes. The filters are linkable and should be indexable */} {/* This section is added to the DOM for SEO purposes. The filters are linkable and should be indexable */}
<nav className={styles.visuallyHidden}> <nav className="sr-only">
<ul> <ul>
{facilityFilters.map((filter) => ( {facilityFilters.map((filter) => (
<li key={`filter-${filter.slug}`}> <li key={`filter-${filter.slug}`}>

View File

@@ -0,0 +1,16 @@
import type { SidePeekProps } from "./sidePeek"
// Sidepeeks generally have important content that should be indexed by search engines.
// The content is hidden behind a modal, but it is still important for SEO.
// This component is used to provide SEO information for the sidepeek content.
export default function SidePeekSEO({
title,
children,
}: React.PropsWithChildren<Pick<SidePeekProps, "title">>) {
return (
<div className="sr-only">
<h2>{title}</h2>
{children}
</div>
)
}

View File

@@ -1,6 +1,5 @@
"use client" "use client"
import { useIsSSR } from "@react-aria/ssr"
import { useContext, useRef } from "react" import { useContext, useRef } from "react"
import { Dialog, Modal, ModalOverlay } from "react-aria-components" import { Dialog, Modal, ModalOverlay } from "react-aria-components"
import { useIntl } from "react-intl" import { useIntl } from "react-intl"
@@ -11,12 +10,13 @@ import { Typography } from "@scandic-hotels/design-system/Typography"
import { SidePeekContext } from "@/components/SidePeeks/SidePeekProvider" import { SidePeekContext } from "@/components/SidePeeks/SidePeekProvider"
import Button from "../Button" import Button from "../Button"
import SidePeekSEO from "./SidePeekSEO"
import styles from "./sidePeek.module.css" import styles from "./sidePeek.module.css"
import type { SidePeekProps } from "./sidePeek" import type { SidePeekProps } from "./sidePeek"
function SidePeek({ export default function SidePeek({
children, children,
title, title,
contentKey, contentKey,
@@ -24,7 +24,6 @@ function SidePeek({
isOpen, isOpen,
openInRoot = false, openInRoot = false,
}: React.PropsWithChildren<SidePeekProps>) { }: React.PropsWithChildren<SidePeekProps>) {
const isSSR = useIsSSR()
const intl = useIntl() const intl = useIntl()
const rootDiv = useRef<HTMLDivElement>(null) const rootDiv = useRef<HTMLDivElement>(null)
@@ -34,16 +33,8 @@ function SidePeek({
closeHandler && closeHandler(false) closeHandler && closeHandler(false)
} }
if (isSSR) {
return (
<div className={styles.visuallyHidden}>
<h2>{title}</h2>
{children}
</div>
)
}
return ( return (
<>
<div ref={openInRoot ? null : rootDiv}> <div ref={openInRoot ? null : rootDiv}>
<ModalOverlay <ModalOverlay
UNSTABLE_portalContainer={rootDiv.current || undefined} UNSTABLE_portalContainer={rootDiv.current || undefined}
@@ -69,7 +60,10 @@ function SidePeek({
intent="text" intent="text"
onPress={onClose} onPress={onClose}
> >
<MaterialIcon icon="close" color="Icon/Interactive/Default" /> <MaterialIcon
icon="close"
color="Icon/Interactive/Default"
/>
</Button> </Button>
</header> </header>
<div className={styles.sidePeekContent}>{children}</div> <div className={styles.sidePeekContent}>{children}</div>
@@ -78,7 +72,8 @@ function SidePeek({
</Modal> </Modal>
</ModalOverlay> </ModalOverlay>
</div> </div>
<SidePeekSEO title={title}>{children}</SidePeekSEO>
</>
) )
} }
export default SidePeek

View File

@@ -21,12 +21,6 @@
} }
} }
.visuallyHidden {
position: absolute;
opacity: 0;
visibility: hidden;
}
.overlay { .overlay {
position: fixed; position: fixed;
top: 0; top: 0;