Merged in fix/SW-3434-skeleton-ui-bug (pull request #2772)

fix(SW-3434): skeleton ui fix for booking widget

* fix(SW-3434): skeleton ui fix for booking widget

* fix(SW-3434): use cx


Approved-by: Anton Gunnarsson
This commit is contained in:
Bianca Widstam
2025-09-10 08:35:14 +00:00
parent f04fe467da
commit 1ceb1520a6
4 changed files with 68 additions and 35 deletions

View File

@@ -1,5 +1,5 @@
"use client" "use client"
import { FormProvider, useForm } from "react-hook-form" import { cx } from "class-variance-authority"
import { useIntl } from "react-intl" import { useIntl } from "react-intl"
import Caption from "@scandic-hotels/design-system/Caption" import Caption from "@scandic-hotels/design-system/Caption"
@@ -33,28 +33,32 @@ export function VoucherSkeleton() {
defaultMessage: "Reward Night", defaultMessage: "Reward Night",
}) })
const form = useForm()
return ( return (
<FormProvider {...form}> <div className={styles.optionsContainer}>
<div className={styles.optionsContainer}> <div className={styles.voucherSkeletonContainer}>
<div className={styles.voucherSkeletonContainer}> <label>
<label> <Caption type="bold" color="red" asChild>
<Caption type="bold" color="red" asChild> <span>{vouchers}</span>
<span>{vouchers}</span> </Caption>
</Caption> </label>
</label> <SkeletonShimmer width="100%" display="block" />
<SkeletonShimmer width={"100%"} display={"block"} /> </div>
<div className={styles.options}>
<div className={cx(styles.option, styles.showOnTablet)}>
<SkeletonShimmer width="24px" height="24px" />
<Caption color="uiTextMediumContrast" asChild>
<span>{vouchers}</span>
</Caption>
</div> </div>
<div className={styles.options}>
<div className={styles.option}> <div className={styles.option}>
<SkeletonShimmer width="24px" height="24px" /> <SkeletonShimmer width="24px" height="24px" />
<Caption color="uiTextMediumContrast" asChild> <Caption color="uiTextMediumContrast" asChild>
<span>{reward}</span> <span>{reward}</span>
</Caption> </Caption>
</div>
</div> </div>
</div> </div>
</FormProvider> </div>
) )
} }

View File

@@ -25,6 +25,10 @@
height: 24px; height: 24px;
} }
.showOnTablet {
display: none;
}
@media screen and (min-width: 768px) { @media screen and (min-width: 768px) {
.options { .options {
flex-direction: row; flex-direction: row;
@@ -41,6 +45,15 @@
} }
} }
@media screen and (min-width: 768px) and (max-width: 1366px) {
.voucherSkeletonContainer {
display: none;
}
.showOnTablet {
display: flex;
}
}
@media screen and (min-width: 1367px) { @media screen and (min-width: 1367px) {
.options { .options {
flex-direction: column; flex-direction: column;

View File

@@ -1,5 +1,6 @@
"use client" "use client"
import { cx } from "class-variance-authority"
import { usePathname } from "next/navigation" import { usePathname } from "next/navigation"
import { useFormContext, useWatch } from "react-hook-form" import { useFormContext, useWatch } from "react-hook-form"
import { useIntl } from "react-intl" import { useIntl } from "react-intl"
@@ -95,7 +96,7 @@ export default function FormContent({
<GuestsRoomsPickerForm ariaLabelledBy="rooms-and-guests" /> <GuestsRoomsPickerForm ariaLabelledBy="rooms-and-guests" />
</div> </div>
</div> </div>
<div className={`${styles.buttonContainer} ${styles.showOnTablet}`}> <div className={cx(styles.buttonContainer, styles.showOnTablet)}>
<Button <Button
className={styles.button} className={styles.button}
form={formId} form={formId}
@@ -108,10 +109,10 @@ export default function FormContent({
</span> </span>
</Button> </Button>
</div> </div>
<div className={`${styles.voucherContainer} ${styles.voucherRow}`}> <div className={cx(styles.voucherContainer, styles.voucherRow)}>
<Voucher /> <Voucher />
</div> </div>
<div className={`${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}>
@@ -169,7 +170,7 @@ export function BookingWidgetFormContentSkeleton() {
)} )}
</label> </label>
</Typography> </Typography>
<SkeletonShimmer width={"100%"} display={"block"} /> <SkeletonShimmer width="100%" display="block" />
</div> </div>
<div className={styles.rooms}> <div className={styles.rooms}>
<Typography <Typography
@@ -182,13 +183,26 @@ export function BookingWidgetFormContentSkeleton() {
})} })}
</label> </label>
</Typography> </Typography>
<SkeletonShimmer width={"100%"} display={"block"} /> <SkeletonShimmer width="100%" display="block" />
</div> </div>
</div> </div>
<div className={styles.voucherContainer}> <div className={cx(styles.buttonContainer, styles.showOnTablet)}>
<Button
className={styles.button}
intent="primary"
theme="base"
type="submit"
disabled
>
<span className={styles.icon}>
<MaterialIcon icon="search" color="Icon/Inverted" size={28} />
</span>
</Button>
</div>
<div className={cx(styles.voucherContainer, styles.voucherRow)}>
<VoucherSkeleton /> <VoucherSkeleton />
</div> </div>
<div className={styles.buttonContainer}> <div className={cx(styles.buttonContainer, styles.hideOnTablet)}>
<Button <Button
className={styles.button} className={styles.button}
intent="primary" intent="primary"

View File

@@ -1,3 +1,13 @@
.shimmer {
position: relative;
overflow: hidden;
display: inline-block;
border-radius: 4px;
min-height: 1em;
min-width: 2ch;
background-color: var(--shimmer-background);
}
.shimmer.dark { .shimmer.dark {
--shimmer-background: rgba(255, 255, 255, 0.1); --shimmer-background: rgba(255, 255, 255, 0.1);
--shimmer: linear-gradient( --shimmer: linear-gradient(
@@ -17,14 +27,6 @@
rgba(255, 255, 255, 0.5) 60%, rgba(255, 255, 255, 0.5) 60%,
rgba(255, 255, 255, 0) 100% rgba(255, 255, 255, 0) 100%
); );
background-color: var(--shimmer-background);
position: relative;
overflow: hidden;
display: inline-block;
border-radius: 4px;
min-height: 1em;
min-width: 2ch;
} }
.shimmer::after { .shimmer::after {
position: absolute; position: absolute;