@times-components/ts-components 1.145.1-b32ea924749bafdf12e3e8515023538fa20e7808.3 → 1.145.1-cfea81c4084e6f91221ea00fec9fc730d5b933cb.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 (136) hide show
  1. package/dist/components/carousel-component/CarouselComponent.stories.js +146 -0
  2. package/dist/components/carousel-component/CarouselItem.d.ts +3 -0
  3. package/dist/components/carousel-component/CarouselItem.js +11 -0
  4. package/dist/components/carousel-component/DefaultNavigationArrow.d.ts +8 -0
  5. package/dist/components/carousel-component/DefaultNavigationArrow.js +6 -0
  6. package/dist/components/carousel-component/DefaultPageDot.d.ts +8 -0
  7. package/dist/components/carousel-component/DefaultPageDot.js +4 -0
  8. package/dist/components/carousel-component/__tests__/CarouselComponent.test.d.ts +1 -0
  9. package/dist/components/carousel-component/__tests__/CarouselComponent.test.js +163 -0
  10. package/dist/components/carousel-component/__tests__/CarouselItem.test.d.ts +1 -0
  11. package/dist/components/carousel-component/__tests__/CarouselItem.test.js +80 -0
  12. package/dist/components/carousel-component/__tests__/DefaultNavigationArrow.test.d.ts +1 -0
  13. package/dist/components/carousel-component/__tests__/DefaultNavigationArrow.test.js +62 -0
  14. package/dist/components/carousel-component/__tests__/DefaultPageDot.test.d.ts +1 -0
  15. package/dist/components/carousel-component/__tests__/DefaultPageDot.test.js +68 -0
  16. package/dist/components/carousel-component/hooks/__tests__/useCarousel.test.d.ts +1 -0
  17. package/dist/components/carousel-component/hooks/__tests__/useCarousel.test.js +314 -0
  18. package/dist/components/carousel-component/hooks/useCarousel.d.ts +2 -0
  19. package/dist/components/carousel-component/hooks/useCarousel.js +140 -0
  20. package/dist/components/carousel-component/index.d.ts +4 -0
  21. package/dist/components/carousel-component/index.js +20 -0
  22. package/dist/components/carousel-component/styles.d.ts +30 -0
  23. package/dist/components/carousel-component/styles.js +120 -0
  24. package/dist/components/carousel-component/types.d.ts +46 -0
  25. package/dist/components/carousel-component/types.js +2 -0
  26. package/dist/components/opta/cricket/scorecard/OptaCricketScorecard.js +2 -10
  27. package/dist/components/opta/cricket/scorecard/__tests__/OptaCricketScorecard.test.js +17 -94
  28. package/dist/components/opta/football/summary/OptaFootballSummary.js +2 -10
  29. package/dist/components/opta/football/summary/__tests__/OptaFootballSummary.test.js +18 -95
  30. package/dist/components/opta/rugby/summary/OptaRugbySummary.js +2 -10
  31. package/dist/components/opta/rugby/summary/__tests__/OptaRugbySummary.test.js +17 -94
  32. package/dist/components/trip-cards/SkeletonCard.d.ts +2 -0
  33. package/dist/components/trip-cards/SkeletonCard.js +21 -0
  34. package/dist/components/trip-cards/TripCard.d.ts +3 -0
  35. package/dist/components/trip-cards/TripCard.js +47 -0
  36. package/dist/components/trip-cards/TripCards.stories.d.ts +1 -0
  37. package/dist/components/trip-cards/TripCards.stories.js +40 -0
  38. package/dist/components/trip-cards/TripCardsLayout.d.ts +3 -0
  39. package/dist/components/trip-cards/TripCardsLayout.js +26 -0
  40. package/dist/components/trip-cards/__tests__/SkeletonCard.test.d.ts +1 -0
  41. package/dist/components/trip-cards/__tests__/SkeletonCard.test.js +139 -0
  42. package/dist/components/trip-cards/__tests__/TripCard.test.d.ts +1 -0
  43. package/dist/components/trip-cards/__tests__/TripCard.test.js +95 -0
  44. package/dist/components/trip-cards/__tests__/TripCardsLayout.test.d.ts +1 -0
  45. package/dist/components/trip-cards/__tests__/TripCardsLayout.test.js +277 -0
  46. package/dist/components/trip-cards/__tests__/assets.test.d.ts +1 -0
  47. package/dist/components/trip-cards/__tests__/assets.test.js +165 -0
  48. package/dist/components/trip-cards/__tests__/helpers.test.d.ts +1 -0
  49. package/dist/components/trip-cards/__tests__/helpers.test.js +135 -0
  50. package/dist/components/trip-cards/__tests__/index.test.d.ts +1 -0
  51. package/dist/components/trip-cards/__tests__/index.test.js +437 -0
  52. package/dist/components/trip-cards/__tests__/mockData.test.d.ts +1 -0
  53. package/dist/components/trip-cards/__tests__/mockData.test.js +57 -0
  54. package/dist/components/trip-cards/__tests__/skeletonStyles.test.d.ts +1 -0
  55. package/dist/components/trip-cards/__tests__/skeletonStyles.test.js +194 -0
  56. package/dist/components/trip-cards/assets/BoatIcon.d.ts +1 -0
  57. package/dist/components/trip-cards/assets/BoatIcon.js +4 -0
  58. package/dist/components/trip-cards/assets/CalendarIcon.d.ts +1 -0
  59. package/dist/components/trip-cards/assets/CalendarIcon.js +4 -0
  60. package/dist/components/trip-cards/assets/ChevronRightIcon.d.ts +1 -0
  61. package/dist/components/trip-cards/assets/ChevronRightIcon.js +4 -0
  62. package/dist/components/trip-cards/assets/LocationIcon.d.ts +1 -0
  63. package/dist/components/trip-cards/assets/LocationIcon.js +4 -0
  64. package/dist/components/trip-cards/assets/MoonIcon.d.ts +1 -0
  65. package/dist/components/trip-cards/assets/MoonIcon.js +4 -0
  66. package/dist/components/trip-cards/assets/index.d.ts +6 -0
  67. package/dist/components/trip-cards/assets/index.js +7 -0
  68. package/dist/components/trip-cards/helpers.d.ts +4 -0
  69. package/dist/components/trip-cards/helpers.js +74 -0
  70. package/dist/components/trip-cards/index.d.ts +4 -0
  71. package/dist/components/trip-cards/index.js +70 -0
  72. package/dist/components/trip-cards/mockData.d.ts +3 -0
  73. package/dist/components/trip-cards/mockData.js +323 -0
  74. package/dist/components/trip-cards/skeletonStyles.d.ts +9 -0
  75. package/dist/components/trip-cards/skeletonStyles.js +37 -0
  76. package/dist/components/trip-cards/styles.d.ts +39 -0
  77. package/dist/components/trip-cards/styles.js +387 -0
  78. package/dist/components/trip-cards/types.d.ts +87 -0
  79. package/dist/components/trip-cards/types.js +2 -0
  80. package/dist/index.d.ts +1 -0
  81. package/dist/index.js +2 -1
  82. package/package.json +3 -3
  83. package/rnw.js +1 -1
  84. package/src/components/carousel-component/CarouselComponent.stories.tsx +220 -0
  85. package/src/components/carousel-component/CarouselItem.tsx +20 -0
  86. package/src/components/carousel-component/DefaultNavigationArrow.tsx +37 -0
  87. package/src/components/carousel-component/DefaultPageDot.tsx +20 -0
  88. package/src/components/carousel-component/__tests__/CarouselComponent.test.tsx +259 -0
  89. package/src/components/carousel-component/__tests__/CarouselItem.test.tsx +140 -0
  90. package/src/components/carousel-component/__tests__/DefaultNavigationArrow.test.tsx +153 -0
  91. package/src/components/carousel-component/__tests__/DefaultPageDot.test.tsx +105 -0
  92. package/src/components/carousel-component/hooks/__tests__/useCarousel.test.ts +438 -0
  93. package/src/components/carousel-component/hooks/useCarousel.ts +187 -0
  94. package/src/components/carousel-component/index.tsx +88 -0
  95. package/src/components/carousel-component/styles.ts +140 -0
  96. package/src/components/carousel-component/types.ts +51 -0
  97. package/src/components/opta/cricket/scorecard/OptaCricketScorecard.tsx +0 -13
  98. package/src/components/opta/cricket/scorecard/__tests__/OptaCricketScorecard.test.tsx +16 -126
  99. package/src/components/opta/cricket/scorecard/__tests__/__snapshots__/OptaCricketScorecard.test.tsx.snap +6 -5
  100. package/src/components/opta/football/summary/OptaFootballSummary.tsx +0 -13
  101. package/src/components/opta/football/summary/__tests__/OptaFootballSummary.test.tsx +18 -127
  102. package/src/components/opta/football/summary/__tests__/__snapshots__/OptaFootballSummary.test.tsx.snap +6 -5
  103. package/src/components/opta/rugby/summary/OptaRugbySummary.tsx +0 -13
  104. package/src/components/opta/rugby/summary/__tests__/OptaRugbySummary.test.tsx +17 -127
  105. package/src/components/opta/rugby/summary/__tests__/__snapshots__/OptaRugbySummary.test.tsx.snap +6 -5
  106. package/src/components/trip-cards/SkeletonCard.tsx +54 -0
  107. package/src/components/trip-cards/TripCard.tsx +135 -0
  108. package/src/components/trip-cards/TripCards.stories.tsx +67 -0
  109. package/src/components/trip-cards/TripCardsLayout.tsx +75 -0
  110. package/src/components/trip-cards/__tests__/SkeletonCard.test.tsx +169 -0
  111. package/src/components/trip-cards/__tests__/TripCard.test.tsx +120 -0
  112. package/src/components/trip-cards/__tests__/TripCardsLayout.test.tsx +532 -0
  113. package/src/components/trip-cards/__tests__/assets.test.tsx +206 -0
  114. package/src/components/trip-cards/__tests__/helpers.test.ts +165 -0
  115. package/src/components/trip-cards/__tests__/index.test.tsx +499 -0
  116. package/src/components/trip-cards/__tests__/mockData.test.ts +67 -0
  117. package/src/components/trip-cards/__tests__/skeletonStyles.test.tsx +256 -0
  118. package/src/components/trip-cards/assets/BoatIcon.tsx +17 -0
  119. package/src/components/trip-cards/assets/CalendarIcon.tsx +17 -0
  120. package/src/components/trip-cards/assets/ChevronRightIcon.tsx +20 -0
  121. package/src/components/trip-cards/assets/LocationIcon.tsx +17 -0
  122. package/src/components/trip-cards/assets/MoonIcon.tsx +17 -0
  123. package/src/components/trip-cards/assets/index.ts +7 -0
  124. package/src/components/trip-cards/helpers.ts +99 -0
  125. package/src/components/trip-cards/index.tsx +104 -0
  126. package/src/components/trip-cards/mockData.ts +351 -0
  127. package/src/components/trip-cards/skeletonStyles.ts +46 -0
  128. package/src/components/trip-cards/styles.ts +426 -0
  129. package/src/components/trip-cards/types.ts +91 -0
  130. package/src/index.ts +2 -0
  131. package/dist/components/opta/utils/__tests__/emitEvent.test.js +0 -264
  132. package/dist/components/opta/utils/emitEvent.d.ts +0 -1
  133. package/dist/components/opta/utils/emitEvent.js +0 -9
  134. package/src/components/opta/utils/__tests__/emitEvent.test.tsx +0 -415
  135. package/src/components/opta/utils/emitEvent.ts +0 -11
  136. /package/dist/components/{opta/utils/__tests__/emitEvent.test.d.ts → carousel-component/CarouselComponent.stories.d.ts} +0 -0
@@ -0,0 +1,187 @@
1
+ import { useState, useEffect, useRef, useCallback } from 'react';
2
+ import { UseCarouselOptions, UseCarouselReturn } from '../types';
3
+
4
+ export const useCarousel = (
5
+ totalItems: number,
6
+ options: UseCarouselOptions = {}
7
+ ): UseCarouselReturn => {
8
+ const { itemsPerPage = 2, onPageChange } = options;
9
+
10
+ const [currentPage, setCurrentPage] = useState(0);
11
+ const carouselRef = useRef<HTMLDivElement>(null);
12
+ const isScrollingRef = useRef(false);
13
+ const isDraggingRef = useRef(false);
14
+ const startXRef = useRef(0);
15
+
16
+ const totalPages = Math.ceil(totalItems / itemsPerPage);
17
+
18
+ const scrollToPage = useCallback(
19
+ (page: number) => {
20
+ if (carouselRef.current) {
21
+ const cardElements = carouselRef.current.children;
22
+
23
+ if (cardElements.length > 0) {
24
+ isScrollingRef.current = true;
25
+
26
+ const container = carouselRef.current;
27
+ const targetCardIndex = page * itemsPerPage;
28
+ const targetCard = cardElements[targetCardIndex] as HTMLElement;
29
+
30
+ if (targetCard) {
31
+ const targetScroll = targetCard.offsetLeft;
32
+
33
+ container.scrollTo({
34
+ left: targetScroll,
35
+ behavior: 'smooth'
36
+ });
37
+ setCurrentPage(page);
38
+
39
+ if (onPageChange) {
40
+ onPageChange(page);
41
+ }
42
+
43
+ setTimeout(() => {
44
+ isScrollingRef.current = false;
45
+ }, 800);
46
+ }
47
+ }
48
+ }
49
+ },
50
+ [itemsPerPage, onPageChange]
51
+ );
52
+
53
+ const handlePrevious = useCallback(
54
+ () => {
55
+ const newPage = Math.max(0, currentPage - 1);
56
+ scrollToPage(newPage);
57
+ },
58
+ [currentPage, scrollToPage]
59
+ );
60
+
61
+ const handleNext = useCallback(
62
+ () => {
63
+ const newPage = Math.min(totalPages - 1, currentPage + 1);
64
+ scrollToPage(newPage);
65
+ },
66
+ [currentPage, totalPages, scrollToPage]
67
+ );
68
+
69
+ const handleMouseDown = useCallback((e: React.MouseEvent) => {
70
+ if (!carouselRef.current) {
71
+ return;
72
+ }
73
+ e.preventDefault();
74
+ isDraggingRef.current = true;
75
+ startXRef.current = e.pageX;
76
+ carouselRef.current.style.cursor = 'grabbing';
77
+ }, []);
78
+
79
+ const handleMouseMove = useCallback((e: React.MouseEvent) => {
80
+ if (!isDraggingRef.current) {
81
+ return;
82
+ }
83
+ e.preventDefault();
84
+ }, []);
85
+
86
+ const handleMouseUp = useCallback(
87
+ (e: React.MouseEvent) => {
88
+ if (!isDraggingRef.current) {
89
+ return;
90
+ }
91
+ isDraggingRef.current = false;
92
+
93
+ if (carouselRef.current) {
94
+ carouselRef.current.style.cursor = 'grab';
95
+
96
+ const endX = e.pageX;
97
+ const diff = startXRef.current - endX;
98
+
99
+ if (Math.abs(diff) > 30) {
100
+ if (diff > 0) {
101
+ handleNext();
102
+ } else {
103
+ handlePrevious();
104
+ }
105
+ }
106
+ }
107
+ },
108
+ [handleNext, handlePrevious]
109
+ );
110
+
111
+ const handleMouseLeave = useCallback(() => {
112
+ if (!isDraggingRef.current) {
113
+ return;
114
+ }
115
+ isDraggingRef.current = false;
116
+ if (carouselRef.current) {
117
+ carouselRef.current.style.cursor = 'grab';
118
+ }
119
+ }, []);
120
+
121
+ const handleScroll = useCallback(
122
+ () => {
123
+ if (isScrollingRef.current) {
124
+ return;
125
+ }
126
+
127
+ if (carouselRef.current) {
128
+ const container = carouselRef.current;
129
+ const children = container.children;
130
+ if (children.length === 0) {
131
+ return;
132
+ }
133
+
134
+ const scrollLeft = container.scrollLeft;
135
+
136
+ let closestPage = 0;
137
+ let closestDistance = Infinity;
138
+
139
+ for (let page = 0; page < totalPages; page++) {
140
+ const cardIndex = page * itemsPerPage;
141
+ if (cardIndex < children.length) {
142
+ const card = children[cardIndex] as HTMLElement;
143
+ const distance = Math.abs(card.offsetLeft - scrollLeft);
144
+ if (distance < closestDistance) {
145
+ closestDistance = distance;
146
+ closestPage = page;
147
+ }
148
+ }
149
+ }
150
+
151
+ if (closestPage !== currentPage) {
152
+ setCurrentPage(closestPage);
153
+ if (onPageChange) {
154
+ onPageChange(closestPage);
155
+ }
156
+ }
157
+ }
158
+ },
159
+ [currentPage, totalPages, itemsPerPage, onPageChange]
160
+ );
161
+
162
+ useEffect(
163
+ () => {
164
+ const carousel = carouselRef.current;
165
+ if (carousel) {
166
+ carousel.addEventListener('scroll', handleScroll);
167
+ return () => carousel.removeEventListener('scroll', handleScroll);
168
+ }
169
+ return undefined;
170
+ },
171
+ [handleScroll]
172
+ );
173
+
174
+ return {
175
+ currentPage,
176
+ totalPages,
177
+ carouselRef,
178
+ isScrolling: isScrollingRef.current,
179
+ handlePrevious,
180
+ handleNext,
181
+ scrollToPage,
182
+ handleMouseDown,
183
+ handleMouseMove,
184
+ handleMouseUp,
185
+ handleMouseLeave
186
+ };
187
+ };
@@ -0,0 +1,88 @@
1
+ import React from 'react';
2
+ import { useCarousel } from './hooks/useCarousel';
3
+ import {
4
+ CarouselContainer,
5
+ CarouselWrapper,
6
+ CarouselContent,
7
+ CardsRow,
8
+ PageControl
9
+ } from './styles';
10
+ import { DefaultNavigationArrow } from './DefaultNavigationArrow';
11
+ import { DefaultPageDot } from './DefaultPageDot';
12
+ import { CarouselComponentProps } from './types';
13
+
14
+ export const CarouselComponent: React.FC<CarouselComponentProps> = ({
15
+ items,
16
+ options,
17
+ showArrows = true,
18
+ showDots = true,
19
+ arrowComponent: CustomArrow,
20
+ dotComponent: CustomDot,
21
+ className
22
+ }) => {
23
+ const {
24
+ currentPage,
25
+ totalPages,
26
+ carouselRef,
27
+ handlePrevious,
28
+ handleNext,
29
+ scrollToPage,
30
+ handleMouseDown,
31
+ handleMouseMove,
32
+ handleMouseUp,
33
+ handleMouseLeave
34
+ } = useCarousel(items.length, options);
35
+
36
+ const ArrowComponent = CustomArrow || DefaultNavigationArrow;
37
+ const DotComponent = CustomDot || DefaultPageDot;
38
+
39
+ return (
40
+ <CarouselContainer className={className}>
41
+ <CarouselWrapper>
42
+ {showArrows && (
43
+ <ArrowComponent
44
+ direction="left"
45
+ onClick={handlePrevious}
46
+ disabled={currentPage === 0}
47
+ />
48
+ )}
49
+
50
+ <CarouselContent>
51
+ <CardsRow
52
+ ref={carouselRef}
53
+ onMouseDown={handleMouseDown}
54
+ onMouseMove={handleMouseMove}
55
+ onMouseUp={handleMouseUp}
56
+ onMouseLeave={handleMouseLeave}
57
+ >
58
+ {items}
59
+ </CardsRow>
60
+ </CarouselContent>
61
+
62
+ {showArrows && (
63
+ <ArrowComponent
64
+ direction="right"
65
+ onClick={handleNext}
66
+ disabled={currentPage >= totalPages - 1}
67
+ />
68
+ )}
69
+ </CarouselWrapper>
70
+
71
+ {showDots &&
72
+ totalPages > 1 && (
73
+ <PageControl>
74
+ {Array.from({ length: totalPages }).map((_, pageIndex) => (
75
+ <DotComponent
76
+ key={pageIndex}
77
+ active={pageIndex === currentPage}
78
+ onClick={() => scrollToPage(pageIndex)}
79
+ index={pageIndex}
80
+ />
81
+ ))}
82
+ </PageControl>
83
+ )}
84
+ </CarouselContainer>
85
+ );
86
+ };
87
+
88
+ export { CarouselItem } from './CarouselItem';
@@ -0,0 +1,140 @@
1
+ import styled from 'styled-components';
2
+
3
+ export const breakpoints = {
4
+ sm: '390px',
5
+ md: '768px',
6
+ lg: '1024px',
7
+ xl: '1320px'
8
+ };
9
+
10
+ export const colors = {
11
+ primary: '#005C8A',
12
+ white: '#FFFFFF'
13
+ };
14
+
15
+ export const ItemContainer = styled.div<{
16
+ widthConfig: {
17
+ mobile?: string;
18
+ tablet?: string;
19
+ desktop?: string;
20
+ xl?: string;
21
+ };
22
+ }>`
23
+ flex: 0 0 ${({ widthConfig }) => widthConfig.mobile};
24
+ scroll-snap-align: start;
25
+ border-radius: 8px;
26
+ transition: filter 0.3s ease;
27
+
28
+ @media (min-width: ${breakpoints.md}) {
29
+ flex: 0 0 ${({ widthConfig }) => widthConfig.tablet};
30
+ }
31
+
32
+ @media (min-width: ${breakpoints.lg}) {
33
+ flex: 0 0 ${({ widthConfig }) => widthConfig.desktop};
34
+ }
35
+
36
+ @media (min-width: ${breakpoints.xl}) {
37
+ flex: 0 0 ${({ widthConfig }) => widthConfig.xl};
38
+ }
39
+ `;
40
+
41
+ export const CarouselContainer = styled.div`
42
+ width: 100%;
43
+ `;
44
+
45
+ export const CarouselWrapper = styled.div`
46
+ position: relative;
47
+ width: 100%;
48
+ `;
49
+
50
+ export const CarouselContent = styled.div`
51
+ overflow: hidden;
52
+ `;
53
+
54
+ export const CardsRow = styled.div`
55
+ display: flex;
56
+ gap: 20px;
57
+ overflow-x: auto;
58
+ scroll-snap-type: x mandatory;
59
+ scrollbar-width: none;
60
+ -ms-overflow-style: none;
61
+ padding: 0;
62
+ scroll-behavior: smooth;
63
+ cursor: grab;
64
+ user-select: none;
65
+
66
+ &::-webkit-scrollbar {
67
+ display: none;
68
+ }
69
+
70
+ &:active {
71
+ cursor: grabbing;
72
+ }
73
+
74
+ @media (max-width: ${breakpoints.md}) {
75
+ padding-left: 10px;
76
+ }
77
+ `;
78
+
79
+ export const PageControl = styled.div`
80
+ display: flex;
81
+ justify-content: center;
82
+ align-items: center;
83
+ gap: 10px;
84
+ padding: 12px;
85
+ background: ${colors.white};
86
+ `;
87
+
88
+ export const NavigationArrowButton = styled.button<{
89
+ direction: 'left' | 'right';
90
+ disabled?: boolean;
91
+ }>`
92
+ display: none;
93
+ position: absolute;
94
+ top: 50%;
95
+ transform: translateY(-50%);
96
+ ${({ direction }) =>
97
+ direction === 'left' ? 'left: -60px;' : 'right: -60px;'} z-index: 10;
98
+ width: 48px;
99
+ height: 48px;
100
+ border: none;
101
+ border-radius: 50%;
102
+ background: ${({ disabled }) => (disabled ? '#CCCCCC' : colors.primary)};
103
+ cursor: ${({ disabled }) => (disabled ? 'default' : 'pointer')};
104
+ align-items: center;
105
+ justify-content: center;
106
+ transition: background 0.2s ease;
107
+ pointer-events: ${({ disabled }) => (disabled ? 'none' : 'auto')};
108
+
109
+ svg {
110
+ width: 24px;
111
+ height: 24px;
112
+ }
113
+
114
+ svg path {
115
+ stroke: ${colors.white};
116
+ }
117
+
118
+ &:hover:not(:disabled) {
119
+ background: #004a6e;
120
+ }
121
+
122
+ @media (min-width: ${breakpoints.lg}) {
123
+ display: flex;
124
+ }
125
+ `;
126
+
127
+ export const PageDotButton = styled.button<{ active: boolean }>`
128
+ width: 8px;
129
+ height: 8px;
130
+ border-radius: 1000px;
131
+ border: none;
132
+ padding: 0;
133
+ background: ${({ active }) => (active ? '#01000D' : '#AAAAAA')};
134
+ cursor: pointer;
135
+ transition: background 0.2s ease;
136
+
137
+ &:hover {
138
+ background: #01000d;
139
+ }
140
+ `;
@@ -0,0 +1,51 @@
1
+ import { ReactNode } from 'react';
2
+
3
+ export interface CarouselComponentProps {
4
+ items: ReactNode[];
5
+ options?: UseCarouselOptions;
6
+ showArrows?: boolean;
7
+ showDots?: boolean;
8
+ arrowComponent?: React.ComponentType<{
9
+ direction: 'left' | 'right';
10
+ onClick: () => void;
11
+ disabled: boolean;
12
+ }>;
13
+ dotComponent?: React.ComponentType<{
14
+ active: boolean;
15
+ onClick: () => void;
16
+ index: number;
17
+ }>;
18
+ className?: string;
19
+ }
20
+
21
+ export interface CarouselItemProps {
22
+ children: ReactNode;
23
+ widthConfig?: {
24
+ xs?: string;
25
+ mobile?: string;
26
+ tablet?: string;
27
+ desktop?: string;
28
+ xl?: string;
29
+ };
30
+ className?: string;
31
+ }
32
+
33
+ // Carousel Hook Types
34
+ export interface UseCarouselOptions {
35
+ itemsPerPage?: number;
36
+ onPageChange?: (page: number) => void;
37
+ }
38
+
39
+ export interface UseCarouselReturn {
40
+ currentPage: number;
41
+ totalPages: number;
42
+ carouselRef: React.RefObject<HTMLDivElement>;
43
+ isScrolling: boolean;
44
+ handlePrevious: () => void;
45
+ handleNext: () => void;
46
+ scrollToPage: (page: number) => void;
47
+ handleMouseDown: (e: React.MouseEvent) => void;
48
+ handleMouseMove: (e: React.MouseEvent) => void;
49
+ handleMouseUp: (e: React.MouseEvent) => void;
50
+ handleMouseLeave: () => void;
51
+ }
@@ -12,7 +12,6 @@ import {
12
12
  import { Container, PlaceholderContainer } from '../../shared/shared-styles';
13
13
  import { WidgetContainer } from './styles';
14
14
  import Button from '../../shared/button/Button';
15
- import { emitEvent } from '../../utils/emitEvent';
16
15
 
17
16
  export const OptaCricketScorecard: React.FC<{
18
17
  competition: string;
@@ -31,7 +30,6 @@ export const OptaCricketScorecard: React.FC<{
31
30
  heightLg = 258
32
31
  }) => {
33
32
  const ref = React.createRef<HTMLDivElement>();
34
- const containerRef = React.createRef<HTMLDivElement>();
35
33
  const [isReady, setIsReady] = useState<boolean>(false);
36
34
  const [showDetails, setShowDetails] = useState<boolean>(false);
37
35
 
@@ -83,16 +81,6 @@ export const OptaCricketScorecard: React.FC<{
83
81
  });
84
82
  }, []);
85
83
 
86
- useEffect(
87
- () => {
88
- const height = containerRef.current
89
- ? containerRef.current.offsetHeight
90
- : 0;
91
- emitEvent('updateHeight', height);
92
- },
93
- [showDetails]
94
- );
95
-
96
84
  return (
97
85
  <Container
98
86
  fullWidth={full_width}
@@ -100,7 +88,6 @@ export const OptaCricketScorecard: React.FC<{
100
88
  heightMd={heightMd}
101
89
  heightLg={heightLg}
102
90
  hasPadding
103
- ref={containerRef}
104
91
  >
105
92
  <WidgetContainer ref={ref} showDetails={showDetails} />
106
93
 
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { render, act, fireEvent, waitFor } from '@testing-library/react';
2
+ import { render, act, fireEvent } from '@testing-library/react';
3
3
  import 'regenerator-runtime';
4
4
  import '@testing-library/jest-dom';
5
5
 
@@ -10,27 +10,22 @@ jest.mock('@times-components/image', () => ({
10
10
  const mockInitSettings = jest.fn();
11
11
  const mockInitStyleSheet = jest.fn();
12
12
  const mockInitComponent = jest.fn();
13
- const mockInitScript = jest.fn();
14
- const mockEmitEvent = jest.fn();
13
+ const mockHasMatchEvents = jest.fn();
15
14
 
16
- const mockInitElement = jest.fn(() => {
15
+ const mockInitElement = () => {
17
16
  const element = document.createElement('div');
18
17
  element.appendChild(document.createTextNode('Widget'));
19
18
  return element;
20
- });
19
+ };
21
20
 
22
21
  jest.mock('../../../utils/config', () => ({
23
22
  initSettings: mockInitSettings,
24
23
  initStyleSheet: mockInitStyleSheet,
25
- initScript: mockInitScript,
24
+ initScript: () => new Promise(resolve => resolve({})),
26
25
  initElement: mockInitElement,
27
26
  initComponent: mockInitComponent
28
27
  }));
29
28
 
30
- jest.mock('../../../utils/emitEvent', () => ({
31
- emitEvent: mockEmitEvent
32
- }));
33
-
34
29
  import { OptaCricketScorecard } from '../OptaCricketScorecard';
35
30
 
36
31
  const requiredProps = {
@@ -41,26 +36,19 @@ const requiredProps = {
41
36
  describe('OptaCricketScorecard', () => {
42
37
  beforeEach(() => {
43
38
  jest.clearAllMocks();
44
- mockInitScript.mockResolvedValue({});
45
- });
46
-
47
- afterEach(() => {
48
- jest.clearAllMocks();
49
- document.body.innerHTML = '';
50
39
  });
51
40
 
52
41
  it('should render correctly', async () => {
53
- const { asFragment, getByRole } = render(
54
- <OptaCricketScorecard {...requiredProps} />
55
- );
42
+ const { asFragment } = render(<OptaCricketScorecard {...requiredProps} />);
56
43
 
57
- await waitFor(() => {
58
- expect(mockInitSettings).toHaveBeenCalledTimes(1);
44
+ act(() => {
45
+ mockInitComponent();
46
+ mockHasMatchEvents();
59
47
  });
60
48
 
61
- expect(mockInitStyleSheet).toHaveBeenCalledWith('cricket');
49
+ expect(mockInitSettings).toHaveBeenCalledTimes(1);
50
+ expect(mockInitStyleSheet).toHaveBeenCalledTimes(1);
62
51
  expect(mockInitComponent).toHaveBeenCalledTimes(1);
63
- expect(getByRole('button')).toBeInTheDocument();
64
52
 
65
53
  expect(asFragment()).toMatchSnapshot();
66
54
  });
@@ -71,112 +59,14 @@ describe('OptaCricketScorecard', () => {
71
59
  expect(button).not.toBeDisabled();
72
60
  });
73
61
 
74
- it('should toggle details when button is clicked', async () => {
62
+ it('should toggle details when button is clicked', () => {
75
63
  const { getByRole } = render(<OptaCricketScorecard {...requiredProps} />);
76
64
  const button = getByRole('button');
77
65
 
78
66
  expect(button).toHaveTextContent('Show Details');
79
-
80
- act(() => {
81
- fireEvent.click(button);
82
- });
83
-
84
- await waitFor(() => {
85
- expect(button).toHaveTextContent('Hide Details');
86
- });
87
-
88
- act(() => {
89
- fireEvent.click(button);
90
- });
91
-
92
- await waitFor(() => {
93
- expect(button).toHaveTextContent('Show Details');
94
- });
95
- });
96
-
97
- describe('emitEvent', () => {
98
- it('should call emitEvent with updateHeight when details are toggled', async () => {
99
- const { getByRole } = render(<OptaCricketScorecard {...requiredProps} />);
100
- const button = getByRole('button');
101
-
102
- // Clear initial calls
103
- jest.clearAllMocks();
104
-
105
- act(() => {
106
- fireEvent.click(button);
107
- });
108
-
109
- await waitFor(() => {
110
- expect(mockEmitEvent).toHaveBeenCalledWith(
111
- 'updateHeight',
112
- expect.any(Number)
113
- );
114
- });
115
- });
116
-
117
- it('should emit updateHeight event on each toggle', async () => {
118
- const { getByRole } = render(<OptaCricketScorecard {...requiredProps} />);
119
- const button = getByRole('button');
120
-
121
- // Clear initial calls
122
- jest.clearAllMocks();
123
-
124
- // First toggle
125
- act(() => {
126
- fireEvent.click(button);
127
- });
128
-
129
- await waitFor(() => {
130
- expect(mockEmitEvent).toHaveBeenCalledTimes(1);
131
- });
132
-
133
- // Second toggle
134
- act(() => {
135
- fireEvent.click(button);
136
- });
137
-
138
- await waitFor(() => {
139
- expect(mockEmitEvent).toHaveBeenCalledTimes(2);
140
- });
141
-
142
- // Third toggle
143
- act(() => {
144
- fireEvent.click(button);
145
- });
146
-
147
- await waitFor(() => {
148
- expect(mockEmitEvent).toHaveBeenCalledTimes(3);
149
- });
150
- });
151
-
152
- it('should emit updateHeight with container offsetHeight', async () => {
153
- const { getByRole, container } = render(
154
- <OptaCricketScorecard {...requiredProps} />
155
- );
156
- const button = getByRole('button');
157
-
158
- // Clear initial calls
159
- jest.clearAllMocks();
160
-
161
- // Mock offsetHeight
162
- const containerElement = container.querySelector('[class*="Container"]');
163
- if (containerElement) {
164
- Object.defineProperty(containerElement, 'offsetHeight', {
165
- value: 300,
166
- configurable: true
167
- });
168
- }
169
-
170
- act(() => {
171
- fireEvent.click(button);
172
- });
173
-
174
- await waitFor(() => {
175
- expect(mockEmitEvent).toHaveBeenCalledWith(
176
- 'updateHeight',
177
- expect.any(Number)
178
- );
179
- });
180
- });
67
+ fireEvent.click(button);
68
+ expect(button).toHaveTextContent('Hide Details');
69
+ fireEvent.click(button);
70
+ expect(button).toHaveTextContent('Show Details');
181
71
  });
182
72
  });