feat(SW-2042): Synced sidebar ui with design

Approved-by: Christian Andolf
Approved-by: Matilda Landström
This commit is contained in:
Erik Tiekstra
2025-06-02 09:37:39 +00:00
parent 09879d2f4a
commit 5d6776c383
8 changed files with 81 additions and 70 deletions

View File

@@ -1,18 +1,18 @@
.hotelListWrapper { .hotelListWrapper {
display: grid; display: grid;
gap: var(--Spacing-x3); gap: var(--Space-x3);
} }
.header { .header {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
gap: var(--Spacing-x2); gap: var(--Space-x2);
} }
.hotelList { .hotelList {
display: grid; display: grid;
gap: var(--Spacing-x3); gap: var(--Space-x3);
list-style: none; list-style: none;
} }

View File

@@ -4,10 +4,11 @@ import { useMap, useMapsLibrary } from "@vis.gl/react-google-maps"
import { useEffect, useMemo, useState } from "react" import { useEffect, useMemo, useState } from "react"
import { useIntl } from "react-intl" import { useIntl } from "react-intl"
import { Typography } from "@scandic-hotels/design-system/Typography"
import { useDestinationDataStore } from "@/stores/destination-data" import { useDestinationDataStore } from "@/stores/destination-data"
import DestinationFilterAndSort from "@/components/DestinationFilterAndSort" import DestinationFilterAndSort from "@/components/DestinationFilterAndSort"
import Body from "@/components/TempDesignSystem/Text/Body"
import { debounce } from "@/utils/debounce" import { debounce } from "@/utils/debounce"
import HotelListContent from "./Content" import HotelListContent from "./Content"
@@ -60,14 +61,16 @@ export default function HotelList() {
return ( return (
<div className={styles.hotelListWrapper}> <div className={styles.hotelListWrapper}>
<div className={styles.header}> <div className={styles.header}>
<Body> <Typography variant="Body/Paragraph/mdRegular">
<p>
{intl.formatMessage( {intl.formatMessage(
{ {
defaultMessage: "{count} hotels", defaultMessage: "{count} hotels",
}, },
{ count: visibleHotels.length } { count: visibleHotels.length }
)} )}
</Body> </p>
</Typography>
<DestinationFilterAndSort listType="hotel" /> <DestinationFilterAndSort listType="hotel" />
</div> </div>

View File

@@ -1,9 +1,10 @@
.hotelListItem { .hotelListItem {
display: grid; display: grid;
background-color: var(--Base-Surface-Primary-light-Normal); background-color: var(--Surface-Primary-Default);
border: 1px solid var(--Base-Border-Subtle); border: 1px solid var(--Border-Default);
border-radius: var(--Corner-radius-md); border-radius: var(--Corner-radius-md);
overflow: hidden; overflow: hidden;
scroll-margin-top: var(--Space-x2);
} }
.activeCard { .activeCard {
@@ -13,8 +14,8 @@
.content { .content {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: var(--Spacing-x2); gap: var(--Space-x2);
padding: var(--Spacing-x2) var(--Spacing-x3); padding: var(--Space-x2) var(--Space-x3);
align-content: flex-start; align-content: flex-start;
justify-items: flex-start; justify-items: flex-start;
} }
@@ -30,25 +31,22 @@
left: 16px; left: 16px;
display: flex; display: flex;
align-items: center; align-items: center;
gap: var(--Spacing-x-half); gap: var(--Space-x05);
background-color: var(--Base-Surface-Primary-light-Normal); background-color: var(--Surface-Primary-Default);
padding: var(--Spacing-x-quarter) var(--Spacing-x1); padding: var(--Space-x025) var(--Space-x1);
border-radius: var(--Corner-radius-sm); border-radius: var(--Corner-radius-sm);
color: var(--Text-Interactive-Default); color: var(--Text-Interactive-Default);
} }
.hotelName {
color: var(--Text-Default);
}
.intro { .intro {
display: grid; display: grid;
gap: var(--Spacing-x-half); gap: var(--Space-x05);
} }
.captions { .captions {
display: flex; display: flex;
gap: var(--Spacing-x1); column-gap: var(--Space-x1);
flex-wrap: wrap;
color: var(--Text-Tertiary); color: var(--Text-Tertiary);
} }
@@ -66,14 +64,14 @@
.amenityList { .amenityList {
display: flex; display: flex;
gap: var(--Spacing-x-one-and-half); gap: var(--Space-x025) var(--Space-x1);
flex-wrap: wrap; flex-wrap: wrap;
color: var(--Text-Secondary); color: var(--Text-Secondary);
} }
.amenityItem { .amenityItem {
display: flex; display: flex;
gap: var(--Spacing-x-half); gap: var(--Space-x05);
align-items: center; align-items: center;
} }
@@ -98,8 +96,8 @@
} }
.content { .content {
padding: var(--Spacing-x-one-and-half); padding: var(--Space-x15);
gap: var(--Spacing-x1); gap: var(--Space-x1);
} }
.logo, .logo,

View File

@@ -38,7 +38,7 @@ export default function HotelListItem(data: DestinationPagesHotelData) {
if (element) { if (element) {
element.scrollIntoView({ element.scrollIntoView({
behavior: "smooth", behavior: "smooth",
block: "nearest", block: "start",
inline: "start", inline: "start",
}) })
} }
@@ -89,10 +89,10 @@ export default function HotelListItem(data: DestinationPagesHotelData) {
<HotelLogoIcon hotelId={hotel.id} hotelType={hotel.hotelType} /> <HotelLogoIcon hotelId={hotel.id} hotelType={hotel.hotelType} />
</div> </div>
<Typography variant="Title/Subtitle/lg"> <Typography variant="Title/Subtitle/lg">
<h3 className={styles.hotelName}>{hotel.name}</h3> <h3>{hotel.name}</h3>
</Typography> </Typography>
<Typography variant="Body/Supporting text (caption)/smRegular"> <Typography variant="Body/Supporting text (caption)/smRegular">
<div className={styles.captions}> <p className={styles.captions}>
<Typography variant="Link/sm"> <Typography variant="Link/sm">
<ButtonRAC <ButtonRAC
className={styles.addressButton} className={styles.addressButton}
@@ -101,8 +101,14 @@ export default function HotelListItem(data: DestinationPagesHotelData) {
{address} {address}
</ButtonRAC> </ButtonRAC>
</Typography> </Typography>
<Divider variant="vertical" color="beige" /> <span>
<p> <Divider
className={styles.divider}
variant="vertical"
color="Border/Divider/Default"
/>
</span>
<span>
{intl.formatMessage( {intl.formatMessage(
{ {
defaultMessage: "{number} km to city center", defaultMessage: "{number} km to city center",
@@ -113,8 +119,8 @@ export default function HotelListItem(data: DestinationPagesHotelData) {
), ),
} }
)} )}
</span>
</p> </p>
</div>
</Typography> </Typography>
</div> </div>
<Typography variant="Body/Supporting text (caption)/smRegular"> <Typography variant="Body/Supporting text (caption)/smRegular">

View File

@@ -1,51 +1,57 @@
.mapWrapper { .mapWrapper {
position: fixed; position: fixed;
display: flex; display: flex;
flex-direction: column;
height: 100dvh; height: 100dvh;
width: 100dvw; width: 100dvw;
background-color: var(--Base-Surface-Primary-light-Normal); background-color: var(--Background-Primary);
z-index: 1; z-index: 1;
} }
.sidebar { .sidebar {
width: 100%;
max-width: 500px;
background-color: var(--Base-Surface-Primary-Normal);
overflow-y: auto;
padding: var(--Spacing-x4);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: var(--Spacing-x4); gap: var(--Space-x4);
} }
.closeButton { .closeButton {
pointer-events: initial; pointer-events: initial;
box-shadow: var(--button-box-shadow); box-shadow: var(--button-box-shadow);
gap: var(--Spacing-x-half); gap: var(--Space-x05);
} }
.mobileNavigation { .mobileNavigation {
display: none; display: flex;
padding: var(--Space-x2);
justify-content: space-between;
background-color: var(--Surface-Primary-OnSurface-Default);
} }
@media screen and (max-width: 949px) { @media screen and (max-width: 949px) {
.mapWrapper {
flex-direction: column;
}
.mobileNavigation {
display: flex;
padding: var(--Spacing-x2);
justify-content: space-between;
background-color: var(--Surface-Primary-OnSurface-Default);
}
.sidebar { .sidebar {
position: absolute; position: absolute;
max-width: none; width: 100%;
padding: 0 0 var(--Spacing-x2) 0; padding-bottom: var(--Space-x2);
overflow: hidden; overflow: hidden;
bottom: 0; bottom: 0;
z-index: 3; z-index: 3;
} }
} }
@media screen and (min-width: 950px) {
.mapWrapper {
flex-direction: row;
}
.sidebar {
width: 420px;
flex-shrink: 0;
overflow-y: auto;
padding: var(--Space-x5);
background-color: var(--Background-Primary);
}
.mobileNavigation {
display: none;
}
}

View File

@@ -7,16 +7,15 @@
.imageCount { .imageCount {
position: absolute; position: absolute;
bottom: 16px; bottom: var(--Space-x2);
right: 16px; right: var(--Space-x2);
max-height: 32px; background-color: var(--Overlay-90);
width: 48px; padding: var(--Space-x025) var(--Space-x05);
background-color: rgba(0, 0, 0, 0.6);
padding: var(--Spacing-x-quarter) var(--Spacing-x-half);
border-radius: var(--Corner-radius-sm); border-radius: var(--Corner-radius-sm);
display: flex; display: flex;
align-items: center; align-items: center;
gap: var(--Spacing-x-quarter); justify-content: center;
gap: var(--Space-x025);
color: var(--Text-Inverted); color: var(--Text-Inverted);
} }
@@ -40,7 +39,6 @@
.imagePlaceholder { .imagePlaceholder {
height: 100%; height: 100%;
min-height: 190px; min-height: 190px;
aspect-ratio: 16/9;
width: 100%; width: 100%;
background-color: #fff; background-color: #fff;
background-image: background-image:

View File

@@ -1,7 +1,7 @@
"use client" "use client"
import { memo, useState } from "react" import { memo, useState } from "react"
import { Button } from "react-aria-components" import { Button as ButtonRAC } from "react-aria-components"
import { useIntl } from "react-intl" import { useIntl } from "react-intl"
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
@@ -45,11 +45,11 @@ function ImageGallery({
/> />
<Typography variant={"Body/Supporting text (caption)/smRegular"}> <Typography variant={"Body/Supporting text (caption)/smRegular"}>
<span className={styles.imageCount}> <span className={styles.imageCount}>
<MaterialIcon icon="filter" color="Icon/Inverted" /> <MaterialIcon icon="filter" color="Icon/Inverted" size={16} />
<span>{images.length}</span> <span>{images.length}</span>
</span> </span>
</Typography> </Typography>
<Button <ButtonRAC
className={styles.triggerArea} className={styles.triggerArea}
onPress={() => setIsOpen(true)} onPress={() => setIsOpen(true)}
aria-label={intl.formatMessage({ aria-label={intl.formatMessage({

View File

@@ -1,11 +1,11 @@
.divider { .divider {
pointer-events: none; pointer-events: none;
border: 0;
} }
.horizontal { .horizontal {
height: 1px; height: 1px;
width: 100%; width: 100%;
border: 0;
} }
.vertical { .vertical {