Merged in feat/SW-3477-hide-voucher-booking-code-sas- (pull request #2836)

feat(SW-3477) Updated booking widget for SAS white label

Approved-by: Anton Gunnarsson
This commit is contained in:
Hrishikesh Vaipurkar
2025-09-23 08:44:55 +00:00
parent 046d342b6f
commit 16e6c1596c
21 changed files with 173 additions and 79 deletions

View File

@@ -15,6 +15,7 @@ import { bookingTermsAndConditionsRoutes } from "@scandic-hotels/common/constant
import { customerService } from "@scandic-hotels/common/constants/routes/customerService" import { customerService } from "@scandic-hotels/common/constants/routes/customerService"
import { myStay } from "@scandic-hotels/common/constants/routes/myStay" import { myStay } from "@scandic-hotels/common/constants/routes/myStay"
import { privacyPolicyRoutes } from "@scandic-hotels/common/constants/routes/privacyPolicyRoutes" import { privacyPolicyRoutes } from "@scandic-hotels/common/constants/routes/privacyPolicyRoutes"
import { ScandicPartnersEnum } from "@scandic-hotels/common/constants/scandicPartners"
import { ToastHandler } from "@scandic-hotels/design-system/ToastHandler" import { ToastHandler } from "@scandic-hotels/design-system/ToastHandler"
import AdobeSDKScript from "@/components/AdobeSDKScript" import AdobeSDKScript from "@/components/AdobeSDKScript"
@@ -61,6 +62,7 @@ export default async function RootLayout(props: RootLayoutProps) {
const bookingFlowConfig: BookingFlowConfig = { const bookingFlowConfig: BookingFlowConfig = {
bookingCodeEnabled: false, bookingCodeEnabled: false,
partner: ScandicPartnersEnum.sas,
routes: { routes: {
myStay: routeToScandicWeb(myStay), myStay: routeToScandicWeb(myStay),
bookingTermsAndConditions: routeToScandicWeb( bookingTermsAndConditions: routeToScandicWeb(

View File

@@ -5,9 +5,11 @@ import { cache } from "react"
import { BookingFlowConfigContextProvider } from "./bookingFlowConfigContext" import { BookingFlowConfigContextProvider } from "./bookingFlowConfigContext"
import type { LangRoute } from "@scandic-hotels/common/constants/routes/langRoute" import type { LangRoute } from "@scandic-hotels/common/constants/routes/langRoute"
import type { ScandicPartnersEnum } from "@scandic-hotels/common/constants/scandicPartners"
export type BookingFlowConfig = { export type BookingFlowConfig = {
bookingCodeEnabled: boolean bookingCodeEnabled: boolean
partner?: ScandicPartnersEnum
routes: { routes: {
myStay: LangRoute myStay: LangRoute
bookingTermsAndConditions: LangRoute bookingTermsAndConditions: LangRoute

View File

@@ -2,6 +2,8 @@
import { createContext, useContext } from "react" import { createContext, useContext } from "react"
import type { ScandicPartnersEnum } from "@scandic-hotels/common/constants/scandicPartners"
import type { BookingFlowConfig } from "./bookingFlowConfig" import type { BookingFlowConfig } from "./bookingFlowConfig"
type BookingFlowConfigContextData = BookingFlowConfig type BookingFlowConfigContextData = BookingFlowConfig
@@ -10,6 +12,18 @@ const BookingFlowConfigContext = createContext<
BookingFlowConfigContextData | undefined BookingFlowConfigContextData | undefined
>(undefined) >(undefined)
export const useIsPartner = (partner: ScandicPartnersEnum) => {
const context = useContext(BookingFlowConfigContext)
if (!context) {
throw new Error(
"useBookingFlowConfig must be used within a BookingFlowConfigContextProvider. Did you forget to use BookingFlowConfig in the consuming app?"
)
}
return context.partner === partner
}
export const useBookingFlowConfig = (): BookingFlowConfigContextData => { export const useBookingFlowConfig = (): BookingFlowConfigContextData => {
const context = useContext(BookingFlowConfigContext) const context = useContext(BookingFlowConfigContext)

View File

@@ -1,3 +1,4 @@
import { ScandicPartnersEnum } from "@scandic-hotels/common/constants/scandicPartners"
import { logger } from "@scandic-hotels/common/logger" import { logger } from "@scandic-hotels/common/logger"
import { phoneErrors } from "@scandic-hotels/common/utils/zod/phoneValidator" import { phoneErrors } from "@scandic-hotels/common/utils/zod/phoneValidator"
@@ -9,7 +10,11 @@ import {
import type { IntlShape } from "react-intl" import type { IntlShape } from "react-intl"
export function getErrorMessage(intl: IntlShape, errorCode?: string) { export function getErrorMessage(
intl: IntlShape,
errorCode?: string,
partner?: ScandicPartnersEnum
) {
switch (errorCode) { switch (errorCode) {
case bookingWidgetErrors.BOOKING_CODE_INVALID: case bookingWidgetErrors.BOOKING_CODE_INVALID:
return intl.formatMessage({ return intl.formatMessage({
@@ -42,10 +47,15 @@ export function getErrorMessage(intl: IntlShape, errorCode?: string) {
"Multi-room booking is not available with this booking code.", "Multi-room booking is not available with this booking code.",
}) })
case bookingWidgetErrors.MULTIROOM_REWARD_NIGHT_UNAVAILABLE: case bookingWidgetErrors.MULTIROOM_REWARD_NIGHT_UNAVAILABLE:
return intl.formatMessage({ return partner === ScandicPartnersEnum.sas
defaultMessage: ? intl.formatMessage({
"Multi-room booking is not available with reward night.", defaultMessage:
}) "Multi-room booking is not available with euro bonus points.",
})
: intl.formatMessage({
defaultMessage:
"Multi-room booking is not available with reward night.",
})
case bookingWidgetErrors.CODE_VOUCHER_REWARD_NIGHT_UNAVAILABLE: case bookingWidgetErrors.CODE_VOUCHER_REWARD_NIGHT_UNAVAILABLE:
return intl.formatMessage({ return intl.formatMessage({
defaultMessage: defaultMessage:

View File

@@ -19,6 +19,10 @@
color: var(--Text-Secondary); color: var(--Text-Secondary);
} }
.colorSecondary {
color: var(--Text-Secondary);
}
.errorContainer { .errorContainer {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -46,6 +50,7 @@
.bookingCodeTooltip { .bookingCodeTooltip {
max-width: 560px; max-width: 560px;
margin-top: var(--Spacing-x2); margin-top: var(--Spacing-x2);
color: var(--Text-Secondary);
} }
.bookingCodeRememberVisible label { .bookingCodeRememberVisible label {

View File

@@ -4,15 +4,11 @@ import { type FieldError, useFormContext } from "react-hook-form"
import { useIntl } from "react-intl" import { useIntl } from "react-intl"
import { useMediaQuery } from "usehooks-ts" import { useMediaQuery } from "usehooks-ts"
import Body from "@scandic-hotels/design-system/Body" import { Button } from "@scandic-hotels/design-system/Button"
import Caption from "@scandic-hotels/design-system/Caption"
import Checkbox from "@scandic-hotels/design-system/Form/Checkbox" import Checkbox from "@scandic-hotels/design-system/Form/Checkbox"
import { IconButton } from "@scandic-hotels/design-system/IconButton"
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
import Modal from "@scandic-hotels/design-system/Modal" import Modal from "@scandic-hotels/design-system/Modal"
import {
type ButtonProps,
OldDSButton as Button,
} from "@scandic-hotels/design-system/OldDSButton"
import Switch from "@scandic-hotels/design-system/Switch" import Switch from "@scandic-hotels/design-system/Switch"
import { Typography } from "@scandic-hotels/design-system/Typography" import { Typography } from "@scandic-hotels/design-system/Typography"
import { SEARCH_TYPE_REDEMPTION } from "@scandic-hotels/trpc/constants/booking" import { SEARCH_TYPE_REDEMPTION } from "@scandic-hotels/trpc/constants/booking"
@@ -20,6 +16,7 @@ import { SEARCH_TYPE_REDEMPTION } from "@scandic-hotels/trpc/constants/booking"
import BookingFlowInput from "../../../../BookingFlowInput" import BookingFlowInput from "../../../../BookingFlowInput"
import { getErrorMessage } from "../../../../BookingFlowInput/errors" import { getErrorMessage } from "../../../../BookingFlowInput/errors"
import { Input as BookingWidgetInput } from "../Input" import { Input as BookingWidgetInput } from "../Input"
import { RemoveExtraRooms } from "../RemoveExtraRooms/RemoveExtraRooms"
import { isMultiRoomError } from "../utils" import { isMultiRoomError } from "../utils"
import styles from "./booking-code.module.css" import styles from "./booking-code.module.css"
@@ -192,13 +189,15 @@ export default function BookingCode() {
} }
> >
<Switch name="bookingCode.remember" className="mobile-switch"> <Switch name="bookingCode.remember" className="mobile-switch">
<Caption asChild> <Typography
variant={"Body/Supporting text (caption)/smRegular"}
>
<span> <span>
{intl.formatMessage({ {intl.formatMessage({
defaultMessage: "Remember code", defaultMessage: "Remember code",
})} })}
</span> </span>
</Caption> </Typography>
</Switch> </Switch>
</div> </div>
)} )}
@@ -226,19 +225,19 @@ function CodeRulesModal() {
return ( return (
<Modal <Modal
trigger={ trigger={
<Button intent="text"> <IconButton theme={"Black"} wrapping>
<MaterialIcon <MaterialIcon
icon="info" icon="info"
color="Icon/Interactive/Placeholder" color="Icon/Interactive/Placeholder"
size={20} size={20}
/> />
</Button> </IconButton>
} }
title={codeVoucher} title={codeVoucher}
> >
<Body color="uiTextHighContrast" className={styles.bookingCodeTooltip}> <Typography variant={"Body/Paragraph/mdRegular"}>
{bookingCodeTooltipText} <p className={styles.bookingCodeTooltip}>{bookingCodeTooltipText}</p>
</Body> </Typography>
</Modal> </Modal>
) )
} }
@@ -249,20 +248,19 @@ function CodeRemember({ bookingCodeValue, onApplyClick }: CodeRememberProps) {
return ( return (
<> <>
<Checkbox name="bookingCode.remember"> <Checkbox name="bookingCode.remember">
<Caption asChild> <Typography variant={"Body/Supporting text (caption)/smRegular"}>
<span> <span>
{intl.formatMessage({ {intl.formatMessage({
defaultMessage: "Remember code", defaultMessage: "Remember code",
})} })}
</span> </span>
</Caption> </Typography>
</Checkbox> </Checkbox>
{bookingCodeValue ? ( {bookingCodeValue ? (
<Button <Button
size="small" size="Small"
className={styles.hideOnMobile} className={styles.hideOnMobile}
intent="tertiary" variant="Tertiary"
theme="base"
type="button" type="button"
onClick={onApplyClick} onClick={onApplyClick}
> >
@@ -303,41 +301,13 @@ function BookingCodeError({
</Typography> </Typography>
{isMultiroomError ? ( {isMultiroomError ? (
<div className={styles.removeButton}> <div className={styles.removeButton}>
<RemoveExtraRooms fullWidth /> <RemoveExtraRooms />
</div> </div>
) : null} ) : null}
</div> </div>
) )
} }
export function RemoveExtraRooms({ ...props }: ButtonProps) {
const intl = useIntl()
const { getValues, setValue, trigger } = useFormContext<BookingWidgetSchema>()
function removeExtraRooms() {
// Timeout to delay the event scheduling issue with touch events on mobile
window.setTimeout(() => {
const rooms = getValues("rooms")[0]
setValue("rooms", [rooms], { shouldValidate: true, shouldDirty: true })
trigger("bookingCode.value")
trigger(SEARCH_TYPE_REDEMPTION)
}, 300)
}
return (
<Button
type="button"
onClick={removeExtraRooms}
size="small"
intent="secondary"
{...props}
>
{intl.formatMessage({
defaultMessage: "Remove extra rooms",
})}
</Button>
)
}
function TabletBookingCode({ function TabletBookingCode({
bookingCode, bookingCode,
updateValue, updateValue,
@@ -381,7 +351,7 @@ function TabletBookingCode({
return ( return (
<div className={styles.container}> <div className={styles.container}>
<DialogTrigger isOpen={isOpen} onOpenChange={toggleModal}> <DialogTrigger isOpen={isOpen} onOpenChange={toggleModal}>
<Button type="button" intent="text"> <Button type="button" variant={"Text"}>
{/* For some reason Checkbox click triggers twice modal state change, which returns the modal back to old state. So we are using overlay as trigger for modal */} {/* For some reason Checkbox click triggers twice modal state change, which returns the modal back to old state. So we are using overlay as trigger for modal */}
<div className={styles.overlayTrigger}></div> <div className={styles.overlayTrigger}></div>
<Checkbox <Checkbox
@@ -394,9 +364,9 @@ function TabletBookingCode({
}, },
})} })}
> >
<Caption color="uiTextMediumContrast" type="bold" asChild> <Typography variant={"Body/Supporting text (caption)/smBold"}>
<span>{codeVoucher}</span> <span className={styles.colorSecondary}>{codeVoucher}</span>
</Caption> </Typography>
</Checkbox> </Checkbox>
</Button> </Button>
<Popover <Popover

View File

@@ -0,0 +1,36 @@
import { useFormContext } from "react-hook-form"
import { useIntl } from "react-intl"
import { Button, type ButtonProps } from "@scandic-hotels/design-system/Button"
import { SEARCH_TYPE_REDEMPTION } from "@scandic-hotels/trpc/constants/booking"
import type { BookingWidgetSchema } from "../../../Client"
export function RemoveExtraRooms({ ...props }: ButtonProps) {
const intl = useIntl()
const { getValues, setValue, trigger } = useFormContext<BookingWidgetSchema>()
function removeExtraRooms() {
// Timeout to delay the event scheduling issue with touch events on mobile
window.setTimeout(() => {
const rooms = getValues("rooms")[0]
setValue("rooms", [rooms], { shouldValidate: true, shouldDirty: true })
trigger("bookingCode.value")
trigger(SEARCH_TYPE_REDEMPTION)
}, 300)
}
return (
<Button
style={{ width: "100%" }}
type="button"
onClick={removeExtraRooms}
size="Small"
variant={"Secondary"}
{...props}
>
{intl.formatMessage({
defaultMessage: "Remove extra rooms",
})}
</Button>
)
}

View File

@@ -5,16 +5,20 @@ import { useFormContext } from "react-hook-form"
import { useIntl } from "react-intl" import { useIntl } from "react-intl"
import { useMediaQuery } from "usehooks-ts" import { useMediaQuery } from "usehooks-ts"
import Caption from "@scandic-hotels/design-system/Caption" import { ScandicPartnersEnum } from "@scandic-hotels/common/constants/scandicPartners"
import Checkbox from "@scandic-hotels/design-system/Form/Checkbox" import Checkbox from "@scandic-hotels/design-system/Form/Checkbox"
import { IconButton } from "@scandic-hotels/design-system/IconButton"
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
import Modal from "@scandic-hotels/design-system/Modal" import Modal from "@scandic-hotels/design-system/Modal"
import { OldDSButton as Button } from "@scandic-hotels/design-system/OldDSButton"
import { Typography } from "@scandic-hotels/design-system/Typography" import { Typography } from "@scandic-hotels/design-system/Typography"
import { SEARCH_TYPE_REDEMPTION } from "@scandic-hotels/trpc/constants/booking" import { SEARCH_TYPE_REDEMPTION } from "@scandic-hotels/trpc/constants/booking"
import {
useBookingFlowConfig,
useIsPartner,
} from "../../../../../bookingFlowConfig/bookingFlowConfigContext"
import { getErrorMessage } from "../../../../BookingFlowInput/errors" import { getErrorMessage } from "../../../../BookingFlowInput/errors"
import { RemoveExtraRooms } from "../BookingCode" import { RemoveExtraRooms } from "../RemoveExtraRooms/RemoveExtraRooms"
import { isMultiRoomError } from "../utils" import { isMultiRoomError } from "../utils"
import styles from "./reward-night.module.css" import styles from "./reward-night.module.css"
@@ -23,6 +27,8 @@ import type { BookingWidgetSchema } from "../../../Client"
export default function RewardNight() { export default function RewardNight() {
const intl = useIntl() const intl = useIntl()
const config = useBookingFlowConfig()
const isPartnerSas = useIsPartner(ScandicPartnersEnum.sas)
const { const {
setValue, setValue,
getValues, getValues,
@@ -30,13 +36,22 @@ export default function RewardNight() {
trigger, trigger,
} = useFormContext<BookingWidgetSchema>() } = useFormContext<BookingWidgetSchema>()
const ref = useRef<HTMLDivElement | null>(null) const ref = useRef<HTMLDivElement | null>(null)
const reward = intl.formatMessage({ const reward = isPartnerSas
defaultMessage: "Reward Night", ? intl.formatMessage({
}) defaultMessage: "EuroBonus Points",
const rewardNightTooltip = intl.formatMessage({ })
defaultMessage: : intl.formatMessage({
"To book a reward night, make sure you're logged in to your Scandic Friends account.", defaultMessage: "Reward Night",
}) })
const rewardNightTooltip = isPartnerSas
? intl.formatMessage({
defaultMessage:
"To book with EuroBonus points, make sure you're logged into your SAS EuroBonus account.",
})
: intl.formatMessage({
defaultMessage:
"To book a reward night, make sure you're logged in to your Scandic Friends account.",
})
const redemptionErr = errors[SEARCH_TYPE_REDEMPTION] const redemptionErr = errors[SEARCH_TYPE_REDEMPTION]
const isDesktop = useMediaQuery("(min-width: 767px)") const isDesktop = useMediaQuery("(min-width: 767px)")
@@ -92,19 +107,22 @@ export default function RewardNight() {
}} }}
> >
<div className={styles.rewardNightLabel}> <div className={styles.rewardNightLabel}>
<Caption color="uiTextMediumContrast" asChild> <Typography
variant={"Body/Supporting text (caption)/smRegular"}
className={styles.label}
>
<span>{reward}</span> <span>{reward}</span>
</Caption> </Typography>
<Modal <Modal
trigger={ trigger={
<Button intent="text"> <IconButton theme={"Black"} wrapping>
<MaterialIcon <MaterialIcon
icon="info" icon="info"
size={20} size={20}
color="Icon/Interactive/Placeholder" color="Icon/Interactive/Placeholder"
className={styles.errorIcon} className={styles.errorIcon}
/> />
</Button> </IconButton>
} }
title={reward} title={reward}
> >
@@ -131,12 +149,12 @@ export default function RewardNight() {
className={styles.errorIcon} className={styles.errorIcon}
isFilled={!isDesktop} isFilled={!isDesktop}
/> />
{getErrorMessage(intl, redemptionErr.message)} {getErrorMessage(intl, redemptionErr.message, config.partner)}
</span> </span>
</Typography> </Typography>
{isMultiRoomError(redemptionErr.message) ? ( {isMultiRoomError(redemptionErr.message) ? (
<div className={styles.hideOnMobile}> <div className={styles.hideOnMobile}>
<RemoveExtraRooms fullWidth /> <RemoveExtraRooms />
</div> </div>
) : null} ) : null}
</div> </div>

View File

@@ -17,7 +17,9 @@
.rewardNightLabel { .rewardNightLabel {
align-items: center; align-items: center;
display: flex; display: flex;
gap: var(--Spacing-x1); color: var(--Text-Secondary);
min-width: 160px;
gap: var(--Space-x1);
} }
.rewardNightTooltip { .rewardNightTooltip {

View File

@@ -185,4 +185,8 @@
.input { .input {
gap: var(--Spacing-x2); gap: var(--Spacing-x2);
} }
.bookingCodeDisabled {
flex: none;
}
} }

View File

@@ -13,10 +13,11 @@ import SkeletonShimmer from "@scandic-hotels/design-system/SkeletonShimmer"
import { Typography } from "@scandic-hotels/design-system/Typography" import { Typography } from "@scandic-hotels/design-system/Typography"
import { SEARCH_TYPE_REDEMPTION } from "@scandic-hotels/trpc/constants/booking" import { SEARCH_TYPE_REDEMPTION } from "@scandic-hotels/trpc/constants/booking"
import { useBookingFlowConfig } from "../../../../bookingFlowConfig/bookingFlowConfigContext"
import useLang from "../../../../hooks/useLang" import useLang from "../../../../hooks/useLang"
import GuestsRoomsPickerForm from "../../../BookingWidget/GuestsRoomsPicker" import GuestsRoomsPickerForm from "../../../BookingWidget/GuestsRoomsPicker"
import DatePicker from "../../DatePicker" import DatePicker from "../../DatePicker"
import { RemoveExtraRooms } from "./BookingCode" import { RemoveExtraRooms } from "./RemoveExtraRooms/RemoveExtraRooms"
import { Search, SearchSkeleton } from "./Search" import { Search, SearchSkeleton } from "./Search"
import { isMultiRoomError } from "./utils" import { isMultiRoomError } from "./utils"
import ValidationError from "./ValidationError" import ValidationError from "./ValidationError"
@@ -40,6 +41,7 @@ export default function FormContent({
const { const {
formState: { errors, isDirty }, formState: { errors, isDirty },
} = useFormContext<BookingWidgetSchema>() } = useFormContext<BookingWidgetSchema>()
const { bookingCodeEnabled } = useBookingFlowConfig()
const lang = useLang() const lang = useLang()
const pathName = usePathname() const pathName = usePathname()
@@ -109,14 +111,20 @@ export default function FormContent({
</span> </span>
</Button> </Button>
</div> </div>
<div className={cx(styles.voucherContainer, styles.voucherRow)}> <div
className={cx(
styles.voucherContainer,
styles.voucherRow,
bookingCodeEnabled ? null : styles.bookingCodeDisabled
)}
>
<Voucher /> <Voucher />
</div> </div>
<div className={cx(styles.buttonContainer, styles.hideOnTablet)}> <div className={cx(styles.buttonContainer, styles.hideOnTablet)}>
{isMultiRoomError(errors.bookingCode?.value?.message) || {isMultiRoomError(errors.bookingCode?.value?.message) ||
isMultiRoomError(errors[SEARCH_TYPE_REDEMPTION]?.message) ? ( isMultiRoomError(errors[SEARCH_TYPE_REDEMPTION]?.message) ? (
<div className={styles.showOnMobile}> <div className={styles.showOnMobile}>
<RemoveExtraRooms size="medium" fullWidth /> <RemoveExtraRooms />
</div> </div>
) : null} ) : null}
<Button <Button

View File

@@ -14,6 +14,7 @@ import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
import { trpc } from "@scandic-hotels/trpc/client" import { trpc } from "@scandic-hotels/trpc/client"
import { SEARCH_TYPE_REDEMPTION } from "@scandic-hotels/trpc/constants/booking" import { SEARCH_TYPE_REDEMPTION } from "@scandic-hotels/trpc/constants/booking"
import { useBookingFlowConfig } from "../../bookingFlowConfig/bookingFlowConfigContext"
import useLang from "../../hooks/useLang" import useLang from "../../hooks/useLang"
import { import {
type bookingCodeSchema, type bookingCodeSchema,
@@ -52,6 +53,7 @@ export default function BookingWidgetClient({
const [originalOverflowY, setOriginalOverflowY] = useState<string | null>( const [originalOverflowY, setOriginalOverflowY] = useState<string | null>(
null null
) )
const { bookingCodeEnabled } = useBookingFlowConfig()
const shouldFetchAutoComplete = !!data.hotelId || !!data.city const shouldFetchAutoComplete = !!data.hotelId || !!data.city
@@ -124,7 +126,7 @@ export default function BookingWidgetClient({
toDate: toDate.format("YYYY-MM-DD"), toDate: toDate.format("YYYY-MM-DD"),
}, },
bookingCode: { bookingCode: {
value: selectedBookingCode, value: bookingCodeEnabled ? selectedBookingCode : "",
remember: false, remember: false,
}, },
redemption: data.searchType === SEARCH_TYPE_REDEMPTION, redemption: data.searchType === SEARCH_TYPE_REDEMPTION,

View File

@@ -0,0 +1,3 @@
export enum ScandicPartnersEnum {
sas = "sas",
}

View File

@@ -28,6 +28,7 @@
"./constants/routes/*": "./constants/routes/*.ts", "./constants/routes/*": "./constants/routes/*.ts",
"./constants/signatureHotels": "./constants/signatureHotels.ts", "./constants/signatureHotels": "./constants/signatureHotels.ts",
"./constants/paymentCallbackStatus": "./constants/paymentCallbackStatus.ts", "./constants/paymentCallbackStatus": "./constants/paymentCallbackStatus.ts",
"./constants/scandicPartners": "./constants/scandicPartners.ts",
"./dataCache": "./dataCache/index.ts", "./dataCache": "./dataCache/index.ts",
"./dt": "./dt/dt.ts", "./dt": "./dt/dt.ts",
"./dt/utils/hasOverlappingDates": "./dt/utils/hasOverlappingDates.ts", "./dt/utils/hasOverlappingDates": "./dt/utils/hasOverlappingDates.ts",

View File

@@ -1,3 +1,5 @@
export { Button } from './Button' export { Button } from './Button'
// eslint-disable-next-line react-refresh/only-export-components // eslint-disable-next-line react-refresh/only-export-components
export { withButton } from './variants' export { withButton } from './variants'
export { type ButtonProps } from './types'

View File

@@ -1,7 +1,7 @@
.container { .container {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
color: var(--text-color); color: var(--Text-Default);
cursor: pointer; cursor: pointer;
} }

View File

@@ -27,6 +27,11 @@ const meta: Meta<typeof IconButton> = {
type: 'string', type: 'string',
description: `The style variant is only applied on certain variants. The examples below shows the possible combinations of variants and style variants.`, description: `The style variant is only applied on certain variants. The examples below shows the possible combinations of variants and style variants.`,
}, },
wrapping: {
control: 'select',
options: Object.keys(config.variants.wrapping),
default: undefined,
},
}, },
} }

View File

@@ -8,11 +8,13 @@ export function IconButton({
theme, theme,
style, style,
className, className,
wrapping,
...props ...props
}: IconButtonProps) { }: IconButtonProps) {
const classNames = variants({ const classNames = variants({
theme, theme,
style, style,
wrapping,
className, className,
}) })

View File

@@ -100,3 +100,7 @@
background-color: var(--Component-Button-Muted-Fill-Disabled-inverted); background-color: var(--Component-Button-Muted-Fill-Disabled-inverted);
} }
} }
.no-wrapping {
padding: 0;
}

View File

@@ -33,6 +33,10 @@ export const config = {
[variantKeys.style.Elevated]: '', [variantKeys.style.Elevated]: '',
[variantKeys.style.Faded]: '', [variantKeys.style.Faded]: '',
}, },
wrapping: {
true: styles['no-wrapping'],
false: undefined,
},
}, },
compoundVariants: [ compoundVariants: [
// Primary should only use Normal // Primary should only use Normal

View File

@@ -1,7 +1,7 @@
.container { .container {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
color: var(--text-color); color: var(--Text-Default);
cursor: pointer; cursor: pointer;
width: 100%; width: 100%;
justify-content: space-between; justify-content: space-between;