fix(SW-2657): Added sidepeek image component to handle images inside hotel page sidepeeks
Approved-by: Matilda Landström
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
.sidePeekImages {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--Space-x2);
|
||||
}
|
||||
|
||||
.image {
|
||||
object-fit: cover;
|
||||
height: 240px;
|
||||
min-width: 0; /* Prevents image from causing flex item overflow by allowing shrinking below content size */
|
||||
width: 100%;
|
||||
border-radius: var(--Corner-radius-md);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import Image from "@/components/Image"
|
||||
|
||||
import styles from "./images.module.css"
|
||||
|
||||
import type { ApiImage } from "@/types/hotel"
|
||||
|
||||
interface SidePeekImagesProps {
|
||||
images: ApiImage[]
|
||||
}
|
||||
|
||||
export default function SidePeekImages({ images }: SidePeekImagesProps) {
|
||||
const showMultipleImages = images.length > 2
|
||||
const imageWidth = showMultipleImages ? 240 : 496
|
||||
const sizesString = showMultipleImages
|
||||
? "(min-width: 1367px) 240px, 50vw"
|
||||
: "(min-width: 1367px) 496px, 100vw"
|
||||
|
||||
return (
|
||||
<div className={styles.sidePeekImages}>
|
||||
{images.map(({ metaData, imageSizes }) => (
|
||||
<Image
|
||||
key={imageSizes.tiny}
|
||||
src={imageSizes.tiny}
|
||||
alt={metaData.altText}
|
||||
height={240}
|
||||
width={imageWidth}
|
||||
sizes={sizesString}
|
||||
className={styles.image}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
import Image from "@/components/Image"
|
||||
import Button from "@/components/TempDesignSystem/Button"
|
||||
import Link from "@/components/TempDesignSystem/Link"
|
||||
import SidePeek from "@/components/TempDesignSystem/SidePeek"
|
||||
@@ -7,6 +6,7 @@ import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
|
||||
import Title from "@/components/TempDesignSystem/Text/Title"
|
||||
import { getIntl } from "@/i18n"
|
||||
|
||||
import SidePeekImages from "../Images"
|
||||
import { getConferenceRoomTexts } from "./util"
|
||||
|
||||
import styles from "./meetingsAndConferences.module.css"
|
||||
@@ -22,18 +22,7 @@ export default async function MeetingsAndConferencesSidePeek({
|
||||
}: MeetingsAndConferencesSidePeekProps) {
|
||||
const intl = await getIntl()
|
||||
const { seatingText, roomText } = await getConferenceRoomTexts(meetingRooms)
|
||||
|
||||
const fallbackAlt = intl.formatMessage({
|
||||
defaultMessage: "Creative spaces for meetings",
|
||||
})
|
||||
|
||||
const primaryImage = meetingFacilities?.heroImages[0]?.imageSizes.medium
|
||||
const primaryAltText =
|
||||
meetingFacilities?.heroImages[0]?.metaData.altText || fallbackAlt
|
||||
|
||||
const secondaryImage = meetingFacilities?.heroImages[1]?.imageSizes.medium
|
||||
const secondaryAltText =
|
||||
meetingFacilities?.heroImages[1]?.metaData.altText || fallbackAlt
|
||||
const visibleImages = meetingFacilities?.heroImages.slice(0, 2)
|
||||
|
||||
return (
|
||||
<SidePeek
|
||||
@@ -50,26 +39,9 @@ export default async function MeetingsAndConferencesSidePeek({
|
||||
})}
|
||||
</Title>
|
||||
</Subtitle>
|
||||
{primaryImage && (
|
||||
<div className={secondaryImage ? styles.imageContainer : ""}>
|
||||
<Image
|
||||
src={primaryImage}
|
||||
alt={primaryAltText}
|
||||
height={300}
|
||||
width={200}
|
||||
className={styles.image}
|
||||
/>
|
||||
{secondaryImage && (
|
||||
<Image
|
||||
src={secondaryImage}
|
||||
alt={secondaryAltText}
|
||||
height={300}
|
||||
width={200}
|
||||
className={`${styles.image} ${styles.secondaryImage}`}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{visibleImages?.length ? (
|
||||
<SidePeekImages images={visibleImages} />
|
||||
) : null}
|
||||
{descriptions?.medium && (
|
||||
<Body color="uiTextHighContrast">{descriptions.medium}</Body>
|
||||
)}
|
||||
|
||||
@@ -6,17 +6,6 @@
|
||||
); /* Creates space between the wrapper and buttonContainer */
|
||||
}
|
||||
|
||||
.image {
|
||||
width: 100%;
|
||||
height: 300px;
|
||||
object-fit: cover;
|
||||
border-radius: var(--Corner-radius-md);
|
||||
}
|
||||
|
||||
.secondaryImage {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.buttonContainer {
|
||||
background-color: var(--Base-Background-Primary-Normal);
|
||||
border-top: 1px solid var(--Base-Border-Subtle);
|
||||
@@ -26,19 +15,3 @@
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 768px) {
|
||||
.imageContainer {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: var(--Spacing-x2);
|
||||
}
|
||||
|
||||
.image {
|
||||
height: 240px;
|
||||
}
|
||||
|
||||
.secondaryImage {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,11 +2,12 @@ import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||
|
||||
import ButtonLink from "@/components/ButtonLink"
|
||||
import Image from "@/components/Image"
|
||||
import OpeningHours from "@/components/OpeningHours"
|
||||
import Link from "@/components/TempDesignSystem/Link"
|
||||
import { getIntl } from "@/i18n"
|
||||
|
||||
import SidePeekImages from "../../Images"
|
||||
|
||||
import styles from "./restaurantBarItem.module.css"
|
||||
|
||||
import type { RestaurantBarItemProps } from "@/types/components/hotelPage/sidepeek/restaurantBar"
|
||||
@@ -24,9 +25,7 @@ export default async function RestaurantBarItem({
|
||||
restaurantPage,
|
||||
mainBody,
|
||||
} = restaurant
|
||||
const { images } = restaurant.content
|
||||
const visibleImages = restaurant.content.images.slice(0, 2)
|
||||
const imageWidth = images.length === 2 ? 240 : 496
|
||||
|
||||
return (
|
||||
<div className={styles.restaurantBarItem}>
|
||||
@@ -35,20 +34,7 @@ export default async function RestaurantBarItem({
|
||||
<h3 className={styles.heading}>{name}</h3>
|
||||
</Typography>
|
||||
</div>
|
||||
{visibleImages.length ? (
|
||||
<div className={styles.imageWrapper}>
|
||||
{visibleImages.map(({ metaData, imageSizes }) => (
|
||||
<Image
|
||||
key={imageSizes.tiny}
|
||||
src={imageSizes.tiny}
|
||||
alt={metaData.altText}
|
||||
width={imageWidth}
|
||||
height={240}
|
||||
className={styles.image}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
) : null}
|
||||
{visibleImages.length ? <SidePeekImages images={visibleImages} /> : null}
|
||||
<Typography variant="Body/Paragraph/mdRegular">
|
||||
<p>{content.texts.descriptions.short}</p>
|
||||
</Typography>
|
||||
|
||||
@@ -19,19 +19,6 @@
|
||||
bottom: -16px;
|
||||
}
|
||||
|
||||
.imageWrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--Space-x2);
|
||||
}
|
||||
|
||||
.image {
|
||||
border-radius: var(--Corner-radius-md);
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.content {
|
||||
display: grid;
|
||||
gap: var(--Space-x15);
|
||||
|
||||
@@ -4,13 +4,6 @@
|
||||
gap: var(--Spacing-x2);
|
||||
}
|
||||
|
||||
.image {
|
||||
width: 100%;
|
||||
height: 270px;
|
||||
object-fit: cover;
|
||||
border-radius: var(--Corner-radius-md);
|
||||
}
|
||||
|
||||
.information {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||
|
||||
import Image from "@/components/Image"
|
||||
import { getIntl } from "@/i18n"
|
||||
|
||||
import { translateWellnessType } from "../../../utils"
|
||||
import SidePeekImages from "../../Images"
|
||||
import { translateWellnessDetails } from "./utils"
|
||||
|
||||
import styles from "./facility.module.css"
|
||||
@@ -32,15 +32,7 @@ export default async function Facility({ data }: FacilityProps) {
|
||||
|
||||
return (
|
||||
<div className={styles.content}>
|
||||
{image?.imageSizes.medium && (
|
||||
<Image
|
||||
src={image.imageSizes.medium}
|
||||
alt={image.metaData.altText || ""}
|
||||
className={styles.image}
|
||||
height={400}
|
||||
width={200}
|
||||
/>
|
||||
)}
|
||||
{image ? <SidePeekImages images={[image]} /> : null}
|
||||
<div className={styles.information}>
|
||||
<Typography variant="Title/Subtitle/lg" className={styles.title}>
|
||||
<h3>{translateWellnessType(data.type, intl)}</h3>
|
||||
|
||||
Reference in New Issue
Block a user