@times-components/ts-components 1.146.2-be27d508c972211ad80599875cd69c63bf67d4b1.45 → 1.146.2-e5795a0ef59e2adb61ba52aeb7332fda4405cb7a.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (156) hide show
  1. package/dist/components/opta/football/opta-match-stats/matchday-live/DesktopWidget.d.ts +10 -0
  2. package/dist/components/opta/football/opta-match-stats/matchday-live/DesktopWidget.js +69 -0
  3. package/dist/components/opta/football/opta-match-stats/matchday-live/MobileWidget.d.ts +12 -0
  4. package/dist/components/opta/football/opta-match-stats/matchday-live/MobileWidget.js +90 -0
  5. package/dist/components/opta/football/opta-match-stats/matchday-live/OptaMatchStatsMatchdayLive.d.ts +12 -0
  6. package/dist/components/opta/football/opta-match-stats/matchday-live/OptaMatchStatsMatchdayLive.js +10 -0
  7. package/dist/components/opta/football/opta-match-stats/matchday-live/OptaMatchStatsMatchdayLive.stories.js +24 -0
  8. package/dist/components/opta/football/opta-match-stats/matchday-live/__tests__/MobileWidget.test.js +57 -0
  9. package/dist/components/{carousel-component/__tests__/DefaultPageDot.test.d.ts → opta/football/opta-match-stats/matchday-live/__tests__/OptaMatchStatsMatchdayLive.test.d.ts} +1 -0
  10. package/dist/components/opta/football/opta-match-stats/matchday-live/__tests__/OptaMatchStatsMatchdayLive.test.js +48 -0
  11. package/dist/components/opta/football/opta-match-stats/matchday-live/styles/MatchdayLiveController.d.ts +1 -0
  12. package/dist/components/opta/football/opta-match-stats/matchday-live/styles/MatchdayLiveController.js +19 -0
  13. package/dist/components/opta/football/opta-match-stats/matchday-live/styles/NavigationWrapper.d.ts +12 -0
  14. package/dist/components/opta/football/opta-match-stats/matchday-live/styles/NavigationWrapper.js +67 -0
  15. package/dist/components/opta/football/opta-match-stats/matchday-live/styles/WidgetContainer.d.ts +6 -0
  16. package/dist/components/opta/football/opta-match-stats/matchday-live/styles/WidgetContainer.js +736 -0
  17. package/dist/components/opta/football/opta-match-stats/matchday-live/styles/__tests__/NavigationWrapper.test.js +33 -0
  18. package/dist/components/opta/football/opta-match-stats/matchday-live/styles/__tests__/WidgetContainer.test.js +36 -0
  19. package/dist/components/opta/football/opta-match-stats/shared/styles.js +8 -1
  20. package/dist/components/opta/football/opta-match-stats/summary/OptaMatchStatsSummary.js +2 -2
  21. package/dist/components/opta/football/opta-match-stats/summary/OptaMatchStatsSummary.stories.js +1 -1
  22. package/dist/components/opta/football/opta-match-stats/summary/WidgetContainer.js +19 -5
  23. package/dist/index.d.ts +1 -1
  24. package/dist/index.js +2 -2
  25. package/package.json +3 -3
  26. package/rnw.js +1 -1
  27. package/src/components/opta/football/opta-match-stats/commentary/__tests__/__snapshots__/OptaMatchStatsCommentary.test.tsx.snap +1 -1
  28. package/src/components/opta/football/opta-match-stats/matchday-live/DesktopWidget.tsx +108 -0
  29. package/src/components/opta/football/opta-match-stats/matchday-live/MobileWidget.tsx +158 -0
  30. package/src/components/opta/football/opta-match-stats/matchday-live/OptaMatchStatsMatchdayLive.stories.tsx +38 -0
  31. package/src/components/opta/football/opta-match-stats/matchday-live/OptaMatchStatsMatchdayLive.tsx +23 -0
  32. package/src/components/opta/football/opta-match-stats/matchday-live/__tests__/MobileWidget.test.tsx +69 -0
  33. package/src/components/opta/football/opta-match-stats/matchday-live/__tests__/OptaMatchStatsMatchdayLive.test.tsx +61 -0
  34. package/src/components/opta/football/opta-match-stats/matchday-live/__tests__/__snapshots__/OptaMatchStatsMatchdayLive.test.tsx.snap +61 -0
  35. package/src/components/opta/football/opta-match-stats/matchday-live/styles/MatchdayLiveController.tsx +19 -0
  36. package/src/components/opta/football/opta-match-stats/matchday-live/styles/NavigationWrapper.tsx +81 -0
  37. package/src/components/opta/football/opta-match-stats/matchday-live/styles/WidgetContainer.tsx +767 -0
  38. package/src/components/opta/football/opta-match-stats/matchday-live/styles/__tests__/NavigationWrapper.test.tsx +67 -0
  39. package/src/components/opta/football/opta-match-stats/matchday-live/styles/__tests__/WidgetContainer.test.tsx +64 -0
  40. package/src/components/opta/football/opta-match-stats/shared/styles.ts +8 -0
  41. package/src/components/opta/football/opta-match-stats/stats-graphs/__tests__/__snapshots__/OptaMatchStatsGraphs.test.tsx.snap +1 -1
  42. package/src/components/opta/football/opta-match-stats/summary/OptaMatchStatsSummary.stories.tsx +1 -1
  43. package/src/components/opta/football/opta-match-stats/summary/OptaMatchStatsSummary.tsx +1 -1
  44. package/src/components/opta/football/opta-match-stats/summary/WidgetContainer.tsx +18 -4
  45. package/src/components/opta/football/opta-match-stats/summary/__tests__/__snapshots__/OptaMatchStatsSummary.test.tsx.snap +1 -1
  46. package/src/index.ts +3 -2
  47. package/dist/components/carousel-component/CarouselComponent.stories.js +0 -146
  48. package/dist/components/carousel-component/CarouselItem.d.ts +0 -3
  49. package/dist/components/carousel-component/CarouselItem.js +0 -12
  50. package/dist/components/carousel-component/DefaultNavigationArrow.d.ts +0 -8
  51. package/dist/components/carousel-component/DefaultNavigationArrow.js +0 -6
  52. package/dist/components/carousel-component/DefaultPageDot.d.ts +0 -8
  53. package/dist/components/carousel-component/DefaultPageDot.js +0 -4
  54. package/dist/components/carousel-component/__tests__/CarouselComponent.test.js +0 -163
  55. package/dist/components/carousel-component/__tests__/CarouselItem.test.js +0 -80
  56. package/dist/components/carousel-component/__tests__/DefaultNavigationArrow.test.js +0 -62
  57. package/dist/components/carousel-component/__tests__/DefaultPageDot.test.js +0 -68
  58. package/dist/components/carousel-component/hooks/__tests__/useCarousel.test.d.ts +0 -1
  59. package/dist/components/carousel-component/hooks/__tests__/useCarousel.test.js +0 -459
  60. package/dist/components/carousel-component/hooks/useCarousel.d.ts +0 -2
  61. package/dist/components/carousel-component/hooks/useCarousel.js +0 -167
  62. package/dist/components/carousel-component/index.d.ts +0 -4
  63. package/dist/components/carousel-component/index.js +0 -20
  64. package/dist/components/carousel-component/styles.d.ts +0 -28
  65. package/dist/components/carousel-component/styles.js +0 -172
  66. package/dist/components/carousel-component/types.d.ts +0 -53
  67. package/dist/components/carousel-component/types.js +0 -2
  68. package/dist/components/trip-cards/SkeletonCard.d.ts +0 -7
  69. package/dist/components/trip-cards/SkeletonCard.js +0 -22
  70. package/dist/components/trip-cards/TripCard.d.ts +0 -3
  71. package/dist/components/trip-cards/TripCard.js +0 -49
  72. package/dist/components/trip-cards/TripCards.stories.d.ts +0 -1
  73. package/dist/components/trip-cards/TripCards.stories.js +0 -159
  74. package/dist/components/trip-cards/TripCardsLayout.d.ts +0 -3
  75. package/dist/components/trip-cards/TripCardsLayout.js +0 -56
  76. package/dist/components/trip-cards/__tests__/SkeletonCard.test.d.ts +0 -1
  77. package/dist/components/trip-cards/__tests__/SkeletonCard.test.js +0 -139
  78. package/dist/components/trip-cards/__tests__/TripCard.test.d.ts +0 -1
  79. package/dist/components/trip-cards/__tests__/TripCard.test.js +0 -95
  80. package/dist/components/trip-cards/__tests__/TripCardsLayout.test.d.ts +0 -1
  81. package/dist/components/trip-cards/__tests__/TripCardsLayout.test.js +0 -314
  82. package/dist/components/trip-cards/__tests__/assets.test.d.ts +0 -1
  83. package/dist/components/trip-cards/__tests__/assets.test.js +0 -165
  84. package/dist/components/trip-cards/__tests__/helpers.test.d.ts +0 -1
  85. package/dist/components/trip-cards/__tests__/helpers.test.js +0 -220
  86. package/dist/components/trip-cards/__tests__/index.test.d.ts +0 -1
  87. package/dist/components/trip-cards/__tests__/index.test.js +0 -478
  88. package/dist/components/trip-cards/__tests__/mockData.test.d.ts +0 -1
  89. package/dist/components/trip-cards/__tests__/mockData.test.js +0 -57
  90. package/dist/components/trip-cards/__tests__/skeletonStyles.test.d.ts +0 -1
  91. package/dist/components/trip-cards/__tests__/skeletonStyles.test.js +0 -194
  92. package/dist/components/trip-cards/assets/BoatIcon.d.ts +0 -1
  93. package/dist/components/trip-cards/assets/BoatIcon.js +0 -4
  94. package/dist/components/trip-cards/assets/CalendarIcon.d.ts +0 -1
  95. package/dist/components/trip-cards/assets/CalendarIcon.js +0 -4
  96. package/dist/components/trip-cards/assets/ChevronRightIcon.d.ts +0 -1
  97. package/dist/components/trip-cards/assets/ChevronRightIcon.js +0 -4
  98. package/dist/components/trip-cards/assets/LocationIcon.d.ts +0 -1
  99. package/dist/components/trip-cards/assets/LocationIcon.js +0 -4
  100. package/dist/components/trip-cards/assets/MoonIcon.d.ts +0 -1
  101. package/dist/components/trip-cards/assets/MoonIcon.js +0 -4
  102. package/dist/components/trip-cards/assets/index.d.ts +0 -6
  103. package/dist/components/trip-cards/assets/index.js +0 -7
  104. package/dist/components/trip-cards/helpers.d.ts +0 -11
  105. package/dist/components/trip-cards/helpers.js +0 -138
  106. package/dist/components/trip-cards/index.d.ts +0 -4
  107. package/dist/components/trip-cards/index.js +0 -68
  108. package/dist/components/trip-cards/mockData.d.ts +0 -3
  109. package/dist/components/trip-cards/mockData.js +0 -317
  110. package/dist/components/trip-cards/skeletonStyles.d.ts +0 -9
  111. package/dist/components/trip-cards/skeletonStyles.js +0 -37
  112. package/dist/components/trip-cards/styles.d.ts +0 -43
  113. package/dist/components/trip-cards/styles.js +0 -404
  114. package/dist/components/trip-cards/types.d.ts +0 -119
  115. package/dist/components/trip-cards/types.js +0 -2
  116. package/src/components/carousel-component/CarouselComponent.stories.tsx +0 -220
  117. package/src/components/carousel-component/CarouselItem.tsx +0 -26
  118. package/src/components/carousel-component/DefaultNavigationArrow.tsx +0 -37
  119. package/src/components/carousel-component/DefaultPageDot.tsx +0 -20
  120. package/src/components/carousel-component/__tests__/CarouselComponent.test.tsx +0 -259
  121. package/src/components/carousel-component/__tests__/CarouselItem.test.tsx +0 -140
  122. package/src/components/carousel-component/__tests__/DefaultNavigationArrow.test.tsx +0 -153
  123. package/src/components/carousel-component/__tests__/DefaultPageDot.test.tsx +0 -105
  124. package/src/components/carousel-component/hooks/__tests__/useCarousel.test.ts +0 -625
  125. package/src/components/carousel-component/hooks/useCarousel.ts +0 -229
  126. package/src/components/carousel-component/index.tsx +0 -92
  127. package/src/components/carousel-component/styles.ts +0 -188
  128. package/src/components/carousel-component/types.ts +0 -62
  129. package/src/components/trip-cards/SkeletonCard.tsx +0 -64
  130. package/src/components/trip-cards/TripCard.tsx +0 -140
  131. package/src/components/trip-cards/TripCards.stories.tsx +0 -224
  132. package/src/components/trip-cards/TripCardsLayout.tsx +0 -145
  133. package/src/components/trip-cards/__tests__/SkeletonCard.test.tsx +0 -169
  134. package/src/components/trip-cards/__tests__/TripCard.test.tsx +0 -120
  135. package/src/components/trip-cards/__tests__/TripCardsLayout.test.tsx +0 -583
  136. package/src/components/trip-cards/__tests__/assets.test.tsx +0 -206
  137. package/src/components/trip-cards/__tests__/helpers.test.ts +0 -272
  138. package/src/components/trip-cards/__tests__/index.test.tsx +0 -550
  139. package/src/components/trip-cards/__tests__/mockData.test.ts +0 -67
  140. package/src/components/trip-cards/__tests__/skeletonStyles.test.tsx +0 -256
  141. package/src/components/trip-cards/assets/BoatIcon.tsx +0 -17
  142. package/src/components/trip-cards/assets/CalendarIcon.tsx +0 -17
  143. package/src/components/trip-cards/assets/ChevronRightIcon.tsx +0 -20
  144. package/src/components/trip-cards/assets/LocationIcon.tsx +0 -17
  145. package/src/components/trip-cards/assets/MoonIcon.tsx +0 -17
  146. package/src/components/trip-cards/assets/index.ts +0 -7
  147. package/src/components/trip-cards/helpers.ts +0 -176
  148. package/src/components/trip-cards/index.tsx +0 -119
  149. package/src/components/trip-cards/mockData.ts +0 -345
  150. package/src/components/trip-cards/skeletonStyles.ts +0 -46
  151. package/src/components/trip-cards/styles.ts +0 -450
  152. package/src/components/trip-cards/types.ts +0 -128
  153. /package/dist/components/{carousel-component/CarouselComponent.stories.d.ts → opta/football/opta-match-stats/matchday-live/OptaMatchStatsMatchdayLive.stories.d.ts} +0 -0
  154. /package/dist/components/{carousel-component/__tests__/CarouselComponent.test.d.ts → opta/football/opta-match-stats/matchday-live/__tests__/MobileWidget.test.d.ts} +0 -0
  155. /package/dist/components/{carousel-component/__tests__/CarouselItem.test.d.ts → opta/football/opta-match-stats/matchday-live/styles/__tests__/NavigationWrapper.test.d.ts} +0 -0
  156. /package/dist/components/{carousel-component/__tests__/DefaultNavigationArrow.test.d.ts → opta/football/opta-match-stats/matchday-live/styles/__tests__/WidgetContainer.test.d.ts} +0 -0
@@ -1,140 +0,0 @@
1
- import React, { FC, useState } from 'react';
2
- import { Placeholder } from '@times-components/image';
3
- import { TripCardProps } from './types';
4
- import {
5
- CardContainer,
6
- ImageContainer,
7
- CardImage,
8
- OfferLabel,
9
- GiftBanner,
10
- CardContent,
11
- TopContainer,
12
- BottomContainer,
13
- Headline,
14
- DataPointsList,
15
- DataPoint,
16
- DataIcon,
17
- PriceSection,
18
- PriceContainer,
19
- OfferContainer,
20
- PriceLabel,
21
- OriginalPrice,
22
- CurrentPrice,
23
- LogoContainer,
24
- CTAButton,
25
- PriceSuffix,
26
- StyledLink
27
- } from './styles';
28
- import { MoonIcon, LocationIcon, BoatIcon, CalendarIcon } from './assets';
29
-
30
- export const TripCard: FC<TripCardProps> = ({
31
- card,
32
- isStaticGrid,
33
- imgHeight = {}
34
- }) => {
35
- const [imageLoaded, setImageLoaded] = useState(false);
36
-
37
- return (
38
- <CardContainer>
39
- <StyledLink href={card.cta_url} target="_blank" rel="noopener noreferrer">
40
- <ImageContainer isStaticGrid={isStaticGrid} {...imgHeight}>
41
- {!imageLoaded && <Placeholder />}
42
- <CardImage
43
- src={card.image}
44
- alt={card.headline}
45
- onLoad={() => setImageLoaded(true)}
46
- isLoaded={imageLoaded}
47
- />
48
- {card.offer_label && <OfferLabel>{card.offer_label}</OfferLabel>}
49
- {card.gift_banner && <GiftBanner>{card.gift_banner}</GiftBanner>}
50
- </ImageContainer>
51
- </StyledLink>
52
-
53
- <CardContent>
54
- <TopContainer>
55
- <StyledLink
56
- href={card.cta_url}
57
- target="_blank"
58
- rel="noopener noreferrer"
59
- >
60
- <Headline>{card.headline}</Headline>
61
- </StyledLink>
62
-
63
- <DataPointsList>
64
- {card.date && (
65
- <DataPoint>
66
- <DataIcon>
67
- <CalendarIcon />
68
- </DataIcon>
69
- <span>{card.date}</span>
70
- </DataPoint>
71
- )}
72
- {card.duration && (
73
- <DataPoint>
74
- <DataIcon>
75
- <MoonIcon />
76
- </DataIcon>
77
- <span>{card.duration}</span>
78
- </DataPoint>
79
- )}
80
- {card.route && (
81
- <DataPoint>
82
- <DataIcon>
83
- <LocationIcon />
84
- </DataIcon>
85
- <span>{card.route}</span>
86
- </DataPoint>
87
- )}
88
- {card.ship && (
89
- <DataPoint>
90
- <DataIcon>
91
- <BoatIcon />
92
- </DataIcon>
93
- <span>{card.ship}</span>
94
- </DataPoint>
95
- )}
96
- </DataPointsList>
97
- </TopContainer>
98
-
99
- <BottomContainer>
100
- <PriceSection>
101
- <PriceContainer>
102
- {card.price !== 'Enquire now' && (
103
- <OfferContainer>
104
- {<PriceLabel>From</PriceLabel>}
105
- {card.original_price && (
106
- <OriginalPrice>{card.original_price}</OriginalPrice>
107
- )}
108
- </OfferContainer>
109
- )}
110
- <CurrentPrice $isEnquire={card.price === 'Enquire now'}>
111
- {card.price}
112
- {card.price !== 'Enquire now' && <PriceSuffix>pp</PriceSuffix>}
113
- </CurrentPrice>
114
- </PriceContainer>
115
-
116
- {card.logo && (
117
- <LogoContainer>
118
- <a
119
- href={card.logo_url}
120
- target="_blank"
121
- rel="noopener noreferrer"
122
- >
123
- <img src={card.logo} alt="Partner logo" />
124
- </a>
125
- </LogoContainer>
126
- )}
127
- </PriceSection>
128
-
129
- <CTAButton
130
- href={card.cta_url}
131
- target="_blank"
132
- rel="noopener noreferrer"
133
- >
134
- {card.cta_text || 'View Itinerary'}
135
- </CTAButton>
136
- </BottomContainer>
137
- </CardContent>
138
- </CardContainer>
139
- );
140
- };
@@ -1,224 +0,0 @@
1
- import React from 'react';
2
- import { storiesOf } from '@storybook/react';
3
- import { TripCards } from './index';
4
- import styled from 'styled-components';
5
- import { defaultTripCardImgHeight } from './helpers';
6
-
7
- const spacing = (multiplier: number) => `${multiplier * 8}px`;
8
-
9
- const breakpoints = {
10
- medium: 768,
11
- wide: 1024
12
- };
13
-
14
- const InteractiveContainer = styled.div`
15
- position: relative;
16
- margin-bottom: ${spacing(4)};
17
- padding: 0 ${spacing(2)};
18
-
19
- @media (min-width: ${breakpoints.medium}px) {
20
- width: 80.8%;
21
- margin-left: auto;
22
- margin-right: auto;
23
- padding: 0;
24
- }
25
-
26
- @media (min-width: ${breakpoints.wide}px) {
27
- width: 56.2%;
28
- }
29
- `;
30
-
31
- storiesOf('Typescript Component/TripCards', module)
32
- .add('Channel View Two Cards', () => (
33
- <TripCards
34
- element={{
35
- class: 'trip-cards',
36
- tripcards: btoa(JSON.stringify([2074350, 2140335])),
37
- title: 'Similar cruises',
38
- titleurl: 'https://www.thetimes.com/travel/holidays',
39
- description: 'Brought to you by Times Holidays'
40
- }}
41
- useMockData={true}
42
- maxWidthItemConfig={{
43
- xs: '85%',
44
- mobile: '87%',
45
- tablet: '44%',
46
- desktop: '314px',
47
- xl: '368px'
48
- }}
49
- widthContainerConfig={{
50
- tablet: '728px',
51
- desktop: '984px',
52
- xl: '1144px'
53
- }}
54
- />
55
- ))
56
- .add('Channel View Three Cards', () => (
57
- <TripCards
58
- element={{
59
- class: 'trip-cards',
60
- tripcards: btoa(JSON.stringify([2074350, 2140335, 2177685])),
61
- title: 'Featured Voyages',
62
- titleurl: 'https://www.thetimes.com/travel/holidays',
63
- description: 'Handpicked by our travel experts'
64
- }}
65
- forceStaticGrid={true}
66
- maxWidthItemConfig={{
67
- xs: '85%',
68
- mobile: '87%',
69
- tablet: '44%',
70
- desktop: '314px',
71
- xl: '368px'
72
- }}
73
- widthContainerConfig={{
74
- tablet: '728px',
75
- desktop: '984px',
76
- xl: '1144px'
77
- }}
78
- useMockData={true}
79
- />
80
- ))
81
- .add('Article View Two Trip Cards', () => (
82
- <InteractiveContainer>
83
- <TripCards
84
- element={{
85
- class: 'trip-cards',
86
- tripcards: btoa(JSON.stringify([2074350, 2140335])),
87
- title: 'Similar cruises',
88
- titleurl: 'https://www.thetimes.com/travel/holidays',
89
- description: 'Brought to you by Times Holidays'
90
- }}
91
- useMockData={true}
92
- maxWidthItemConfig={{
93
- mobile: '320px',
94
- tablet: '260px',
95
- desktop: '260px',
96
- xl: '300px'
97
- }}
98
- widthContainerConfig={{
99
- mobile: '390px',
100
- tablet: '620px',
101
- desktop: '574px',
102
- xl: '663px'
103
- }}
104
- imgHeight={defaultTripCardImgHeight}
105
- />
106
- </InteractiveContainer>
107
- ))
108
- .add('Article View Three Cards', () => (
109
- <InteractiveContainer>
110
- <TripCards
111
- element={{
112
- class: 'trip-cards',
113
- tripcards: btoa(JSON.stringify([2074350, 2140335, 2177685])),
114
- title: 'Similar cruises',
115
- titleurl: 'https://www.thetimes.com/travel/holidays',
116
- description: 'Brought to you by Times Holidays'
117
- }}
118
- useMockData={true}
119
- maxWidthItemConfig={{
120
- mobile: '320px',
121
- tablet: '260px',
122
- desktop: '260px',
123
- xl: '300px'
124
- }}
125
- widthContainerConfig={{
126
- mobile: '390px',
127
- tablet: '620px',
128
- desktop: '574px',
129
- xl: '663px'
130
- }}
131
- imgHeight={{ ...defaultTripCardImgHeight, $heightXs: '100%' }}
132
- />
133
- </InteractiveContainer>
134
- ))
135
- .add('Article View Two Trip Cards', () => (
136
- <InteractiveContainer>
137
- <TripCards
138
- element={{
139
- class: 'trip-cards',
140
- tripcards: btoa(JSON.stringify([2074350, 2140335])),
141
- title: 'Similar cruises',
142
- titleurl: 'https://www.thetimes.com/travel/holidays',
143
- description: 'Brought to you by Times Holidays'
144
- }}
145
- useMockData={true}
146
- maxWidthItemConfig={{
147
- mobile: '320px',
148
- tablet: '260px',
149
- desktop: '260px',
150
- xl: '300px'
151
- }}
152
- widthContainerConfig={{
153
- mobile: '390px',
154
- tablet: '620px',
155
- desktop: '574px',
156
- xl: '663px'
157
- }}
158
- imgHeight={defaultTripCardImgHeight}
159
- />
160
- </InteractiveContainer>
161
- ))
162
- .add('Article View Trip Cards', () => (
163
- <InteractiveContainer>
164
- <TripCards
165
- element={{
166
- class: 'trip-cards',
167
- tripcards: btoa(JSON.stringify([2074350, 2140335, 2177685])),
168
- title: 'Similar cruises',
169
- titleurl: 'https://www.thetimes.com/travel/holidays',
170
- description: 'Brought to you by Times Holidays'
171
- }}
172
- useMockData={true}
173
- maxWidthItemConfig={{
174
- mobile: '320px',
175
- tablet: '260px',
176
- desktop: '260px',
177
- xl: '300px'
178
- }}
179
- widthContainerConfig={{
180
- mobile: '390px',
181
- tablet: '620px',
182
- desktop: '574px',
183
- xl: '663px'
184
- }}
185
- imgHeight={defaultTripCardImgHeight}
186
- />
187
- </InteractiveContainer>
188
- ))
189
- .add('Article View Six Cards', () => (
190
- <InteractiveContainer>
191
- <TripCards
192
- element={{
193
- class: 'trip-cards',
194
- tripcards: btoa(
195
- JSON.stringify([
196
- 2074350,
197
- 2140335,
198
- 2177685,
199
- 2074351,
200
- 2140336,
201
- 2177686
202
- ])
203
- ),
204
- title: 'Similar cruises',
205
- titleurl: 'https://www.thetimes.com/travel/holidays',
206
- description: 'Brought to you by Times Holidays'
207
- }}
208
- useMockData={true}
209
- maxWidthItemConfig={{
210
- mobile: '320px',
211
- tablet: '260px',
212
- desktop: '260px',
213
- xl: '300px'
214
- }}
215
- widthContainerConfig={{
216
- mobile: '390px',
217
- tablet: '620px',
218
- desktop: '574px',
219
- xl: '663px'
220
- }}
221
- imgHeight={defaultTripCardImgHeight}
222
- />
223
- </InteractiveContainer>
224
- ));
@@ -1,145 +0,0 @@
1
- import React, { FC, useRef, useState, useEffect } from 'react';
2
- import { CarouselComponent, CarouselItem } from '../carousel-component';
3
- import { TripCardsLayoutProps } from './types';
4
- import {
5
- Container,
6
- TitleSection,
7
- TitleBar,
8
- TitleContent,
9
- Title,
10
- Subtitle,
11
- TitleLink,
12
- StaticCardsGrid,
13
- StyledLink
14
- } from './styles';
15
- import { ChevronRightIcon } from './assets';
16
-
17
- export const TripCardsLayout: FC<TripCardsLayoutProps> = ({
18
- element,
19
- items,
20
- CardComponent,
21
- itemsPerPage,
22
- widthContainerConfig = {},
23
- widthItemConfig,
24
- maxWidthItemConfig,
25
- imgHeight,
26
- forceStaticGrid
27
- }) => {
28
- const { titleurl, title, description } = element;
29
- const gridRef = useRef<HTMLDivElement>(null);
30
- const [hasOverflow, setHasOverflow] = useState(false);
31
- const [isTabletMobile, setIsTabletMobile] = useState(false);
32
-
33
- const isStaticGrid = items.length === 2 || forceStaticGrid;
34
-
35
- // Handle responsive breakpoint detection
36
- useEffect(() => {
37
- const mediaQuery = window.matchMedia('(max-width: 1024px)');
38
- const handleMediaChange = (e: MediaQueryListEvent | MediaQueryList) => {
39
- setIsTabletMobile(e.matches);
40
- };
41
- handleMediaChange(mediaQuery);
42
- mediaQuery.addEventListener('change', handleMediaChange);
43
-
44
- return () => {
45
- mediaQuery.removeEventListener('change', handleMediaChange);
46
- };
47
- }, []);
48
-
49
- useEffect(
50
- () => {
51
- if (!isStaticGrid || !gridRef.current) {
52
- setHasOverflow(false);
53
- return;
54
- }
55
-
56
- const checkOverflow = () => {
57
- if (gridRef.current) {
58
- const isOverflowing =
59
- gridRef.current.scrollWidth > gridRef.current.clientWidth;
60
- setHasOverflow(isOverflowing);
61
- }
62
- };
63
-
64
- checkOverflow();
65
- const resizeObserver = new ResizeObserver(checkOverflow);
66
- resizeObserver.observe(gridRef.current);
67
-
68
- return () => {
69
- resizeObserver.disconnect();
70
- };
71
- },
72
- [isStaticGrid, items.length]
73
- );
74
-
75
- const shouldUseCarousel =
76
- (isTabletMobile && items.length >= 3) || !isStaticGrid || hasOverflow;
77
-
78
- return (
79
- <Container data-testid="trip-cards-container" {...widthContainerConfig}>
80
- <TitleSection data-testid="title-section">
81
- <TitleBar
82
- data-testid="title-bar"
83
- applyRightPadding={!!widthContainerConfig.mobile}
84
- >
85
- <TitleContent data-testid="title-content">
86
- {titleurl ? (
87
- <StyledLink
88
- href={titleurl}
89
- target="_blank"
90
- rel="noopener noreferrer"
91
- data-testid="trip-cards-title-link"
92
- >
93
- <Title data-testid="trip-cards-title">{title}</Title>
94
- </StyledLink>
95
- ) : (
96
- <Title data-testid="trip-cards-title">{title}</Title>
97
- )}
98
- <Subtitle data-testid="trip-cards-subtitle">{description}</Subtitle>
99
- </TitleContent>
100
- {titleurl && (
101
- <TitleLink
102
- href={titleurl}
103
- target="_blank"
104
- rel="noopener noreferrer"
105
- data-testid="title-link"
106
- >
107
- <ChevronRightIcon />
108
- </TitleLink>
109
- )}
110
- </TitleBar>
111
- </TitleSection>
112
-
113
- {!shouldUseCarousel ? (
114
- <StaticCardsGrid data-testid="static-cards-grid" ref={gridRef}>
115
- {items.map(item => (
116
- <CardComponent
117
- imgHeight={imgHeight}
118
- key={item.id}
119
- card={item.data}
120
- isStaticGrid={true}
121
- forceStaticGrid={forceStaticGrid}
122
- />
123
- ))}
124
- </StaticCardsGrid>
125
- ) : (
126
- <CarouselComponent
127
- items={items.map(item => (
128
- <CarouselItem
129
- key={item.id}
130
- widthItemConfig={widthItemConfig}
131
- maxWidthItemConfig={maxWidthItemConfig}
132
- >
133
- <CardComponent card={item.data} imgHeight={imgHeight} />
134
- </CarouselItem>
135
- ))}
136
- options={{
137
- itemsPerPage
138
- }}
139
- showArrows={!isStaticGrid}
140
- showDots={true}
141
- />
142
- )}
143
- </Container>
144
- );
145
- };
@@ -1,169 +0,0 @@
1
- import React from 'react';
2
- import { render, screen } from '@testing-library/react';
3
- import '@testing-library/jest-dom';
4
- import { SkeletonCard } from '../SkeletonCard';
5
-
6
- describe('SkeletonCard', () => {
7
- it('renders without crashing', () => {
8
- const { container } = render(<SkeletonCard />);
9
- expect(container.firstChild).toBeInTheDocument();
10
- });
11
-
12
- it('renders placeholder image', () => {
13
- render(<SkeletonCard />);
14
- const imageContainer = screen.getByTestId('skeleton-image-container');
15
- expect(imageContainer).toBeInTheDocument();
16
- });
17
-
18
- it('renders skeleton headline', () => {
19
- render(<SkeletonCard />);
20
- const skeletonHeadline = screen.getByTestId('skeleton-headline');
21
- expect(skeletonHeadline).toBeInTheDocument();
22
- });
23
-
24
- it('renders four skeleton data points in the list', () => {
25
- render(<SkeletonCard />);
26
- const dataPoints = [
27
- screen.getByTestId('skeleton-data-point-1'),
28
- screen.getByTestId('skeleton-data-point-2'),
29
- screen.getByTestId('skeleton-data-point-3'),
30
- screen.getByTestId('skeleton-data-point-4')
31
- ];
32
- expect(dataPoints.length).toBe(4);
33
- });
34
-
35
- it('renders skeleton lines for data points', () => {
36
- render(<SkeletonCard />);
37
- const skeletonLines = [
38
- screen.getByTestId('skeleton-line-1'),
39
- screen.getByTestId('skeleton-line-2'),
40
- screen.getByTestId('skeleton-line-3'),
41
- screen.getByTestId('skeleton-line-4'),
42
- screen.getByTestId('skeleton-price-label')
43
- ];
44
- expect(skeletonLines.length).toBe(5);
45
- });
46
-
47
- it('renders skeleton price', () => {
48
- render(<SkeletonCard />);
49
- const skeletonPrice = screen.getByTestId('skeleton-price');
50
- expect(skeletonPrice).toBeInTheDocument();
51
- });
52
-
53
- it('renders skeleton button', () => {
54
- render(<SkeletonCard />);
55
- const skeletonButton = screen.getByTestId('skeleton-button');
56
- expect(skeletonButton).toBeInTheDocument();
57
- });
58
-
59
- it('has correct card structure', () => {
60
- render(<SkeletonCard />);
61
- const cardContainer = screen.getByTestId('skeleton-card-container');
62
- const cardContent = screen.getByTestId('skeleton-card-content');
63
- const topContainer = screen.getByTestId('skeleton-top-container');
64
- const bottomContainer = screen.getByTestId('skeleton-bottom-container');
65
-
66
- expect(cardContainer).toBeInTheDocument();
67
- expect(cardContent).toBeInTheDocument();
68
- expect(topContainer).toBeInTheDocument();
69
- expect(bottomContainer).toBeInTheDocument();
70
- });
71
-
72
- it('renders price section with container', () => {
73
- render(<SkeletonCard />);
74
- const priceSection = screen.getByTestId('skeleton-price-section');
75
- const priceContainer = screen.getByTestId('skeleton-price-container');
76
-
77
- expect(priceSection).toBeInTheDocument();
78
- expect(priceContainer).toBeInTheDocument();
79
- });
80
-
81
- it('renders data points list', () => {
82
- render(<SkeletonCard />);
83
- const dataPointsList = screen.getByTestId('skeleton-data-points-list');
84
- expect(dataPointsList).toBeInTheDocument();
85
- });
86
-
87
- it('skeleton lines are rendered for each data point', () => {
88
- render(<SkeletonCard />);
89
- const skeletonLines = [
90
- screen.getByTestId('skeleton-line-1'),
91
- screen.getByTestId('skeleton-line-2'),
92
- screen.getByTestId('skeleton-line-3'),
93
- screen.getByTestId('skeleton-line-4'),
94
- screen.getByTestId('skeleton-price-label')
95
- ];
96
- expect(skeletonLines.length).toBe(5);
97
- });
98
-
99
- it('renders with correct skeleton styling', () => {
100
- render(<SkeletonCard />);
101
-
102
- expect(screen.getByTestId('skeleton-headline')).toBeInTheDocument();
103
- expect(screen.getByTestId('skeleton-price')).toBeInTheDocument();
104
- expect(screen.getByTestId('skeleton-button')).toBeInTheDocument();
105
- // Check that skeleton lines are present
106
- expect(screen.getByTestId('skeleton-line-1')).toBeInTheDocument();
107
- });
108
-
109
- it('renders consistent structure', () => {
110
- render(<SkeletonCard />);
111
-
112
- expect(screen.getByTestId('skeleton-card-container')).toBeInTheDocument();
113
- expect(screen.getByTestId('skeleton-image-container')).toBeInTheDocument();
114
- expect(screen.getByTestId('skeleton-card-content')).toBeInTheDocument();
115
- expect(screen.getByTestId('skeleton-top-container')).toBeInTheDocument();
116
- expect(screen.getByTestId('skeleton-bottom-container')).toBeInTheDocument();
117
- });
118
-
119
- it('can render multiple skeleton cards', () => {
120
- render(
121
- <>
122
- <SkeletonCard />
123
- <SkeletonCard />
124
- <SkeletonCard />
125
- </>
126
- );
127
-
128
- const cards = screen.getAllByTestId('skeleton-card-container');
129
- expect(cards.length).toBe(3);
130
- });
131
-
132
- it('renders skeleton elements in correct order', () => {
133
- render(<SkeletonCard />);
134
-
135
- const cardContent = screen.getByTestId('skeleton-card-content');
136
- const topContainer = screen.getByTestId('skeleton-top-container');
137
- const bottomContainer = screen.getByTestId('skeleton-bottom-container');
138
-
139
- // Verify both containers exist as children of card content
140
- expect(cardContent.contains(topContainer)).toBe(true);
141
- expect(cardContent.contains(bottomContainer)).toBe(true);
142
- });
143
-
144
- it('skeleton button has correct structure', () => {
145
- render(<SkeletonCard />);
146
- const skeletonButton = screen.getByTestId('skeleton-button');
147
-
148
- expect(skeletonButton.tagName.toLowerCase()).toBe('div');
149
- });
150
-
151
- it('skeleton lines have correct width props', () => {
152
- render(<SkeletonCard />);
153
-
154
- // Check that the skeleton lines are rendered
155
- expect(screen.getByTestId('skeleton-line-1')).toBeInTheDocument();
156
- expect(screen.getByTestId('skeleton-line-2')).toBeInTheDocument();
157
- expect(screen.getByTestId('skeleton-line-3')).toBeInTheDocument();
158
- expect(screen.getByTestId('skeleton-line-4')).toBeInTheDocument();
159
- });
160
-
161
- it('renders without any interactive elements', () => {
162
- const { container } = render(<SkeletonCard />);
163
- const buttons = container.querySelectorAll('button');
164
- const links = container.querySelectorAll('a');
165
-
166
- expect(buttons.length).toBe(0);
167
- expect(links.length).toBe(0);
168
- });
169
- });