refactor: Move Sidepeek param logic to SidePeekProvider
This commit is contained in:
@@ -73,6 +73,7 @@ export default async function IntroSection({
|
|||||||
color="burgundy"
|
color="burgundy"
|
||||||
variant="icon"
|
variant="icon"
|
||||||
href={`?s=${about[lang]}`}
|
href={`?s=${about[lang]}`}
|
||||||
|
scroll={false}
|
||||||
>
|
>
|
||||||
{intl.formatMessage({ id: "Read more about the hotel" })}
|
{intl.formatMessage({ id: "Read more about the hotel" })}
|
||||||
<ArrowRight color="burgundy" />
|
<ArrowRight color="burgundy" />
|
||||||
|
|||||||
@@ -1,99 +0,0 @@
|
|||||||
"use client"
|
|
||||||
|
|
||||||
import { usePathname, useRouter, useSearchParams } from "next/navigation"
|
|
||||||
import { useEffect, useState } from "react"
|
|
||||||
import { useIntl } from "react-intl"
|
|
||||||
|
|
||||||
import {
|
|
||||||
about,
|
|
||||||
activities,
|
|
||||||
amenities,
|
|
||||||
meetingsAndConferences,
|
|
||||||
restaurantAndBar,
|
|
||||||
wellnessAndExercise,
|
|
||||||
} from "@/constants/routes/hotelPageParams"
|
|
||||||
|
|
||||||
import SidePeek from "@/components/TempDesignSystem/SidePeek"
|
|
||||||
import SidePeekItem from "@/components/TempDesignSystem/SidePeek/Item"
|
|
||||||
import { SidePeekContentKey } from "@/components/TempDesignSystem/SidePeek/types"
|
|
||||||
import useLang from "@/hooks/useLang"
|
|
||||||
|
|
||||||
function SidePeekContainer() {
|
|
||||||
const router = useRouter()
|
|
||||||
const pathname = usePathname()
|
|
||||||
const searchParams = useSearchParams()
|
|
||||||
const [activeSidePeek, setActiveSidePeek] =
|
|
||||||
useState<SidePeekContentKey | null>(() => {
|
|
||||||
const sidePeekParam = searchParams.get("s") as SidePeekContentKey | null
|
|
||||||
return sidePeekParam || null
|
|
||||||
})
|
|
||||||
|
|
||||||
const lang = useLang()
|
|
||||||
const intl = useIntl()
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const sidePeekParam = searchParams.get("s") as SidePeekContentKey | null
|
|
||||||
if (sidePeekParam !== activeSidePeek) {
|
|
||||||
setActiveSidePeek(sidePeekParam)
|
|
||||||
}
|
|
||||||
}, [searchParams, activeSidePeek])
|
|
||||||
|
|
||||||
function handleClose(isOpen: boolean) {
|
|
||||||
if (!isOpen) {
|
|
||||||
setActiveSidePeek(null)
|
|
||||||
|
|
||||||
const nextSearchParams = new URLSearchParams(searchParams.toString())
|
|
||||||
nextSearchParams.delete("s")
|
|
||||||
|
|
||||||
router.push(`${pathname}?${nextSearchParams}`, { scroll: false })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<SidePeek handleClose={handleClose} activeSidePeek={activeSidePeek}>
|
|
||||||
<SidePeekItem
|
|
||||||
contentKey={amenities[lang]}
|
|
||||||
title={intl.formatMessage({ id: "Amenities" })}
|
|
||||||
>
|
|
||||||
{/* TODO: Render amenities as per the design. */}
|
|
||||||
Read more about the amenities here
|
|
||||||
</SidePeekItem>
|
|
||||||
<SidePeekItem
|
|
||||||
contentKey={about[lang]}
|
|
||||||
title={intl.formatMessage({ id: "Read more about the hotel" })}
|
|
||||||
>
|
|
||||||
Some additional information about the hotel
|
|
||||||
</SidePeekItem>
|
|
||||||
<SidePeekItem
|
|
||||||
contentKey={restaurantAndBar[lang]}
|
|
||||||
title={intl.formatMessage({ id: "Restaurant & Bar" })}
|
|
||||||
>
|
|
||||||
{/* TODO */}
|
|
||||||
Restaurant & Bar
|
|
||||||
</SidePeekItem>
|
|
||||||
<SidePeekItem
|
|
||||||
contentKey={wellnessAndExercise[lang]}
|
|
||||||
title={intl.formatMessage({ id: "Wellness & Exercise" })}
|
|
||||||
>
|
|
||||||
{/* TODO */}
|
|
||||||
Wellness & Exercise
|
|
||||||
</SidePeekItem>
|
|
||||||
<SidePeekItem
|
|
||||||
contentKey={activities[lang]}
|
|
||||||
title={intl.formatMessage({ id: "Activities" })}
|
|
||||||
>
|
|
||||||
{/* TODO */}
|
|
||||||
Activities
|
|
||||||
</SidePeekItem>
|
|
||||||
<SidePeekItem
|
|
||||||
contentKey={meetingsAndConferences[lang]}
|
|
||||||
title={intl.formatMessage({ id: "Meetings & Conferences" })}
|
|
||||||
>
|
|
||||||
{/* TODO */}
|
|
||||||
Meetings & Conferences
|
|
||||||
</SidePeekItem>
|
|
||||||
</SidePeek>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default SidePeekContainer
|
|
||||||
@@ -1,6 +1,12 @@
|
|||||||
|
import hotelPageParams from "@/constants/routes/hotelPageParams"
|
||||||
import { env } from "@/env/server"
|
import { env } from "@/env/server"
|
||||||
import { serverClient } from "@/lib/trpc/server"
|
import { serverClient } from "@/lib/trpc/server"
|
||||||
|
|
||||||
|
import SidePeekProvider from "@/components/SidePeekProvider"
|
||||||
|
import SidePeek from "@/components/TempDesignSystem/SidePeek"
|
||||||
|
import { getIntl } from "@/i18n"
|
||||||
|
import { getLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import { MOCK_FACILITIES } from "./Facilities/mockData"
|
import { MOCK_FACILITIES } from "./Facilities/mockData"
|
||||||
import { setActivityCard } from "./Facilities/utils"
|
import { setActivityCard } from "./Facilities/utils"
|
||||||
import DynamicMap from "./Map/DynamicMap"
|
import DynamicMap from "./Map/DynamicMap"
|
||||||
@@ -12,13 +18,14 @@ import Facilities from "./Facilities"
|
|||||||
import IntroSection from "./IntroSection"
|
import IntroSection from "./IntroSection"
|
||||||
import PreviewImages from "./PreviewImages"
|
import PreviewImages from "./PreviewImages"
|
||||||
import { Rooms } from "./Rooms"
|
import { Rooms } from "./Rooms"
|
||||||
import SidePeeks from "./SidePeeks"
|
|
||||||
import TabNavigation from "./TabNavigation"
|
import TabNavigation from "./TabNavigation"
|
||||||
|
|
||||||
import styles from "./hotelPage.module.css"
|
import styles from "./hotelPage.module.css"
|
||||||
|
|
||||||
export default async function HotelPage() {
|
export default async function HotelPage() {
|
||||||
const googleMapsApiKey = env.GOOGLE_STATIC_MAP_KEY
|
const googleMapsApiKey = env.GOOGLE_STATIC_MAP_KEY
|
||||||
|
const intl = await getIntl()
|
||||||
|
const lang = getLang()
|
||||||
const hotelData = await serverClient().hotel.get({
|
const hotelData = await serverClient().hotel.get({
|
||||||
include: ["RoomCategories"],
|
include: ["RoomCategories"],
|
||||||
})
|
})
|
||||||
@@ -61,6 +68,51 @@ export default async function HotelPage() {
|
|||||||
address={hotelAddress}
|
address={hotelAddress}
|
||||||
tripAdvisor={hotelRatings?.tripAdvisor}
|
tripAdvisor={hotelRatings?.tripAdvisor}
|
||||||
/>
|
/>
|
||||||
|
<SidePeekProvider>
|
||||||
|
{/* eslint-disable import/no-named-as-default-member */}
|
||||||
|
<SidePeek
|
||||||
|
contentKey={hotelPageParams.amenities[lang]}
|
||||||
|
title={intl.formatMessage({ id: "Amenities" })}
|
||||||
|
>
|
||||||
|
{/* TODO: Render amenities as per the design. */}
|
||||||
|
Read more about the amenities here
|
||||||
|
</SidePeek>
|
||||||
|
<SidePeek
|
||||||
|
contentKey={hotelPageParams.about[lang]}
|
||||||
|
title={intl.formatMessage({ id: "Read more about the hotel" })}
|
||||||
|
>
|
||||||
|
Some additional information about the hotel
|
||||||
|
</SidePeek>
|
||||||
|
<SidePeek
|
||||||
|
contentKey={hotelPageParams.restaurantAndBar[lang]}
|
||||||
|
title={intl.formatMessage({ id: "Restaurant & Bar" })}
|
||||||
|
>
|
||||||
|
{/* TODO */}
|
||||||
|
Restaurant & Bar
|
||||||
|
</SidePeek>
|
||||||
|
<SidePeek
|
||||||
|
contentKey={hotelPageParams.wellnessAndExercise[lang]}
|
||||||
|
title={intl.formatMessage({ id: "Wellness & Exercise" })}
|
||||||
|
>
|
||||||
|
{/* TODO */}
|
||||||
|
Wellness & Exercise
|
||||||
|
</SidePeek>
|
||||||
|
<SidePeek
|
||||||
|
contentKey={hotelPageParams.activities[lang]}
|
||||||
|
title={intl.formatMessage({ id: "Activities" })}
|
||||||
|
>
|
||||||
|
{/* TODO */}
|
||||||
|
Activities
|
||||||
|
</SidePeek>
|
||||||
|
<SidePeek
|
||||||
|
contentKey={hotelPageParams.meetingsAndConferences[lang]}
|
||||||
|
title={intl.formatMessage({ id: "Meetings & Conferences" })}
|
||||||
|
>
|
||||||
|
{/* TODO */}
|
||||||
|
Meetings & Conferences
|
||||||
|
</SidePeek>
|
||||||
|
{/* eslint-enable import/no-named-as-default-member */}
|
||||||
|
</SidePeekProvider>
|
||||||
<AmenitiesList detailedFacilities={hotelDetailedFacilities} />
|
<AmenitiesList detailedFacilities={hotelDetailedFacilities} />
|
||||||
</div>
|
</div>
|
||||||
<Rooms rooms={roomCategories} />
|
<Rooms rooms={roomCategories} />
|
||||||
@@ -80,7 +132,6 @@ export default async function HotelPage() {
|
|||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
) : null}
|
) : null}
|
||||||
<SidePeeks />
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
45
components/SidePeekProvider/index.tsx
Normal file
45
components/SidePeekProvider/index.tsx
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
"use client"
|
||||||
|
import { usePathname, useRouter, useSearchParams } from "next/navigation"
|
||||||
|
import { createContext, useEffect, useState } from "react"
|
||||||
|
|
||||||
|
interface ISidePeekContext {
|
||||||
|
handleClose: (isOpen: boolean) => void
|
||||||
|
activeSidePeek: string | null
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SidePeekContext = createContext<ISidePeekContext | null>(null)
|
||||||
|
|
||||||
|
function SidePeekProvider({ children }: React.PropsWithChildren) {
|
||||||
|
const router = useRouter()
|
||||||
|
const pathname = usePathname()
|
||||||
|
const searchParams = useSearchParams()
|
||||||
|
const [activeSidePeek, setActiveSidePeek] = useState<string | null>(() => {
|
||||||
|
const sidePeekParam = searchParams.get("s")
|
||||||
|
return sidePeekParam || null
|
||||||
|
})
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const sidePeekParam = searchParams.get("s")
|
||||||
|
if (sidePeekParam !== activeSidePeek) {
|
||||||
|
setActiveSidePeek(sidePeekParam)
|
||||||
|
}
|
||||||
|
}, [searchParams, activeSidePeek])
|
||||||
|
|
||||||
|
function handleClose(isOpen: boolean) {
|
||||||
|
if (!isOpen) {
|
||||||
|
const nextSearchParams = new URLSearchParams(searchParams.toString())
|
||||||
|
nextSearchParams.delete("s")
|
||||||
|
|
||||||
|
router.push(`${pathname}?${nextSearchParams}`, { scroll: false })
|
||||||
|
setActiveSidePeek(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SidePeekContext.Provider value={{ handleClose, activeSidePeek }}>
|
||||||
|
{children}
|
||||||
|
</SidePeekContext.Provider>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SidePeekProvider
|
||||||
@@ -75,7 +75,7 @@ export default function Link({
|
|||||||
trackPageViewStart()
|
trackPageViewStart()
|
||||||
startTransition(() => {
|
startTransition(() => {
|
||||||
startRouterTransition()
|
startRouterTransition()
|
||||||
router.push(href)
|
router.push(href, { scroll })
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
href={href}
|
href={href}
|
||||||
|
|||||||
@@ -1,39 +0,0 @@
|
|||||||
"use client"
|
|
||||||
|
|
||||||
import { PropsWithChildren } from "react"
|
|
||||||
|
|
||||||
import { CloseIcon } from "@/components/Icons"
|
|
||||||
import { SidePeekContentProps } from "@/components/TempDesignSystem/SidePeek/types"
|
|
||||||
import Title from "@/components/TempDesignSystem/Text/Title"
|
|
||||||
|
|
||||||
import Button from "../../Button"
|
|
||||||
|
|
||||||
import styles from "./sidePeekItem.module.css"
|
|
||||||
|
|
||||||
function SidePeekItem({
|
|
||||||
title,
|
|
||||||
children,
|
|
||||||
isActive = false,
|
|
||||||
onClose,
|
|
||||||
}: PropsWithChildren<SidePeekContentProps>) {
|
|
||||||
return isActive ? (
|
|
||||||
<aside className={styles.sidePeekItem}>
|
|
||||||
<header className={styles.header}>
|
|
||||||
<Title color="burgundy" textTransform="uppercase" level="h2" as="h3">
|
|
||||||
{title}
|
|
||||||
</Title>
|
|
||||||
<Button
|
|
||||||
intent="text"
|
|
||||||
onClick={() => {
|
|
||||||
onClose && onClose()
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<CloseIcon color="burgundy" height={32} width={32} />
|
|
||||||
</Button>
|
|
||||||
</header>
|
|
||||||
{children}
|
|
||||||
</aside>
|
|
||||||
) : null
|
|
||||||
}
|
|
||||||
|
|
||||||
export default SidePeekItem
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
.sidePeekItem {
|
|
||||||
display: grid;
|
|
||||||
grid-template-rows: min-content auto;
|
|
||||||
gap: var(--Spacing-x4);
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content>* {
|
|
||||||
padding: var(--Spacing-x3) var(--Spacing-x2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.header {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
border-bottom: 1px solid var(--Base-Border-Subtle);
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header:has(> h2) {
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (min-width: 1367px) {
|
|
||||||
.content>* {
|
|
||||||
padding: var(--Spacing-x4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +1,20 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import { useIsSSR } from "@react-aria/ssr"
|
import { useIsSSR } from "@react-aria/ssr"
|
||||||
import React, { Children, cloneElement } from "react"
|
import { useContext } from "react"
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
DialogTrigger,
|
DialogTrigger,
|
||||||
Modal,
|
Modal,
|
||||||
ModalOverlay,
|
ModalOverlay,
|
||||||
} from "react-aria-components"
|
} from "react-aria-components"
|
||||||
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
import { SidePeekContentKey } from "@/components/TempDesignSystem/SidePeek/types"
|
import { CloseIcon } from "@/components/Icons"
|
||||||
|
import { SidePeekContext } from "@/components/SidePeekProvider"
|
||||||
|
|
||||||
|
import Button from "../Button"
|
||||||
|
import Title from "../Text/Title"
|
||||||
|
|
||||||
import styles from "./sidePeek.module.css"
|
import styles from "./sidePeek.module.css"
|
||||||
|
|
||||||
@@ -17,33 +22,61 @@ import type { SidePeekProps } from "./sidePeek"
|
|||||||
|
|
||||||
function SidePeek({
|
function SidePeek({
|
||||||
children,
|
children,
|
||||||
|
title,
|
||||||
|
contentKey,
|
||||||
handleClose,
|
handleClose,
|
||||||
activeSidePeek,
|
isOpen,
|
||||||
}: React.PropsWithChildren<SidePeekProps>) {
|
}: React.PropsWithChildren<SidePeekProps>) {
|
||||||
const sidePeekChildren = Children.map(children, (child) => {
|
|
||||||
if (!React.isValidElement(child)) {
|
|
||||||
return child
|
|
||||||
}
|
|
||||||
return cloneElement(child as React.ReactElement, {
|
|
||||||
isActive:
|
|
||||||
(child.props.contentKey as SidePeekContentKey) === activeSidePeek,
|
|
||||||
onClose: handleClose,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
const isSSR = useIsSSR()
|
const isSSR = useIsSSR()
|
||||||
return isSSR ? (
|
const intl = useIntl()
|
||||||
<div>{children}</div>
|
const context = useContext(SidePeekContext)
|
||||||
) : (
|
function onClose() {
|
||||||
|
const closeHandler = handleClose || context?.handleClose
|
||||||
|
closeHandler && closeHandler(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isSSR) {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h2>{title}</h2>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return (
|
||||||
<DialogTrigger>
|
<DialogTrigger>
|
||||||
<ModalOverlay
|
<ModalOverlay
|
||||||
className={styles.overlay}
|
className={styles.overlay}
|
||||||
isOpen={!!activeSidePeek}
|
isOpen={isOpen || contentKey === context?.activeSidePeek}
|
||||||
onOpenChange={handleClose}
|
onOpenChange={onClose}
|
||||||
isDismissable
|
isDismissable
|
||||||
>
|
>
|
||||||
<Modal className={styles.sidePeek}>
|
<Modal className={styles.modal}>
|
||||||
<Dialog className={styles.dialog}>{sidePeekChildren}</Dialog>
|
<Dialog className={styles.dialog}>
|
||||||
|
<aside className={styles.sidePeek}>
|
||||||
|
<header className={styles.header}>
|
||||||
|
{title ? (
|
||||||
|
<Title
|
||||||
|
color="burgundy"
|
||||||
|
textTransform="uppercase"
|
||||||
|
level="h2"
|
||||||
|
as="h3"
|
||||||
|
>
|
||||||
|
{title}
|
||||||
|
</Title>
|
||||||
|
) : null}
|
||||||
|
<Button
|
||||||
|
aria-label={intl.formatMessage({ id: "Close" })}
|
||||||
|
className={styles.closeButton}
|
||||||
|
intent="text"
|
||||||
|
onPress={onClose}
|
||||||
|
>
|
||||||
|
<CloseIcon color="burgundy" height={32} width={32} />
|
||||||
|
</Button>
|
||||||
|
</header>
|
||||||
|
<div className={styles.sidePeekContent}>{children}</div>
|
||||||
|
</aside>
|
||||||
|
</Dialog>
|
||||||
</Modal>
|
</Modal>
|
||||||
</ModalOverlay>
|
</ModalOverlay>
|
||||||
</DialogTrigger>
|
</DialogTrigger>
|
||||||
|
|||||||
@@ -1,38 +1,9 @@
|
|||||||
.sidePeek {
|
.modal {
|
||||||
position: fixed;
|
--sidepeek-desktop-width: 600px;
|
||||||
top: var(--current-mobile-site-header-height);
|
|
||||||
right: auto;
|
|
||||||
bottom: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: calc(100vh - var(--current-mobile-site-header-height));
|
|
||||||
background-color: var(--Base-Background-Primary-Normal);
|
|
||||||
z-index: 100;
|
|
||||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.85);
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidePeek[data-entering] {
|
|
||||||
animation: slide-up 300ms;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidePeek[data-exiting] {
|
|
||||||
animation: slide-up 300ms reverse;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dialog {
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.overlay {
|
|
||||||
position: absolute;
|
|
||||||
top: var(--current-mobile-site-header-height);
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
z-index: 99;
|
|
||||||
}
|
}
|
||||||
@keyframes slide-in {
|
@keyframes slide-in {
|
||||||
from {
|
from {
|
||||||
right: -600px;
|
right: calc(-1 * var(--sidepeek-desktop-width));
|
||||||
}
|
}
|
||||||
|
|
||||||
to {
|
to {
|
||||||
@@ -46,24 +17,84 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
to {
|
to {
|
||||||
top: var(--current-mobile-site-header-height);
|
top: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (min-width: 1367px) {
|
.overlay {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
z-index: 99;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
right: auto;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100vh;
|
||||||
|
background-color: var(--Base-Background-Primary-Normal);
|
||||||
|
z-index: 100;
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.85);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal[data-entering] {
|
||||||
|
animation: slide-up 300ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal[data-exiting] {
|
||||||
|
animation: slide-up 300ms reverse;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.sidePeek {
|
.sidePeek {
|
||||||
|
display: grid;
|
||||||
|
grid-template-rows: min-content auto;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
border-bottom: 1px solid var(--Base-Border-Subtle);
|
||||||
|
align-items: center;
|
||||||
|
padding: var(--Spacing-x4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.header:has(> h2) {
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.closeButton {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidePeekContent {
|
||||||
|
padding: var(--Spacing-x4);
|
||||||
|
}
|
||||||
|
@media screen and (min-width: 1367px) {
|
||||||
|
.modal {
|
||||||
top: 0;
|
top: 0;
|
||||||
right: 0px;
|
right: 0px;
|
||||||
width: 600px;
|
width: var(--sidepeek-desktop-width);
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
}
|
}
|
||||||
.sidePeek[data-entering] {
|
|
||||||
|
.modal[data-entering] {
|
||||||
animation: slide-in 250ms;
|
animation: slide-in 250ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidePeek[data-exiting] {
|
.modal[data-exiting] {
|
||||||
animation: slide-in 250ms reverse;
|
animation: slide-in 250ms reverse;
|
||||||
}
|
}
|
||||||
|
|
||||||
.overlay {
|
.overlay {
|
||||||
top: 0;
|
top: 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
export interface SidePeekProps {
|
export interface SidePeekProps {
|
||||||
handleClose: (isOpen: boolean) => void
|
contentKey: string
|
||||||
activeSidePeek: string | null
|
title: string
|
||||||
|
isOpen?: boolean
|
||||||
|
handleClose?: (isOpen: boolean) => void
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
export type SidePeekContentKey = string
|
|
||||||
|
|
||||||
export type SidePeekProps = {
|
export type SidePeekProps = {
|
||||||
activeContent: string | null
|
activeContent: string | null
|
||||||
onClose: (isOpen: boolean) => void
|
onClose: (isOpen: boolean) => void
|
||||||
@@ -7,7 +5,7 @@ export type SidePeekProps = {
|
|||||||
|
|
||||||
export type SidePeekContentProps = {
|
export type SidePeekContentProps = {
|
||||||
title?: string
|
title?: string
|
||||||
contentKey: SidePeekContentKey
|
contentKey: string
|
||||||
isActive?: boolean
|
isActive?: boolean
|
||||||
onClose?: () => void
|
onClose?: () => void
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user