Merged in SW-3270-move-interactive-map-to-design-system-or-booking-flow (pull request #2681)
SW-3270 move interactive map to design system or booking flow * wip * wip * merge * wip * add support for locales in design-system * add story for HotelCard * setup alias * . * remove tracking from design-system for hotelcard * pass isUserLoggedIn * export design-system-new-deprecated.css from design-system * Add HotelMarkerByType to Storybook * Add interactive map to Storybook * fix reactintl in vitest * rename env variables * . * fix background colors * add storybook stories for <Link /> * merge * fix tracking for when clicking 'See rooms' in InteractiveMap * Merge branch 'master' of bitbucket.org:scandic-swap/web into SW-3270-move-interactive-map-to-design-system-or-booking-flow * remove deprecated comment Approved-by: Anton Gunnarsson
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react-vite'
|
||||
import { fn } from 'storybook/test'
|
||||
import { BookingCodeChip } from './index'
|
||||
|
||||
const meta = {
|
||||
title: 'Components/BookingCodeChip',
|
||||
component: BookingCodeChip,
|
||||
parameters: {
|
||||
layout: 'centered',
|
||||
},
|
||||
} satisfies Meta<typeof BookingCodeChip>
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof BookingCodeChip>
|
||||
|
||||
export const Default: Story = {
|
||||
args: {},
|
||||
render: () => <BookingCodeChip bookingCode="ABC123" withText />,
|
||||
}
|
||||
|
||||
export const WithoutText: Story = {
|
||||
args: {},
|
||||
render: () => <BookingCodeChip bookingCode="ABC123" withText={false} />,
|
||||
}
|
||||
|
||||
export const FilledIcon: Story = {
|
||||
args: {},
|
||||
render: () => <BookingCodeChip bookingCode="ABC123" filledIcon />,
|
||||
}
|
||||
|
||||
export const Unavailable: Story = {
|
||||
args: {},
|
||||
render: () => <BookingCodeChip bookingCode="ABC123" isUnavailable />,
|
||||
}
|
||||
|
||||
export const AlignCenter: Story = {
|
||||
args: {},
|
||||
render: () => <BookingCodeChip bookingCode="ABC123" alignCenter />,
|
||||
}
|
||||
|
||||
export const WithCloseButton: Story = {
|
||||
args: {},
|
||||
render: () => (
|
||||
<BookingCodeChip bookingCode="ABC123" withCloseButton onClose={fn} />
|
||||
),
|
||||
}
|
||||
|
||||
export const CampaignBreakfastIncluded: Story = {
|
||||
args: {},
|
||||
render: () => (
|
||||
<BookingCodeChip isCampaign bookingCode="SUMMER25" isBreakfastIncluded />
|
||||
),
|
||||
}
|
||||
|
||||
export const CampaignBreakfastExcluded: Story = {
|
||||
args: {},
|
||||
render: () => (
|
||||
<BookingCodeChip
|
||||
isCampaign
|
||||
bookingCode="SUMMER25"
|
||||
isBreakfastIncluded={false}
|
||||
/>
|
||||
),
|
||||
}
|
||||
|
||||
export const CampaignFilledIcon: Story = {
|
||||
args: {},
|
||||
render: () => (
|
||||
<BookingCodeChip
|
||||
isCampaign
|
||||
bookingCode="SUMMER25"
|
||||
isBreakfastIncluded
|
||||
filledIcon
|
||||
/>
|
||||
),
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
.bookingCodeChip {
|
||||
display: flex;
|
||||
gap: var(--Space-x05);
|
||||
}
|
||||
|
||||
.unavailable {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.center {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.removeButton {
|
||||
color: currentColor;
|
||||
background-color: transparent;
|
||||
border-width: 0;
|
||||
cursor: pointer;
|
||||
padding: var(--Space-x05);
|
||||
margin: calc(-1 * var(--Space-x05));
|
||||
}
|
||||
123
packages/design-system/lib/components/BookingCodeChip/index.tsx
Normal file
123
packages/design-system/lib/components/BookingCodeChip/index.tsx
Normal file
@@ -0,0 +1,123 @@
|
||||
import { Button as ButtonRAC } from 'react-aria-components'
|
||||
import { useIntl } from 'react-intl'
|
||||
|
||||
import IconChip from '@scandic-hotels/design-system/IconChip'
|
||||
import DiscountIcon from '@scandic-hotels/design-system/Icons/DiscountIcon'
|
||||
import FilledDiscountIcon from '@scandic-hotels/design-system/Icons/FilledDiscountIcon'
|
||||
import { MaterialIcon } from '@scandic-hotels/design-system/Icons/MaterialIcon'
|
||||
import { Typography } from '@scandic-hotels/design-system/Typography'
|
||||
|
||||
import styles from './bookingCodeChip.module.css'
|
||||
|
||||
type BaseBookingCodeChipProps = {
|
||||
alignCenter?: boolean
|
||||
bookingCode?: string | null
|
||||
isBreakfastIncluded?: boolean
|
||||
isCampaign?: boolean
|
||||
isUnavailable?: boolean
|
||||
withText?: boolean
|
||||
filledIcon?: boolean
|
||||
}
|
||||
type BookingCodeChipWithoutCloseButtonProps = BaseBookingCodeChipProps & {
|
||||
withCloseButton?: false
|
||||
}
|
||||
type BookingCodeChipWithCloseButtonProps = BaseBookingCodeChipProps & {
|
||||
withCloseButton: true
|
||||
onClose: () => void
|
||||
}
|
||||
|
||||
type BookingCodeChipProps =
|
||||
| BookingCodeChipWithoutCloseButtonProps
|
||||
| BookingCodeChipWithCloseButtonProps
|
||||
|
||||
export function BookingCodeChip({
|
||||
alignCenter,
|
||||
bookingCode,
|
||||
isBreakfastIncluded,
|
||||
isCampaign,
|
||||
isUnavailable,
|
||||
withText = true,
|
||||
filledIcon = false,
|
||||
...props
|
||||
}: BookingCodeChipProps) {
|
||||
const intl = useIntl()
|
||||
|
||||
if (isCampaign) {
|
||||
return (
|
||||
<IconChip
|
||||
color="green"
|
||||
icon={
|
||||
filledIcon ? (
|
||||
<FilledDiscountIcon color="Icon/Feedback/Success" />
|
||||
) : (
|
||||
<DiscountIcon color="Icon/Feedback/Success" />
|
||||
)
|
||||
}
|
||||
className={alignCenter ? styles.center : undefined}
|
||||
>
|
||||
<p className={styles.bookingCodeChip}>
|
||||
<Typography variant="Body/Supporting text (caption)/smBold">
|
||||
<strong>
|
||||
{intl.formatMessage({ defaultMessage: 'Campaign' })}
|
||||
</strong>
|
||||
</Typography>
|
||||
<Typography variant="Body/Supporting text (caption)/smRegular">
|
||||
<span>
|
||||
{isBreakfastIncluded
|
||||
? // eslint-disable-next-line formatjs/no-literal-string-in-jsx
|
||||
`${bookingCode ?? ''} ${intl.formatMessage({
|
||||
defaultMessage: 'Breakfast included',
|
||||
})}`
|
||||
: // eslint-disable-next-line formatjs/no-literal-string-in-jsx
|
||||
`${bookingCode ?? ''} ${intl.formatMessage({
|
||||
defaultMessage: 'Breakfast excluded',
|
||||
})}`}
|
||||
</span>
|
||||
</Typography>
|
||||
</p>
|
||||
</IconChip>
|
||||
)
|
||||
}
|
||||
|
||||
if (!bookingCode) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<IconChip
|
||||
color="blue"
|
||||
icon={
|
||||
filledIcon ? (
|
||||
<FilledDiscountIcon fill="Icon/Feedback/Information" />
|
||||
) : (
|
||||
<DiscountIcon color="Icon/Feedback/Information" />
|
||||
)
|
||||
}
|
||||
className={alignCenter ? styles.center : undefined}
|
||||
>
|
||||
<p
|
||||
className={`${styles.bookingCodeChip} ${isUnavailable ? styles.unavailable : ''}`}
|
||||
>
|
||||
{withText && (
|
||||
<Typography variant="Body/Supporting text (caption)/smBold">
|
||||
<strong>
|
||||
{intl.formatMessage({
|
||||
defaultMessage: 'Booking code',
|
||||
})}
|
||||
</strong>
|
||||
</Typography>
|
||||
)}
|
||||
<Typography variant="Body/Supporting text (caption)/smRegular">
|
||||
<span>{bookingCode}</span>
|
||||
</Typography>
|
||||
</p>
|
||||
{props.withCloseButton && (
|
||||
<>
|
||||
<ButtonRAC className={styles.removeButton} onPress={props.onClose}>
|
||||
<MaterialIcon icon="close" size={16} color="CurrentColor" />
|
||||
</ButtonRAC>
|
||||
</>
|
||||
)}
|
||||
</IconChip>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user