@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
@@ -1,4 +1,4 @@
1
- import React, { forwardRef } from 'react'
1
+ import React from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
  import {
4
4
  IconButton as IconButtonBase,
@@ -6,23 +6,25 @@ import {
6
6
  getTokensPropType
7
7
  } from '@telus-uds/components-base'
8
8
 
9
- const IconButton = forwardRef(({ icon, action, tokens, variant = {}, ...iconButtonProps }, ref) => {
10
- const variantWithAction = action && !variant.action ? { ...variant, action } : variant
11
- const { icon: themeIcon } = useThemeTokens('IconButton', tokens, variantWithAction)
9
+ const IconButton = React.forwardRef(
10
+ ({ icon = null, action, tokens = {}, variant = {}, ...iconButtonProps }, ref) => {
11
+ const variantWithAction = action && !variant.action ? { ...variant, action } : variant
12
+ const { icon: themeIcon } = useThemeTokens('IconButton', tokens, variantWithAction)
12
13
 
13
- return (
14
- // If we want the arrow icons to have directional animation instead of scale, we can pass
15
- // either appropriate iconTransateX/Y here, or define and pass variants like { direction: 'left' }
16
- // which have theme rules that set `iconTranslateX` tokens in the theme rules and unset `iconScale`.
17
- <IconButtonBase
18
- ref={ref}
19
- {...iconButtonProps}
20
- tokens={tokens}
21
- variant={variant}
22
- icon={icon ?? themeIcon}
23
- />
24
- )
25
- })
14
+ return (
15
+ // If we want the arrow icons to have directional animation instead of scale, we can pass
16
+ // either appropriate iconTransateX/Y here, or define and pass variants like { direction: 'left' }
17
+ // which have theme rules that set `iconTranslateX` tokens in the theme rules and unset `iconScale`.
18
+ <IconButtonBase
19
+ ref={ref}
20
+ {...iconButtonProps}
21
+ tokens={tokens}
22
+ variant={variant}
23
+ icon={icon ?? themeIcon}
24
+ />
25
+ )
26
+ }
27
+ )
26
28
 
27
29
  const multiBrandIconNames = [
28
30
  'add',
@@ -44,7 +46,6 @@ IconButton.propTypes = {
44
46
  /**
45
47
  * To set the icon to a multi-brand compatabile icon
46
48
  */
47
- // eslint-disable-next-line react/require-default-props
48
49
  action: PropTypes.oneOf(multiBrandIconNames),
49
50
  /**
50
51
  * To set a custom icon
@@ -52,6 +53,4 @@ IconButton.propTypes = {
52
53
  icon: PropTypes.func
53
54
  }
54
55
 
55
- IconButton.defaultProps = { icon: null, tokens: {} }
56
-
57
56
  export default IconButton
@@ -5,53 +5,50 @@ import { warn } from '../utils/logger'
5
5
 
6
6
  const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs])
7
7
 
8
- const Image = ({
9
- src,
10
- width,
11
- height,
12
- alt,
13
- rounded,
14
- loading = 'eager',
15
- tokens,
16
- theme,
17
- variant,
18
- ...rest
19
- }) => {
20
- let { borderRadius } = theme
21
- const isCircle = rounded === 'circle'
22
- const isCorners = rounded === 'corners'
23
- const isSquare = width === height
8
+ const Image = React.forwardRef(
9
+ (
10
+ { src, width, height, alt, rounded, loading = 'eager', tokens, theme, variant, ...rest },
11
+ ref
12
+ ) => {
13
+ let { borderRadius } = theme
14
+ const isCircle = rounded === 'circle'
15
+ const isCorners = rounded === 'corners'
16
+ const isSquare = width === height
24
17
 
25
- if (isCircle && !isSquare) {
26
- warn(
27
- 'Image',
28
- 'rounded="circle" is not supported for non-square images. Please provide a square image, otherwise the resulting shape will not be a circle.'
29
- )
30
- }
18
+ if (isCircle && !isSquare) {
19
+ warn(
20
+ 'Image',
21
+ 'rounded="circle" is not supported for non-square images. Please provide a square image, otherwise the resulting shape will not be a circle.'
22
+ )
23
+ }
31
24
 
32
- if (isCircle) {
33
- borderRadius = '50%'
34
- } else if (isCorners) {
35
- borderRadius = '4px'
36
- }
25
+ if (isCircle) {
26
+ borderRadius = '50%'
27
+ } else if (isCorners) {
28
+ borderRadius = '4px'
29
+ }
37
30
 
38
- const style = {
39
- borderRadius,
40
- height: height ?? 'auto',
41
- maxWidth: '100%'
31
+ const style = {
32
+ borderRadius,
33
+ height: height ?? 'auto',
34
+ maxWidth: '100%'
35
+ }
36
+ return (
37
+ <img
38
+ {...selectProps(rest)}
39
+ style={style}
40
+ src={src}
41
+ width={width}
42
+ height={height}
43
+ alt={alt}
44
+ loading={loading}
45
+ ref={ref}
46
+ />
47
+ )
42
48
  }
43
- return (
44
- <img
45
- {...selectProps(rest)}
46
- style={style}
47
- src={src}
48
- width={width}
49
- height={height}
50
- alt={alt}
51
- loading={loading}
52
- />
53
- )
54
- }
49
+ )
50
+
51
+ Image.displayName = 'Image'
55
52
 
56
53
  Image.propTypes = {
57
54
  ...selectedSystemPropTypes,
@@ -1,21 +1,19 @@
1
- import React, { forwardRef } from 'react'
1
+ import React from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
  import { ListItem as ListItemBase, Typography } from '@telus-uds/components-base'
4
4
 
5
- const ListItem = forwardRef(({ children, title, ...rest }, ref) => (
5
+ const ListItem = React.forwardRef(({ children, title, ...rest }, ref) => (
6
6
  <ListItemBase ref={ref} {...rest}>
7
7
  {Boolean(title) && <Typography variant={{ size: 'h4' }}>{title}</Typography>}
8
8
  {children}
9
9
  </ListItemBase>
10
10
  ))
11
+
11
12
  ListItem.displayName = 'ListItem'
12
13
 
13
14
  ListItem.propTypes = {
14
15
  children: PropTypes.node.isRequired,
15
16
  title: PropTypes.string
16
17
  }
17
- ListItem.defaultProps = {
18
- title: undefined
19
- }
20
18
 
21
19
  export default ListItem
@@ -1,12 +1,11 @@
1
- import React, { forwardRef, useEffect, useRef, useState, useCallback } from 'react'
1
+ import React from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
  import {
4
4
  selectSystemProps,
5
5
  StackView,
6
6
  Typography,
7
7
  useResponsiveProp,
8
- withLinkRouter,
9
- getTokensPropType
8
+ withLinkRouter
10
9
  } from '@telus-uds/components-base'
11
10
  import styled from 'styled-components'
12
11
  import { htmlAttrs } from '../utils'
@@ -28,7 +27,7 @@ const Heading = styled.div({
28
27
  * NavigationBar can be used to allow customers to consistently navigate across
29
28
  * key pages within a specific product line
30
29
  */
31
- const NavigationBar = forwardRef(
30
+ const NavigationBar = React.forwardRef(
32
31
  (
33
32
  {
34
33
  accessibilityRole = 'navigation',
@@ -45,8 +44,8 @@ const NavigationBar = forwardRef(
45
44
  ) => {
46
45
  const direction = useResponsiveProp({ xs: 'column', sm: 'row' })
47
46
  const itemsForViewport = useResponsiveProp({ xs: collapseItems(items, selectedId), lg: items })
48
- const openOverlayRef = useRef(null)
49
- const [openSubMenuId, setOpenSubMenuId] = useState(null)
47
+ const openOverlayRef = React.useRef(null)
48
+ const [openSubMenuId, setOpenSubMenuId] = React.useState(null)
50
49
  const handleSubMenuClose = (event) => {
51
50
  if (event.type === 'keydown') {
52
51
  if (event.key === 'Escape' || event.key === 27) {
@@ -69,12 +68,12 @@ const NavigationBar = forwardRef(
69
68
  }
70
69
  }
71
70
 
72
- const navRefDefault = useRef(null)
71
+ const navRefDefault = React.useRef(null)
73
72
  const navRef = ref ?? navRefDefault
74
- const itemsRef = useRef(null)
73
+ const itemsRef = React.useRef(null)
75
74
 
76
75
  // Close the submenu when the user clicks outside the navigation bar
77
- const handleMouseDown = useCallback(
76
+ const handleMouseDown = React.useCallback(
78
77
  (event) => {
79
78
  if (navRef.current && itemsRef.current) {
80
79
  // Get the bounding rectangles of the navigation bar and the items container
@@ -103,7 +102,7 @@ const NavigationBar = forwardRef(
103
102
  )
104
103
 
105
104
  // TODO: create a custom hook for that and use here and in the Footnote
106
- useEffect(() => {
105
+ React.useEffect(() => {
107
106
  // Add listeners for mouse clicks outside and for key presses
108
107
  document.addEventListener('mousedown', handleMouseDown)
109
108
 
@@ -202,7 +201,6 @@ NavigationBar.displayName = 'NavigationBar'
202
201
 
203
202
  NavigationBar.propTypes = {
204
203
  ...selectedSystemPropTypes,
205
- tokens: getTokensPropType('NavigationBar'),
206
204
  ...withLinkRouter.propTypes,
207
205
  /**
208
206
  * NavigationBar pages
@@ -256,12 +254,5 @@ NavigationBar.propTypes = {
256
254
  */
257
255
  accessibilityRole: PropTypes.string
258
256
  }
259
- NavigationBar.defaultProps = {
260
- heading: undefined,
261
- headingLevel: 'h1',
262
- onChange: () => {},
263
- accessibilityRole: '',
264
- tokens: {}
265
- }
266
257
 
267
258
  export default NavigationBar
@@ -1,11 +1,12 @@
1
- import React, { forwardRef } from 'react'
1
+ import React from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
  import {
4
4
  Button,
5
5
  selectSystemProps,
6
6
  useResponsiveProp,
7
7
  useViewport,
8
- useThemeTokensCallback
8
+ useThemeTokensCallback,
9
+ getTokensPropType
9
10
  } from '@telus-uds/components-base'
10
11
  import styled from 'styled-components'
11
12
  import { htmlAttrs } from '../utils'
@@ -28,14 +29,14 @@ const ItemContainer = styled.div(({ targetWidth }) => ({
28
29
  *
29
30
  * This is rendered automatically by `NavigationBar` and isn't intended be used directly.
30
31
  */
31
- const NavigationItem = forwardRef(
32
+ const NavigationItem = React.forwardRef(
32
33
  (
33
34
  {
34
35
  accessibilityRole = 'link', // @todo switch to 'button' for dropdowns
35
36
  children,
36
37
  id,
37
38
  onClick: handleClick = () => {},
38
- selected,
39
+ selected = false,
39
40
  accessibilityState = { current: selected ? 'page' : false },
40
41
  href,
41
42
  tokens,
@@ -76,10 +77,10 @@ NavigationItem.displayName = 'NavigationItem'
76
77
 
77
78
  NavigationItem.propTypes = {
78
79
  ...selectedSystemPropTypes,
80
+ tokens: getTokensPropType('NavigationBar'),
79
81
  onClick: PropTypes.func,
80
82
  selected: PropTypes.bool,
81
83
  children: PropTypes.oneOfType([PropTypes.string, PropTypes.func]).isRequired
82
84
  }
83
- NavigationItem.defaultProps = { onClick: () => {}, selected: false }
84
85
 
85
86
  export default NavigationItem
@@ -1,6 +1,12 @@
1
- import React, { useRef } from 'react'
1
+ import React from 'react'
2
2
  import PropTypes from 'prop-types'
3
- import { Icon, useResponsiveProp, useThemeTokens, Listbox } from '@telus-uds/components-base'
3
+ import {
4
+ Icon,
5
+ useResponsiveProp,
6
+ useThemeTokens,
7
+ Listbox,
8
+ getTokensPropType
9
+ } from '@telus-uds/components-base'
4
10
  import NavigationItem from './NavigationItem'
5
11
  import useOverlaidPosition from '../utils/useOverlaidPosition'
6
12
  import resolveItemSelection from './resolveItemSelection'
@@ -10,103 +16,113 @@ import resolveItemSelection from './resolveItemSelection'
10
16
  *
11
17
  * This is rendered automatically by `NavigationBar` and isn't intended be used directly.
12
18
  */
13
- const NavigationSubMenu = ({
14
- children,
15
- id,
16
- isOpen = false,
17
- label,
18
- onClick,
19
- selectedId,
20
- items = [],
21
- openOverlayRef,
22
- LinkRouter,
23
- linkRouterProps,
24
- itemsContainerRef
25
- }) => {
26
- const focusTrapRef = useRef()
19
+ const NavigationSubMenu = React.forwardRef(
20
+ (
21
+ {
22
+ children,
23
+ id,
24
+ isOpen = false,
25
+ tokens = {},
26
+ label,
27
+ onClick,
28
+ selectedId,
29
+ items = [],
30
+ openOverlayRef,
31
+ LinkRouter,
32
+ linkRouterProps,
33
+ itemsContainerRef
34
+ },
35
+ ref
36
+ ) => {
37
+ const focusTrapRef = React.useRef()
27
38
 
28
- const maxWidth = 289 // Slightly over 288 of nav item to account for subpixel rounding
29
- const defaultOffsets = { offsets: { vertical: 4 } }
30
- const { align, offsets, minWidth } = useResponsiveProp({
31
- xs: { ...defaultOffsets, align: { top: 'bottom', left: 'left' }, minWidth: maxWidth },
32
- sm: { ...defaultOffsets, align: { top: 'bottom', right: 'right' }, minWidth: maxWidth },
33
- lg: {
34
- ...defaultOffsets,
35
- align: { top: 'bottom', center: 'center' },
36
- minWidth: 192
37
- }
38
- })
39
+ const maxWidth = 289 // Slightly over 288 of nav item to account for subpixel rounding
40
+ const defaultOffsets = { offsets: { vertical: 4 } }
41
+ const { align, offsets, minWidth } = useResponsiveProp({
42
+ xs: { ...defaultOffsets, align: { top: 'bottom', left: 'left' }, minWidth: maxWidth },
43
+ sm: { ...defaultOffsets, align: { top: 'bottom', right: 'right' }, minWidth: maxWidth },
44
+ lg: {
45
+ ...defaultOffsets,
46
+ align: { top: 'bottom', center: 'center' },
47
+ minWidth: 192
48
+ }
49
+ })
39
50
 
40
- const { overlaidPosition, sourceRef, targetRef, onTargetLayout, isReady } = useOverlaidPosition({
41
- isShown: isOpen,
42
- offsets,
43
- align
44
- })
45
- const { selected } = resolveItemSelection({ id, label, items }, selectedId)
51
+ const { overlaidPosition, sourceRef, targetRef, onTargetLayout, isReady } = useOverlaidPosition(
52
+ {
53
+ isShown: isOpen,
54
+ offsets,
55
+ align
56
+ }
57
+ )
58
+ const { selected } = resolveItemSelection({ id, label, items }, selectedId)
46
59
 
47
- const handleClick = (event) => {
48
- if (typeof onClick === 'function') onClick(event)
49
- }
60
+ const handleClick = (event) => {
61
+ if (typeof onClick === 'function') onClick(event)
62
+ }
50
63
 
51
- const { icoMenu } = useThemeTokens('NavigationBar', {}, {}, { expanded: isOpen })
64
+ const { icoMenu } = useThemeTokens('NavigationBar', {}, {}, { expanded: isOpen })
52
65
 
53
- return (
54
- <>
55
- <NavigationItem
56
- ref={sourceRef}
57
- accessibilityRole="button"
58
- id={id}
59
- selected={selected}
60
- onClick={handleClick}
61
- icon={icoMenu}
62
- >
63
- {({ textStyles }) => [
64
- children,
65
- <Icon
66
- key={`${id}_icon`}
67
- icon={icoMenu}
68
- variant={{ size: 'micro' }}
69
- tokens={{ color: textStyles[0]?.color }}
70
- />
71
- ]}
72
- </NavigationItem>
73
- {isOpen && (
74
- <>
75
- <Listbox.Overlay
76
- overlaidPosition={overlaidPosition}
77
- maxWidth={maxWidth}
78
- minWidth={minWidth}
79
- isReady={isReady}
80
- onLayout={onTargetLayout}
81
- ref={openOverlayRef}
82
- >
83
- <Listbox
84
- items={items}
85
- firstItemRef={targetRef}
86
- parentRef={sourceRef}
87
- selectedId={selectedId}
88
- LinkRouter={LinkRouter}
89
- linkRouterProps={linkRouterProps}
90
- ref={itemsContainerRef}
66
+ return (
67
+ <>
68
+ <NavigationItem
69
+ ref={sourceRef}
70
+ accessibilityRole="button"
71
+ id={id}
72
+ selected={selected}
73
+ onClick={handleClick}
74
+ icon={icoMenu}
75
+ tokens={tokens}
76
+ >
77
+ {({ textStyles }) => [
78
+ children,
79
+ <Icon
80
+ key={`${id}_icon`}
81
+ icon={icoMenu}
82
+ variant={{ size: 'micro' }}
83
+ tokens={{ color: textStyles[0]?.color }}
91
84
  />
92
- </Listbox.Overlay>
93
- <div
94
- // This catches and shifts focus to other interactive elements.
95
- // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
96
- tabIndex={0}
97
- ref={focusTrapRef}
98
- onFocus={() => targetRef.current.focus()}
99
- />
100
- </>
101
- )}
102
- </>
103
- )
104
- }
85
+ ]}
86
+ </NavigationItem>
87
+ {isOpen && (
88
+ <>
89
+ <Listbox.Overlay
90
+ overlaidPosition={overlaidPosition}
91
+ maxWidth={maxWidth}
92
+ minWidth={minWidth}
93
+ isReady={isReady}
94
+ onLayout={onTargetLayout}
95
+ ref={openOverlayRef}
96
+ >
97
+ <Listbox
98
+ items={items}
99
+ firstItemRef={targetRef}
100
+ parentRef={sourceRef}
101
+ selectedId={selectedId}
102
+ LinkRouter={LinkRouter}
103
+ linkRouterProps={linkRouterProps}
104
+ ref={itemsContainerRef || ref}
105
+ />
106
+ </Listbox.Overlay>
107
+ <div
108
+ // This catches and shifts focus to other interactive elements.
109
+ // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
110
+ tabIndex={0}
111
+ ref={focusTrapRef}
112
+ onFocus={() => targetRef.current.focus()}
113
+ />
114
+ </>
115
+ )}
116
+ </>
117
+ )
118
+ }
119
+ )
105
120
 
106
121
  NavigationSubMenu.displayName = 'NavigationSubMenu'
107
122
 
108
123
  // @TODO - proper prop types and comments
109
124
  NavigationSubMenu.propTypes = {
125
+ tokens: getTokensPropType('NavigationBar'),
110
126
  children: PropTypes.node,
111
127
  id: PropTypes.string,
112
128
  isOpen: PropTypes.bool,
@@ -1,3 +1,6 @@
1
1
  import NavigationBar from './NavigationBar'
2
+ import NavigationItem from './NavigationItem'
3
+
4
+ NavigationBar.Item = NavigationItem
2
5
 
3
6
  export default NavigationBar
@@ -1,4 +1,4 @@
1
- import React, { useEffect, useState } from 'react'
1
+ import React from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
  import { selectSystemProps } from '@telus-uds/components-base'
4
4
  import ResponsiveImage from '../ResponsiveImage'
@@ -7,48 +7,55 @@ import { htmlAttrs } from '../utils'
7
7
 
8
8
  const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs])
9
9
 
10
- const OptimizeImage = ({
11
- contentfulAssetUrl,
12
- alt,
13
- quality = 80,
14
- xs = 320,
15
- sm = 576,
16
- md = 768,
17
- lg = 992,
18
- xl = 1200,
19
- sizeByHeight = false,
20
- disableRetina = false,
21
- ...rest
22
- }) => {
23
- // `useHeight` is a deprecated TDS prop, replaced by `sizeByHeight`
24
- const dimension = sizeByHeight || rest.useHeight ? 'h' : 'w'
25
- // by default assuming webP support for SSR
26
- const [imgUrls, setImgUrls] = useState(
27
- getImageUrls(contentfulAssetUrl, dimension, xs, sm, md, lg, xl, quality, disableRetina, true)
28
- )
10
+ const OptimizeImage = React.forwardRef(
11
+ (
12
+ {
13
+ contentfulAssetUrl,
14
+ alt,
15
+ quality = 80,
16
+ xs = 320,
17
+ sm = 576,
18
+ md = 768,
19
+ lg = 992,
20
+ xl = 1200,
21
+ sizeByHeight = false,
22
+ disableRetina = false,
23
+ ...rest
24
+ },
25
+ ref
26
+ ) => {
27
+ // `useHeight` is a deprecated TDS prop, replaced by `sizeByHeight`
28
+ const dimension = sizeByHeight || rest.useHeight ? 'h' : 'w'
29
+ // by default assuming webP support for SSR
30
+ const [imgUrls, setImgUrls] = React.useState(
31
+ getImageUrls(contentfulAssetUrl, dimension, xs, sm, md, lg, xl, quality, disableRetina, true)
32
+ )
29
33
 
30
- useEffect(() => {
31
- // Checking for webP support for CSR
32
- hasWebpSupport().then((supportsWebp) => {
33
- const imageUrls = getImageUrls(
34
- contentfulAssetUrl,
35
- dimension,
36
- xs,
37
- sm,
38
- md,
39
- lg,
40
- xl,
41
- quality,
42
- disableRetina,
43
- supportsWebp
44
- )
45
- setImgUrls(imageUrls)
46
- })
47
- }, [contentfulAssetUrl, dimension, disableRetina, lg, md, quality, sm, xl, xs])
34
+ React.useEffect(() => {
35
+ // Checking for webP support for CSR
36
+ hasWebpSupport().then((supportsWebp) => {
37
+ const imageUrls = getImageUrls(
38
+ contentfulAssetUrl,
39
+ dimension,
40
+ xs,
41
+ sm,
42
+ md,
43
+ lg,
44
+ xl,
45
+ quality,
46
+ disableRetina,
47
+ supportsWebp
48
+ )
49
+ setImgUrls(imageUrls)
50
+ })
51
+ }, [contentfulAssetUrl, dimension, disableRetina, lg, md, quality, sm, xl, xs])
48
52
 
49
- if (!imgUrls) return null
50
- return <ResponsiveImage {...imgUrls} alt={alt} {...selectProps(rest)} />
51
- }
53
+ if (!imgUrls) return null
54
+ return <ResponsiveImage {...imgUrls} alt={alt} {...selectProps(rest)} ref={ref} />
55
+ }
56
+ )
57
+
58
+ OptimizeImage.displayName = 'OptimizeImage'
52
59
 
53
60
  OptimizeImage.propTypes = {
54
61
  ...selectedSystemPropTypes,