feat: add mobile design to accordions

This commit is contained in:
Christel Westerberg
2024-11-11 10:15:47 +01:00
parent 66b2dc0c78
commit ee6aa8d188
9 changed files with 164 additions and 86 deletions

View File

@@ -5,7 +5,6 @@ import { useIntl } from "react-intl"
import { useEnterDetailsStore } from "@/stores/enter-details" import { useEnterDetailsStore } from "@/stores/enter-details"
import { CheckIcon, ChevronDownIcon } from "@/components/Icons" import { CheckIcon, ChevronDownIcon } from "@/components/Icons"
import Button from "@/components/TempDesignSystem/Button"
import Footnote from "@/components/TempDesignSystem/Text/Footnote" import Footnote from "@/components/TempDesignSystem/Text/Footnote"
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle" import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
@@ -72,9 +71,10 @@ export default function SectionAccordion({
</div> </div>
</div> </div>
<div className={styles.main}> <div className={styles.main}>
<header className={styles.headerContainer}> <header>
<div> <button onClick={onModify} className={styles.modifyButton}>
<Footnote <Footnote
className={styles.title}
asChild asChild
textTransform="uppercase" textTransform="uppercase"
type="label" type="label"
@@ -83,26 +83,17 @@ export default function SectionAccordion({
<h2>{header}</h2> <h2>{header}</h2>
</Footnote> </Footnote>
<Subtitle <Subtitle
type="two"
className={styles.selection} className={styles.selection}
type="two"
color="uiTextHighContrast" color="uiTextHighContrast"
> >
{title} {title}
</Subtitle> </Subtitle>
</div>
{isComplete && !isOpen && ( {isComplete && !isOpen && (
<Button <ChevronDownIcon className={styles.button} color="burgundy" />
onClick={onModify} )}
theme="base" </button>
size="small"
variant="icon"
intent="text"
wrapping
>
{intl.formatMessage({ id: "Modify" })}{" "}
<ChevronDownIcon color="burgundy" width={20} height={20} />
</Button>
)}
</header> </header>
<div className={styles.content}>{children}</div> <div className={styles.content}>{children}</div>
</div> </div>

View File

@@ -2,25 +2,33 @@
position: relative; position: relative;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
gap: var(--Spacing-x3); gap: var(--Spacing-x-one-and-half);
padding-top: var(--Spacing-x3); padding-top: var(--Spacing-x3);
} }
.wrapper:not(:last-child)::after {
position: absolute;
left: 12px;
bottom: 0;
top: var(--Spacing-x5);
height: 100%;
content: "";
border-left: 1px solid var(--Primary-Light-On-Surface-Divider-subtle);
}
.wrapper:last-child .main { .wrapper:last-child .main {
border-bottom: none; border-bottom: none;
} }
.modifyButton {
display: grid;
grid-template-areas: "title button" "selection button";
cursor: pointer;
background-color: transparent;
border: none;
width: 100%;
}
.title {
grid-area: title;
text-align: start;
}
.button {
grid-area: button;
justify-self: flex-end;
}
.main { .main {
display: grid; display: grid;
gap: var(--Spacing-x3); gap: var(--Spacing-x3);
@@ -31,21 +39,14 @@
grid-template-rows: 2em 0fr; grid-template-rows: 2em 0fr;
} }
.headerContainer {
display: flex;
justify-content: space-between;
align-items: center;
}
.selection { .selection {
font-weight: 450; font-weight: 450;
font-size: var(--typography-Title-4-fontSize); font-size: var(--typography-Title-4-fontSize);
grid-area: selection;
} }
.iconWrapper { .iconWrapper {
position: relative; position: relative;
top: var(--Spacing-x1);
z-index: 1;
} }
.circle { .circle {
@@ -78,3 +79,23 @@
.content { .content {
overflow: hidden; overflow: hidden;
} }
@media screen and (min-width: 1367px) {
.wrapper {
gap: var(--Spacing-x3);
}
.iconWrapper {
top: var(--Spacing-x1);
}
.wrapper:not(:last-child)::after {
position: absolute;
left: 12px;
bottom: 0;
top: var(--Spacing-x7);
height: 100%;
content: "";
border-left: 1px solid var(--Primary-Light-On-Surface-Divider-subtle);
}
}

View File

@@ -4,6 +4,7 @@ import { useIntl } from "react-intl"
import useSidePeekStore from "@/stores/sidepeek" import useSidePeekStore from "@/stores/sidepeek"
import ChevronRight from "@/components/Icons/ChevronRight"
import Button from "@/components/TempDesignSystem/Button" import Button from "@/components/TempDesignSystem/Button"
import { SidePeekEnum } from "@/types/components/hotelReservation/sidePeek" import { SidePeekEnum } from "@/types/components/hotelReservation/sidePeek"
@@ -28,6 +29,7 @@ export default function ToggleSidePeek({
wrapping wrapping
> >
{intl.formatMessage({ id: "See room details" })}{" "} {intl.formatMessage({ id: "See room details" })}{" "}
<ChevronRight height="14" />
</Button> </Button>
) )
} }

View File

@@ -33,26 +33,25 @@ export default function SelectedRoom({
</div> </div>
<div className={styles.main}> <div className={styles.main}>
<div className={styles.headerContainer}> <div className={styles.headerContainer}>
<div> <Footnote
<Footnote className={styles.title}
asChild asChild
textTransform="uppercase" textTransform="uppercase"
type="label" type="label"
color="uiTextHighContrast" color="uiTextHighContrast"
> >
<h2>{intl.formatMessage({ id: "Your room" })}</h2> <h2>{intl.formatMessage({ id: "Your room" })}</h2>
</Footnote> </Footnote>
<Subtitle <Subtitle
type="two" type="two"
className={styles.selection} className={styles.description}
color="uiTextHighContrast" color="uiTextHighContrast"
> >
{room.roomType}{" "} {room.roomType}{" "}
<span className={styles.rate}>{`(${rateDescription})`}</span> <span className={styles.rate}>{rateDescription}</span>
</Subtitle> </Subtitle>
</div>
<Link <Link
className={styles.button}
color="burgundy" color="burgundy"
href={selectRateUrl} href={selectRateUrl}
size="small" size="small"

View File

@@ -2,43 +2,42 @@
position: relative; position: relative;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
gap: var(--Spacing-x3); gap: var(--Spacing-x-one-and-half);
padding-top: var(--Spacing-x3); padding-top: var(--Spacing-x3);
} }
.wrapper::after {
position: absolute;
left: 12px;
bottom: 0;
top: var(--Spacing-x5);
height: 100%;
content: "";
border-left: 1px solid var(--Primary-Light-On-Surface-Divider-subtle);
}
.main { .main {
display: grid;
width: 100%; width: 100%;
border-bottom: 1px solid var(--Primary-Light-On-Surface-Divider-subtle); border-bottom: 1px solid var(--Primary-Light-On-Surface-Divider-subtle);
padding-bottom: var(--Spacing-x3); padding-bottom: var(--Spacing-x3);
grid-template-rows: 2em 0fr;
} }
.headerContainer { .headerContainer {
display: flex; display: grid;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
grid-template-areas:
"title button"
"description button";
} }
.selection { .title {
grid-area: title;
}
.description {
font-weight: 450; font-weight: 450;
font-size: var(--typography-Title-4-fontSize); font-size: var(--typography-Title-4-fontSize);
grid-area: description;
}
.button {
grid-area: button;
justify-self: flex-end;
} }
.iconWrapper { .iconWrapper {
position: relative; position: relative;
top: var(--Spacing-x1);
z-index: 1;
} }
.circle { .circle {
@@ -57,9 +56,41 @@
.rate { .rate {
color: var(--UI-Text-Placeholder); color: var(--UI-Text-Placeholder);
display: block;
} }
.details { .details {
display: flex; display: flex;
justify-content: flex-start; justify-content: flex-start;
} }
@media screen and (min-width: 1367px) {
.wrapper {
gap: var(--Spacing-x3);
}
.iconWrapper {
top: var(--Spacing-x1);
}
.rate {
display: inline;
}
.rate::before {
content: "(";
}
.rate::after {
content: ")";
}
.wrapper:not(:last-child)::after {
position: absolute;
left: 12px;
bottom: 0;
top: var(--Spacing-x7);
height: 100%;
content: "";
border-left: 1px solid var(--Primary-Light-On-Surface-Divider-subtle);
}
}

View File

@@ -19,7 +19,7 @@
transition: 0.5s ease-in-out; transition: 0.5s ease-in-out;
} }
.priceDetails { .priceDetailsButton {
display: block; display: block;
border: none; border: none;
background: none; background: none;
@@ -28,6 +28,7 @@
transition: transition:
opacity 0.5s ease-in-out, opacity 0.5s ease-in-out,
padding 0.5s ease-in-out; padding 0.5s ease-in-out;
cursor: pointer;
} }
.wrapper[data-open="true"] { .wrapper[data-open="true"] {
@@ -38,12 +39,12 @@
grid-template-columns: 0fr 1fr; grid-template-columns: 0fr 1fr;
} }
.wrapper[data-open="true"] .priceDetails { .wrapper[data-open="true"] .priceDetailsButton {
opacity: 0; opacity: 0;
padding: 0; padding: 0;
} }
.content, .content,
.priceDetails { .priceDetailsButton {
overflow: hidden; overflow: hidden;
} }

View File

@@ -8,7 +8,6 @@ import { useEnterDetailsStore } from "@/stores/enter-details"
import Button from "@/components/TempDesignSystem/Button" import Button from "@/components/TempDesignSystem/Button"
import Caption from "@/components/TempDesignSystem/Text/Caption" import Caption from "@/components/TempDesignSystem/Text/Caption"
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle" import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
import { formatNumber } from "@/utils/format"
import styles from "./bottomSheet.module.css" import styles from "./bottomSheet.module.css"
@@ -30,14 +29,14 @@ export function SummaryBottomSheet({ children }: PropsWithChildren) {
<button <button
data-open={isSummaryOpen} data-open={isSummaryOpen}
onClick={toggleSummaryOpen} onClick={toggleSummaryOpen}
className={styles.priceDetails} className={styles.priceDetailsButton}
> >
<Caption>{intl.formatMessage({ id: "Total price" })}:</Caption> <Caption>{intl.formatMessage({ id: "Total price" })}:</Caption>
<Subtitle> <Subtitle>
{intl.formatMessage( {intl.formatMessage(
{ id: "{amount} {currency}" }, { id: "{amount} {currency}" },
{ {
amount: formatNumber(totalPrice.local.price), amount: intl.formatNumber(totalPrice.local.price),
currency: totalPrice.local.currency, currency: totalPrice.local.currency,
} }
)} )}

View File

@@ -1,12 +1,14 @@
"use client" "use client"
import { useEffect, useState } from "react" import { useEffect, useState } from "react"
import { ChevronDown } from "react-feather"
import { useIntl } from "react-intl" import { useIntl } from "react-intl"
import { dt } from "@/lib/dt" import { dt } from "@/lib/dt"
import { useEnterDetailsStore } from "@/stores/enter-details" import { useEnterDetailsStore } from "@/stores/enter-details"
import { ArrowRightIcon, CloseIcon } from "@/components/Icons" import { ArrowRightIcon } from "@/components/Icons"
import Button from "@/components/TempDesignSystem/Button"
import Divider from "@/components/TempDesignSystem/Divider" import Divider from "@/components/TempDesignSystem/Divider"
import Link from "@/components/TempDesignSystem/Link" import Link from "@/components/TempDesignSystem/Link"
import Body from "@/components/TempDesignSystem/Text/Body" import Body from "@/components/TempDesignSystem/Text/Body"
@@ -116,18 +118,25 @@ export default function Summary({
}) })
}, [room.localPrice, room.euroPrice, setTotalPrice]) }, [room.localPrice, room.euroPrice, setTotalPrice])
const showToggleButton = true
return ( return (
<section className={styles.summary}> <section className={styles.summary}>
<header> <header className={styles.header}>
<Subtitle type="two">{intl.formatMessage({ id: "Summary" })}</Subtitle> <Subtitle className={styles.title} type="two">
{intl.formatMessage({ id: "Summary" })}
</Subtitle>
<Body className={styles.date} color="baseTextMediumContrast"> <Body className={styles.date} color="baseTextMediumContrast">
{dt(fromDate).locale(lang).format("ddd, D MMM")} {dt(fromDate).locale(lang).format("ddd, D MMM")}
<ArrowRightIcon color="peach80" height={15} width={15} /> <ArrowRightIcon color="peach80" height={15} width={15} />
{dt(toDate).locale(lang).format("ddd, D MMM")} ({nights}) {dt(toDate).locale(lang).format("ddd, D MMM")} ({nights})
</Body> </Body>
{showToggleButton ? <CloseIcon onClick={toggleSummaryOpen} /> : null} <Button
intent="text"
size="small"
className={styles.chevronButton}
onClick={toggleSummaryOpen}
>
<ChevronDown height="20" width="20" />
</Button>
</header> </header>
<Divider color="primaryLightSubtle" /> <Divider color="primaryLightSubtle" />
<div className={styles.addOns}> <div className={styles.addOns}>

View File

@@ -7,11 +7,28 @@
height: 100%; height: 100%;
} }
.header {
display: grid;
grid-template-areas: "title button" "date button";
}
.title {
grid-area: title;
}
.chevronButton {
grid-area: button;
justify-self: end;
align-items: center;
margin-right: calc(0px - var(--Spacing-x2));
}
.date { .date {
align-items: center; align-items: center;
display: flex; display: flex;
gap: var(--Spacing-x1); gap: var(--Spacing-x1);
justify-content: flex-start; justify-content: flex-start;
grid-area: date;
} }
.link { .link {
@@ -47,4 +64,12 @@
.bottomDivider { .bottomDivider {
display: block; display: block;
} }
.header {
display: block;
}
.chevronButton {
display: none;
}
} }