@telus-uds/components-web 1.9.0 → 1.11.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 (83) hide show
  1. package/CHANGELOG.md +40 -2
  2. package/lib/Breadcrumbs/Breadcrumbs.js +8 -3
  3. package/lib/Breadcrumbs/Item/Item.js +31 -6
  4. package/lib/Callout/Callout.js +24 -3
  5. package/lib/Disclaimer/Disclaimer.js +72 -0
  6. package/lib/Disclaimer/index.js +15 -0
  7. package/lib/Footnote/Footnote.js +70 -28
  8. package/lib/Footnote/FootnoteLink.js +11 -13
  9. package/lib/NavigationBar/NavigationBar.js +231 -0
  10. package/lib/NavigationBar/NavigationItem.js +111 -0
  11. package/lib/NavigationBar/NavigationSubMenu.js +179 -0
  12. package/lib/NavigationBar/collapseItems.js +51 -0
  13. package/lib/NavigationBar/index.js +13 -0
  14. package/lib/PriceLockup/PriceLockup.js +40 -17
  15. package/lib/PriceLockup/tokens.js +49 -116
  16. package/lib/Progress/ProgressBar.js +100 -0
  17. package/lib/Progress/index.js +16 -0
  18. package/lib/Ribbon/Ribbon.js +53 -32
  19. package/lib/Spinner/Spinner.js +18 -14
  20. package/lib/Table/Cell.js +15 -1
  21. package/lib/Toast/Toast.js +15 -8
  22. package/lib/VideoPicker/VideoPicker.js +177 -0
  23. package/lib/VideoPicker/VideoPickerPlayer.js +54 -0
  24. package/lib/VideoPicker/VideoPickerThumbnail.js +201 -0
  25. package/lib/VideoPicker/VideoSlider.js +100 -0
  26. package/lib/VideoPicker/index.js +13 -0
  27. package/lib/VideoPicker/videoPropType.js +25 -0
  28. package/lib/index.js +37 -1
  29. package/lib-module/Breadcrumbs/Breadcrumbs.js +8 -3
  30. package/lib-module/Breadcrumbs/Item/Item.js +32 -7
  31. package/lib-module/Callout/Callout.js +24 -3
  32. package/lib-module/Disclaimer/Disclaimer.js +54 -0
  33. package/lib-module/Disclaimer/index.js +1 -0
  34. package/lib-module/Footnote/Footnote.js +68 -27
  35. package/lib-module/Footnote/FootnoteLink.js +12 -14
  36. package/lib-module/NavigationBar/NavigationBar.js +207 -0
  37. package/lib-module/NavigationBar/NavigationItem.js +87 -0
  38. package/lib-module/NavigationBar/NavigationSubMenu.js +161 -0
  39. package/lib-module/NavigationBar/collapseItems.js +43 -0
  40. package/lib-module/NavigationBar/index.js +2 -0
  41. package/lib-module/PriceLockup/PriceLockup.js +42 -19
  42. package/lib-module/PriceLockup/tokens.js +54 -119
  43. package/lib-module/Progress/ProgressBar.js +83 -0
  44. package/lib-module/Progress/index.js +4 -0
  45. package/lib-module/Ribbon/Ribbon.js +53 -32
  46. package/lib-module/Spinner/Spinner.js +17 -14
  47. package/lib-module/Table/Cell.js +15 -1
  48. package/lib-module/Toast/Toast.js +15 -8
  49. package/lib-module/VideoPicker/VideoPicker.js +151 -0
  50. package/lib-module/VideoPicker/VideoPickerPlayer.js +41 -0
  51. package/lib-module/VideoPicker/VideoPickerThumbnail.js +180 -0
  52. package/lib-module/VideoPicker/VideoSlider.js +83 -0
  53. package/lib-module/VideoPicker/index.js +2 -0
  54. package/lib-module/VideoPicker/videoPropType.js +9 -0
  55. package/lib-module/index.js +4 -0
  56. package/package.json +3 -3
  57. package/src/Breadcrumbs/Breadcrumbs.jsx +4 -3
  58. package/src/Breadcrumbs/Item/Item.jsx +18 -4
  59. package/src/Callout/Callout.jsx +27 -3
  60. package/src/Disclaimer/Disclaimer.jsx +39 -0
  61. package/src/Disclaimer/index.js +1 -0
  62. package/src/Footnote/Footnote.jsx +76 -26
  63. package/src/Footnote/FootnoteLink.jsx +28 -18
  64. package/src/NavigationBar/NavigationBar.jsx +217 -0
  65. package/src/NavigationBar/NavigationItem.jsx +83 -0
  66. package/src/NavigationBar/NavigationSubMenu.jsx +121 -0
  67. package/src/NavigationBar/collapseItems.js +29 -0
  68. package/src/NavigationBar/index.js +3 -0
  69. package/src/PriceLockup/PriceLockup.jsx +47 -21
  70. package/src/PriceLockup/tokens.js +34 -54
  71. package/src/Progress/ProgressBar.jsx +67 -0
  72. package/src/Progress/index.js +6 -0
  73. package/src/Ribbon/Ribbon.jsx +21 -9
  74. package/src/Spinner/Spinner.jsx +20 -17
  75. package/src/Table/Cell.jsx +22 -5
  76. package/src/Toast/Toast.jsx +12 -5
  77. package/src/VideoPicker/VideoPicker.jsx +144 -0
  78. package/src/VideoPicker/VideoPickerPlayer.jsx +21 -0
  79. package/src/VideoPicker/VideoPickerThumbnail.jsx +182 -0
  80. package/src/VideoPicker/VideoSlider.jsx +85 -0
  81. package/src/VideoPicker/index.js +3 -0
  82. package/src/VideoPicker/videoPropType.js +12 -0
  83. package/src/index.js +4 -0
@@ -0,0 +1,121 @@
1
+ import React, { useRef } from 'react'
2
+ import PropTypes from 'prop-types'
3
+ import { Icon, Spacer, useResponsiveProp, useThemeTokens } from '@telus-uds/components-base'
4
+ import NavigationItem from './NavigationItem'
5
+ import Listbox from '../Listbox'
6
+ import useOverlaidPosition from '../utils/useOverlaidPosition'
7
+ import resolveItemSelection from './resolveItemSelection'
8
+
9
+ /**
10
+ * A NavigationItem that opens or closes a Listbox of other NavigationItems.
11
+ *
12
+ * This is rendered automatically by `NavigationBar` and isn't intended be used directly.
13
+ */
14
+ const NavigationSubMenu = ({
15
+ children,
16
+ id,
17
+ isOpen = false,
18
+ label,
19
+ onClick,
20
+ selectedId,
21
+ items = [],
22
+ openOverlayRef,
23
+ LinkRouter,
24
+ linkRouterProps
25
+ }) => {
26
+ const focusTrapRef = useRef()
27
+
28
+ const maxWidth = 289 // Slightly over 288 of nav item to account for subpixel rounding
29
+ const { align, offsets, minWidth } = useResponsiveProp({
30
+ xs: { align: { top: 'top', left: 'left' }, minWidth: maxWidth },
31
+ sm: { align: { top: 'top', right: 'right' }, minWidth: maxWidth },
32
+ lg: {
33
+ align: { top: 'bottom', center: 'center' },
34
+ offsets: { vertical: 4 },
35
+ minWidth: 192
36
+ }
37
+ })
38
+
39
+ const { overlaidPosition, sourceRef, targetRef, onTargetLayout, isReady } = useOverlaidPosition({
40
+ isShown: isOpen,
41
+ offsets,
42
+ align
43
+ })
44
+ const { selected } = resolveItemSelection({ id, label, items }, selectedId)
45
+
46
+ const handleClick = (event) => {
47
+ if (typeof onClick === 'function') onClick(event)
48
+ }
49
+
50
+ const { icoMenu } = useThemeTokens('NavigationBar', {}, {}, { expanded: isOpen })
51
+
52
+ return (
53
+ <>
54
+ <NavigationItem
55
+ ref={sourceRef}
56
+ accessibilityRole="button"
57
+ id={id}
58
+ selected={selected}
59
+ onClick={handleClick}
60
+ icon={icoMenu}
61
+ >
62
+ {({ textStyles }) => [
63
+ children,
64
+ <Spacer key={`${id}_spacer`} space={1} direction="row" />,
65
+ <Icon
66
+ key={`${id}_icon`}
67
+ icon={icoMenu}
68
+ variant={{ size: 'small' }}
69
+ tokens={{ color: textStyles[0]?.color, size: textStyles[0]?.fontSize }}
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
+ />
91
+ </Listbox.Overlay>
92
+ <div
93
+ // This catches and shifts focus to other interactive elements.
94
+ // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
95
+ tabIndex={0}
96
+ ref={focusTrapRef}
97
+ onFocus={() => targetRef.current.focus()}
98
+ />
99
+ </>
100
+ )}
101
+ </>
102
+ )
103
+ }
104
+
105
+ NavigationSubMenu.displayName = 'NavigationSubMenu'
106
+
107
+ // @TODO - proper prop types and comments
108
+ NavigationSubMenu.propTypes = {
109
+ children: PropTypes.node,
110
+ id: PropTypes.string,
111
+ isOpen: PropTypes.bool,
112
+ label: PropTypes.string,
113
+ onClick: PropTypes.func,
114
+ selectedId: PropTypes.string,
115
+ items: PropTypes.array,
116
+ openOverlayRef: PropTypes.object,
117
+ LinkRouter: PropTypes.elementType,
118
+ linkRouterProps: PropTypes.object
119
+ }
120
+
121
+ export default NavigationSubMenu
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Make a list of items into a one-item list where all items are nested under the first item
3
+ */
4
+ const collapseItems = (items, selectedId) => {
5
+ if (!items?.length) return items
6
+
7
+ // Give the root item the label of the current active link
8
+ // (or the first item if for some reason there's no match on the selectedId)
9
+ let rootLabel = items[0].label
10
+ const isSelected = ({ label, id }) => selectedId === id ?? label
11
+
12
+ // Linter doesn't like for loops, simulate loop that breaks
13
+ items.some((item) => {
14
+ if (isSelected(item)) {
15
+ rootLabel = item.label
16
+ return true // break
17
+ }
18
+ const nestedMatch = item.items?.find(isSelected)
19
+ if (nestedMatch) {
20
+ rootLabel = nestedMatch.label
21
+ return true // break
22
+ }
23
+ return false // continue
24
+ })
25
+
26
+ return [{ id: 'navigation-bar-root', label: rootLabel, items }]
27
+ }
28
+
29
+ export default collapseItems
@@ -0,0 +1,3 @@
1
+ import NavigationBar from './NavigationBar'
2
+
3
+ export default NavigationBar
@@ -5,11 +5,12 @@ import {
5
5
  Divider,
6
6
  selectSystemProps,
7
7
  Typography,
8
- useThemeTokens
8
+ useThemeTokens,
9
+ useViewport
9
10
  } from '@telus-uds/components-base'
10
11
  import styled from 'styled-components'
11
12
  import FootnoteLink from '../Footnote/FootnoteLink'
12
- import typographyTokens from './tokens'
13
+ import getTypographyTokens from './tokens'
13
14
  import { htmlAttrs, warn } from '../utils'
14
15
 
15
16
  const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs])
@@ -56,11 +57,23 @@ const StrikeThroughContainer = styled.div`
56
57
  content: '';
57
58
  width: 100%;
58
59
  height: ${({ strikeThroughHeight }) => strikeThroughHeight};
59
- background: ${({ strikeThroughBackground }) => strikeThroughBackground};
60
+ background: ${({ strikeThroughColor }) => strikeThroughColor};
60
61
  position: absolute;
61
62
  }
62
63
  `
63
64
 
65
+ const selectFootnoteLinkStyles = ({
66
+ footnoteLinkColor,
67
+ footnoteLinkFontName,
68
+ footnoteLinkFontWeight
69
+ }) => {
70
+ return {
71
+ color: footnoteLinkColor,
72
+ fontName: footnoteLinkFontName,
73
+ fontWeight: footnoteLinkFontWeight
74
+ }
75
+ }
76
+
64
77
  const PriceLockup = ({
65
78
  size = 'medium',
66
79
  signDirection = 'left',
@@ -77,6 +90,7 @@ const PriceLockup = ({
77
90
  variant = {},
78
91
  ...rest
79
92
  }) => {
93
+ const viewport = useViewport()
80
94
  const {
81
95
  footnoteMarginTop,
82
96
  footnoteGap,
@@ -85,11 +99,18 @@ const PriceLockup = ({
85
99
  bottomLinksMarginLeft,
86
100
  topTextMarginBottom,
87
101
  strikeThroughHeight,
88
- strikeThroughBackground,
102
+ strikeThroughColor,
89
103
  fontColor,
90
- dividerColor
91
- } = useThemeTokens('PriceLockup', priceLockupTokens, variant)
92
-
104
+ dividerColor,
105
+ footnoteLinkFontSize,
106
+ ...themeTokens
107
+ } = useThemeTokens(
108
+ 'PriceLockup',
109
+ priceLockupTokens,
110
+ { ...variant, size },
111
+ { viewport, strikeThrough }
112
+ )
113
+ const typographyTokens = getTypographyTokens(themeTokens)
93
114
  const priceString = String(price)
94
115
  const lastDotPosition = priceString.lastIndexOf('.')
95
116
  const lastCommaPosition = priceString.lastIndexOf(',')
@@ -102,29 +123,32 @@ const PriceLockup = ({
102
123
  const amount = hasCents ? priceString.substring(0, separatorPosition) : priceString
103
124
  const cents = hasCents ? priceString.substring(separatorPosition + 1) : null
104
125
 
105
- const color = strikeThrough ? strikeThroughBackground : fontColor
106
-
107
126
  const renderTypography = (value, tokens) => (
108
- <Typography tokens={{ ...tokens, color }}>{value}</Typography>
127
+ <Typography tokens={{ ...tokens, color: fontColor }}>{value}</Typography>
109
128
  )
110
129
 
111
130
  const renderCurrencySymbol = () =>
112
- renderTypography(`${currencySymbol}`, typographyTokens.dollarSign[size])
131
+ renderTypography(`${currencySymbol}`, typographyTokens.dollarSign)
113
132
 
114
133
  const renderFootnoteLinks = () =>
115
134
  footnoteLinks && footnoteLinks.length > 0 ? (
116
- <FootnoteLink number={footnoteLinks} onClick={onClickFootnote} />
135
+ <FootnoteLink
136
+ fontSize={footnoteLinkFontSize}
137
+ tokens={selectFootnoteLinkStyles(themeTokens)}
138
+ number={footnoteLinks}
139
+ onClick={onClickFootnote}
140
+ />
117
141
  ) : null
118
142
 
119
143
  const renderAmount = () => {
120
- const amountComponent = renderTypography(amount, typographyTokens.amount[size])
144
+ const amountComponent = renderTypography(amount, typographyTokens.amount)
121
145
  if (strikeThrough) {
122
146
  return (
123
147
  <>
124
148
  <A11yText text={a11yText} />
125
149
  <StrikeThroughContainer
126
150
  strikeThroughHeight={`${strikeThroughHeight}px`}
127
- strikeThroughBackground={strikeThroughBackground}
151
+ strikeThroughColor={strikeThroughColor}
128
152
  >
129
153
  {amountComponent}
130
154
  </StrikeThroughContainer>
@@ -140,12 +164,10 @@ const PriceLockup = ({
140
164
  <PriceContainer priceMarginBottom={`${priceMarginBottom}px`}>
141
165
  {signDirection === 'left' && renderCurrencySymbol()}
142
166
  {renderAmount()}
143
- {cents && renderTypography(`${separator}${cents}`, typographyTokens.cents[size])}
167
+ {cents && renderTypography(`${separator}${cents}`, typographyTokens.cents)}
144
168
  {signDirection === 'right' && <>&nbsp;{renderCurrencySymbol()}</>}
145
169
  {rateText && (
146
- <RateTextContainer>
147
- {renderTypography(rateText, typographyTokens.rate[size])}
148
- </RateTextContainer>
170
+ <RateTextContainer>{renderTypography(rateText, typographyTokens.rate)}</RateTextContainer>
149
171
  )}
150
172
  {!bottomText && footnoteLinks.length <= 3 && (
151
173
  <BottomLinksContainer bottomLinksMarginLeft={`${bottomLinksMarginLeft}px`}>
@@ -164,7 +186,7 @@ const PriceLockup = ({
164
186
  footnoteGap={`${footnoteGap}px`}
165
187
  >
166
188
  <BottomTextContainer bottomTextMarginTop={`${bottomTextMarginTop}px`}>
167
- {renderTypography(bottomText, typographyTokens.bottomText[size])}
189
+ {renderTypography(bottomText, typographyTokens.bottomText)}
168
190
  </BottomTextContainer>
169
191
  {footnoteLinks.length <= 3 && renderFootnoteLinks()}
170
192
  </FootnoteContainer>
@@ -180,12 +202,16 @@ const PriceLockup = ({
180
202
  <PriceLockupContainer {...selectProps(rest)}>
181
203
  {topText && (
182
204
  <TopTextContainer topTextMarginBottom={`${topTextMarginBottom}px`}>
183
- {renderTypography(topText, typographyTokens.topText[size])}
205
+ {renderTypography(topText, typographyTokens.topText)}
184
206
  </TopTextContainer>
185
207
  )}
186
208
  {renderPrice()}
187
209
  {bottomText && (
188
- <Divider testID="price-lockup-divider" role="separator" tokens={{ color: dividerColor }} />
210
+ <Divider
211
+ testID="price-lockup-divider"
212
+ role="separator"
213
+ tokens={{ color: dividerColor ?? 'rgba(0, 0, 0, 0)' }}
214
+ />
189
215
  )}
190
216
  {bottomText && renderFootnoteContent()}
191
217
  </PriceLockupContainer>
@@ -1,58 +1,38 @@
1
- import palette from '@telus-uds/palette-allium/build/rn/palette'
2
-
3
- const {
4
- fontSize: { size14, size16, size20, size28, size36, size40, size64 },
5
- lineHeight: {
6
- ratio1to1,
7
- ratio10to7,
8
- ratio3to2,
9
- ratio8to5,
10
- ratio5to4,
11
- ratio6to5,
12
- ratio9to8,
13
- ratio4to3,
14
- ratio8to7
15
- },
16
- letterSpacing: { condensed }
17
- } = palette
18
-
19
- const typographyTokens = {
20
- topText: {
21
- small: { fontSize: size14, lineHeight: ratio10to7 },
22
- medium: { fontSize: size16, lineHeight: ratio3to2 },
23
- large: { fontSize: size20, lineHeight: ratio8to5 }
24
- },
1
+ // map typography tokens accordenly
2
+ export default ({
3
+ topTextFontSize,
4
+ fontColor,
5
+ topTextLineHeight,
6
+ currencySymbolFontSize,
7
+ currencySymbolLineHeight,
8
+ currencySymbolFontWeight,
9
+ amountFontSize,
10
+ amountLineHeight,
11
+ amountLetterSpacing,
12
+ amountFontWeight,
13
+ centsFontSize,
14
+ centsLineHeight,
15
+ rateFontSize,
16
+ rateLineHeight,
17
+ bottomTextFontSize,
18
+ bottomTextLineHeight,
19
+ rateFontWeight,
20
+ centsFontWeight
21
+ }) => ({
22
+ topText: { fontSize: topTextFontSize, lineHeight: topTextLineHeight },
25
23
  dollarSign: {
26
- small: { fontSize: size16, lineHeight: ratio5to4 },
27
- medium: { fontSize: size20, lineHeight: ratio6to5 },
28
- large: { fontSize: size36, lineHeight: ratio9to8 }
24
+ fontSize: currencySymbolFontSize,
25
+ lineHeight: currencySymbolLineHeight,
26
+ fontWeight: currencySymbolFontWeight
29
27
  },
30
- // TODO - fontWeight should have its own const on palette
31
28
  amount: {
32
- small: { fontSize: size28, lineHeight: ratio1to1, letterSpacing: condensed, fontWeight: '300' },
33
- medium: {
34
- fontSize: size40,
35
- lineHeight: ratio1to1,
36
- letterSpacing: condensed,
37
- fontWeight: '300'
38
- },
39
- large: { fontSize: size64, lineHeight: ratio1to1, letterSpacing: condensed, fontWeight: '300' }
40
- },
41
- cents: {
42
- small: { fontSize: size16, lineHeight: ratio4to3 },
43
- medium: { fontSize: size20, lineHeight: ratio6to5 },
44
- large: { fontSize: size36, lineHeight: ratio9to8 }
45
- },
46
- rate: {
47
- small: { fontSize: size14, lineHeight: ratio8to7 },
48
- medium: { fontSize: size16, lineHeight: ratio5to4 },
49
- large: { fontSize: size20, lineHeight: ratio8to5 }
29
+ color: fontColor,
30
+ fontSize: amountFontSize,
31
+ lineHeight: amountLineHeight,
32
+ letterSpacing: amountLetterSpacing,
33
+ fontWeight: amountFontWeight
50
34
  },
51
- bottomText: {
52
- small: { fontSize: size14, lineHeight: ratio10to7 },
53
- medium: { fontSize: size16, lineHeight: ratio3to2 },
54
- large: { fontSize: size20, lineHeight: ratio8to5 }
55
- }
56
- }
57
-
58
- export default typographyTokens
35
+ cents: { fontSize: centsFontSize, lineHeight: centsLineHeight, fontWeight: centsFontWeight },
36
+ rate: { fontSize: rateFontSize, lineHeight: rateLineHeight, fontWeight: rateFontWeight },
37
+ bottomText: { fontSize: bottomTextFontSize, lineHeight: bottomTextLineHeight }
38
+ })
@@ -0,0 +1,67 @@
1
+ import React from 'react'
2
+ import PropTypes from 'prop-types'
3
+ import {
4
+ getTokensPropType,
5
+ Progress,
6
+ selectSystemProps,
7
+ useThemeTokens,
8
+ a11yProps,
9
+ viewProps,
10
+ variantProp
11
+ } from '@telus-uds/components-base'
12
+ import styled from 'styled-components'
13
+
14
+ // Passes React Native-oriented system props through UDS Progress
15
+ const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps])
16
+
17
+ const { Bar: ProgressBarBase } = Progress
18
+ const Gradient = styled.div.attrs({ 'data-testid': 'ProgressBar-Gradient' })(
19
+ ({ percentage, gradient: { angle, stops, type } }) => ({
20
+ height: '100%',
21
+ // As per the design specs, we need to have the gradient expanding to 100% and being
22
+ // revealed by bar width, so we need to stretch it beyond the parent (progress element)
23
+ // to the full length of the progress bar
24
+ width: `${(100 * 100) / percentage}%`,
25
+ background: `${type}-gradient(${angle}deg, ${stops[0].color}, ${stops[1].color})`
26
+ })
27
+ )
28
+
29
+ /**
30
+ * The `ProgressBar` is a visual representation of linear progression.
31
+ * It provides simple but important information at a quick glance.
32
+ * This is a Web-specific progress bar.
33
+ *
34
+ * ## Component API
35
+ *
36
+ * Use props and tokens from the base ProgressBar component. The difference is that the
37
+ * `gradient` is being used here to provide gradient filling.
38
+ *
39
+ */
40
+ const ProgressBar = ({ percentage, tokens, variant, ...rest }) => {
41
+ const themeTokens = useThemeTokens('ProgressBar', tokens, variant)
42
+ const selectedProps = selectProps(rest)
43
+
44
+ return (
45
+ <ProgressBarBase percentage={percentage} tokens={tokens} variant={variant} {...selectedProps}>
46
+ {themeTokens.gradient && <Gradient {...themeTokens} percentage={percentage} />}
47
+ </ProgressBarBase>
48
+ )
49
+ }
50
+
51
+ ProgressBar.propTypes = {
52
+ ...selectedSystemPropTypes,
53
+ /**
54
+ * Percentage of completion.
55
+ */
56
+ percentage: PropTypes.number,
57
+ /**
58
+ * ProgressBar tokens.
59
+ */
60
+ tokens: getTokensPropType('ProgressBar'),
61
+ /**
62
+ * ProgressBar variant.
63
+ */
64
+ variant: variantProp.propType
65
+ }
66
+
67
+ export default ProgressBar
@@ -0,0 +1,6 @@
1
+ import { Progress } from '@telus-uds/components-base'
2
+ import ProgressBar from './ProgressBar'
3
+
4
+ Progress.Bar = ProgressBar
5
+
6
+ export default Progress
@@ -22,6 +22,8 @@ const RibbonContainer = styled.div`
22
22
  border-radius: ${({ borderRadius }) => borderRadius};
23
23
  width: fit-content;
24
24
  box-shadow: ${({ boxShadow, shouldWrap }) => shouldWrap && boxShadow};
25
+ border-bottom-right-radius: ${({ borderRadiusBottomLeft }) => borderRadiusBottomLeft};
26
+ border-bottom-left-radius: ${({ borderRadiusBottomRight }) => borderRadiusBottomRight};
25
27
  `
26
28
 
27
29
  const RibbonCurve = styled.div`
@@ -71,15 +73,18 @@ const Ribbon = ({
71
73
  paddingLeft,
72
74
  paddingRight,
73
75
  paddingTop,
74
- gradient
75
- } = useThemeTokens('Ribbon', tokens, variant)
76
-
77
- const { purpose } = variant
78
- const { type: gradientType, angle: gradientAngle, stops: gradientColors } = gradient
79
- const isOfferPurpose = purpose === 'offer'
80
- const gradientBackground = `${gradientType}-gradient(${gradientAngle}deg, ${gradientColors[0].color}, ${gradientColors[1].color})`
81
- const background = isOfferPurpose ? gradientBackground : backgroundColor
76
+ gradient,
77
+ fontColor,
78
+ borderRadiusBottomLeft,
79
+ borderRadiusBottomRight
80
+ } = useThemeTokens('Ribbon', tokens, { ...variant, wrap: shouldWrap })
82
81
 
82
+ let background = backgroundColor
83
+ if (gradient) {
84
+ const { type: gradientType, angle: gradientAngle, stops: gradientColors } = gradient
85
+ const gradientBackground = `${gradientType}-gradient(${gradientAngle}deg, ${gradientColors[0].color}, ${gradientColors[1].color})`
86
+ background = gradientBackground
87
+ }
83
88
  return (
84
89
  <RibbonWrapper left={left} top={top} data-testid="ribbon-wrapper" {...selectProps(rest)}>
85
90
  <RibbonContainer
@@ -88,8 +93,15 @@ const Ribbon = ({
88
93
  padding={`${paddingTop}px ${paddingRight}px ${paddingBottom}px ${paddingLeft}px`}
89
94
  borderRadius={`${borderRadius}px`}
90
95
  boxShadow={`${boxShadowPaddingTop}px ${boxShadowPaddingRight}px ${boxShadowPaddingBottom}px ${boxShadowPaddingLeft}px ${boxShadowColor}`}
96
+ borderRadiusBottomLeft={`${borderRadiusBottomLeft}px`}
97
+ borderRadiusBottomRight={`${borderRadiusBottomRight}px`}
91
98
  >
92
- <Typography variant={{ size: 'micro', bold: true, inverse: true }}>{children}</Typography>
99
+ <Typography
100
+ variant={{ size: 'micro', bold: true, inverse: true }}
101
+ tokens={{ color: fontColor }}
102
+ >
103
+ {children}
104
+ </Typography>
93
105
  </RibbonContainer>
94
106
  {shouldWrap && (
95
107
  <RibbonCurve
@@ -2,6 +2,7 @@ import React from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
  import styled from 'styled-components'
4
4
  import { selectSystemProps, useScrollBlocking, useThemeTokens } from '@telus-uds/components-base'
5
+ import { Portal } from '@gorhom/portal'
5
6
  import SpinnerContent from './SpinnerContent'
6
7
  import { htmlAttrs, media } from '../utils'
7
8
  import { BACKDROP_OPACITY, BACKDROP_Z_INDEX } from './constants'
@@ -86,23 +87,25 @@ const Spinner = ({
86
87
  // Full screen spinner
87
88
  if (fullScreen) {
88
89
  return (
89
- <FullscreenOverlay fullScreenOverLayBackground={fullScreenOverLayBackground}>
90
- <SpinnerContainer
91
- inline={inline}
92
- fullScreen={fullScreen}
93
- aria-live="assertive"
94
- {...selectProps(rest)}
95
- >
96
- <SpinnerContent
97
- label={label}
98
- overlay={true}
99
- size={size}
100
- thickness={thickness}
101
- sizeVariant={sizeVariant}
102
- isStatic={isStatic}
103
- />
104
- </SpinnerContainer>
105
- </FullscreenOverlay>
90
+ <Portal>
91
+ <FullscreenOverlay fullScreenOverLayBackground={fullScreenOverLayBackground}>
92
+ <SpinnerContainer
93
+ inline={inline}
94
+ fullScreen={fullScreen}
95
+ aria-live="assertive"
96
+ {...selectProps(rest)}
97
+ >
98
+ <SpinnerContent
99
+ label={label}
100
+ overlay={true}
101
+ size={size}
102
+ thickness={thickness}
103
+ sizeVariant={sizeVariant}
104
+ isStatic={isStatic}
105
+ />
106
+ </SpinnerContainer>
107
+ </FullscreenOverlay>
108
+ </Portal>
106
109
  )
107
110
  }
108
111
 
@@ -73,7 +73,10 @@ const Cell = ({ children, type = 'default', isFirstInRow, align = 'left' }) => {
73
73
  cellPaddingTop,
74
74
  cellPaddingRight,
75
75
  cellPaddingLeft,
76
- cellPaddingBottom
76
+ cellPaddingBottom,
77
+ fontName,
78
+ fontWeight,
79
+ fontSize
77
80
  } = useThemeTokens('Table', tokens, variant)
78
81
  const sharedProps = {
79
82
  align,
@@ -86,6 +89,12 @@ const Cell = ({ children, type = 'default', isFirstInRow, align = 'left' }) => {
86
89
  cellBoxShadowColor
87
90
  }
88
91
 
92
+ const typographyTokens = {
93
+ fontName,
94
+ fontWeight,
95
+ fontSize
96
+ }
97
+
89
98
  switch (type) {
90
99
  case 'heading':
91
100
  return (
@@ -95,7 +104,9 @@ const Cell = ({ children, type = 'default', isFirstInRow, align = 'left' }) => {
95
104
  cellHeadingBoxShadowColor={cellHeadingBoxShadowColor}
96
105
  {...sharedProps}
97
106
  >
98
- <Typography variant={{ size: 'h4' }}>{children}</Typography>
107
+ <Typography tokens={typographyTokens} variant={{ size: 'h4' }}>
108
+ {children}
109
+ </Typography>
99
110
  </StyledHeading>
100
111
  )
101
112
  case 'subHeading':
@@ -105,7 +116,9 @@ const Cell = ({ children, type = 'default', isFirstInRow, align = 'left' }) => {
105
116
  cellSubheadingBackground={cellSubheadingBackground}
106
117
  {...sharedProps}
107
118
  >
108
- <Typography variant={{ size: 'h5' }}>{children}</Typography>
119
+ <Typography tokens={typographyTokens} variant={{ size: 'h5' }}>
120
+ {children}
121
+ </Typography>
109
122
  </StyledSubHeading>
110
123
  )
111
124
  case 'rowHeading':
@@ -115,14 +128,18 @@ const Cell = ({ children, type = 'default', isFirstInRow, align = 'left' }) => {
115
128
  cellRowHeadingBackground={cellRowHeadingBackground}
116
129
  {...sharedProps}
117
130
  >
118
- <Typography variant={{ size: text === 'small' ? 'h5' : 'h4' }}>{children}</Typography>
131
+ <Typography tokens={typographyTokens} variant={{ size: text === 'small' ? 'h5' : 'h4' }}>
132
+ {children}
133
+ </Typography>
119
134
  </StyledRowHeading>
120
135
  )
121
136
 
122
137
  default:
123
138
  return (
124
139
  <StyledCell cellBackground={cellBackground} {...sharedProps}>
125
- <Typography variant={{ size: text }}>{children}</Typography>
140
+ <Typography tokens={{ fontSize }} variant={{ size: text }}>
141
+ {children}
142
+ </Typography>
126
143
  </StyledCell>
127
144
  )
128
145
  }