@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 styled from 'styled-components'
4
4
  import {
@@ -67,38 +67,41 @@ const ItemContent = styled.div({
67
67
  flex: 1
68
68
  })
69
69
 
70
- const Item = forwardRef(({ children, counterName, title, tokens, variant, ...rest }, ref) => {
71
- // We are reusing some tokens from the list component here in order to provide a unified
72
- // experience
73
- const themeTokens = useThemeTokens('OrderedList', tokens, variant)
74
- const headingTokens = title && {
75
- lineHeight: themeTokens.itemLineHeight,
76
- fontSize: themeTokens.itemFontSize,
77
- color: themeTokens.itemColor,
78
- fontName: themeTokens.headerFontName,
79
- fontWeight: themeTokens.headerFontWeight
80
- }
70
+ const Item = React.forwardRef(
71
+ ({ children, counterName, title, tokens = {}, variant, ...rest }, ref) => {
72
+ // We are reusing some tokens from the list component here in order to provide a unified
73
+ // experience
74
+ const themeTokens = useThemeTokens('OrderedList', tokens, variant)
75
+ const headingTokens = title && {
76
+ lineHeight: themeTokens.itemLineHeight,
77
+ fontSize: themeTokens.itemFontSize,
78
+ color: themeTokens.itemColor,
79
+ fontName: themeTokens.headerFontName,
80
+ fontWeight: themeTokens.headerFontWeight
81
+ }
81
82
 
82
- const { themeOptions } = useTheme()
83
- const itemContent = wrapStringsInText(children, {
84
- style: selectItemTextStyles(themeTokens, themeOptions)
85
- })
83
+ const { themeOptions } = useTheme()
84
+ const itemContent = wrapStringsInText(children, {
85
+ style: selectItemTextStyles(themeTokens, themeOptions)
86
+ })
87
+
88
+ return (
89
+ <StyledItemBase ref={ref} themeOptions={themeOptions} {...themeTokens} {...selectProps(rest)}>
90
+ {title ? (
91
+ <StackView tokens={{ flexShrink: 1 }} space={0}>
92
+ <Typography variant={{ size: 'h4' }} tokens={headingTokens}>
93
+ {title}
94
+ </Typography>
95
+ <ItemContent {...themeTokens}>{itemContent}</ItemContent>
96
+ </StackView>
97
+ ) : (
98
+ itemContent
99
+ )}
100
+ </StyledItemBase>
101
+ )
102
+ }
103
+ )
86
104
 
87
- return (
88
- <StyledItemBase ref={ref} themeOptions={themeOptions} {...themeTokens} {...selectProps(rest)}>
89
- {title ? (
90
- <StackView tokens={{ flexShrink: 1 }} space={0}>
91
- <Typography variant={{ size: 'h4' }} tokens={headingTokens}>
92
- {title}
93
- </Typography>
94
- <ItemContent {...themeTokens}>{itemContent}</ItemContent>
95
- </StackView>
96
- ) : (
97
- itemContent
98
- )}
99
- </StyledItemBase>
100
- )
101
- })
102
105
  Item.displayName = 'OrderedListItem'
103
106
 
104
107
  Item.propTypes = {
@@ -116,9 +119,5 @@ Item.propTypes = {
116
119
  */
117
120
  tokens: getTokensPropType('List')
118
121
  }
119
- Item.defaultProps = {
120
- title: undefined,
121
- tokens: {}
122
- }
123
122
 
124
123
  export default Item
@@ -1,7 +1,7 @@
1
- import React, { forwardRef, useMemo } from 'react'
1
+ import React from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
  import styled from 'styled-components'
4
- import { selectSystemProps, getTokensPropType, variantProp } from '@telus-uds/components-base'
4
+ import { selectSystemProps, variantProp } from '@telus-uds/components-base'
5
5
  import { htmlAttrs } from '../utils'
6
6
  import OrderedListBase from './OrderedListBase'
7
7
  import Item from './Item'
@@ -18,12 +18,12 @@ const StyledOrderedListBase = styled(OrderedListBase)(({ start }) => ({
18
18
  /**
19
19
  * Themed semantic ordered list.
20
20
  */
21
- const OrderedList = forwardRef(({ children, start, variant, ...rest }, ref) => {
21
+ const OrderedList = React.forwardRef(({ children, start = 1, variant = {}, ...rest }, ref) => {
22
22
  // Check if children is an array
23
23
  const isChildrenArray = Array.isArray(children)
24
24
 
25
25
  // Pass any variants "OrderedList" receives down to the individual list items.
26
- const childrenWithParentVariants = useMemo(() => {
26
+ const childrenWithParentVariants = React.useMemo(() => {
27
27
  const addVariantToProps = (child) => {
28
28
  const existingChildVariants = child.props?.variant ?? {}
29
29
  return React.cloneElement(child, {
@@ -54,7 +54,6 @@ OrderedList.displayName = 'OrderedList'
54
54
 
55
55
  OrderedList.propTypes = {
56
56
  ...selectedSystemPropTypes,
57
- tokens: getTokensPropType('OrderedList'),
58
57
  /**
59
58
  * A list of ordered items wrapped in `OrderedList.Item`.
60
59
  */
@@ -65,7 +64,6 @@ OrderedList.propTypes = {
65
64
  start: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
66
65
  variant: variantProp.propType
67
66
  }
68
- OrderedList.defaultProps = { start: 1, tokens: {}, variant: {} }
69
67
 
70
68
  OrderedList.Item = Item
71
69
 
@@ -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 styled from 'styled-components'
4
4
  import ItemBase from './ItemBase'
@@ -14,7 +14,7 @@ const StyledList = styled.ol({
14
14
  /**
15
15
  * Semantic ordered list.
16
16
  */
17
- const OrderedListBase = forwardRef(({ children, start, ...rest }, ref) => (
17
+ const OrderedListBase = React.forwardRef(({ children, start = 1, ...rest }, ref) => (
18
18
  <StyledList {...rest} ref={ref} start={start}>
19
19
  {children}
20
20
  </StyledList>
@@ -31,7 +31,6 @@ OrderedListBase.propTypes = {
31
31
  */
32
32
  start: PropTypes.oneOfType([PropTypes.number, PropTypes.string])
33
33
  }
34
- OrderedListBase.defaultProps = { start: 1 }
35
34
 
36
35
  OrderedListBase.Item = ItemBase
37
36
 
@@ -1,7 +1,7 @@
1
1
  import React from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
  import styled from 'styled-components'
4
- import { selectSystemProps } from '@telus-uds/components-base'
4
+ import { getTokensPropType, selectSystemProps } from '@telus-uds/components-base'
5
5
 
6
6
  import { htmlAttrs, useTypographyTheme } from '../utils'
7
7
 
@@ -31,20 +31,25 @@ const StyledParagraph = styled.p`
31
31
  contrast.
32
32
  * - All Allium Typography variants other than header size variants are supported.
33
33
  */
34
- const Paragraph = ({ children, variant, tokens, testID, align, linesBetween = 1, ...rest }) => {
35
- const style = useTypographyTheme(variant, tokens)
36
- return (
37
- <StyledParagraph
38
- linesBetween={linesBetween}
39
- data-testid={testID}
40
- align={align}
41
- style={style}
42
- {...selectProps(rest)}
43
- >
44
- {children}
45
- </StyledParagraph>
46
- )
47
- }
34
+ const Paragraph = React.forwardRef(
35
+ ({ children, variant, tokens, testID, align, linesBetween = 1, ...rest }, ref) => {
36
+ const style = useTypographyTheme(variant, tokens)
37
+ return (
38
+ <StyledParagraph
39
+ ref={ref}
40
+ linesBetween={linesBetween}
41
+ data-testid={testID}
42
+ align={align}
43
+ style={style}
44
+ {...selectProps(rest)}
45
+ >
46
+ {children}
47
+ </StyledParagraph>
48
+ )
49
+ }
50
+ )
51
+
52
+ Paragraph.displayName = 'Paragraph'
48
53
 
49
54
  Paragraph.propTypes = {
50
55
  ...selectedSystemPropTypes,
@@ -67,7 +72,7 @@ Paragraph.propTypes = {
67
72
  /**
68
73
  * Paragraph takes the same tokens overrides as Typography
69
74
  */
70
- tokens: PropTypes.oneOf([PropTypes.object, PropTypes.func]),
75
+ tokens: getTokensPropType('Typography'),
71
76
  /**
72
77
  * Paragraph takes any of Typography's theme variants except for header sizes
73
78
  */
@@ -1,5 +1,4 @@
1
- /* eslint-disable react/require-default-props */
2
- import React, { forwardRef } from 'react'
1
+ import React from 'react'
3
2
  import PropTypes from 'prop-types'
4
3
  import omit from 'lodash.omit'
5
4
  import {
@@ -62,7 +61,7 @@ const defaultTokens = {
62
61
  * - Use `href` to set the target URL
63
62
  * - Use `fullBleedContent` to set the thumbnail image
64
63
  */
65
- const PreviewCard = forwardRef(
64
+ const PreviewCard = React.forwardRef(
66
65
  (
67
66
  {
68
67
  tag,
@@ -97,156 +97,163 @@ const selectStrikeThroughTokens = ({
97
97
  strikeThroughColor
98
98
  })
99
99
 
100
- const PriceLockup = ({
101
- size = 'medium',
102
- signDirection = 'left',
103
- footnoteLinks = [],
104
- topText,
105
- price,
106
- currencySymbol = '$',
107
- rateText,
108
- ratePosition = 'right',
109
- bottomText,
110
- onClickFootnote,
111
- strikeThrough,
112
- a11yText,
113
- tokens: priceLockupTokens,
114
- variant = {},
115
- ...rest
116
- }) => {
117
- const viewport = useViewport()
118
- const {
119
- footnoteMarginTop,
120
- footnoteGap,
121
- bottomTextMarginTop,
122
- priceMarginBottom,
123
- bottomLinksMarginLeft,
124
- topTextMarginBottom,
125
- fontColor,
126
- dividerColor,
127
- footnoteLinkFontSize,
128
- ...themeTokens
129
- } = useThemeTokens(
130
- 'PriceLockup',
131
- priceLockupTokens,
132
- { ...variant, size },
133
- { viewport, strikeThrough }
134
- )
135
- const typographyTokens = getTypographyTokens(themeTokens)
136
- const priceString = String(price)
137
- const lastDotPosition = priceString.lastIndexOf('.')
138
- const lastCommaPosition = priceString.lastIndexOf(',')
139
- const [separator, separatorPosition] =
140
- lastDotPosition > lastCommaPosition ? ['.', lastDotPosition] : [',', lastCommaPosition]
100
+ const PriceLockup = React.forwardRef(
101
+ (
102
+ {
103
+ size = 'medium',
104
+ signDirection = 'left',
105
+ footnoteLinks = [],
106
+ topText,
107
+ price,
108
+ currencySymbol = '$',
109
+ rateText,
110
+ ratePosition = 'right',
111
+ bottomText,
112
+ onClickFootnote,
113
+ strikeThrough,
114
+ a11yText,
115
+ tokens: priceLockupTokens,
116
+ variant = {},
117
+ ...rest
118
+ },
119
+ ref
120
+ ) => {
121
+ const viewport = useViewport()
122
+ const {
123
+ footnoteMarginTop,
124
+ footnoteGap,
125
+ bottomTextMarginTop,
126
+ priceMarginBottom,
127
+ bottomLinksMarginLeft,
128
+ topTextMarginBottom,
129
+ fontColor,
130
+ dividerColor,
131
+ footnoteLinkFontSize,
132
+ ...themeTokens
133
+ } = useThemeTokens(
134
+ 'PriceLockup',
135
+ priceLockupTokens,
136
+ { ...variant, size },
137
+ { viewport, strikeThrough }
138
+ )
139
+ const typographyTokens = getTypographyTokens(themeTokens)
140
+ const priceString = String(price)
141
+ const lastDotPosition = priceString.lastIndexOf('.')
142
+ const lastCommaPosition = priceString.lastIndexOf(',')
143
+ const [separator, separatorPosition] =
144
+ lastDotPosition > lastCommaPosition ? ['.', lastDotPosition] : [',', lastCommaPosition]
141
145
 
142
- // If the separator is at the fourth character from the end of the string or more, it's most probably
143
- // a part of the amount, and the cents are not included in the price string
144
- const hasCents = separatorPosition !== -1 && separatorPosition >= priceString.length - 3
145
- const amount = hasCents ? priceString.substring(0, separatorPosition) : priceString
146
- const cents = hasCents ? priceString.substring(separatorPosition + 1) : null
146
+ // If the separator is at the fourth character from the end of the string or more, it's most probably
147
+ // a part of the amount, and the cents are not included in the price string
148
+ const hasCents = separatorPosition !== -1 && separatorPosition >= priceString.length - 3
149
+ const amount = hasCents ? priceString.substring(0, separatorPosition) : priceString
150
+ const cents = hasCents ? priceString.substring(separatorPosition + 1) : null
147
151
 
148
- const renderTypography = (value, tokens, position) => {
149
- const customProps =
150
- position === 'bottom'
151
- ? { variant: { size: 'micro' }, tokens: { color: fontColor } }
152
- : { tokens: { ...tokens, color: fontColor } }
153
- return <Typography {...customProps}>{value}</Typography>
154
- }
152
+ const renderTypography = (value, tokens, position) => {
153
+ const customProps =
154
+ position === 'bottom'
155
+ ? { variant: { size: 'micro' }, tokens: { color: fontColor } }
156
+ : { tokens: { ...tokens, color: fontColor } }
157
+ return <Typography {...customProps}>{value}</Typography>
158
+ }
155
159
 
156
- const renderCurrencySymbol = () =>
157
- renderTypography(`${currencySymbol}`, typographyTokens.dollarSign)
160
+ const renderCurrencySymbol = () =>
161
+ renderTypography(`${currencySymbol}`, typographyTokens.dollarSign)
158
162
 
159
- const renderFootnoteLinks = () =>
160
- footnoteLinks && footnoteLinks.length > 0 ? (
161
- <FootnoteLink
162
- fontSize={footnoteLinkFontSize}
163
- tokens={selectFootnoteLinkStyles(themeTokens)}
164
- number={footnoteLinks}
165
- onClick={onClickFootnote}
166
- />
167
- ) : null
163
+ const renderFootnoteLinks = () =>
164
+ footnoteLinks && footnoteLinks.length > 0 ? (
165
+ <FootnoteLink
166
+ fontSize={footnoteLinkFontSize}
167
+ tokens={selectFootnoteLinkStyles(themeTokens)}
168
+ number={footnoteLinks}
169
+ onClick={onClickFootnote}
170
+ />
171
+ ) : null
172
+
173
+ const renderAmount = () => {
174
+ const amountComponent = renderTypography(amount, typographyTokens.amount)
175
+ if (strikeThrough) {
176
+ return (
177
+ <>
178
+ <A11yText text={a11yText} />
179
+ <StrikeThroughContainer {...selectStrikeThroughTokens(themeTokens)}>
180
+ {amountComponent}
181
+ </StrikeThroughContainer>
182
+ </>
183
+ )
184
+ }
168
185
 
169
- const renderAmount = () => {
170
- const amountComponent = renderTypography(amount, typographyTokens.amount)
171
- if (strikeThrough) {
172
- return (
173
- <>
174
- <A11yText text={a11yText} />
175
- <StrikeThroughContainer {...selectStrikeThroughTokens(themeTokens)}>
176
- {amountComponent}
177
- </StrikeThroughContainer>
178
- </>
179
- )
186
+ return amountComponent
180
187
  }
181
188
 
182
- return amountComponent
183
- }
189
+ const renderPrice = () => (
190
+ <>
191
+ <PriceContainer priceMarginBottom={`${priceMarginBottom}px`}>
192
+ <PriceTextContainer ratePosition={ratePosition}>
193
+ <RateContainer>
194
+ {signDirection === 'left' && renderCurrencySymbol()}
195
+ {renderAmount()}
196
+ {cents && renderTypography(`${separator}${cents}`, typographyTokens.cents)}
197
+ {signDirection === 'right' && <>&nbsp;{renderCurrencySymbol()}</>}
198
+ </RateContainer>
199
+ {rateText && (
200
+ <RateTextContainer ratePosition={ratePosition}>
201
+ {renderTypography(rateText, typographyTokens.rate, ratePosition)}
202
+ </RateTextContainer>
203
+ )}
204
+ </PriceTextContainer>
184
205
 
185
- const renderPrice = () => (
186
- <>
187
- <PriceContainer priceMarginBottom={`${priceMarginBottom}px`}>
188
- <PriceTextContainer ratePosition={ratePosition}>
189
- <RateContainer>
190
- {signDirection === 'left' && renderCurrencySymbol()}
191
- {renderAmount()}
192
- {cents && renderTypography(`${separator}${cents}`, typographyTokens.cents)}
193
- {signDirection === 'right' && <>&nbsp;{renderCurrencySymbol()}</>}
194
- </RateContainer>
195
- {rateText && (
196
- <RateTextContainer ratePosition={ratePosition}>
197
- {renderTypography(rateText, typographyTokens.rate, ratePosition)}
198
- </RateTextContainer>
206
+ {!bottomText && footnoteLinks.length <= 3 && (
207
+ <BottomLinksContainer bottomLinksMarginLeft={`${bottomLinksMarginLeft}px`}>
208
+ {renderFootnoteLinks()}
209
+ </BottomLinksContainer>
199
210
  )}
200
- </PriceTextContainer>
211
+ </PriceContainer>
212
+ {!bottomText && footnoteLinks.length > 3 && renderFootnoteLinks()}
213
+ </>
214
+ )
201
215
 
202
- {!bottomText && footnoteLinks.length <= 3 && (
203
- <BottomLinksContainer bottomLinksMarginLeft={`${bottomLinksMarginLeft}px`}>
204
- {renderFootnoteLinks()}
205
- </BottomLinksContainer>
206
- )}
207
- </PriceContainer>
208
- {!bottomText && footnoteLinks.length > 3 && renderFootnoteLinks()}
209
- </>
210
- )
216
+ const renderFootnoteContent = () => (
217
+ <>
218
+ <FootnoteContainer
219
+ footnoteMarginTop={`${footnoteMarginTop}px`}
220
+ footnoteGap={`${footnoteGap}px`}
221
+ >
222
+ <BottomTextContainer bottomTextMarginTop={`${bottomTextMarginTop}px`}>
223
+ {renderTypography(bottomText, typographyTokens.bottomText)}
224
+ </BottomTextContainer>
225
+ {footnoteLinks.length <= 3 && renderFootnoteLinks()}
226
+ </FootnoteContainer>
227
+ {footnoteLinks.length > 3 && renderFootnoteLinks()}
228
+ </>
229
+ )
211
230
 
212
- const renderFootnoteContent = () => (
213
- <>
214
- <FootnoteContainer
215
- footnoteMarginTop={`${footnoteMarginTop}px`}
216
- footnoteGap={`${footnoteGap}px`}
217
- >
218
- <BottomTextContainer bottomTextMarginTop={`${bottomTextMarginTop}px`}>
219
- {renderTypography(bottomText, typographyTokens.bottomText)}
220
- </BottomTextContainer>
221
- {footnoteLinks.length <= 3 && renderFootnoteLinks()}
222
- </FootnoteContainer>
223
- {footnoteLinks.length > 3 && renderFootnoteLinks()}
224
- </>
225
- )
231
+ if (strikeThrough && !a11yText) {
232
+ warn('PriceLockup', 'a11yText must be provided with strikethrough pricing')
233
+ }
226
234
 
227
- if (strikeThrough && !a11yText) {
228
- warn('PriceLockup', 'a11yText must be provided with strikethrough pricing')
235
+ return (
236
+ <PriceLockupContainer {...selectProps(rest)} ref={ref}>
237
+ {topText && (
238
+ <TopTextContainer topTextMarginBottom={`${topTextMarginBottom}px`}>
239
+ {renderTypography(topText, typographyTokens.topText)}
240
+ </TopTextContainer>
241
+ )}
242
+ {renderPrice()}
243
+ {bottomText && (
244
+ <Divider
245
+ testID="price-lockup-divider"
246
+ role="separator"
247
+ tokens={{ color: dividerColor ?? 'rgba(0, 0, 0, 0)' }}
248
+ />
249
+ )}
250
+ {bottomText && renderFootnoteContent()}
251
+ </PriceLockupContainer>
252
+ )
229
253
  }
254
+ )
230
255
 
231
- return (
232
- <PriceLockupContainer {...selectProps(rest)}>
233
- {topText && (
234
- <TopTextContainer topTextMarginBottom={`${topTextMarginBottom}px`}>
235
- {renderTypography(topText, typographyTokens.topText)}
236
- </TopTextContainer>
237
- )}
238
- {renderPrice()}
239
- {bottomText && (
240
- <Divider
241
- testID="price-lockup-divider"
242
- role="separator"
243
- tokens={{ color: dividerColor ?? 'rgba(0, 0, 0, 0)' }}
244
- />
245
- )}
246
- {bottomText && renderFootnoteContent()}
247
- </PriceLockupContainer>
248
- )
249
- }
256
+ PriceLockup.displayName = 'PriceLockup'
250
257
 
251
258
  PriceLockup.propTypes = {
252
259
  ...selectedSystemPropTypes,
@@ -37,16 +37,24 @@ const Gradient = styled.div.attrs({ 'data-testid': 'ProgressBar-Gradient' })(
37
37
  * `gradient` is being used here to provide gradient filling.
38
38
  *
39
39
  */
40
- const ProgressBar = ({ percentage, tokens, variant, ...rest }) => {
40
+ const ProgressBar = React.forwardRef(({ percentage, tokens, variant, ...rest }, ref) => {
41
41
  const themeTokens = useThemeTokens('ProgressBar', tokens, variant)
42
42
  const selectedProps = selectProps(rest)
43
43
 
44
44
  return (
45
- <ProgressBarBase percentage={percentage} tokens={tokens} variant={variant} {...selectedProps}>
45
+ <ProgressBarBase
46
+ percentage={percentage}
47
+ tokens={tokens}
48
+ variant={variant}
49
+ ref={ref}
50
+ {...selectedProps}
51
+ >
46
52
  {themeTokens.gradient && <Gradient {...themeTokens} percentage={percentage} />}
47
53
  </ProgressBarBase>
48
54
  )
49
- }
55
+ })
56
+
57
+ ProgressBar.displayName = 'ProgressBar'
50
58
 
51
59
  ProgressBar.propTypes = {
52
60
  ...selectedSystemPropTypes,