@telus-uds/components-web 2.13.0 → 2.15.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.
@@ -5,7 +5,7 @@ import { Box, Divider, selectSystemProps, Typography, useCopy, useThemeTokens, u
5
5
  import ExpandCollapse from './ExpandCollapse';
6
6
  import OrderedListBase from '../OrderedList/OrderedListBase';
7
7
  import { htmlAttrs, media, renderStructuredContent } from '../utils';
8
- import dictionary from './dictionary';
8
+ import defaultDictionary from './dictionary';
9
9
  import { jsx as _jsx } from "react/jsx-runtime";
10
10
  import { jsxs as _jsxs } from "react/jsx-runtime";
11
11
  const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs]);
@@ -106,6 +106,7 @@ const TermsAndConditions = /*#__PURE__*/forwardRef((_ref6, ref) => {
106
106
  nonIndexedContent,
107
107
  tokens,
108
108
  variant = {},
109
+ dictionary = defaultDictionary,
109
110
  ...rest
110
111
  } = _ref6;
111
112
  const getCopy = useCopy({
@@ -172,7 +173,13 @@ const TermsAndConditions = /*#__PURE__*/forwardRef((_ref6, ref) => {
172
173
  })]
173
174
  });
174
175
  });
175
- TermsAndConditions.displayName = 'TermsAndConditions';
176
+ TermsAndConditions.displayName = 'TermsAndConditions'; // If a language dictionary entry is provided, it must contain every key
177
+
178
+ const dictionaryContentShape = PropTypes.shape({
179
+ headingHide: PropTypes.string.isRequired,
180
+ headingView: PropTypes.string.isRequired,
181
+ nonIndexedTitle: PropTypes.string.isRequired
182
+ });
176
183
  TermsAndConditions.propTypes = { ...selectedSystemPropTypes,
177
184
 
178
185
  /**
@@ -198,11 +205,20 @@ TermsAndConditions.propTypes = { ...selectedSystemPropTypes,
198
205
  *
199
206
  * nonIndexedContent do not have a corresponding superscript and instead apply to the page as a whole.
200
207
  */
201
- nonIndexedContent: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.node, PropTypes.string]))
208
+ nonIndexedContent: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.node, PropTypes.string])),
209
+
210
+ /**
211
+ * Custom dictionary containing the labels to use for `TermsAndConditions`
212
+ */
213
+ dictionary: PropTypes.shape({
214
+ en: dictionaryContentShape,
215
+ fr: dictionaryContentShape
216
+ })
202
217
  };
203
218
  TermsAndConditions.defaultProps = {
204
219
  copy: 'en',
205
220
  indexedContent: [],
206
- nonIndexedContent: []
221
+ nonIndexedContent: [],
222
+ dictionary: defaultDictionary
207
223
  };
208
224
  export default TermsAndConditions;
@@ -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 { Icon, selectSystemProps, Typography, useThemeTokens } from '@telus-uds/components-base';
4
+ import { Icon, selectSystemProps, Typography, useThemeTokens, useViewport } from '@telus-uds/components-base';
5
5
  import Image from '../Image';
6
6
  import { htmlAttrs } from '../utils';
7
7
  import { jsx as _jsx } from "react/jsx-runtime";
@@ -83,11 +83,13 @@ const Testimonial = _ref5 => {
83
83
  imageSrc,
84
84
  image = imageSrc,
85
85
  additionalInfo,
86
- testimonialStyle = 'heading',
86
+ testimonialStyle = 'large',
87
87
  tokens,
88
+ copy = 'en',
88
89
  variant = {},
89
90
  ...rest
90
91
  } = _ref5;
92
+ const viewport = useViewport();
91
93
  const {
92
94
  testimonialContainerGap,
93
95
  quoteContainerGap,
@@ -96,9 +98,34 @@ const Testimonial = _ref5 => {
96
98
  figcaptionGap,
97
99
  textColor,
98
100
  icon,
101
+ iconFr,
99
102
  iconColor,
100
- imageSize
101
- } = useThemeTokens('Testimonial', tokens, variant);
103
+ imageSize,
104
+ testimonialFontSizeLarge,
105
+ testimonialLineHeightLarge,
106
+ testimonialFontWeightLarge,
107
+ testimonialFontSizeHeading,
108
+ testimonialLineHeightHeading,
109
+ testimonialFontNameHeading,
110
+ testimonialFontWeightHeading,
111
+ authorFontSize,
112
+ authorLineHeight,
113
+ authorFontName,
114
+ authorFontWeight,
115
+ additionalFontSize,
116
+ additionalLineHeight,
117
+ additionalFontName,
118
+ additionalFontWeight
119
+ } = useThemeTokens('Testimonial', tokens, variant, {
120
+ viewport
121
+ });
122
+
123
+ const getQuoteTestimonial = open => {
124
+ let quote = '';
125
+ if (copy === 'en') quote = open ? '\u201C' : '\u201D';else quote = open ? '\u00AB ' : ' \u00BB';
126
+ return quote;
127
+ };
128
+
102
129
  return /*#__PURE__*/_jsxs(TestimonialContainer, {
103
130
  testimonialContainerGap: testimonialContainerGap,
104
131
  ...selectProps(rest),
@@ -111,7 +138,7 @@ const Testimonial = _ref5 => {
111
138
  variant: {
112
139
  size: 'micro'
113
140
  },
114
- icon: icon
141
+ icon: copy === 'en' ? icon : iconFr
115
142
  }), showDivider && /*#__PURE__*/_jsx(Divider, {
116
143
  dividerBackgroundColor: dividerBackgroundColor,
117
144
  dividerBorder: dividerBorder,
@@ -124,9 +151,12 @@ const Testimonial = _ref5 => {
124
151
  },
125
152
  tokens: {
126
153
  color: textColor,
127
- fontWeight: '400'
154
+ fontSize: testimonialStyle === 'heading' ? testimonialFontSizeHeading : testimonialFontSizeLarge,
155
+ lineHeight: testimonialStyle === 'heading' ? testimonialLineHeightHeading : testimonialLineHeightLarge,
156
+ fontName: testimonialFontNameHeading,
157
+ fontWeight: testimonialStyle === 'heading' ? testimonialFontWeightHeading : testimonialFontWeightLarge
128
158
  },
129
- children: `\u201C${testimonial}\u201D`
159
+ children: `${getQuoteTestimonial(true)}${testimonial}${getQuoteTestimonial()}`
130
160
  })
131
161
  }), (image || title || additionalInfo) && /*#__PURE__*/_jsxs(Figcaption, {
132
162
  figcaptionGap: figcaptionGap,
@@ -139,20 +169,26 @@ const Testimonial = _ref5 => {
139
169
  }) : image), (title || additionalInfo) && /*#__PURE__*/_jsxs(AuthorInfoContainer, {
140
170
  children: [title && /*#__PURE__*/_jsx(Typography, {
141
171
  variant: {
142
- size: 'small',
143
- colour: 'secondary'
172
+ size: 'small'
144
173
  },
145
174
  tokens: {
146
- fontWeight: '500'
175
+ color: textColor,
176
+ fontSize: authorFontSize,
177
+ lineHeight: authorLineHeight,
178
+ fontName: authorFontName,
179
+ fontWeight: authorFontWeight
147
180
  },
148
181
  children: title
149
182
  }), additionalInfo && /*#__PURE__*/_jsx(Typography, {
150
183
  variant: {
151
- size: 'micro',
152
- colour: 'secondary'
184
+ size: 'small'
153
185
  },
154
186
  tokens: {
155
- fontWeight: '400'
187
+ color: textColor,
188
+ fontSize: additionalFontSize,
189
+ lineHeight: additionalLineHeight,
190
+ fontName: additionalFontName,
191
+ fontWeight: additionalFontWeight
156
192
  },
157
193
  children: additionalInfo
158
194
  })]
@@ -21,19 +21,29 @@ const animation = props => css(["", " 1s ease-in-out 2s forwards,", " 1s ease-in
21
21
  const ToastContainer = /*#__PURE__*/styled.div.withConfig({
22
22
  displayName: "Toast__ToastContainer",
23
23
  componentId: "components-web__sc-p78jdh-0"
24
- })(["display:flex;justify-content:center;align-items:center;flex-wrap:wrap;background:", ";gap:", ";height:0;overflow:hidden;animation:", ";"], _ref => {
24
+ })(["display:flex;justify-content:center;align-items:center;flex-wrap:wrap;padding-left:", "px;padding-right:", "px;background:", ";gap:", ";height:0;overflow:hidden;animation:", ";"], _ref => {
25
25
  let {
26
- containerBackgroundColor
26
+ padding
27
27
  } = _ref;
28
- return containerBackgroundColor;
28
+ return padding;
29
29
  }, _ref2 => {
30
30
  let {
31
- containerGap
31
+ padding
32
32
  } = _ref2;
33
+ return padding;
34
+ }, _ref3 => {
35
+ let {
36
+ containerBackgroundColor
37
+ } = _ref3;
38
+ return containerBackgroundColor;
39
+ }, _ref4 => {
40
+ let {
41
+ containerGap
42
+ } = _ref4;
33
43
  return containerGap;
34
44
  }, animation);
35
45
 
36
- const Toast = _ref3 => {
46
+ const Toast = _ref5 => {
37
47
  let {
38
48
  toast,
39
49
  copy,
@@ -42,7 +52,7 @@ const Toast = _ref3 => {
42
52
  tokens,
43
53
  variant = {},
44
54
  ...rest
45
- } = _ref3;
55
+ } = _ref5;
46
56
  // viewport hook added to work adjust the padding to different sizes
47
57
  const viewport = useViewport();
48
58
  const {
@@ -58,7 +68,8 @@ const Toast = _ref3 => {
58
68
  animationBackgroundColorAfter,
59
69
  animationColorBefore,
60
70
  animationColorAfter,
61
- chevronlinkFontWeight
71
+ chevronlinkFontWeight,
72
+ ...extraTokens
62
73
  } = useThemeTokens('Toast', tokens, variant, {
63
74
  viewport
64
75
  }); // inherit ChevronLink tokens for animation colors
@@ -91,6 +102,7 @@ const Toast = _ref3 => {
91
102
  animationColorAfter: animationColorAfter,
92
103
  animationFillColorBefore: chevronInverseColor,
93
104
  animationFillColorAfter: chevronDefaultColor,
105
+ ...extraTokens,
94
106
  ...selectProps(rest),
95
107
  children: [headline && /*#__PURE__*/_jsx(Typography, {
96
108
  variant: {
package/package.json CHANGED
@@ -5,14 +5,14 @@
5
5
  ],
6
6
  "dependencies": {
7
7
  "@gorhom/portal": "^1.0.14",
8
- "@telus-uds/components-base": "1.54.0",
9
- "@telus-uds/system-constants": "^1.2.1",
8
+ "@telus-uds/components-base": "1.56.0",
9
+ "@telus-uds/system-constants": "^1.3.0",
10
10
  "fscreen": "^1.2.0",
11
11
  "lodash.omit": "^4.5.0",
12
12
  "react-dates": "^21.8.0",
13
13
  "react-helmet-async": "^1.3.0",
14
14
  "react-moment-proptypes": "^1.8.1",
15
- "@telus-uds/system-theme-tokens": "^2.37.0",
15
+ "@telus-uds/system-theme-tokens": "^2.39.0",
16
16
  "prop-types": "^15.7.2",
17
17
  "lodash.throttle": "^4.1.1",
18
18
  "react-youtube": "^10.1.0",
@@ -63,5 +63,5 @@
63
63
  "skip": true
64
64
  },
65
65
  "types": "types/index.d.ts",
66
- "version": "2.13.0"
66
+ "version": "2.15.0"
67
67
  }
@@ -42,7 +42,8 @@ const Badge = ({ children, tokens, variant = {}, ...rest }) => {
42
42
  paddingTop,
43
43
  paddingBottom,
44
44
  fontName,
45
- fontWeight
45
+ fontWeight,
46
+ fontSize
46
47
  } = useThemeTokens('Badge', tokens, variant)
47
48
 
48
49
  const semanticGradient = gradient && transformGradient(gradient)
@@ -56,6 +57,12 @@ const Badge = ({ children, tokens, variant = {}, ...rest }) => {
56
57
  background = semanticGradient
57
58
  }
58
59
 
60
+ const fontSizeMapping = {
61
+ 12: 'micro',
62
+ 14: 'small',
63
+ 16: 'h6'
64
+ }
65
+
59
66
  return (
60
67
  <BadgeContainer
61
68
  isOutlineOffer={isOutlineOffer}
@@ -69,7 +76,12 @@ const Badge = ({ children, tokens, variant = {}, ...rest }) => {
69
76
  border={`${borderWidth}px solid ${borderColor}`}
70
77
  {...selectProps(rest)}
71
78
  >
72
- <Typography tokens={{ fontName, fontWeight, color }}>{children}</Typography>
79
+ <Typography
80
+ tokens={{ fontName, fontWeight, color }}
81
+ variant={{ size: fontSizeMapping[fontSize] }}
82
+ >
83
+ {children}
84
+ </Typography>
73
85
  </BadgeContainer>
74
86
  )
75
87
  }
@@ -23,7 +23,8 @@ const CardContentContainer = styled.div(
23
23
  contentAlignItems: alignItems,
24
24
  contentFlexGrow: flexGrow,
25
25
  contentFlexShrink: flexShrink,
26
- contentJustifyContent: justifyContent
26
+ contentJustifyContent: justifyContent,
27
+ borderWidth
27
28
  }) => ({
28
29
  // We need to make sure to have sharp corners on the bottom
29
30
  // if the card has a footer
@@ -31,10 +32,10 @@ const CardContentContainer = styled.div(
31
32
  borderBottomRightRadius: withFooter ? 0 : borderRadius,
32
33
  borderTopLeftRadius: borderRadius,
33
34
  borderTopRightRadius: borderRadius,
34
- paddingBottom,
35
- paddingLeft,
36
- paddingRight,
37
- paddingTop,
35
+ paddingBottom: paddingBottom - borderWidth,
36
+ paddingLeft: paddingLeft - borderWidth,
37
+ paddingRight: paddingRight - borderWidth,
38
+ paddingTop: paddingTop - borderWidth,
38
39
  display: 'flex',
39
40
  flexDirection: 'column',
40
41
  alignItems,
@@ -15,6 +15,7 @@ import {
15
15
  applyTextStyles
16
16
  } from '@telus-uds/components-base'
17
17
  import moment from 'moment'
18
+ import { isUndefined } from 'lodash'
18
19
  import CalendarContainer from './CalendarContainer'
19
20
  import dictionary from './dictionary'
20
21
  import { htmlAttrs } from '../utils'
@@ -23,25 +24,17 @@ const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs])
23
24
  const dateFormat = 'DD / MM / YYYY'
24
25
  const dateFormatWithoutSpaces = 'DD/MM/YYYY'
25
26
  const getResponsiveDaySize = (inline = false, viewport = 'md') => {
26
- let responsiveDaySize
27
27
  if (viewport === 'xs') {
28
- responsiveDaySize = inline ? undefined : 36
29
- } else {
30
- responsiveDaySize = inline ? 60 : 44
28
+ return inline ? undefined : 36
31
29
  }
32
-
33
- return responsiveDaySize
30
+ return inline ? 60 : 44
34
31
  }
35
32
 
36
33
  const getResponsiveCircleSize = (inline = false, viewport = 'md') => {
37
- let responsiveCircleSize
38
34
  if (viewport === 'xs') {
39
- responsiveCircleSize = 26
40
- } else {
41
- responsiveCircleSize = inline ? 44 : 26
35
+ return 26
42
36
  }
43
-
44
- return responsiveCircleSize
37
+ return inline ? 44 : 26
45
38
  }
46
39
 
47
40
  const MonthCenterContainer = styled.div({
@@ -106,7 +99,11 @@ const DatePicker = forwardRef(
106
99
  const [isClickedInside, setIsClickedInside] = useState(false)
107
100
  const getCopy = useCopy({ dictionary, copy })
108
101
  useEffect(() => {
109
- if (!moment(date).isSame(inputDate)) {
102
+ /**
103
+ * `date` could be passed as `null` to reset the value so explicitly
104
+ * checking for not being `undefined`
105
+ */
106
+ if (!isUndefined(date) && !moment(date).isSame(inputDate)) {
110
107
  setInputDate(date)
111
108
  setInputText(date instanceof moment ? date.format(dateFormat) : '')
112
109
  }
@@ -139,6 +136,7 @@ const DatePicker = forwardRef(
139
136
  const onChange = (value) => {
140
137
  setInputDate(value)
141
138
  setInputText(value.format(dateFormat))
139
+ setIsFocused(false)
142
140
  if (onDateChange) onDateChange(value)
143
141
  }
144
142
  const onChangeInput = (value) => {
@@ -1,7 +1,6 @@
1
1
  import React, { useState } from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
  import {
4
- getThemeTokens,
5
4
  Box,
6
5
  TextInput,
7
6
  Spacer,
@@ -9,13 +8,12 @@ import {
9
8
  InputLabel,
10
9
  useInputValue,
11
10
  useCopy,
12
- useThemeTokens,
13
- useTheme
11
+ useThemeTokensCallback
14
12
  } from '@telus-uds/components-base'
15
13
 
16
- import IconButton from '../IconButton'
17
- import { InputField, InputWrapper, LeftButtonWrapper, RightButtonWrapper } from './styles'
14
+ import { InputField, InputWrapper } from './styles'
18
15
  import defaultDictionary from './dictionary'
16
+ import SideButton from './SideButton'
19
17
 
20
18
  const { isNaN } = Number
21
19
 
@@ -28,6 +26,7 @@ const QuantitySelector = ({
28
26
  minNumber,
29
27
  maxNumber,
30
28
  defaultValue,
29
+ value,
31
30
  label,
32
31
  hint,
33
32
  hintPosition,
@@ -40,13 +39,8 @@ const QuantitySelector = ({
40
39
  tokens,
41
40
  testID
42
41
  }) => {
43
- const {
44
- components: { QuantitySelector: componentTheme }
45
- } = useTheme()
46
-
47
- const { leftIcon, rightIcon, padding } = useThemeTokens('QuantitySelector', tokens, variant)
42
+ const { disabled } = variant
48
43
  const [error, setError] = useState('')
49
- const { alternative } = variant
50
44
  const getCopy = useCopy({ dictionary, copy })
51
45
 
52
46
  const getValidatedNumber = (numberToEvaluate) => {
@@ -58,16 +52,14 @@ const QuantitySelector = ({
58
52
  return numberToEvaluate
59
53
  }
60
54
 
61
- const initialValue = getValidatedNumber(defaultValue)
62
-
63
55
  const { currentValue: number, setValue: setNumber } = useInputValue({
64
- value: undefined,
65
- initialValue,
56
+ value: getValidatedNumber(value),
57
+ initialValue: getValidatedNumber(defaultValue),
66
58
  onChange
67
59
  })
68
60
 
69
- const isDecreaseEnabled = !isNumber(minNumber) || number > minNumber
70
- const isIncreaseEnabled = !isNumber(maxNumber) || number < maxNumber
61
+ const isDecreaseEnabled = (!disabled && !isNumber(minNumber)) || number > minNumber
62
+ const isIncreaseEnabled = (!disabled && !isNumber(maxNumber)) || number < maxNumber
71
63
  const inputValue = isNumber(number) ? number.toString() : ''
72
64
 
73
65
  const updateNumber = (newNumber, originalInputEvent) => {
@@ -101,24 +93,34 @@ const QuantitySelector = ({
101
93
  />
102
94
  ) : null
103
95
 
96
+ const getTokens = useThemeTokensCallback('QuantitySelector', tokens, variant)
97
+
104
98
  const renderTextInput = () => (
105
99
  <TextInput
106
100
  nativeID={id}
107
101
  value={inputValue}
102
+ defaultValue={defaultValue}
108
103
  tokens={(textInputState) => {
109
- const { inputBorderColor, inputBackgroundColor } = getThemeTokens(
110
- componentTheme,
111
- tokens,
112
- variant,
113
- textInputState
114
- )
115
-
104
+ const {
105
+ inputWidth,
106
+ inputBorderWidth,
107
+ inputBorderColor,
108
+ textColor,
109
+ inputBackgroundColor,
110
+ ...rest
111
+ } = getTokens({
112
+ ...textInputState
113
+ })
116
114
  return {
117
- borderRadius: 0,
118
- margin: 0,
119
- padding: 0,
115
+ ...rest,
116
+ order: 1,
117
+ borderWidth: inputBorderWidth,
118
+ backgroundColor: inputBackgroundColor,
119
+ color: textColor,
120
+ width: inputWidth,
120
121
  borderColor: inputBorderColor,
121
- backgroundColor: inputBackgroundColor
122
+ borderRadius: 0,
123
+ outerBorderWidth: 0
122
124
  }
123
125
  }}
124
126
  onChange={inputChangeHandler}
@@ -133,58 +135,34 @@ const QuantitySelector = ({
133
135
  />
134
136
  )
135
137
 
136
- const getButtonTokens = (isEnabled) => (buttonState) => {
137
- const disabled = !isEnabled
138
- const { ...buttonTokens } = getThemeTokens(componentTheme, tokens, variant, {
139
- ...buttonState,
140
- disabled
141
- })
142
-
143
- return {
144
- ...buttonTokens,
145
- outerBorderGap: 0,
146
- padding
147
- }
148
- }
149
-
150
- const renderLeftButton = () => {
151
- return (
152
- <IconButton
153
- icon={leftIcon}
154
- tokens={getButtonTokens(isDecreaseEnabled)}
155
- onPress={(event) => updateNumber(number - 1, event)}
156
- onDoubleClick={(event) => updateNumber(number - 1, event)}
157
- accessibilityLabel={getCopy('accessibility').decreaseButton}
158
- accessibilityDisabled={!isDecreaseEnabled}
159
- />
160
- )
161
- }
162
-
163
- const renderRightButton = () => (
164
- <IconButton
165
- icon={rightIcon}
166
- tokens={getButtonTokens(isIncreaseEnabled)}
167
- onPress={() => updateNumber(number + 1)}
168
- onDoubleClick={() => updateNumber(number + 1)}
169
- accessibilityLabel={getCopy('accessibility').increaseButton}
170
- accessibilityDisabled={!isIncreaseEnabled}
171
- />
172
- )
173
-
174
138
  return (
175
139
  <Box space={2} testID={testID}>
176
140
  {renderLabel()}
177
141
  <Spacer space={2} />
178
142
  <InputWrapper>
179
- <InputField className={`${alternative ? 'alternative' : ''}`}>
180
- {renderTextInput()}
181
- </InputField>
182
- <RightButtonWrapper className={`${alternative ? 'alternative' : ''}`}>
183
- {renderRightButton()}
184
- </RightButtonWrapper>
185
- <LeftButtonWrapper className={`${alternative ? 'alternative' : ''}`}>
186
- {renderLeftButton()}
187
- </LeftButtonWrapper>
143
+ <InputField>{renderTextInput()}</InputField>
144
+ <div style={{ order: 0 }}>
145
+ <SideButton
146
+ isEnabled={isDecreaseEnabled}
147
+ onPress={() => updateNumber(number - 1)}
148
+ onDoubleClick={() => updateNumber(number - 1)}
149
+ tokens={tokens}
150
+ variant={{ decrease: true, ...variant }}
151
+ accessibilityLabel={getCopy('accessibility').decreaseButton}
152
+ accessibilityDisabled={!isDecreaseEnabled}
153
+ />
154
+ </div>
155
+ <div style={{ order: 2 }}>
156
+ <SideButton
157
+ isEnabled={isIncreaseEnabled}
158
+ onPress={() => updateNumber(number + 1)}
159
+ onDoubleClick={() => updateNumber(number + 1)}
160
+ accessibilityLabel={getCopy('accessibility').increaseButton}
161
+ accessibilityDisabled={!isIncreaseEnabled}
162
+ tokens={tokens}
163
+ variant={{ increase: true, ...variant }}
164
+ />
165
+ </div>
188
166
  </InputWrapper>
189
167
  {error ? (
190
168
  <Box vertical={2}>
@@ -230,6 +208,11 @@ QuantitySelector.propTypes = {
230
208
  * The default value of the input field
231
209
  */
232
210
  defaultValue: PropTypes.number,
211
+ /**
212
+ * If the input's state is to be controlled by a parent component, use this prop
213
+ * together with the `onChange` to pass down and update the lifted state.
214
+ */
215
+ value: PropTypes.number,
233
216
  /**
234
217
  * The label of the input field
235
218
  */
@@ -262,7 +245,8 @@ QuantitySelector.propTypes = {
262
245
  */
263
246
  copy: PropTypes.oneOfType([PropTypes.oneOf(['en', 'fr'])]),
264
247
  variant: PropTypes.exact({
265
- alternative: PropTypes.bool
248
+ alternative: PropTypes.bool,
249
+ disabled: PropTypes.bool
266
250
  }),
267
251
  tokens: PropTypes.oneOf([PropTypes.object, PropTypes.func]),
268
252
  /**
@@ -0,0 +1,74 @@
1
+ import { IconButton, useThemeTokensCallback } from '@telus-uds/components-base'
2
+ import React from 'react'
3
+ import PropTypes from 'prop-types'
4
+
5
+ const SideButton = ({
6
+ isEnabled,
7
+ onPress,
8
+ onDoubleClick,
9
+ accessibilityLabel,
10
+ accessibilityDisabled,
11
+ tokens,
12
+ variant
13
+ }) => {
14
+ const getTokens = useThemeTokensCallback('QuantitySelectorSideButton', tokens, variant)
15
+ const getButtonTokens = ({ buttonState, disabled }) => {
16
+ const {
17
+ borderRadius,
18
+ borderTopLeftRadius,
19
+ borderTopRightRadius,
20
+ borderBottomLeftRadius,
21
+ borderBottomRightRadius,
22
+ ...rest
23
+ } = getTokens({ ...buttonState, disabled })
24
+
25
+ return {
26
+ ...rest,
27
+ borderRadius,
28
+ borderTopLeftRadius,
29
+ borderTopRightRadius,
30
+ borderBottomLeftRadius,
31
+ borderBottomRightRadius,
32
+ outerBorderRadius: borderRadius,
33
+ outerBorderTopLeftRadius: borderTopLeftRadius,
34
+ outerBorderTopRightRadius: borderTopRightRadius,
35
+ outerBorderBottomLeftRadius: borderBottomLeftRadius,
36
+ outerBorderBottomRightRadius: borderBottomRightRadius,
37
+ outerBorderGap: 0,
38
+ outerBorderWidth: 0
39
+ }
40
+ }
41
+
42
+ return (
43
+ <IconButton
44
+ tokens={(buttonState) => getButtonTokens({ disabled: !isEnabled, buttonState })}
45
+ onPress={onPress}
46
+ onDoubleClick={onDoubleClick}
47
+ accessibilityLabel={accessibilityLabel}
48
+ accessibilityDisabled={accessibilityDisabled}
49
+ />
50
+ )
51
+ }
52
+
53
+ SideButton.displayName = 'QuantitySelectorSideButton'
54
+
55
+ SideButton.defaultProps = {
56
+ isEnabled: true,
57
+ onPress: () => {},
58
+ onDoubleClick: () => {},
59
+ accessibilityLabel: '',
60
+ accessibilityDisabled: false,
61
+ tokens: {},
62
+ variant: {}
63
+ }
64
+
65
+ SideButton.propTypes = {
66
+ isEnabled: PropTypes.bool,
67
+ onPress: PropTypes.func,
68
+ onDoubleClick: PropTypes.func,
69
+ accessibilityLabel: PropTypes.string,
70
+ accessibilityDisabled: PropTypes.bool,
71
+ tokens: PropTypes.object,
72
+ variant: PropTypes.object
73
+ }
74
+ export default SideButton