feat(SW-2227): Implemented new design for room package filters
Approved-by: Arvid Norlin
This commit is contained in:
@@ -41,35 +41,35 @@ export default function SpecialRequests() {
|
|||||||
TODO: Hiding because API is not ready for this yet (https://scandichotels.atlassian.net/browse/SW-1497). Add back in when API is ready.
|
TODO: Hiding because API is not ready for this yet (https://scandichotels.atlassian.net/browse/SW-1497). Add back in when API is ready.
|
||||||
|
|
||||||
<Select
|
<Select
|
||||||
label={intl.formatMessage({ id: "Floor preference" })}
|
label={intl.formatMessage({ defaultMessage: "Floor preference" })}
|
||||||
name="specialRequest.floorPreference"
|
name="specialRequest.floorPreference"
|
||||||
items={[
|
items={[
|
||||||
noPreferenceItem,
|
noPreferenceItem,
|
||||||
{
|
{
|
||||||
value: FloorPreference.HIGH,
|
value: FloorPreference.HIGH,
|
||||||
label: intl.formatMessage({ id: "High floor" }),
|
label: intl.formatMessage({ defaultMessage: "High floor" }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: FloorPreference.LOW,
|
value: FloorPreference.LOW,
|
||||||
label: intl.formatMessage({ id: "Low floor" }),
|
label: intl.formatMessage({ defaultMessage: "Low floor" }),
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<Select
|
<Select
|
||||||
label={intl.formatMessage({ id: "Elevator preference" })}
|
label={intl.formatMessage({ defaultMessage: "Elevator preference" })}
|
||||||
name="specialRequest.elevatorPreference"
|
name="specialRequest.elevatorPreference"
|
||||||
items={[
|
items={[
|
||||||
noPreferenceItem,
|
noPreferenceItem,
|
||||||
{
|
{
|
||||||
value: ElevatorPreference.AWAY_FROM_ELEVATOR,
|
value: ElevatorPreference.AWAY_FROM_ELEVATOR,
|
||||||
label: intl.formatMessage({
|
label: intl.formatMessage({
|
||||||
id: "Away from elevator",
|
defaultMessage: "Away from elevator",
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: ElevatorPreference.NEAR_ELEVATOR,
|
value: ElevatorPreference.NEAR_ELEVATOR,
|
||||||
label: intl.formatMessage({
|
label: intl.formatMessage({
|
||||||
id: "Near elevator",
|
defaultMessage: "Near elevator",
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
|
|||||||
@@ -1,52 +1,76 @@
|
|||||||
|
.checkboxGroup {
|
||||||
|
display: grid;
|
||||||
|
gap: var(--Space-x15);
|
||||||
|
}
|
||||||
|
|
||||||
.checkboxWrapper {
|
.checkboxWrapper {
|
||||||
|
display: grid;
|
||||||
|
gap: var(--Space-x05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkboxField {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: auto 1fr auto;
|
grid-template-columns: auto 1fr auto;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: var(--Spacing-x-one-and-half);
|
gap: var(--Space-x15);
|
||||||
padding: var(--Spacing-x1) var(--Spacing-x-one-and-half);
|
padding: var(--Space-x1) var(--Space-x15);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border-radius: var(--Corner-radius-Medium);
|
border-radius: var(--Corner-radius-Medium);
|
||||||
transition: background-color 0.3s;
|
transition: background-color 0.3s;
|
||||||
color: var(--Text-Default);
|
color: var(--Text-Default);
|
||||||
}
|
|
||||||
|
|
||||||
.checkboxWrapper:hover {
|
&[data-disabled] {
|
||||||
background-color: var(--UI-Input-Controls-Surface-Hover);
|
cursor: unset;
|
||||||
|
|
||||||
|
.checkbox {
|
||||||
|
border-color: var(--Border-Interactive-Disabled);
|
||||||
|
background-color: var(--Surface-UI-Fill-Disabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
.text {
|
||||||
|
color: var(--Base-Text-Disabled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover:not([data-disabled]) {
|
||||||
|
background-color: var(--UI-Input-Controls-Surface-Hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
&[data-focus-visible] .checkbox {
|
||||||
|
/* Used this value as it makes sense from a token name perspective and has a good contrast, but we need to decide for a default ui state */
|
||||||
|
outline: 2px solid var(--Border-Interactive-Focus);
|
||||||
|
outline-offset: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&[data-selected] .checkbox {
|
||||||
|
border-color: var(--Surface-UI-Fill-Active);
|
||||||
|
background-color: var(--Surface-UI-Fill-Active);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.checkbox {
|
.checkbox {
|
||||||
width: 24px;
|
width: 24px;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
min-width: 24px;
|
min-width: 24px;
|
||||||
border: 1px solid var(--UI-Input-Controls-Border-Normal);
|
border: 1px solid var(--Border-Interactive-Default);
|
||||||
border-radius: var(--Corner-radius-Small);
|
border-radius: var(--Corner-radius-Small);
|
||||||
transition: all 0.3s;
|
transition: all 0.3s;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
background-color: var(--UI-Input-Controls-Surface-Normal);
|
background-color: var(--Surface-UI-Fill-Default);
|
||||||
}
|
}
|
||||||
|
|
||||||
.checkboxWrapper[data-selected] .checkbox {
|
.text {
|
||||||
border-color: var(--UI-Input-Controls-Fill-Selected);
|
color: var(--Text-Default);
|
||||||
background-color: var(--UI-Input-Controls-Fill-Selected);
|
|
||||||
}
|
|
||||||
|
|
||||||
.checkboxWrapper[data-disabled] .checkbox {
|
|
||||||
border-color: var(--UI-Input-Controls-Border-Disabled);
|
|
||||||
background-color: var(--UI-Input-Controls-Surface-Disabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
.checkboxWrapper[data-disabled] .text {
|
|
||||||
color: var(--Base-Text-Disabled);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 767px) {
|
@media screen and (max-width: 767px) {
|
||||||
.checkboxWrapper:hover {
|
.checkboxField:hover:not([data-disabled]) {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.checkboxWrapper[data-selected] {
|
.checkboxField[data-selected] {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
"use client"
|
"use client"
|
||||||
import { Fragment } from "react"
|
|
||||||
import { Checkbox, CheckboxGroup } from "react-aria-components"
|
import { Checkbox, CheckboxGroup } from "react-aria-components"
|
||||||
import { Controller, useFormContext } from "react-hook-form"
|
import { Controller, useFormContext } from "react-hook-form"
|
||||||
|
|
||||||
@@ -32,46 +31,44 @@ export default function Checkboxes() {
|
|||||||
const allergyRoomSelected = includesAllergyRoom(field.value)
|
const allergyRoomSelected = includesAllergyRoom(field.value)
|
||||||
const petRoomSelected = includesPetRoom(field.value)
|
const petRoomSelected = includesPetRoom(field.value)
|
||||||
return (
|
return (
|
||||||
<CheckboxGroup {...field}>
|
<CheckboxGroup {...field} className={styles.checkboxGroup}>
|
||||||
<div>
|
{packageOptions.map((option) => {
|
||||||
{packageOptions.map((option) => {
|
const isAllergyRoom = checkIsAllergyRoom(option.code)
|
||||||
const isAllergyRoom = checkIsAllergyRoom(option.code)
|
const isPetRoom = checkIsPetRoom(option.code)
|
||||||
const isPetRoom = checkIsPetRoom(option.code)
|
const isDisabled =
|
||||||
const isDisabled =
|
(isPetRoom && allergyRoomSelected) ||
|
||||||
(isPetRoom && allergyRoomSelected) ||
|
(isAllergyRoom && petRoomSelected)
|
||||||
(isAllergyRoom && petRoomSelected)
|
|
||||||
|
|
||||||
const isSelected = field.value.includes(option.code)
|
const isSelected = field.value.includes(option.code)
|
||||||
const iconName = getIconNameByPackageCode(option.code)
|
const iconName = getIconNameByPackageCode(option.code)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment key={option.code}>
|
<div key={option.code} className={styles.checkboxWrapper}>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
key={option.code}
|
key={option.code}
|
||||||
className={styles.checkboxWrapper}
|
className={styles.checkboxField}
|
||||||
isDisabled={isDisabled}
|
isDisabled={isDisabled}
|
||||||
value={option.code}
|
value={option.code}
|
||||||
>
|
>
|
||||||
<span className={styles.checkbox}>
|
<span className={styles.checkbox}>
|
||||||
{isSelected ? (
|
{isSelected ? (
|
||||||
<MaterialIcon icon="check" color="Icon/Inverted" />
|
<MaterialIcon icon="check" color="Icon/Inverted" />
|
||||||
) : null}
|
|
||||||
</span>
|
|
||||||
<Typography
|
|
||||||
className={styles.text}
|
|
||||||
variant="Body/Paragraph/mdRegular"
|
|
||||||
>
|
|
||||||
<span>{option.description}</span>
|
|
||||||
</Typography>
|
|
||||||
{iconName ? (
|
|
||||||
<MaterialIcon icon={iconName} color="Icon/Default" />
|
|
||||||
) : null}
|
) : null}
|
||||||
</Checkbox>
|
</span>
|
||||||
{isPetRoom ? <PetRoomMessage /> : null}
|
<Typography
|
||||||
</Fragment>
|
className={styles.text}
|
||||||
)
|
variant="Body/Paragraph/mdRegular"
|
||||||
})}
|
>
|
||||||
</div>
|
<span>{option.description}</span>
|
||||||
|
</Typography>
|
||||||
|
{iconName ? (
|
||||||
|
<MaterialIcon icon={iconName} color="Icon/Default" />
|
||||||
|
) : null}
|
||||||
|
</Checkbox>
|
||||||
|
{isPetRoom ? <PetRoomMessage /> : null}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})}
|
||||||
</CheckboxGroup>
|
</CheckboxGroup>
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -1,11 +1,30 @@
|
|||||||
.footer {
|
.footer {
|
||||||
display: grid;
|
|
||||||
gap: var(--Space-x1);
|
|
||||||
padding: 0 var(--Space-x15);
|
padding: 0 var(--Space-x15);
|
||||||
}
|
}
|
||||||
|
|
||||||
.buttonContainer {
|
.buttonContainer {
|
||||||
align-items: center;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
flex-direction: column;
|
||||||
|
gap: var(--Space-x1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.divider {
|
||||||
|
margin: var(--Space-x15) 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 767px) {
|
||||||
|
.divider {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.footer {
|
||||||
|
margin-top: var(--Space-x5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 768px) {
|
||||||
|
.buttonContainer {
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,8 +74,13 @@ export default function Form({ close }: { close: VoidFunction }) {
|
|||||||
<form onSubmit={methods.handleSubmit(onSubmit)}>
|
<form onSubmit={methods.handleSubmit(onSubmit)}>
|
||||||
<Checkboxes />
|
<Checkboxes />
|
||||||
<div className={styles.footer}>
|
<div className={styles.footer}>
|
||||||
<Divider color="borderDividerSubtle" />
|
<Divider color="borderDividerSubtle" className={styles.divider} />
|
||||||
<div className={styles.buttonContainer}>
|
<div className={styles.buttonContainer}>
|
||||||
|
<Typography variant="Body/Supporting text (caption)/smBold">
|
||||||
|
<Button variant="Tertiary" size="Small" type="submit">
|
||||||
|
{intl.formatMessage({ defaultMessage: "Apply" })}
|
||||||
|
</Button>
|
||||||
|
</Typography>
|
||||||
<Typography variant="Body/Supporting text (caption)/smBold">
|
<Typography variant="Body/Supporting text (caption)/smBold">
|
||||||
<Button
|
<Button
|
||||||
onPress={clearSelectedPackages}
|
onPress={clearSelectedPackages}
|
||||||
@@ -87,13 +92,6 @@ export default function Form({ close }: { close: VoidFunction }) {
|
|||||||
})}
|
})}
|
||||||
</Button>
|
</Button>
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="Body/Supporting text (caption)/smBold">
|
|
||||||
<Button variant="Tertiary" size="Small" type="submit">
|
|
||||||
{intl.formatMessage({
|
|
||||||
defaultMessage: "Apply",
|
|
||||||
})}
|
|
||||||
</Button>
|
|
||||||
</Typography>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
import { useState } from "react"
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogTrigger,
|
||||||
|
Modal,
|
||||||
|
ModalOverlay,
|
||||||
|
} from "react-aria-components"
|
||||||
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
|
import { Button } from "@scandic-hotels/design-system/Button"
|
||||||
|
import { ChipButton } from "@scandic-hotels/design-system/ChipButton"
|
||||||
|
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
||||||
|
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||||
|
|
||||||
|
import Form from "./Form"
|
||||||
|
|
||||||
|
import styles from "./roomPackageFilter.module.css"
|
||||||
|
|
||||||
|
export default function RoomPackageFilterModal() {
|
||||||
|
const intl = useIntl()
|
||||||
|
const [isOpen, setIsOpen] = useState(false)
|
||||||
|
return (
|
||||||
|
<DialogTrigger isOpen={isOpen} onOpenChange={setIsOpen}>
|
||||||
|
<ChipButton variant="Outlined">
|
||||||
|
{intl.formatMessage({ defaultMessage: "Room preferences" })}
|
||||||
|
<MaterialIcon
|
||||||
|
icon="keyboard_arrow_down"
|
||||||
|
size={20}
|
||||||
|
color="CurrentColor"
|
||||||
|
/>
|
||||||
|
</ChipButton>
|
||||||
|
|
||||||
|
<ModalOverlay className={styles.modalOverlay} isDismissable>
|
||||||
|
<Modal className={styles.modal}>
|
||||||
|
<Dialog className={styles.modalDialog}>
|
||||||
|
<div className={styles.header}>
|
||||||
|
<Typography variant="Title/Subtitle/md">
|
||||||
|
<h3>
|
||||||
|
{intl.formatMessage({ defaultMessage: "Room preferences" })}
|
||||||
|
</h3>
|
||||||
|
</Typography>
|
||||||
|
<Button variant="Icon" onPress={() => setIsOpen(false)}>
|
||||||
|
<MaterialIcon icon="close" size={24} color="CurrentColor" />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<Form close={() => setIsOpen(false)} />
|
||||||
|
</Dialog>
|
||||||
|
</Modal>
|
||||||
|
</ModalOverlay>
|
||||||
|
</DialogTrigger>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import { useState } from "react"
|
||||||
|
import { Dialog, DialogTrigger, Popover } from "react-aria-components"
|
||||||
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
|
import { ChipButton } from "@scandic-hotels/design-system/ChipButton"
|
||||||
|
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
||||||
|
|
||||||
|
import Form from "./Form"
|
||||||
|
|
||||||
|
import styles from "./roomPackageFilter.module.css"
|
||||||
|
|
||||||
|
export default function RoomPackageFilterPopover() {
|
||||||
|
const intl = useIntl()
|
||||||
|
const [isOpen, setIsOpen] = useState(false)
|
||||||
|
return (
|
||||||
|
<DialogTrigger isOpen={isOpen} onOpenChange={setIsOpen}>
|
||||||
|
<ChipButton variant="Outlined">
|
||||||
|
{intl.formatMessage({ defaultMessage: "Room preferences" })}
|
||||||
|
<MaterialIcon
|
||||||
|
icon="keyboard_arrow_down"
|
||||||
|
size={20}
|
||||||
|
color="CurrentColor"
|
||||||
|
/>
|
||||||
|
</ChipButton>
|
||||||
|
|
||||||
|
<Popover placement="bottom end" className={styles.popover}>
|
||||||
|
<Dialog className={styles.popoverDialog}>
|
||||||
|
<Form close={() => setIsOpen(false)} />
|
||||||
|
</Dialog>
|
||||||
|
</Popover>
|
||||||
|
</DialogTrigger>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,15 +1,9 @@
|
|||||||
"use client"
|
"use client"
|
||||||
import { useState } from "react"
|
import { Button as AriaButton } from "react-aria-components"
|
||||||
import {
|
import { useMediaQuery } from "usehooks-ts"
|
||||||
Button as AriaButton,
|
|
||||||
Dialog,
|
|
||||||
DialogTrigger,
|
|
||||||
Popover,
|
|
||||||
} from "react-aria-components"
|
|
||||||
import { useIntl } from "react-intl"
|
|
||||||
|
|
||||||
import { ChipButton } from "@scandic-hotels/design-system/ChipButton"
|
|
||||||
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
||||||
|
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||||
|
|
||||||
import { trpc } from "@/lib/trpc/client"
|
import { trpc } from "@/lib/trpc/client"
|
||||||
import { useRatesStore } from "@/stores/select-rate"
|
import { useRatesStore } from "@/stores/select-rate"
|
||||||
@@ -17,7 +11,8 @@ import { useRatesStore } from "@/stores/select-rate"
|
|||||||
import { useRoomContext } from "@/contexts/SelectRate/Room"
|
import { useRoomContext } from "@/contexts/SelectRate/Room"
|
||||||
import useLang from "@/hooks/useLang"
|
import useLang from "@/hooks/useLang"
|
||||||
|
|
||||||
import Form from "./Form"
|
import RoomPackageFilterModal from "./Modal"
|
||||||
|
import RoomPackageFilterPopover from "./Popover"
|
||||||
import { getIconNameByPackageCode } from "./utils"
|
import { getIconNameByPackageCode } from "./utils"
|
||||||
|
|
||||||
import styles from "./roomPackageFilter.module.css"
|
import styles from "./roomPackageFilter.module.css"
|
||||||
@@ -25,11 +20,9 @@ import styles from "./roomPackageFilter.module.css"
|
|||||||
import type { PackageEnum } from "@/types/requests/packages"
|
import type { PackageEnum } from "@/types/requests/packages"
|
||||||
|
|
||||||
export default function RoomPackageFilter() {
|
export default function RoomPackageFilter() {
|
||||||
const intl = useIntl()
|
|
||||||
const lang = useLang()
|
const lang = useLang()
|
||||||
const utils = trpc.useUtils()
|
const utils = trpc.useUtils()
|
||||||
|
const displayAsPopover = useMediaQuery("(min-width: 768px)")
|
||||||
const [isOpen, setIsOpen] = useState(false)
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
actions: { removeSelectedPackage, updateRooms },
|
actions: { removeSelectedPackage, updateRooms },
|
||||||
@@ -63,41 +56,35 @@ export default function RoomPackageFilter() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.roomPackageFilter}>
|
<div className={styles.roomPackageFilter}>
|
||||||
{selectedPackages.map((pkg) => (
|
<div className={styles.selectedPackages}>
|
||||||
<AriaButton
|
{selectedPackages.map((pkg) => (
|
||||||
key={pkg.code}
|
<Typography
|
||||||
className={styles.activeFilterButton}
|
key={pkg.code}
|
||||||
onPress={() => deleteSelectedPackage(pkg.code)}
|
variant="Body/Supporting text (caption)/smRegular"
|
||||||
>
|
>
|
||||||
<MaterialIcon
|
<span className={styles.selectedPackage}>
|
||||||
icon={getIconNameByPackageCode(pkg.code)}
|
<MaterialIcon
|
||||||
size={16}
|
icon={getIconNameByPackageCode(pkg.code)}
|
||||||
color="Icon/Interactive/Default"
|
size={16}
|
||||||
/>
|
color="CurrentColor"
|
||||||
<MaterialIcon
|
/>
|
||||||
icon="close"
|
{pkg.description}
|
||||||
size={16}
|
<AriaButton
|
||||||
color="Icon/Interactive/Default"
|
onPress={() => deleteSelectedPackage(pkg.code)}
|
||||||
/>
|
className={styles.removeButton}
|
||||||
</AriaButton>
|
>
|
||||||
))}
|
<MaterialIcon icon="close" size={16} color="CurrentColor" />
|
||||||
<DialogTrigger isOpen={isOpen} onOpenChange={setIsOpen}>
|
</AriaButton>
|
||||||
<ChipButton variant="Outlined">
|
</span>
|
||||||
{intl.formatMessage({
|
</Typography>
|
||||||
defaultMessage: "Room preferences",
|
))}
|
||||||
})}
|
</div>
|
||||||
<MaterialIcon
|
<div hidden={displayAsPopover}>
|
||||||
icon="keyboard_arrow_down"
|
<RoomPackageFilterModal />
|
||||||
size={20}
|
</div>
|
||||||
color="CurrentColor"
|
<div hidden={!displayAsPopover}>
|
||||||
/>
|
<RoomPackageFilterPopover />
|
||||||
</ChipButton>
|
</div>
|
||||||
<Popover placement="bottom end">
|
|
||||||
<Dialog className={styles.dialog}>
|
|
||||||
<Form close={() => setIsOpen(false)} />
|
|
||||||
</Dialog>
|
|
||||||
</Popover>
|
|
||||||
</DialogTrigger>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,28 +1,141 @@
|
|||||||
.roomPackageFilter {
|
.roomPackageFilter {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: var(--Space-x1);
|
gap: var(--Space-x1);
|
||||||
|
flex-direction: column-reverse;
|
||||||
|
align-items: start;
|
||||||
}
|
}
|
||||||
|
|
||||||
.activeFilterButton {
|
.selectedPackages {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
gap: var(--Space-x1);
|
||||||
align-items: center;
|
flex-wrap: wrap;
|
||||||
padding: 0 var(--Space-x1);
|
}
|
||||||
gap: var(--Space-x05);
|
|
||||||
border-radius: var(--Corner-radius-Small);
|
.modalOverlay {
|
||||||
background-color: var(--Surface-Secondary-Default-dark);
|
position: fixed;
|
||||||
border-width: 0;
|
inset: 0;
|
||||||
cursor: pointer;
|
background-color: var(--Overlay-40);
|
||||||
|
|
||||||
|
&[data-entering] {
|
||||||
|
animation: overlay-fade 200ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
&[data-exiting] {
|
||||||
|
animation: overlay-fade 150ms reverse ease-in;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
padding: var(--Space-x2) var(--Space-x05);
|
||||||
|
border-radius: var(--Corner-radius-md) var(--Corner-radius-md) 0 0;
|
||||||
|
background-color: var(--Surface-Primary-Default);
|
||||||
|
box-shadow: 0px 0px 14px 6px rgba(0, 0, 0, 0.1);
|
||||||
|
|
||||||
|
&[data-entering] {
|
||||||
|
animation: modal-anim 200ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
&[data-exiting] {
|
||||||
|
animation: modal-anim 150ms reverse ease-in;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.modalDialog {
|
||||||
|
display: grid;
|
||||||
|
gap: var(--Space-x2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dialog {
|
.dialog {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: var(--Space-x1);
|
gap: var(--Space-x2);
|
||||||
padding: var(--Space-x2);
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: flex-end;
|
|
||||||
border-radius: var(--Corner-radius-md);
|
|
||||||
background-color: var(--Surface-Primary-Default);
|
|
||||||
box-shadow: 0px 0px 14px 6px rgba(0, 0, 0, 0.1);
|
|
||||||
max-width: 340px;
|
max-width: 340px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 var(--Space-x15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
display: grid;
|
||||||
|
gap: var(--Space-x1);
|
||||||
|
padding: 0 var(--Space-x15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.selectedPackage {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
padding: var(--Space-x1);
|
||||||
|
gap: var(--Space-x05);
|
||||||
|
border-radius: var(--Corner-radius-Small);
|
||||||
|
background-color: var(--Surface-Secondary-Default-dark);
|
||||||
|
color: var(--Text-Interactive-Default);
|
||||||
|
}
|
||||||
|
|
||||||
|
.removeButton {
|
||||||
|
background-color: transparent;
|
||||||
|
border-width: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: var(--Space-x05);
|
||||||
|
margin: calc(-1 * var(--Space-x05));
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 767px) {
|
||||||
|
.popover {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 768px) {
|
||||||
|
.roomPackageFilter {
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modalOverlay {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popover {
|
||||||
|
padding: var(--Space-x2);
|
||||||
|
border-radius: var(--Corner-radius-md);
|
||||||
|
background-color: var(--Surface-Primary-Default);
|
||||||
|
box-shadow: 0px 0px 14px 6px rgba(0, 0, 0, 0.1);
|
||||||
|
max-width: 340px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkboxContainer {
|
||||||
|
padding: 0 var(--Space-x1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes overlay-fade {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes modal-anim {
|
||||||
|
from {
|
||||||
|
transform: translateY(100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user