@telus-uds/components-web 3.0.1 → 3.2.0

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 (166) hide show
  1. package/CHANGELOG.md +31 -2
  2. package/lib/Badge/Badge.js +0 -0
  3. package/lib/Badge/index.js +0 -0
  4. package/lib/BlockQuote/BlockQuote.js +56 -10
  5. package/lib/BlockQuote/index.js +0 -0
  6. package/lib/Breadcrumbs/Breadcrumbs.js +0 -0
  7. package/lib/Breadcrumbs/Item/Item.js +0 -0
  8. package/lib/Breadcrumbs/index.js +0 -0
  9. package/lib/Callout/Callout.js +0 -0
  10. package/lib/Callout/index.js +0 -0
  11. package/lib/Card/Card.js +0 -0
  12. package/lib/Card/CardContent.js +0 -0
  13. package/lib/Card/CardFooter.js +0 -0
  14. package/lib/Card/index.js +0 -0
  15. package/lib/Countdown/Countdown.js +78 -6
  16. package/lib/Countdown/Segment.js +6 -0
  17. package/lib/Countdown/constants.js +0 -0
  18. package/lib/Countdown/dictionary.js +0 -0
  19. package/lib/Countdown/index.js +0 -0
  20. package/lib/Countdown/types.js +0 -0
  21. package/lib/Countdown/useCountdown.js +0 -0
  22. package/lib/DatePicker/CalendarContainer.js +0 -0
  23. package/lib/DatePicker/DatePicker.js +0 -0
  24. package/lib/DatePicker/dictionary.js +0 -0
  25. package/lib/DatePicker/index.js +0 -0
  26. package/lib/DatePicker/reactDatesCss.js +0 -0
  27. package/lib/Disclaimer/Disclaimer.js +0 -0
  28. package/lib/Disclaimer/index.js +0 -0
  29. package/lib/ExpandCollapseMini/ExpandCollapseMini.js +0 -0
  30. package/lib/ExpandCollapseMini/ExpandCollapseMiniControl.js +0 -0
  31. package/lib/ExpandCollapseMini/index.js +0 -0
  32. package/lib/Footnote/Footnote.js +0 -0
  33. package/lib/Footnote/FootnoteLink.js +0 -0
  34. package/lib/Footnote/dictionary.js +0 -0
  35. package/lib/Footnote/index.js +0 -0
  36. package/lib/IconButton/IconButton.js +0 -0
  37. package/lib/IconButton/index.js +0 -0
  38. package/lib/Image/Image.js +0 -0
  39. package/lib/Image/index.js +0 -0
  40. package/lib/Image/server.js +0 -0
  41. package/lib/List/List.js +0 -0
  42. package/lib/List/ListItem.js +0 -0
  43. package/lib/List/index.js +0 -0
  44. package/lib/NavigationBar/NavigationBar.js +69 -15
  45. package/lib/NavigationBar/NavigationItem.js +0 -0
  46. package/lib/NavigationBar/NavigationSubMenu.js +0 -0
  47. package/lib/NavigationBar/collapseItems.js +0 -0
  48. package/lib/NavigationBar/index.js +0 -0
  49. package/lib/NavigationBar/resolveItemSelection.js +0 -0
  50. package/lib/OptimizeImage/OptimizeImage.js +0 -0
  51. package/lib/OptimizeImage/index.js +0 -0
  52. package/lib/OptimizeImage/utils/getFallbackUrl.js +0 -0
  53. package/lib/OptimizeImage/utils/getImageUrls.js +0 -0
  54. package/lib/OptimizeImage/utils/getOptimizedUrl.js +0 -0
  55. package/lib/OptimizeImage/utils/hasWebpSupport.js +0 -0
  56. package/lib/OptimizeImage/utils/index.js +0 -0
  57. package/lib/OptimizeImage/utils/isSvgUrl.js +0 -0
  58. package/lib/OrderedList/Item.js +0 -0
  59. package/lib/OrderedList/ItemBase.js +0 -0
  60. package/lib/OrderedList/OrderedList.js +0 -0
  61. package/lib/OrderedList/OrderedListBase.js +0 -0
  62. package/lib/OrderedList/constants.js +0 -0
  63. package/lib/OrderedList/index.js +0 -0
  64. package/lib/Paragraph/Paragraph.js +0 -0
  65. package/lib/Paragraph/index.js +0 -0
  66. package/lib/PreviewCard/AuthorDate.js +0 -0
  67. package/lib/PreviewCard/PreviewCard.js +0 -0
  68. package/lib/PreviewCard/index.js +0 -0
  69. package/lib/PriceLockup/PriceLockup.js +0 -0
  70. package/lib/PriceLockup/index.js +0 -0
  71. package/lib/PriceLockup/tokens.js +0 -0
  72. package/lib/Progress/ProgressBar.js +11 -1
  73. package/lib/Progress/index.js +0 -0
  74. package/lib/QuantitySelector/QuantitySelector.js +1 -1
  75. package/lib/QuantitySelector/SideButton.js +0 -0
  76. package/lib/QuantitySelector/dictionary.js +0 -0
  77. package/lib/QuantitySelector/index.js +0 -0
  78. package/lib/QuantitySelector/styles.js +0 -0
  79. package/lib/ResponsiveImage/ResponsiveImage.js +9 -3
  80. package/lib/ResponsiveImage/index.js +0 -0
  81. package/lib/Ribbon/Ribbon.js +0 -0
  82. package/lib/Ribbon/index.js +0 -0
  83. package/lib/SkeletonProvider/SkeletonImage.js +0 -0
  84. package/lib/SkeletonProvider/SkeletonProvider.js +0 -0
  85. package/lib/SkeletonProvider/SkeletonTypography.js +0 -0
  86. package/lib/SkeletonProvider/index.js +0 -0
  87. package/lib/Span/Span.js +0 -0
  88. package/lib/Span/index.js +0 -0
  89. package/lib/Spinner/Spinner.js +0 -0
  90. package/lib/Spinner/SpinnerContent.js +0 -0
  91. package/lib/Spinner/constants.js +0 -0
  92. package/lib/Spinner/index.js +0 -0
  93. package/lib/StoryCard/StoryCard.js +0 -0
  94. package/lib/StoryCard/index.js +0 -0
  95. package/lib/Table/Body.js +0 -0
  96. package/lib/Table/Cell.js +0 -0
  97. package/lib/Table/Header.js +0 -0
  98. package/lib/Table/Row.js +0 -0
  99. package/lib/Table/SubHeading.js +0 -0
  100. package/lib/Table/Table.js +0 -0
  101. package/lib/Table/index.js +0 -0
  102. package/lib/TermsAndConditions/ExpandCollapse.js +0 -0
  103. package/lib/TermsAndConditions/TermsAndConditions.js +0 -0
  104. package/lib/TermsAndConditions/dictionary.js +0 -0
  105. package/lib/TermsAndConditions/index.js +0 -0
  106. package/lib/Testimonial/Testimonial.js +0 -0
  107. package/lib/Testimonial/index.js +0 -0
  108. package/lib/Toast/Toast.js +0 -0
  109. package/lib/Toast/index.js +0 -0
  110. package/lib/Video/ControlBar/ControlBar.js +0 -0
  111. package/lib/Video/ControlBar/Controls/VideoButton/VideoButton.js +0 -0
  112. package/lib/Video/ControlBar/Controls/VideoMenu/VideoMenu.js +0 -0
  113. package/lib/Video/ControlBar/Controls/VideoProgressBar/VideoProgressBar.js +3 -0
  114. package/lib/Video/ControlBar/Controls/VolumeSlider/VolumeSlider.js +0 -0
  115. package/lib/Video/MiddleControlButton/MiddleControlButton.js +0 -0
  116. package/lib/Video/Video.js +0 -0
  117. package/lib/Video/index.js +0 -0
  118. package/lib/Video/videoText.js +0 -0
  119. package/lib/VideoPicker/VideoPicker.js +0 -0
  120. package/lib/VideoPicker/VideoPickerPlayer.js +0 -0
  121. package/lib/VideoPicker/VideoPickerThumbnail.js +0 -0
  122. package/lib/VideoPicker/VideoSlider.js +0 -0
  123. package/lib/VideoPicker/index.js +0 -0
  124. package/lib/VideoPicker/videoPropType.js +0 -0
  125. package/lib/WaffleGrid/WaffleGrid.js +0 -0
  126. package/lib/WaffleGrid/index.js +0 -0
  127. package/lib/WebVideo/WebVideo.js +0 -0
  128. package/lib/WebVideo/index.js +0 -0
  129. package/lib/WebVideo/utils/index.js +0 -0
  130. package/lib/baseExports.js +0 -0
  131. package/lib/index.js +0 -0
  132. package/lib/server.js +0 -0
  133. package/lib/shared/ConditionalWrapper/ConditionalWrapper.js +0 -0
  134. package/lib/shared/ConditionalWrapper/index.js +0 -0
  135. package/lib/shared/FullBleedContent/FullBleedContent.js +0 -0
  136. package/lib/shared/FullBleedContent/getFullBleedBorderRadius.js +0 -0
  137. package/lib/shared/FullBleedContent/index.js +0 -0
  138. package/lib/shared/FullBleedContent/useFullBleedContentProps.js +0 -0
  139. package/lib/shared/VideoSplash/SplashButton/SplashButton.js +0 -0
  140. package/lib/shared/VideoSplash/SplashButtonWithDetails/SplashButtonWithDetails.js +0 -0
  141. package/lib/shared/VideoSplash/VideoSplash.js +0 -0
  142. package/lib/shared/VideoSplash/helpers.js +0 -0
  143. package/lib/utils/index.js +3 -2
  144. package/lib/utils/isElementFocusable.js +0 -0
  145. package/lib/utils/logger.js +0 -0
  146. package/lib/utils/media.js +0 -0
  147. package/lib/utils/renderStructuredContent.js +0 -0
  148. package/lib/utils/scrollToAnchor.js +19 -0
  149. package/lib/utils/ssr.js +0 -0
  150. package/lib/utils/theming/get-theme-from-server.js +0 -0
  151. package/lib/utils/theming/with-client-theme.js +0 -0
  152. package/lib/utils/theming/with-server-theme.js +0 -0
  153. package/lib/utils/transforms.js +0 -0
  154. package/lib/utils/useOverlaidPosition.js +0 -0
  155. package/lib/utils/useTypographyTheme.js +0 -0
  156. package/package.json +3 -3
  157. package/src/BlockQuote/BlockQuote.jsx +73 -11
  158. package/src/Countdown/Countdown.jsx +90 -6
  159. package/src/Countdown/Segment.jsx +8 -2
  160. package/src/NavigationBar/NavigationBar.jsx +53 -12
  161. package/src/Progress/ProgressBar.jsx +11 -2
  162. package/src/QuantitySelector/QuantitySelector.jsx +1 -1
  163. package/src/ResponsiveImage/ResponsiveImage.jsx +12 -5
  164. package/src/Video/ControlBar/Controls/VideoProgressBar/VideoProgressBar.jsx +5 -1
  165. package/src/utils/index.js +5 -2
  166. package/src/utils/scrollToAnchor.js +18 -0
@@ -4,11 +4,13 @@ import {
4
4
  selectSystemProps,
5
5
  StackView,
6
6
  Typography,
7
+ useHash,
8
+ useInputValue,
7
9
  useResponsiveProp,
8
10
  withLinkRouter
9
11
  } from '@telus-uds/components-base'
10
12
  import styled from 'styled-components'
11
- import { htmlAttrs } from '../utils'
13
+ import { htmlAttrs, scrollToAnchor } from '../utils'
12
14
  import NavigationItem from './NavigationItem'
13
15
  import NavigationSubMenu from './NavigationSubMenu'
14
16
  import collapseItems from './collapseItems'
@@ -34,16 +36,37 @@ const NavigationBar = React.forwardRef(
34
36
  heading,
35
37
  headingLevel = 'h1',
36
38
  items,
37
- onChange = () => {},
39
+ onChange,
38
40
  selectedId,
41
+ value,
39
42
  LinkRouter,
40
43
  linkRouterProps,
41
44
  ...rest
42
45
  },
43
46
  ref
44
47
  ) => {
48
+ const { currentValue, setValue } = useInputValue({ value, initialValue: selectedId, onChange })
49
+
50
+ useHash(
51
+ (hash, event) => {
52
+ let hashItem = hash && items.find(({ href }) => hash === href)
53
+ if (!hashItem) {
54
+ const parentItem = items.find(({ items: parentItems }) =>
55
+ parentItems?.some(({ href }) => hash === href)
56
+ )
57
+ hashItem = parentItem?.items.find(({ href }) => hash === href)
58
+ }
59
+ const hashId = hashItem && (hashItem.id || hashItem.label)
60
+ if (hashId) setValue(hashId, event)
61
+ },
62
+ [items, setValue]
63
+ )
64
+
45
65
  const direction = useResponsiveProp({ xs: 'column', sm: 'row' })
46
- const itemsForViewport = useResponsiveProp({ xs: collapseItems(items, selectedId), lg: items })
66
+ const itemsForViewport = useResponsiveProp({
67
+ xs: collapseItems(items, currentValue),
68
+ lg: items
69
+ })
47
70
  const openOverlayRef = React.useRef(null)
48
71
  const [openSubMenuId, setOpenSubMenuId] = React.useState(null)
49
72
  const handleSubMenuClose = (event) => {
@@ -161,14 +184,28 @@ const NavigationBar = React.forwardRef(
161
184
  const handleClick = (event) => {
162
185
  if (nestedItems) {
163
186
  setOpenSubMenuId(openSubMenuId !== itemId ? itemId : null)
187
+ return
188
+ }
189
+ if (href?.startsWith('#')) {
190
+ scrollToAnchor(href, event, () => setValue(itemId, event))
191
+ } else {
192
+ setValue(itemId, event)
164
193
  }
165
194
  onClick?.(event)
166
- onChange?.(itemId, event)
167
195
  }
168
196
 
169
197
  const ItemComponent = nestedItems ? NavigationSubMenu : NavigationItem
170
198
  const isOpen = itemId === openSubMenuId
171
199
 
200
+ const scrollableNestedItems =
201
+ nestedItems?.map((item) => ({
202
+ ...item,
203
+ onPress: (event) => {
204
+ const nestedItemId = item.id ?? item.label
205
+ scrollToAnchor(item.href, event, () => setValue(nestedItemId, event))
206
+ }
207
+ })) ?? nestedItems
208
+
172
209
  return (
173
210
  <ItemComponent
174
211
  ref={itemRef}
@@ -176,16 +213,16 @@ const NavigationBar = React.forwardRef(
176
213
  href={href}
177
214
  onClick={handleClick}
178
215
  // TODO: refactor to pass selected ID via context
179
- selectedId={selectedId}
216
+ selectedId={currentValue}
180
217
  index={index}
181
218
  LinkRouter={ItemLinkRouter}
182
219
  linkRouterProps={{ ...linkRouterProps, ...itemLinkRouterProps }}
183
- items={nestedItems}
184
- selected={itemId === selectedId}
220
+ items={scrollableNestedItems}
221
+ selected={itemId === currentValue}
185
222
  itemsContainerRef={itemsRef}
186
223
  {...itemRest}
187
- {...(nestedItems && { isOpen })}
188
- {...(nestedItems && isOpen && { openOverlayRef })}
224
+ {...(scrollableNestedItems && { isOpen })}
225
+ {...(scrollableNestedItems && isOpen && { openOverlayRef })}
189
226
  >
190
227
  {label}
191
228
  </ItemComponent>
@@ -207,7 +244,7 @@ NavigationBar.propTypes = {
207
244
  *
208
245
  * Each `item` object must contain:
209
246
  * - `heading` - user-facing text in the tab link
210
- * - `href` - the URL of the page linked to. Do not use hash links, for content within a page, use `Tabs`.
247
+ * - `href` - the URL of the page linked to.
211
248
  * - `id` - a stable, unique identifier of the page within the set. Not written into the HTML.
212
249
  */
213
250
  items: PropTypes.arrayOf(
@@ -242,13 +279,17 @@ NavigationBar.propTypes = {
242
279
  */
243
280
  headingLevel: PropTypes.oneOf(['h1', 'h2', 'h3', 'h4', 'h5', 'h6']),
244
281
  /**
245
- * Matches the `id` property of the item in `items` corresponding to the current page
282
+ * Initial selected item ID
246
283
  */
247
- selectedId: PropTypes.string.isRequired,
284
+ selectedId: PropTypes.string,
248
285
  /**
249
286
  * Optional function to be called on pressing a link
250
287
  */
251
288
  onChange: PropTypes.func,
289
+ /**
290
+ * Controlled value for selected item ID
291
+ */
292
+ value: PropTypes.string,
252
293
  /**
253
294
  * Accesibility role for stackview
254
295
  */
@@ -37,7 +37,8 @@ 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 = React.forwardRef(({ percentage, tokens, variant, ...rest }, ref) => {
40
+
41
+ const ProgressBar = React.forwardRef(({ percentage, tokens, variant, offset, ...rest }, ref) => {
41
42
  const themeTokens = useThemeTokens('ProgressBar', tokens, variant)
42
43
  const selectedProps = selectProps(rest)
43
44
 
@@ -47,6 +48,7 @@ const ProgressBar = React.forwardRef(({ percentage, tokens, variant, ...rest },
47
48
  tokens={tokens}
48
49
  variant={variant}
49
50
  ref={ref}
51
+ offset={offset}
50
52
  {...selectedProps}
51
53
  >
52
54
  {themeTokens.gradient && <Gradient {...themeTokens} />}
@@ -69,7 +71,14 @@ ProgressBar.propTypes = {
69
71
  /**
70
72
  * ProgressBar variant.
71
73
  */
72
- variant: variantProp.propType
74
+ variant: variantProp.propType,
75
+ /**
76
+ * Offset position.
77
+ */
78
+ offset: PropTypes.shape({
79
+ items: PropTypes.number,
80
+ current: PropTypes.number
81
+ })
73
82
  }
74
83
 
75
84
  export default ProgressBar
@@ -96,7 +96,7 @@ const QuantitySelector = React.forwardRef(
96
96
  }
97
97
 
98
98
  const renderLabel = () =>
99
- label ? (
99
+ label || hint ? (
100
100
  <InputLabel
101
101
  forId={id}
102
102
  label={label}
@@ -2,9 +2,9 @@ import React from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
  import { selectSystemProps } from '@telus-uds/components-base'
4
4
  import { viewports } from '@telus-uds/system-constants'
5
- import { htmlAttrs } from '../utils'
5
+ import { htmlAttrs, contentfulProps } from '../utils'
6
6
 
7
- const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs])
7
+ const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs, contentfulProps])
8
8
 
9
9
  const staticStyles = {
10
10
  image: { display: 'block', width: '100%' }
@@ -14,9 +14,12 @@ const staticStyles = {
14
14
  * Provide different image sources for different screen sizes.
15
15
  */
16
16
  const ResponsiveImage = React.forwardRef(
17
- ({ xsSrc, smSrc, mdSrc, lgSrc, xlSrc, fallbackSrc, alt, loading = 'eager', ...rest }, ref) => {
17
+ (
18
+ { xsSrc, smSrc, mdSrc, lgSrc, xlSrc, fallbackSrc, alt, loading = 'eager', dataSet, ...rest },
19
+ ref
20
+ ) => {
18
21
  return (
19
- <picture {...selectProps(rest)} ref={ref}>
22
+ <picture {...selectProps(rest)} ref={ref} {...dataSet}>
20
23
  <source srcSet={xlSrc} media={`(min-width: ${viewports.map.get(viewports.xl)}px)`} />
21
24
  <source srcSet={lgSrc} media={`(min-width: ${viewports.map.get(viewports.lg)}px)`} />
22
25
  <source srcSet={mdSrc} media={`(min-width: ${viewports.map.get(viewports.md)}px)`} />
@@ -65,7 +68,11 @@ ResponsiveImage.propTypes = {
65
68
  * @default 'eager'
66
69
  * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-loading
67
70
  */
68
- loading: PropTypes.oneOf(['eager', 'lazy'])
71
+ loading: PropTypes.oneOf(['eager', 'lazy']),
72
+ /**
73
+ * The dataSet prop allows to pass data-* attributes element to the component.
74
+ */
75
+ dataSet: PropTypes.object
69
76
  }
70
77
 
71
78
  export default ResponsiveImage
@@ -119,6 +119,8 @@ const VideoProgressBar = ({
119
119
  thumbBackground,
120
120
  timestampMarginLeft,
121
121
  timestampMarginRight,
122
+ remainingTimestampMarginLeft,
123
+ remainingTimestampMarginRight,
122
124
  trackGradientStart,
123
125
  trackGradientEnd,
124
126
  rangeBackground
@@ -166,7 +168,9 @@ const VideoProgressBar = ({
166
168
  tabIndex="-1"
167
169
  {...sharedProps}
168
170
  />
169
- <StyledTimestamp>
171
+ <StyledTimestamp
172
+ margin={`0 ${remainingTimestampMarginRight}px 0 ${remainingTimestampMarginLeft}px`}
173
+ >
170
174
  <Typography variant={{ inverse: true }}>{remainingTimestamp}</Typography>
171
175
  </StyledTimestamp>
172
176
  </ProgressBarContainer>
@@ -1,4 +1,4 @@
1
- import { htmlAttrs } from '@telus-uds/components-base'
1
+ import { htmlAttrs, contentfulProps } from '@telus-uds/components-base'
2
2
  import { warn, deprecate } from './logger'
3
3
  import { transformGradient } from './transforms'
4
4
  import useTypographyTheme from './useTypographyTheme'
@@ -7,10 +7,12 @@ import ssrStyles from './ssr'
7
7
  import isElementFocusable from './isElementFocusable'
8
8
  import renderStructuredContent from './renderStructuredContent'
9
9
  import useOverlaidPosition from './useOverlaidPosition'
10
+ import scrollToAnchor from './scrollToAnchor'
10
11
 
11
12
  export {
12
13
  deprecate,
13
14
  htmlAttrs,
15
+ contentfulProps,
14
16
  transformGradient,
15
17
  useTypographyTheme,
16
18
  warn,
@@ -18,5 +20,6 @@ export {
18
20
  renderStructuredContent,
19
21
  ssrStyles,
20
22
  isElementFocusable,
21
- useOverlaidPosition
23
+ useOverlaidPosition,
24
+ scrollToAnchor
22
25
  }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Scrolls smoothly to the anchor element specified by the href.
3
+ *
4
+ * @param {string} href - The href attribute value, expected to be an anchor link starting with '#'.
5
+ * @param {Event} event - The event object associated with the click or navigation action.
6
+ * @param {Function} onAfterScroll - A callback function to be executed after the scroll action is completed.
7
+ */
8
+ const scrollToAnchor = (href, event, onAfterScroll) => {
9
+ if (href?.startsWith('#')) {
10
+ event.preventDefault()
11
+ const target = document.getElementById(href.slice(1))
12
+ target?.scrollIntoView({ behavior: 'smooth' })
13
+ window.location.hash = href
14
+ onAfterScroll(event)
15
+ }
16
+ }
17
+
18
+ export default scrollToAnchor