@telus-uds/components-web 2.33.2 → 2.34.1

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 (192) hide show
  1. package/CHANGELOG.md +29 -3
  2. package/lib/Badge/Badge.js +4 -2
  3. package/lib/BlockQuote/BlockQuote.js +4 -2
  4. package/lib/Breadcrumbs/Breadcrumbs.js +7 -5
  5. package/lib/Breadcrumbs/Item/Item.js +2 -13
  6. package/lib/Callout/Callout.js +4 -2
  7. package/lib/Card/Card.js +3 -5
  8. package/lib/Card/CardContent.js +4 -2
  9. package/lib/Countdown/Countdown.js +2 -6
  10. package/lib/Countdown/Segment.js +4 -2
  11. package/lib/DatePicker/CalendarContainer.js +2 -2
  12. package/lib/DatePicker/DatePicker.js +21 -35
  13. package/lib/Disclaimer/Disclaimer.js +4 -2
  14. package/lib/ExpandCollapseMini/ExpandCollapseMini.js +5 -11
  15. package/lib/ExpandCollapseMini/ExpandCollapseMiniControl.js +4 -2
  16. package/lib/Footnote/Footnote.js +32 -37
  17. package/lib/Footnote/FootnoteLink.js +9 -6
  18. package/lib/IconButton/IconButton.js +4 -11
  19. package/lib/Image/Image.js +5 -3
  20. package/lib/List/ListItem.js +2 -7
  21. package/lib/NavigationBar/NavigationBar.js +8 -18
  22. package/lib/NavigationBar/NavigationItem.js +4 -9
  23. package/lib/NavigationBar/NavigationSubMenu.js +8 -7
  24. package/lib/NavigationBar/index.js +2 -0
  25. package/lib/OptimizeImage/OptimizeImage.js +8 -8
  26. package/lib/OrderedList/Item.js +3 -9
  27. package/lib/OrderedList/OrderedList.js +5 -13
  28. package/lib/OrderedList/OrderedListBase.js +3 -8
  29. package/lib/Paragraph/Paragraph.js +5 -3
  30. package/lib/PreviewCard/PreviewCard.js +3 -5
  31. package/lib/PriceLockup/PriceLockup.js +4 -2
  32. package/lib/Progress/ProgressBar.js +4 -2
  33. package/lib/QuantitySelector/QuantitySelector.js +21 -24
  34. package/lib/QuantitySelector/SideButton.js +12 -20
  35. package/lib/ResponsiveImage/ResponsiveImage.js +4 -2
  36. package/lib/Ribbon/Ribbon.js +4 -2
  37. package/lib/SkeletonProvider/SkeletonImage.js +5 -3
  38. package/lib/SkeletonProvider/SkeletonProvider.js +3 -5
  39. package/lib/SkeletonProvider/SkeletonTypography.js +5 -3
  40. package/lib/Span/Span.js +5 -3
  41. package/lib/Spinner/Spinner.js +4 -2
  42. package/lib/Spinner/SpinnerContent.js +4 -2
  43. package/lib/StoryCard/StoryCard.js +3 -5
  44. package/lib/Table/Body.js +4 -2
  45. package/lib/Table/Cell.js +5 -3
  46. package/lib/Table/Header.js +6 -6
  47. package/lib/Table/Row.js +6 -6
  48. package/lib/Table/SubHeading.js +6 -6
  49. package/lib/Table/Table.js +6 -8
  50. package/lib/TermsAndConditions/ExpandCollapse.js +2 -7
  51. package/lib/TermsAndConditions/TermsAndConditions.js +5 -14
  52. package/lib/Testimonial/Testimonial.js +4 -2
  53. package/lib/Toast/Toast.js +4 -2
  54. package/lib/Video/Video.js +19 -55
  55. package/lib/VideoPicker/VideoPicker.js +38 -9
  56. package/lib/VideoPicker/VideoPickerPlayer.js +4 -2
  57. package/lib/VideoPicker/VideoPickerThumbnail.js +4 -2
  58. package/lib/VideoPicker/VideoSlider.js +7 -7
  59. package/lib/WaffleGrid/WaffleGrid.js +4 -2
  60. package/lib/WebVideo/WebVideo.js +51 -13
  61. package/lib/WebVideo/utils/index.js +58 -0
  62. package/lib/baseExports.js +6 -0
  63. package/lib/utils/theming/with-client-theme.js +1 -1
  64. package/lib/utils/theming/with-server-theme.js +1 -1
  65. package/lib-module/Badge/Badge.js +4 -2
  66. package/lib-module/BlockQuote/BlockQuote.js +4 -2
  67. package/lib-module/Breadcrumbs/Breadcrumbs.js +7 -5
  68. package/lib-module/Breadcrumbs/Item/Item.js +2 -11
  69. package/lib-module/Callout/Callout.js +4 -2
  70. package/lib-module/Card/Card.js +2 -3
  71. package/lib-module/Card/CardContent.js +4 -2
  72. package/lib-module/Countdown/Countdown.js +2 -3
  73. package/lib-module/Countdown/Segment.js +4 -2
  74. package/lib-module/DatePicker/CalendarContainer.js +2 -2
  75. package/lib-module/DatePicker/DatePicker.js +21 -33
  76. package/lib-module/Disclaimer/Disclaimer.js +4 -2
  77. package/lib-module/ExpandCollapseMini/ExpandCollapseMini.js +5 -9
  78. package/lib-module/ExpandCollapseMini/ExpandCollapseMiniControl.js +4 -2
  79. package/lib-module/Footnote/Footnote.js +31 -36
  80. package/lib-module/Footnote/FootnoteLink.js +9 -7
  81. package/lib-module/IconButton/IconButton.js +4 -9
  82. package/lib-module/Image/Image.js +5 -3
  83. package/lib-module/List/ListItem.js +2 -5
  84. package/lib-module/NavigationBar/NavigationBar.js +9 -17
  85. package/lib-module/NavigationBar/NavigationItem.js +5 -8
  86. package/lib-module/NavigationBar/NavigationSubMenu.js +9 -6
  87. package/lib-module/NavigationBar/index.js +2 -0
  88. package/lib-module/OptimizeImage/OptimizeImage.js +8 -6
  89. package/lib-module/OrderedList/Item.js +3 -7
  90. package/lib-module/OrderedList/OrderedList.js +6 -12
  91. package/lib-module/OrderedList/OrderedListBase.js +3 -6
  92. package/lib-module/Paragraph/Paragraph.js +6 -4
  93. package/lib-module/PreviewCard/PreviewCard.js +2 -3
  94. package/lib-module/PriceLockup/PriceLockup.js +4 -2
  95. package/lib-module/Progress/ProgressBar.js +4 -2
  96. package/lib-module/QuantitySelector/QuantitySelector.js +22 -23
  97. package/lib-module/QuantitySelector/SideButton.js +13 -21
  98. package/lib-module/ResponsiveImage/ResponsiveImage.js +4 -2
  99. package/lib-module/Ribbon/Ribbon.js +4 -2
  100. package/lib-module/SkeletonProvider/SkeletonImage.js +5 -3
  101. package/lib-module/SkeletonProvider/SkeletonProvider.js +3 -3
  102. package/lib-module/SkeletonProvider/SkeletonTypography.js +5 -3
  103. package/lib-module/Span/Span.js +6 -4
  104. package/lib-module/Spinner/Spinner.js +4 -2
  105. package/lib-module/Spinner/SpinnerContent.js +4 -2
  106. package/lib-module/StoryCard/StoryCard.js +2 -3
  107. package/lib-module/Table/Body.js +4 -2
  108. package/lib-module/Table/Cell.js +5 -3
  109. package/lib-module/Table/Header.js +6 -4
  110. package/lib-module/Table/Row.js +6 -4
  111. package/lib-module/Table/SubHeading.js +6 -4
  112. package/lib-module/Table/Table.js +6 -6
  113. package/lib-module/TermsAndConditions/ExpandCollapse.js +2 -5
  114. package/lib-module/TermsAndConditions/TermsAndConditions.js +5 -12
  115. package/lib-module/Testimonial/Testimonial.js +4 -2
  116. package/lib-module/Toast/Toast.js +4 -2
  117. package/lib-module/Video/Video.js +19 -53
  118. package/lib-module/VideoPicker/VideoPicker.js +37 -8
  119. package/lib-module/VideoPicker/VideoPickerPlayer.js +4 -2
  120. package/lib-module/VideoPicker/VideoPickerThumbnail.js +4 -2
  121. package/lib-module/VideoPicker/VideoSlider.js +7 -5
  122. package/lib-module/WaffleGrid/WaffleGrid.js +4 -2
  123. package/lib-module/WebVideo/WebVideo.js +51 -11
  124. package/lib-module/WebVideo/utils/index.js +50 -0
  125. package/lib-module/baseExports.js +1 -1
  126. package/lib-module/utils/theming/with-client-theme.js +2 -2
  127. package/lib-module/utils/theming/with-server-theme.js +2 -2
  128. package/package.json +3 -3
  129. package/src/Badge/Badge.jsx +5 -2
  130. package/src/BlockQuote/BlockQuote.jsx +120 -112
  131. package/src/Breadcrumbs/Breadcrumbs.jsx +84 -77
  132. package/src/Breadcrumbs/Item/Item.jsx +2 -9
  133. package/src/Callout/Callout.jsx +37 -40
  134. package/src/Card/Card.jsx +2 -3
  135. package/src/Card/CardContent.jsx +19 -14
  136. package/src/Countdown/Countdown.jsx +72 -71
  137. package/src/Countdown/Segment.jsx +40 -28
  138. package/src/DatePicker/CalendarContainer.jsx +2 -2
  139. package/src/DatePicker/DatePicker.jsx +21 -34
  140. package/src/Disclaimer/Disclaimer.jsx +5 -3
  141. package/src/ExpandCollapseMini/ExpandCollapseMini.jsx +37 -40
  142. package/src/ExpandCollapseMini/ExpandCollapseMiniControl.jsx +52 -44
  143. package/src/Footnote/Footnote.jsx +32 -38
  144. package/src/Footnote/FootnoteLink.jsx +45 -49
  145. package/src/IconButton/IconButton.jsx +19 -20
  146. package/src/Image/Image.jsx +40 -43
  147. package/src/List/ListItem.jsx +3 -5
  148. package/src/NavigationBar/NavigationBar.jsx +9 -18
  149. package/src/NavigationBar/NavigationItem.jsx +6 -5
  150. package/src/NavigationBar/NavigationSubMenu.jsx +104 -88
  151. package/src/NavigationBar/index.js +3 -0
  152. package/src/OptimizeImage/OptimizeImage.jsx +48 -41
  153. package/src/OrderedList/Item.jsx +34 -35
  154. package/src/OrderedList/OrderedList.jsx +4 -6
  155. package/src/OrderedList/OrderedListBase.jsx +2 -3
  156. package/src/Paragraph/Paragraph.jsx +21 -16
  157. package/src/PreviewCard/PreviewCard.jsx +2 -3
  158. package/src/PriceLockup/PriceLockup.jsx +143 -136
  159. package/src/Progress/ProgressBar.jsx +11 -3
  160. package/src/QuantitySelector/QuantitySelector.jsx +162 -154
  161. package/src/QuantitySelector/SideButton.jsx +52 -56
  162. package/src/ResponsiveImage/ResponsiveImage.jsx +16 -22
  163. package/src/Ribbon/Ribbon.jsx +85 -83
  164. package/src/SkeletonProvider/SkeletonImage.jsx +24 -15
  165. package/src/SkeletonProvider/SkeletonProvider.jsx +3 -3
  166. package/src/SkeletonProvider/SkeletonTypography.jsx +18 -13
  167. package/src/Span/Span.jsx +7 -5
  168. package/src/Spinner/Spinner.jsx +86 -79
  169. package/src/Spinner/SpinnerContent.jsx +31 -33
  170. package/src/StoryCard/StoryCard.jsx +2 -3
  171. package/src/Table/Body.jsx +5 -3
  172. package/src/Table/Cell.jsx +77 -67
  173. package/src/Table/Header.jsx +7 -5
  174. package/src/Table/Row.jsx +7 -5
  175. package/src/Table/SubHeading.jsx +7 -5
  176. package/src/Table/Table.jsx +6 -6
  177. package/src/TermsAndConditions/ExpandCollapse.jsx +2 -6
  178. package/src/TermsAndConditions/TermsAndConditions.jsx +5 -13
  179. package/src/Testimonial/Testimonial.jsx +148 -137
  180. package/src/Toast/Toast.jsx +68 -63
  181. package/src/Video/Video.jsx +25 -45
  182. package/src/VideoPicker/VideoPicker.jsx +114 -75
  183. package/src/VideoPicker/VideoPickerPlayer.jsx +13 -9
  184. package/src/VideoPicker/VideoPickerThumbnail.jsx +102 -94
  185. package/src/VideoPicker/VideoSlider.jsx +8 -6
  186. package/src/WaffleGrid/WaffleGrid.jsx +36 -40
  187. package/src/WebVideo/WebVideo.jsx +114 -60
  188. package/src/WebVideo/utils/index.js +56 -0
  189. package/src/baseExports.js +1 -0
  190. package/src/utils/theming/with-client-theme.jsx +2 -2
  191. package/src/utils/theming/with-server-theme.jsx +2 -2
  192. package/types/WebVideo.d.ts +2 -1
@@ -90,74 +90,79 @@ const ToastContainer = styled.div`
90
90
  animation: ${animation};
91
91
  `
92
92
 
93
- const Toast = ({ toast, copy, headline, link, tokens, variant = {}, ...rest }) => {
94
- // viewport hook added to work adjust the padding to different sizes
95
- const viewport = useViewport()
93
+ const Toast = React.forwardRef(
94
+ ({ toast, copy, headline, link, tokens, variant = {}, ...rest }, ref) => {
95
+ // viewport hook added to work adjust the padding to different sizes
96
+ const viewport = useViewport()
96
97
 
97
- const {
98
- containerBackgroundColor,
99
- containerGap,
100
- animationHeightBefore,
101
- animationHeightAfter,
102
- animationPaddingBottomBefore,
103
- animationPaddingBottomAfter,
104
- animationPaddingTopBefore,
105
- animationPaddingTopAfter,
106
- animationBackgroundColorBefore,
107
- animationBackgroundColorAfter,
108
- animationColorBefore,
109
- animationColorAfter,
110
- chevronlinkFontWeight,
111
- ...extraTokens
112
- } = useThemeTokens('Toast', tokens, variant, { viewport })
98
+ const {
99
+ containerBackgroundColor,
100
+ containerGap,
101
+ animationHeightBefore,
102
+ animationHeightAfter,
103
+ animationPaddingBottomBefore,
104
+ animationPaddingBottomAfter,
105
+ animationPaddingTopBefore,
106
+ animationPaddingTopAfter,
107
+ animationBackgroundColorBefore,
108
+ animationBackgroundColorAfter,
109
+ animationColorBefore,
110
+ animationColorAfter,
111
+ chevronlinkFontWeight,
112
+ ...extraTokens
113
+ } = useThemeTokens('Toast', tokens, variant, { viewport })
113
114
 
114
- // inherit ChevronLink tokens for animation colors
115
- const { color: chevronDefaultColor } = useThemeTokens('ChevronLink', {}, {})
116
- const { color: chevronInverseColor } = useThemeTokens('ChevronLink', {}, { inverse: true })
115
+ // inherit ChevronLink tokens for animation colors
116
+ const { color: chevronDefaultColor } = useThemeTokens('ChevronLink', {}, {})
117
+ const { color: chevronInverseColor } = useThemeTokens('ChevronLink', {}, { inverse: true })
117
118
 
118
- if (!toast) {
119
- return null
119
+ if (!toast) {
120
+ return null
121
+ }
122
+
123
+ return (
124
+ <ToastContainer
125
+ containerBackgroundColor={containerBackgroundColor}
126
+ containerGap={containerGap}
127
+ animationHeightBefore={animationHeightBefore}
128
+ animationHeightAfter={animationHeightAfter}
129
+ animationPaddingBottomBefore={animationPaddingBottomBefore}
130
+ animationPaddingBottomAfter={animationPaddingBottomAfter}
131
+ animationPaddingTopBefore={animationPaddingTopBefore}
132
+ animationPaddingTopAfter={animationPaddingTopAfter}
133
+ animationBackgroundColorBefore={animationBackgroundColorBefore}
134
+ animationBackgroundColorAfter={animationBackgroundColorAfter}
135
+ animationColorBefore={animationColorBefore}
136
+ animationColorAfter={animationColorAfter}
137
+ animationFillColorBefore={chevronInverseColor}
138
+ animationFillColorAfter={chevronDefaultColor}
139
+ ref={ref}
140
+ {...extraTokens}
141
+ {...selectProps(rest)}
142
+ >
143
+ {headline && <Typography variant={{ bold: true, inverse: true }}>{headline}</Typography>}
144
+ <Spacer space={2} direction="row" />
145
+ <Typography variant={{ inverse: true }}>{copy}</Typography>
146
+ <Spacer space={2} direction="row" />
147
+ {link && (
148
+ <ChevronLink
149
+ variant={{
150
+ inverse: true
151
+ }}
152
+ tokens={{ blockFontWeight: chevronlinkFontWeight }}
153
+ href={link.href}
154
+ LinkRouter={link.LinkRouter}
155
+ linkRouterProps={link.linkRouterProps}
156
+ >
157
+ {link.text}
158
+ </ChevronLink>
159
+ )}
160
+ </ToastContainer>
161
+ )
120
162
  }
163
+ )
121
164
 
122
- return (
123
- <ToastContainer
124
- containerBackgroundColor={containerBackgroundColor}
125
- containerGap={containerGap}
126
- animationHeightBefore={animationHeightBefore}
127
- animationHeightAfter={animationHeightAfter}
128
- animationPaddingBottomBefore={animationPaddingBottomBefore}
129
- animationPaddingBottomAfter={animationPaddingBottomAfter}
130
- animationPaddingTopBefore={animationPaddingTopBefore}
131
- animationPaddingTopAfter={animationPaddingTopAfter}
132
- animationBackgroundColorBefore={animationBackgroundColorBefore}
133
- animationBackgroundColorAfter={animationBackgroundColorAfter}
134
- animationColorBefore={animationColorBefore}
135
- animationColorAfter={animationColorAfter}
136
- animationFillColorBefore={chevronInverseColor}
137
- animationFillColorAfter={chevronDefaultColor}
138
- {...extraTokens}
139
- {...selectProps(rest)}
140
- >
141
- {headline && <Typography variant={{ bold: true, inverse: true }}>{headline}</Typography>}
142
- <Spacer space={2} direction="row" />
143
- <Typography variant={{ inverse: true }}>{copy}</Typography>
144
- <Spacer space={2} direction="row" />
145
- {link && (
146
- <ChevronLink
147
- variant={{
148
- inverse: true
149
- }}
150
- tokens={{ blockFontWeight: chevronlinkFontWeight }}
151
- href={link.href}
152
- LinkRouter={link.LinkRouter}
153
- linkRouterProps={link.linkRouterProps}
154
- >
155
- {link.text}
156
- </ChevronLink>
157
- )}
158
- </ToastContainer>
159
- )
160
- }
165
+ Toast.displayName = 'Toast'
161
166
 
162
167
  Toast.propTypes = {
163
168
  ...selectedSystemPropTypes,
@@ -1,4 +1,4 @@
1
- import React, { useEffect, useRef, useState } from 'react'
1
+ import React from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
  import styled from 'styled-components'
4
4
  import fscreen from 'fscreen'
@@ -62,26 +62,29 @@ const VideoOverlayElementContainer = styled.div({
62
62
  height: '100%'
63
63
  })
64
64
 
65
- const Video = (props) => {
66
- const refVideoPlayer = useRef({})
67
- const refVideoPlayerContainer = useRef({})
68
- const refKeyboardInstructions = useRef({})
65
+ const Video = ({
66
+ analyticsTracking,
67
+ videoTitle,
68
+ videoBorder = false,
69
+ simpleMode = false,
70
+ copy,
71
+ posterSrc,
72
+ crossOrigin,
73
+ defaultVolume = 100,
74
+ beginMuted = false,
75
+ sources,
76
+ tracks,
77
+ defaultDesktopQuality = 1,
78
+ defaultMobileQuality = 1,
79
+ tokens,
80
+ variant = {},
81
+ ...rest
82
+ }) => {
83
+ const refVideoPlayer = React.useRef({})
84
+ const refVideoPlayerContainer = React.useRef({})
85
+ const refKeyboardInstructions = React.useRef({})
69
86
 
70
87
  let inactivityTimer = null
71
- const {
72
- videoBorder,
73
- simpleMode,
74
- copy,
75
- posterSrc,
76
- crossOrigin,
77
- defaultVolume,
78
- sources,
79
- tracks,
80
- defaultDesktopQuality,
81
- tokens,
82
- variant = {},
83
- ...rest
84
- } = props
85
88
 
86
89
  const { borderColor, pauseIcon, playIcon, replayIcon } = useThemeTokens('Video', tokens, variant)
87
90
 
@@ -92,7 +95,7 @@ const Video = (props) => {
92
95
  compactModeThreshold: 700 // in px
93
96
  }
94
97
 
95
- const [videoPlayerState, setVideoPlayerState] = useState({
98
+ const [videoPlayerState, setVideoPlayerState] = React.useState({
96
99
  loadedSources: null,
97
100
  loadedTracks: null,
98
101
  videoLength: 0,
@@ -145,7 +148,6 @@ const Video = (props) => {
145
148
  }
146
149
 
147
150
  const refreshMedia = () => {
148
- const { defaultMobileQuality } = props
149
151
  const { videoUnplayed } = videoPlayerState
150
152
 
151
153
  // Handle mobile check
@@ -213,7 +215,6 @@ const Video = (props) => {
213
215
  // required for analytics
214
216
  const calculatePercentageWatched = () => {
215
217
  const { videoCurrentTime, videoLength, percentageWatched } = videoPlayerState
216
- const { videoTitle, analyticsTracking } = props
217
218
 
218
219
  let percentValue = (videoCurrentTime / videoLength) * 100
219
220
  percentValue = Math.round(percentValue)
@@ -230,7 +231,6 @@ const Video = (props) => {
230
231
 
231
232
  const setPlaying = async (isPlaying) => {
232
233
  const videoPlayer = refVideoPlayer.current
233
- const { analyticsTracking, videoTitle } = props
234
234
 
235
235
  if (isPlaying) {
236
236
  await videoPlayer.play()
@@ -248,7 +248,6 @@ const Video = (props) => {
248
248
  }
249
249
 
250
250
  const updateAnalyticsData = () => {
251
- const { videoTitle, analyticsTracking } = props
252
251
  const { videoIsPlaying, percentageWatched } = videoPlayerState
253
252
 
254
253
  const analyticsObject = { name: 'video tracking', details: videoTitle }
@@ -357,8 +356,6 @@ const Video = (props) => {
357
356
  videoQualityChanged: false
358
357
  }))
359
358
 
360
- const { analyticsTracking } = props
361
-
362
359
  if (analyticsTracking) {
363
360
  updateAnalyticsData()
364
361
  }
@@ -370,8 +367,6 @@ const Video = (props) => {
370
367
  clearInactivityTimer()
371
368
  setVideoPlayerState((prevState) => ({ ...prevState, videoIsPlaying: false }))
372
369
 
373
- const { analyticsTracking } = props
374
-
375
370
  if (analyticsTracking) {
376
371
  updateAnalyticsData()
377
372
  }
@@ -655,18 +650,16 @@ const Video = (props) => {
655
650
  }
656
651
 
657
652
  // Prepares video and caption files
658
- useEffect(() => {
653
+ React.useEffect(() => {
659
654
  refreshMedia()
660
655
  // eslint-disable-next-line react-hooks/exhaustive-deps
661
656
  }, [])
662
657
 
663
658
  // Initial Setup after loading sources
664
- useEffect(() => {
659
+ React.useEffect(() => {
665
660
  const { loadedSources, loadedTracks } = videoPlayerState
666
661
 
667
662
  if (loadedSources && loadedTracks) {
668
- const { beginMuted, analyticsTracking, videoTitle } = props
669
-
670
663
  const videoPlayer = refVideoPlayer.current
671
664
 
672
665
  // Initializes Settings
@@ -979,17 +972,4 @@ Video.propTypes = {
979
972
  variant: variantProp.propType
980
973
  }
981
974
 
982
- Video.defaultProps = {
983
- tracks: undefined,
984
- defaultVolume: 100,
985
- beginMuted: false,
986
- defaultMobileQuality: 1,
987
- defaultDesktopQuality: 1,
988
- crossOrigin: undefined,
989
- simpleMode: false,
990
- videoBorder: false,
991
- analyticsTracking: undefined,
992
- videoTitle: undefined
993
- }
994
-
995
975
  export default Video
@@ -1,4 +1,4 @@
1
- import React, { useState, useEffect, useRef } from 'react'
1
+ import React from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
  import { viewports } from '@telus-uds/system-constants'
4
4
  import {
@@ -66,79 +66,100 @@ const VideoListContainer = styled.div`
66
66
  ${(props) => props.isFramed && framedVideoListContainerStyle}
67
67
  `
68
68
 
69
- const VideoPicker = ({
70
- videoList = [],
71
- selectedVideo = videoList[0]?.videoId,
72
- frame,
73
- onStartVideo = () => {},
74
- onSelectVideo = () => {},
75
- ...rest
76
- }) => {
77
- const viewport = useViewport()
78
- const { stackViewDividerColor, ...themeTokens } = useThemeTokens('VideoPicker')
79
- const [currentVideoId, setCurrentVideoId] = useState(selectedVideo)
80
- const videoPlayerRef = useRef(null)
81
-
82
- const currentVideo = videoList.find((video) => video.videoId === currentVideoId)
83
- useEffect(() => {
84
- // Update current video if parent changes which video id it passes down
85
- setCurrentVideoId(selectedVideo)
86
- }, [selectedVideo])
87
-
88
- // `frame` variant should only work on larger screens
89
- const isFramed = frame && [viewports.lg, viewports.xl].includes(viewport)
90
-
91
- const hasSlider = !frame && [viewports.md, viewports.lg, viewports.xl].includes(viewport)
92
-
93
- const listElements = videoList.map((video, index) => (
94
- <VideoPickerThumbnail
95
- key={video.videoId}
96
- video={video}
97
- videoPlayerRef={videoPlayerRef}
98
- selectedVideoId={currentVideoId}
99
- onSelectVideo={(current) => {
100
- setCurrentVideoId(current.videoId)
101
- onSelectVideo(current)
102
- }}
103
- layout={!hasSlider ? 'horizontal' : 'vertical'}
104
- index={index}
105
- isFramed={isFramed}
106
- />
107
- ))
108
-
109
- return (
110
- <VideoPickerContainer isFramed={isFramed} {...selectProps(rest)} {...themeTokens}>
111
- <StackView
112
- divider={
113
- isFramed
114
- ? { tokens: { color: stackViewDividerColor } }
115
- : { variant: { decorative: true } }
116
- }
117
- space={isFramed ? 0 : 4} // everything has internal padding in `frame` variant
118
- direction={isFramed ? 'row' : 'column'}
119
- >
120
- <VideoPlayerContainer {...themeTokens} isFramed={isFramed}>
121
- <VideoPickerPlayer
122
- video={currentVideo}
123
- videoPlayerRef={videoPlayerRef}
124
- onStartVideo={onStartVideo}
125
- />
126
- </VideoPlayerContainer>
127
- {hasSlider ? (
128
- <VideoSlider>{listElements}</VideoSlider>
129
- ) : (
130
- <VideoListContainer
131
- viewport={viewport}
132
- data-testid="video-list-container"
133
- isFramed={isFramed}
134
- >
135
- {listElements}
136
- </VideoListContainer>
137
- )}
138
- </StackView>
139
- </VideoPickerContainer>
140
- )
141
- }
69
+ const VideoPicker = React.forwardRef(
70
+ (
71
+ {
72
+ videoList = [],
73
+ selectedVideo = videoList[0]?.videoId,
74
+ frame,
75
+ onStartVideo = () => {},
76
+ onSelectVideo = () => {},
77
+ onPlay = () => {},
78
+ onPause = () => {},
79
+ onProgress = () => {},
80
+ ...rest
81
+ },
82
+ ref
83
+ ) => {
84
+ const viewport = useViewport()
85
+ const { stackViewDividerColor, ...themeTokens } = useThemeTokens('VideoPicker')
86
+ const [currentVideoId, setCurrentVideoId] = React.useState(selectedVideo)
87
+ const videoPlayerRef = React.useRef(null)
88
+
89
+ const currentVideo = videoList.find((video) => video.videoId === currentVideoId)
90
+
91
+ React.useEffect(() => {
92
+ // Update current video if parent changes which video id it passes down
93
+ setCurrentVideoId(selectedVideo)
94
+ }, [selectedVideo])
95
+
96
+ const addVideoEventHandlers = (video) => {
97
+ if (!video) return {}
98
+ return {
99
+ ...video,
100
+ onPlay: video.onPlay || onPlay,
101
+ onPause: video.onPause || onPause,
102
+ onProgress: video.onProgress || onProgress
103
+ }
104
+ }
105
+
106
+ // `frame` variant should only work on larger screens
107
+ const isFramed = frame && [viewports.lg, viewports.xl].includes(viewport)
108
+
109
+ const hasSlider = !frame && [viewports.md, viewports.lg, viewports.xl].includes(viewport)
110
+
111
+ const listElements = videoList.map((video, index) => (
112
+ <VideoPickerThumbnail
113
+ key={video.videoId}
114
+ video={video}
115
+ videoPlayerRef={videoPlayerRef}
116
+ selectedVideoId={currentVideoId}
117
+ onSelectVideo={(current) => {
118
+ setCurrentVideoId(current.videoId)
119
+ onSelectVideo(current)
120
+ }}
121
+ layout={!hasSlider ? 'horizontal' : 'vertical'}
122
+ index={index}
123
+ isFramed={isFramed}
124
+ />
125
+ ))
126
+
127
+ return (
128
+ <VideoPickerContainer ref={ref} isFramed={isFramed} {...selectProps(rest)} {...themeTokens}>
129
+ <StackView
130
+ divider={
131
+ isFramed
132
+ ? { tokens: { color: stackViewDividerColor } }
133
+ : { variant: { decorative: true } }
134
+ }
135
+ space={isFramed ? 0 : 4} // everything has internal padding in `frame` variant
136
+ direction={isFramed ? 'row' : 'column'}
137
+ >
138
+ <VideoPlayerContainer {...themeTokens} isFramed={isFramed}>
139
+ <VideoPickerPlayer
140
+ video={addVideoEventHandlers(currentVideo, onPlay, onPause, onProgress)}
141
+ videoPlayerRef={videoPlayerRef}
142
+ onStartVideo={onStartVideo}
143
+ />
144
+ </VideoPlayerContainer>
145
+ {hasSlider ? (
146
+ <VideoSlider>{listElements}</VideoSlider>
147
+ ) : (
148
+ <VideoListContainer
149
+ viewport={viewport}
150
+ data-testid="video-list-container"
151
+ isFramed={isFramed}
152
+ >
153
+ {listElements}
154
+ </VideoListContainer>
155
+ )}
156
+ </StackView>
157
+ </VideoPickerContainer>
158
+ )
159
+ }
160
+ )
161
+
162
+ VideoPicker.displayName = 'VideoPicker'
142
163
 
143
164
  VideoPicker.propTypes = {
144
165
  ...selectedSystemPropTypes,
@@ -164,7 +185,25 @@ VideoPicker.propTypes = {
164
185
  * Callback function trigerred when a video is selected from the thumbnail list.
165
186
  * @param {object} video - The video object that is selected.
166
187
  */
167
- onSelectVideo: PropTypes.func
188
+ onSelectVideo: PropTypes.func,
189
+
190
+ /**
191
+ * Callback function trigerred during progress milestones 10% 25% 50% 75% 100%.
192
+ * @param {object} event - The event object.
193
+ */
194
+ onProgress: PropTypes.func,
195
+
196
+ /**
197
+ * Callback function trigerred when the video player starts playing video.
198
+ * @param {object} event - The event object.
199
+ */
200
+ onPlay: PropTypes.func,
201
+
202
+ /**
203
+ * Callback function trigerred when the video gets paused.
204
+ * @param {object} event - The event object.
205
+ */
206
+ onPause: PropTypes.func
168
207
  }
169
208
 
170
209
  export default VideoPicker
@@ -4,18 +4,22 @@ import PropTypes from 'prop-types'
4
4
  import WebVideo from '../WebVideo/WebVideo'
5
5
  import { VideoPropType, RefPropType } from './videoPropType'
6
6
 
7
- const VideoPickerPlayer = ({ video = {}, videoPlayerRef, onStartVideo = () => {} }) => (
8
- <StackView space={3} tokens={{ flexShrink: 1 }}>
9
- <div ref={videoPlayerRef}>
10
- {video.videoId && <WebVideo {...video} onStart={() => onStartVideo(video)} />}
11
- </div>
12
- <StackView space={2}>
13
- <Typography variant={{ size: 'h3' }}>{video.title}</Typography>
14
- <Typography variant={{ colour: 'default' }}>{video.description}</Typography>
7
+ const VideoPickerPlayer = React.forwardRef(
8
+ ({ video = {}, videoPlayerRef, onStartVideo = () => {} }, ref) => (
9
+ <StackView space={3} tokens={{ flexShrink: 1 }} ref={ref}>
10
+ <div ref={videoPlayerRef}>
11
+ {video.videoId && <WebVideo {...video} onStart={() => onStartVideo(video)} />}
12
+ </div>
13
+ <StackView space={2}>
14
+ <Typography variant={{ size: 'h3' }}>{video.title}</Typography>
15
+ <Typography variant={{ colour: 'default' }}>{video.description}</Typography>
16
+ </StackView>
15
17
  </StackView>
16
- </StackView>
18
+ )
17
19
  )
18
20
 
21
+ VideoPickerPlayer.displayName = 'VideoPickerPlayer'
22
+
19
23
  VideoPickerPlayer.propTypes = {
20
24
  video: VideoPropType,
21
25
  videoPlayerRef: RefPropType,