@telus-uds/components-web 1.8.0 → 1.9.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 (179) hide show
  1. package/CHANGELOG.md +27 -2
  2. package/lib/Autocomplete/Autocomplete.js +393 -0
  3. package/lib/Autocomplete/Loading.js +51 -0
  4. package/lib/Autocomplete/Suggestions.js +81 -0
  5. package/lib/Autocomplete/constants.js +19 -0
  6. package/lib/Autocomplete/dictionary.js +19 -0
  7. package/lib/Autocomplete/index.js +13 -0
  8. package/lib/Callout/Callout.js +3 -0
  9. package/lib/Card/Card.js +180 -0
  10. package/lib/Card/CardContent.js +110 -0
  11. package/lib/Card/CardFooter.js +98 -0
  12. package/lib/Card/index.js +13 -0
  13. package/lib/Countdown/Countdown.js +189 -0
  14. package/lib/Countdown/Segment.js +111 -0
  15. package/lib/Countdown/constants.js +14 -0
  16. package/lib/Countdown/dictionary.js +29 -0
  17. package/lib/Countdown/index.js +13 -0
  18. package/lib/Countdown/types.js +39 -0
  19. package/lib/Countdown/useCountdown.js +40 -0
  20. package/lib/Modal/ModalContent.js +11 -4
  21. package/lib/OptimizeImage/OptimizeImage.js +127 -0
  22. package/lib/OptimizeImage/index.js +13 -0
  23. package/lib/OptimizeImage/utils/getFallbackUrl.js +18 -0
  24. package/lib/OptimizeImage/utils/getOptimizedUrl.js +32 -0
  25. package/lib/OptimizeImage/utils/hasWebpSupport.js +38 -0
  26. package/lib/OptimizeImage/utils/index.js +31 -0
  27. package/lib/OptimizeImage/utils/isSvgUrl.js +10 -0
  28. package/lib/QuantitySelector/QuantitySelector.js +253 -0
  29. package/lib/QuantitySelector/dictionary.js +33 -0
  30. package/lib/QuantitySelector/index.js +13 -0
  31. package/lib/QuantitySelector/styles.js +40 -0
  32. package/lib/StoryCard/StoryCard.js +244 -0
  33. package/lib/StoryCard/index.js +13 -0
  34. package/lib/TermsAndConditions/ExpandCollapse.js +141 -0
  35. package/lib/TermsAndConditions/TermsAndConditions.js +221 -0
  36. package/lib/TermsAndConditions/dictionary.js +19 -0
  37. package/lib/TermsAndConditions/index.js +15 -0
  38. package/lib/Testimonial/Testimonial.js +226 -0
  39. package/lib/Testimonial/index.js +13 -0
  40. package/lib/Video/ControlBar/ControlBar.js +315 -0
  41. package/lib/Video/ControlBar/Controls/VideoButton/VideoButton.js +91 -0
  42. package/lib/Video/ControlBar/Controls/VideoMenu/VideoMenu.js +186 -0
  43. package/lib/Video/ControlBar/Controls/VideoProgressBar/VideoProgressBar.js +221 -0
  44. package/lib/Video/ControlBar/Controls/VolumeSlider/VolumeSlider.js +213 -0
  45. package/lib/Video/MiddleControlButton/MiddleControlButton.js +89 -0
  46. package/lib/Video/Video.js +1072 -0
  47. package/lib/Video/index.js +13 -0
  48. package/lib/Video/videoText.js +62 -0
  49. package/lib/WebVideo/WebVideo.js +170 -0
  50. package/lib/WebVideo/index.js +13 -0
  51. package/lib/baseExports.js +0 -6
  52. package/lib/index.js +91 -1
  53. package/lib/shared/VideoSplash/SplashButton/SplashButton.js +102 -0
  54. package/lib/shared/VideoSplash/SplashButtonWithDetails/SplashButtonWithDetails.js +234 -0
  55. package/lib/shared/VideoSplash/VideoSplash.js +86 -0
  56. package/lib/shared/VideoSplash/helpers.js +38 -0
  57. package/lib/utils/index.js +8 -0
  58. package/lib-module/Autocomplete/Autocomplete.js +369 -0
  59. package/lib-module/Autocomplete/Loading.js +38 -0
  60. package/lib-module/Autocomplete/Suggestions.js +64 -0
  61. package/lib-module/Autocomplete/constants.js +5 -0
  62. package/lib-module/Autocomplete/dictionary.js +12 -0
  63. package/lib-module/Autocomplete/index.js +2 -0
  64. package/lib-module/Callout/Callout.js +3 -0
  65. package/lib-module/Card/Card.js +158 -0
  66. package/lib-module/Card/CardContent.js +92 -0
  67. package/lib-module/Card/CardFooter.js +80 -0
  68. package/lib-module/Card/index.js +2 -0
  69. package/lib-module/Countdown/Countdown.js +165 -0
  70. package/lib-module/Countdown/Segment.js +94 -0
  71. package/lib-module/Countdown/constants.js +4 -0
  72. package/lib-module/Countdown/dictionary.js +22 -0
  73. package/lib-module/Countdown/index.js +2 -0
  74. package/lib-module/Countdown/types.js +23 -0
  75. package/lib-module/Countdown/useCountdown.js +32 -0
  76. package/lib-module/Modal/ModalContent.js +10 -4
  77. package/lib-module/OptimizeImage/OptimizeImage.js +106 -0
  78. package/lib-module/OptimizeImage/index.js +2 -0
  79. package/lib-module/OptimizeImage/utils/getFallbackUrl.js +8 -0
  80. package/lib-module/OptimizeImage/utils/getOptimizedUrl.js +22 -0
  81. package/lib-module/OptimizeImage/utils/hasWebpSupport.js +32 -0
  82. package/lib-module/OptimizeImage/utils/index.js +4 -0
  83. package/lib-module/OptimizeImage/utils/isSvgUrl.js +3 -0
  84. package/lib-module/QuantitySelector/QuantitySelector.js +232 -0
  85. package/lib-module/QuantitySelector/dictionary.js +26 -0
  86. package/lib-module/QuantitySelector/index.js +2 -0
  87. package/lib-module/QuantitySelector/styles.js +21 -0
  88. package/lib-module/StoryCard/StoryCard.js +220 -0
  89. package/lib-module/StoryCard/index.js +2 -0
  90. package/lib-module/TermsAndConditions/ExpandCollapse.js +120 -0
  91. package/lib-module/TermsAndConditions/TermsAndConditions.js +193 -0
  92. package/lib-module/TermsAndConditions/dictionary.js +12 -0
  93. package/lib-module/TermsAndConditions/index.js +1 -0
  94. package/lib-module/Testimonial/Testimonial.js +204 -0
  95. package/lib-module/Testimonial/index.js +2 -0
  96. package/lib-module/Video/ControlBar/ControlBar.js +292 -0
  97. package/lib-module/Video/ControlBar/Controls/VideoButton/VideoButton.js +74 -0
  98. package/lib-module/Video/ControlBar/Controls/VideoMenu/VideoMenu.js +167 -0
  99. package/lib-module/Video/ControlBar/Controls/VideoProgressBar/VideoProgressBar.js +201 -0
  100. package/lib-module/Video/ControlBar/Controls/VolumeSlider/VolumeSlider.js +193 -0
  101. package/lib-module/Video/MiddleControlButton/MiddleControlButton.js +72 -0
  102. package/lib-module/Video/Video.js +1042 -0
  103. package/lib-module/Video/index.js +2 -0
  104. package/lib-module/Video/videoText.js +55 -0
  105. package/lib-module/WebVideo/WebVideo.js +144 -0
  106. package/lib-module/WebVideo/index.js +2 -0
  107. package/lib-module/baseExports.js +1 -1
  108. package/lib-module/index.js +10 -0
  109. package/lib-module/shared/VideoSplash/SplashButton/SplashButton.js +85 -0
  110. package/lib-module/shared/VideoSplash/SplashButtonWithDetails/SplashButtonWithDetails.js +216 -0
  111. package/lib-module/shared/VideoSplash/VideoSplash.js +65 -0
  112. package/lib-module/shared/VideoSplash/helpers.js +23 -0
  113. package/lib-module/utils/index.js +2 -1
  114. package/package.json +7 -5
  115. package/src/Autocomplete/Autocomplete.jsx +354 -0
  116. package/src/Autocomplete/Loading.jsx +18 -0
  117. package/src/Autocomplete/Suggestions.jsx +52 -0
  118. package/src/Autocomplete/constants.js +6 -0
  119. package/src/Autocomplete/dictionary.js +12 -0
  120. package/src/Autocomplete/index.js +3 -0
  121. package/src/Callout/Callout.jsx +1 -1
  122. package/src/Card/Card.jsx +170 -0
  123. package/src/Card/CardContent.jsx +88 -0
  124. package/src/Card/CardFooter.jsx +70 -0
  125. package/src/Card/index.js +3 -0
  126. package/src/Countdown/Countdown.jsx +144 -0
  127. package/src/Countdown/Segment.jsx +69 -0
  128. package/src/Countdown/constants.js +4 -0
  129. package/src/Countdown/dictionary.js +22 -0
  130. package/src/Countdown/index.js +3 -0
  131. package/src/Countdown/types.js +23 -0
  132. package/src/Countdown/useCountdown.js +34 -0
  133. package/src/Modal/ModalContent.jsx +8 -4
  134. package/src/OptimizeImage/OptimizeImage.jsx +131 -0
  135. package/src/OptimizeImage/index.js +3 -0
  136. package/src/OptimizeImage/utils/getFallbackUrl.js +9 -0
  137. package/src/OptimizeImage/utils/getOptimizedUrl.js +30 -0
  138. package/src/OptimizeImage/utils/hasWebpSupport.js +33 -0
  139. package/src/OptimizeImage/utils/index.js +5 -0
  140. package/src/OptimizeImage/utils/isSvgUrl.js +3 -0
  141. package/src/QuantitySelector/QuantitySelector.jsx +245 -0
  142. package/src/QuantitySelector/dictionary.js +27 -0
  143. package/src/QuantitySelector/index.js +3 -0
  144. package/src/QuantitySelector/styles.js +83 -0
  145. package/src/StoryCard/StoryCard.jsx +198 -0
  146. package/src/StoryCard/index.js +3 -0
  147. package/src/TermsAndConditions/ExpandCollapse.jsx +106 -0
  148. package/src/TermsAndConditions/TermsAndConditions.jsx +161 -0
  149. package/src/TermsAndConditions/dictionary.js +12 -0
  150. package/src/TermsAndConditions/index.js +1 -0
  151. package/src/Testimonial/Testimonial.jsx +169 -0
  152. package/src/Testimonial/index.js +3 -0
  153. package/src/Video/ControlBar/ControlBar.jsx +261 -0
  154. package/src/Video/ControlBar/Controls/VideoButton/VideoButton.jsx +61 -0
  155. package/src/Video/ControlBar/Controls/VideoMenu/VideoMenu.jsx +159 -0
  156. package/src/Video/ControlBar/Controls/VideoProgressBar/VideoProgressBar.jsx +185 -0
  157. package/src/Video/ControlBar/Controls/VolumeSlider/VolumeSlider.jsx +184 -0
  158. package/src/Video/MiddleControlButton/MiddleControlButton.jsx +64 -0
  159. package/src/Video/Video.jsx +988 -0
  160. package/src/Video/index.js +3 -0
  161. package/src/Video/videoText.js +58 -0
  162. package/src/WebVideo/WebVideo.jsx +131 -0
  163. package/src/WebVideo/index.js +3 -0
  164. package/src/baseExports.js +0 -1
  165. package/src/index.js +10 -0
  166. package/src/shared/VideoSplash/SplashButton/SplashButton.jsx +64 -0
  167. package/src/shared/VideoSplash/SplashButtonWithDetails/SplashButtonWithDetails.jsx +128 -0
  168. package/src/shared/VideoSplash/VideoSplash.jsx +50 -0
  169. package/src/shared/VideoSplash/helpers.js +27 -0
  170. package/src/utils/index.js +10 -1
  171. package/types/Autocomplete.d.ts +32 -0
  172. package/types/Card.d.ts +45 -0
  173. package/types/ControlBar.d.ts +59 -0
  174. package/types/MiddleControlButton.d.ts +15 -0
  175. package/types/Video.d.ts +39 -0
  176. package/types/VideoButton.d.ts +14 -0
  177. package/types/VideoMenu.d.ts +16 -0
  178. package/types/VideoProgressBar.d.ts +17 -0
  179. package/types/VolumeSlider.d.ts +20 -0
@@ -0,0 +1,92 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { getTokensPropType, selectSystemProps, useThemeTokens, useViewport, variantProp } from '@telus-uds/components-base';
4
+ import styled from 'styled-components';
5
+ import { htmlAttrs } from '../utils';
6
+ import { jsx as _jsx } from "react/jsx-runtime";
7
+ const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs]);
8
+ const CardContentContainer = /*#__PURE__*/styled.div.withConfig({
9
+ displayName: "CardContent__CardContentContainer",
10
+ componentId: "components-web__sc-1k2501q-0"
11
+ })(_ref => {
12
+ let {
13
+ backgroundColor,
14
+ borderRadius,
15
+ paddingBottom,
16
+ paddingLeft,
17
+ paddingRight,
18
+ paddingTop,
19
+ withFooter,
20
+ contentAlignItem: alignItem,
21
+ contentFlexGrow: flexGrow,
22
+ contentFlexShrink: flexShrink,
23
+ contentJustifyContent: justifyContent
24
+ } = _ref;
25
+ return {
26
+ backgroundColor,
27
+ // We need to make sure to have sharp corners on the bottom
28
+ // if the card has a footer
29
+ borderBottomLeftRadius: withFooter ? 0 : borderRadius,
30
+ borderBottomRightRadius: withFooter ? 0 : borderRadius,
31
+ borderTopLeftRadius: borderRadius,
32
+ borderTopRightRadius: borderRadius,
33
+ paddingBottom,
34
+ paddingLeft,
35
+ paddingRight,
36
+ paddingTop,
37
+ display: 'flex',
38
+ flexDirection: 'column',
39
+ alignItem,
40
+ flexGrow,
41
+ flexShrink,
42
+ justifyContent
43
+ };
44
+ });
45
+ /**
46
+ * Card content, applying the card tokens as per the theme used.
47
+ */
48
+
49
+ const CardContent = _ref2 => {
50
+ let {
51
+ children,
52
+ flexContent,
53
+ tokens,
54
+ variant,
55
+ withFooter = false,
56
+ ...rest
57
+ } = _ref2;
58
+ const viewport = useViewport();
59
+ const themeTokens = useThemeTokens('Card', tokens, variant, {
60
+ viewport
61
+ });
62
+ return /*#__PURE__*/_jsx(CardContentContainer, { ...themeTokens,
63
+ flexContent: flexContent,
64
+ withFooter: withFooter,
65
+ ...selectProps(rest),
66
+ children: children
67
+ });
68
+ };
69
+
70
+ CardContent.propTypes = { ...selectedSystemPropTypes,
71
+
72
+ /**
73
+ * Card section content.
74
+ */
75
+ children: PropTypes.node,
76
+
77
+ /**
78
+ * Card tokens.
79
+ */
80
+ tokens: getTokensPropType('Card'),
81
+
82
+ /**
83
+ * Card variant.
84
+ */
85
+ variant: variantProp.propType,
86
+
87
+ /**
88
+ * Whether the card has a footer.
89
+ */
90
+ withFooter: PropTypes.bool
91
+ };
92
+ export default CardContent;
@@ -0,0 +1,80 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { getTokensPropType, paddingProp, selectSystemProps, useThemeTokens, useViewport, variantProp } from '@telus-uds/components-base';
4
+ import styled from 'styled-components';
5
+ import { htmlAttrs } from '../utils';
6
+ import { jsx as _jsx } from "react/jsx-runtime";
7
+ const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs]);
8
+ const CardFooterContainer = /*#__PURE__*/styled.div.withConfig({
9
+ displayName: "CardFooter__CardFooterContainer",
10
+ componentId: "components-web__sc-pm6vns-0"
11
+ })(_ref => {
12
+ let {
13
+ backgroundColor,
14
+ borderRadius,
15
+ paddingBottom,
16
+ paddingLeft,
17
+ paddingRight,
18
+ paddingTop
19
+ } = _ref;
20
+ return {
21
+ backgroundColor,
22
+ borderBottomLeftRadius: borderRadius,
23
+ borderBottomRightRadius: borderRadius,
24
+ // @todo circle back to the following non-standard value to
25
+ // see if it can be integrated into the palette
26
+ boxShadow: 'inset 0px 1px 3px rgba(0, 0, 0, 0.05)',
27
+ paddingBottom,
28
+ paddingLeft,
29
+ paddingRight,
30
+ paddingTop
31
+ };
32
+ });
33
+ /**
34
+ * Card footer, applying the tokens as per the theme used.
35
+ */
36
+
37
+ const CardFooter = _ref2 => {
38
+ let {
39
+ children,
40
+ padding,
41
+ tokens,
42
+ variant,
43
+ ...rest
44
+ } = _ref2;
45
+ const viewport = useViewport();
46
+ const themeTokens = useThemeTokens('Card', tokens, { ...variant,
47
+ background: 'alternative'
48
+ }, {
49
+ viewport
50
+ });
51
+ return /*#__PURE__*/_jsx(CardFooterContainer, { ...themeTokens,
52
+ ...padding,
53
+ ...selectProps(rest),
54
+ children: children
55
+ });
56
+ };
57
+
58
+ CardFooter.propTypes = { ...selectedSystemPropTypes,
59
+
60
+ /**
61
+ * Card footer content.
62
+ */
63
+ children: PropTypes.node,
64
+
65
+ /**
66
+ * Card footer padding.
67
+ */
68
+ padding: paddingProp.propType,
69
+
70
+ /**
71
+ * Card tokens.
72
+ */
73
+ tokens: getTokensPropType('Card'),
74
+
75
+ /**
76
+ * Card variant.
77
+ */
78
+ variant: variantProp.propType
79
+ };
80
+ export default CardFooter;
@@ -0,0 +1,2 @@
1
+ import Card from './Card';
2
+ export default Card;
@@ -0,0 +1,165 @@
1
+ /* eslint-disable react/require-default-props */
2
+ import React, { forwardRef } from 'react';
3
+ import PropTypes from 'prop-types';
4
+ import { Spacer, StackView, Typography, selectSystemProps, useViewport, useThemeTokens, applyTextStyles } from '@telus-uds/components-base';
5
+ import { viewports } from '@telus-uds/system-constants';
6
+ import styled from 'styled-components'; // Reading these from the RN palette since they will be used to generate
7
+ // the `Typography` tokens
8
+
9
+ import { htmlAttrs, transformGradient } from '../utils';
10
+ import Segment from './Segment';
11
+ import useCountdown from './useCountdown';
12
+ import { countdownVariantPropType, dictionaryContentShape } from './types';
13
+ import { jsx as _jsx } from "react/jsx-runtime";
14
+ import { jsxs as _jsxs } from "react/jsx-runtime";
15
+ const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs]);
16
+ const Container = /*#__PURE__*/styled.div.withConfig({
17
+ displayName: "Countdown__Container",
18
+ componentId: "components-web__sc-18tqcb2-0"
19
+ })(_ref => {
20
+ let {
21
+ variant: {
22
+ feature,
23
+ inverse,
24
+ large
25
+ },
26
+ themeTokens,
27
+ gradient
28
+ } = _ref;
29
+ return { ...(large || feature && {
30
+ display: 'flex',
31
+ flex: 0
32
+ }),
33
+ ...(feature && {
34
+ borderRadius: themeTokens.containerBorderRadius,
35
+ justifyContent: 'center',
36
+ paddingBottom: `${themeTokens.containerPaddingBottomTop}px`,
37
+ paddingLeft: `${themeTokens.containerPaddingLeftRight}px`,
38
+ paddingRight: `${themeTokens.containerPaddingLeftRight}px`,
39
+ paddingTop: `${themeTokens.containerPaddingBottomTop}px`,
40
+ width: 'fit-content'
41
+ }),
42
+ ...(feature && !inverse && {
43
+ background: `linear-gradient(#fff 0 0) padding-box, ${gradient} border-box`,
44
+ border: `${themeTokens.containerInverseBorder}px solid transparent`
45
+ }),
46
+ ...(feature && inverse && {
47
+ border: `${themeTokens.containerInverseBorder}px solid ${themeTokens.inverseBorderColor}`
48
+ })
49
+ };
50
+ });
51
+
52
+ const getLabelTokens = themeTokens => ({
53
+ color: themeTokens.labelBorderColor,
54
+ fontWeight: themeTokens.textTimerFontWeight,
55
+ fontSize: `${themeTokens.labelFontSize}`,
56
+ lineHeight: `${themeTokens.labelLineHeight}`
57
+ });
58
+
59
+ const getMainTextTokens = themeTokens => ({
60
+ color: themeTokens.labelBorderColor,
61
+ fontWeight: themeTokens.textTimerFontWeight,
62
+ fontSize: themeTokens.textFontSize,
63
+ lineHeight: themeTokens.textLineHeight
64
+ });
65
+
66
+ const Countdown = /*#__PURE__*/forwardRef((_ref2, ref) => {
67
+ let {
68
+ copy = 'en',
69
+ targetTime,
70
+ tokens,
71
+ variant = {},
72
+ ...rest
73
+ } = _ref2;
74
+ const [days, hours, minutes, seconds] = useCountdown(targetTime);
75
+ const viewport = useViewport();
76
+ const {
77
+ feature,
78
+ large,
79
+ label,
80
+ noDivider
81
+ } = variant;
82
+
83
+ if (noDivider && !label) {
84
+ throw new Error('`noDivider` variant can only be used with `label` enabled!');
85
+ }
86
+
87
+ const themeTokens = useThemeTokens('Countdown', tokens, variant, {
88
+ viewport
89
+ });
90
+ const segmentFontSize = themeTokens.textFontSize;
91
+ const semanticGradient = themeTokens.containerGradient && transformGradient(themeTokens.containerGradient);
92
+ const mainTextTokens = getMainTextTokens(themeTokens);
93
+ const divider = noDivider === true ?
94
+ /*#__PURE__*/
95
+ // StackView-based subcontainer adds a 1-step space on the each side of the divider
96
+ _jsx(Spacer, {
97
+ direction: "row",
98
+ space: (feature || large) && viewport !== viewports.xs ? 7 : 2
99
+ }) : /*#__PURE__*/_jsx(Typography, {
100
+ tokens: mainTextTokens,
101
+ children: ":"
102
+ });
103
+ const labelTokens = getLabelTokens(themeTokens);
104
+ const commonProps = {
105
+ copy,
106
+ labelTokens,
107
+ numberTokens: mainTextTokens,
108
+ segmentFontSize,
109
+ variant
110
+ };
111
+ return (
112
+ /*#__PURE__*/
113
+ // Making it focusable for accessibility purposes
114
+ _jsx(Container, {
115
+ ref: ref,
116
+ variant: variant,
117
+ ...selectProps(rest),
118
+ tabIndex: 0,
119
+ themeTokens: themeTokens,
120
+ gradient: semanticGradient,
121
+ children: /*#__PURE__*/_jsxs(StackView, {
122
+ direction: "row",
123
+ space: 1,
124
+ children: [/*#__PURE__*/_jsx(Segment, {
125
+ labelKey: "day",
126
+ number: days,
127
+ segmentWidth: String(days).length,
128
+ ...commonProps
129
+ }), divider, /*#__PURE__*/_jsx(Segment, {
130
+ labelKey: "hour",
131
+ number: hours,
132
+ ...commonProps,
133
+ ...applyTextStyles(themeTokens)
134
+ }), divider, /*#__PURE__*/_jsx(Segment, {
135
+ labelKey: "minute",
136
+ number: minutes,
137
+ ...commonProps,
138
+ ...applyTextStyles(themeTokens)
139
+ }), divider, /*#__PURE__*/_jsx(Segment, {
140
+ labelKey: "second",
141
+ number: seconds,
142
+ ...commonProps,
143
+ ...applyTextStyles(themeTokens)
144
+ })]
145
+ })
146
+ })
147
+ );
148
+ });
149
+ Countdown.displayName = 'Countdown';
150
+ Countdown.propTypes = { ...selectedSystemPropTypes,
151
+
152
+ /**
153
+ * Copy language identifier (`'en'` or `'fr'`) or a dictionary instance (an object with
154
+ * the following keys: days, day, hours, hour, minutes, minute, seconds, second)
155
+ */
156
+ copy: PropTypes.oneOfType([PropTypes.oneOf(['en', 'fr']), dictionaryContentShape]),
157
+
158
+ /**
159
+ * An instance of JavaScript `Date` object or a string parseable via `Date.parse()`
160
+ * representing a point in the future to count down to.
161
+ */
162
+ targetTime: PropTypes.instanceOf(Date),
163
+ variant: countdownVariantPropType
164
+ };
165
+ export default Countdown;
@@ -0,0 +1,94 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { StackView, Typography, useCopy } from '@telus-uds/components-base';
4
+ import styled from 'styled-components';
5
+ import dictionary from './dictionary';
6
+ import { countdownVariantPropType, dictionaryContentShape } from './types';
7
+ import { SEGMENT_WIDTH_TO_FONT_SIZE_RATIO } from './constants'; // Pads with zeros on the left if it's a single digit number
8
+
9
+ import { jsx as _jsx } from "react/jsx-runtime";
10
+ import { jsxs as _jsxs } from "react/jsx-runtime";
11
+
12
+ const pad = function (number) {
13
+ let segmentWidth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2;
14
+ return String(number).padStart(segmentWidth, '0');
15
+ };
16
+
17
+ const Container = /*#__PURE__*/styled.div.withConfig({
18
+ displayName: "Segment__Container",
19
+ componentId: "components-web__sc-yrh35y-0"
20
+ })(_ref => {
21
+ let {
22
+ segmentFontSize,
23
+ segmentWidth = 2,
24
+ variant: {
25
+ feature
26
+ }
27
+ } = _ref;
28
+ return {
29
+ justifyContent: 'space-evenly',
30
+ display: 'inline-flex',
31
+ ...(feature && {
32
+ width: `${segmentFontSize * SEGMENT_WIDTH_TO_FONT_SIZE_RATIO * segmentWidth}px`,
33
+ display: 'flex'
34
+ })
35
+ };
36
+ }); // A segment of the countdown string: we need to make sure it
37
+ // keeps its width constant to prevent the whole component from
38
+ // being automatically resized while using variable size fonts
39
+
40
+ const Segment = _ref2 => {
41
+ let {
42
+ copy = 'en',
43
+ segmentFontSize,
44
+ labelKey,
45
+ labelTokens,
46
+ number,
47
+ numberTokens,
48
+ segmentWidth = 2,
49
+ variant = {}
50
+ } = _ref2;
51
+ const getCopy = useCopy({
52
+ dictionary,
53
+ copy
54
+ });
55
+ const {
56
+ label,
57
+ large,
58
+ feature
59
+ } = variant;
60
+ return /*#__PURE__*/_jsx(Container, {
61
+ segmentFontSize: segmentFontSize,
62
+ segmentWidth: segmentWidth,
63
+ variant: variant,
64
+ children: /*#__PURE__*/_jsxs(StackView, {
65
+ direction: large || feature ? 'column' : 'row',
66
+ space: large || feature ? 0 : 1,
67
+ tokens: {
68
+ alignItems: 'center'
69
+ },
70
+ children: [/*#__PURE__*/_jsx(Typography, {
71
+ tokens: numberTokens,
72
+ children: pad(number, segmentWidth)
73
+ }), label && /*#__PURE__*/_jsx(Typography, {
74
+ tokens: labelTokens,
75
+ children: getCopy(number === 1 ? labelKey : `${labelKey}s`)
76
+ })]
77
+ })
78
+ });
79
+ };
80
+
81
+ Segment.propTypes = {
82
+ /**
83
+ * Copy language identifier or a dictionary instance.
84
+ */
85
+ copy: PropTypes.oneOfType([PropTypes.oneOf(['en', 'fr']), dictionaryContentShape]),
86
+ segmentFontSize: PropTypes.number,
87
+ labelKey: PropTypes.oneOf(['day', 'hour', 'minute', 'second']),
88
+ labelTokens: PropTypes.object,
89
+ number: PropTypes.number,
90
+ numberTokens: PropTypes.object,
91
+ segmentWidth: PropTypes.number,
92
+ variant: countdownVariantPropType
93
+ };
94
+ export default Segment;
@@ -0,0 +1,4 @@
1
+ export const DEFAULT_FONT_SIZE = 16;
2
+ export const LARGE_FONT_SIZE = 64;
3
+ export const SEGMENT_WIDTH_TO_FONT_SIZE_RATIO = 0.8;
4
+ export const XS_FONT_SIZE = 28;
@@ -0,0 +1,22 @@
1
+ export default {
2
+ en: {
3
+ days: 'Days',
4
+ day: 'Day',
5
+ hours: 'Hours',
6
+ hour: 'Hour',
7
+ minutes: 'Minutes',
8
+ minute: 'Minute',
9
+ seconds: 'Seconds',
10
+ second: 'Second'
11
+ },
12
+ fr: {
13
+ days: 'Jours',
14
+ day: 'Jour',
15
+ hours: 'Heures',
16
+ hour: 'Heure',
17
+ minutes: 'Minutes',
18
+ minute: 'Minute',
19
+ seconds: 'Secondes',
20
+ second: 'Seconde'
21
+ }
22
+ };
@@ -0,0 +1,2 @@
1
+ import Countdown from './Countdown';
2
+ export default Countdown;
@@ -0,0 +1,23 @@
1
+ import PropTypes from 'prop-types';
2
+ export const countdownVariantPropType = PropTypes.shape({
3
+ feature: PropTypes.bool,
4
+ inverse: PropTypes.bool,
5
+ label: PropTypes.bool,
6
+ large: PropTypes.bool,
7
+ noDivider: PropTypes.bool
8
+ }); // If a language dictionary entry is provided, it must contain every key
9
+
10
+ export const dictionaryContentShape = PropTypes.shape({
11
+ days: PropTypes.string.isRequired,
12
+ day: PropTypes.string.isRequired,
13
+ hours: PropTypes.string.isRequired,
14
+ hour: PropTypes.string.isRequired,
15
+ minutes: PropTypes.string.isRequired,
16
+ minute: PropTypes.string.isRequired,
17
+ seconds: PropTypes.string.isRequired,
18
+ second: PropTypes.string.isRequired
19
+ });
20
+ export default {
21
+ countdownVariantPropType,
22
+ dictionaryContentShape
23
+ };
@@ -0,0 +1,32 @@
1
+ import { useEffect, useState } from 'react';
2
+
3
+ const getTimeCounts = countdown => {
4
+ if (countdown <= 0) {
5
+ return [0, 0, 0, 0];
6
+ }
7
+
8
+ const days = Math.floor(countdown / (1000 * 60 * 60 * 24));
9
+ const hours = Math.floor(countdown % (1000 * 60 * 60 * 24) / (1000 * 60 * 60));
10
+ const minutes = Math.floor(countdown % (1000 * 60 * 60) / (1000 * 60));
11
+ const seconds = Math.floor(countdown % (1000 * 60) / 1000);
12
+ return [days, hours, minutes, seconds];
13
+ };
14
+
15
+ const useCountdown = targetTime => {
16
+ const countdownTime = new Date(targetTime).getTime();
17
+
18
+ if (!countdownTime) {
19
+ throw new Error('Invalid target time is provided!');
20
+ }
21
+
22
+ const [countdown, setCountdown] = useState(countdownTime - new Date().getTime());
23
+ useEffect(() => {
24
+ const interval = setInterval(() => {
25
+ setCountdown(countdownTime - new Date().getTime());
26
+ }, 1000);
27
+ return () => clearInterval(interval);
28
+ }, [countdownTime]);
29
+ return getTimeCounts(countdown);
30
+ };
31
+
32
+ export default useCountdown;
@@ -27,9 +27,15 @@ const StyledSubHeading = /*#__PURE__*/styled.div.withConfig({
27
27
  } = _ref2;
28
28
  return marginTop;
29
29
  });
30
+ const StyledTextButtonContainer = /*#__PURE__*/styled.div.withConfig({
31
+ displayName: "ModalContent__StyledTextButtonContainer",
32
+ componentId: "components-web__sc-k40cwb-3"
33
+ })({
34
+ display: 'flex'
35
+ });
30
36
  const StyledFooter = /*#__PURE__*/styled.footer.withConfig({
31
37
  displayName: "ModalContent__StyledFooter",
32
- componentId: "components-web__sc-k40cwb-3"
38
+ componentId: "components-web__sc-k40cwb-4"
33
39
  })(_ref3 => {
34
40
  let {
35
41
  hasBorder,
@@ -143,15 +149,15 @@ const ModalContent = _ref4 => {
143
149
  },
144
150
  onPress: onConfirm,
145
151
  children: confirmButtonText
146
- }), /*#__PURE__*/_jsx("div", {
147
- children: hasCancelButton && /*#__PURE__*/_jsx(CancelButton, {
152
+ }), hasCancelButton ? /*#__PURE__*/_jsx(StyledTextButtonContainer, {
153
+ children: /*#__PURE__*/_jsx(CancelButton, {
148
154
  tokens: {
149
155
  color: cancelButtonColor
150
156
  },
151
157
  onPress: onCancel,
152
158
  children: cancelButtonText
153
159
  })
154
- })]
160
+ }) : null]
155
161
  })]
156
162
  });
157
163
  };
@@ -0,0 +1,106 @@
1
+ import React, { useEffect, useState } from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { selectSystemProps } from '@telus-uds/components-base';
4
+ import ResponsiveImage from '../ResponsiveImage';
5
+ import { hasWebpSupport, getOptimizedUrl, getFallbackUrl } from './utils';
6
+ import { htmlAttrs } from '../utils';
7
+ import { jsx as _jsx } from "react/jsx-runtime";
8
+ const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs]);
9
+
10
+ const OptimizeImage = _ref => {
11
+ let {
12
+ contentfulAssetUrl,
13
+ alt,
14
+ quality = 80,
15
+ xs = 320,
16
+ sm = 576,
17
+ md = 768,
18
+ lg = 992,
19
+ xl = 1200,
20
+ sizeByHeight = false,
21
+ disableRetina = false,
22
+ ...rest
23
+ } = _ref;
24
+ const [imgUrls, setImgUrls] = useState(); // `useHeight` is a deprecated TDS prop, replaced by `sizeByHeight`
25
+
26
+ const dimension = sizeByHeight || rest.useHeight ? 'h' : 'w';
27
+ useEffect(() => {
28
+ // Currently not all browsers support webP
29
+ hasWebpSupport().then(supportsWebp => {
30
+ setImgUrls({
31
+ xsSrc: getOptimizedUrl(contentfulAssetUrl, dimension, xs, quality, disableRetina, supportsWebp),
32
+ smSrc: getOptimizedUrl(contentfulAssetUrl, dimension, sm, quality, disableRetina, supportsWebp),
33
+ mdSrc: getOptimizedUrl(contentfulAssetUrl, dimension, md, quality, disableRetina, supportsWebp),
34
+ lgSrc: getOptimizedUrl(contentfulAssetUrl, dimension, lg, quality, disableRetina, supportsWebp),
35
+ xlSrc: getOptimizedUrl(contentfulAssetUrl, dimension, xl, quality, disableRetina, supportsWebp),
36
+ fallbackSrc: getFallbackUrl(contentfulAssetUrl, xl, quality)
37
+ });
38
+ });
39
+ }, [contentfulAssetUrl, dimension, disableRetina, lg, md, quality, sm, xl, xs]);
40
+ if (!imgUrls) return null;
41
+ return /*#__PURE__*/_jsx(ResponsiveImage, { ...imgUrls,
42
+ alt: alt,
43
+ ...selectProps(rest)
44
+ });
45
+ };
46
+
47
+ OptimizeImage.propTypes = { ...selectedSystemPropTypes,
48
+
49
+ /**
50
+ * The source to load the image. Only contentful image urls are supported. See https://www.contentful.com/developers/docs/references/images-api/ for details.
51
+ */
52
+ contentfulAssetUrl: PropTypes.string.isRequired,
53
+
54
+ /**
55
+ * Alternative text to display if image cannot be loaded or a screen reader is used.
56
+ */
57
+ alt: PropTypes.string.isRequired,
58
+
59
+ /**
60
+ * Customize quality as a percentage between 1 and 100.
61
+ */
62
+ quality: PropTypes.number,
63
+
64
+ /**
65
+ * Customize width for xs screen size in px, this may affect the quality of the image.
66
+ */
67
+ xs: PropTypes.number,
68
+
69
+ /**
70
+ * Customize width for sm screen size in px, this may affect the quality of the image.
71
+ */
72
+ sm: PropTypes.number,
73
+
74
+ /**
75
+ * Customize width for md screen size in px, this may affect the quality of the image.
76
+ */
77
+ md: PropTypes.number,
78
+
79
+ /**
80
+ * Customize width for lg screen size in px, this may affect the quality of the image.
81
+ */
82
+ lg: PropTypes.number,
83
+
84
+ /**
85
+ * Customize width for xl screen size in px, this may affect the quality of the image.
86
+ */
87
+ xl: PropTypes.number,
88
+
89
+ /**
90
+ * Switches size dimension to height, default is false
91
+ */
92
+ sizeByHeight: PropTypes.bool,
93
+
94
+ /**
95
+ * Turns off retina display functionality
96
+ */
97
+ disableRetina: PropTypes.bool,
98
+
99
+ /**
100
+ * Loading strategy.
101
+ * @default 'eager'
102
+ * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-loading
103
+ */
104
+ loading: PropTypes.oneOf(['eager', 'lazy'])
105
+ };
106
+ export default OptimizeImage;
@@ -0,0 +1,2 @@
1
+ import OptimizeImage from './OptimizeImage';
2
+ export default OptimizeImage;
@@ -0,0 +1,8 @@
1
+ import isSvgUrl from './isSvgUrl';
2
+ export default function getFallbackUrl(url, width, quality) {
3
+ if (!isSvgUrl(url)) {
4
+ return `${url}?w=${width}&q=${quality}`;
5
+ }
6
+
7
+ return url;
8
+ }