Merged in feat/SW-2241-country-map (pull request #2808)
Feat/SW-2241 country map Approved-by: Erik Tiekstra Approved-by: Chuma Mcphoy (We Ahead)
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
import type { Meta, StoryObj } from '@storybook/nextjs-vite'
|
||||
|
||||
import { Badge } from './Badge.tsx'
|
||||
|
||||
const meta: Meta<typeof Badge> = {
|
||||
title: 'Components/Badge',
|
||||
component: Badge,
|
||||
}
|
||||
|
||||
export default meta
|
||||
|
||||
type Story = StoryObj<typeof Badge>
|
||||
|
||||
export const Default: Story = {}
|
||||
|
||||
export const XS: Story = {
|
||||
render: () => (
|
||||
<div style={{ display: 'flex', gap: '16px', alignItems: 'center' }}>
|
||||
<Badge number={3} color="primary" size="20" />
|
||||
<Badge number={3} color="green" size="20" />
|
||||
</div>
|
||||
),
|
||||
}
|
||||
|
||||
export const Small: Story = {
|
||||
render: () => (
|
||||
<div style={{ display: 'flex', gap: '16px', alignItems: 'center' }}>
|
||||
<Badge number={3} color="primary" size="24" />
|
||||
<Badge number={3} color="green" size="24" />
|
||||
</div>
|
||||
),
|
||||
}
|
||||
export const Medium: Story = {
|
||||
render: () => (
|
||||
<div style={{ display: 'flex', gap: '16px', alignItems: 'center' }}>
|
||||
<Badge number={3} color="primary" size="28" />
|
||||
<Badge number={3} color="green" size="28" />
|
||||
</div>
|
||||
),
|
||||
}
|
||||
export const Large: Story = {
|
||||
render: () => (
|
||||
<div style={{ display: 'flex', gap: '16px', alignItems: 'center' }}>
|
||||
<Badge number={3} color="primary" size="32" />
|
||||
<Badge number={3} color="green" size="32" />
|
||||
</div>
|
||||
),
|
||||
}
|
||||
|
||||
export const XL: Story = {
|
||||
render: () => (
|
||||
<div style={{ display: 'flex', gap: '16px', alignItems: 'center' }}>
|
||||
<Badge number={3} color="primary" size="36" />
|
||||
<Badge number={3} color="green" size="36" />
|
||||
</div>
|
||||
),
|
||||
}
|
||||
35
packages/design-system/lib/components/Badge/Badge.tsx
Normal file
35
packages/design-system/lib/components/Badge/Badge.tsx
Normal file
@@ -0,0 +1,35 @@
|
||||
import { config } from './variants'
|
||||
|
||||
import { VariantProps } from 'class-variance-authority'
|
||||
import { Typography } from '../Typography'
|
||||
import { TypographyProps } from '../Typography/types'
|
||||
|
||||
interface BadgeProps extends VariantProps<typeof config> {
|
||||
number: number
|
||||
}
|
||||
|
||||
export function Badge({ number, color, size }: BadgeProps) {
|
||||
const classNames = config({
|
||||
color,
|
||||
size,
|
||||
})
|
||||
|
||||
return (
|
||||
<Typography variant={getTypography(size)}>
|
||||
<span className={classNames}>{number}</span>
|
||||
</Typography>
|
||||
)
|
||||
}
|
||||
|
||||
function getTypography(size: BadgeProps['size']): TypographyProps['variant'] {
|
||||
switch (size) {
|
||||
case '36':
|
||||
case '32':
|
||||
return 'Body/Paragraph/mdBold'
|
||||
case '28':
|
||||
case '24':
|
||||
return 'Body/Supporting text (caption)/smBold'
|
||||
case '20':
|
||||
return 'Label/xsRegular'
|
||||
}
|
||||
}
|
||||
42
packages/design-system/lib/components/Badge/badge.module.css
Normal file
42
packages/design-system/lib/components/Badge/badge.module.css
Normal file
@@ -0,0 +1,42 @@
|
||||
.badge {
|
||||
border-radius: var(--Corner-radius-xl);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: var(--Space-x025);
|
||||
}
|
||||
|
||||
.primary {
|
||||
background-color: var(--Surface-Brand-Primary-2-Default);
|
||||
color: var(--Text-Inverted);
|
||||
}
|
||||
|
||||
.green {
|
||||
background-color: var(--Surface-Feedback-Succes);
|
||||
color: var(--Text-Feedback-Succes-Accent);
|
||||
}
|
||||
|
||||
._36 {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
}
|
||||
|
||||
._32 {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
._28 {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
|
||||
._24 {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
._20 {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
1
packages/design-system/lib/components/Badge/index.tsx
Normal file
1
packages/design-system/lib/components/Badge/index.tsx
Normal file
@@ -0,0 +1 @@
|
||||
export { Badge } from './Badge'
|
||||
23
packages/design-system/lib/components/Badge/variants.ts
Normal file
23
packages/design-system/lib/components/Badge/variants.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { cva } from 'class-variance-authority'
|
||||
|
||||
import styles from './badge.module.css'
|
||||
|
||||
export const config = cva(styles.badge, {
|
||||
variants: {
|
||||
color: {
|
||||
primary: styles.primary,
|
||||
green: styles.green,
|
||||
},
|
||||
size: {
|
||||
'36': styles._36,
|
||||
'32': styles._32,
|
||||
'28': styles._28,
|
||||
'24': styles._24,
|
||||
'20': styles._20,
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
color: 'primary',
|
||||
size: '28',
|
||||
},
|
||||
})
|
||||
@@ -7,14 +7,9 @@ import { useIntl } from 'react-intl'
|
||||
import { IconButton } from '../../IconButton'
|
||||
import { MaterialIcon } from '../../Icons/MaterialIcon'
|
||||
|
||||
import {
|
||||
DEFAULT_ZOOM,
|
||||
MAP_RESTRICTIONS,
|
||||
MAX_ZOOM,
|
||||
MIN_ZOOM,
|
||||
} from '../mapConstants'
|
||||
import { HOTEL_PAGE, MAP_RESTRICTIONS } from '../mapConstants'
|
||||
|
||||
import { useZoomControls } from './useZoomControls'
|
||||
import { useZoomControls } from '@scandic-hotels/common/hooks/map/useZoomControls'
|
||||
|
||||
import { HotelListingMapContent } from './HotelListingMapContent'
|
||||
import PoiMapMarkers from './PoiMapMarkers'
|
||||
@@ -87,12 +82,12 @@ export function InteractiveMap({
|
||||
const intl = useIntl()
|
||||
const map = useMap()
|
||||
const [hasInitializedBounds, setHasInitializedBounds] = useState(false)
|
||||
const { zoomIn, zoomOut, isMaxZoom, isMinZoom } = useZoomControls()
|
||||
const { zoomIn, zoomOut, isMaxZoom, isMinZoom } = useZoomControls(HOTEL_PAGE)
|
||||
|
||||
const mapOptions: MapProps = {
|
||||
defaultZoom: DEFAULT_ZOOM,
|
||||
minZoom: MIN_ZOOM,
|
||||
maxZoom: MAX_ZOOM,
|
||||
defaultZoom: HOTEL_PAGE.DEFAULT_ZOOM,
|
||||
minZoom: HOTEL_PAGE.MIN_ZOOM,
|
||||
maxZoom: HOTEL_PAGE.MAX_ZOOM,
|
||||
defaultCenter: coordinates,
|
||||
disableDefaultUI: true,
|
||||
clickableIcons: false,
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
import { useMap } from '@vis.gl/react-google-maps'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { DEFAULT_ZOOM, MAX_ZOOM, MIN_ZOOM } from '../mapConstants'
|
||||
|
||||
export function useZoomControls() {
|
||||
const map = useMap()
|
||||
const [zoomLevel, setZoomLevel] = useState(DEFAULT_ZOOM)
|
||||
|
||||
const zoomIn = () => {
|
||||
if (map && zoomLevel < MAX_ZOOM) {
|
||||
map.setZoom(zoomLevel + 1)
|
||||
}
|
||||
}
|
||||
|
||||
const zoomOut = () => {
|
||||
if (map && zoomLevel > MIN_ZOOM) {
|
||||
map.setZoom(zoomLevel - 1)
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!map) return
|
||||
|
||||
const handleZoomChanged = () => {
|
||||
const currentZoom = map.getZoom()
|
||||
if (currentZoom != null) {
|
||||
setZoomLevel(currentZoom)
|
||||
}
|
||||
}
|
||||
|
||||
const listener = map.addListener('zoom_changed', handleZoomChanged)
|
||||
return () => listener.remove()
|
||||
}, [map])
|
||||
|
||||
return {
|
||||
zoomLevel,
|
||||
zoomIn,
|
||||
zoomOut,
|
||||
isMinZoom: zoomLevel <= MIN_ZOOM,
|
||||
isMaxZoom: zoomLevel >= MAX_ZOOM,
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,34 @@ export const MAP_RESTRICTIONS = {
|
||||
latLngBounds: { north: 85, south: -85, west: -180, east: 180 },
|
||||
}
|
||||
|
||||
export const DEFAULT_ZOOM = 14
|
||||
export const MAX_ZOOM = 18
|
||||
export const MIN_ZOOM = 8
|
||||
export const HOTEL_PAGE = {
|
||||
DEFAULT_ZOOM: 14,
|
||||
MAX_ZOOM: 18,
|
||||
MIN_ZOOM: 8,
|
||||
} as const
|
||||
|
||||
export const DESTINATION_PAGE = {
|
||||
DEFAULT_ZOOM: 10,
|
||||
MAX_ZOOM: 18,
|
||||
MIN_ZOOM: 3,
|
||||
}
|
||||
|
||||
export const CITY_PAGE = {
|
||||
DEFAULT_ZOOM: 10,
|
||||
SELECTED_HOTEL_ZOOM: 15,
|
||||
MAX_ZOOM: 18,
|
||||
MIN_ZOOM: 3,
|
||||
} as const
|
||||
|
||||
export const COUNTRY_PAGE = {
|
||||
DEFAULT_ZOOM: 3,
|
||||
SELECTED_HOTEL_ZOOM: 15,
|
||||
MAX_ZOOM: 18,
|
||||
MIN_ZOOM: 3,
|
||||
} as const
|
||||
|
||||
export type MapType =
|
||||
| typeof HOTEL_PAGE
|
||||
| typeof DESTINATION_PAGE
|
||||
| typeof CITY_PAGE
|
||||
| typeof COUNTRY_PAGE
|
||||
|
||||
@@ -276,7 +276,7 @@
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: block;
|
||||
src: url(/_static/shared/fonts/material-symbols/rounded-f2d895e1.woff2)
|
||||
src: url(/_static/shared/fonts/material-symbols/rounded-1db5531f.woff2)
|
||||
format('woff2');
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user